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