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