KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > innig > macker > structure > ClassManager


1 /*______________________________________________________________________________
2  *
3  * Macker http://innig.net/macker/
4  *
5  * Copyright 2002-2003 Paul Cantrell
6  *
7  * This program is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License version 2, as published by the
9  * Free Software Foundation. See the file LICENSE.html for more information.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY, including the implied warranty of MERCHANTABILITY or FITNESS
13  * FOR A PARTICULAR PURPOSE. See the license for more details.
14  *
15  * You should have received a copy of the GNU General Public License along with
16  * this program; if not, write to the Free Software Foundation, Inc. / 59 Temple
17  * Place, Suite 330 / Boston, MA 02111-1307 / USA.
18  *______________________________________________________________________________
19  */

20  
21 package net.innig.macker.structure;
22
23 import net.innig.macker.util.ClassNameTranslator;
24 import net.innig.macker.structure.ClassParseException;
25
26 import java.io.File JavaDoc;
27 import java.io.InputStream JavaDoc;
28 import java.io.IOException JavaDoc;
29 import java.util.*;
30
31 import net.innig.collect.*;
32
33 /**
34     The global collection of classes in Macker's rule-checking space.
35 */

36 public class ClassManager
37     {
38     public ClassManager()
39         {
40         // Trees make nice sorted output
41
allClasses = new TreeSet();
42         primaryClasses = new TreeSet();
43         classNameToInfo = new TreeMap();
44         references = new TreeMultiMap();
45         classLoader = Thread.currentThread().getContextClassLoader();
46         
47         for(Iterator i = PrimitiveTypeInfo.ALL.iterator(); i.hasNext(); )
48             replaceClass((ClassInfo) i.next());
49         }
50     
51     public ClassLoader JavaDoc getClassLoader()
52         { return classLoader; }
53     
54     public void setClassLoader(ClassLoader JavaDoc classLoader)
55         { this.classLoader = classLoader; }
56     
57     public ClassInfo readClass(File JavaDoc classFile)
58         throws ClassParseException, IOException JavaDoc
59         {
60         ClassInfo classInfo = new ParsedClassInfo(this, classFile);
61         addClass(classInfo);
62         return classInfo;
63         }
64     
65     public ClassInfo readClass(InputStream JavaDoc classFile)
66         throws ClassParseException, IOException JavaDoc
67         {
68         ClassInfo classInfo = new ParsedClassInfo(this, classFile);
69         addClass(classInfo);
70         return classInfo;
71         }
72     
73     private void addClass(ClassInfo classInfo)
74         {
75         ClassInfo existing = findClassInfo(classInfo.getFullName());
76         if(existing != null && !(existing instanceof HollowClassInfo))
77             throw new IllegalStateException JavaDoc(
78                 "ClassManager already contains a class named " + classInfo);
79         replaceClass(classInfo);
80         }
81     
82     private void replaceClass(ClassInfo classInfo)
83         {
84         allClasses.add(classInfo);
85         classNameToInfo.put(classInfo.getFullName(), classInfo);
86         }
87     
88     public void makePrimary(ClassInfo classInfo)
89         {
90         if(!classInfo.isComplete())
91             throw new IncompleteClassInfoException(
92                 classInfo + " cannot be a primary class, because the"
93                 + " class file isn't on Macker's classpath");
94         if(classInfo instanceof PrimitiveTypeInfo)
95             throw new IllegalArgumentException JavaDoc(
96                 classInfo + " cannot be a primary class, because it is a primitive type");
97         checkOwner(classInfo);
98         classInfo = findClassInfo(classInfo.getFullName()); // in case of hollow
99
primaryClasses.add(classInfo);
100         references.putAll(classInfo, classInfo.getReferences().keySet());
101         allClasses.addAll(classInfo.getReferences().keySet());
102         }
103     
104     public Set/*<ClassInfo>*/ getAllClasses()
105         { return Collections.unmodifiableSet(allClasses); }
106     
107     public Set/*<ClassInfo>*/ getPrimaryClasses()
108         { return Collections.unmodifiableSet(primaryClasses); }
109     
110     public MultiMap/*<ClassInfo,ClassInfo>*/ getReferences()
111         { return InnigCollections.unmodifiableMultiMap(references); }
112
113     public ClassInfo getClassInfo(String JavaDoc className)
114         {
115         ClassInfo classInfo = findClassInfo(className);
116         if(classInfo != null)
117             return classInfo;
118         else
119             {
120             classInfo = new HollowClassInfo(this, className);
121             replaceClass(classInfo);
122             return classInfo;
123             }
124         }
125     
126     ClassInfo loadClassInfo(String JavaDoc className)
127         {
128         ClassInfo classInfo = findClassInfo(className);
129         if(classInfo == null || classInfo instanceof HollowClassInfo)
130             {
131             classInfo = null; // don't use hollow!
132
String JavaDoc resourceName = ClassNameTranslator.classToResourceName(className);
133             InputStream JavaDoc classStream = classLoader.getResourceAsStream(resourceName);
134             
135             if(classStream == null)
136                 {
137                 showIncompleteWarning();
138                 System.out.println("WARNING: Unable to find class " + className + " in the classpath");
139                 }
140             else
141                 try {
142                     classInfo = new ParsedClassInfo(this, classStream);
143                     }
144                 catch(Exception JavaDoc e)
145                     {
146                     if(e instanceof RuntimeException JavaDoc)
147                         throw (RuntimeException JavaDoc) e;
148                     showIncompleteWarning();
149                     System.out.println("WARNING: Unable to load class " + className + ": " + e);
150                     }
151                 finally
152                     {
153                     try { classStream.close(); }
154                     catch(IOException JavaDoc ioe) { } // nothing we can do
155
}
156
157             if(classInfo == null)
158                 classInfo = new IncompleteClassInfo(this, className);
159             
160             replaceClass(classInfo);
161             }
162         
163         return classInfo;
164         }
165     
166     private ClassInfo findClassInfo(String JavaDoc className)
167         { return (ClassInfo) classNameToInfo.get(className); }
168     
169     private void checkOwner(ClassInfo classInfo)
170         throws IllegalStateException JavaDoc
171         {
172         if(classInfo.getClassManager() != this)
173             throw new IllegalStateException JavaDoc(
174                 "classInfo argument (" + classInfo + ") is not managed by this ClassManager");
175         }
176     
177     private void showIncompleteWarning()
178         {
179         if(!incompleteClassWarning)
180             {
181             incompleteClassWarning = true;
182             System.out.println(
183                 "WARNING: Macker is unable to load some of the external classes"
184                 + " used by the primary classes (see warnings below). Rules which"
185                 + " depend on attributes of these missing classes other than their"
186                 + " names will fail.");
187             }
188         }
189     
190     private boolean incompleteClassWarning;
191     private ClassLoader JavaDoc classLoader;
192     private Set allClasses, primaryClasses;
193     private Map/*<String,ClassInfo>*/ classNameToInfo;
194     private MultiMap/*<ClassInfo,ClassInfo>*/ references;
195     }
196
197
198
199
Popular Tags