1    package org.torweg.pulse.component.survey.model;
2    
3    import javax.persistence.Basic;
4    import javax.persistence.Column;
5    import javax.persistence.Entity;
6    import javax.persistence.Inheritance;
7    import javax.persistence.InheritanceType;
8    import javax.persistence.Transient;
9    import javax.xml.bind.annotation.XmlAccessOrder;
10   import javax.xml.bind.annotation.XmlAccessType;
11   import javax.xml.bind.annotation.XmlAccessorOrder;
12   import javax.xml.bind.annotation.XmlAccessorType;
13   import javax.xml.bind.annotation.XmlAttribute;
14   import javax.xml.bind.annotation.XmlElement;
15   import javax.xml.bind.annotation.XmlRootElement;
16   
17   import org.hibernate.Session;
18   import org.hibernate.Transaction;
19   import org.torweg.pulse.invocation.lifecycle.Lifecycle;
20   import org.torweg.pulse.service.PulseException;
21   import org.torweg.pulse.util.entity.AbstractBasicEntity;
22   
23   /**
24    * The base-class to derive an answer from.
25    * 
26    * @param <T>
27    *            the type of the {@code AbstractTypedAnswer<T>}
28    * 
29    * @author Daniel Dietz
30    * @version $Revision: 1586 $
31    */
32   @Entity
33   @Inheritance(strategy = InheritanceType.JOINED)
34   @XmlRootElement(name = "abstract-answer")
35   @XmlAccessorOrder(XmlAccessOrder.UNDEFINED)
36   @XmlAccessorType(XmlAccessType.FIELD)
37   public abstract class AbstractTypedAnswer<T> extends AbstractBasicEntity {
38   
39       /**
40        * The serialVersionUID.
41        */
42       private static final long serialVersionUID = -3015370690973043330L;
43   
44       /**
45        * The {@code AbstractQuestion} this
46        * {@code AbstractTypedAnswer<T>} belongs to.
47        */
48       @Basic
49       @Column(nullable = false, updatable = false)
50       @XmlAttribute(name = "question-id")
51       private Long questionId;
52   
53       /**
54        * Indicates if the {@code AbstractTypedAnswer<T>} did validate
55        * against the {@code AbstractQuestion} it was created by.
56        * <p>
57        * default: {@code true}
58        * </p>
59        */
60       @Basic
61       @XmlElement(name = "is-valid")
62       private boolean isValid = true;
63   
64       /**
65        * The error which is being set by the {@code AbstractQuestion} during
66        * validation.
67        */
68       @Transient
69       @XmlElement(name = "validation-error")
70       private AnswerValidationError validationError = null;
71   
72       /**
73        * Sets the <tt>id</tt> of the {@code AbstractQuestion} this
74        * {@code AbstractTypedAnswer<T>} belongs to.
75        * 
76        * @param questId
77        *            the {@code AbstractQuestion} to set
78        */
79       protected final void setQuestionId(final Long questId) {
80           if (questId == null) {
81               throw new PulseException(
82                       "The questionId for the answer cannot be null!");
83           }
84           this.questionId = questId;
85       }
86   
87       /**
88        * Returns the <tt>id</tt> of the {@code AbstractQuestion} this
89        * {@code AbstractTypedAnswer<T>} belongs to.
90        * 
91        * @return the {@code AbstractQuestion}
92        */
93       public final Long getQuestionId() {
94           return this.questionId;
95       }
96   
97       /**
98        * Returns the {@code AbstractQuestion} the
99        * {@code AbstractTypedAnswer<T>} belongs to.
100       * 
101       * @param s
102       *            the hibernate<sup>TM</sup>-{@code Session}
103       * 
104       * @return the {@code AbstractQuestion} the
105       *         {@code AbstractTypedAnswer<T>} belongs to if a
106       *         {@code AbstractQuestion} could be loaded, {@code null}
107       *         otherwise
108       */
109      public final AbstractQuestion getQuestion(final Session s) {
110          AbstractQuestion question = null;
111  
112          if (s != null) {
113              question = (AbstractQuestion) s.get(AbstractQuestion.class,
114                      getQuestionId());
115          } else {
116              Session ss = Lifecycle.getHibernateDataSource().createNewSession();
117              Transaction tx = ss.beginTransaction();
118              try {
119                  question = (AbstractQuestion) ss.get(AbstractQuestion.class,
120                          getQuestionId());
121                  tx.commit();
122              } catch (Exception e) {
123                  tx.rollback();
124                  throw new PulseException("Error: " + e.getLocalizedMessage(), e);
125              } finally {
126                  ss.close();
127              }
128          }
129  
130          return question;
131      }
132  
133      /**
134       * Sets the valid-state for the {@code AbstractTypedAnswear}.
135       * 
136       * @param valid
137       *            the value to be set
138       */
139      protected final void setValid(final boolean valid) {
140          this.isValid = valid;
141      }
142  
143      /**
144       * Returns {@code true} if the
145       * {@code AbstractTypedAnswer<T>} is valid, {@code false}
146       * otherwise.
147       * 
148       * @return {@code true} if the
149       *         {@code AbstractTypedAnswer<T>} is valid,
150       *         {@code false} otherwise
151       */
152      public final boolean isValid() {
153          return this.isValid;
154      }
155  
156      /**
157       * Sets the <tt>validationError</tt>.
158       * 
159       * @param error
160       *            the {@code AnswerValidationError} to set
161       */
162      protected final void setValidationError(final AnswerValidationError error) {
163          this.validationError = error;
164      }
165  
166      /**
167       * Returns the <tt>validationError</tt>.
168       * 
169       * @return the <tt>validationError</tt>
170       */
171      public final AnswerValidationError getValidationError() {
172          return this.validationError;
173      }
174  
175      /**
176       * Returns the value of the {@code AbstractTypedAnswer<T>}.
177       * 
178       * @return the value
179       */
180      public abstract T getValue();
181  
182  }
183