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