1 11 package org.eclipse.pde.internal.ui.wizards.tools; 12 13 import java.io.File ; 14 import java.util.ArrayList ; 15 import java.util.HashSet ; 16 import java.util.Set ; 17 import java.util.regex.Pattern ; 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 F_NL_PREFIX = "$nl$"; private static String [] F_ICON_EXTENSIONS = new String [] { 87 "BMP", "ICO", "JPEG", "JPG", "GIF", "PNG", "TIFF" }; 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 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, ""); 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 Set packages = new HashSet (); 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 name = fragment.getElementName(); 139 if (name.length() == 0) 140 name = "."; 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 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 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 pat = PatternConstructor.createPattern(packageFilter, false); 170 for (int i = 0; i < currentPkgs.length; i++) { 171 String 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 availablePackages = getAvailableExportedPackages(); 188 for (int i = 0; i < importedPackages.length; i++) { 190 String 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 getAvailableExportedPackages() { 202 State state = TargetPlatformHelper.getState(); 203 ExportPackageDescription[] packages = state.getExportedPackages(); 204 Set set = new HashSet (); 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 [] remove = new String [] { 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 localization = bundle.getLocalization(); 233 if (localization == null) 234 localization = "plugin"; IFile propertiesFile = project.getFile(localization + ".properties"); 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 allKeys = new ArrayList (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 usedkeys = new ArrayList (); 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 for (int i = 0; i < entries.length; i++) { 262 String [] tokens = entries[i].getTokens(); 263 if (tokens == null || tokens.length == 0) 264 continue; 265 String 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 for (int j = 0; j < allKeys.size(); j++) { 273 String akey = '%' + (String )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 )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 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 (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 (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 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 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 list) { 376 IDocumentTextNode text = parent.getTextNode(); 377 String 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 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 list) { 398 if (bundle == null) 399 return; 400 for (int i = 0; i < ICoreConstants.TRANSLATABLE_HEADERS.length; i++) { 401 String 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 getTranslatedKey(String 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 container, String filename) { 415 return new File (container + filename).exists(); 416 } 417 418 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 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 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 |