| Editing Manifest programmatically [message #333650] | 
Fri, 19 December 2008 12:14   | 
 
Eclipse User  | 
 | 
 | 
   | 
 
Are there any APIs for editing manifest files, for example if I wish to  
add a plugin to the  manifest element Require-Bundle when altering a  
project nature.  
Or is it just a case of reading the manifest using  
 org.eclipse.osgi.util.ManifestElement.parseBundleManifest(In putStream,  
Map) to read and then replicating that sort of behaviour on write using  
some sort of PrintWriter?
 |  
 |  
  | 
| Re: Editing Manifest programmatically [message #333672 is a reply to message #333650] | 
Mon, 22 December 2008 10:34   | 
 
Eclipse User  | 
 | 
 | 
   | 
 
Doh! Using java.util.jar.Manifest seems to work ok... 
 
 
For example; 
 
public void addPluginDependency(String plugin, 
									String version, 
									boolean reexport, 
									boolean overwrite) throws BundleException 
	{ 
		String requireBundleHeader = "Require-Bundle"; 
		String bundleVersionAttr = "bundle-version"; 
		String rexportDirective = "visibility"; 
 
		assert (plugin != null); 
		if(plugin == null) 
			return; 
		if(version == null) 
		{ 
			version = "1.0.0"; 
		} 
 
		boolean foundHeader = false; 
		boolean hasValuesForPlugin = false; 
		StringBuilder strBuilder = new StringBuilder(); 
 
		Attributes mainAttrs = manifest.getMainAttributes(); 
		for (Object entryName : mainAttrs.keySet()) 
		{ 
			String values; 
			String header; 
			 
			//Get the values safely 
			if(entryName instanceof String) 
			{ 
				header = (String) entryName; 
				values = mainAttrs.getValue(header); 
			} 
			else if(entryName instanceof Attributes.Name) 
			{ 
				header = (String) ((Attributes.Name) entryName).toString(); 
				values = mainAttrs.getValue((Attributes.Name) entryName); 
			} 
			else 
			{ 
				throw new BundleException("Unknown Main Attribute Key type: " 
						+ entryName.getClass() + " (" + entryName + ")"); 
			} 
			 
			//loop to the next header if we don't find ours 
			if(!requireBundleHeader.equals(header)) 
				continue; 
			 
			//found it 
			foundHeader = true; 
			 
			//process the components of the value for this element see  
ManifestElement javadocs for spec 
			if(values != null) 
			{ 
				ManifestElement[] elements = ManifestElement.parseHeader(header,  
values); 
				for (int i = 0; i < elements.length; i++) 
				{ 
					ManifestElement manifestElement = elements[i]; 
					Enumeration<?> keys = manifestElement.getKeys(); 
					Enumeration<?> directiveKeys = manifestElement.getDirectiveKeys(); 
					StringBuilder valueComponents = new StringBuilder(); 
					boolean lastElement = i >= elements.length-1; 
					boolean firstElement = i == 0; 
					boolean elementIsRequiredPlugin = false; 
					 
					for (int j = 0; j < manifestElement.getValueComponents().length; j++) 
					{ 
						String pureValue = manifestElement.getValueComponents()[j]; 
						if(plugin.equalsIgnoreCase(pureValue)) 
						{ 
							hasValuesForPlugin = true; 
							elementIsRequiredPlugin = true; 
							//if its already in the header element components and we are not  
overwriting quit now 
							if(!overwrite) 
								return; 
						} 
						//ALWAYS WRITE THE LAST ; -> if we don't have any keys or directives  
now - we will have 
						//if this is not the required element we will just write the line in  
one go using manifestElement.getValue() 
						valueComponents.append(pureValue + ";"); 
					} 
					 
					if(!elementIsRequiredPlugin) 
					{ 
						//we haven't got a component THIS TIME which is equal to the  
component we are looking to change 
						//so just write out the whole of this component without editing it,  
and carry on looking 
						strBuilder.append((firstElement?"":" ") + manifestElement.getValue() 
								+ (lastElement ? "" : ",\n")); 
						continue; 
					} 
					else 
					{ 
						//write out the value components found so far - we may wish to edit  
bits of it 
						strBuilder.append((firstElement?"":" ") + valueComponents); 
					} 
					boolean foundVersionAttr = false; 
					if(keys != null) 
					{ 
						while (keys.hasMoreElements()) 
						{ 
							String key = (String) keys.nextElement(); 
							String value = manifestElement.getAttribute(key); 
							if(bundleVersionAttr.equalsIgnoreCase(key)) 
							{ 
								//always write the last ; if we are editing the values - we will  
be writing the export directive 
								strBuilder.append(key + "=\"" + version + "\";"); 
								foundVersionAttr = true; 
							} 
							else 
							{ 
								//always write the last ; if we are editing the values - we will  
be writing the export directive 
								strBuilder.append(key + "=\"" + value + "\";"); 
							} 
						} 
					} 
					if(!foundVersionAttr) 
					{ 
						//always write the last ; if we are editing the values - we will be  
writing the export directive 
						strBuilder.append(bundleVersionAttr + "=" + version + ";"); 
					} 
					boolean foundDirective = false; 
					if(directiveKeys != null) 
					{ 
						while (directiveKeys.hasMoreElements()) 
						{ 
							String key = (String) directiveKeys.nextElement(); 
							boolean lastDirective = !directiveKeys.hasMoreElements(); 
							if(rexportDirective.equalsIgnoreCase(key)) 
							{ 
								foundDirective = true; 
								strBuilder.append(key + ":="); 
								String dirValues[] = manifestElement.getDirectives(key); 
								for (int j = 0; j < dirValues.length; j++) 
								{ 
									String string = dirValues[j]; 
									boolean lastDirectiveValue = j >= dirValues.length-1; 
									if("reexport".equalsIgnoreCase(string) && !reexport) 
									{ 
										string = "private"; 
									} 
									else if("private".equalsIgnoreCase(string) && reexport) 
									{ 
										string = "reexport"; 
									} 
									strBuilder.append(string + (lastDirectiveValue?"":",")); 
								} 
							} 
							else 
							{ 
								strBuilder.append(key + ":=" + manifestElement.getDirective(key)); 
							} 
							if(!lastDirective) 
							{ 
								strBuilder.append(";"); 
							} 
						} 
					} 
					if(!foundDirective) 
					{ 
						strBuilder.append(rexportDirective + ":=" +  
(reexport?"rexport":"private")); 
					} 
					if(!lastElement) 
					{ 
						strBuilder.append(",\n"); 
					} 
				} 
			} 
			break; 
		} 
		if(!foundHeader) 
		{ 
			//Add a new one 
			manifest.getMainAttributes().putValue(requireBundleHeader, plugin + ";"  
+ bundleVersionAttr + "=" + version + ";" + rexportDirective + ":=" +  
(reexport?"rexport":"private")); 
		} 
		else if(overwrite) 
		{ 
			//found it and wish to edit it... 
			if(hasValuesForPlugin) 
			{ 
				//we have already edited the values for the plugin we wish to add 
				manifest.getMainAttributes().putValue(requireBundleHeader,  
strBuilder.toString()); 
			} 
			else 
			{ 
				//There are no values for the plugin we wish to add. 
				//...create a fresh entry 
				String existingValues = strBuilder.toString(); 
				boolean areExistingValues = existingValues.trim().length() != 0; 
				String newValue = plugin + ";" + bundleVersionAttr + "=" + version +  
";" + rexportDirective + ":=" + (reexport?"rexport":"private"); 
				newValue = (areExistingValues)?(existingValues+",\n  
"+newValue):newValue; 
				manifest.getMainAttributes().putValue(requireBundleHeader, newValue); 
			} 
		} 
	} 
 
	public static void main(String[] args) throws Exception 
	{ 
		try 
		{ 
			String fileName = "C:\\Documents and  
 Settings\\Administrator.ARDEN\\branchWorkspace\\org.jvnet.ja xbw.eclipse\\testData\\Manifest.mf "; 
			ManifestChanger manifestChanger = new ManifestChanger(); 
			FileInputStream in = new FileInputStream(fileName); 
			manifestChanger.loadManifest(in); 
			in.close(); 
			manifestChanger.addPluginDependency("MyPlugin", "1.5.0", false, true); 
			FileOutputStream out = new FileOutputStream(fileName); 
			manifestChanger.writeManifest(out); 
			out.close(); 
		} 
		catch (Throwable t) 
		{ 
			System.err.println("Unexpected Exception: " + t); 
			t.printStackTrace(); 
		} 
	}
 |  
 |  
  | 
Powered by 
FUDForum. Page generated in 0.03642 seconds