KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > apisupport > project > ManifestManager


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;
21
22 import java.io.File JavaDoc;
23 import java.io.FileInputStream JavaDoc;
24 import java.io.IOException JavaDoc;
25 import java.io.InputStream JavaDoc;
26 import java.util.ArrayList JavaDoc;
27 import java.util.Collections JavaDoc;
28 import java.util.HashSet JavaDoc;
29 import java.util.List JavaDoc;
30 import java.util.Set JavaDoc;
31 import java.util.StringTokenizer JavaDoc;
32 import java.util.jar.Attributes JavaDoc;
33 import java.util.jar.JarFile JavaDoc;
34 import java.util.jar.Manifest JavaDoc;
35 import org.openide.ErrorManager;
36 import org.openide.filesystems.FileObject;
37 import org.openide.modules.Dependency;
38 import org.openide.util.Exceptions;
39
40 // XXX a lot of code in this method is more or less duplicated from
41
// org.netbeans.core.modules.Module class. Do not forgot to refactor this as
42
// soon as there is some kind of API (public packages, friends, ...)
43

44 /**
45  * TODO - Comment whole code!
46  *
47  * @author Martin Krauskopf
48  */

49 public final class ManifestManager {
50     
51     private String JavaDoc codeNameBase;
52     private String JavaDoc releaseVersion;
53     private String JavaDoc specificationVersion;
54     private String JavaDoc implementationVersion;
55     private String JavaDoc[] provTokens;
56     private String JavaDoc provTokensString;
57     private String JavaDoc[] requiredTokens;
58     private String JavaDoc[] neededTokens;
59     private String JavaDoc localizingBundle;
60     private String JavaDoc layer;
61     private String JavaDoc classPath;
62     private PackageExport[] publicPackages;
63     private String JavaDoc[] friendNames;
64     private String JavaDoc moduleDependencies;
65     private boolean deprecated;
66     
67     public static final String JavaDoc OPENIDE_MODULE = "OpenIDE-Module"; // NOI18N
68
public static final String JavaDoc OPENIDE_MODULE_SPECIFICATION_VERSION = "OpenIDE-Module-Specification-Version"; // NOI18N
69
public static final String JavaDoc OPENIDE_MODULE_IMPLEMENTATION_VERSION = "OpenIDE-Module-Implementation-Version"; // NOI18N
70
public static final String JavaDoc OPENIDE_MODULE_PROVIDES = "OpenIDE-Module-Provides"; // NOI18N
71
public static final String JavaDoc OPENIDE_MODULE_REQUIRES = "OpenIDE-Module-Requires"; // NOI18N
72
public static final String JavaDoc OPENIDE_MODULE_NEEDS = "OpenIDE-Module-Needs"; // NOI18N
73
public static final String JavaDoc OPENIDE_MODULE_LAYER = "OpenIDE-Module-Layer"; // NOI18N
74
public static final String JavaDoc OPENIDE_MODULE_LOCALIZING_BUNDLE = "OpenIDE-Module-Localizing-Bundle"; // NOI18N
75
public static final String JavaDoc OPENIDE_MODULE_PUBLIC_PACKAGES = "OpenIDE-Module-Public-Packages"; // NOI18N
76
public static final String JavaDoc OPENIDE_MODULE_FRIENDS = "OpenIDE-Module-Friends"; // NOI18N
77
public static final String JavaDoc OPENIDE_MODULE_MODULE_DEPENDENCIES = "OpenIDE-Module-Module-Dependencies"; // NOI18N
78
public static final String JavaDoc CLASS_PATH = "Class-Path"; // NOI18N
79

80     static final PackageExport[] EMPTY_EXPORTED_PACKAGES = new PackageExport[0];
81     
82     public static final ManifestManager NULL_INSTANCE = new ManifestManager();
83     
84     private ManifestManager() {
85         this.provTokens = new String JavaDoc[0];
86         this.requiredTokens = new String JavaDoc[0];
87         this.neededTokens = new String JavaDoc[0];
88     }
89     
90     private ManifestManager(String JavaDoc cnb, String JavaDoc releaseVersion, String JavaDoc specVer,
91             String JavaDoc implVer, String JavaDoc provTokensString, String JavaDoc requiredTokens, String JavaDoc neededTokens,
92             String JavaDoc locBundle, String JavaDoc layer, String JavaDoc classPath,
93             PackageExport[] publicPackages, String JavaDoc[] friendNames,
94             boolean deprecated, String JavaDoc moduleDependencies) {
95         this.codeNameBase = cnb;
96         this.releaseVersion = releaseVersion;
97         this.specificationVersion = specVer;
98         this.implementationVersion = implVer;
99         this.provTokensString = provTokensString;
100         this.provTokens = parseTokens(provTokensString); // XXX could be lazy-loaded
101
this.requiredTokens = parseTokens(requiredTokens); // XXX could be lazy-loaded
102
this.neededTokens = parseTokens(neededTokens); // XXX could be lazy-loaded
103
this.localizingBundle = locBundle;
104         this.layer = layer;
105         this.classPath = classPath;
106         this.publicPackages = (publicPackages == null)
107                 ? EMPTY_EXPORTED_PACKAGES : publicPackages;
108         this.friendNames = friendNames;
109         this.deprecated = deprecated;
110         this.moduleDependencies = moduleDependencies;
111     }
112     
113     private String JavaDoc[] parseTokens(String JavaDoc tokens) {
114         if (tokens == null) {
115             return new String JavaDoc[0];
116         }
117         StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(tokens, ","); // NOI18N
118
String JavaDoc[] result = new String JavaDoc[st.countTokens()];
119         for (int i = 0; i < result.length; i++) {
120             result[i] = st.nextToken().trim();
121         }
122         return result;
123     }
124     
125     public static ManifestManager getInstance(File JavaDoc manifest, boolean loadPublicPackages) {
126         if (manifest.exists()) {
127             try {
128                 InputStream JavaDoc mis = new FileInputStream JavaDoc(manifest); // NOI18N
129
try {
130                     Manifest JavaDoc mf = new Manifest JavaDoc(mis);
131                     return ManifestManager.getInstance(mf, loadPublicPackages);
132                 } finally {
133                     mis.close();;
134                 }
135             } catch (IOException JavaDoc x) {
136                 Exceptions.attachMessage(x, "While opening: " + manifest);
137                 Exceptions.printStackTrace(x);
138             }
139         }
140         return NULL_INSTANCE;
141     }
142     
143     public static ManifestManager getInstanceFromJAR(File JavaDoc jar) {
144         try {
145             if (!jar.isFile()) {
146                 throw new IOException JavaDoc("No such JAR: " + jar); // NOI18N
147
}
148             JarFile JavaDoc jf = new JarFile JavaDoc(jar, false);
149             try {
150                 Manifest JavaDoc m = jf.getManifest();
151                 if (m == null) { // #87064
152
throw new IOException JavaDoc("No manifest in " + jar); // NOI18N
153
}
154                 return ManifestManager.getInstance(m, true);
155             } finally {
156                 jf.close();
157             }
158         } catch (IOException JavaDoc e) {
159             Util.err.notify(ErrorManager.INFORMATIONAL, e);
160             return NULL_INSTANCE;
161         }
162     }
163     
164     public static ManifestManager getInstance(Manifest JavaDoc manifest, boolean loadPublicPackages) {
165         Attributes JavaDoc attr = manifest.getMainAttributes();
166         String JavaDoc codename = attr.getValue(OPENIDE_MODULE);
167         String JavaDoc codenamebase = null;
168         String JavaDoc releaseVersion = null;
169         if (codename != null) {
170             int slash = codename.lastIndexOf('/');
171             if (slash == -1) {
172                 codenamebase = codename;
173             } else {
174                 codenamebase = codename.substring(0, slash);
175                 releaseVersion = codename.substring(slash + 1);
176             }
177         }
178         PackageExport[] publicPackages = null;
179         String JavaDoc[] friendNames = null;
180         if (loadPublicPackages) {
181             publicPackages = EMPTY_EXPORTED_PACKAGES;
182             String JavaDoc pp = attr.getValue(OPENIDE_MODULE_PUBLIC_PACKAGES);
183             if (pp != null) {
184                 publicPackages = parseExportedPackages(pp);
185             }
186             String JavaDoc friends = attr.getValue(OPENIDE_MODULE_FRIENDS);
187             if (friends != null) {
188                 friendNames = parseFriends(friends);
189                 if (friendNames.length > 0 && publicPackages.length == 0) {
190                     throw new IllegalArgumentException JavaDoc("No use specifying OpenIDE-Module-Friends without any public packages: " + friends); // NOI18N
191
}
192             }
193         }
194         boolean deprecated = "true".equals(attr.getValue("OpenIDE-Module-Deprecated")); // NOI18N
195
return new ManifestManager(
196                 codenamebase, releaseVersion,
197                 attr.getValue(OPENIDE_MODULE_SPECIFICATION_VERSION),
198                 attr.getValue(OPENIDE_MODULE_IMPLEMENTATION_VERSION),
199                 attr.getValue(OPENIDE_MODULE_PROVIDES),
200                 attr.getValue(OPENIDE_MODULE_REQUIRES),
201                 attr.getValue(OPENIDE_MODULE_NEEDS),
202                 attr.getValue(OPENIDE_MODULE_LOCALIZING_BUNDLE),
203                 attr.getValue(OPENIDE_MODULE_LAYER),
204                 attr.getValue(CLASS_PATH),
205                 publicPackages,
206                 friendNames,
207                 deprecated,
208                 attr.getValue(OPENIDE_MODULE_MODULE_DEPENDENCIES));
209     }
210     
211     /**
212      * Generates module manifest with the given values into the given
213      * <code>manifest</code>.
214      */

215     static void createManifest(FileObject manifest, String JavaDoc cnb, String JavaDoc specVer,
216             String JavaDoc bundlePath, String JavaDoc layerPath) throws IOException JavaDoc {
217         EditableManifest em = new EditableManifest();
218         em.setAttribute(OPENIDE_MODULE, cnb, null);
219         em.setAttribute(OPENIDE_MODULE_SPECIFICATION_VERSION, specVer, null);
220         em.setAttribute(OPENIDE_MODULE_LOCALIZING_BUNDLE, bundlePath, null);
221         if (layerPath != null) {
222             em.setAttribute(OPENIDE_MODULE_LAYER, layerPath, null);
223         }
224         Util.storeManifest(manifest, em);
225     }
226     
227     private static PackageExport[] parseExportedPackages(final String JavaDoc exportsS) {
228         PackageExport[] exportedPackages = null;
229         if (exportsS.trim().equals("-")) { // NOI18N
230
exportedPackages = EMPTY_EXPORTED_PACKAGES;
231         } else {
232             StringTokenizer JavaDoc tok = new StringTokenizer JavaDoc(exportsS, ", "); // NOI18N
233
List JavaDoc exports = new ArrayList JavaDoc(Math.max(tok.countTokens(), 1)); // List<PackageExport>
234
while (tok.hasMoreTokens()) {
235                 String JavaDoc piece = tok.nextToken();
236                 if (piece.endsWith(".*")) { // NOI18N
237
String JavaDoc pkg = piece.substring(0, piece.length() - 2);
238                     Dependency.create(Dependency.TYPE_MODULE, pkg);
239                     if (pkg.lastIndexOf('/') != -1) {
240                         throw new IllegalArgumentException JavaDoc("Illegal OpenIDE-Module-Public-Packages: " + exportsS); // NOI18N
241
}
242                     exports.add(new PackageExport(pkg, false));
243                 } else if (piece.endsWith(".**")) { // NOI18N
244
String JavaDoc pkg = piece.substring(0, piece.length() - 3);
245                     Dependency.create(Dependency.TYPE_MODULE, pkg);
246                     if (pkg.lastIndexOf('/') != -1) {
247                         throw new IllegalArgumentException JavaDoc("Illegal OpenIDE-Module-Public-Packages: " + exportsS); // NOI18N
248
}
249                     exports.add(new PackageExport(pkg, true));
250                 } else {
251                     throw new IllegalArgumentException JavaDoc("Illegal OpenIDE-Module-Public-Packages: " + exportsS); // NOI18N
252
}
253             }
254             if (exports.isEmpty()) {
255                 throw new IllegalArgumentException JavaDoc("Illegal OpenIDE-Module-Public-Packages: " + exportsS); // NOI18N
256
}
257             exportedPackages = (PackageExport[])exports.toArray(new PackageExport[exports.size()]);
258         }
259         return exportedPackages;
260     }
261     
262     private static String JavaDoc[] parseFriends(final String JavaDoc friends) {
263         Set JavaDoc set = new HashSet JavaDoc();
264         StringTokenizer JavaDoc tok = new StringTokenizer JavaDoc(friends, ", "); // NOI18N
265
while (tok.hasMoreTokens()) {
266             String JavaDoc piece = tok.nextToken();
267             if (piece.indexOf('/') != -1) {
268                 throw new IllegalArgumentException JavaDoc("May specify only module code name bases in OpenIDE-Module-Friends, not major release versions: " + piece); // NOI18N
269
}
270             // Indirect way of checking syntax:
271
Dependency.create(Dependency.TYPE_MODULE, piece);
272             // OK, add it.
273
set.add(piece);
274         }
275         if (set.isEmpty()) {
276             throw new IllegalArgumentException JavaDoc("Empty OpenIDE-Module-Friends: " + friends); // NOI18N
277
}
278         return (String JavaDoc[]) set.toArray(new String JavaDoc[set.size()]);
279     }
280     
281     public String JavaDoc getCodeNameBase() {
282         return codeNameBase;
283     }
284     
285     public String JavaDoc getReleaseVersion() {
286         return releaseVersion;
287     }
288     
289     public String JavaDoc getSpecificationVersion() {
290         return specificationVersion;
291     }
292     
293     public String JavaDoc getImplementationVersion() {
294         return implementationVersion;
295     }
296     
297     public String JavaDoc getProvidedTokensString() {
298         return provTokensString;
299     }
300     
301     public String JavaDoc[] getProvidedTokens() {
302         return provTokens;
303     }
304     
305     public String JavaDoc[] getRequiredTokens() {
306         return requiredTokens;
307     }
308     
309     public String JavaDoc[] getNeededTokens() {
310         return neededTokens;
311     }
312     
313     public String JavaDoc getLocalizingBundle() {
314         return localizingBundle;
315     }
316     
317     public String JavaDoc getLayer() {
318         return layer;
319     }
320     
321     public String JavaDoc getClassPath() {
322         return classPath;
323     }
324     
325     /**
326      * @return an array of public packages. May be empty but not <code>null</code>.
327      */

328     public PackageExport[] getPublicPackages() {
329         return publicPackages;
330     }
331     
332     public String JavaDoc[] getFriends() {
333         return friendNames;
334     }
335     
336     public boolean isDeprecated() {
337         return deprecated;
338     }
339     
340     public Set JavaDoc<Dependency> getModuleDependencies() {
341         if (moduleDependencies != null) {
342             return Dependency.create(Dependency.TYPE_MODULE, moduleDependencies);
343         } else {
344             return Collections.EMPTY_SET;
345         }
346     }
347     
348     /**
349      * Struct representing a package exported from a module.
350      */

351     public static final class PackageExport {
352         
353         private final String JavaDoc pkg;
354         private final boolean recursive;
355         
356         /** Create a package export struct with the named parameters. */
357         public PackageExport(String JavaDoc pkg, boolean recursive) {
358             this.pkg = pkg;
359             this.recursive = recursive;
360         }
361         
362         /** Package to export, in the form <samp>org.netbeans.modules.foo</samp>. */
363         public String JavaDoc getPackage() {
364             return pkg;
365         }
366         
367         /** If true, exports subpackages also. */
368         public boolean isRecursive() {
369             return recursive;
370         }
371         
372         public String JavaDoc toString() {
373             return "PackageExport[" + pkg + (recursive ? "/**" : "") + "]"; // NOI18N
374
}
375     }
376     
377 }
378
Popular Tags