1    /*
2     * Copyright 2009 :torweg free software group
3     *
4     * This program is free software: you can redistribute it and/or modify
5     * it under the terms of the GNU General Public License as published by
6     * the Free Software Foundation, either version 3 of the License, or
7     * (at your option) any later version.
8     * 
9     * This program is distributed in the hope that it will be useful,
10    * but WITHOUT ANY WARRANTY; without even the implied warranty of
11    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    * GNU General Public License for more details.
13    * 
14    * You should have received a copy of the GNU General Public License
15    * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16    *
17    */
18   package org.torweg.pulse.site.content;
19   
20   import java.io.IOException;
21   import java.io.StringReader;
22   import java.util.Set;
23   
24   import javax.persistence.Column;
25   import javax.persistence.Lob;
26   import javax.persistence.MappedSuperclass;
27   import javax.persistence.Transient;
28   import javax.xml.bind.annotation.XmlElement;
29   import javax.xml.bind.annotation.XmlTransient;
30   import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
31   
32   import org.hibernate.LazyInitializationException;
33   import org.jdom.Element;
34   import org.jdom.JDOMException;
35   import org.jdom.input.SAXBuilder;
36   import org.torweg.pulse.service.PulseException;
37   import org.torweg.pulse.site.content.util.ILinkCorrectableElement;
38   import org.torweg.pulse.util.xml.XMLConverter;
39   import org.torweg.pulse.util.xml.bind.ElementXmlAdapter;
40   
41   /**
42    * @param <T>
43    *            the actual implementation
44    * 
45    * @author Thomas Weber
46    * @version $Revision: 1984 $
47    */
48   @MappedSuperclass
49   public abstract class AbstractSummaryDescriptionVariant<T extends AbstractSummaryDescriptionVariant<T>>
50           extends AbstractBasicVariant<T> {
51   
52       /**
53        * serialVersionUID.
54        */
55       private static final long serialVersionUID = -5792584035373330549L;
56   
57       /**
58        * The description of the {@code AbstractSummaryDescriptionContent}.
59        */
60       @Lob
61       @Column(length = 65535, nullable = false)
62       @XmlTransient
63       private String description = "<body/>";
64   
65       /**
66        * The description of the {@code AbstractSummaryDescriptionContent} as a
67        * JDOM {@code Element}.
68        */
69       @Transient
70       private transient Element descriptionElement = null;
71   
72       /**
73        * Returns the description of the {@code AbstractSummaryDescriptionContent}.
74        * 
75        * @return the description of the {@code AbstractSummaryDescriptionContent}
76        */
77       public final String getDescription() {
78           return this.description;
79       }
80   
81       /**
82        * Sets the description of the {@code AbstractSummaryDescriptionContent}
83        * from a JDOM {@code Element}.
84        * 
85        * @param pDescription
86        *            the JDOM {@code Element} representing the description to be
87        *            set.
88        */
89       public final void setDescription(final Element pDescription) {
90           this.description = XMLConverter.getRawString(pDescription, true);
91           this.descriptionElement = pDescription;
92       }
93   
94       /**
95        * Returns the description of the {@code AbstractSummaryDescriptionContent}
96        * as a JDOM {@code Element}.
97        * 
98        * @return the description of the {@code AbstractSummaryDescriptionContent}
99        *         as a JDOM {@code Element}.
100       */
101      public final Element getDescriptionElement() {
102          if (getDescription() == null) {
103              return null;
104          }
105          if (this.descriptionElement == null) {
106              try {
107                  this.descriptionElement = new SAXBuilder().build(
108                          new StringReader(getDescription())).getRootElement();
109              } catch (JDOMException e) {
110                  throw new PulseException("Error parsing XML for description: "
111                          + e.getLocalizedMessage(), e);
112              } catch (IOException e) {
113                  throw new PulseException("Error reading XML for description: "
114                          + e.getLocalizedMessage(), e);
115              }
116          }
117          return (Element) this.descriptionElement.clone();
118      }
119  
120      /**
121       * For JAXB only.
122       * 
123       * @return this.getDescriptionElement()
124       */
125      @XmlElement(name = "description-element")
126      @XmlJavaTypeAdapter(value = ElementXmlAdapter.class)
127      @SuppressWarnings("unused")
128      @Deprecated
129      private Element getDescriptionElementJAXB() {
130          try {
131              return getDescriptionElement();
132          } catch (LazyInitializationException e) {
133              LOGGER.debug("ignored: {}", e.getLocalizedMessage());
134              return null;
135          }
136      }
137  
138      /**
139       * Returns the {@code AbstractSummaryDescriptionVariant<T>}'s textual information as it is
140       * supposed to be supplied for the index.
141       * 
142       * <p>
143       * Implementing classes may override the method to supply more information
144       * for the index.
145       * </p>
146       * 
147       * @return the {@code AbstractSummaryDescriptionVariant<T>}'s textual information as it is
148       *         supposed to be supplied for the index.
149       */
150      @Override
151      public StringBuilder getFullTextValue() {
152          return new StringBuilder(getName()).append(' ').append(
153                  XMLConverter.getHTMLText(getDescriptionElement()));
154      }
155      
156      /**
157       * @return the set of {@code ILinkCorrectableElement}s
158       * @see org.torweg.pulse.site.content.AbstractBasicContent#getLinkCorrectables()
159       */
160      @Override
161      public Set<ILinkCorrectableElement> getLinkCorrectables() {
162          Set<ILinkCorrectableElement> correctables = super.getLinkCorrectables();
163          correctables.add(new DescriptionCorrectable(this));
164          return correctables;
165      }
166  
167      /**
168       * is an {@code ILinkCorrectableElement} for the summary of the {@code
169       * AbstractSummaryDescriptionVariant}.
170       * 
171       * @author Thomas Weber
172       */
173      private static final class DescriptionCorrectable implements
174              ILinkCorrectableElement {
175  
176          /**
177           * the abstract basic content.
178           */
179          private final AbstractSummaryDescriptionVariant<?> variant;
180  
181          /**
182           * creates a new {@code SummaryCorrectable} for the given {@code
183           * AbstractSummaryDescriptionVariant}.
184           * 
185           * @param c
186           *            the content as a back reference
187           */
188          public DescriptionCorrectable(
189                  final AbstractSummaryDescriptionVariant<?> c) {
190              super();
191              this.variant = c;
192          }
193  
194          /**
195           * @return the element
196           * @see org.torweg.pulse.site.content.util.ILinkCorrectableElement#getElement()
197           */
198          public Element getElement() {
199              return this.variant.getDescriptionElement();
200          }
201  
202          /**
203           * @param e
204           *            the element to set
205           * @see org.torweg.pulse.site.content.util.ILinkCorrectableElement#setElement(org.jdom.Element)
206           */
207          public void setElement(final Element e) {
208              this.variant.setDescription(e);
209          }
210  
211      }
212  }
213