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