KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > pde > internal > ui > wizards > product > UpdateSplashProgressOperation


1 /*******************************************************************************
2  * Copyright (c) 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
12 package org.eclipse.pde.internal.ui.wizards.product;
13
14 import org.eclipse.core.filebuffers.FileBuffers;
15 import org.eclipse.core.filebuffers.ITextFileBuffer;
16 import org.eclipse.core.filebuffers.ITextFileBufferManager;
17 import org.eclipse.core.filebuffers.LocationKind;
18 import org.eclipse.core.resources.IFile;
19 import org.eclipse.core.resources.IProject;
20 import org.eclipse.core.resources.IResource;
21 import org.eclipse.core.resources.IWorkspaceRunnable;
22 import org.eclipse.core.runtime.CoreException;
23 import org.eclipse.core.runtime.IPath;
24 import org.eclipse.core.runtime.IProgressMonitor;
25 import org.eclipse.core.runtime.IStatus;
26 import org.eclipse.core.runtime.NullProgressMonitor;
27 import org.eclipse.core.runtime.Status;
28 import org.eclipse.core.runtime.SubProgressMonitor;
29 import org.eclipse.jface.text.BadLocationException;
30 import org.eclipse.jface.text.IDocument;
31 import org.eclipse.pde.core.build.IBuildEntry;
32 import org.eclipse.pde.core.build.IBuildModel;
33 import org.eclipse.pde.core.plugin.IExtensionsModelFactory;
34 import org.eclipse.pde.core.plugin.IPluginAttribute;
35 import org.eclipse.pde.core.plugin.IPluginElement;
36 import org.eclipse.pde.core.plugin.IPluginExtension;
37 import org.eclipse.pde.core.plugin.IPluginModelBase;
38 import org.eclipse.pde.core.plugin.IPluginObject;
39 import org.eclipse.pde.internal.core.build.WorkspaceBuildModel;
40 import org.eclipse.pde.internal.core.text.build.BuildModel;
41 import org.eclipse.pde.internal.core.text.build.PropertiesTextChangeListener;
42 import org.eclipse.pde.internal.core.util.PDETextHelper;
43 import org.eclipse.pde.internal.ui.IPDEUIConstants;
44 import org.eclipse.pde.internal.ui.PDEUIMessages;
45 import org.eclipse.text.edits.MalformedTreeException;
46 import org.eclipse.text.edits.MultiTextEdit;
47 import org.eclipse.text.edits.TextEdit;
48
49 /**
50  * UpdateSplashProgressOperation
51  *
52  */

