1 11 package org.eclipse.pde.internal.ui.util; 12 13 import java.util.ArrayList ; 14 import java.util.Hashtable ; 15 import java.util.Iterator ; 16 17 import org.eclipse.core.filebuffers.FileBuffers; 18 import org.eclipse.core.filebuffers.ITextFileBuffer; 19 import org.eclipse.core.filebuffers.ITextFileBufferManager; 20 import org.eclipse.core.resources.IFile; 21 import org.eclipse.core.resources.IProject; 22 import org.eclipse.core.runtime.CoreException; 23 import org.eclipse.core.runtime.IProgressMonitor; 24 import org.eclipse.jface.text.BadLocationException; 25 import org.eclipse.jface.text.IDocument; 26 import org.eclipse.pde.core.IBaseModel; 27 import org.eclipse.pde.core.plugin.IPluginModelBase; 28 import org.eclipse.pde.core.plugin.ISharedExtensionsModel; 29 import org.eclipse.pde.internal.core.bundle.BundleFragmentModel; 30 import org.eclipse.pde.internal.core.bundle.BundlePluginModel; 31 import org.eclipse.pde.internal.core.ibundle.IBundleModel; 32 import org.eclipse.pde.internal.core.ibundle.IBundlePluginModelBase; 33 import org.eclipse.pde.internal.core.text.AbstractEditingModel; 34 import org.eclipse.pde.internal.core.text.IEditingModel; 35 import org.eclipse.pde.internal.core.text.IModelTextChangeListener; 36 import org.eclipse.pde.internal.core.text.build.BuildModel; 37 import org.eclipse.pde.internal.core.text.build.PropertiesTextChangeListener; 38 import org.eclipse.pde.internal.core.text.bundle.BundleModel; 39 import org.eclipse.pde.internal.core.text.bundle.BundleTextChangeListener; 40 import org.eclipse.pde.internal.core.text.plugin.FragmentModel; 41 import org.eclipse.pde.internal.core.text.plugin.PluginModel; 42 import org.eclipse.pde.internal.core.text.plugin.XMLTextChangeListener; 43 import org.eclipse.pde.internal.ui.IPDEUIConstants; 44 import org.eclipse.pde.internal.ui.PDEPlugin; 45 import org.eclipse.pde.internal.ui.editor.PDEFormEditor; 46 import org.eclipse.pde.internal.ui.editor.build.BuildEditor; 47 import org.eclipse.pde.internal.ui.editor.build.BuildInputContext; 48 import org.eclipse.pde.internal.ui.editor.build.BuildSourcePage; 49 import org.eclipse.pde.internal.ui.editor.context.InputContext; 50 import org.eclipse.pde.internal.ui.editor.plugin.ManifestEditor; 51 import org.eclipse.pde.internal.ui.editor.schema.SchemaEditor; 52 import org.eclipse.pde.internal.ui.editor.schema.SchemaInputContext; 53 import org.eclipse.pde.internal.ui.editor.site.SiteEditor; 54 import org.eclipse.swt.widgets.Display; 55 import org.eclipse.text.edits.MalformedTreeException; 56 import org.eclipse.text.edits.MultiTextEdit; 57 import org.eclipse.text.edits.TextEdit; 58 import org.eclipse.ui.IEditorInput; 59 import org.eclipse.ui.IEditorPart; 60 import org.eclipse.ui.IFileEditorInput; 61 import org.eclipse.ui.forms.editor.IFormPage; 62 import org.osgi.framework.Constants; 63 64 68 public class PDEModelUtility { 69 70 public static final String F_MANIFEST = "MANIFEST.MF"; public static final String F_MANIFEST_FP = "META-INF/" + F_MANIFEST; public static final String F_PLUGIN = "plugin.xml"; public static final String F_FRAGMENT = "fragment.xml"; public static final String F_PROPERTIES = ".properties"; public static final String F_BUILD = "build" + F_PROPERTIES; 77 private static final int F_Bi = 0; private static final int F_Xi = 1; 81 private static Hashtable fOpenPDEEditors = new Hashtable (); 82 83 91 public static void connect(PDEFormEditor editor) { 92 IProject project = editor.getCommonProject(); 93 if (project == null) 94 return; 95 if (fOpenPDEEditors.containsKey(project)) { 96 ArrayList list = (ArrayList )fOpenPDEEditors.get(project); 97 if (!list.contains(editor)) 98 list.add(editor); 99 } else { 100 ArrayList list = new ArrayList (); 101 list.add(editor); 102 fOpenPDEEditors.put(project, list); 103 } 104 } 105 106 110 public static void disconnect(PDEFormEditor editor) { 111 IProject project = editor.getCommonProject(); 112 if (project == null) 113 return; 114 if (!fOpenPDEEditors.containsKey(project)) 115 return; 116 ArrayList list = (ArrayList )fOpenPDEEditors.get(project); 117 list.remove(editor); 118 if (list.size() == 0) 119 fOpenPDEEditors.remove(project); 120 } 121 122 127 public static ManifestEditor getOpenManifestEditor(IProject project) { 128 return (ManifestEditor)getOpenEditor(project, IPDEUIConstants.MANIFEST_EDITOR_ID); 129 } 130 131 136 public static BuildEditor getOpenBuildPropertiesEditor(IProject project) { 137 return (BuildEditor) getOpenEditor(project, IPDEUIConstants.BUILD_EDITOR_ID); 138 } 139 140 145 public static SiteEditor getOpenUpdateSiteEditor(IProject project) { 146 return (SiteEditor) getOpenEditor(project, IPDEUIConstants.SITE_EDITOR_ID); 147 } 148 149 private static PDEFormEditor getOpenEditor(IProject project, String editorId) { 150 ArrayList list = (ArrayList )fOpenPDEEditors.get(project); 151 if (list == null) 152 return null; 153 for (int i = 0; i < list.size(); i++) { 154 PDEFormEditor editor = (PDEFormEditor)list.get(i); 155 if (editor.getEditorSite().getId().equals(editorId)) 156 return editor; 157 } 158 return null; 159 } 160 161 166 public static SchemaEditor getOpenSchemaEditor(IFile file) { 167 return (SchemaEditor)getOpenEditor( 168 IPDEUIConstants.SCHEMA_EDITOR_ID, 169 SchemaInputContext.CONTEXT_ID, 170 file); 171 } 172 173 179 private static PDEFormEditor getOpenEditor(String editorID, 180 String inputContextID, IFile file) { 181 IProject project = file.getProject(); 183 ArrayList list = (ArrayList )fOpenPDEEditors.get(project); 185 if (list == null) { 187 return null; 188 } 189 for (int i = 0; i < list.size(); i++) { 194 PDEFormEditor editor = (PDEFormEditor)list.get(i); 196 String currentEditorID = editor.getEditorSite().getId(); 199 if (currentEditorID.equals(editorID) == false) { 200 continue; 201 } 202 InputContext context = 205 editor.getContextManager().findContext(inputContextID); 206 if (context == null) { 208 continue; 209 } 210 IEditorInput input = context.getInput(); 212 if ((input instanceof IFileEditorInput) == false) { 214 continue; 215 } 216 IFile currentFile = ((IFileEditorInput)input).getFile(); 218 if (currentFile.equals(file)) { 221 return editor; 222 } 223 } 224 return null; 225 } 226 227 232 public static IPluginModelBase getActivePluginModel() { 233 IEditorPart editor = PDEPlugin.getActivePage().getActiveEditor(); 234 if (editor instanceof ManifestEditor) { 235 IBaseModel model = ((ManifestEditor)editor).getAggregateModel(); 236 if (model instanceof IPluginModelBase) 237 return (IPluginModelBase)model; 238 } 239 return null; 240 } 241 242 247 public static IEditingModel getOpenModel(IDocument doc) { 248 Iterator it = fOpenPDEEditors.values().iterator(); 249 while (it.hasNext()) { 250 ArrayList list = (ArrayList )it.next(); 251 for (int i = 0; i < list.size(); i++) { 252 PDEFormEditor e = (PDEFormEditor)list.get(i); 253 IPluginModelBase model = (IPluginModelBase)e.getAggregateModel(); 254 if (model instanceof IBundlePluginModelBase) { 255 IBundleModel bModel = ((IBundlePluginModelBase)model).getBundleModel(); 256 if (bModel instanceof IEditingModel && 257 doc == ((IEditingModel)bModel).getDocument()) 258 return (IEditingModel)bModel; 259 ISharedExtensionsModel eModel = ((IBundlePluginModelBase)model).getExtensionsModel(); 260 if (eModel instanceof IEditingModel && 261 doc == ((IEditingModel)eModel).getDocument()) 262 return (IEditingModel)eModel; 263 } 264 265 270 if (model instanceof IEditingModel && 271 doc == ((IEditingModel)model).getDocument()) 272 return (IEditingModel)model; 273 } 274 } 275 return null; 276 } 277 278 292 public static void modifyModel(final ModelModification modification, final IProgressMonitor monitor) { 293 if (modification.getFile() == null) 296 return; 297 298 PDEFormEditor editor = getOpenEditor(modification); 299 IBaseModel model = getModelFromEditor(editor, modification); 300 301 if (model != null) { 302 modifyEditorModel(modification, editor, model, monitor); 304 } else { 305 ITextFileBufferManager manager = FileBuffers.getTextFileBufferManager(); 307 IFile[] files; 308 if (modification.isFullBundleModification()) { 309 files = new IFile[2]; 310 files[F_Bi] = modification.getManifestFile(); 311 files[F_Xi] = modification.getXMLFile(); 312 } else { 313 files = new IFile[] { modification.getFile() }; 314 } 315 int sc = 0; 318 try { 319 ITextFileBuffer[] buffers = new ITextFileBuffer[files.length]; 320 IDocument[] documents = new IDocument[files.length]; 321 for (int i = 0; i < files.length; i++) { 322 if (files[i] == null || !files[i].exists()) 323 continue; 324 manager.connect(files[i].getFullPath(), monitor); 325 sc++; 326 buffers[i] = manager.getTextFileBuffer(files[i].getFullPath()); 327 if (buffers[i].isDirty()) 328 buffers[i].commit(monitor, true); 329 documents[i] = buffers[i].getDocument(); 330 } 331 332 IBaseModel editModel; 333 if (modification.isFullBundleModification()) 334 editModel = prepareBundlePluginModel(files, documents); 335 else 336 editModel = prepareAbstractEditingModel(files[0], documents[0]); 337 338 modification.modifyModel(editModel, monitor); 339 340 IModelTextChangeListener[] listeners = gatherListeners(editModel); 341 for (int i = 0; i < listeners.length; i++) { 342 if (listeners[i] == null) 343 continue; 344 TextEdit[] edits = listeners[i].getTextOperations(); 345 if (edits.length > 0) { 346 MultiTextEdit multi = new MultiTextEdit(); 347 multi.addChildren(edits); 348 multi.apply(documents[i]); 349 buffers[i].commit(monitor, true); 350 } 351 } 352 } catch (CoreException e) { 353 PDEPlugin.log(e); 354 } catch (MalformedTreeException e) { 355 PDEPlugin.log(e); 356 } catch (BadLocationException e) { 357 PDEPlugin.log(e); 358 } finally { 359 int dc = 0; 362 for (int i = 0; i < files.length && dc <= sc; i++) { 363 if (files[i] == null || !files[i].exists()) 364 continue; 365 try { 366 manager.disconnect(files[i].getFullPath(), monitor); 367 dc++; 368 } catch (CoreException e) { 369 PDEPlugin.log(e); 370 } 371 } 372 } 373 } 374 } 375 376 private static void modifyEditorModel( 377 final ModelModification mod, 378 final PDEFormEditor editor, 379 final IBaseModel model, 380 final IProgressMonitor monitor) { 381 getDisplay().syncExec(new Runnable () { 382 public void run() { 383 try { 384 mod.modifyModel(model, monitor); 385 IFile[] files = new IFile[] { 386 mod.getManifestFile(), 387 mod.getXMLFile(), 388 mod.getPropertiesFile() 389 }; 390 for (int i = 0; i < files.length; i++) { 391 if (files[i] == null) 392 continue; 393 InputContext con = editor.getContextManager().findContext(files[i]); 394 if (con != null) 395 con.flushEditorInput(); 396 } 397 if (mod.saveOpenEditor()) 398 editor.doSave(monitor); 399 } catch (CoreException e) { 400 PDEPlugin.log(e); 401 } 402 } 403 }); 404 } 405 406 private static PDEFormEditor getOpenEditor(ModelModification modification) { 407 IProject project = modification.getFile().getProject(); 408 String name = modification.getFile().getName(); 409 if (name.equals(F_PLUGIN) || name.equals(F_FRAGMENT) || name.equals(F_MANIFEST)) { 410 return getOpenManifestEditor(project); 411 } else if (name.equals(F_BUILD)) { 412 PDEFormEditor openEditor = getOpenBuildPropertiesEditor(project); 413 if (openEditor == null) 414 openEditor = getOpenManifestEditor(project); 415 return openEditor; 416 } 417 return null; 418 } 419 420 private static IBaseModel getModelFromEditor(PDEFormEditor openEditor, ModelModification modification) { 421 if (openEditor == null) 422 return null; 423 String name = modification.getFile().getName(); 424 IBaseModel model = null; 425 if (name.equals(F_PLUGIN) || name.equals(F_FRAGMENT)) { 426 model = openEditor.getAggregateModel(); 427 if (model instanceof IBundlePluginModelBase) 428 model = ((IBundlePluginModelBase)model).getExtensionsModel(); 429 } else if (name.equals(F_BUILD)) { 430 if (openEditor instanceof BuildEditor) { 431 model = openEditor.getAggregateModel(); 432 } else if (openEditor instanceof ManifestEditor) { 433 IFormPage page = openEditor.findPage(BuildInputContext.CONTEXT_ID); 434 if (page instanceof BuildSourcePage) 435 model = ((BuildSourcePage)page).getInputContext().getModel(); 436 } 437 } else if (name.equals(F_MANIFEST)) { 438 model = openEditor.getAggregateModel(); 439 if (model instanceof IBundlePluginModelBase) 440 return model; 441 } 442 if (model instanceof AbstractEditingModel) 443 return model; 444 return null; 445 } 446 447 private static IModelTextChangeListener createListener(String filename, IDocument doc) { 448 if (filename.equals(F_PLUGIN) || filename.equals(F_FRAGMENT)) 449 return new XMLTextChangeListener(doc); 450 else if (filename.equals(F_MANIFEST)) 451 return new BundleTextChangeListener(doc); 452 else if (filename.endsWith(F_PROPERTIES)) 453 return new PropertiesTextChangeListener(doc); 454 return null; 455 } 456 457 private static AbstractEditingModel prepareAbstractEditingModel(IFile file, IDocument doc) { 458 AbstractEditingModel model; 459 String filename = file.getName(); 460 if (filename.equals(F_MANIFEST)) 461 model = new BundleModel(doc, true); 462 else if (filename.equals(F_FRAGMENT)) 463 model = new FragmentModel(doc, true); 464 else if (filename.equals(F_PLUGIN)) 465 model = new PluginModel(doc, true); 466 else if (filename.endsWith(F_PROPERTIES)) 467 model = new BuildModel(doc, true); 468 else 469 return null; 470 model.setUnderlyingResource(file); 471 try { 472 model.load(); 473 IModelTextChangeListener listener = createListener(filename, doc); 474 model.addModelChangedListener(listener); 475 } catch (CoreException e) { 476 PDEPlugin.log(e); 477 } 478 return model; 479 } 480 481 private static IBaseModel prepareBundlePluginModel(IFile[] files, IDocument[] docs) throws CoreException { 482 AbstractEditingModel[] models = new AbstractEditingModel[docs.length]; 483 484 boolean isFragment = false; 485 models[F_Bi] = prepareAbstractEditingModel(files[F_Bi], docs[F_Bi]); 486 if (models[F_Bi] instanceof IBundleModel) 487 isFragment = ((IBundleModel)models[F_Bi]).getBundle().getHeader(Constants.FRAGMENT_HOST) != null; 488 489 IBundlePluginModelBase pluginModel; 490 if (isFragment) 491 pluginModel = new BundleFragmentModel(); 492 else 493 pluginModel = new BundlePluginModel(); 494 495 pluginModel.setBundleModel((IBundleModel)models[F_Bi]); 496 if (files.length > F_Xi && files[F_Xi] != null) { 497 models[F_Xi] = prepareAbstractEditingModel(files[F_Xi], docs[F_Xi]); 498 pluginModel.setExtensionsModel((ISharedExtensionsModel)models[F_Xi]); 499 } 500 return pluginModel; 501 } 502 503 private static IModelTextChangeListener[] gatherListeners(IBaseModel editModel) { 504 IModelTextChangeListener[] listeners = new IModelTextChangeListener[0]; 505 if (editModel instanceof AbstractEditingModel) 506 listeners = new IModelTextChangeListener[] { 507 ((AbstractEditingModel)editModel).getLastTextChangeListener()}; 508 if (editModel instanceof IBundlePluginModelBase) { 509 IBundlePluginModelBase modelBase = (IBundlePluginModelBase)editModel; 510 listeners = new IModelTextChangeListener[2]; 511 listeners[F_Bi] = gatherListener(modelBase.getBundleModel()); 512 listeners[F_Xi] = gatherListener(modelBase.getExtensionsModel()); 513 return listeners; 514 } 515 return listeners; 516 } 517 518 private static IModelTextChangeListener gatherListener(IBaseModel model) { 519 if (model instanceof AbstractEditingModel) 520 return((AbstractEditingModel)model).getLastTextChangeListener(); 521 return null; 522 } 523 524 private static Display getDisplay() { 525 Display display = Display.getCurrent(); 526 if (display == null) 527 display = Display.getDefault(); 528 return display; 529 } 530 } 531 | Popular Tags |