1 11 package org.eclipse.pde.internal.core; 12 13 import java.io.File ; 14 import java.io.FileNotFoundException ; 15 import java.io.IOException ; 16 import java.net.MalformedURLException ; 17 import java.net.URL ; 18 import java.util.ArrayList ; 19 import java.util.Dictionary ; 20 import java.util.HashMap ; 21 22 import org.eclipse.core.resources.IFile; 23 import org.eclipse.core.resources.IProject; 24 import org.eclipse.core.runtime.CoreException; 25 import org.eclipse.core.runtime.IProgressMonitor; 26 import org.eclipse.core.runtime.IStatus; 27 import org.eclipse.core.runtime.Platform; 28 import org.eclipse.core.runtime.Status; 29 import org.eclipse.osgi.service.pluginconversion.PluginConversionException; 30 import org.eclipse.osgi.service.resolver.BundleDescription; 31 import org.eclipse.osgi.service.resolver.State; 32 import org.eclipse.pde.core.plugin.IPluginModelBase; 33 import org.eclipse.pde.core.plugin.PluginRegistry; 34 import org.eclipse.pde.internal.core.bundle.BundleFragmentModel; 35 import org.eclipse.pde.internal.core.bundle.BundlePluginModel; 36 import org.eclipse.pde.internal.core.bundle.BundlePluginModelBase; 37 import org.eclipse.pde.internal.core.bundle.WorkspaceBundleModel; 38 import org.eclipse.pde.internal.core.plugin.ExternalFragmentModel; 39 import org.eclipse.pde.internal.core.plugin.ExternalPluginModel; 40 import org.eclipse.pde.internal.core.plugin.ExternalPluginModelBase; 41 import org.eclipse.pde.internal.core.plugin.WorkspaceExtensionsModel; 42 import org.eclipse.pde.internal.core.plugin.WorkspaceFragmentModel; 43 import org.eclipse.pde.internal.core.plugin.WorkspacePluginModel; 44 import org.eclipse.pde.internal.core.plugin.WorkspacePluginModelBase; 45 import org.eclipse.pde.internal.core.util.CoreUtility; 46 import org.w3c.dom.Node ; 47 48 49 public class PDEState extends MinimalState { 50 51 private PDEExtensionRegistry fExtensionRegistry; 52 private PDEAuxiliaryState fAuxiliaryState; 53 54 private ArrayList fTargetModels = new ArrayList (); 55 private ArrayList fWorkspaceModels = new ArrayList (); 56 private boolean fCombined; 57 private long fTargetTimestamp; 58 private boolean fNewState; 59 60 public PDEState(PDEState state) { 61 super(state); 62 fTargetModels = new ArrayList (state.fTargetModels); 63 fCombined = false; 64 fTargetTimestamp = state.fTargetTimestamp; 65 fAuxiliaryState = new PDEAuxiliaryState(state.fAuxiliaryState); 66 if (fAuxiliaryState.fPluginInfos.isEmpty()) 67 fAuxiliaryState.readPluginInfoCache(new File (DIR, Long.toString(fTargetTimestamp) + ".target")); fExtensionRegistry = new PDEExtensionRegistry(state.fExtensionRegistry); 69 } 70 71 public PDEState(URL [] urls, boolean resolve, IProgressMonitor monitor) { 72 this(new URL [0], urls, resolve, monitor); 73 } 74 75 public PDEState(URL [] workspace, URL [] target, boolean resolve, IProgressMonitor monitor) { 76 long start = System.currentTimeMillis(); 77 fExtensionRegistry = new PDEExtensionRegistry(); 78 fAuxiliaryState = new PDEAuxiliaryState(); 79 80 if (resolve) { 81 readTargetState(target, monitor); 82 } else { 83 createNewTargetState(resolve, target, monitor); 84 fExtensionRegistry.createExtensionDocument(fState); 85 } 86 createTargetModels(fState.getBundles()); 87 88 if (resolve && workspace.length > 0 && !fNewState && !"true".equals(System.getProperty("pde.nocache"))) readWorkspaceState(workspace); 90 91 fExtensionRegistry.clear(); 92 fAuxiliaryState.clear(); 93 94 if (DEBUG) 95 System.out.println("Time to create state: " + (System.currentTimeMillis() - start) + " ms"); } 97 98 private void readTargetState(URL [] urls, IProgressMonitor monitor) { 99 fTargetTimestamp = computeTimestamp(urls); 100 File dir = new File (DIR, Long.toString(fTargetTimestamp) + ".target"); if ((fState = readStateCache(dir)) == null || !fAuxiliaryState.readPluginInfoCache(dir)) { 102 createNewTargetState(true, urls, monitor); 103 if (!dir.exists()) 104 dir.mkdirs(); 105 fAuxiliaryState.savePluginInfo(dir); 106 resolveState(false); 107 saveState(dir); 108 } else { 109 boolean propertiesChanged = initializePlatformProperties(); 110 fState.setResolver(Platform.getPlatformAdmin().getResolver()); 111 if (propertiesChanged) 112 fState.resolve(false); 113 fId = fState.getBundles().length; 114 } 115 if (!fExtensionRegistry.readExtensionsCache(dir)) 116 fExtensionRegistry.saveExtensions(fState, dir); 117 } 118 119 private void createNewTargetState(boolean resolve, URL [] urls, IProgressMonitor monitor) { 120 fState = stateObjectFactory.createState(resolve); 121 monitor.beginTask("", urls.length); for (int i = 0; i < urls.length; i++) { 123 File file = new File (urls[i].getFile()); 124 try { 125 if (monitor.isCanceled()) 126 return; 128 monitor.subTask(file.getName()); 129 addBundle(file, -1); 130 } catch (PluginConversionException e) { 131 } catch (CoreException e) { 132 } catch (IOException e) { 133 PDECore.log(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, IStatus.ERROR, 134 "Invalid manifest format at " + file.getAbsolutePath(), null)); 136 } finally { 137 monitor.worked(1); 138 } 139 } 140 fNewState = true; 141 } 142 143 protected void addAuxiliaryData(BundleDescription desc, Dictionary manifest, boolean hasBundleStructure) { 144 fAuxiliaryState.addAuxiliaryData(desc, manifest, hasBundleStructure); 145 } 146 147 public IPluginModelBase[] createTargetModels(BundleDescription[] bundleDescriptions) { 148 HashMap models = new HashMap ((4/3) * bundleDescriptions.length + 1); 149 for (int i = 0; i < bundleDescriptions.length; i++) { 150 BundleDescription desc = bundleDescriptions[i]; 151 IPluginModelBase base = createExternalModel(desc); 152 fTargetModels.add(base); 153 models.put(desc.getSymbolicName(), base); 154 } 155 if (models.isEmpty()) 156 return new IPluginModelBase[0]; 157 return (IPluginModelBase[]) models.values().toArray(new IPluginModelBase[models.size()]); 158 } 159 160 private void readWorkspaceState(URL [] urls) { 161 long workspace = computeTimestamp(urls); 162 File dir = new File (DIR, Long.toString(workspace) + ".workspace"); State localState = readStateCache(dir); 164 fCombined = localState != null 165 && fAuxiliaryState.readPluginInfoCache(dir) 166 && fExtensionRegistry.readExtensionsCache(dir); 167 if (fCombined) { 168 long targetCount = fId; 169 BundleDescription[] bundles = localState.getBundles(); 170 for (int i = 0; i < bundles.length; i++) { 171 BundleDescription desc = bundles[i]; 172 String id = desc.getSymbolicName(); 173 BundleDescription[] conflicts = fState.getBundles(id); 174 175 for (int j = 0; j < conflicts.length; j++) { 176 if (conflicts[j].getBundleId() <= targetCount) 180 fState.removeBundle(conflicts[j]); 181 } 182 183 BundleDescription newbundle = stateObjectFactory.createBundleDescription(desc); 184 IPluginModelBase model = createWorkspaceModel(newbundle); 185 if (model != null && fState.addBundle(newbundle)) { 186 fId = Math.max(fId, newbundle.getBundleId()); 187 fWorkspaceModels.add(model); 188 } 189 } 190 fId = Math.max(fId, fState.getBundles().length); 191 fState.resolve(false); 192 } 193 } 194 195 public boolean isCombined() { 196 return fCombined; 197 } 198 199 private State readStateCache(File dir) { 200 if (dir.exists() && dir.isDirectory()) { 201 try { 202 return stateObjectFactory.readState(dir); 203 } catch (IllegalStateException e) { 204 PDECore.log(e); 205 } catch (FileNotFoundException e) { 206 PDECore.log(e); 207 } catch (IOException e) { 208 PDECore.log(e); 209 } finally { 210 } 211 } 212 return null; 213 } 214 215 private long computeTimestamp(URL [] urls) { 216 return computeTimestamp(urls, 0); 217 } 218 219 private long computeTimestamp(URL [] urls, long timestamp) { 220 for (int i = 0; i < urls.length; i++) { 221 File file = new File (urls[i].getFile()); 222 if (file.exists()) { 223 if (file.isFile()) { 224 timestamp ^= file.lastModified(); 225 } else { 226 File manifest = new File (file, "META-INF/MANIFEST.MF"); if (manifest.exists()) 228 timestamp ^= manifest.lastModified(); 229 manifest = new File (file, "plugin.xml"); if (manifest.exists()) 231 timestamp ^= manifest.lastModified(); 232 manifest = new File (file, "fragment.xml"); if (manifest.exists()) 234 timestamp ^= manifest.lastModified(); 235 } 236 timestamp ^= file.getAbsolutePath().hashCode(); 237 } 238 } 239 return timestamp; 240 } 241 242 private IPluginModelBase createWorkspaceModel(BundleDescription desc) { 243 String projectName = fAuxiliaryState.getProject(desc.getBundleId()); 244 if (projectName == null) 245 return null; 246 IProject project = PDECore.getWorkspace().getRoot().getProject(projectName); 247 if (!project.exists()) 248 return null; 249 if (project.exists(ICoreConstants.MANIFEST_PATH)) { 250 BundlePluginModelBase model = null; 251 if (desc.getHost() == null) 252 model = new BundlePluginModel(); 253 else 254 model = new BundleFragmentModel(); 255 model.setEnabled(true); 256 WorkspaceBundleModel bundle = new WorkspaceBundleModel(project.getFile("META-INF/MANIFEST.MF")); bundle.load(desc, this); 258 model.setBundleDescription(desc); 259 model.setBundleModel(bundle); 260 261 String filename = (desc.getHost() == null) ? "plugin.xml" : "fragment.xml"; IFile file = project.getFile(filename); 263 if (file.exists()) { 264 WorkspaceExtensionsModel extensions = new WorkspaceExtensionsModel(file); 265 extensions.load(desc, this); 266 extensions.setBundleModel(model); 267 model.setExtensionsModel(extensions); 268 } 269 return model; 270 } 271 272 WorkspacePluginModelBase model = null; 273 if (desc.getHost() == null) 274 model = new WorkspacePluginModel(project.getFile("plugin.xml"), true); else 276 model = new WorkspaceFragmentModel(project.getFile("fragment.xml"), true); model.load(desc, this); 278 model.setBundleDescription(desc); 279 return model; 280 } 281 282 private IPluginModelBase createExternalModel(BundleDescription desc) { 283 ExternalPluginModelBase model = null; 284 if (desc.getHost() == null) 285 model = new ExternalPluginModel(); 286 else 287 model = new ExternalFragmentModel(); 288 model.load(desc, this); 289 model.setBundleDescription(desc); 290 return model; 291 } 292 293 public IPluginModelBase[] getTargetModels() { 294 return (IPluginModelBase[])fTargetModels.toArray(new IPluginModelBase[fTargetModels.size()]); 295 } 296 297 public IPluginModelBase[] getWorkspaceModels() { 298 return (IPluginModelBase[])fWorkspaceModels.toArray(new IPluginModelBase[fWorkspaceModels.size()]); 299 } 300 301 public void shutdown() { 302 IPluginModelBase[] models = PluginRegistry.getWorkspaceModels(); 303 long timestamp = 0; 304 if (!"true".equals(System.getProperty("pde.nocache")) && shouldSaveState(models)) { timestamp = computeTimestamp(models); 306 File dir = new File (DIR, Long.toString(timestamp) + ".workspace"); State state = stateObjectFactory.createState(false); 308 for (int i = 0; i < models.length; i++) { 309 state.addBundle(models[i].getBundleDescription()); 310 } 311 saveState(state, dir); 312 PDEAuxiliaryState.writePluginInfo(models, dir); 313 PDEExtensionRegistry.writeExtensions(models, dir); 314 } 315 clearStaleStates(".target", fTargetTimestamp); clearStaleStates(".workspace", timestamp); clearStaleStates(".cache", 0); } 319 320 private long computeTimestamp(IPluginModelBase[] models) { 321 URL [] urls = new URL [models.length]; 322 for (int i = 0; i < models.length; i++) { 323 try { 324 IProject project = models[i].getUnderlyingResource().getProject(); 325 urls[i] = new File (project.getLocation().toString()).toURL(); 326 } catch (MalformedURLException e) { 327 } 328 } 329 return computeTimestamp(urls); 330 } 331 332 private boolean shouldSaveState(IPluginModelBase[] models) { 333 for (int i = 0; i < models.length; i++) { 334 String id = models[i].getPluginBase().getId(); 335 if (id == null 336 || id.trim().length() == 0 337 || !models[i].isLoaded() 338 || !models[i].isInSync() 339 || models[i].getBundleDescription() == null) 340 return false; 341 } 342 return models.length > 0; 343 } 344 345 private void clearStaleStates(String extension, long latest) { 346 File dir = new File (PDECore.getDefault().getStateLocation().toOSString()); 347 File [] children = dir.listFiles(); 348 if (children != null) { 349 for (int i = 0; i < children.length; i++) { 350 File child = children[i]; 351 if (child.isDirectory()) { 352 String name = child.getName(); 353 if (name.endsWith(extension) 354 && name.length() > extension.length() 355 && !name.equals(Long.toString(latest) + extension)) { 356 CoreUtility.deleteContent(child); 357 } 358 } 359 } 360 } 361 } 362 363 public Node [] getExtensions(long bundleID) { 364 return fExtensionRegistry.getExtensions(bundleID); 365 } 366 367 public Node [] getExtensionPoints(long bundleID) { 368 return fExtensionRegistry.getExtensionPoints(bundleID); 369 } 370 371 public Node [] getAllExtensions(long bundleID) { 372 return fExtensionRegistry.getAllExtensions(bundleID); 373 } 374 375 public String getClassName(long bundleID) { 376 return fAuxiliaryState.getClassName(bundleID); 377 } 378 379 public boolean hasExtensibleAPI(long bundleID) { 380 return fAuxiliaryState.hasExtensibleAPI(bundleID); 381 } 382 383 public boolean isPatchFragment(long bundleID) { 384 return fAuxiliaryState.isPatchFragment(bundleID); 385 } 386 387 public boolean hasBundleStructure(long bundleID) { 388 return fAuxiliaryState.hasBundleStructure(bundleID); 389 } 390 391 public String getSchemaVersion(long bundleID) { 392 return fExtensionRegistry.getSchemaVersion(bundleID); 393 } 394 395 public String getPluginName(long bundleID) { 396 return fAuxiliaryState.getPluginName(bundleID); 397 } 398 399 public String getProviderName(long bundleID) { 400 return fAuxiliaryState.getProviderName(bundleID); 401 } 402 403 public String [] getLibraryNames(long bundleID) { 404 return fAuxiliaryState.getLibraryNames(bundleID); 405 } 406 407 public String getBundleLocalization(long bundleID) { 408 return fAuxiliaryState.getBundleLocalization(bundleID); 409 } 410 411 public String getProject(long bundleID) { 412 return fAuxiliaryState.getProject(bundleID); 413 } 414 415 public BundleDescription[] addAdditionalBundles(URL [] newBundleURLs) { 416 ArrayList descriptions = new ArrayList (newBundleURLs.length); 418 for (int i = 0; i < newBundleURLs.length; i++) { 419 File file = new File (newBundleURLs[i].getFile()); 420 try { 421 BundleDescription desc = addBundle(file, -1); 422 if (desc != null) 423 descriptions.add(desc); 424 } catch (PluginConversionException e) { 425 } catch (CoreException e) { 426 } catch (IOException e) { 427 PDECore.log(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, IStatus.ERROR, 428 "Invalid manifest format at " + file.getAbsolutePath(), null)); 430 } 431 } 432 fTargetTimestamp = computeTimestamp(newBundleURLs, fTargetTimestamp); 434 File dir = new File (DIR, Long.toString(fTargetTimestamp) + ".target"); if (!dir.exists()) 436 dir.mkdirs(); 437 fAuxiliaryState.savePluginInfo(dir); 438 saveState(dir); 439 fExtensionRegistry.saveExtensions(fState, dir); 440 441 resolveState(false); 443 444 return (BundleDescription[]) descriptions.toArray(new BundleDescription[descriptions.size()]); 445 } 446 447 } 448 | Popular Tags |