53 public class UpdateSplashProgressOperation implements IWorkspaceRunnable {
54
55     public static final String JavaDoc F_EXTENSION_PRODUCT = "org.eclipse.core.runtime.products"; //$NON-NLS-1$
56

57     public static final String JavaDoc F_ELEMENT_PRODUCT = "product"; //$NON-NLS-1$
58

59     public static final String JavaDoc F_ELEMENT_PROPERTY = "property"; //$NON-NLS-1$
60

61     public static final String JavaDoc F_ATTRIBUTE_NAME = "name"; //$NON-NLS-1$
62

63     public static final String JavaDoc F_ATTRIBUTE_VALUE = "value"; //$NON-NLS-1$
64

65     public static final String JavaDoc F_ATTRIBUTE_NAME_PREFCUST = "preferenceCustomization"; //$NON-NLS-1$
66

67     public static final String JavaDoc F_KEY_SHOW_PROGRESS = "org.eclipse.ui/SHOW_PROGRESS_ON_STARTUP"; //$NON-NLS-1$
68

69     public static final String JavaDoc F_FILE_NAME_PLUGIN_CUSTOM = "plugin_customization.ini"; //$NON-NLS-1$
70

71     private IPluginModelBase fModel;
72     
73     private IProgressMonitor fMonitor;
74     
75     private boolean fShowProgress;
76     
77     private IProject fProject;
78     
79     private String JavaDoc fProductID;
80     
81     protected String JavaDoc fPluginId;
82     
83     private ITextFileBufferManager fTextFileBufferManager;
84     
85     private ITextFileBuffer fTextFileBuffer;
86     
87     private PropertiesTextChangeListener fPropertiesListener;
88     
89     /**
90      *
91      */

92     public UpdateSplashProgressOperation() {
93         reset();
94     }
95     
96     /**
97      *
98      */

99     public void reset() {
100         // External Fields
101
fModel = null;
102         fMonitor = null;
103         fProductID = null;
104         fShowProgress = true;
105         fProject = null;
106         fPluginId = null;
107         // Internal Fields
108
fTextFileBufferManager = null;
109         fPropertiesListener = null;
110         fTextFileBuffer = null;
111     }
112     
113     /**
114      * @param pluginID
115      */

116     public void setPluginID(String JavaDoc pluginID) {
117         fPluginId = pluginID;
118     }
119     
120     /**
121      * @param model
122      */

123     public void setModel(IPluginModelBase model) {
124         fModel = model;
125     }
126     
127     /**
128      * @param monitor
129      */

130     private void setMonitor(IProgressMonitor monitor) {
131         if (monitor == null) {
132             monitor = new NullProgressMonitor();
133         }
134         fMonitor = monitor;
135     }
136     
137     /**
138      * @param showProgress
139      */

140     public void setShowProgress(boolean showProgress) {
141         fShowProgress = showProgress;
142     }
143     
144     /**
145      * @param productID
146      */

147     public void setProductID(String JavaDoc productID) {
148         fProductID = productID;
149     }
150     
151     /**
152      * @param project
153      */

154     public void setProject(IProject project) {
155         fProject = project;
156     }
157     
158     /* (non-Javadoc)
159      * @see org.eclipse.core.resources.IWorkspaceRunnable#run(org.eclipse.core.runtime.IProgressMonitor)
160      */

161     public void run(IProgressMonitor monitor) throws CoreException {
162         // Set the progress monitor
163
setMonitor(monitor);
164         // Perform the operation
165
fMonitor.beginTask(PDEUIMessages.UpdateSplashProgressAction_msgProgressCustomizingSplash, 10);
166         try {
167             update();
168         } finally {
169             fMonitor.done();
170         }
171     }
172     
173     /**
174      * @throws CoreException
175      */

176     private void update() throws CoreException {
177         // Find the product extension
178
IPluginExtension productExtension = findProductExtension();
179         fMonitor.worked(1);
180         // Ensure product extension exists
181
if (productExtension == null) {
182             // Something is seriously wrong
183
return;
184         }
185         // Find the product element
186
IPluginElement productElement = findProductElement(productExtension);
187         fMonitor.worked(1);
188         // Ensure product element exists
189
if (productElement == null) {
190             // Something is seriously wrong
191
return;
192         }
193         // Find the preference customization property
194
IPluginElement propertyElement = findPrefCustPropertyElement(productElement);
195         fMonitor.worked(1);
196         if ((propertyElement == null) &&
197                 fShowProgress) {
198             // Operation: Add progress
199
// The preference customization property does not exist
200
// Create it
201
addPreferenceCustomizationElement(productElement);
202         } else if (propertyElement == null) {
203             // Operation: Remove progress
204
// The preference customization property does not exist
205
// NO-OP
206
// Note: If plugin_customization.ini exists in the root of the
207
// plug-in, this is the default file name in the default location
208
// Its values will be loaded.
209
// Therefore, since it is possible for a the show progress on
210
// startup key to be present and true, make it false
211
updateDefaultPluginCustomizationFile();
212         } else {
213             // Operations: Add progress, Remove progress
214
// The preference customization property exists
215
// Update it
216
updatePreferenceCustomizationElement(propertyElement);
217         }
218         fMonitor.worked(4);
219     }
220     
221     /**
222      * @param valueAttribute
223      * @return
224      */

225     private boolean isAttributeValueDefined(IPluginAttribute valueAttribute) {
226         if (valueAttribute == null) {
227             return false;
228         }
229         return PDETextHelper.isDefined(valueAttribute.getValue());
230     }
231     
232     /**
233      * @param resource
234      * @return
235      */

236     private boolean isFileExist(IResource resource) {
237         if (resource == null) {
238             return false;
239         }
240         return (resource instanceof IFile);
241     }
242     
243     /**
244      * @param propertyElement
245      * @throws CoreException
246      */

247     private void updatePreferenceCustomizationElement(
248             IPluginElement propertyElement) throws CoreException {
249         // Get the plug-in customization ini file name
250
IPluginAttribute valueAttribute = propertyElement.getAttribute(F_ATTRIBUTE_VALUE);
251         // Ensure we have a plug-in customization ini file value
252
boolean isAttributeValueNotDefined = !isAttributeValueDefined(valueAttribute);
253         if (isAttributeValueNotDefined &&
254                 fShowProgress) {
255             // Operation: Add progress
256
// Value is not defined
257
// Create the default plugin customization ini file
258
createDefaultPluginCustomizationFile(propertyElement);
259             return;
260         } else if (isAttributeValueNotDefined) {
261             // Operation: Remove progress
262
// Fall-back to the default plugin customization ini file
263
updateDefaultPluginCustomizationFile();
264             return;
265         }
266         // Get the plugin customization ini file name
267
String JavaDoc pluginCustomizationFileName = valueAttribute.getValue();
268         // Find the file in the project
269
IResource resource = fProject.findMember(pluginCustomizationFileName);
270         // Ensure the plug-in customization ini file exists
271
boolean isFileNotExist = !isFileExist(resource);
272         if (isFileNotExist &&
273                 fShowProgress) {
274             // Operation: Add progress
275
// File does not exist in the project
276
// Create the default plugin customization ini file
277
createDefaultPluginCustomizationFile(propertyElement);
278             return;
279         } else if (isFileNotExist) {
280             // Operation: Remove progress
281
// NO-OP
282
return;
283         }
284         // Operations: Add progress, Remove progress
285
// File exists in the project
286
// Update it
287
updatePluginCustomizationFile((IFile)resource);
288     }
289
290     /**
291      * @param message
292      * @param exception
293      * @return
294      */

295     private CoreException createCoreException(String JavaDoc message, Throwable JavaDoc exception) {
296         IStatus status = new Status(IStatus.ERROR, IPDEUIConstants.PLUGIN_ID, message, exception);
297         return new CoreException(status);
298     }
299     
300     /**
301      * @param message
302      * @return
303      */

304     private CoreException createCoreException(String JavaDoc message) {
305         IStatus status = new Status(IStatus.ERROR, IPDEUIConstants.PLUGIN_ID, message);
306         return new CoreException(status);
307     }
308     
309     /**
310      * @return
311      * @throws CoreException
312      */

313     private ITextFileBufferManager getTextFileBufferManager() throws CoreException {
314         if (fTextFileBufferManager == null) {
315             // Get the text file buffer manager
316
fTextFileBufferManager = FileBuffers.getTextFileBufferManager();
317         }
318         // Ensure manager is defined
319
if (fTextFileBufferManager == null) {
320             throw createCoreException(PDEUIMessages.UpdateSplashProgressAction_msgErrorTextFileBufferManager);
321         }
322         return fTextFileBufferManager;
323     }
324     
325     /**
326      * @param file
327      * @return
328      * @throws CoreException
329      */

330     private ITextFileBuffer getPluginCustomizationBuffer(IFile file) throws CoreException {
331         IPath path = file.getFullPath();
332         LocationKind kind = LocationKind.IFILE;
333         // Get the text file buffer
334
fTextFileBuffer =
335             getTextFileBufferManager().getTextFileBuffer(path, kind);
336         // Ensure buffer is defined
337
if (fTextFileBuffer == null) {
338             throw createCoreException(PDEUIMessages.UpdateSplashProgressAction_msgErrorTextFileBuffer);
339         }
340         return fTextFileBuffer;
341     }
342     
343     /**
344      * @param file
345      * @return
346      * @throws CoreException
347      */

348     private BuildModel getBuildModel(IFile file) throws CoreException {
349         // Convert the file to a document
350
// Defines a text file buffer
351
IDocument document = getPluginCustomizationBuffer(file).getDocument();
352         // Create the plugin customization model
353
BuildModel pluginCustomModel = new BuildModel(document, false);
354         pluginCustomModel.setUnderlyingResource(file);
355         pluginCustomModel.setCharset(file.getCharset());
356         // Create the listener to listen to text edit operations
357
// (Operations need to be collected and applied to the document before
358
// saving)
359
fPropertiesListener = new PropertiesTextChangeListener(document);
360         pluginCustomModel.addModelChangedListener(fPropertiesListener);
361         
362         return pluginCustomModel;
363     }
364     
365     /**
366      * @param file
367      * @throws CoreException
368      */

369     private void updatePluginCustomizationFile(IFile file) throws CoreException {
370         IPath path = file.getFullPath();
371         LocationKind kind = LocationKind.IFILE;
372         // Connect to the text file buffer manager
373
getTextFileBufferManager().connect(path, kind, new SubProgressMonitor(fMonitor, 1));
374         try {
375             // Create the plugin customization model
376
BuildModel pluginCustomModel = getBuildModel(file);
377             // Load the plugin customization file
378
pluginCustomModel.load();
379             // Find the show progress on startup key
380
IBuildEntry showProgressEntry =
381                 pluginCustomModel.getBuild().getEntry(F_KEY_SHOW_PROGRESS);
382             // Check to see if we found the entry
383
if (showProgressEntry == null) {
384                 // No show progress entry
385
// Create one
386
addShowProgressEntry(pluginCustomModel);
387             } else {
388                 // Show progress entry exists
389
// Update it
390
updateShowProgressEntry(showProgressEntry);
391             }
392             // Save plugin customization file changes
393
savePluginCustomFileChanges(pluginCustomModel);
394         } catch (MalformedTreeException e) {
395             throw createCoreException(PDEUIMessages.UpdateSplashProgressAction_msgErrorCustomFileSaveFailed, e);
396         } catch (BadLocationException e) {
397             throw createCoreException(PDEUIMessages.UpdateSplashProgressAction_msgErrorCustomFileSaveFailed, e);
398         } finally {
399             // Disconnect from the text file buffer manager
400
getTextFileBufferManager().disconnect(path, kind, new SubProgressMonitor(fMonitor, 1));
401         }
402     }
403
404     /**
405      * @param pluginCustomModel
406      * @throws CoreException
407      * @throws MalformedTreeException
408      * @throws BadLocationException
409      */

410     private void savePluginCustomFileChanges(BuildModel pluginCustomModel) throws CoreException, MalformedTreeException, BadLocationException {
411         // Ensure there is something to save
412
if (pluginCustomModel.isDirty() == false) {
413             // Nothing to save
414
return;
415         } else if (fPropertiesListener == null) {
416             // Prereq: Serious setup problem
417
return;
418         } else if (fTextFileBuffer == null) {
419             // Prereq: Serious setup problem
420
return;
421         }
422         // Get the accumulated text operations (if any)
423
TextEdit[] edits = fPropertiesListener.getTextOperations();
424         if (edits.length == 0) {
425             // Nothing to save
426
return;
427         }
428         // Apply text editor operations to the document
429
MultiTextEdit multi = new MultiTextEdit();
430         multi.addChildren(edits);
431         multi.apply(pluginCustomModel.getDocument());
432         // Ensure there is something to save
433
if (fTextFileBuffer.isDirty() == false) {
434             // Nothing to save
435
return;
436         }
437         // Perform the actual save
438
fTextFileBuffer.commit(new SubProgressMonitor(fMonitor, 1), true);
439     }
440     
441     /**
442      * @param value
443      * @return
444      */

445     private String JavaDoc getBooleanValue(boolean value) {
446         if (value) {
447             return Boolean.TRUE.toString();
448         }
449         return Boolean.FALSE.toString();
450     }
451     
452     /**
453      * @param showProgressEntry
454      * @throws CoreException
455      */

456     private void updateShowProgressEntry(IBuildEntry showProgressEntry) throws CoreException {
457         // Convert boolean to String
458
String JavaDoc newBooleanValue = getBooleanValue(fShowProgress);
459         // Get the value of the show progress entry
460
String JavaDoc[] values = showProgressEntry.getTokens();
461         // There should only be one value (the first one)
462
if (values.length == 0) {
463             // No values
464
// Define true value
465
showProgressEntry.addToken(newBooleanValue);
466             return;
467         } else if (values.length > 1) {
468             // Too many values
469
// Remove all values and add the true value
470
removeEntryTokens(showProgressEntry, values);
471             showProgressEntry.addToken(newBooleanValue);
472             return;
473         }
474         // Get the boolean value
475
String JavaDoc oldBooleanValue = values[0];
476         // If the old value is not the same as the new value, replace the old
477
// with the new
478
if (oldBooleanValue.equals(newBooleanValue) == false) {
479             showProgressEntry.renameToken(oldBooleanValue, newBooleanValue);
480         }
481         // Nothing to do if the value is the same already
482
}
483
484     /**
485      * @param showProgressEntry
486      * @param values
487      * @throws CoreException
488      */

489     private void removeEntryTokens(IBuildEntry showProgressEntry, String JavaDoc[] values) throws CoreException {
490         // Remove each token
491
for (int i = 0; i < values.length; i++) {
492             showProgressEntry.removeToken(values[i]);
493         }
494     }
495     
496     /**
497      * @param pluginCustomModel
498      * @throws CoreException
499      */

500     private void addShowProgressEntry(IBuildModel pluginCustomModel) throws CoreException {
501         // Create the show progress key
502
IBuildEntry showProgressEntry =
503             pluginCustomModel.getFactory().createEntry(F_KEY_SHOW_PROGRESS);
504         // Set the show progress value
505
showProgressEntry.addToken(getBooleanValue(fShowProgress));
506         // Add the show progress entry to the model
507
pluginCustomModel.getBuild().add(showProgressEntry);
508     }
509
510     /**
511      * @throws CoreException
512      */

513     private void createPluginCustomizationFile() throws CoreException {
514         // Create a handle to the workspace file
515
// (Does not exist yet)
516
IFile file = fProject.getFile(F_FILE_NAME_PLUGIN_CUSTOM);
517         // Create the plugin customization model
518
WorkspaceBuildModel pluginCustomModel =
519             new WorkspaceBuildModel(file);
520         // Add the show progress entry to the model
521
addShowProgressEntry(pluginCustomModel);
522         // Create the file by saving the model
523
pluginCustomModel.save();
524     }
525     
526     /**
527      * @param productElement
528      * @throws CoreException
529      */

530     private void addPreferenceCustomizationElement(IPluginElement productElement) throws CoreException {
531         // Get the factory
532
IExtensionsModelFactory factory = productElement.getModel().getFactory();
533         // Create a property element
534
IPluginElement propertyElement =
535             factory.createElement(productElement);
536         propertyElement.setName(F_ELEMENT_PROPERTY);
537         // Create the name attribute
538
propertyElement.setAttribute(F_ATTRIBUTE_NAME, F_ATTRIBUTE_NAME_PREFCUST);
539         // Add the property element to the product element
540
productElement.add(propertyElement);
541         // Create the default plugin customization ini file
542
createDefaultPluginCustomizationFile(propertyElement);
543     }
544
545     /**
546      * @throws CoreException
547      */

548     private void createDefaultPluginCustomizationFile(IPluginElement propertyElement) throws CoreException {
549         // Define the value as the default plugin customization ini file name
550
propertyElement.setAttribute(F_ATTRIBUTE_VALUE, F_FILE_NAME_PLUGIN_CUSTOM);
551         // Check to see if the default file already exists in the project
552
IResource resource = fProject.findMember(F_FILE_NAME_PLUGIN_CUSTOM);
553         // Ensure the plug-in customization ini file exists
554
if (isFileExist(resource)) {
555             // File exists in the project
556
// Update it
557
updatePluginCustomizationFile((IFile)resource);
558         } else {
559             // File does not exist in the project
560
// Create the plugin customization ini file
561
createPluginCustomizationFile();
562         }
563     }
564     
565     /**
566      * @throws CoreException
567      */

568     private void updateDefaultPluginCustomizationFile() throws CoreException {
569         // Check to see if the default file already exists in the project
570
IResource resource = fProject.findMember(F_FILE_NAME_PLUGIN_CUSTOM);
571         if (isFileExist(resource)) {
572             // File exists in the project
573
// Update it
574
updatePluginCustomizationFile((IFile)resource);
575         }
576     }
577     
578     /**
579      * @param productElement
580      * @return
581      */

582     private IPluginElement findPrefCustPropertyElement(
583             IPluginElement productElement) {
584         // Ensure the produce element has children
585
if (productElement.getChildCount() == 0) {
586             return null;
587         }
588         // Get the product element children
589
IPluginObject[] objects = productElement.getChildren();
590         // Process all children
591
for (int i = 0; i < objects.length; i++) {
592             // Ensure we have an element
593
if ((objects[i] instanceof IPluginElement) == false) {
594                 continue;
595             }
596             // Property elements are the only legitimate children of product elements
597
if (objects[i].getName().equals(F_ELEMENT_PROPERTY) == false) {
598                 continue;
599             }
600             IPluginElement element = (IPluginElement)objects[i];
601             // Get the name
602
IPluginAttribute nameAttribute = element.getAttribute(F_ATTRIBUTE_NAME);
603             // Ensure we have a preference customization property
604
if (nameAttribute == null) {
605                 continue;
606             } else if (PDETextHelper.isDefined(nameAttribute.getValue()) == false) {
607                 continue;
608             } else if (nameAttribute.getValue().equals(F_ATTRIBUTE_NAME_PREFCUST) == false) {
609                 continue;
610             }
611             
612             return element;
613         }
614         return null;
615     }
616
617     /**
618      * @param extension
619      * @return
620      */

621     private IPluginElement findProductElement(IPluginExtension extension) {
622         // The product extension is only allowed one child
623
if (extension.getChildCount() != 1) {
624             return null;
625         }
626         // Get the one child
627
IPluginObject pluginObject = extension.getChildren()[0];
628         // Ensure that the child is an element
629
if ((pluginObject instanceof IPluginElement) == false) {
630             return null;
631         }
632         // Ensure that the child is a product element
633
if (pluginObject.getName().equals(F_ELEMENT_PRODUCT) == false) {
634             return null;
635         }
636         return (IPluginElement)pluginObject;
637     }
638     
639     /**
640      * @return
641      */

642     private IPluginExtension findProductExtension() {
643         // Get all the extensions
644
IPluginExtension[] extensions = fModel.getPluginBase().getExtensions();
645         // Get the extension matching the product extension point ID
646
// and product ID
647
for (int i = 0; i < extensions.length; i++) {
648             // Get the extension point
649
String JavaDoc point = extensions[i].getPoint();
650             // Ensure we have a product extension
651
if (point.equals(F_EXTENSION_PRODUCT) == false) {
652                 continue;
653             }
654             // Ensure we have the exact product
655
// Get the fully qualified product ID
656
String JavaDoc id = fPluginId +
657                         '.' +
658                         extensions[i].getId();
659             if (id.equals(fProductID) == false) {
660                 continue;
661             }
662             return extensions[i];
663         }
664         return null;
665     }
666
667 }
668
Popular Tags