001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.geronimo.console.classloaderview;
018
019 import java.io.IOException;
020 import java.util.ArrayList;
021 import java.util.Iterator;
022 import java.util.Hashtable;
023 import java.util.List;
024 import java.util.Collections;
025
026 import org.apache.geronimo.console.BasePortlet;
027 import org.apache.geronimo.console.util.StringTree;
028
029 import javax.portlet.ActionRequest;
030 import javax.portlet.ActionResponse;
031 import javax.portlet.PortletConfig;
032 import javax.portlet.PortletException;
033 import javax.portlet.PortletRequestDispatcher;
034 import javax.portlet.RenderRequest;
035 import javax.portlet.RenderResponse;
036 import javax.portlet.WindowState;
037
038 import org.apache.geronimo.kernel.util.ClassLoaderRegistry;
039
040 public class ClassLoaderViewPortlet extends BasePortlet {
041
042 private static final String NORMALVIEW_JSP = "/WEB-INF/view/classloaderview/view.jsp";
043
044 private static final String MAXIMIZEDVIEW_JSP = "/WEB-INF/view/classloaderview/view.jsp";
045
046 private static final String HELPVIEW_JSP = "/WEB-INF/view/classloaderview/help.jsp";
047
048 private PortletRequestDispatcher normalView;
049
050 private PortletRequestDispatcher maximizedView;
051
052 private PortletRequestDispatcher helpView;
053
054 private boolean inverse;
055
056 public void processAction(ActionRequest actionRequest,
057 ActionResponse actionResponse) throws PortletException, IOException {
058 // set selectedNode
059 actionRequest.getPortletSession().setAttribute("selectedNode", actionRequest.getParameter("snNode"));
060 // toggle between inverse and non-inverse each time the form is processed
061 inverse = actionRequest.getParameter("inverse").equalsIgnoreCase("true")? true : false;
062 // toggle
063 inverse = (!inverse);
064 // store inverse variable for the jsp
065 actionRequest.getPortletSession().setAttribute("invert", inverse );
066 }
067
068 protected void doView(RenderRequest renderRequest,
069 RenderResponse renderResponse) throws IOException, PortletException {
070 if (WindowState.MINIMIZED.equals(renderRequest.getWindowState())) {
071 return;
072 }
073 renderRequest.getPortletSession().setAttribute("classloaderTree", this);
074 renderRequest.setAttribute("inverse", inverse);
075 renderRequest.getPortletSession().setAttribute("inverse", inverse);
076
077 if (WindowState.NORMAL.equals(renderRequest.getWindowState())) {
078 normalView.include(renderRequest, renderResponse);
079 } else {
080 maximizedView.include(renderRequest, renderResponse);
081 }
082 }
083
084 protected void doHelp(RenderRequest renderRequest,
085 RenderResponse renderResponse) throws PortletException, IOException {
086 helpView.include(renderRequest, renderResponse);
087 }
088
089 public void init(PortletConfig portletConfig) throws PortletException {
090 super.init(portletConfig);
091 normalView = portletConfig.getPortletContext().getRequestDispatcher(
092 NORMALVIEW_JSP);
093 maximizedView = portletConfig.getPortletContext().getRequestDispatcher(
094 MAXIMIZEDVIEW_JSP);
095 helpView = portletConfig.getPortletContext().getRequestDispatcher(
096 HELPVIEW_JSP);
097 inverse = false;
098 }
099
100 public void destroy() {
101 normalView = null;
102 maximizedView = null;
103 helpView = null;
104 super.destroy();
105 }
106
107 public String getJSONTrees(boolean inverse) {
108 List list = getTrees(inverse);
109 if (list == null)
110 return "[]";
111
112 StringBuffer stb = new StringBuffer();
113 stb.append("[");
114 Hashtable htLinks = new Hashtable();
115 // First level cannot be a link
116 for (int i = 0; i < list.size(); i++) {
117 StringTree node = (StringTree) list.get(i);
118 htLinks.put(node.name, ""+i);
119 }
120 for (int i = 0; i < list.size(); i++) {
121 StringTree node = (StringTree) list.get(i);
122 if (i != 0)
123 stb.append(",");
124 stb.append(node.toJSONObject("" + i, htLinks, true));
125 }
126 stb.append("]");
127 list = null;
128 return stb.toString();
129 }
130
131 public ArrayList getTrees(boolean inverse) {
132 ArrayList parentNodes = new ArrayList();
133 List list = ClassLoaderRegistry.getList();
134 Iterator iter = list.iterator();
135 while (iter.hasNext()) {
136 if(!inverse)
137 updateTree((ClassLoader) iter.next(), parentNodes);
138 else
139 inverseTree((ClassLoader) iter.next(), parentNodes);
140 }
141 Collections.sort(parentNodes);
142 return parentNodes;
143 }
144
145 public StringTree inverseTree(ClassLoader classloader, ArrayList parentNodes) {
146
147 StringTree node = new StringTree(classloader.toString());
148 int index = parentNodes.indexOf(node);
149 if(index != -1)
150 return (StringTree)parentNodes.get(index);
151
152 node = addClasses(node, classloader);
153
154 if (classloader instanceof org.apache.geronimo.kernel.config.MultiParentClassLoader) {
155 org.apache.geronimo.kernel.config.MultiParentClassLoader mpclassloader = (org.apache.geronimo.kernel.config.MultiParentClassLoader) classloader;
156 ClassLoader[] parents = mpclassloader.getParents();
157 if (parents != null)
158 for (int i = 0; i < parents.length; i++) {
159 StringTree parentNode = inverseTree(parents[i],parentNodes);
160 node.addChild(parentNode);
161 }
162 } else if (classloader.getParent() != null) {
163 StringTree parentNode = inverseTree(classloader.getParent(),parentNodes);
164 node.addChild(parentNode);
165 }
166 if(!parentNodes.contains(node))
167 parentNodes.add(node);
168
169 return node;
170 }
171
172 public StringTree updateTree(ClassLoader classloader, ArrayList parentNodes) {
173
174 Iterator iter = parentNodes.iterator();
175 StringTree node = null;
176 while (iter.hasNext()) {
177 StringTree currNode = (StringTree) iter.next();
178 node = currNode.findNode(classloader.toString());
179 if (node != null)
180 return node;
181 }
182
183 if (node == null) {
184 node = new StringTree(classloader.toString());
185 node = addClasses(node, classloader);
186
187 if (classloader instanceof org.apache.geronimo.kernel.config.MultiParentClassLoader) {
188 org.apache.geronimo.kernel.config.MultiParentClassLoader mpclassloader = (org.apache.geronimo.kernel.config.MultiParentClassLoader) classloader;
189 ClassLoader[] parents = mpclassloader.getParents();
190 if (parents == null)
191 parentNodes.add(node);
192 else if (parents.length == 0)
193 parentNodes.add(node);
194 else {
195 for (int i = 0; i < parents.length; i++) {
196 StringTree parentNode = updateTree(parents[i],
197 parentNodes);
198 parentNode.addChild(node);
199 }
200 }
201 } else if (classloader.getParent() != null) {
202 StringTree parentNode = updateTree(classloader.getParent(),
203 parentNodes);
204 parentNode.addChild(node);
205 } else
206 parentNodes.add(node);
207 }
208 return node;
209 }
210
211 private StringTree addClasses(StringTree node, ClassLoader loader) {
212 try {
213 java.lang.reflect.Field CLASSES_VECTOR_FIELD = ClassLoader.class
214 .getDeclaredField("classes");
215
216 if (CLASSES_VECTOR_FIELD.getType() != java.util.Vector.class) {
217 return node;
218 }
219 CLASSES_VECTOR_FIELD.setAccessible(true);
220
221 final java.util.Vector classes = (java.util.Vector) CLASSES_VECTOR_FIELD
222 .get(loader);
223 if (classes == null)
224 return node;
225
226 final Class[] result;
227
228 synchronized (classes) {
229 result = new Class[classes.size()];
230 classes.toArray(result);
231 }
232
233 CLASSES_VECTOR_FIELD.setAccessible(false);
234
235 StringTree classNames = new StringTree("Classes");
236 StringTree interfaceNames = new StringTree("Interfaces");
237 node.addChild(classNames);
238 node.addChild(interfaceNames);
239
240 for (int i = 0; i < result.length; i++) {
241 if (result[i].isInterface())
242 interfaceNames.addChild(result[i].toString());
243 else
244 classNames.addChild(result[i].toString());
245 }
246
247 return node;
248 } catch (Exception e) {
249 return node;
250 }
251 }
252
253 }