Skip to content

Package: GenerateJavaCodeAction$CreateJavaCodeAction

GenerateJavaCodeAction$CreateJavaCodeAction

nameinstructionbranchcomplexitylinemethod
GenerateJavaCodeAction.CreateJavaCodeAction(GenerateJavaCodeAction, GenModel, ISelectionProvider)
M: 0 C: 8
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
GenerateJavaCodeAction.CreateJavaCodeAction(GenerateJavaCodeAction, GenModel, String, Object[], ISelectionProvider)
M: 0 C: 10
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
GenerateJavaCodeAction.CreateJavaCodeAction(GenerateJavaCodeAction, ISelectionProvider)
M: 0 C: 46
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 12
100%
M: 0 C: 1
100%
GenerateJavaCodeAction.CreateJavaCodeAction(GenerateJavaCodeAction, String, Object[], ISelectionProvider)
M: 0 C: 13
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
getGenModel()
M: 0 C: 3
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getJavaCodeAction(String, Object[])
M: 0 C: 12
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getSelectionProvider()
M: 0 C: 3
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
run()
M: 31 C: 38
55%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 5 C: 8
62%
M: 0 C: 1
100%
setGenModel(GenModel)
M: 0 C: 4
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%

Coverage

1: /*******************************************************************************
2: * Copyright (c) 2011-2013 EclipseSource Muenchen GmbH and others.
3: *
4: * All rights reserved. This program and the accompanying materials
5: * are made available under the terms of the Eclipse Public License 2.0
6: * which accompanies this distribution, and is available at
7: * https://www.eclipse.org/legal/epl-2.0/
8: *
9: * SPDX-License-Identifier: EPL-2.0
10: *
11: * Contributors:
12: * Clemens Elflein - initial API and implementation
13: ******************************************************************************/
14: package org.eclipse.emfforms.internal.editor.genmodel.toolbaractions;
15:
16: import java.io.ByteArrayInputStream;
17: import java.io.ByteArrayOutputStream;
18: import java.io.IOException;
19: import java.io.InputStream;
20: import java.lang.reflect.InvocationTargetException;
21: import java.text.MessageFormat;
22: import java.util.HashSet;
23: import java.util.Set;
24: import java.util.jar.Attributes;
25: import java.util.jar.Manifest;
26:
27: import org.eclipse.core.resources.IFile;
28: import org.eclipse.core.resources.IResource;
29: import org.eclipse.core.runtime.CoreException;
30: import org.eclipse.core.runtime.IProgressMonitor;
31: import org.eclipse.core.runtime.IStatus;
32: import org.eclipse.core.runtime.NullProgressMonitor;
33: import org.eclipse.core.runtime.Status;
34: import org.eclipse.emf.codegen.ecore.generator.Generator;
35: import org.eclipse.emf.codegen.ecore.genmodel.GenModel;
36: import org.eclipse.emf.codegen.ecore.genmodel.GenPackage;
37: import org.eclipse.emf.codegen.ecore.genmodel.generator.GenBaseGeneratorAdapter;
38: import org.eclipse.emf.codegen.ecore.genmodel.util.GenModelUtil;
39: import org.eclipse.emf.common.util.BasicMonitor;
40: import org.eclipse.emf.common.util.URI;
41: import org.eclipse.emf.ecore.resource.Resource;
42: import org.eclipse.emf.ecore.resource.ResourceSet;
43: import org.eclipse.emf.ecp.view.spi.model.reporting.StatusReport;
44: import org.eclipse.emfforms.internal.editor.genmodel.Activator;
45: import org.eclipse.emfforms.internal.editor.genmodel.Messages;
46: import org.eclipse.emfforms.internal.editor.genmodel.util.PluginXmlUtil;
47: import org.eclipse.emfforms.spi.editor.IToolbarAction;
48: import org.eclipse.emfforms.spi.editor.helpers.ResourceUtil;
49: import org.eclipse.jface.action.Action;
50: import org.eclipse.jface.action.ActionContributionItem;
51: import org.eclipse.jface.action.IMenuCreator;
52: import org.eclipse.jface.dialogs.ProgressMonitorDialog;
53: import org.eclipse.jface.operation.IRunnableWithProgress;
54: import org.eclipse.jface.resource.ImageDescriptor;
55: import org.eclipse.jface.viewers.ISelection;
56: import org.eclipse.jface.viewers.ISelectionProvider;
57: import org.eclipse.jface.viewers.StructuredSelection;
58: import org.eclipse.swt.SWT;
59: import org.eclipse.swt.widgets.Control;
60: import org.eclipse.swt.widgets.Display;
61: import org.eclipse.swt.widgets.Menu;
62: import org.osgi.framework.FrameworkUtil;
63:
64: /**
65: * The ToolbarAction allowing the User to generate Java code for the currently visible Genmodel.
66: *
67: * @author Clemens Elflein
68: */
69: public class GenerateJavaCodeAction implements IToolbarAction {
70:
71:         @Override
72:         public Action getAction(Object currentObject, ISelectionProvider selectionProvider) {
73:                 final ResourceSet resourceSet = (ResourceSet) currentObject;
74:                 final GenModel genModel = getGenModel(resourceSet);
75:                 return new CreateJavaCodeAction(genModel, selectionProvider);
76:         }
77:
78:         /**
79:          * Returns the first {@link GenModel} object found in the first of the given {@link ResourceSet}.
80:          *
81:          * @param resourceSet the {@link ResourceSet} to check
82:          * @return the {@link GenModel} or <code>null</code> if none was found
83:          */
84:         protected GenModel getGenModel(ResourceSet resourceSet) {
85:                 if (resourceSet.getResources().isEmpty()) {
86:                         return null;
87:                 }
88:                 final Resource topResource = resourceSet.getResources().get(0);
89:                 if (!topResource.getContents().isEmpty() && GenModel.class.isInstance(topResource.getContents().get(0))) {
90:                         return (GenModel) topResource.getContents().get(0);
91:                 }
92:                 return null;
93:         }
94:
95:         @Override
96:         public boolean canExecute(Object object) {
97:                 // We can't execute our Action on Objects other than ResourceSet
98:                 if (!(object instanceof ResourceSet)) {
99:                         return false;
100:                 }
101:                 // We can execute our Action only if the ResourceSet contains a GenModel
102:                 final ResourceSet resourceSet = (ResourceSet) object;
103:                 final GenModel genModel = getGenModel(resourceSet);
104:                 return genModel != null;
105:         }
106:
107:         /**
108:          * ToolbarAction to generate Java Code. It also provides the DropDown menu to create
109:          * each type separately (Model, Edit, Editor, Tests).
110:          */
111:         class CreateJavaCodeAction extends Action {
112:                 private final Object[] types;
113:                 private final ISelectionProvider selectionProvider;
114:                 private GenModel genModel;
115:                 private static final String FILE_NAME_PLUGIN_XML = "plugin.xml"; //$NON-NLS-1$
116:                 private static final String FILE_NAME_META_INF = "META-INF"; //$NON-NLS-1$
117:                 private static final String FILE_NAME_MANIFEST_MF = "MANIFEST.MF"; //$NON-NLS-1$
118:                 private static final String REQUIRE_BUNDLE_HEADER = "Require-Bundle"; //$NON-NLS-1$
119:                 private static final String EDITOR_BUNDLE_NAME = "org.eclipse.emfforms.editor";//$NON-NLS-1$
120:                 private static final String EDITOR_BUNDLE_VERSION = "1.8.0";//$NON-NLS-1$
121:                 private static final String EMFFORMS_EDITOR_CLASS_NAME = "org.eclipse.emfforms.spi.editor.GenericEditor";//$NON-NLS-1$
122:                 private static final String EMFFORMS_EDITOR_NAME = "EMFForms Editor";//$NON-NLS-1$
123:                 private static final String EMFFORMS_EDITOR_ID = "emfformseditor";//$NON-NLS-1$
124:
125:                 /**
126:                  * Constructor.
127:                  *
128:                  * @param text the string used as the text for the action, or null if there is no text
129:                  * @param types the project types
130:                  * @param selectionProvider the {@link ISelectionProvider}
131:                  */
132:                 CreateJavaCodeAction(String text, Object[] types, ISelectionProvider selectionProvider) {
133:                         super(text);
134:                         this.types = types;
135:                         this.selectionProvider = selectionProvider;
136:                 }
137:
138:                 /**
139:                  * Constructor.
140:                  *
141:                  * @param genModel the {@link GenModel}
142:                  * @param selectionProvider the {@link ISelectionProvider}
143:                  */
144:                 CreateJavaCodeAction(GenModel genModel, ISelectionProvider selectionProvider) {
145:                         this(selectionProvider);
146:                         this.genModel = genModel;
147:                 }
148:
149:                 /**
150:                  * Constructor.
151:                  *
152:                  * @param genModel the {@link GenModel}
153:                  * @param text the string used as the text for the action, or null if there is no text
154:                  * @param types the project types
155:                  * @param selectionProvider the {@link ISelectionProvider}
156:                  */
157:                 CreateJavaCodeAction(GenModel genModel, String text, Object[] types,
158:                         ISelectionProvider selectionProvider) {
159:                         this(text, types, selectionProvider);
160:                         this.genModel = genModel;
161:                 }
162:
163:                 /**
164:                  * Constructor.
165:                  *
166:                  * @param selectionProvider the {@link ISelectionProvider}
167:                  */
168:                 CreateJavaCodeAction(ISelectionProvider selectionProvider) {
169:                         super(Messages.GenerateJavaCodeAction_generateAll, SWT.DROP_DOWN);
170:                         this.selectionProvider = selectionProvider;
171:
172:                         types = new Object[] {
173:                                 GenBaseGeneratorAdapter.MODEL_PROJECT_TYPE,
174:                                 GenBaseGeneratorAdapter.EDIT_PROJECT_TYPE,
175:                                 GenBaseGeneratorAdapter.EDITOR_PROJECT_TYPE,
176:                                 GenBaseGeneratorAdapter.TESTS_PROJECT_TYPE
177:                         };
178:
179:                         setMenuCreator(new GenmodelDropdownCreator());
180:
181:                         setImageDescriptor(ImageDescriptor.createFromURL(FrameworkUtil.getBundle(
182:                                 this.getClass()).getResource("icons/page_white_cup.png"))); //$NON-NLS-1$
183:                 }
184:
185:                 /**
186:                  * Returns the Java code generation action.
187:                  *
188:                  * @param text the text of the Action
189:                  * @param types the project types
190:                  * @return a new Action
191:                  */
192:                 protected Action getJavaCodeAction(String text, Object[] types) {
193:                         return new CreateJavaCodeAction(genModel, text, types, selectionProvider);
194:                 }
195:
196:                 /**
197:                  * Sets the {@link GenModel} for the java code generation action.
198:                  *
199:                  * @param genModel the genModel to set
200:                  */
201:                 public void setGenModel(GenModel genModel) {
202:                         this.genModel = genModel;
203:                 }
204:
205:                 @Override
206:                 public void run() {
207:                         final ISelection oldSelection = selectionProvider.getSelection();
208:                         selectionProvider.setSelection(new StructuredSelection(getGenModel()));
209:                         getGenModel().reconcile();
210:                         selectionProvider.setSelection(oldSelection);
211:                         final IRunnableWithProgress generateCodeRunnable = new GenerateJavaCodeRunnable(getGenModel());
212:
213:                         try {
214:                                 new ProgressMonitorDialog(Display.getCurrent().getActiveShell()).run(true, false, generateCodeRunnable);
215:                         } catch (final InvocationTargetException ex) {
216:                                 Activator.getDefault().getReportService().report(
217:                                         new StatusReport(new Status(IStatus.ERROR, Activator.PLUGIN_ID, ex.getMessage(), ex)));
218:                         } catch (final InterruptedException ex) {
219:                                 Activator.getDefault().getReportService().report(
220:                                         new StatusReport(new Status(IStatus.ERROR, Activator.PLUGIN_ID, ex.getMessage(), ex)));
221:                         }
222:                 }
223:
224:                 /**
225:                  * @return the genModel
226:                  */
227:                 public GenModel getGenModel() {
228:                         return genModel;
229:                 }
230:
231:                 /**
232:                  * @return the selectionProvider
233:                  */
234:                 public ISelectionProvider getSelectionProvider() {
235:                         return selectionProvider;
236:                 }
237:
238:                 /**
239:                  * {@link IRunnableWithProgress} to execute code generation.
240:                  */
241:                 public class GenerateJavaCodeRunnable implements IRunnableWithProgress {
242:
243:                         private final GenModel genmodel;
244:
245:                         /**
246:                          * Constructor.
247:                          *
248:                          * @param genmodel the {@link GenModel}
249:                          */
250:                         GenerateJavaCodeRunnable(GenModel genmodel) {
251:                                 this.genmodel = genmodel;
252:                         }
253:
254:                         @Override
255:                         public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
256:                                 monitor.beginTask(Messages.GenerateJavaCodeAction_generatingCodeTask, IProgressMonitor.UNKNOWN);
257:
258:                                 genmodel.setCanGenerate(true);
259:
260:                                 final Generator generator = GenModelUtil
261:                                         .createGenerator(genmodel);
262:
263:                                 final Set<URI> knownUris = new HashSet<URI>();
264:
265:                                 for (final Object type : types) {
266:                                         generate(monitor, genmodel, generator, knownUris, type);
267:                                 }
268:                         }
269:
270:                         private void generate(IProgressMonitor monitor, final GenModel genmodel, final Generator generator,
271:                                 final Set<URI> knownUris, final Object type) {
272:                                 generator.generate(genmodel, type,
273:                                         new BasicMonitor.EclipseSubProgress(monitor, 1));
274:
275:                                 final Set<URI> uris = new HashSet<URI>(generator.getGeneratedOutputs());
276:                                 uris.removeAll(knownUris);
277:                                 knownUris.addAll(uris);
278:
279:                                 if (GenBaseGeneratorAdapter.EDITOR_PROJECT_TYPE.equals(type)) {
280:                                         handleGeneratedEditorProject(uris, genmodel);
281:                                 }
282:                         }
283:
284:                         /**
285:                          * Handles the case that an editor project was generated. Takes a set of generated URIs to find the
286:                          * plugin.xml file to edit.
287:                          *
288:                          * @param uris a set of generated URIs
289:                          * @param genmodel
290:                          */
291:                         private void handleGeneratedEditorProject(Set<URI> uris, GenModel genmodel) {
292:                                 URI pluginXml = null;
293:                                 URI manifestMf = null;
294:                                 for (final URI uri : uris) {
295:                                         if (isPluginXml(uri)) {
296:                                                 pluginXml = uri;
297:                                         } else if (isManifestMf(uri)) {
298:                                                 manifestMf = uri;
299:                                         }
300:                                 }
301:
302:                                 if (pluginXml != null && manifestMf != null) {
303:                                         injectPluginXml(pluginXml, genmodel);
304:                                         injectManifestMf(manifestMf);
305:                                 }
306:                         }
307:
308:                         private boolean isPluginXml(URI uri) {
309:                                 if (uri.segmentCount() != 2) {
310:                                         return false;
311:                                 }
312:
313:                                 final String lastSegment = uri.lastSegment();
314:                                 return FILE_NAME_PLUGIN_XML.equals(lastSegment);
315:                         }
316:
317:                         private boolean isManifestMf(URI uri) {
318:                                 if (uri.segmentCount() != 3) {
319:                                         return false;
320:                                 }
321:
322:                                 final String secondSegment = uri.segment(1);
323:                                 final String lastSegment = uri.lastSegment();
324:                                 return FILE_NAME_META_INF.equals(secondSegment) && FILE_NAME_MANIFEST_MF.equals(lastSegment);
325:                         }
326:
327:                         private void injectManifestMf(URI manifestMf) {
328:                                 final IResource resource = ResourceUtil.getResourceFromURI(manifestMf);
329:                                 final IFile file = (IFile) resource;
330:
331:                                 InputStream original;
332:                                 try {
333:                                         original = file.getContents();
334:                                         final Manifest originalManifest = new Manifest(original);
335:                                         final Attributes attributes = originalManifest.getMainAttributes();
336:                                         String newValue = attributes.getValue(REQUIRE_BUNDLE_HEADER);
337:                                         if (newValue == null) {
338:                                                 newValue = ""; //$NON-NLS-1$
339:                                         } else {
340:                                                 newValue += ","; //$NON-NLS-1$
341:                                         }
342:                                         newValue += EDITOR_BUNDLE_NAME;
343:                                         if (EDITOR_BUNDLE_VERSION != null) {
344:                                                 newValue += ";bundle-version=\"" + EDITOR_BUNDLE_VERSION + "\""; //$NON-NLS-1$ //$NON-NLS-2$
345:                                         }
346:                                         attributes.putValue(REQUIRE_BUNDLE_HEADER, newValue);
347:                                         final ByteArrayOutputStream bos = new ByteArrayOutputStream();
348:                                         originalManifest.write(bos);
349:                                         file.setContents(new ByteArrayInputStream(bos.toByteArray()), false, true,
350:                                                 new NullProgressMonitor());
351:                                 } catch (final CoreException ex) {
352:                                         Activator.getDefault().getReportService().report(
353:                                                 new StatusReport(new Status(IStatus.ERROR, Activator.PLUGIN_ID, ex.getMessage(), ex)));
354:                                 } catch (final IOException ex) {
355:                                         Activator.getDefault().getReportService().report(
356:                                                 new StatusReport(new Status(IStatus.ERROR, Activator.PLUGIN_ID, ex.getMessage(), ex)));
357:                                 }
358:                         }
359:
360:                         private void injectPluginXml(URI pluginXml, GenModel genmodel) {
361:                                 final IResource resource = ResourceUtil.getResourceFromURI(pluginXml);
362:                                 final GenPackage genPackage = genmodel.getGenPackages().get(0);
363:
364:                                 PluginXmlUtil.addEditorExtensionPoint(
365:                                         (IFile) resource,
366:                                         EMFFORMS_EDITOR_CLASS_NAME,
367:                                         false, /* default */
368:                                         getFileExtension(genmodel),
369:                                         /**
370:                                          * Code from org.eclipse.emf.codegen.ecore.templates.editor.PluginXML
371:                                          * stringBuffer.append("icon=\"icons/full/obj16/");
372:                                          * stringBuffer.append(genPackage.getPrefix());
373:                                          * stringBuffer.append("ModelFile.gif\"");
374:                                          */
375:                                         MessageFormat.format("icons/full/obj16/{0}ModelFile.gif", genPackage.getPrefix()), //$NON-NLS-1$
376:                                         /**
377:                                          * Default id is the fully qualified generated editor class appended by ID.
378:                                          * e.g.: org.eclipse.emf.ecp.makeithappen.model.task.presentation.TaskEditorID
379:                                          *
380:                                          * we will use the generated editor plugin id appended by the package prefix appended by
381:                                          * emfformseditor.
382:                                          * e.g.: org.eclipse.emf.ecp.makeithappen.model.editor.Task.emfformseditor
383:                                          */
384:                                         MessageFormat.format("{0}.{1}.{2}", genmodel.getEditorPluginID(), genPackage.getPrefix(), //$NON-NLS-1$
385:                                                 EMFFORMS_EDITOR_ID),
386:                                         EMFFORMS_EDITOR_NAME);
387:                         }
388:
389:                         private String getFileExtension(GenModel genmodel) {
390:                                 return genmodel.getGenPackages().get(0).getFileExtensions();
391:                         }
392:                 }
393:
394:                 /**
395:                  * IMenuCreator to create each type separately.
396:                  */
397:                 private class GenmodelDropdownCreator implements IMenuCreator {
398:                         private Menu dropDown;
399:
400:                         @Override
401:                         public void dispose() {
402:                                 if (dropDown != null) {
403:                                         dropDown.dispose();
404:                                 }
405:                         }
406:
407:                         @Override
408:                         public Menu getMenu(Control parent) {
409:                                 dispose();
410:
411:                                 dropDown = new Menu(parent);
412:                                 final Action generateModelAndEdit = getJavaCodeAction(
413:                                         Messages.GenerateJavaCodeAction_generateModelEdit, new Object[] {
414:                                                 GenBaseGeneratorAdapter.MODEL_PROJECT_TYPE, GenBaseGeneratorAdapter.EDIT_PROJECT_TYPE });
415:
416:                                 final Action generateModel = getJavaCodeAction(Messages.GenerateJavaCodeAction_generateModel,
417:                                         new Object[] { GenBaseGeneratorAdapter.MODEL_PROJECT_TYPE });
418:
419:                                 final Action generateEdit = getJavaCodeAction(Messages.GenerateJavaCodeAction_generateEdit,
420:                                         new Object[] { GenBaseGeneratorAdapter.EDIT_PROJECT_TYPE });
421:
422:                                 final Action generateEditor = getJavaCodeAction(Messages.GenerateJavaCodeAction_generateEditor,
423:                                         new Object[] { GenBaseGeneratorAdapter.EDITOR_PROJECT_TYPE });
424:
425:                                 final Action generateTests = getJavaCodeAction(Messages.GenerateJavaCodeAction_generateTests,
426:                                         new Object[] { GenBaseGeneratorAdapter.TESTS_PROJECT_TYPE });
427:
428:                                 new ActionContributionItem(generateModelAndEdit).fill(dropDown, 0);
429:                                 new ActionContributionItem(generateModel).fill(dropDown, 1);
430:                                 new ActionContributionItem(generateEdit).fill(dropDown, 2);
431:                                 new ActionContributionItem(generateEditor).fill(dropDown, 3);
432:                                 new ActionContributionItem(generateTests).fill(dropDown, 4);
433:
434:                                 return dropDown;
435:                         }
436:
437:                         @Override
438:                         public Menu getMenu(Menu parent) {
439:                                 return null;
440:                         }
441:
442:                 }
443:         }
444: }