KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > pde > internal > ui > wizards > tools > OrganizeManifest


1 /*******************************************************************************
2  * Copyright (c) 2005, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.pde.internal.ui.wizards.tools;
12
13 import java.io.File JavaDoc;
14 import java.util.ArrayList JavaDoc;
15 import java.util.HashSet JavaDoc;
16 import java.util.Set JavaDoc;
17 import java.util.regex.Pattern JavaDoc;
18
19 import org.eclipse.core.resources.IFile;
20 import org.eclipse.core.resources.IProject;
21 import org.eclipse.core.runtime.CoreException;
22 import org.eclipse.core.runtime.IPath;
23 import org.eclipse.core.runtime.IProgressMonitor;
24 import org.eclipse.core.runtime.Path;
25 import org.eclipse.jdt.core.IJavaElement;
26 import org.eclipse.jdt.core.IPackageFragment;
27 import org.eclipse.jdt.core.IPackageFragmentRoot;
28 import org.eclipse.jdt.core.JavaModelException;
29 import org.eclipse.jface.text.IDocument;
30 import org.eclipse.osgi.service.resolver.BundleDescription;
31 import org.eclipse.osgi.service.resolver.ExportPackageDescription;
32 import org.eclipse.osgi.service.resolver.HostSpecification;
33 import org.eclipse.osgi.service.resolver.State;
34 import org.eclipse.pde.core.IBaseModel;
35 import org.eclipse.pde.core.build.IBuild;
36 import org.eclipse.pde.core.build.IBuildEntry;
37 import org.eclipse.pde.core.build.IBuildModel;
38 import org.eclipse.pde.core.plugin.IFragmentModel;
39 import org.eclipse.pde.core.plugin.IPluginAttribute;
40 import org.eclipse.pde.core.plugin.IPluginElement;
41 import org.eclipse.pde.core.plugin.IPluginExtension;
42 import org.eclipse.pde.core.plugin.IPluginExtensionPoint;
43 import org.eclipse.pde.core.plugin.IPluginModelBase;
44 import org.eclipse.pde.core.plugin.IPluginObject;
45 import org.eclipse.pde.core.plugin.IPluginParent;
46 import org.eclipse.pde.core.plugin.PluginRegistry;
47 import org.eclipse.pde.internal.core.ICoreConstants;
48 import org.eclipse.pde.internal.core.PDECore;
49 import org.eclipse.pde.internal.core.PDEManager;
50 import org.eclipse.pde.internal.core.TargetPlatformHelper;
51 import org.eclipse.pde.internal.core.ibundle.IBundle;
52 import org.eclipse.pde.internal.core.ibundle.IBundleModel;
53 import org.eclipse.pde.internal.core.ibundle.IManifestHeader;
54 import org.eclipse.pde.internal.core.ischema.IMetaAttribute;
55 import org.eclipse.pde.internal.core.ischema.ISchema;
56 import org.eclipse.pde.internal.core.ischema.ISchemaAttribute;
57 import org.eclipse.pde.internal.core.ischema.ISchemaElement;
58 import org.eclipse.pde.internal.core.schema.SchemaRegistry;
59 import org.eclipse.pde.internal.core.text.IDocumentAttribute;
60 import org.eclipse.pde.internal.core.text.IDocumentNode;
61 import org.eclipse.pde.internal.core.text.IDocumentTextNode;
62 import org.eclipse.pde.internal.core.text.IModelTextChangeListener;
63 import org.eclipse.pde.internal.core.text.bundle.Bundle;
64 import org.eclipse.pde.internal.core.text.bundle.BundleModel;
65 import org.eclipse.pde.internal.core.text.bundle.ExportPackageHeader;
66 import org.eclipse.pde.internal.core.text.bundle.ExportPackageObject;
67 import org.eclipse.pde.internal.core.text.bundle.ImportPackageHeader;
68 import org.eclipse.pde.internal.core.text.bundle.ImportPackageObject;
69 import org.eclipse.pde.internal.core.text.bundle.RequireBundleHeader;
70 import org.eclipse.pde.internal.core.text.bundle.RequireBundleObject;
71 import org.eclipse.pde.internal.core.text.bundle.SingleManifestHeader;
72 import org.eclipse.pde.internal.core.text.plugin.FragmentModel;
73 import org.eclipse.pde.internal.core.text.plugin.PluginModel;
74 import org.eclipse.pde.internal.core.util.CoreUtility;
75 import org.eclipse.pde.internal.core.util.ManifestUtils;
76 import org.eclipse.pde.internal.core.util.PatternConstructor;
77 import org.eclipse.pde.internal.ui.util.ModelModification;
78 import org.eclipse.pde.internal.ui.util.PDEModelUtility;
79 import org.eclipse.text.edits.MultiTextEdit;
80 import org.eclipse.text.edits.TextEdit;
81 import org.osgi.framework.Constants;
82
83 public class OrganizeManifest implements IOrganizeManifestsSettings {
84
85     private static String JavaDoc F_NL_PREFIX = "$nl$"; //$NON-NLS-1$
86
private static String JavaDoc[] F_ICON_EXTENSIONS = new String JavaDoc[] {
87         "BMP", "ICO", "JPEG", "JPG", "GIF", "PNG", "TIFF" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$
88
};
89     
90     public static void organizeRequireBundles(IBundle bundle, boolean removeImports) {
91         if (!(bundle instanceof Bundle))
92             return;
93         
94         RequireBundleHeader header = (RequireBundleHeader)((Bundle)bundle).getManifestHeader(Constants.REQUIRE_BUNDLE);
95         if (header != null) {
96             RequireBundleObject[] bundles = header.getRequiredBundles();
97             for (int i = 0; i < bundles.length; i++) {
98                 String JavaDoc pluginId = bundles[i].getId();
99                 if (PluginRegistry.findModel(pluginId) == null) {
100                     if (removeImports)
101                         header.removeBundle(bundles[i]);
102                     else {
103                         bundles[i].setOptional(true);
104                     }
105                 }
106             }
107         }
108     }
109     
110     public static void organizeExportPackages(IBundle bundle, IProject project, boolean addMissing, boolean removeUnresolved) {
111         if (!addMissing && !removeUnresolved)
112             return;
113         
114         if (!(bundle instanceof Bundle))
115             return;
116         
117         ExportPackageHeader header = (ExportPackageHeader)bundle.getManifestHeader(Constants.EXPORT_PACKAGE);
118         ExportPackageObject[] currentPkgs;
119         if (header == null) {
120             bundle.setHeader(Constants.EXPORT_PACKAGE, ""); //$NON-NLS-1$
121
header = (ExportPackageHeader)bundle.getManifestHeader(Constants.EXPORT_PACKAGE);
122             currentPkgs = new ExportPackageObject[0];
123         } else
124             currentPkgs = header.getPackages();
125         
126         IManifestHeader bundleClasspathheader = bundle.getManifestHeader(Constants.BUNDLE_CLASSPATH);
127         
128         IPackageFragmentRoot[] roots = ManifestUtils.findPackageFragmentRoots(bundleClasspathheader, project);
129         // Running list of packages in the project
130
Set JavaDoc packages = new HashSet JavaDoc();
131         for (int i = 0; i < roots.length; i++) {
132             try {
133                 if (ManifestUtils.isImmediateRoot(roots[i])) {
134                     IJavaElement[] elements = roots[i].getChildren();
135                     for (int j = 0; j < elements.length; j++)
136                         if (elements[j] instanceof IPackageFragment) {
137                             IPackageFragment fragment = (IPackageFragment)elements[j];
138                             String JavaDoc name = fragment.getElementName();
139                             if (name.length() == 0)
140                                 name = "."; //$NON-NLS-1$
141
if ((fragment.hasChildren() || fragment.getNonJavaResources().length > 0)){
142                                 if (addMissing && !header.hasPackage(name))
143                                     header.addPackage(new ExportPackageObject(header, fragment, Constants.VERSION_ATTRIBUTE));
144                                 else
145                                     packages.add(name);
146                             }
147                         }
148                 }
149             } catch (JavaModelException e) {
150             }
151         }
152         
153         // Remove packages that don't exist
154
if (removeUnresolved)
155             for (int i = 0; i < currentPkgs.length; i++)
156                 if (!packages.contains(currentPkgs[i].getName()))
157                     header.removePackage(currentPkgs[i]);
158     }
159
160     public static void markPackagesInternal(IBundle bundle, String JavaDoc packageFilter) {
161         if (packageFilter == null || bundle == null || !(bundle instanceof Bundle))
162             return;
163         
164         ExportPackageHeader header = (ExportPackageHeader)bundle.getManifestHeader(Constants.EXPORT_PACKAGE);
165         if (header == null)
166             return;
167         
168         ExportPackageObject[] currentPkgs = header.getPackages();
169         Pattern JavaDoc pat = PatternConstructor.createPattern(packageFilter, false);
170         for (int i = 0; i < currentPkgs.length; i++) {
171             String JavaDoc values = currentPkgs[i].getValueComponents()[0];
172             if (!currentPkgs[i].isInternal()
173                     && currentPkgs[i].getFriends().length == 0
174                     && pat.matcher(values).matches()) {
175                 currentPkgs[i].setInternal(true);
176             }
177         }
178     }
179     
180     public static void organizeImportPackages(IBundle bundle, boolean removeImports) {
181         if (!(bundle instanceof Bundle))
182             return;
183         ImportPackageHeader header = (ImportPackageHeader)((Bundle)bundle).getManifestHeader(Constants.IMPORT_PACKAGE);
184         if (header == null)
185             return;
186         ImportPackageObject[] importedPackages = header.getPackages();
187         Set JavaDoc availablePackages = getAvailableExportedPackages();
188         // get Preference
189
for (int i = 0; i < importedPackages.length; i++) {
190             String JavaDoc pkgName = importedPackages[i].getName();
191             if (!availablePackages.contains(pkgName)){
192                 if (removeImports)
193                     header.removePackage(importedPackages[i]);
194                 else {
195                     importedPackages[i].setOptional(true);
196                 }
197             }
198         }
199     }
200     
201     private static final Set JavaDoc getAvailableExportedPackages() {
202         State state = TargetPlatformHelper.getState();
203         ExportPackageDescription[] packages = state.getExportedPackages();
204         Set JavaDoc set = new HashSet JavaDoc();
205         for (int i = 0; i < packages.length; i++) {
206             set.add(packages[i].getName());
207         }
208         return set;
209     }
210
211
212     
213     public static void removeUnneededLazyStart(IBundle bundle) {
214         if (!(bundle instanceof Bundle))
215             return;
216         if (bundle.getHeader(Constants.BUNDLE_ACTIVATOR) == null) {
217             String JavaDoc[] remove = new String JavaDoc[] {
218                     ICoreConstants.ECLIPSE_LAZYSTART, ICoreConstants.ECLIPSE_AUTOSTART};
219             for (int i = 0; i < remove.length; i++) {
220                 IManifestHeader lazy = ((Bundle)bundle).getManifestHeader(remove[i]);
221                 if (lazy instanceof SingleManifestHeader)
222                     ((SingleManifestHeader)lazy).setMainComponent(null);
223             }
224         }
225         
226     }
227     
228     public static void removeUnusedKeys(
229             final IProject project,
230             final IBundle bundle,
231             final IPluginModelBase modelBase) {
232         String JavaDoc localization = bundle.getLocalization();
233         if (localization == null)
234             localization = "plugin"; //$NON-NLS-1$
235
IFile propertiesFile = project.getFile(localization + ".properties"); //$NON-NLS-1$
236
if (!propertiesFile.exists())
237             return;
238         
239         PDEModelUtility.modifyModel(new ModelModification(propertiesFile) {
240             protected void modifyModel(IBaseModel model, IProgressMonitor monitor) throws CoreException {
241                 if (!(model instanceof IBuildModel))
242                     return;
243
244                 IBuild build = ((IBuildModel)model).getBuild();
245                 IBuildEntry[] entries = build.getBuildEntries();
246                 ArrayList JavaDoc allKeys = new ArrayList JavaDoc(entries.length);
247                 for (int i = 0; i < entries.length; i++)
248                     if (!allKeys.contains(entries[i].getName()))
249                         allKeys.add(entries[i].getName());
250                 
251                 ArrayList JavaDoc usedkeys = new ArrayList JavaDoc();
252                 findTranslatedStrings(project, modelBase, bundle, usedkeys);
253                 
254                 for (int i = 0; i < usedkeys.size(); i++)
255                     allKeys.remove(usedkeys.get(i));
256                 
257                 if (allKeys.size() == 0)
258                     return;
259                 
260                 // scan properties file for keys referencing other keys
261
for (int i = 0; i < entries.length; i++) {
262                     String JavaDoc[] tokens = entries[i].getTokens();
263                     if (tokens == null || tokens.length == 0)
264                         continue;
265                     String JavaDoc entry = tokens[0];
266                     for (int k = 1; k < tokens.length; k++)
267                         entry += ',' + tokens[k];
268                     if (entry.indexOf('%') == entry.lastIndexOf('%'))
269                         continue;
270                     
271                     // allKeys must NOT have any duplicates
272
for (int j = 0; j < allKeys.size(); j++) {
273                         String JavaDoc akey = '%' + (String JavaDoc)allKeys.get(j) + '%';
274                         if (entry.indexOf(akey) != -1)
275                             allKeys.remove(allKeys.get(j--));
276                         if (allKeys.size() == 0)
277                             return;
278                     }
279                 }
280                 
281                 for (int i = 0; i < allKeys.size(); i++) {
282                     IBuildEntry entry = build.getEntry((String JavaDoc)allKeys.get(i));
283                     build.remove(entry);
284                 }
285             }
286         }, null);
287     }
288     
289     private static void findTranslatedStrings(IProject project, IPluginModelBase pluginModel, IBundle bundle, ArrayList JavaDoc list) {
290         
291         findTranslatedXMLStrings(pluginModel, list);
292         findTranslatedMFStrings(bundle, list);
293         
294         IPluginModelBase model = PluginRegistry.findModel(project);
295         
296         BundleDescription bundleDesc = model.getBundleDescription();
297         HostSpecification hostSpec = bundleDesc.getHost();
298         if (hostSpec != null) {
299             BundleDescription[] hosts = hostSpec.getHosts();
300             for (int i = 0; i < hosts.length; i++) {
301                 IPluginModelBase hostModel = PluginRegistry.findModel(hosts[i]);
302                 if (hostModel != null) {
303                     findTranslatedXMLStrings(getTextModel(hostModel, false), list);
304                     findTranslatedMFStrings(getTextBundle(hostModel), list);
305                 }
306             }
307         } else {
308             IFragmentModel[] fragmentModels = PDEManager.findFragmentsFor(model);
309             for (int i = 0; i < fragmentModels.length; i++) {
310                 findTranslatedXMLStrings(getTextModel(fragmentModels[i], true), list);
311                 findTranslatedMFStrings(getTextBundle(fragmentModels[i]), list);
312             }
313         }
314     }
315     
316     private static IPluginModelBase getTextModel(IPluginModelBase model, boolean fragment) {
317         if (model instanceof PluginModel || model instanceof FragmentModel)
318             return model;
319
320         if (model != null) {
321             if (!fileExists(model.getInstallLocation(),
322                     fragment ? F_FRAGMENT_FILE : F_PLUGIN_FILE))
323                 return null;
324             IDocument doc = CoreUtility.getTextDocument(
325                     new File JavaDoc(model.getInstallLocation()),
326                     fragment ? F_FRAGMENT_FILE : F_PLUGIN_FILE);
327             IPluginModelBase returnModel;
328             if (fragment)
329                 returnModel = new FragmentModel(doc, false);
330             else
331                 returnModel = new PluginModel(doc, false);
332             try {
333                 returnModel.load();
334             } catch (CoreException e) {}
335             
336             if (returnModel.isLoaded())
337                 return returnModel;
338         }
339         return null;
340     }
341     
342     private static IBundle getTextBundle(IPluginModelBase model) {
343         if (model != null) {
344             if (!fileExists(model.getInstallLocation(), F_MANIFEST_FILE))
345                 return null;
346             IDocument doc = CoreUtility.getTextDocument(
347                     new File JavaDoc(model.getInstallLocation()), F_MANIFEST_FILE);
348             IBundleModel bundleModel = new BundleModel(doc, false);
349             try {
350                 bundleModel.load();
351             } catch (CoreException e) {}
352             
353             if (bundleModel.isLoaded())
354                 return bundleModel.getBundle();
355         }
356         return null;
357     }
358     
359     private static void findTranslatedXMLStrings(IPluginModelBase model, ArrayList JavaDoc list) {
360         if (model == null)
361             return;
362         
363         IPluginExtensionPoint[] points = model.getPluginBase().getExtensionPoints();
364         for (int i = 0; i < points.length; i++) {
365             String JavaDoc value = getTranslatedKey(points[i].getName());
366             if (value != null && !list.contains(value))
367                 list.add(value);
368         }
369         IPluginExtension[] extensions = model.getPluginBase().getExtensions();
370         for (int i = 0; i < extensions.length; i++)
371             if (extensions[i] instanceof IDocumentNode)
372                 inspectElementForTranslation((IDocumentNode)extensions[i], list);
373     }
374     
375     private static void inspectElementForTranslation(IDocumentNode parent, ArrayList JavaDoc list) {
376         IDocumentTextNode text = parent.getTextNode();
377         String JavaDoc textValue = getTranslatedKey(text != null ? text.getText() : null);
378         if (textValue != null && !list.contains(textValue))
379             list.add(textValue);
380         
381         IDocumentAttribute[] attributes = parent.getNodeAttributes();
382         for (int j = 0; j < attributes.length; j++) {
383             String JavaDoc attrValue = getTranslatedKey(attributes[j].getAttributeValue());
384             if (attrValue != null && !list.contains(attrValue))
385                 list.add(attrValue);
386         }
387         
388         if (!(parent instanceof IPluginParent))
389             return;
390         
391         IPluginObject[] children = ((IPluginParent)parent).getChildren();
392         for (int i = 0; i < children.length; i++)
393             if (children[i] instanceof IDocumentNode)
394                 inspectElementForTranslation((IDocumentNode)children[i], list);
395     }
396     
397     private static void findTranslatedMFStrings(IBundle bundle, ArrayList JavaDoc list) {
398         if (bundle == null)
399             return;
400         for (int i = 0; i < ICoreConstants.TRANSLATABLE_HEADERS.length; i++) {
401             String JavaDoc key = getTranslatedKey(bundle.getHeader(ICoreConstants.TRANSLATABLE_HEADERS[i]));
402             if (key != null && !list.contains(key))
403                 list.add(key);
404         }
405     }
406     
407     private static String JavaDoc getTranslatedKey(String JavaDoc value) {
408         if (value != null && value.length() > 1
409                 && value.charAt(0) == '%' && value.charAt(1) != '%')
410             return value.substring(1);
411         return null;
412     }
413     
414     private static boolean fileExists(String JavaDoc container, String JavaDoc filename) {
415         return new File JavaDoc(container + filename).exists();
416     }
417     
418     /**
419      * Finds all resource paths ending with a valid icon file extension and creates
420      * a text edit operation in <code>multiEdit</code> for each one that is not prefixed by an
421      * $nl$ segment.
422      *
423      * @param model -
424      */

