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;
17
18 import java.lang.reflect.Method;
19 import java.util.HashMap;
20 import java.util.Locale;
21 import java.util.Map;
22
23 import org.apache.commons.lang.builder.ToStringBuilder;
24
25 import de.smartics.properties.api.core.domain.DocumentMetaData;
26 import de.smartics.properties.api.core.domain.PropertiesContext;
27 import de.smartics.properties.api.core.domain.PropertyDescriptor;
28 import de.smartics.properties.spi.core.metadata.projectdoc.ProjectdocAnnotationCollector;
29 import de.smartics.properties.spi.core.metadata.projectdoc.ProjectdocAnnotationCollector.Defaults;
30 import de.smartics.properties.spi.core.metadata.projectdoc.ProjectdocMetaDataParser;
31 import de.smartics.properties.spi.core.util.SerializableMethod;
32
33 /**
34 * Allows to lazy load annotation information.
35 */
36 public final class MetaInfDocumentMetaDataProxy implements
37 DocumentMetaDataProxy
38 {
39 // ********************************* Fields *********************************
40
41 // --- constants ------------------------------------------------------------
42
43 /**
44 * The class version identifier.
45 */
46 private static final long serialVersionUID = 1L;
47
48 // --- members --------------------------------------------------------------
49
50 /**
51 * The properties context to fetch information from the META-INF folder. May
52 * be <code>null</code>.
53 *
54 * @serial
55 */
56 private final PropertiesContext context;
57
58 /**
59 * The method to use to fetch annotations in case the context is not to be
60 * used.
61 *
62 * @serial
63 */
64 private final SerializableMethod propertyMethod;
65
66 /**
67 * The cached comments.
68 *
69 * @serial
70 */
71 private final Map<Locale, DocumentMetaData> metaData =
72 new HashMap<Locale, DocumentMetaData>();
73
74 // ****************************** Initializer *******************************
75
76 // ****************************** Constructors ******************************
77
78 /**
79 * Default constructor.
80 *
81 * @param context the properties context to fetch information from the
82 * <code>META-INF</code> folder.
83 * @param propertyMethod the method to use to fetch annotations in case the
84 * context is not to be used.
85 */
86 public MetaInfDocumentMetaDataProxy(final PropertiesContext context,
87 final Method propertyMethod)
88 {
89 this.context = context;
90 this.propertyMethod = new SerializableMethod(propertyMethod);
91 }
92
93 // ****************************** Inner Classes *****************************
94
95 // ********************************* Methods ********************************
96
97 // --- init -----------------------------------------------------------------
98
99 // --- get&set --------------------------------------------------------------
100
101 // --- business -------------------------------------------------------------
102
103 /**
104 * Returns the document meta data.
105 *
106 * @param descriptor the descriptor of the property whose document meta data
107 * is requested.
108 * @param locale the locale to select the meta data in a specific language.
109 * @return the document meta data written for the given locale.
110 */
111 @Override
112 public DocumentMetaData getDocumentMetaData(
113 final PropertyDescriptor descriptor, final Locale locale)
114 {
115 DocumentMetaData metaData = this.metaData.get(locale);
116
117 if (metaData == null)
118 {
119 final Method propertyMethod = this.propertyMethod.getMethod();
120
121 if (propertyMethod == null)
122 {
123 throw new IllegalStateException(
124 "Cannot find documentation for method value 'null'.");
125 }
126
127 final Class<?> declaringType = propertyMethod.getDeclaringClass();
128
129 if (context != null)
130 {
131 final Defaults defaults = new PropertyMetaDataDefaults(propertyMethod);
132 final ProjectdocMetaDataParser parser =
133 new ProjectdocMetaDataParser(context, defaults);
134 metaData = parser.parse(descriptor, locale);
135 }
136
137 if (metaData == null)
138 {
139 final Defaults defaults =
140 new PropertyMetaDataDefaults(declaringType, propertyMethod);
141 final ProjectdocAnnotationCollector collector =
142 new ProjectdocAnnotationCollector(declaringType, defaults);
143
144 metaData = collector.createMetaDataFromAnnotations(propertyMethod);
145 this.metaData.put(locale, metaData);
146 }
147 }
148
149 return metaData;
150 }
151
152 // --- object basics --------------------------------------------------------
153
154 /**
155 * Returns the string representation of the object.
156 *
157 * @return the string representation of the object.
158 */
159 @Override
160 public String toString()
161 {
162 return ToStringBuilder.reflectionToString(this);
163 }
164 }