001: /*******************************************************************************
002: * Copyright (c) 2006, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.pde.internal.core;
011:
012: import java.io.File;
013: import java.io.IOException;
014: import java.util.ArrayList;
015: import java.util.Dictionary;
016: import java.util.HashMap;
017: import java.util.Iterator;
018: import java.util.Map;
019:
020: import javax.xml.parsers.DocumentBuilder;
021: import javax.xml.parsers.DocumentBuilderFactory;
022: import javax.xml.parsers.FactoryConfigurationError;
023: import javax.xml.parsers.ParserConfigurationException;
024:
025: import org.eclipse.osgi.service.resolver.BundleDescription;
026: import org.eclipse.osgi.util.ManifestElement;
027: import org.eclipse.pde.core.plugin.IPlugin;
028: import org.eclipse.pde.core.plugin.IPluginBase;
029: import org.eclipse.pde.core.plugin.IPluginLibrary;
030: import org.eclipse.pde.core.plugin.IPluginModelBase;
031: import org.eclipse.pde.internal.core.ibundle.IBundlePluginModelBase;
032: import org.osgi.framework.BundleException;
033: import org.osgi.framework.Constants;
034: import org.w3c.dom.Document;
035: import org.w3c.dom.Element;
036: import org.w3c.dom.Node;
037: import org.w3c.dom.NodeList;
038:
039: public class PDEAuxiliaryState {
040:
041: private static String CACHE_EXTENSION = ".pluginInfo"; //$NON-NLS-1$
042:
043: private static String ATTR_BUNDLE_ID = "bundleID"; //$NON-NLS-1$
044: private static String ATTR_BUNDLE_STRUCTURE = "isBundle"; //$NON-NLS-1$
045: private static String ATTR_CLASS = "class"; //$NON-NLS-1$
046: private static String ATTR_EXPORTED = "exported"; //$NON-NLS-1$
047: private static String ATTR_EXTENSIBLE_API = "hasExtensibleAPI"; //$NON-NLS-1$
048: private static String ATTR_LOCALIZATION = "localization"; //$NON-NLS-1$
049: private static String ATTR_NAME = "name"; //$NON-NLS-1$
050: private static String ATTR_PATCH = "patch"; //$NON-NLS-1$
051: private static String ATTR_PROJECT = "project"; //$NON-NLS-1$
052: private static String ATTR_PROVIDER = "provider"; //$NON-NLS-1$
053:
054: private static String ELEMENT_BUNDLE = "bundle"; //$NON-NLS-1$
055: private static String ELEMENT_LIB = "library"; //$NON-NLS-1$
056: private static String ELEMENT_ROOT = "map"; //$NON-NLS-1$
057:
058: protected Map fPluginInfos = new HashMap();
059:
060: protected PDEAuxiliaryState() {
061: }
062:
063: protected PDEAuxiliaryState(PDEAuxiliaryState state) {
064: this .fPluginInfos = new HashMap(state.fPluginInfos);
065: }
066:
067: class PluginInfo {
068: String name;
069: String providerName;
070: String className;
071: boolean hasExtensibleAPI;
072: boolean isPatchFragment;
073: boolean hasBundleStructure;
074: String[] libraries;
075: String project;
076: String localization;
077: }
078:
079: private void createPluginInfo(Element element) {
080: PluginInfo info = new PluginInfo();
081: if (element.hasAttribute(ATTR_NAME))
082: info.name = element.getAttribute(ATTR_NAME);
083: if (element.hasAttribute(ATTR_PROVIDER))
084: info.providerName = element.getAttribute(ATTR_PROVIDER);
085: if (element.hasAttribute(ATTR_CLASS))
086: info.className = element.getAttribute(ATTR_CLASS);
087: info.hasExtensibleAPI = "true".equals(element.getAttribute(ATTR_EXTENSIBLE_API)); //$NON-NLS-1$
088: info.isPatchFragment = "true".equals(element.getAttribute(ATTR_PATCH)); //$NON-NLS-1$
089: info.hasBundleStructure = !"false".equals(element.getAttribute(ATTR_BUNDLE_STRUCTURE)); //$NON-NLS-1$
090: if (element.hasAttribute(ATTR_PROJECT))
091: info.project = element.getAttribute(ATTR_PROJECT);
092: if (element.hasAttribute(ATTR_LOCALIZATION))
093: info.localization = element.getAttribute(ATTR_LOCALIZATION);
094:
095: NodeList libs = element.getChildNodes();
096: ArrayList list = new ArrayList(libs.getLength());
097: for (int i = 0; i < libs.getLength(); i++) {
098: if (libs.item(i).getNodeType() == Node.ELEMENT_NODE) {
099: Element lib = (Element) libs.item(i);
100: list.add(lib.getAttribute(ATTR_NAME));
101: }
102: }
103: info.libraries = (String[]) list
104: .toArray(new String[list.size()]);
105: fPluginInfos.put(element.getAttribute(ATTR_BUNDLE_ID), info);
106: }
107:
108: public String getClassName(long bundleID) {
109: PluginInfo info = (PluginInfo) fPluginInfos.get(Long
110: .toString(bundleID));
111: return info == null ? null : info.className;
112: }
113:
114: public boolean hasExtensibleAPI(long bundleID) {
115: PluginInfo info = (PluginInfo) fPluginInfos.get(Long
116: .toString(bundleID));
117: return info == null ? false : info.hasExtensibleAPI;
118: }
119:
120: public boolean isPatchFragment(long bundleID) {
121: PluginInfo info = (PluginInfo) fPluginInfos.get(Long
122: .toString(bundleID));
123: return info == null ? false : info.isPatchFragment;
124: }
125:
126: public boolean hasBundleStructure(long bundleID) {
127: PluginInfo info = (PluginInfo) fPluginInfos.get(Long
128: .toString(bundleID));
129: return info == null ? false : info.hasBundleStructure;
130: }
131:
132: public String getPluginName(long bundleID) {
133: PluginInfo info = (PluginInfo) fPluginInfos.get(Long
134: .toString(bundleID));
135: return info == null ? null : info.name;
136: }
137:
138: public String getProviderName(long bundleID) {
139: PluginInfo info = (PluginInfo) fPluginInfos.get(Long
140: .toString(bundleID));
141: return info == null ? null : info.providerName;
142: }
143:
144: public String[] getLibraryNames(long bundleID) {
145: PluginInfo info = (PluginInfo) fPluginInfos.get(Long
146: .toString(bundleID));
147: return info == null ? new String[0] : info.libraries;
148: }
149:
150: public String getBundleLocalization(long bundleID) {
151: PluginInfo info = (PluginInfo) fPluginInfos.get(Long
152: .toString(bundleID));
153: return info == null ? null : info.localization;
154: }
155:
156: public String getProject(long bundleID) {
157: PluginInfo info = (PluginInfo) fPluginInfos.get(Long
158: .toString(bundleID));
159: return info == null ? null : info.project;
160: }
161:
162: protected void savePluginInfo(File dir) {
163: try {
164: DocumentBuilderFactory factory = DocumentBuilderFactory
165: .newInstance();
166: Document doc = factory.newDocumentBuilder().newDocument();
167: Element root = doc.createElement(ELEMENT_ROOT);
168:
169: Iterator iter = fPluginInfos.keySet().iterator();
170: while (iter.hasNext()) {
171: String key = iter.next().toString();
172: Element element = doc.createElement(ELEMENT_BUNDLE);
173: element.setAttribute(ATTR_BUNDLE_ID, key);
174: PluginInfo info = (PluginInfo) fPluginInfos.get(key);
175: if (info.className != null)
176: element.setAttribute(ATTR_CLASS, info.className);
177: if (info.providerName != null)
178: element.setAttribute(ATTR_PROVIDER,
179: info.providerName);
180: if (info.name != null)
181: element.setAttribute(ATTR_NAME, info.name);
182: if (info.hasExtensibleAPI)
183: element.setAttribute(ATTR_EXTENSIBLE_API, "true"); //$NON-NLS-1$
184: if (info.isPatchFragment)
185: element.setAttribute(ATTR_PATCH, "true"); //$NON-NLS-1$
186: if (!info.hasBundleStructure)
187: element
188: .setAttribute(ATTR_BUNDLE_STRUCTURE,
189: "false"); //$NON-NLS-1$
190: if (info.localization != null)
191: element.setAttribute(ATTR_LOCALIZATION,
192: info.localization);
193: if (info.libraries != null) {
194: for (int i = 0; i < info.libraries.length; i++) {
195: Element lib = doc.createElement(ELEMENT_LIB);
196: lib.setAttribute(ATTR_NAME, info.libraries[i]);
197: element.appendChild(lib);
198: }
199: }
200: root.appendChild(element);
201: }
202: doc.appendChild(root);
203: XMLPrintHandler.writeFile(doc, new File(dir,
204: CACHE_EXTENSION));
205: } catch (Exception e) {
206: PDECore.log(e);
207: }
208: }
209:
210: protected boolean readPluginInfoCache(File dir) {
211: File file = new File(dir, CACHE_EXTENSION);
212: if (file.exists() && file.isFile()) {
213: try {
214: DocumentBuilderFactory factory = DocumentBuilderFactory
215: .newInstance();
216: Document doc = factory.newDocumentBuilder().parse(file);
217: Element root = doc.getDocumentElement();
218: if (root != null) {
219: NodeList list = root.getChildNodes();
220: for (int i = 0; i < list.getLength(); i++) {
221: if (list.item(i).getNodeType() == Node.ELEMENT_NODE)
222: createPluginInfo((Element) list.item(i));
223: }
224: }
225: return true;
226: } catch (org.xml.sax.SAXException e) {
227: PDECore.log(e);
228: } catch (IOException e) {
229: PDECore.log(e);
230: } catch (ParserConfigurationException e) {
231: PDECore.log(e);
232: }
233: }
234: return false;
235: }
236:
237: public static void writePluginInfo(IPluginModelBase[] models,
238: File destination) {
239: try {
240: DocumentBuilder builder = DocumentBuilderFactory
241: .newInstance().newDocumentBuilder();
242: Document doc = builder.newDocument();
243:
244: Element root = doc.createElement(ELEMENT_ROOT);
245: doc.appendChild(root);
246: for (int i = 0; i < models.length; i++) {
247: IPluginBase plugin = models[i].getPluginBase();
248: BundleDescription desc = models[i]
249: .getBundleDescription();
250: Element element = doc.createElement(ELEMENT_BUNDLE);
251: element.setAttribute(ATTR_BUNDLE_ID, Long.toString(desc
252: .getBundleId()));
253: element
254: .setAttribute(ATTR_PROJECT, models[i]
255: .getUnderlyingResource().getProject()
256: .getName());
257: if (plugin instanceof IPlugin
258: && ((IPlugin) plugin).getClassName() != null)
259: element.setAttribute(ATTR_CLASS, ((IPlugin) plugin)
260: .getClassName());
261: if (plugin.getProviderName() != null)
262: element.setAttribute(ATTR_PROVIDER, plugin
263: .getProviderName());
264: if (plugin.getName() != null)
265: element.setAttribute(ATTR_NAME, plugin.getName());
266: if (ClasspathUtilCore.hasExtensibleAPI(models[i]))
267: element.setAttribute(ATTR_EXTENSIBLE_API, "true"); //$NON-NLS-1$
268: else if (ClasspathUtilCore.isPatchFragment(models[i]))
269: element.setAttribute(ATTR_PATCH, "true"); //$NON-NLS-1$
270: if (!(models[i] instanceof IBundlePluginModelBase))
271: element
272: .setAttribute(ATTR_BUNDLE_STRUCTURE,
273: "false"); //$NON-NLS-1$
274: if (models[i] instanceof IBundlePluginModelBase) {
275: String localization = ((IBundlePluginModelBase) models[i])
276: .getBundleLocalization();
277: if (localization != null)
278: element.setAttribute(ATTR_LOCALIZATION,
279: localization);
280: }
281: IPluginLibrary[] libraries = plugin.getLibraries();
282: for (int j = 0; j < libraries.length; j++) {
283: Element lib = doc.createElement(ELEMENT_LIB);
284: lib.setAttribute(ATTR_NAME, libraries[j].getName());
285: if (!libraries[j].isExported())
286: lib.setAttribute(ATTR_EXPORTED, "false"); //$NON-NLS-1$
287: element.appendChild(lib);
288: }
289: root.appendChild(element);
290: }
291: XMLPrintHandler.writeFile(doc, new File(destination,
292: CACHE_EXTENSION));
293: } catch (ParserConfigurationException e) {
294: } catch (FactoryConfigurationError e) {
295: } catch (IOException e) {
296: }
297: }
298:
299: protected void addAuxiliaryData(BundleDescription desc,
300: Dictionary manifest, boolean hasBundleStructure) {
301: PluginInfo info = new PluginInfo();
302: info.name = (String) manifest.get(Constants.BUNDLE_NAME);
303: info.providerName = (String) manifest
304: .get(Constants.BUNDLE_VENDOR);
305:
306: String className = (String) manifest
307: .get(ICoreConstants.PLUGIN_CLASS);
308: info.className = className != null ? className
309: : (String) manifest.get(Constants.BUNDLE_ACTIVATOR);
310: info.libraries = getClasspath(manifest);
311: info.hasExtensibleAPI = "true".equals(manifest.get(ICoreConstants.EXTENSIBLE_API)); //$NON-NLS-1$
312: info.isPatchFragment = "true".equals(manifest.get(ICoreConstants.PATCH_FRAGMENT)); //$NON-NLS-1$
313: info.localization = (String) manifest
314: .get(Constants.BUNDLE_LOCALIZATION);
315: info.hasBundleStructure = hasBundleStructure;
316: fPluginInfos.put(Long.toString(desc.getBundleId()), info);
317: }
318:
319: protected String[] getClasspath(Dictionary manifest) {
320: String fullClasspath = (String) manifest
321: .get(Constants.BUNDLE_CLASSPATH);
322: String[] result = new String[0];
323: try {
324: if (fullClasspath != null) {
325: ManifestElement[] classpathEntries = ManifestElement
326: .parseHeader(Constants.BUNDLE_CLASSPATH,
327: fullClasspath);
328: result = new String[classpathEntries.length];
329: for (int i = 0; i < classpathEntries.length; i++) {
330: result[i] = classpathEntries[i].getValue();
331: }
332: }
333: } catch (BundleException e) {
334: }
335: return result;
336: }
337:
338: protected void clear() {
339: fPluginInfos.clear();
340: }
341:
342: }
|