KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > text > correction > SerialVersionHashOperation


1 /*******************************************************************************
2  * Copyright (c) 2000, 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.jdt.internal.ui.text.correction;
12
13 import java.io.IOException JavaDoc;
14 import java.lang.reflect.InvocationTargetException JavaDoc;
15 import java.util.ArrayList JavaDoc;
16 import java.util.List JavaDoc;
17
18 import org.eclipse.core.runtime.Assert;
19 import org.eclipse.core.runtime.CoreException;
20 import org.eclipse.core.runtime.FileLocator;
21 import org.eclipse.core.runtime.IPath;
22 import org.eclipse.core.runtime.IProgressMonitor;
23 import org.eclipse.core.runtime.Path;
24 import org.eclipse.core.runtime.SubProgressMonitor;
25
26 import org.eclipse.core.filebuffers.FileBuffers;
27 import org.eclipse.core.filebuffers.ITextFileBuffer;
28 import org.eclipse.core.filebuffers.LocationKind;
29
30 import org.eclipse.core.resources.IncrementalProjectBuilder;
31
32 import org.eclipse.swt.widgets.Display;
33 import org.eclipse.swt.widgets.Shell;
34
35 import org.eclipse.jface.dialogs.MessageDialog;
36 import org.eclipse.jface.operation.IRunnableWithProgress;
37
38 import org.eclipse.ui.PlatformUI;
39
40 import org.eclipse.jdt.core.ICompilationUnit;
41 import org.eclipse.jdt.core.IJavaProject;
42 import org.eclipse.jdt.core.dom.ASTNode;
43 import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
44 import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
45 import org.eclipse.jdt.core.dom.ClassInstanceCreation;
46 import org.eclipse.jdt.core.dom.ITypeBinding;
47 import org.eclipse.jdt.core.dom.ParameterizedType;
48 import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
49 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
50
51 import org.eclipse.jdt.internal.corext.fix.AbstractSerialVersionOperation;
52 import org.eclipse.jdt.internal.corext.fix.LinkedProposalModel;
53 import org.eclipse.jdt.internal.corext.util.Messages;
54
55 import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
56 import org.eclipse.jdt.launching.JavaRuntime;
57
58 import org.eclipse.jdt.internal.ui.JavaPlugin;
59
60 /**
61  * Proposal for a hashed serial version id.
62  *
63  * @since 3.1
64  */

