KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > osgi > framework > stats > ClassloaderStats


1 /*******************************************************************************
2  * Copyright (c) 2000, 2004 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.osgi.framework.stats;
12
13 import java.io.*;
14 import java.util.*;
15
16 /**
17  * Contains information about the classes and the bundles loaded by a given classloader. Typically there is one classloader per plugin so at levels above boot, this equates to information about
18  * classes and bundles in a plugin.
19  */

20 public class ClassloaderStats {
21     private String JavaDoc id;
22     private long loadingTime; // time spent loading classes
23
private int failureCount = 0; // number of classes requested but that we fail to provide
24
/**
25      * classes loaded by the plugin (key: class name, value: ClassStats)
26      */

27     private Map classes = Collections.synchronizedMap(new HashMap(20));
28     private ArrayList bundles = new ArrayList(2); // bundles loaded
29

30     private boolean keepTraces = false; // indicate whether or not the traces of classes loaded are kept
31

32     // filters to indicate which classes we want to keep the traces
33
private static ArrayList packageFilters = new ArrayList(4); // filters on a package basis
34
private static Set pluginFilters = new HashSet(5); // filters on a plugin basis
35

36     private static Stack classStack = new Stack(); // represents the classes that are currently being loaded
37
/**
38      * a dictionary of the classloaderStats (key: pluginId, value: ClassloaderStats)
39      */

40     private static Map loaders = Collections.synchronizedMap(new HashMap(20));
41     public static File traceFile;
42
43     static {
44         if (StatsManager.TRACE_CLASSES || StatsManager.TRACE_BUNDLES)
45             initializeTraceOptions();
46     }
47
48     private static void initializeTraceOptions() {
49         // create the trace file
50
String JavaDoc filename = StatsManager.TRACE_FILENAME;
51         traceFile = new File(filename);
52         traceFile.delete();
53
54         //load the filters
55
if (!StatsManager.TRACE_CLASSES)
56             return;
57         filename = StatsManager.TRACE_FILTERS;
58         if (filename == null || filename.length() == 0)
59             return;
60         try {
61             File filterFile = new File(filename);
62             System.out.print("Runtime tracing elements defined in: " + filterFile.getAbsolutePath() + "..."); //$NON-NLS-1$ //$NON-NLS-2$
63
InputStream input = new FileInputStream(filterFile);
64             System.out.println(" Loaded."); //$NON-NLS-1$
65
Properties filters = new Properties() {
66                 public Object JavaDoc put(Object JavaDoc key, Object JavaDoc value) {
67                     addFilters((String JavaDoc) key, (String JavaDoc) value);
68                     return null;
69                 }
70             };
71             try {
72                 filters.load(input);
73             } finally {
74                 input.close();
75             }
76         } catch (IOException e) {
77             System.out.println(" No trace filters loaded."); //$NON-NLS-1$
78
}
79     }
80
81     protected static void addFilters(String JavaDoc key, String JavaDoc value) {
82         String JavaDoc[] filters = StatsManager.getArrayFromList(value);
83         if ("plugins".equals(key)) //$NON-NLS-1$
84
pluginFilters.addAll(Arrays.asList(filters));
85         if ("packages".equals(key)) //$NON-NLS-1$
86
packageFilters.addAll(Arrays.asList(filters));
87     }
88
89     public static void startLoadingClass(String JavaDoc id, String JavaDoc className) {
90         findLoader(id).startLoadClass(className);
91     }
92
93     // get and create if does not exist
94
private static ClassloaderStats findLoader(String JavaDoc id) {
95         synchronized (loaders) {
96             ClassloaderStats result = (ClassloaderStats) loaders.get(id);
97             if (result == null) {
98                 result = new ClassloaderStats(id);
99                 loaders.put(id, result);
100             }
101             return result;
102         }
103     }
104
105     public static Stack getClassStack() {
106         return classStack;
107     }
108
109     public static ClassloaderStats[] getLoaders() {
110         //the parameter to toArray is of size zero for thread safety, otherwise this
111
//could return an array with null entries if the map shrinks concurrently
112
return (ClassloaderStats[]) loaders.values().toArray(new ClassloaderStats[0]);
113     }
114
115     public static void endLoadingClass(String JavaDoc id, String JavaDoc className, boolean success) {
116         findLoader(id).endLoadClass(className, success);
117     }
118
119     public static void loadedBundle(String JavaDoc id, ResourceBundleStats info) {
120         findLoader(id).loadedBundle(info);
121     }
122
123     public static ClassloaderStats getLoader(String JavaDoc id) {
124         return (ClassloaderStats) loaders.get(id);
125     }
126
127     public ClassloaderStats(String JavaDoc id) {
128         this.id = id;
129         keepTraces = pluginFilters.contains(id);
130     }
131
132     public void addBaseClasses(String JavaDoc[] baseClasses) {
133         for (int i = 0; i < baseClasses.length; i++) {
134             String JavaDoc name = baseClasses[i];
135             if (classes.get(name) == null) {
136                 ClassStats value = new ClassStats(name, this);
137                 value.toBaseClass();
138                 classes.put(name, value);
139             }
140         }
141     }
142
143     private void loadedBundle(ResourceBundleStats bundle) {
144         bundles.add(bundle);
145     }
146
147     public ArrayList getBundles() {
148         return bundles;
149     }
150
151     private synchronized void startLoadClass(String JavaDoc name) {
152         classStack.push(findClass(name));
153     }
154
155     // internal method that return the existing classStats or creates one
156
private ClassStats findClass(String JavaDoc name) {
157         ClassStats result = (ClassStats) classes.get(name);
158         return result == null ? new ClassStats(name, this) : result;
159     }
160
161     private synchronized void endLoadClass(String JavaDoc name, boolean success) {
162         ClassStats current = (ClassStats) classStack.pop();
163         if (!success) {
164             failureCount++;
165             return;
166         }
167         if (current.getLoadOrder() >= 0)
168             return;
169
170         classes.put(name, current);
171         current.setLoadOrder(classes.size());
172         current.loadingDone();
173         traceLoad(name, current);
174
175         // is there something on the load stack. if so, link them together...
176
if (classStack.size() != 0) {
177             // get the time spent loading cli and subtract its load time from the class that requires loading
178
ClassStats previous = ((ClassStats) classStack.peek());
179             previous.addTimeLoadingOthers(current.getTimeLoading());
180             current.setLoadedBy(previous);
181             previous.loaded(current);
182         } else {
183             loadingTime = loadingTime + current.getTimeLoading();
184         }
185     }
186
187     private void traceLoad(String JavaDoc name, ClassStats target) {
188         // Stack trace code
189
if (!keepTraces) {
190             boolean found = false;
191             for (int i = 0; !found && i < packageFilters.size(); i++)
192                 if (name.startsWith((String JavaDoc) packageFilters.get(i)))
193                     found = true;
194             if (!found)
195                 return;
196         }
197
198         // Write the stack trace. The position in the file are set to the corresponding classStat object
199
try {
200             target.setTraceStart(traceFile.length());
201             PrintWriter output = new PrintWriter(new FileOutputStream(traceFile.getAbsolutePath(), true));
202             try {
203                 output.println("Loading class: " + name); //$NON-NLS-1$
204
output.println("Class loading stack:"); //$NON-NLS-1$
205
output.println("\t" + name); //$NON-NLS-1$
206
for (int i = classStack.size() - 1; i >= 0; i--)
207                     output.println("\t" + ((ClassStats) classStack.get(i)).getClassName()); //$NON-NLS-1$
208
output.println("Stack trace:"); //$NON-NLS-1$
209
new Throwable JavaDoc().printStackTrace(output);
210             } finally {
211                 output.close();
212             }
213             target.setTraceEnd(traceFile.length());
214         } catch (FileNotFoundException e) {
215             e.printStackTrace();
216         }
217     }
218
219     public int getClassLoadCount() {
220         return classes.size();
221     }
222
223     public long getClassLoadTime() {
224         return loadingTime;
225     }
226
227     public ClassStats[] getClasses() {
228         //the parameter to toArray is of size zero for thread safety, otherwise this
229
//could return an array with null entries if the map shrinks concurrently
230
return (ClassStats[]) classes.values().toArray(new ClassStats[0]);
231     }
232
233     public String JavaDoc getId() {
234         return id;
235     }
236 }
Popular Tags