001
014
015 package com.liferay.portal.javadoc;
016
017 import com.liferay.portal.kernel.javadoc.BaseJavadoc;
018 import com.liferay.portal.kernel.javadoc.JavadocClass;
019 import com.liferay.portal.kernel.javadoc.JavadocManager;
020 import com.liferay.portal.kernel.javadoc.JavadocMethod;
021 import com.liferay.portal.kernel.log.Log;
022 import com.liferay.portal.kernel.log.LogFactoryUtil;
023 import com.liferay.portal.kernel.util.StreamUtil;
024 import com.liferay.portal.kernel.util.StringUtil;
025 import com.liferay.portal.kernel.xml.Document;
026 import com.liferay.portal.kernel.xml.Element;
027 import com.liferay.portal.kernel.xml.SAXReaderUtil;
028
029 import java.io.InputStream;
030
031 import java.lang.reflect.Method;
032
033 import java.net.URL;
034
035 import java.util.Collection;
036 import java.util.HashMap;
037 import java.util.Iterator;
038 import java.util.List;
039 import java.util.Map;
040
041
044 public class JavadocManagerImpl implements JavadocManager {
045
046 public void load(String servletContextName, ClassLoader classLoader) {
047 if (_log.isInfoEnabled()) {
048 _log.info("Loading Javadocs for \"" + servletContextName + '\"');
049 }
050
051 Document document = getDocument(classLoader);
052
053 if (document == null) {
054 return;
055 }
056
057 parseDocument(servletContextName, classLoader, document);
058
059 if (_log.isInfoEnabled()) {
060 _log.info("Loaded Javadocs for \"" + servletContextName + '\"');
061 }
062 }
063
064 public JavadocMethod lookupJavadocMethod(Method method) {
065 JavadocMethod javadocMethod = _javadocMethods.get(method);
066
067 if (javadocMethod != null) {
068 return javadocMethod;
069 }
070
071 Class<?> clazz = method.getDeclaringClass();
072
073 String className = clazz.getName();
074
075 if (!className.contains(".service.") ||
076 !className.endsWith("ServiceUtil")) {
077
078 return null;
079 }
080
081 String implClassName = StringUtil.replace(
082 className, new String[] {".service.", "ServiceUtil"},
083 new String[] {".service.impl.", "ServiceImpl"});
084
085 if (_log.isDebugEnabled()) {
086 _log.debug(
087 "Attempting to load method from class " + implClassName +
088 " instead of " + className);
089 }
090
091 try {
092 Class<?> implClass = JavadocUtil.loadClass(
093 clazz.getClassLoader(), implClassName);
094
095 Method implMethod = implClass.getMethod(
096 method.getName(), method.getParameterTypes());
097
098 return _javadocMethods.get(implMethod);
099 }
100 catch (NoSuchMethodException nsme) {
101 if (_log.isWarnEnabled()) {
102 _log.warn(
103 "Unable to load method " + method.getName() +
104 " from class " + implClassName);
105 }
106 }
107 catch (Exception e) {
108 if (_log.isWarnEnabled()) {
109 _log.warn(
110 "Unable to load implementation class " + implClassName);
111 }
112 }
113
114 return null;
115 }
116
117 public void unload(String servletContextName) {
118 if (_log.isInfoEnabled()) {
119 _log.info("Unloading Javadocs for \"" + servletContextName + '\"');
120 }
121
122 unload(servletContextName, _javadocClasses.values());
123 unload(servletContextName, _javadocMethods.values());
124
125 if (_log.isInfoEnabled()) {
126 _log.info("Unloaded Javadocs for \"" + servletContextName + '\"');
127 }
128 }
129
130 protected Document getDocument(ClassLoader classLoader) {
131 InputStream inputStream = null;
132
133 try {
134 URL url = classLoader.getResource("META-INF/javadocs.xml");
135
136 if (url == null) {
137 return null;
138 }
139
140 inputStream = url.openStream();
141
142 return SAXReaderUtil.read(inputStream, true);
143 }
144 catch (Exception e) {
145 _log.error(e, e);
146 }
147 finally {
148 StreamUtil.cleanUp(inputStream);
149 }
150
151 return null;
152 }
153
154 protected void parseDocument(
155 String servletContextName, ClassLoader classLoader, Document document) {
156
157 Element rootElement = document.getRootElement();
158
159 List<Element> javadocElements = rootElement.elements("javadoc");
160
161 for (Element javadocElement : javadocElements) {
162 String type = javadocElement.elementText("type");
163
164 Class<?> clazz = null;
165
166 try {
167 clazz = JavadocUtil.loadClass(classLoader, type);
168 }
169 catch (ClassNotFoundException cnfe) {
170 if (_log.isWarnEnabled()) {
171 _log.warn("Unable to load class " + type);
172 }
173
174 continue;
175 }
176
177 JavadocClass javadocClass = parseJavadocClass(
178 servletContextName, javadocElement, clazz);
179
180 _javadocClasses.put(clazz, javadocClass);
181
182 List<Element> methodElements = javadocElement.elements("method");
183
184 for (Element methodElement : methodElements) {
185 try {
186 JavadocMethod javadocMethod = parseJavadocMethod(
187 servletContextName, clazz, methodElement);
188
189 _javadocMethods.put(
190 javadocMethod.getMethod(), javadocMethod);
191 }
192 catch (Exception e) {
193 String methodName = methodElement.elementText("name");
194
195 if (_log.isWarnEnabled()) {
196 _log.warn(
197 "Unable to load method " + methodName +
198 " from class " + type);
199 }
200 }
201 }
202 }
203 }
204
205 protected JavadocClass parseJavadocClass(
206 String servletContextName, Element javadocElement, Class<?> clazz) {
207
208 JavadocClass javadocClass = new JavadocClass(clazz);
209
210 List<Element> authorElements = javadocElement.elements("author");
211
212 String[] authors = new String[authorElements.size()];
213
214 for (int i = 0; i < authorElements.size(); i++) {
215 Element authorElement = authorElements.get(i);
216
217 authors[i] = authorElement.getText();
218 }
219
220 javadocClass.setAuthors(authors);
221
222 String comment = javadocElement.elementText("comment");
223
224 javadocClass.setComment(comment);
225
226 javadocClass.setServletContextName(servletContextName);
227
228 return javadocClass;
229 }
230
231 protected JavadocMethod parseJavadocMethod(
232 String servletContextName, Class<?> clazz, Element methodElement)
233 throws Exception {
234
235 String name = methodElement.elementText("name");
236
237 List<Element> paramElements = methodElement.elements("param");
238
239 Class<?>[] parameterTypeClasses = new Class<?>[paramElements.size()];
240 String[] parameterComments = new String[paramElements.size()];
241
242 for (int i = 0; i < paramElements.size(); i++) {
243 Element paramElement = paramElements.get(i);
244
245 String parameterType = paramElement.elementText("type");
246
247 Class<?> parametarTypeClass = JavadocUtil.loadClass(
248 clazz.getClassLoader(), parameterType);
249
250 parameterTypeClasses[i] = parametarTypeClass;
251
252 String parameterComment = paramElement.elementText("comment");
253
254 parameterComments[i] = parameterComment;
255 }
256
257 Method method = clazz.getDeclaredMethod(name, parameterTypeClasses);
258
259 JavadocMethod javadocMethod = new JavadocMethod(method);
260
261 String comment = methodElement.elementText("comment");
262
263 javadocMethod.setComment(comment);
264
265 javadocMethod.setParameterComments(parameterComments);
266
267 Element returnElement = methodElement.element("return");
268
269 if (returnElement != null) {
270 String returnComment = returnElement.elementText("comment");
271
272 javadocMethod.setReturnComment(returnComment);
273 }
274
275 javadocMethod.setServletContextName(servletContextName);
276
277 List<Element> throwsElements = methodElement.elements("throws");
278
279 String[] throwsComments = new String[throwsElements.size()];
280
281 for (int i = 0; i < throwsElements.size(); i++) {
282 Element throwElement = throwsElements.get(i);
283
284 throwsComments[i] = throwElement.elementText("comment");
285 }
286
287 javadocMethod.setThrowsComments(throwsComments);
288
289 return javadocMethod;
290 }
291
292 protected void unload(
293 String servletContextName,
294 Collection<? extends BaseJavadoc> collection) {
295
296 Iterator<? extends BaseJavadoc> iterator = collection.iterator();
297
298 while (iterator.hasNext()) {
299 BaseJavadoc javadoc = iterator.next();
300
301 if (servletContextName.equals(javadoc.getServletContextName())) {
302 iterator.remove();
303 }
304 }
305 }
306
307 private static Log _log = LogFactoryUtil.getLog(JavadocManager.class);
308
309 private Map<Class<?>, JavadocClass> _javadocClasses =
310 new HashMap<Class<?>, JavadocClass>();
311 private Map<Method, JavadocMethod> _javadocMethods =
312 new HashMap<Method, JavadocMethod>();
313
314 }