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