65 public final class SerialVersionHashOperation extends AbstractSerialVersionOperation {
66
67     /** The serial support jar */
68     private static final String JavaDoc SERIAL_SUPPORT_JAR= "serialsupport.jar"; //$NON-NLS-1$
69

70     /**
71      * Computes the class path entries which are on the user class path and are
72      * explicitely put on the boot class path.
73      *
74      * @param project
75      * the project to compute the classpath for
76      * @return the computed classpath. May be empty, but not null.
77      * @throws CoreException
78      * if the project's class path cannot be computed
79      */

80     public static String JavaDoc[] computeUserAndBootClasspath(final IJavaProject project) throws CoreException {
81         final IRuntimeClasspathEntry[] unresolved= JavaRuntime.computeUnresolvedRuntimeClasspath(project);
82         final List JavaDoc resolved= new ArrayList JavaDoc(unresolved.length);
83         for (int index= 0; index < unresolved.length; index++) {
84             final IRuntimeClasspathEntry entry= unresolved[index];
85             final int property= entry.getClasspathProperty();
86             if (property == IRuntimeClasspathEntry.USER_CLASSES || property == IRuntimeClasspathEntry.BOOTSTRAP_CLASSES) {
87                 final IRuntimeClasspathEntry[] entries= JavaRuntime.resolveRuntimeClasspathEntry(entry, project);
88                 for (int offset= 0; offset < entries.length; offset++) {
89                     final String JavaDoc location= entries[offset].getLocation();
90                     if (location != null)
91                         resolved.add(location);
92                 }
93             }
94         }
95         return (String JavaDoc[]) resolved.toArray(new String JavaDoc[resolved.size()]);
96     }
97     
98     public static long[] calculateSerialVersionIds(String JavaDoc[] qualifiedNames, IJavaProject project, final IProgressMonitor monitor) throws CoreException, IOException JavaDoc {
99         final String JavaDoc[] entries= computeUserAndBootClasspath(project);
100         final IRuntimeClasspathEntry[] classpath= new IRuntimeClasspathEntry[entries.length + 2];
101         classpath[0]= JavaRuntime.newRuntimeContainerClasspathEntry(new Path(JavaRuntime.JRE_CONTAINER), IRuntimeClasspathEntry.STANDARD_CLASSES, project);
102         classpath[1]= JavaRuntime.newArchiveRuntimeClasspathEntry(Path.fromOSString(FileLocator.toFileURL(JavaPlugin.getDefault().getBundle().getEntry(SERIAL_SUPPORT_JAR)).getFile()));
103         for (int index= 2; index < classpath.length; index++)
104             classpath[index]= JavaRuntime.newArchiveRuntimeClasspathEntry(Path.fromOSString(entries[index - 2]));
105         return SerialVersionComputationHelper.computeSerialIDs(classpath, project, qualifiedNames, monitor);
106     }
107     
108
109     /**
110      * Displays an appropriate error message for a specific problem.
111      *
112      * @param message
113      * The message to display
114      */

115     private static void displayErrorMessage(final String JavaDoc message) {
116         final Display display= PlatformUI.getWorkbench().getDisplay();
117         if (display != null && !display.isDisposed()) {
118             display.asyncExec(new Runnable JavaDoc() {
119
120                 public final void run() {
121                     if (!display.isDisposed()) {
122                         final Shell shell= display.getActiveShell();
123                         if (shell != null && !shell.isDisposed())
124                             MessageDialog.openError(shell, CorrectionMessages.SerialVersionHashProposal_dialog_error_caption, Messages.format(CorrectionMessages.SerialVersionHashProposal_dialog_error_message, message));
125                     }
126                 }
127             });
128         }
129     }
130
131     /**
132      * Displays an appropriate error message for a specific problem.
133      *
134      * @param throwable
135      * the throwable object to display
136      */

137     private static void displayErrorMessage(final Throwable JavaDoc throwable) {
138         displayErrorMessage(throwable.getLocalizedMessage());
139     }
140
141     /**
142      * Displays a dialog with a question as message.
143      *
144      * @param title
145      * The title to display
146      * @param message
147      * The message to display
148      */

149     private static boolean displayYesNoMessage(final String JavaDoc title, final String JavaDoc message) {
150         final boolean[] result= { true};
151         final Display display= PlatformUI.getWorkbench().getDisplay();
152         if (display != null && !display.isDisposed()) {
153             display.syncExec(new Runnable JavaDoc() {
154
155                 public final void run() {
156                     if (!display.isDisposed()) {
157                         final Shell shell= display.getActiveShell();
158                         if (shell != null && !shell.isDisposed())
159                             result[0]= MessageDialog.openQuestion(shell, title, message);
160                     }
161                 }
162             });
163         }
164         return result[0];
165     }
166
167     private final ICompilationUnit fCompilationUnit;
168     
169     public SerialVersionHashOperation(ICompilationUnit unit, ASTNode[] nodes) {
170         super(unit, nodes);
171         fCompilationUnit= unit;
172     }
173
174     /**
175      * {@inheritDoc}
176      * @throws CoreException
177      */

178     protected boolean addInitializer(final VariableDeclarationFragment fragment, final ASTNode declarationNode) throws CoreException {
179         Assert.isNotNull(fragment);
180         try {
181             PlatformUI.getWorkbench().getProgressService().busyCursorWhile(new IRunnableWithProgress() {
182
183                 public final void run(final IProgressMonitor monitor) throws InterruptedException JavaDoc {
184                     Assert.isNotNull(monitor);
185                     String JavaDoc id= computeId(declarationNode, monitor);
186                     fragment.setInitializer(fragment.getAST().newNumberLiteral(id));
187                 }
188             });
189         } catch (InvocationTargetException JavaDoc exception) {
190             JavaPlugin.log(exception);
191         } catch (InterruptedException JavaDoc exception) {
192             // Do nothing
193
}
194         return true;
195     }
196
197     /**
198      * {@inheritDoc}
199      */

200     protected void addLinkedPositions(ASTRewrite rewrite, VariableDeclarationFragment fragment, LinkedProposalModel positionGroups) {
201         //Do nothing
202
}
203
204     private String JavaDoc computeId(final ASTNode declarationNode, final IProgressMonitor monitor) throws InterruptedException JavaDoc {
205         Assert.isNotNull(monitor);
206         long serialVersionID= SERIAL_VALUE;
207         try {
208             monitor.beginTask(CorrectionMessages.SerialVersionHashProposal_computing_id, 200);
209             final IJavaProject project= fCompilationUnit.getJavaProject();
210             final IPath path= fCompilationUnit.getResource().getFullPath();
211             try {
212                 FileBuffers.getTextFileBufferManager().connect(path, LocationKind.IFILE, new SubProgressMonitor(monitor, 10));
213                 if (monitor.isCanceled())
214                     throw new InterruptedException JavaDoc();
215                 
216                 final ITextFileBuffer buffer= FileBuffers.getTextFileBufferManager().getTextFileBuffer(path, LocationKind.IFILE);
217                 if (buffer.isDirty() && buffer.isStateValidated() && buffer.isCommitable() && displayYesNoMessage(CorrectionMessages.SerialVersionHashProposal_save_caption, CorrectionMessages.SerialVersionHashProposal_save_message))
218                     buffer.commit(new SubProgressMonitor(monitor, 20), true);
219                 else
220                     monitor.worked(20);
221                 
222                 if (monitor.isCanceled())
223                     throw new InterruptedException JavaDoc();
224             } finally {
225                 FileBuffers.getTextFileBufferManager().disconnect(path, LocationKind.IFILE, new SubProgressMonitor(monitor, 10));
226             }
227             project.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, new SubProgressMonitor(monitor, 60));
228             if (monitor.isCanceled())
229                 throw new InterruptedException JavaDoc();
230             
231             long[] ids= calculateSerialVersionIds(new String JavaDoc[] {getQualifiedName(declarationNode)}, project, new SubProgressMonitor(monitor, 100));
232             if (ids.length == 1)
233                 serialVersionID= ids[0];
234         } catch (CoreException exception) {
235             displayErrorMessage(exception);
236         } catch (IOException JavaDoc exception) {
237             displayErrorMessage(exception);
238         } finally {
239             monitor.done();
240         }
241         return serialVersionID + LONG_SUFFIX;
242     }
243
244     /**
245      * Returns the qualified type name of the class declaration.
246      *
247      * @return the qualified type name of the class
248      */

249     private String JavaDoc getQualifiedName(final ASTNode parent) {
250         ITypeBinding binding= null;
251         if (parent instanceof AbstractTypeDeclaration) {
252             final AbstractTypeDeclaration declaration= (AbstractTypeDeclaration) parent;
253             binding= declaration.resolveBinding();
254         } else if (parent instanceof AnonymousClassDeclaration) {
255             final AnonymousClassDeclaration declaration= (AnonymousClassDeclaration) parent;
256             final ClassInstanceCreation creation= (ClassInstanceCreation) declaration.getParent();
257             binding= creation.resolveTypeBinding();
258         } else if (parent instanceof ParameterizedType) {
259             final ParameterizedType type= (ParameterizedType) parent;
260             binding= type.resolveBinding();
261         }
262         if (binding != null)
263             return binding.getBinaryName();
264         return null;
265     }
266 }
267
Popular Tags