Link Here
|
1 |
/* |
2 |
* Copyright (c) 2007 Borland Software 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 |
* Borland Software Corporation - initial API and implementation |
10 |
*/ |
11 |
package org.eclipse.gmf.internal.codegen.popup.actions; |
12 |
|
13 |
import java.io.File; |
14 |
import java.io.IOException; |
15 |
import java.util.ArrayList; |
16 |
import java.util.Collection; |
17 |
import java.util.Collections; |
18 |
import java.util.HashMap; |
19 |
import java.util.Iterator; |
20 |
import java.util.List; |
21 |
import java.util.Map; |
22 |
import java.util.StringTokenizer; |
23 |
|
24 |
import org.eclipse.core.resources.IContainer; |
25 |
import org.eclipse.core.resources.IFile; |
26 |
import org.eclipse.core.resources.IResource; |
27 |
import org.eclipse.core.resources.ResourcesPlugin; |
28 |
import org.eclipse.core.runtime.CoreException; |
29 |
import org.eclipse.core.runtime.IProgressMonitor; |
30 |
import org.eclipse.core.runtime.Path; |
31 |
import org.eclipse.emf.common.ui.dialogs.WorkspaceResourceDialog; |
32 |
import org.eclipse.emf.common.util.BasicMonitor; |
33 |
import org.eclipse.emf.common.util.Diagnostic; |
34 |
import org.eclipse.emf.common.util.Monitor; |
35 |
import org.eclipse.emf.common.util.URI; |
36 |
import org.eclipse.emf.converter.ModelConverter; |
37 |
import org.eclipse.emf.converter.ui.contribution.base.ModelConverterURIPage; |
38 |
import org.eclipse.emf.converter.util.ConverterUtil; |
39 |
import org.eclipse.emf.ecore.EClass; |
40 |
import org.eclipse.emf.ecore.EObject; |
41 |
import org.eclipse.emf.ecore.plugin.EcorePlugin; |
42 |
import org.eclipse.emf.ecore.resource.Resource; |
43 |
import org.eclipse.emf.ecore.resource.ResourceSet; |
44 |
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; |
45 |
import org.eclipse.emf.ecore.xmi.XMLResource; |
46 |
import org.eclipse.jface.dialogs.MessageDialog; |
47 |
import org.eclipse.jface.viewers.ISelection; |
48 |
import org.eclipse.jface.viewers.IStructuredSelection; |
49 |
import org.eclipse.jface.viewers.StructuredSelection; |
50 |
import org.eclipse.jface.viewers.Viewer; |
51 |
import org.eclipse.jface.viewers.ViewerFilter; |
52 |
import org.eclipse.jface.wizard.Wizard; |
53 |
import org.eclipse.jface.wizard.WizardPage; |
54 |
import org.eclipse.swt.SWT; |
55 |
import org.eclipse.swt.events.ModifyEvent; |
56 |
import org.eclipse.swt.events.ModifyListener; |
57 |
import org.eclipse.swt.layout.GridData; |
58 |
import org.eclipse.swt.layout.GridLayout; |
59 |
import org.eclipse.swt.widgets.Combo; |
60 |
import org.eclipse.swt.widgets.Composite; |
61 |
import org.eclipse.swt.widgets.FileDialog; |
62 |
import org.eclipse.swt.widgets.Label; |
63 |
import org.eclipse.ui.IEditorDescriptor; |
64 |
import org.eclipse.ui.IWorkbench; |
65 |
import org.eclipse.ui.IWorkbenchPage; |
66 |
import org.eclipse.ui.IWorkbenchPart; |
67 |
import org.eclipse.ui.IWorkbenchWindow; |
68 |
import org.eclipse.ui.PartInitException; |
69 |
import org.eclipse.ui.actions.WorkspaceModifyOperation; |
70 |
import org.eclipse.ui.part.FileEditorInput; |
71 |
import org.eclipse.ui.part.ISetSelectionTarget; |
72 |
|
73 |
public class AddExtensionModelWizard extends Wizard { |
74 |
|
75 |
private EcoreModelWizardInitialObjectCreationPage myInitialObjectCreationPage; |
76 |
|
77 |
private ModelImporterDetailPage myCustomMetamodelSelectionPage; |
78 |
|
79 |
private IFile myFile; |
80 |
|
81 |
private IWorkbench myWorkbench; |
82 |
|
83 |
public AddExtensionModelWizard() { |
84 |
super(); |
85 |
} |
86 |
|
87 |
public void init(IWorkbench workbench, IStructuredSelection selection) { |
88 |
myWorkbench = workbench; |
89 |
myFile = (IFile) selection.getFirstElement(); |
90 |
setWindowTitle(Messages.AddExtensionModelWizard_0); |
91 |
} |
92 |
|
93 |
protected IFile getGmfgenFile() { |
94 |
return myFile; |
95 |
} |
96 |
|
97 |
protected IWorkbench getWorkbench() { |
98 |
return myWorkbench; |
99 |
} |
100 |
|
101 |
public void addPages() { |
102 |
super.addPages(); |
103 |
|
104 |
myCustomMetamodelSelectionPage = new ModelImporterDetailPage(null, Messages.AddExtensionModelWizard_1); |
105 |
myCustomMetamodelSelectionPage.setTitle(Messages.AddExtensionModelWizard_2); |
106 |
myCustomMetamodelSelectionPage.setDescription(Messages.AddExtensionModelWizard_3); //"Select Your Extension EMF Metamodel" |
107 |
addPage(myCustomMetamodelSelectionPage); |
108 |
|
109 |
myInitialObjectCreationPage = new EcoreModelWizardInitialObjectCreationPage(Messages.AddExtensionModelWizard_4); |
110 |
myInitialObjectCreationPage.setTitle(Messages.AddExtensionModelWizard_5); |
111 |
myInitialObjectCreationPage.setDescription(Messages.AddExtensionModelWizard_6); //"Select a Model Object To Create" |
112 |
addPage(myInitialObjectCreationPage); |
113 |
|
114 |
} |
115 |
|
116 |
public boolean performFinish() { |
117 |
try { |
118 |
// Do the work within an operation. |
119 |
// |
120 |
WorkspaceModifyOperation operation = new WorkspaceModifyOperation() { |
121 |
|
122 |
@Override |
123 |
protected void execute(IProgressMonitor progressMonitor) { |
124 |
try { |
125 |
String userEcoreUri = myCustomMetamodelSelectionPage.getUserEcoreUriString(); |
126 |
if (userEcoreUri != null && userEcoreUri.trim().length() > 0) { |
127 |
List<EClass> nonAbstractClasses = readAllNonAbstractClasses(userEcoreUri); |
128 |
int selectedClass = myInitialObjectCreationPage.getInitialObjectNumber(nonAbstractClasses); |
129 |
if (selectedClass >= 0 && selectedClass < nonAbstractClasses.size()) { |
130 |
EClass selected = nonAbstractClasses.get(selectedClass); |
131 |
if (selected != null) { |
132 |
EObject instantiated = selected.getEPackage().getEFactoryInstance().create(selected); |
133 |
String gmfgenUri = URI.createPlatformResourceURI(getGmfgenFile().getFullPath().toString(), true).toString(); |
134 |
Resource[] resources = getLoadedResources(new String[] { gmfgenUri, userEcoreUri }); |
135 |
|
136 |
resources[0].getContents().add(instantiated); |
137 |
|
138 |
// Save the contents of the resource to the file system. |
139 |
// |
140 |
Map<Object, Object> options = new HashMap<Object, Object>(); |
141 |
options.put(XMLResource.OPTION_ENCODING, myInitialObjectCreationPage.getEncoding()); |
142 |
resources[0].save(options); |
143 |
resources[0].unload(); |
144 |
resources[1].unload(); |
145 |
} |
146 |
} |
147 |
} |
148 |
} catch (Exception e) { |
149 |
EcorePlugin.INSTANCE.getPluginLogger().log(e); |
150 |
} finally { |
151 |
progressMonitor.done(); |
152 |
} |
153 |
} |
154 |
}; |
155 |
|
156 |
getContainer().run(false, false, operation); |
157 |
|
158 |
// Select the new file resource in the current view. |
159 |
// |
160 |
IWorkbenchWindow workbenchWindow = getWorkbench().getActiveWorkbenchWindow(); |
161 |
IWorkbenchPage page = workbenchWindow.getActivePage(); |
162 |
final IWorkbenchPart activePart = page.getActivePart(); |
163 |
if (activePart instanceof ISetSelectionTarget) { |
164 |
final ISelection targetSelection = new StructuredSelection(myFile); |
165 |
getShell().getDisplay().asyncExec(new Runnable() { |
166 |
|
167 |
public void run() { |
168 |
((ISetSelectionTarget) activePart).selectReveal(targetSelection); |
169 |
} |
170 |
}); |
171 |
} |
172 |
|
173 |
// Open an editor on the new file. |
174 |
// |
175 |
try { |
176 |
IEditorDescriptor defaultEditor = getWorkbench().getEditorRegistry().getDefaultEditor(myFile.getFullPath().toString()); |
177 |
page.openEditor(new FileEditorInput(myFile), defaultEditor == null ? "org.eclipse.gmf.codegen.gmfgen.presentation.GMFGenEditorID" : defaultEditor.getId()); //$NON-NLS-1$ |
178 |
} catch (PartInitException exception) { |
179 |
MessageDialog.openError(workbenchWindow.getShell(), Messages.AddExtensionModelWizard_8, exception.getMessage()); |
180 |
return false; |
181 |
} |
182 |
return true; |
183 |
} catch (Exception e) { |
184 |
EcorePlugin.INSTANCE.getPluginLogger().log(e); |
185 |
return false; |
186 |
} |
187 |
} |
188 |
|
189 |
/** |
190 |
* This is the page which allows to browse workspace in order to locate custom metamodel. |
191 |
*/ |
192 |
public class ModelImporterDetailPage extends ModelConverterURIPage { |
193 |
|
194 |
private String myUriString; |
195 |
|
196 |
private Resource[] myResources; |
197 |
|
198 |
public ModelImporterDetailPage(ModelConverter modelConverter, String pageName) { |
199 |
super(modelConverter, pageName); |
200 |
} |
201 |
|
202 |
protected boolean browseFileSystem() { |
203 |
FileDialog fileDialog = new FileDialog(getShell(), SWT.OPEN | SWT.SINGLE); |
204 |
fileDialog.setFilterExtensions(getFilterExtensions()); |
205 |
URI modelURI = getModelLocationURI(getUserEcoreUriString()); |
206 |
if (modelURI != null) { |
207 |
fileDialog.setFileName(modelURI.toFileString()); |
208 |
} |
209 |
if (fileDialog.open() != null && fileDialog.getFileNames().length > 0) { |
210 |
String filePath = fileDialog.getFilterPath() + File.separator + fileDialog.getFileNames()[0]; |
211 |
String uriText = URI.createFileURI(filePath).toString(); |
212 |
setURIText(uriText); |
213 |
uriTextModified(uriText); |
214 |
return true; |
215 |
} |
216 |
return false; |
217 |
} |
218 |
|
219 |
public URI getModelLocationURI(String uriString) { |
220 |
if (isPageComplete()) { |
221 |
return URI.createURI(uriString); |
222 |
} |
223 |
return null; |
224 |
} |
225 |
|
226 |
protected boolean browseWorkspace() { |
227 |
IFile[] selected = WorkspaceResourceDialog.openFileSelection(getShell(), Messages.AddExtensionModelWizard_9, Messages.AddExtensionModelWizard_10, false, getInitialWorkspaceSelection(), |
228 |
getViewerFiltersList()); |
229 |
if (selected.length == 1 && selected[0] != null) { |
230 |
String uriText = URI.createPlatformResourceURI(selected[0].getFullPath().toString(), true).toString(); |
231 |
setURIText(uriText); |
232 |
uriTextModified(uriText); |
233 |
return true; |
234 |
} |
235 |
return false; |
236 |
} |
237 |
|
238 |
protected void uriTextModified(String text) { |
239 |
super.uriTextModified(text); |
240 |
refreshModel(); |
241 |
} |
242 |
|
243 |
protected void refreshModel() { |
244 |
WorkspaceModifyOperation initializeOperation = new WorkspaceModifyOperation() { |
245 |
|
246 |
protected void execute(IProgressMonitor progressMonitor) throws CoreException { |
247 |
Diagnostic errorDiagnostic = null; |
248 |
setErrorMessage(null); |
249 |
setMessage(null); |
250 |
|
251 |
Monitor monitor = BasicMonitor.toMonitor(progressMonitor); |
252 |
try { |
253 |
String uriString = uriText.getText(); |
254 |
Resource[] resources = getLoadedResources(new String[] { uriString }); |
255 |
setResources(resources); |
256 |
if (validatePage()) { |
257 |
List<EClass> nonAbstractClassNames = readAllNonAbstractClasses(uriString); |
258 |
myInitialObjectCreationPage.refresh(nonAbstractClassNames); |
259 |
} |
260 |
} catch (IOException e) { |
261 |
EcorePlugin.INSTANCE.getPluginLogger().log(e); |
262 |
errorDiagnostic = ConverterUtil.createErrorDiagnostic(e, true); |
263 |
} catch (RuntimeException e) { |
264 |
EcorePlugin.INSTANCE.getPluginLogger().log(e); |
265 |
errorDiagnostic = ConverterUtil.createErrorDiagnostic(e, true); |
266 |
} finally { |
267 |
monitor.done(); |
268 |
setResources(null); |
269 |
} |
270 |
|
271 |
if (errorDiagnostic != null) { |
272 |
handleDiagnostic(errorDiagnostic, errorDiagnostic.getMessage(), Messages.AddExtensionModelWizard_11, Messages.AddExtensionModelWizard_12); |
273 |
} |
274 |
} |
275 |
|
276 |
}; |
277 |
|
278 |
myUriString = uriText.getText(); |
279 |
|
280 |
try { |
281 |
getContainer().run(false, false, initializeOperation); |
282 |
} catch (Exception e) { |
283 |
EcorePlugin.INSTANCE.getPluginLogger().log(e); |
284 |
} |
285 |
|
286 |
if (validatePage()) { |
287 |
setPageComplete(true); |
288 |
} else { |
289 |
setPageComplete(false); |
290 |
uriText.selectAll(); |
291 |
uriText.setFocus(); |
292 |
} |
293 |
} |
294 |
|
295 |
private void setResources(Resource[] resources) { |
296 |
myResources = resources; |
297 |
|
298 |
} |
299 |
|
300 |
public String getUserEcoreUriString() { |
301 |
return myUriString; |
302 |
} |
303 |
|
304 |
public boolean validatePage() { |
305 |
return myResources != null && myResources.length > 0; |
306 |
} |
307 |
|
308 |
private Object[] convertResourcesToWorkspaceResources(Resource[] resources) { |
309 |
IResource[] result = new IResource[resources.length]; |
310 |
for (int i=0; i<resources.length; i++) { |
311 |
result[i] = ResourcesPlugin.getWorkspace().getRoot().findMember(new Path(resources[i].getURI().toString()));; |
312 |
} |
313 |
return result; |
314 |
} |
315 |
|
316 |
private Object[] getInitialWorkspaceSelection() { |
317 |
if (validatePage()) { |
318 |
return convertResourcesToWorkspaceResources(myResources); |
319 |
} |
320 |
return new Object[0]; |
321 |
} |
322 |
|
323 |
private List<ViewerFilter> getViewerFiltersList() { |
324 |
ViewerFilter filter = new ViewerFilter() { |
325 |
|
326 |
public boolean select(Viewer viewer, Object parentElement, Object element) { |
327 |
if (element instanceof IContainer) { |
328 |
return true; |
329 |
} |
330 |
if (element instanceof IFile) { |
331 |
IFile iFile = (IFile) element; |
332 |
String[] exts = getFilterExtensions(); |
333 |
boolean goodExt = false; |
334 |
for (int i = 0; i < exts.length; i++) { |
335 |
if (iFile.getFileExtension().equals(exts[i])) { |
336 |
goodExt = true; |
337 |
} |
338 |
} |
339 |
return goodExt; |
340 |
} |
341 |
return false; |
342 |
} |
343 |
}; |
344 |
return Collections.singletonList(filter); |
345 |
} |
346 |
|
347 |
private String[] getFilterExtensions() { |
348 |
return new String[] { "ecore" }; //$NON-NLS-1$ |
349 |
} |
350 |
} |
351 |
|
352 |
/** |
353 |
* This is the page where the type of object to create is selected. |
354 |
*/ |
355 |
public class EcoreModelWizardInitialObjectCreationPage extends WizardPage { |
356 |
|
357 |
protected Combo initialObjectField; |
358 |
|
359 |
protected List<String> encodings; |
360 |
|
361 |
protected Combo encodingField; |
362 |
|
363 |
/** |
364 |
* Pass in the selection. |
365 |
*/ |
366 |
public EcoreModelWizardInitialObjectCreationPage(String pageId) { |
367 |
super(pageId); |
368 |
} |
369 |
|
370 |
public void refresh(List<EClass> initialObjectNames) { |
371 |
initialObjectField.setItems(new String[0]); |
372 |
for (EClass objectName : initialObjectNames) { |
373 |
initialObjectField.add(getLabel(objectName)); |
374 |
} |
375 |
if (initialObjectField.getItemCount() > 0) { |
376 |
initialObjectField.select(0); |
377 |
} |
378 |
} |
379 |
|
380 |
public void createControl(Composite parent) { |
381 |
Composite composite = new Composite(parent, SWT.NONE); |
382 |
{ |
383 |
GridLayout layout = new GridLayout(); |
384 |
layout.numColumns = 1; |
385 |
layout.verticalSpacing = 12; |
386 |
composite.setLayout(layout); |
387 |
|
388 |
GridData data = new GridData(); |
389 |
data.verticalAlignment = GridData.FILL; |
390 |
data.grabExcessVerticalSpace = true; |
391 |
data.horizontalAlignment = GridData.FILL; |
392 |
composite.setLayoutData(data); |
393 |
} |
394 |
|
395 |
Label containerLabel = new Label(composite, SWT.LEFT); |
396 |
{ |
397 |
containerLabel.setText(Messages.AddExtensionModelWizard_14); |
398 |
|
399 |
GridData data = new GridData(); |
400 |
data.horizontalAlignment = GridData.FILL; |
401 |
containerLabel.setLayoutData(data); |
402 |
} |
403 |
|
404 |
initialObjectField = new Combo(composite, SWT.BORDER); |
405 |
{ |
406 |
GridData data = new GridData(); |
407 |
data.horizontalAlignment = GridData.FILL; |
408 |
data.grabExcessHorizontalSpace = true; |
409 |
initialObjectField.setLayoutData(data); |
410 |
} |
411 |
|
412 |
initialObjectField.addModifyListener(validator); |
413 |
|
414 |
Label encodingLabel = new Label(composite, SWT.LEFT); |
415 |
{ |
416 |
encodingLabel.setText(Messages.AddExtensionModelWizard_15); |
417 |
|
418 |
GridData data = new GridData(); |
419 |
data.horizontalAlignment = GridData.FILL; |
420 |
encodingLabel.setLayoutData(data); |
421 |
} |
422 |
encodingField = new Combo(composite, SWT.BORDER); |
423 |
{ |
424 |
GridData data = new GridData(); |
425 |
data.horizontalAlignment = GridData.FILL; |
426 |
data.grabExcessHorizontalSpace = true; |
427 |
encodingField.setLayoutData(data); |
428 |
} |
429 |
|
430 |
for (String encoding : getEncodings()) { |
431 |
encodingField.add(encoding); |
432 |
} |
433 |
|
434 |
encodingField.select(0); |
435 |
encodingField.addModifyListener(validator); |
436 |
|
437 |
setPageComplete(validatePage()); |
438 |
setControl(composite); |
439 |
} |
440 |
|
441 |
protected ModifyListener validator = new ModifyListener() { |
442 |
|
443 |
public void modifyText(ModifyEvent e) { |
444 |
setPageComplete(validatePage()); |
445 |
} |
446 |
}; |
447 |
|
448 |
protected boolean validatePage() { |
449 |
return initialObjectField.getText() != null && initialObjectField.getText().trim().length() > 0 && getEncodings().contains(encodingField.getText()); |
450 |
} |
451 |
|
452 |
public void setVisible(boolean visible) { |
453 |
super.setVisible(visible); |
454 |
if (visible) { |
455 |
if (initialObjectField.getItemCount() == 1) { |
456 |
initialObjectField.clearSelection(); |
457 |
encodingField.setFocus(); |
458 |
} else { |
459 |
encodingField.clearSelection(); |
460 |
initialObjectField.setFocus(); |
461 |
} |
462 |
} |
463 |
} |
464 |
|
465 |
public String getInitialObjectName(List<EClass> allClasses) { |
466 |
String label = initialObjectField.getText(); |
467 |
|
468 |
for (EClass next : allClasses) { |
469 |
if (getLabel(next).equals(label)) { |
470 |
return label; |
471 |
} |
472 |
} |
473 |
return null; |
474 |
} |
475 |
|
476 |
public int getInitialObjectNumber(List<EClass> allClasses) { |
477 |
String label = initialObjectField.getText(); |
478 |
for (int i = 0; i < allClasses.size(); i++) { |
479 |
EClass next = allClasses.get(i); |
480 |
if (getLabel(next).equals(label)) { |
481 |
return i; |
482 |
} |
483 |
} |
484 |
return 0; |
485 |
} |
486 |
|
487 |
public String getEncoding() { |
488 |
return encodingField.getText(); |
489 |
} |
490 |
|
491 |
/** |
492 |
* Returns the label for the specified type name. |
493 |
*/ |
494 |
protected String getLabel(EClass type) { |
495 |
return type.getName(); |
496 |
} |
497 |
|
498 |
protected Collection<String> getEncodings() { |
499 |
if (encodings == null) { |
500 |
encodings = new ArrayList<String>(); |
501 |
for (StringTokenizer stringTokenizer = new StringTokenizer(Messages.AddExtensionModelWizard_16); stringTokenizer.hasMoreTokens();) { |
502 |
encodings.add(stringTokenizer.nextToken()); |
503 |
} |
504 |
} |
505 |
return encodings; |
506 |
} |
507 |
} |
508 |
|
509 |
public static Resource[] getLoadedResources(String[] textURIs) throws IOException { |
510 |
Resource[] result = new Resource[textURIs.length]; |
511 |
ResourceSet resourceSet = new ResourceSetImpl(); |
512 |
for (int i = 0; i < result.length; i++) { |
513 |
URI nextURI = URI.createURI(textURIs[i]); |
514 |
Resource resource = resourceSet.createResource(nextURI); |
515 |
resource.load(resourceSet.getLoadOptions()); |
516 |
result[i] = resource; |
517 |
} |
518 |
return result; |
519 |
} |
520 |
|
521 |
public static List<EClass> readAllNonAbstractClasses(String textURI) throws IOException { |
522 |
List<EClass> nonAbstractClasses = new ArrayList<EClass>(); |
523 |
Resource resource = getLoadedResources(new String[] { textURI })[0]; |
524 |
if (resource != null && resource.isLoaded()) { |
525 |
Iterator<EObject> contents = resource.getAllContents(); |
526 |
while (contents.hasNext()) { |
527 |
EObject next = contents.next(); |
528 |
if (next instanceof EClass) { |
529 |
EClass clazz = (EClass) next; |
530 |
if (!clazz.isAbstract()) { |
531 |
nonAbstractClasses.add(clazz); |
532 |
} |
533 |
} |
534 |
} |
535 |
resource.unload(); |
536 |
} |
537 |
return nonAbstractClasses; |
538 |
} |
539 |
|
540 |
} |