View Javadoc

1   /*
2    * Copyright 2012-2013 smartics, Kronseder & Reiner GmbH
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package de.smartics.properties.spi.core.metadata.comment;
17  
18  import java.io.BufferedInputStream;
19  import java.io.IOException;
20  import java.io.InputStream;
21  import java.util.List;
22  import java.util.Locale;
23  
24  import org.apache.commons.io.IOUtils;
25  import org.jdom.Document;
26  import org.jdom.Element;
27  import org.jdom.JDOMException;
28  import org.jdom.Namespace;
29  import org.jdom.input.SAXBuilder;
30  import org.slf4j.Logger;
31  import org.slf4j.LoggerFactory;
32  
33  import de.smartics.properties.api.core.domain.PropertiesContext;
34  import de.smartics.properties.api.core.domain.PropertyComment;
35  import de.smartics.properties.api.core.domain.PropertyDescriptor;
36  import de.smartics.properties.api.core.domain.PropertyValueComment;
37  import de.smartics.util.lang.Arg;
38  import de.smartics.util.lang.NullArgumentException;
39  
40  /**
41   * Parses property comments for a property descriptors.
42   */
43  public final class PropertyCommentParser
44  {
45    // ********************************* Fields *********************************
46  
47    // --- constants ------------------------------------------------------------
48  
49    /**
50     * Reference to the logger for this class.
51     */
52    private static final Logger LOG = LoggerFactory
53        .getLogger(PropertyCommentParser.class);
54  
55    /**
56     * The namespace of the XML files this parser can parse.
57     */
58    private static final Namespace PROPERTY_NS =
59        Namespace
60            .getNamespace("http://www.smartics.de/schema/projectdoc/doctype/property/1");
61  
62    // --- members --------------------------------------------------------------
63  
64    /**
65     * The properties context to fetch information from the META-INF folder.
66     */
67    private final PropertiesContext context;
68  
69    // ****************************** Initializer *******************************
70  
71    // ****************************** Constructors ******************************
72  
73    /**
74     * Default constructor.
75     *
76     * @param context the properties context to fetch information from the
77     *          META-INF folder.
78     * @throws NullArgumentException if {@code context} is <code>null</code>.
79     */
80    public PropertyCommentParser(final PropertiesContext context)
81      throws NullArgumentException
82    {
83      this.context = Arg.checkNotNull("context", context);
84    }
85  
86    // ****************************** Inner Classes *****************************
87  
88    // ********************************* Methods ********************************
89  
90    // --- init -----------------------------------------------------------------
91  
92    // --- get&set --------------------------------------------------------------
93  
94    // --- business -------------------------------------------------------------
95  
96    /**
97     * Parses the comments for the given descriptor.
98     *
99     * @param descriptor the descriptor whose comments are requested to be parsed.
100    * @param locale the locale to select the comments.
101    * @return the comments for the given locale or the default comments, if the
102    *         locale is not supported.
103    */
104   public PropertyComment parse(final PropertyDescriptor descriptor,
105       final Locale locale)
106   {
107     final String path = context.createMetaInfPath(descriptor, locale);
108     final ClassLoader loader = descriptor.getDeclaringType().getClassLoader(); // NOPMD
109 
110     InputStream input = null;
111     try
112     {
113       final InputStream resource = loader.getResourceAsStream(path);
114       if (resource != null)
115       {
116         input = new BufferedInputStream(resource);
117         final PropertyComment comment = parse(path, input);
118         return comment;
119       }
120       else
121       {
122         LOG.warn("No comments for property descriptor '{}' found: {}",
123             descriptor, path);
124       }
125     }
126     catch (final CommentException e)
127     {
128       LOG.warn("Cannot parse comments for property descriptor '{}': {}",
129           descriptor, e);
130     }
131     finally
132     {
133       IOUtils.closeQuietly(input);
134     }
135 
136     return PropertyComment.EMPTY_COMMENT;
137   }
138 
139   private PropertyComment parse(final String systemId, final InputStream input)
140     throws CommentException
141   {
142     try
143     {
144       final SAXBuilder parser = new SAXBuilder();
145       final Document document = parser.build(input, systemId);
146 
147       final PropertyComment.Builder builder = new PropertyComment.Builder();
148 
149       final Element rootNode = document.getRootElement();
150 
151       final String comment =
152           rootNode.getChildTextNormalize("specification", PROPERTY_NS);
153       final PropertyValueComment valueComment = parseValueComment(rootNode);
154       builder.withText(comment).with(valueComment);
155 
156       return builder.build();
157     }
158     catch (final JDOMException e)
159     {
160       throw new CommentException(systemId, e);
161     }
162     catch (final IOException e)
163     {
164       throw new CommentException(systemId, e);
165     }
166   }
167 
168   @SuppressWarnings("unchecked")
169   private PropertyValueComment parseValueComment(final Element rootNode)
170   {
171     final Element valueRange = rootNode.getChild("valueRange", PROPERTY_NS);
172     if (valueRange == null)
173     {
174       return null;
175     }
176 
177     final String summary =
178         valueRange.getChildTextNormalize("summary", PROPERTY_NS);
179     final PropertyValueComment comment = new PropertyValueComment(summary);
180 
181     final List<Element> elements =
182         (List<Element>) valueRange.getChildren("element", PROPERTY_NS);
183     for (final Element element : elements)
184     {
185       final String value = element.getChildTextNormalize("value", PROPERTY_NS);
186       final String description =
187           element.getChildTextNormalize("description", PROPERTY_NS);
188       comment.addValueComment(value, description);
189     }
190 
191     return comment;
192   }
193 
194   // --- object basics --------------------------------------------------------
195 
196 }