KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > apisupport > project > universe > AbstractEntry


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.apisupport.project.universe;
21
22 import java.io.DataInput JavaDoc;
23 import java.io.DataInputStream JavaDoc;
24 import java.io.File JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.io.InputStream JavaDoc;
27 import java.util.ArrayList JavaDoc;
28 import java.util.Arrays JavaDoc;
29 import java.util.Collections JavaDoc;
30 import java.util.Enumeration JavaDoc;
31 import java.util.HashSet JavaDoc;
32 import java.util.Iterator JavaDoc;
33 import java.util.List JavaDoc;
34 import java.util.Set JavaDoc;
35 import java.util.StringTokenizer JavaDoc;
36 import java.util.jar.JarEntry JavaDoc;
37 import java.util.jar.JarFile JavaDoc;
38 import org.netbeans.modules.apisupport.project.ManifestManager;
39 import org.netbeans.modules.apisupport.project.Util;
40 import org.netbeans.spi.project.support.ant.PropertyUtils;
41 import org.openide.ErrorManager;
42
43 abstract class AbstractEntry implements ModuleEntry {
44     
45     private String JavaDoc localizedName;
46     private Set JavaDoc<String JavaDoc> publicClassNames;
47     
48     protected abstract LocalizedBundleInfo getBundleInfo();
49     
50     public String JavaDoc getLocalizedName() {
51         if (localizedName == null) {
52             localizedName = getBundleInfo().getDisplayName();
53             if (localizedName == null) {
54                 localizedName = getCodeNameBase();
55             }
56         }
57         return localizedName;
58     }
59     
60     public String JavaDoc getCategory() {
61         return getBundleInfo().getCategory();
62     }
63     
64     public String JavaDoc getShortDescription() {
65         return getBundleInfo().getShortDescription();
66     }
67     
68     public String JavaDoc getLongDescription() {
69         return getBundleInfo().getLongDescription();
70     }
71     
72     public int compareTo(Object JavaDoc o) {
73         int retval = getLocalizedName().compareTo(((ModuleEntry) o).getLocalizedName());
74         return (retval != 0) ? retval : getCodeNameBase().compareTo(((ModuleEntry) o).getCodeNameBase());
75     }
76     
77     public synchronized Set JavaDoc<String JavaDoc> getPublicClassNames() {
78         if (publicClassNames == null) {
79             try {
80                 publicClassNames = computePublicClassNamesInMainModule();
81                 String JavaDoc[] cpext = PropertyUtils.tokenizePath(getClassPathExtensions());
82                 for (int i = 0; i < cpext.length; i++) {
83                     File JavaDoc ext = new File JavaDoc(cpext[i]);
84                     if (!ext.isFile()) {
85                         Util.err.log(ErrorManager.WARNING, "Could not find Class-Path extension " + ext + " of " + this);
86                         continue;
87                     }
88                     scanJarForPublicClassNames(publicClassNames, ext);
89                 }
90             } catch (IOException JavaDoc e) {
91                 publicClassNames = Collections.EMPTY_SET;
92                 Util.err.annotate(e, ErrorManager.UNKNOWN, "While scanning for public classes in " + this, null, null, null); // NOI18N
93
Util.err.notify(ErrorManager.INFORMATIONAL, e);
94             }
95         }
96         return publicClassNames;
97     }
98     
99     protected final void scanJarForPublicClassNames(Set JavaDoc<String JavaDoc> result, File JavaDoc jar) throws IOException JavaDoc {
100         ManifestManager.PackageExport[] pkgs = getPublicPackages();
101         Set JavaDoc<String JavaDoc> publicPackagesSlashNonRec = new HashSet JavaDoc();
102         List JavaDoc<String JavaDoc> publicPackagesSlashRec = new ArrayList JavaDoc();
103         for (int i = 0; i < pkgs.length; i++) {
104             String JavaDoc name = pkgs[i].getPackage().replace('.', '/') + '/';
105             if (pkgs[i].isRecursive()) {
106                 publicPackagesSlashRec.add(name);
107             } else {
108                 publicPackagesSlashNonRec.add(name);
109             }
110         }
111         JarFile JavaDoc jf = new JarFile JavaDoc(jar);
112         try {
113             Enumeration JavaDoc entries = jf.entries();
114             ENTRY: while (entries.hasMoreElements()) {
115                 JarEntry JavaDoc entry = (JarEntry JavaDoc) entries.nextElement();
116                 String JavaDoc path = entry.getName();
117                 if (!path.endsWith(".class")) { // NOI18N
118
continue;
119                 }
120                 int slash = path.lastIndexOf('/');
121                 if (slash == -1) {
122                     continue;
123                 }
124                 String JavaDoc pkg = path.substring(0, slash + 1);
125                 if (!publicPackagesSlashNonRec.contains(pkg)) {
126                     boolean pub = false;
127                     Iterator JavaDoc it = publicPackagesSlashRec.iterator();
128                     while (it.hasNext()) {
129                         if (pkg.startsWith((String JavaDoc) it.next())) {
130                             pub = true;
131                             break;
132                         }
133                     }
134                     if (!pub) {
135                         continue;
136                     }
137                 }
138                 StringTokenizer JavaDoc tok = new StringTokenizer JavaDoc(path, "$"); // NOI18N
139
while (tok.hasMoreTokens()) {
140                     String JavaDoc component = tok.nextToken();
141                     char c = component.charAt(0);
142                     if (c >= '0' && c <= '9') {
143                         // Generated anon inner class name, skip.
144
continue ENTRY;
145                     }
146                 }
147                 if (!isPublic(jf, entry)) {
148                     continue;
149                 }
150                 result.add(path.substring(0, path.length() - 6).replace('/', '.'));
151             }
152         } finally {
153             jf.close();
154         }
155     }
156     
157     protected abstract Set JavaDoc<String JavaDoc> computePublicClassNamesInMainModule() throws IOException JavaDoc;
158     
159     // XXX consider inheritance refactoring instead.
160
/**
161      * Just a convenient methods. <code>null</code> may be passed as a
162      * <cdoe>friends</code>.
163      */

164     protected static boolean isDeclaredAsFriend(String JavaDoc[] friends, String JavaDoc cnb) {
165         return friends == null ? true : Arrays.binarySearch(friends, cnb) >= 0;
166     }
167
168     /** Checks whether a .class file is marked as public or not. */
169     private static boolean isPublic(JarFile JavaDoc jf, JarEntry JavaDoc entry) throws IOException JavaDoc {
170         InputStream JavaDoc is = jf.getInputStream(entry);
171         try {
172             DataInput JavaDoc input = new DataInputStream JavaDoc(is);
173             skip(input, 8); // magic, minor_version, major_version
174
// Have to partially parse constant pool to skip over it:
175
int size = input.readUnsignedShort() - 1; // constantPoolCount
176
for (int i = 0; i < size; i++) {
177                 byte tag = input.readByte();
178                 switch (tag) {
179                     case 1: // CONSTANT_Utf8
180
input.readUTF();
181                         break;
182                     case 3: // CONSTANT_Integer
183
case 4: // CONSTANT_Float
184
case 9: // CONSTANT_Fieldref
185
case 10: // CONSTANT_Methodref
186
case 11: // CONSTANT_InterfaceMethodref
187
case 12: // CONSTANT_NameAndType
188
skip(input, 4);
189                         break;
190                     case 7: // CONSTANT_Class
191
case 8: // CONSTANT_String
192
skip(input, 2);
193                         break;
194                     case 5: // CONSTANT_Long
195
case 6: // CONSTANT_Double
196
skip(input, 8);
197                         i++; // weirdness in spec
198
break;
199                     default:
200                         throw new IOException JavaDoc("Unrecognized constant pool tag " + tag + " at index " + i); // NOI18N
201
}
202             }
203             int accessFlags = input.readUnsignedShort();
204             return (accessFlags & 0x0001) > 0;
205         } finally {
206             is.close();
207         }
208     }
209     private static void skip(DataInput JavaDoc input, int bytes) throws IOException JavaDoc {
210         int skipped = input.skipBytes(bytes);
211         if (skipped != bytes) {
212             throw new IOException JavaDoc();
213         }
214     }
215     
216 }
217
Popular Tags