1 19 20 package org.netbeans.modules.apisupport.project; 21 22 import java.io.File ; 23 import java.io.FileInputStream ; 24 import java.io.IOException ; 25 import java.io.InputStream ; 26 import java.util.ArrayList ; 27 import java.util.Collections ; 28 import java.util.HashSet ; 29 import java.util.List ; 30 import java.util.Set ; 31 import java.util.StringTokenizer ; 32 import java.util.jar.Attributes ; 33 import java.util.jar.JarFile ; 34 import java.util.jar.Manifest ; 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 44 49 public final class ManifestManager { 50 51 private String codeNameBase; 52 private String releaseVersion; 53 private String specificationVersion; 54 private String implementationVersion; 55 private String [] provTokens; 56 private String provTokensString; 57 private String [] requiredTokens; 58 private String [] neededTokens; 59 private String localizingBundle; 60 private String layer; 61 private String classPath; 62 private PackageExport[] publicPackages; 63 private String [] friendNames; 64 private String moduleDependencies; 65 private boolean deprecated; 66 67 public static final String OPENIDE_MODULE = "OpenIDE-Module"; public static final String OPENIDE_MODULE_SPECIFICATION_VERSION = "OpenIDE-Module-Specification-Version"; public static final String OPENIDE_MODULE_IMPLEMENTATION_VERSION = "OpenIDE-Module-Implementation-Version"; public static final String OPENIDE_MODULE_PROVIDES = "OpenIDE-Module-Provides"; public static final String OPENIDE_MODULE_REQUIRES = "OpenIDE-Module-Requires"; public static final String OPENIDE_MODULE_NEEDS = "OpenIDE-Module-Needs"; public static final String OPENIDE_MODULE_LAYER = "OpenIDE-Module-Layer"; public static final String OPENIDE_MODULE_LOCALIZING_BUNDLE = "OpenIDE-Module-Localizing-Bundle"; public static final String OPENIDE_MODULE_PUBLIC_PACKAGES = "OpenIDE-Module-Public-Packages"; public static final String OPENIDE_MODULE_FRIENDS = "OpenIDE-Module-Friends"; public static final String OPENIDE_MODULE_MODULE_DEPENDENCIES = "OpenIDE-Module-Module-Dependencies"; public static final String CLASS_PATH = "Class-Path"; 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 [0]; 86 this.requiredTokens = new String [0]; 87 this.neededTokens = new String [0]; 88 } 89 90 private ManifestManager(String cnb, String releaseVersion, String specVer, 91 String implVer, String provTokensString, String requiredTokens, String neededTokens, 92 String locBundle, String layer, String classPath, 93 PackageExport[] publicPackages, String [] friendNames, 94 boolean deprecated, String 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); this.requiredTokens = parseTokens(requiredTokens); this.neededTokens = parseTokens(neededTokens); 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 [] parseTokens(String tokens) { 114 if (tokens == null) { 115 return new String [0]; 116 } 117 StringTokenizer st = new StringTokenizer (tokens, ","); String [] result = new String [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 manifest, boolean loadPublicPackages) { 126 if (manifest.exists()) { 127 try { 128 InputStream mis = new FileInputStream (manifest); try { 130 Manifest mf = new Manifest (mis); 131 return ManifestManager.getInstance(mf, loadPublicPackages); 132 } finally { 133 mis.close();; 134 } 135 } catch (IOException 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 jar) { 144 try { 145 if (!jar.isFile()) { 146 throw new IOException ("No such JAR: " + jar); } 148 JarFile jf = new JarFile (jar, false); 149 try { 150 Manifest m = jf.getManifest(); 151 if (m == null) { throw new IOException ("No manifest in " + jar); } 154 return ManifestManager.getInstance(m, true); 155 } finally { 156 jf.close(); 157 } 158 } catch (IOException e) { 159 Util.err.notify(ErrorManager.INFORMATIONAL, e); 160 return NULL_INSTANCE; 161 } 162 } 163 164 public static ManifestManager getInstance(Manifest manifest, boolean loadPublicPackages) { 165 Attributes attr = manifest.getMainAttributes(); 166 String codename = attr.getValue(OPENIDE_MODULE); 167 String codenamebase = null; 168 String 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 [] friendNames = null; 180 if (loadPublicPackages) { 181 publicPackages = EMPTY_EXPORTED_PACKAGES; 182 String pp = attr.getValue(OPENIDE_MODULE_PUBLIC_PACKAGES); 183 if (pp != null) { 184 publicPackages = parseExportedPackages(pp); 185 } 186 String 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 ("No use specifying OpenIDE-Module-Friends without any public packages: " + friends); } 192 } 193 } 194 boolean deprecated = "true".equals(attr.getValue("OpenIDE-Module-Deprecated")); 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 215 static void createManifest(FileObject manifest, String cnb, String specVer, 216 String bundlePath, String layerPath) throws IOException { 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 exportsS) { 228 PackageExport[] exportedPackages = null; 229 if (exportsS.trim().equals("-")) { exportedPackages = EMPTY_EXPORTED_PACKAGES; 231 } else { 232 StringTokenizer tok = new StringTokenizer (exportsS, ", "); List exports = new ArrayList (Math.max(tok.countTokens(), 1)); while (tok.hasMoreTokens()) { 235 String piece = tok.nextToken(); 236 if (piece.endsWith(".*")) { String pkg = piece.substring(0, piece.length() - 2); 238 Dependency.create(Dependency.TYPE_MODULE, pkg); 239 if (pkg.lastIndexOf('/') != -1) { 240 throw new IllegalArgumentException ("Illegal OpenIDE-Module-Public-Packages: " + exportsS); } 242 exports.add(new PackageExport(pkg, false)); 243 } else if (piece.endsWith(".**")) { String pkg = piece.substring(0, piece.length() - 3); 245 Dependency.create(Dependency.TYPE_MODULE, pkg); 246 if (pkg.lastIndexOf('/') != -1) { 247 throw new IllegalArgumentException ("Illegal OpenIDE-Module-Public-Packages: " + exportsS); } 249 exports.add(new PackageExport(pkg, true)); 250 } else { 251 throw new IllegalArgumentException ("Illegal OpenIDE-Module-Public-Packages: " + exportsS); } 253 } 254 if (exports.isEmpty()) { 255 throw new IllegalArgumentException ("Illegal OpenIDE-Module-Public-Packages: " + exportsS); } 257 exportedPackages = (PackageExport[])exports.toArray(new PackageExport[exports.size()]); 258 } 259 return exportedPackages; 260 } 261 262 private static String [] parseFriends(final String friends) { 263 Set set = new HashSet (); 264 StringTokenizer tok = new StringTokenizer (friends, ", "); while (tok.hasMoreTokens()) { 266 String piece = tok.nextToken(); 267 if (piece.indexOf('/') != -1) { 268 throw new IllegalArgumentException ("May specify only module code name bases in OpenIDE-Module-Friends, not major release versions: " + piece); } 270 Dependency.create(Dependency.TYPE_MODULE, piece); 272 set.add(piece); 274 } 275 if (set.isEmpty()) { 276 throw new IllegalArgumentException ("Empty OpenIDE-Module-Friends: " + friends); } 278 return (String []) set.toArray(new String [set.size()]); 279 } 280 281 public String getCodeNameBase() { 282 return codeNameBase; 283 } 284 285 public String getReleaseVersion() { 286 return releaseVersion; 287 } 288 289 public String getSpecificationVersion() { 290 return specificationVersion; 291 } 292 293 public String getImplementationVersion() { 294 return implementationVersion; 295 } 296 297 public String getProvidedTokensString() { 298 return provTokensString; 299 } 300 301 public String [] getProvidedTokens() { 302 return provTokens; 303 } 304 305 public String [] getRequiredTokens() { 306 return requiredTokens; 307 } 308 309 public String [] getNeededTokens() { 310 return neededTokens; 311 } 312 313 public String getLocalizingBundle() { 314 return localizingBundle; 315 } 316 317 public String getLayer() { 318 return layer; 319 } 320 321 public String getClassPath() { 322 return classPath; 323 } 324 325 328 public PackageExport[] getPublicPackages() { 329 return publicPackages; 330 } 331 332 public String [] getFriends() { 333 return friendNames; 334 } 335 336 public boolean isDeprecated() { 337 return deprecated; 338 } 339 340 public Set <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 351 public static final class PackageExport { 352 353 private final String pkg; 354 private final boolean recursive; 355 356 357 public PackageExport(String pkg, boolean recursive) { 358 this.pkg = pkg; 359 this.recursive = recursive; 360 } 361 362 363 public String getPackage() { 364 return pkg; 365 } 366 367 368 public boolean isRecursive() { 369 return recursive; 370 } 371 372 public String toString() { 373 return "PackageExport[" + pkg + (recursive ? "/**" : "") + "]"; } 375 } 376 377 } 378 | Popular Tags |