Method: createAcceleoLaunchingStrategyEditor(Composite)

1: /*******************************************************************************
2: * Copyright (c) 2008, 2014 Obeo.
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: * Obeo - initial API and implementation
10: *******************************************************************************/
11: package org.eclipse.acceleo.internal.ide.ui.launching;
12:
13: import java.util.ArrayList;
14: import java.util.Collections;
15: import java.util.Iterator;
16: import java.util.List;
17:
18: import org.eclipse.acceleo.common.preference.AcceleoPreferences;
19: import org.eclipse.acceleo.ide.ui.AcceleoUIActivator;
20: import org.eclipse.acceleo.ide.ui.launching.strategy.IAcceleoLaunchingStrategy;
21: import org.eclipse.acceleo.internal.ide.ui.AcceleoUIMessages;
22: import org.eclipse.acceleo.internal.ide.ui.dialog.FileTreeContentProvider;
23: import org.eclipse.acceleo.internal.ide.ui.dialog.ResourceSelectionDialog;
24: import org.eclipse.core.resources.IFile;
25: import org.eclipse.core.resources.IResource;
26: import org.eclipse.core.resources.IWorkspace;
27: import org.eclipse.core.resources.ResourcesPlugin;
28: import org.eclipse.core.runtime.CoreException;
29: import org.eclipse.core.runtime.IConfigurationElement;
30: import org.eclipse.core.runtime.IExtension;
31: import org.eclipse.core.runtime.IExtensionPoint;
32: import org.eclipse.core.runtime.IExtensionRegistry;
33: import org.eclipse.core.runtime.IPath;
34: import org.eclipse.core.runtime.IStatus;
35: import org.eclipse.core.runtime.Path;
36: import org.eclipse.core.runtime.Platform;
37: import org.eclipse.debug.core.ILaunchConfiguration;
38: import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
39: import org.eclipse.debug.ui.ILaunchConfigurationTab;
40: import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
41: import org.eclipse.jface.window.Window;
42: import org.eclipse.swt.SWT;
43: import org.eclipse.swt.events.ModifyEvent;
44: import org.eclipse.swt.events.ModifyListener;
45: import org.eclipse.swt.events.SelectionEvent;
46: import org.eclipse.swt.events.SelectionListener;
47: import org.eclipse.swt.graphics.Font;
48: import org.eclipse.swt.graphics.Image;
49: import org.eclipse.swt.layout.GridData;
50: import org.eclipse.swt.layout.GridLayout;
51: import org.eclipse.swt.widgets.Button;
52: import org.eclipse.swt.widgets.Combo;
53: import org.eclipse.swt.widgets.Composite;
54: import org.eclipse.swt.widgets.Group;
55: import org.eclipse.swt.widgets.Label;
56: import org.eclipse.swt.widgets.Shell;
57: import org.eclipse.swt.widgets.Text;
58: import org.eclipse.swt.widgets.ToolBar;
59: import org.eclipse.swt.widgets.ToolItem;
60: import org.eclipse.swt.widgets.Widget;
61: import org.eclipse.ui.ISharedImages;
62: import org.eclipse.ui.PlatformUI;
63: import org.eclipse.ui.dialogs.ContainerSelectionDialog;
64: import org.eclipse.ui.dialogs.FilteredResourcesSelectionDialog;
65: import org.osgi.framework.Bundle;
66: import org.osgi.framework.Version;
67:
68: /**
69: * The Acceleo main tab of the launch configuration. It displays and edits project and main type name launch
70: * configuration attributes. It provides a way to define the model path and the target folder.
71: *
72: * @author <a href="mailto:jonathan.musset@obeo.fr">Jonathan Musset</a>
73: */
74: public class AcceleoMainTab extends org.eclipse.jdt.debug.ui.launchConfigurations.JavaMainTab {
75:
76:         /**
77:          * Image registry key for help image (value <code>"dialog_help_image"</code> ).
78:          */
79:         private static final String DLG_IMG_HELP = "dialog_help_image"; //$NON-NLS-1$
80:
81:         /**
82:          * Profile mode constant.
83:          */
84:         private static final String PROFILE_MODE = "profile"; //$NON-NLS-1$
85:
86:         /**
87:          * Profile model extension.
88:          */
89:         private static final String PROFILE_EXTENSION = "mtlp"; //$NON-NLS-1$
90:
91:         /**
92:          * Browse message constant.
93:          */
94:         private static final String BROWSE_MESSAGE = "AcceleoMainTab.Browse"; //$NON-NLS-1$
95:
96:         /**
97:          * The launch configuration tab that displays program arguments.
98:          */
99:         AcceleoJavaArgumentsTab javaArgumentsTab;
100:
101:         /**
102:          * The model path text widget, relative to the workspace.
103:          */
104:         private Text modelText;
105:
106:         /**
107:          * The profile model path text widget, relative to the workspace.
108:          */
109:         private Text profileModelText;
110:
111:         /**
112:          * The model button, to browse the workspace to select the model.
113:          */
114:         private Button modelButton;
115:
116:         /**
117:          * The profile model button, to browse the workspace to select the model.
118:          */
119:         private Button profileModelButton;
120:
121:         /**
122:          * The target folder path text widget, relative to the workspace.
123:          */
124:         private Text targetText;
125:
126:         /**
127:          * The target button, to browse the workspace to select the target folder.
128:          */
129:         private Button targetButton;
130:
131:         /**
132:          * Checkbox button that indicates if we would like to compute the traceability information.
133:          */
134:         private Button computeTraceability;
135:
136:         /** The help widget for the traceability checkbox. */
137:         private ToolBar traceabilityHelp;
138:
139:         /**
140:          * Checkbox button that indicates if we would like to compute the profiling information.
141:          */
142:         private Button computeProfiling;
143:
144:         /**
145:          * Available launching strategies in the current Eclipse instance. An internal extension point is defined
146:          * to specify multiple launching strategies.
147:          */
148:         private Combo launchingStrategyCombo;
149:
150:         /**
151:          * The descriptions of all the launching strategies existing in the current Eclipse instance. An internal
152:          * extension point is defined to specify multiple launching strategies. It is used to define a specific
153:          * way of launching an Acceleo generation.
154:          */
155:         private List<String> launchingStrategies;
156:
157:         /**
158:          * The invisible main type shell. It is used to mask some widgets of the superclass.
159:          */
160:         private Shell mainTypeShell;
161:
162:         /**
163:          * Constructor.
164:          *
165:          * @param javaArgumentsTab
166:          * is the launch configuration tab that displays program arguments
167:          */
168:         public AcceleoMainTab(AcceleoJavaArgumentsTab javaArgumentsTab) {
169:                 super();
170:                 this.javaArgumentsTab = javaArgumentsTab;
171:         }
172:
173:         /**
174:          * {@inheritDoc}
175:          *
176:          * @see org.eclipse.debug.ui.AbstractLaunchConfigurationTab#dispose()
177:          */
178:         @Override
179:         public void dispose() {
180:                 super.dispose();
181:                 if (mainTypeShell != null && !mainTypeShell.isDisposed()) {
182:                         mainTypeShell.dispose();
183:                 }
184:         }
185:
186:         /**
187:          * {@inheritDoc}
188:          *
189:          * @see org.eclipse.jdt.debug.ui.launchConfigurations.JavaMainTab#createControl(org.eclipse.swt.widgets.Composite)
190:          */
191:         @Override
192:         public void createControl(Composite parent) {
193:                 super.createControl(parent);
194:                 Composite mainComposite = (Composite)getControl();
195:                 createAcceleoModelEditor(mainComposite);
196:
197:                 createAcceleoTargetEditor(mainComposite);
198:                 if (PROFILE_MODE.equals(getLaunchConfigurationDialog().getMode())) {
199:                         createAcceleoProfileModelEditor(mainComposite, true);
200:                 } else {
201:                         createAcceleoProfileModelEditor(mainComposite, false);
202:                 }
203:
204:                 createAcceleoLaunchconfiguration(mainComposite);
205:
206:                 // Add help to the JDT tabs
207:                 Composite mainClassParent = this.fMainText.getParent();
208:                 createHelpButton(mainClassParent, AcceleoUIMessages.getString("AcceleoMainTab.Help.JavaClass")); //$NON-NLS-1$
209:
210:                 Composite projectParent = this.fProjText.getParent();
211:                 createHelpButton(projectParent, AcceleoUIMessages.getString("AcceleoMainTab.Help.Project")); //$NON-NLS-1$
212:         }
213:
214:         /**
215:          * Creates the configuration group.
216:          *
217:          * @param parent
218:          * The parent composite.
219:          */
220:         private void createAcceleoLaunchconfiguration(Composite parent) {
221:                 Font font = parent.getFont();
222:                 Group mainGroup = createGroup(parent,
223:                                 AcceleoUIMessages.getString("AcceleoMainTab.Configuration"), 2, 1, //$NON-NLS-1$
224:                                 GridData.FILL_HORIZONTAL);
225:                 Composite comp = createComposite(mainGroup, font, 2, 2, GridData.FILL_BOTH, 0, 0);
226:
227:                 createAcceleoLaunchingStrategyEditor(comp);
228:
229:                 createAcceleoTraceabilityEditor(comp);
230:                 if (PROFILE_MODE.equals(getLaunchConfigurationDialog().getMode())) {
231:                         createAcceleoProfilingEditor(comp, true);
232:                 } else {
233:                         createAcceleoProfilingEditor(comp, false);
234:                 }
235:         }
236:
237:         /**
238:          * {@inheritDoc}
239:          *
240:          * @see org.eclipse.jdt.debug.ui.launchConfigurations.JavaMainTab#createMainTypeExtensions(org.eclipse.swt.widgets.Composite)
241:          */
242:         @Override
243:         protected void createMainTypeExtensions(Composite parent) {
244:                 if (mainTypeShell == null) {
245:                         mainTypeShell = new Shell();
246:                 }
247:                 Composite notVisibleComposite = new Composite(mainTypeShell, SWT.NONE);
248:                 super.createMainTypeExtensions(notVisibleComposite);
249:                 notVisibleComposite.setVisible(false);
250:         }
251:
252:         /**
253:          * {@inheritDoc}
254:          *
255:          * @see org.eclipse.debug.ui.AbstractLaunchConfigurationTab#updateLaunchConfigurationDialog()
256:          */
257:         @Override
258:         protected void updateLaunchConfigurationDialog() {
259:                 super.updateLaunchConfigurationDialog();
260:                 updateSettingsVisibility();
261:         }
262:
263:         /**
264:          * Marks the traceability widget as invisible if the launching strategy is 'Java Application', and marks
265:          * it visible otherwise.
266:          */
267:         private void updateSettingsVisibility() {
268:                 if (computeTraceability != null && launchingStrategyCombo != null) {
269:                         if ("Java Application".equals(launchingStrategyCombo.getText())) { //$NON-NLS-1$
270:                                 computeTraceability.setSelection(false);
271:                                 computeTraceability.setVisible(false);
272:                                 traceabilityHelp.setVisible(false);
273:                         } else {
274:                                 computeTraceability.setVisible(true);
275:                                 traceabilityHelp.setVisible(true);
276:                         }
277:                         profileModelButton.setEnabled(computeProfiling.getSelection());
278:                         profileModelText.setEnabled(computeProfiling.getSelection());
279:                 }
280:         }
281:
282:         /**
283:          * Creates a help button in the given parent with the given help message and the given help ID.
284:          *
285:          * @param parent
286:          * The composite
287:          * @param helpMessage
288:          * The help message seen by the user
289:          * @return The toolbar with the button.
290:          */
291:         private ToolBar createHelpButton(Composite parent, String helpMessage) {
292:                 Image image = PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_LCL_LINKTO_HELP);
293:                 ToolBar result = new ToolBar(parent, SWT.FLAT | SWT.NO_FOCUS);
294:                 ((GridLayout)parent.getLayout()).numColumns++;
295:                 result.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
296:                 ToolItem item = new ToolItem(result, SWT.NONE);
297:                 item.setImage(image);
298:                 if (helpMessage != null && !"".equals(helpMessage)) { //$NON-NLS-1$
299:                         item.setToolTipText(helpMessage);
300:                 }
301:                 return result;
302:         }
303:
304:         /**
305:          * Creates the widgets for specifying the model path.
306:          *
307:          * @param parent
308:          * the parent composite
309:          */
310:         protected void createAcceleoModelEditor(Composite parent) {
311:                 Font font = parent.getFont();
312:                 Group mainGroup = createGroup(parent, AcceleoUIMessages.getString("AcceleoMainTab.ModelPath"), 2, 1, //$NON-NLS-1$
313:                                 GridData.FILL_HORIZONTAL);
314:                 Composite comp = createComposite(mainGroup, font, 2, 2, GridData.FILL_BOTH, 0, 0);
315:                 modelText = createSingleText(comp, 1);
316:                 modelText.addModifyListener(new ModifyListener() {
317:                         public void modifyText(ModifyEvent e) {
318:                                 updateLaunchConfigurationDialog();
319:                         }
320:                 });
321:                 modelButton = createPushButton(comp, AcceleoUIMessages.getString(BROWSE_MESSAGE), null);
322:                 modelButton.addSelectionListener(new SelectionListener() {
323:                         public void widgetDefaultSelected(SelectionEvent e) {
324:                         }
325:
326:                         public void widgetSelected(SelectionEvent e) {
327:                                 handleBrowseModelButton();
328:                         }
329:                 });
330:
331:                 createHelpButton(comp, AcceleoUIMessages.getString("AcceleoMainTab.Help.Model")); //$NON-NLS-1$
332:         }
333:
334:         /**
335:          * Creates the widgets for specifying the profile model path.
336:          *
337:          * @param parent
338:          * the parent composite
339:          * @param activatedByDefault
340:          * Indicates if the profiling is activated by default.
341:          */
342:         protected void createAcceleoProfileModelEditor(Composite parent, boolean activatedByDefault) {
343:                 Font font = parent.getFont();
344:                 Group mainGroup = createGroup(parent,
345:                                 AcceleoUIMessages.getString("AcceleoMainTab.ProfileModelPath"), 2, 1, //$NON-NLS-1$
346:                                 GridData.FILL_HORIZONTAL);
347:                 Composite comp = createComposite(mainGroup, font, 2, 2, GridData.FILL_BOTH, 0, 0);
348:                 profileModelText = createSingleText(comp, 1);
349:                 profileModelText.addModifyListener(new ModifyListener() {
350:                         public void modifyText(ModifyEvent e) {
351:                                 updateLaunchConfigurationDialog();
352:                         }
353:                 });
354:                 profileModelButton = createPushButton(comp, AcceleoUIMessages.getString(BROWSE_MESSAGE), null);
355:                 profileModelButton.addSelectionListener(new SelectionListener() {
356:                         public void widgetDefaultSelected(SelectionEvent e) {
357:                                 widgetSelected(e);
358:                         }
359:
360:                         public void widgetSelected(SelectionEvent e) {
361:                                 handleBrowseProfileModelButton();
362:                         }
363:                 });
364:
365:                 createHelpButton(comp, AcceleoUIMessages.getString("AcceleoMainTab.Help.Profile")); //$NON-NLS-1$
366:
367:                 profileModelText.setEnabled(activatedByDefault);
368:                 profileModelButton.setEnabled(activatedByDefault);
369:         }
370:
371:         /**
372:          * Show a dialog that lists all the models.
373:          */
374:         private void handleBrowseModelButton() {
375:                 FilteredResourcesSelectionDialog dialog = new FilteredResourcesSelectionDialog(getShell(), false,
376:                                 ResourcesPlugin.getWorkspace().getRoot(), IResource.FILE);
377:                 dialog.setTitle(AcceleoUIMessages.getString("AcceleoMainTab.SelectModel")); //$NON-NLS-1$
378:                 String path = modelText.getText();
379:                 if (path != null && path.length() > 0 && new Path(path).lastSegment().length() > 0) {
380:                         dialog.setInitialPattern(new Path(path).lastSegment());
381:                 } else {
382:                         String projectName;
383:                         try {
384:                                 projectName = getCurrentLaunchConfiguration().getAttribute(
385:                                                 IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, ""); //$NON-NLS-1$
386:                         } catch (CoreException e) {
387:                                 projectName = ""; //$NON-NLS-1$
388:                                 AcceleoUIActivator.getDefault().getLog().log(e.getStatus());
389:                         }
390:                         String initial;
391:                         if (projectName.toLowerCase().contains(".uml")) { //$NON-NLS-1$
392:                                 initial = "*.uml"; //$NON-NLS-1$
393:                         } else if (projectName.toLowerCase().contains(".ecore")) { //$NON-NLS-1$
394:                                 initial = "*.ecore"; //$NON-NLS-1$
395:                         } else {
396:                                 initial = "*.xmi"; //$NON-NLS-1$
397:                         }
398:                         dialog.setInitialPattern(initial);
399:                 }
400:                 dialog.open();
401:                 if (dialog.getResult() != null && dialog.getResult().length > 0
402:                                 && dialog.getResult()[0] instanceof IFile) {
403:                         modelText.setText(((IFile)dialog.getResult()[0]).getFullPath().toString());
404:                 }
405:         }
406:
407:         /**
408:          * Show a dialog that lists all the models.
409:          */
410:         private void handleBrowseProfileModelButton() {
411:                 IResource initialResource;
412:                 if (new Path(profileModelText.getText()).segmentCount() >= 2
413:                                 && ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(profileModelText.getText()))
414:                                                 .exists()) {
415:                         initialResource = ResourcesPlugin.getWorkspace().getRoot().getFile(
416:                                         new Path(profileModelText.getText()));
417:                 } else {
418:                         initialResource = ResourcesPlugin.getWorkspace().getRoot();
419:                 }
420:                 ResourceSelectionDialog dialog = new ResourceSelectionDialog(getShell(), initialResource,
421:                                 AcceleoUIMessages.getString("AcceleoMainTab.SelectProfileModel")); //$NON-NLS-1$
422:                 dialog.setContentProvider(new FileTreeContentProvider(true, PROFILE_EXTENSION));
423:                 dialog.open();
424:
425:                 if (dialog.getResult().length > 0 && dialog.getResult()[0] instanceof IPath
426:                                 && ((IPath)dialog.getResult()[0]).segmentCount() > 0) {
427:
428:                         String path = dialog.getResult()[0].toString();
429:                         if (path.endsWith(PROFILE_EXTENSION)) {
430:                                 profileModelText.setText(path);
431:                         } else if (path.endsWith("/")) { //$NON-NLS-1$
432:                                 profileModelText.setText(path + "profiling.mtlp"); //$NON-NLS-1$
433:                         } else {
434:                                 profileModelText.setText(path + "/profiling.mtlp"); //$NON-NLS-1$
435:                         }
436:                 }
437:         }
438:
439:         /**
440:          * Creates the widgets for specifying the target folder.
441:          *
442:          * @param parent
443:          * the parent composite
444:          */
445:         protected void createAcceleoTargetEditor(Composite parent) {
446:                 Font font = parent.getFont();
447:                 Group mainGroup = createGroup(parent, AcceleoUIMessages.getString("AcceleoMainTab.TargetPath"), 2, 1, //$NON-NLS-1$
448:                                 GridData.FILL_HORIZONTAL);
449:                 Composite comp = createComposite(mainGroup, font, 2, 2, GridData.FILL_BOTH, 0, 0);
450:                 targetText = createSingleText(comp, 1);
451:                 targetText.addModifyListener(new ModifyListener() {
452:                         public void modifyText(ModifyEvent e) {
453:                                 updateLaunchConfigurationDialog();
454:                         }
455:                 });
456:                 targetButton = createPushButton(comp, AcceleoUIMessages.getString(BROWSE_MESSAGE), null);
457:                 targetButton.addSelectionListener(new SelectionListener() {
458:                         public void widgetDefaultSelected(SelectionEvent e) {
459:                         }
460:
461:                         public void widgetSelected(SelectionEvent e) {
462:                                 handleBrowseTargetButton();
463:                         }
464:                 });
465:                 createHelpButton(comp, AcceleoUIMessages.getString("AcceleoMainTab.Help.Target")); //$NON-NLS-1$
466:         }
467:
468:         /**
469:          * Show a dialog that lists all the models.
470:          */
471:         private void handleBrowseTargetButton() {
472:                 IResource initial;
473:                 if (targetText.getText() != null && targetText.getText().length() > 0) {
474:                         initial = ResourcesPlugin.getWorkspace().getRoot().findMember(new Path(targetText.getText()));
475:                         if (initial instanceof IFile) {
476:                                 initial = initial.getParent();
477:                         }
478:                 } else {
479:                         initial = null;
480:                 }
481:                 ContainerSelectionDialog dialog = new ContainerSelectionDialog(getShell(), ResourcesPlugin
482:                                 .getWorkspace().getRoot(), true, AcceleoUIMessages
483:                                 .getString("AcceleoNewTemplateWizardPage.ContainerSelection")); //$NON-NLS-1$
484:                 if (initial != null) {
485:                         dialog.setInitialSelections(new Object[] {initial });
486:                 }
487:                 dialog.showClosedProjects(false);
488:                 if (dialog.open() == Window.OK) {
489:                         Object[] result = dialog.getResult();
490:                         if (result.length == 1) {
491:                                 targetText.setText(((Path)result[0]).toString());
492:                         }
493:                 }
494:         }
495:
496:         /**
497:          * Creates the widgets for specifying if we compute the traceability information.
498:          *
499:          * @param parent
500:          * the parent composite
501:          */
502:         protected void createAcceleoTraceabilityEditor(Composite parent) {
503:                 Font font = parent.getFont();
504:                 Composite comp = createComposite(parent, font, 1, 2, GridData.FILL_BOTH, 0, 0);
505:                 computeTraceability = new Button(comp, SWT.CHECK);
506:                 computeTraceability.setFont(font);
507:                 GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL);
508:                 gd.horizontalSpan = 1;
509:                 computeTraceability.setLayoutData(gd);
510:                 computeTraceability.setText(AcceleoUIMessages.getString("AcceleoMainTab.ComputeTraceability")); //$NON-NLS-1$
511:                 computeTraceability.addSelectionListener(new SelectionListener() {
512:                         public void widgetSelected(SelectionEvent e) {
513:                                 updateLaunchConfigurationDialog();
514:                         }
515:
516:                         public void widgetDefaultSelected(SelectionEvent e) {
517:
518:                         }
519:                 });
520:
521:                 traceabilityHelp = createHelpButton(comp, AcceleoUIMessages
522:                                 .getString("AcceleoMainTab.Help.Traceability")); //$NON-NLS-1$
523:         }
524:
525:         /**
526:          * Creates the widgets for specifying if we compute the traceability information.
527:          *
528:          * @param parent
529:          * the parent composite
530:          * @param checkedByDefault
531:          * Indicates if the checkbox should be checked by default.
532:          */
533:         protected void createAcceleoProfilingEditor(Composite parent, boolean checkedByDefault) {
534:                 Font font = parent.getFont();
535:
536:                 Composite comp = createComposite(parent, font, 1, 2, GridData.FILL_BOTH, 0, 0);
537:                 computeProfiling = new Button(comp, SWT.CHECK);
538:                 computeProfiling.setFont(font);
539:                 GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL);
540:                 gd.horizontalSpan = 1;
541:                 computeProfiling.setLayoutData(gd);
542:                 computeProfiling.setText(AcceleoUIMessages.getString("AcceleoMainTab.ComputeProfiling")); //$NON-NLS-1$
543:                 computeProfiling.addSelectionListener(new SelectionListener() {
544:                         public void widgetSelected(SelectionEvent e) {
545:                                 Widget widget = e.widget;
546:                                 if (widget instanceof Button) {
547:                                         Button button = (Button)widget;
548:                                         profileModelText.setEnabled(button.getSelection());
549:                                         profileModelButton.setEnabled(button.getSelection());
550:                                         AcceleoPreferences.switchProfiler(button.getSelection());
551:                                         updateLaunchConfigurationDialog();
552:                                 }
553:                         }
554:
555:                         public void widgetDefaultSelected(SelectionEvent e) {
556:
557:                         }
558:                 });
559:
560:                 computeProfiling.setSelection(checkedByDefault);
561:                 createHelpButton(comp, AcceleoUIMessages.getString("AcceleoMainTab.Help.Profiling")); //$NON-NLS-1$
562:         }
563:
564:         /**
565:          * Creates the widgets for specifying the launching strategy.
566:          *
567:          * @param parent
568:          * the parent composite
569:          */
570:         protected void createAcceleoLaunchingStrategyEditor(Composite parent) {
571:                 Composite comp = createComposite(parent, parent.getFont(), 2, 2, GridData.FILL_BOTH, 0, 0);
572:
573:                 Label label = new Label(comp, SWT.NONE);
574:                 label.setText(AcceleoUIMessages.getString("AcceleoMainTab.LaunchingStrategy")); //$NON-NLS-1$
575:                 GridData gridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
576:                 gridData.horizontalSpan = 1;
577:                 label.setLayoutData(gridData);
578:
579:                 launchingStrategyCombo = new Combo(comp, SWT.READ_ONLY);
580:                 gridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL);
581:                 gridData.horizontalSpan = 1;
582:                 launchingStrategyCombo.setLayoutData(gridData);
583:                 launchingStrategyCombo.addSelectionListener(new SelectionListener() {
584:                         public void widgetDefaultSelected(SelectionEvent e) {
585:                                 // nothing to do here
586:                         }
587:
588:                         public void widgetSelected(SelectionEvent e) {
589:                                 updateLaunchConfigurationDialog();
590:                         }
591:                 });
592:                 updateStrategies();
593:•                if (launchingStrategyCombo.getItemCount() > 0) {
594:                         launchingStrategyCombo.select(0);
595:                 }
596:
597:                 createHelpButton(comp, AcceleoUIMessages.getString("AcceleoMainTab.Help.Strategy")); //$NON-NLS-1$
598:         }
599:
600:         /**
601:          * Refreshes the available example strategies in the current Eclipse instance.
602:          */
603:         private void updateStrategies() {
604:                 if (launchingStrategyCombo != null) {
605:                         List<String> descriptions = new ArrayList<String>();
606:                         Iterator<String> strategies = getLaunchingStrategies().iterator();
607:                         while (strategies.hasNext()) {
608:                                 descriptions.add(strategies.next());
609:                         }
610:
611:                         launchingStrategyCombo.setItems(descriptions.toArray(new String[descriptions.size()]));
612:                         final int visibleItemCount = 15;
613:                         if (descriptions.size() < visibleItemCount) {
614:                                 launchingStrategyCombo.setVisibleItemCount(descriptions.size());
615:                         } else {
616:                                 launchingStrategyCombo.setVisibleItemCount(visibleItemCount);
617:                         }
618:                 }
619:         }
620:
621:         /**
622:          * Creates a Group widget.
623:          *
624:          * @param parent
625:          * the parent composite to add this group to
626:          * @param text
627:          * the text for the heading of the group
628:          * @param columns
629:          * the number of columns within the group
630:          * @param hspan
631:          * the horizontal span the group should take up on the parent
632:          * @param fill
633:          * the style for how this composite should fill into its parent Can be one of
634:          * <code>GridData.FILL_HORIZONAL</code>, <code>GridData.FILL_BOTH</code> or
635:          * <code>GridData.FILL_VERTICAL</code>
636:          * @return the new group
637:          */
638:         private Group createGroup(Composite parent, String text, int columns, int hspan, int fill) {
639:                 Group g = new Group(parent, SWT.NONE);
640:                 g.setLayout(new GridLayout(columns, false));
641:                 g.setText(text);
642:                 g.setFont(parent.getFont());
643:                 GridData gd = new GridData(fill);
644:                 gd.horizontalSpan = hspan;
645:                 g.setLayoutData(gd);
646:                 return g;
647:         }
648:
649:         /**
650:          * Creates a Composite widget.
651:          *
652:          * @param parent
653:          * the parent composite to add this composite to
654:          * @param font
655:          * is the font
656:          * @param columns
657:          * the number of columns within the composite
658:          * @param hspan
659:          * the horizontal span the composite should take up on the parent
660:          * @param fill
661:          * the style for how this composite should fill into its parent Can be one of
662:          * <code>GridData.FILL_HORIZONAL</code>, <code>GridData.FILL_BOTH</code> or
663:          * <code>GridData.FILL_VERTICAL</code>
664:          * @param marginwidth
665:          * the width of the margin to place around the composite (default is 5, specified by
666:          * GridLayout)
667:          * @param marginheight
668:          * the height of the margin to place around the composite (default is 5, specified by
669:          * GridLayout)
670:          * @return the new group
671:          */
672:         private Composite createComposite(Composite parent, Font font, int columns, int hspan, int fill,
673:                         int marginwidth, int marginheight) {
674:                 Composite g = new Composite(parent, SWT.NONE);
675:                 GridLayout layout = new GridLayout(columns, false);
676:                 layout.marginWidth = marginwidth;
677:                 layout.marginHeight = marginheight;
678:                 g.setLayout(layout);
679:                 g.setFont(font);
680:                 GridData gd = new GridData(fill);
681:                 gd.horizontalSpan = hspan;
682:                 g.setLayoutData(gd);
683:                 return g;
684:         }
685:
686:         /**
687:          * Creates a new text widget.
688:          *
689:          * @param parent
690:          * the parent composite to add this text widget to
691:          * @param hspan
692:          * the horizontal span to take up on the parent composite
693:          * @return the new text widget
694:          */
695:         private Text createSingleText(Composite parent, int hspan) {
696:                 Text t = new Text(parent, SWT.SINGLE | SWT.BORDER);
697:                 t.setFont(parent.getFont());
698:                 GridData gd = new GridData(GridData.FILL_HORIZONTAL);
699:                 gd.horizontalSpan = hspan;
700:                 t.setLayoutData(gd);
701:                 return t;
702:         }
703:
704:         /**
705:          * {@inheritDoc}
706:          *
707:          * @see org.eclipse.jdt.debug.ui.launchConfigurations.JavaMainTab#getName()
708:          */
709:         @Override
710:         public String getName() {
711:                 return "Acceleo"; //$NON-NLS-1$
712:         }
713:
714:         /**
715:          * {@inheritDoc}
716:          *
717:          * @see org.eclipse.jdt.debug.ui.launchConfigurations.JavaMainTab#getId()
718:          */
719:         @Override
720:         public String getId() {
721:                 return "org.eclipse.acceleo.ide.ui.launching.acceleoMainTab"; //$NON-NLS-1$
722:         }
723:
724:         /**
725:          * {@inheritDoc}
726:          *
727:          * @see org.eclipse.jdt.debug.ui.launchConfigurations.JavaMainTab#initializeFrom(org.eclipse.debug.core.ILaunchConfiguration)
728:          */
729:         @Override
730:         public void initializeFrom(ILaunchConfiguration config) {
731:                 super.initializeFrom(config);
732:                 updateAcceleoModelFromConfig(config);
733:                 updateAcceleoProfileModelFromConfig(config);
734:                 updateAcceleoTargetFromConfig(config);
735:                 updateAcceleoTraceabilityFromConfig(config);
736:                 updateAcceleoLaunchingStrategyFromConfig(config);
737:                 updateSettingsVisibility();
738:         }
739:
740:         /**
741:          * Loads the model path from the launch configuration's preference store.
742:          *
743:          * @param config
744:          * the configuration to load the model path
745:          */
746:         protected void updateAcceleoModelFromConfig(ILaunchConfiguration config) {
747:                 String model = ""; //$NON-NLS-1$
748:                 try {
749:                         model = config.getAttribute(IAcceleoLaunchConfigurationConstants.ATTR_MODEL_PATH, ""); //$NON-NLS-1$
750:                 } catch (CoreException e) {
751:                         AcceleoUIActivator.getDefault().getLog().log(e.getStatus());
752:                 }
753:                 modelText.setText(model);
754:         }
755:
756:         /**
757:          * Loads the profile model path from the launch configuration's preference store.
758:          *
759:          * @param config
760:          * the configuration to load the model path
761:          */
762:         protected void updateAcceleoProfileModelFromConfig(ILaunchConfiguration config) {
763:                 String model = ""; //$NON-NLS-1$
764:                 try {
765:                         model = config.getAttribute(IAcceleoLaunchConfigurationConstants.ATTR_PROFILE_MODEL_PATH, ""); //$NON-NLS-1$
766:                         boolean profiling = config.getAttribute(
767:                                         IAcceleoLaunchConfigurationConstants.ATTR_COMPUTE_PROFILING, false);
768:                         if (profiling) {
769:                                 computeProfiling.setSelection(true);
770:                         } else {
771:                                 computeProfiling.setSelection(false);
772:                         }
773:                 } catch (CoreException e) {
774:                         AcceleoUIActivator.getDefault().getLog().log(e.getStatus());
775:                 }
776:                 profileModelText.setText(model);
777:         }
778:
779:         /**
780:          * Loads the target path from the launch configuration's preference store.
781:          *
782:          * @param config
783:          * the configuration to load the target path
784:          */
785:         protected void updateAcceleoTargetFromConfig(ILaunchConfiguration config) {
786:                 String target = ""; //$NON-NLS-1$
787:                 try {
788:                         target = config.getAttribute(IAcceleoLaunchConfigurationConstants.ATTR_TARGET_PATH, ""); //$NON-NLS-1$
789:                 } catch (CoreException e) {
790:                         AcceleoUIActivator.getDefault().getLog().log(e.getStatus());
791:                 }
792:                 targetText.setText(target);
793:         }
794:
795:         /**
796:          * Loads the traceability status from the launch configuration's preference store.
797:          *
798:          * @param config
799:          * the configuration to load the target path
800:          */
801:         protected void updateAcceleoTraceabilityFromConfig(ILaunchConfiguration config) {
802:                 boolean traceability = false;
803:                 try {
804:                         traceability = config.getAttribute(
805:                                         IAcceleoLaunchConfigurationConstants.ATTR_COMPUTE_TRACEABILITY, false);
806:                 } catch (CoreException e) {
807:                         AcceleoUIActivator.getDefault().getLog().log(e.getStatus());
808:                 }
809:                 computeTraceability.setSelection(traceability);
810:         }
811:
812:         /**
813:          * Loads the launching strategy from the launch configuration's preference store.
814:          *
815:          * @param config
816:          * the configuration to load the launching strategy
817:          */
818:         protected void updateAcceleoLaunchingStrategyFromConfig(ILaunchConfiguration config) {
819:                 String id = ""; //$NON-NLS-1$
820:                 try {
821:                         id = config.getAttribute(
822:                                         IAcceleoLaunchConfigurationConstants.ATTR_LAUNCHING_STRATEGY_DESCRIPTION, ""); //$NON-NLS-1$
823:                 } catch (CoreException e) {
824:                         AcceleoUIActivator.getDefault().getLog().log(e.getStatus());
825:                 }
826:
827:                 int item = -1;
828:                 List<String> strategies = this.getLaunchingStrategies();
829:                 for (int i = 0; i < strategies.size(); i++) {
830:                         if (id.startsWith(strategies.get(i))) {
831:                                 item = i;
832:                         }
833:                 }
834:
835:                 if (item == -1) {
836:                         item = 0;
837:                 }
838:                 if (launchingStrategyCombo.getItemCount() > item) {
839:                         launchingStrategyCombo.select(item);
840:                 } else if (launchingStrategyCombo.getItemCount() > 0) {
841:                         launchingStrategyCombo.select(0);
842:                 }
843:         }
844:
845:         /**
846:          * {@inheritDoc}
847:          *
848:          * @see org.eclipse.jdt.debug.ui.launchConfigurations.JavaMainTab#isValid(org.eclipse.debug.core.ILaunchConfiguration)
849:          */
850:         @Override
851:         public boolean isValid(ILaunchConfiguration config) {
852:                 boolean result = super.isValid(config);
853:
854:                 Bundle bundle = Platform.getBundle("org.eclipse.osgi"); //$NON-NLS-1$
855:                 if (bundle != null) {
856:                         int selectionIndex = this.launchingStrategyCombo.getSelectionIndex();
857:                         String selectedStrategy = this.launchingStrategyCombo.getItem(selectionIndex);
858:                         List<String> strategies = this.getLaunchingStrategies();
859:
860:                         // Luna version
861:                         Version keplerVersion = Version.parseVersion("3.10.0"); //$NON-NLS-1$
862:                         if (bundle.getVersion().compareTo(keplerVersion) >= 0
863:                                         && selectedStrategy.equals(strategies.get(1))) {
864:                                 this.setErrorMessage(AcceleoUIMessages.getString("AcceleoMainTab.Error.PluginLaunchWithLuna")); //$NON-NLS-1$
865:                         }
866:                 }
867:
868:                 IWorkspace workspace = ResourcesPlugin.getWorkspace();
869:                 if (result) {
870:                         String model = modelText.getText().trim();
871:                         IStatus status = workspace.validatePath(model, IResource.FILE);
872:                         if (status.isOK()) {
873:                                 IFile file = workspace.getRoot().getFile(new Path(model));
874:                                 if (!file.exists()) {
875:                                         setErrorMessage(AcceleoUIMessages.getString("AcceleoMainTab.Error.MissingModel", //$NON-NLS-1$
876:                                                         new Object[] {model }));
877:                                         result = false;
878:                                 }
879:                         } else {
880:                                 setErrorMessage(AcceleoUIMessages.getString(
881:                                                 "AcceleoMainTab.Error.InvalidModel", new Object[] {model })); //$NON-NLS-1$
882:                                 result = false;
883:                         }
884:                 }
885:                 if (result) {
886:                         String target = targetText.getText().trim();
887:                         IStatus status = workspace.validatePath(target, IResource.FOLDER | IResource.PROJECT);
888:                         if (!status.isOK()) {
889:                                 setErrorMessage(AcceleoUIMessages.getString("AcceleoMainTab.Error.InvalidTarget", //$NON-NLS-1$
890:                                                 new Object[] {target }));
891:                                 result = false;
892:                         }
893:                 }
894:                 if (result && computeProfiling.getSelection()) {
895:                         if ("".equals(profileModelText.getText().trim())) { //$NON-NLS-1$
896:                                 setErrorMessage(AcceleoUIMessages.getString("AcceleoMainTab.Error.MissingProfileModel")); //$NON-NLS-1$
897:                                 result = false;
898:                         } else if (!profileModelText.getText().trim().endsWith(PROFILE_EXTENSION)) {
899:                                 setErrorMessage(AcceleoUIMessages
900:                                                 .getString("AcceleoMainTab.Error.MissingProfileModelExtension")); //$NON-NLS-1$
901:                                 result = false;
902:                         }
903:                 }
904:                 return result;
905:         }
906:
907:         /**
908:          * {@inheritDoc}
909:          *
910:          * @see org.eclipse.jdt.debug.ui.launchConfigurations.JavaMainTab#performApply(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
911:          */
912:         @Override
913:         public void performApply(ILaunchConfigurationWorkingCopy config) {
914:                 if (javaArgumentsTab != null) {
915:                         AcceleoPropertiesFilesTab acceleoPropertiesFilesTab = null;
916:                         ILaunchConfigurationTab[] tabs = this.getLaunchConfigurationDialog().getTabs();
917:                         for (ILaunchConfigurationTab iLaunchConfigurationTab : tabs) {
918:                                 if (iLaunchConfigurationTab instanceof AcceleoPropertiesFilesTab) {
919:                                         acceleoPropertiesFilesTab = (AcceleoPropertiesFilesTab)iLaunchConfigurationTab;
920:                                 }
921:                         }
922:                         String arguments = null;
923:                         if (acceleoPropertiesFilesTab != null) {
924:                                 arguments = acceleoPropertiesFilesTab.getPropertiesFiles();
925:                         }
926:                         javaArgumentsTab.updateArguments(config, modelText.getText().trim(), targetText.getText().trim(),
927:                                         arguments);
928:                 }
929:                 super.performApply(config);
930:                 config.setAttribute(IAcceleoLaunchConfigurationConstants.ATTR_MODEL_PATH, modelText.getText().trim());
931:                 config.setAttribute(IAcceleoLaunchConfigurationConstants.ATTR_COMPUTE_PROFILING, computeProfiling
932:                                 .getSelection());
933:                 if (computeProfiling.getSelection()) {
934:                         config.setAttribute(IAcceleoLaunchConfigurationConstants.ATTR_PROFILE_MODEL_PATH,
935:                                         profileModelText.getText().trim());
936:                 }
937:                 config.setAttribute(IAcceleoLaunchConfigurationConstants.ATTR_TARGET_PATH, targetText.getText()
938:                                 .trim());
939:                 config.setAttribute(IAcceleoLaunchConfigurationConstants.ATTR_COMPUTE_TRACEABILITY,
940:                                 computeTraceability.getSelection());
941:                 config.setAttribute(IAcceleoLaunchConfigurationConstants.ATTR_LAUNCHING_STRATEGY_DESCRIPTION,
942:                                 launchingStrategyCombo.getText());
943:         }
944:
945:         /**
946:          * {@inheritDoc}
947:          *
948:          * @see org.eclipse.jdt.debug.ui.launchConfigurations.JavaMainTab#setDefaults(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
949:          */
950:         @Override
951:         public void setDefaults(ILaunchConfigurationWorkingCopy config) {
952:                 super.setDefaults(config);
953:                 config.setAttribute(IAcceleoLaunchConfigurationConstants.ATTR_MODEL_PATH, ""); //$NON-NLS-1$
954:                 if (computeProfiling != null && computeProfiling.getSelection()) {
955:                         config.setAttribute(IAcceleoLaunchConfigurationConstants.ATTR_PROFILE_MODEL_PATH, ""); //$NON-NLS-1$
956:                 }
957:                 config.setAttribute(IAcceleoLaunchConfigurationConstants.ATTR_TARGET_PATH, ""); //$NON-NLS-1$
958:                 config.setAttribute(IAcceleoLaunchConfigurationConstants.ATTR_COMPUTE_TRACEABILITY, false);
959:                 config.setAttribute(IAcceleoLaunchConfigurationConstants.ATTR_ARGUMENTS, ""); //$NON-NLS-1$
960:                 config.setAttribute(IAcceleoLaunchConfigurationConstants.ATTR_LAUNCHING_STRATEGY_DESCRIPTION, ""); //$NON-NLS-1$
961:         }
962:
963:         /**
964:          * {@inheritDoc}
965:          *
966:          * @see org.eclipse.jdt.debug.ui.launchConfigurations.JavaMainTab#getImage()
967:          */
968:         @Override
969:         public Image getImage() {
970:                 return AcceleoUIActivator.getDefault().getImage("icons/template-editor/Template_main.gif"); //$NON-NLS-1$
971:         }
972:
973:         /**
974:          * Gets all the launching strategies existing in the current Eclipse instance. The identifier of the
975:          * internal extension point specifying the implementation to use for launching strategy. It is used to
976:          * define a specific way of launching an Acceleo generation.
977:          *
978:          * @return all the launching strategies descriptions
979:          */
980:         private List<String> getLaunchingStrategies() {
981:                 List<String> acceleoStrategies = new ArrayList<String>();
982:
983:                 if (launchingStrategies == null) {
984:                         launchingStrategies = new ArrayList<String>();
985:                         IExtensionRegistry registry = Platform.getExtensionRegistry();
986:                         IExtensionPoint extensionPoint = registry
987:                                         .getExtensionPoint(IAcceleoLaunchingStrategy.LAUNCHING_STRATEGY_EXTENSION_ID);
988:                         if (extensionPoint != null && extensionPoint.getExtensions().length > 0) {
989:                                 IExtension[] extensions = extensionPoint.getExtensions();
990:                                 for (int i = 0; i < extensions.length; i++) {
991:                                         IExtension extension = extensions[i];
992:                                         IConfigurationElement[] members = extension.getConfigurationElements();
993:                                         for (int j = 0; j < members.length; j++) {
994:                                                 IConfigurationElement member = members[j];
995:                                                 String name = member.getContributor().getName();
996:                                                 String description = member.getAttribute("description"); //$NON-NLS-1$
997:                                                 if (description != null && description.length() > 0
998:                                                                 && AcceleoUIActivator.PLUGIN_ID.equals(name)) {
999:                                                         acceleoStrategies.add(description);
1000:                                                 } else if (description != null && description.length() > 0) {
1001:                                                         launchingStrategies.add(description);
1002:                                                 }
1003:                                         }
1004:                                 }
1005:                         }
1006:                         Collections.sort(launchingStrategies);
1007:                 }
1008:                 launchingStrategies.addAll(0, acceleoStrategies);
1009:                 return launchingStrategies;
1010:         }
1011:
1012:         /**
1013:          * Returns the model.
1014:          *
1015:          * @return The model
1016:          */
1017:         public String getModel() {
1018:                 return this.modelText.getText();
1019:         }
1020:
1021:         /**
1022:          * Returns the target folder.
1023:          *
1024:          * @return The target folder.
1025:          */
1026:         public String getTarget() {
1027:                 return this.targetText.getText();
1028:         }
1029:
1030: }