425     public static void prefixIconPaths(IPluginModelBase model) {
426         if (model == null)
427             return;
428         
429         SchemaRegistry registry = PDECore.getDefault().getSchemaRegistry();
430         IPluginExtension[] extensions = model.getPluginBase().getExtensions();
431         for (int i = 0; i < extensions.length; i++) {
432             ISchema schema = registry.getSchema(extensions[i].getPoint());
433             if (schema != null)
434                 inspectElementsIconPaths(schema, extensions[i]);
435         }
436     }
437     
438     private static void inspectElementsIconPaths(ISchema schema, IPluginParent parent) {
439         IPluginObject[] children = parent.getChildren();
440         for (int i = 0; i < children.length; i++) {
441             IPluginElement child = (IPluginElement)children[i];
442             ISchemaElement schemaElement = schema.findElement(child.getName());
443             if (schemaElement != null) {
444                 IPluginAttribute[] attributes = child.getAttributes();
445                 for (int j = 0; j < attributes.length; j++) {
446                     ISchemaAttribute attInfo = schemaElement.getAttribute(attributes[j].getName());
447                     if (attInfo != null && attInfo.getKind() == IMetaAttribute.RESOURCE) {
448                         String JavaDoc value = attributes[j].getValue();
449                         if (value.startsWith(F_NL_PREFIX))
450                             continue;
451                         int fileExtIndex = value.lastIndexOf('.');
452                         if (fileExtIndex == -1)
453                             continue;
454                         value = value.substring(fileExtIndex + 1);
455                         for (int e = 0; e < F_ICON_EXTENSIONS.length; e++) {
456                             if (value.equalsIgnoreCase(F_ICON_EXTENSIONS[e])) {
457                                 IPath path = new Path(F_NL_PREFIX);
458                                 String JavaDoc newValue = attributes[j].getValue();
459                                 if (newValue.charAt(0) != IPath.SEPARATOR)
460                                     path = path.addTrailingSeparator();
461                                 newValue = path.toString() + newValue;
462                                 try {
463                                     child.setAttribute(attributes[j].getName(), newValue);
464                                 } catch (CoreException e1) {
465                                 }
466                                 break;
467                             }
468                         }
469                     }
470                 }
471             }
472             inspectElementsIconPaths(schema, child);
473         }
474     }
475     
476     protected static MultiTextEdit getTextEdit(IModelTextChangeListener listener) {
477         if (listener == null)
478             return null;
479         TextEdit[] edits = listener.getTextOperations();
480         if (edits.length == 0)
481             return null;
482         MultiTextEdit multiEdit = new MultiTextEdit();
483         multiEdit.addChildren(edits);
484         return multiEdit;
485     }
486     
487 }
488
Popular Tags