Skip to content

Package: SelectSubclassAndTemplateWizard$SelectionPage

SelectSubclassAndTemplateWizard$SelectionPage

nameinstructionbranchcomplexitylinemethod
SelectSubclassAndTemplateWizard.SelectionPage(SelectSubclassAndTemplateWizard, String, String, String)
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%
createControl(Composite)
M: 0 C: 39
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 9
100%
M: 0 C: 1
100%
handleDoubleClick(DoubleClickEvent)
M: 23 C: 0
0%
M: 6 C: 0
0%
M: 4 C: 0
0%
M: 5 C: 0
0%
M: 1 C: 0
0%

Coverage

1: /*******************************************************************************
2: * Copyright (c) 2011-2018 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: * Lucas Koehler - initial API and implementation
13: ******************************************************************************/
14: package org.eclipse.emfforms.internal.core.services.datatemplate;
15:
16: import java.util.Collections;
17: import java.util.HashSet;
18: import java.util.LinkedHashSet;
19: import java.util.Set;
20:
21: import org.eclipse.emf.ecore.EClass;
22: import org.eclipse.emf.ecore.EPackage;
23: import org.eclipse.emf.ecp.spi.common.ui.CompositeFactory;
24: import org.eclipse.emf.ecp.spi.common.ui.composites.SelectionComposite;
25: import org.eclipse.emfforms.common.Optional;
26: import org.eclipse.emfforms.datatemplate.Template;
27: import org.eclipse.emfforms.spi.localization.EMFFormsLocalizationService;
28: import org.eclipse.jface.viewers.ColumnViewer;
29: import org.eclipse.jface.viewers.DoubleClickEvent;
30: import org.eclipse.jface.viewers.IStructuredSelection;
31: import org.eclipse.jface.viewers.SelectionChangedEvent;
32: import org.eclipse.jface.viewers.TableViewer;
33: import org.eclipse.jface.viewers.TreeViewer;
34: import org.eclipse.jface.wizard.IWizardPage;
35: import org.eclipse.jface.wizard.Wizard;
36: import org.eclipse.jface.wizard.WizardDialog;
37: import org.eclipse.jface.wizard.WizardPage;
38: import org.eclipse.swt.widgets.Composite;
39:
40: /**
41: * Wizard that allows to select an {@link EClass} on the first page and a model element on the second page. Thereby, the
42: * second page only shows model elements that are an instance of the selected EClass.
43: * <p>
44: * If there is only one possible EClass, the class selection page is skipped and the template selection is shown
45: * directly.
46: * <br />
47: * If there is only one template left after selecting the EClass, the template selection page is skipped and the
48: * remaining {@link Template} counts as selected.
49: *
50: * @author Lucas Koehler
51: *
52: */
53: public class SelectSubclassAndTemplateWizard extends Wizard {
54:
55:         private static final String TEMPLATE_PAGE_NAME = "templateSelectionPage"; //$NON-NLS-1$
56:         private static final String CLASS_PAGE_NAME = "subClassSelectionPage"; //$NON-NLS-1$
57:
58:         private SubClassSelectionPage subClassSelectionPage;
59:         private TemplateSelectionPage modelElementPage;
60:         private final Set<EClass> subClasses;
61:         private final Set<Template> allTemplates;
62:         private boolean showTemplateSelectionPage = true;
63:         private final EMFFormsLocalizationService localizationService;
64:
65:         private EClass selectedSubClass;
66:         private boolean finished;
67:
68:         /**
69:          * Creates a new instance.
70:          *
71:          * @param windowTitle The title of the wizard
72:          * @param subClasses The EClasses to choose from
73:          * @param templates The available templates for all given EClasses
74:          * @param localizationService The {@link EMFFormsLocalizationService}
75:          */
76:         public SelectSubclassAndTemplateWizard(String windowTitle, Set<EClass> subClasses, Set<Template> templates,
77:                 EMFFormsLocalizationService localizationService) {
78:                 setWindowTitle(windowTitle);
79:                 this.subClasses = subClasses;
80:                 this.localizationService = localizationService;
81:                 allTemplates = templates;
82:         }
83:
84:         @Override
85:         public boolean performFinish() {
86:                 finished = true;
87:                 return true;
88:         }
89:
90:         @Override
91:         public boolean canFinish() {
92:                 if (selectedSubClass != null && !showTemplateSelectionPage) {
93:                         return true;
94:                 }
95:                 return super.canFinish();
96:         }
97:
98:         /**
99:          * Returns the template selected by the user. If there is only one valid template left after selecting a sub class,
100:          * this template is selected automatically without showing the second wizard page.
101:          *
102:          * @return The selected {@link Template}, or the empty Optional if none was selected
103:          */
104:         public Optional<Template> getSelectedTemplate() {
105:                 if (!finished) {
106:                         // Return an empty Optional in case the wizard was not finished successfully (e.g. by canceling it)
107:                         return Optional.empty();
108:                 }
109:                 if (showTemplateSelectionPage) {
110:                         final Object[] selection = modelElementPage.getSelectionComposite().getSelection();
111:                         if (selection != null && selection.length > 0) {
112:                                 return Optional.of((Template) selection[0]);
113:                         }
114:                 } else if (selectedSubClass != null) {
115:                         final Set<Template> templates = getAvailableTemplates(selectedSubClass);
116:                         if (templates.iterator().hasNext()) {
117:                                 return Optional.of(templates.iterator().next());
118:                         }
119:                 }
120:                 return Optional.empty();
121:         }
122:
123:         @Override
124:         public void addPages() {
125:                 modelElementPage = new TemplateSelectionPage(TEMPLATE_PAGE_NAME,
126:                         localizationService.getString(SelectSubclassAndTemplateWizard.class,
127:                                 MessageKeys.SelectSubclassAndTemplateWizard_selectTemplateTitle),
128:                         localizationService.getString(SelectSubclassAndTemplateWizard.class,
129:                                 MessageKeys.SelectSubclassAndTemplateWizard_selectTemplateDescription));
130:
131:                 if (subClasses.size() > 1) {
132:                         subClassSelectionPage = new SubClassSelectionPage(CLASS_PAGE_NAME,
133:                                 localizationService.getString(SelectSubclassAndTemplateWizard.class,
134:                                         MessageKeys.SelectSubclassAndTemplateWizard_selectSubClassTitle),
135:                                 localizationService.getString(SelectSubclassAndTemplateWizard.class,
136:                                         MessageKeys.SelectSubclassAndTemplateWizard_selectSubClassDescription),
137:                                 subClasses);
138:                         addPage(subClassSelectionPage);
139:                 }
140:
141:                 addPage(modelElementPage);
142:
143:                 if (subClasses.size() == 1) {
144:                         selectedSubClass = subClasses.iterator().next();
145:                 }
146:                 super.addPages();
147:
148:         }
149:
150:         @Override
151:         public IWizardPage getNextPage(IWizardPage page) {
152:                 if (page == subClassSelectionPage && !showTemplateSelectionPage) {
153:                         // Do not show the template selection page if there is no need to
154:                         return null;
155:                 }
156:                 return super.getNextPage(page);
157:         }
158:
159:         /**
160:          * Update the selected sub class. This is typically called by the {@link SubClassSelectionPage}.
161:          *
162:          * @param subClass The selected sub class
163:          */
164:         protected void setSubClass(EClass subClass) {
165:                 // Necessary to update in case the user goes back in the wizard and selects a different sub class.
166:                 final Set<Template> availableTemplates = subClass != null
167:                         ? getAvailableTemplates(subClass)
168:                         : Collections.<Template> emptySet();
169:                 showTemplateSelectionPage = availableTemplates.size() > 1;
170:                 modelElementPage.updateSelectionComposite(availableTemplates);
171:                 selectedSubClass = subClass;
172:         }
173:
174:         /**
175:          * Get all available templates for the given {@link EClass}. Thereby, only templates whose instance exactly match
176:          * the given EClass are returned. This does <strong>not</strong> include templates for sub classes of the given
177:          * EClass.
178:          *
179:          * @param eClass The {@link EClass}
180:          * @return The available templates
181:          */
182:         protected Set<Template> getAvailableTemplates(EClass eClass) {
183:                 final Set<Template> availableTemplates = new LinkedHashSet<Template>();
184:                 if (eClass != null) {
185:                         for (final Template template : allTemplates) {
186:                                 try {
187:                                         if (eClass == template.getInstance().eClass()) {
188:                                                 availableTemplates.add(template);
189:                                         }
190:                                 }
191:                                 // CHECKSTYLE.OFF: IllegalCatch
192:                                 catch (final RuntimeException e) {
193:                                         // ignore as somebody broke the eclass
194:                                 }
195:                                 // CHECKSTYLE.ON: IllegalCatch
196:                         }
197:                 }
198:
199:                 return availableTemplates;
200:         }
201:
202:         /**
203:          * Abstract base class for the eclass and template selection pages.
204:          *
205:          * @author Lucas Koehler
206:          */
207:         abstract class SelectionPage extends WizardPage {
208:
209:                 /**
210:                  * @param pageName The page's unique name
211:                  * @param pageTitle The title shown for this wizard page
212:                  * @param pageDescription The description shown on this wizard page
213:                  */
214:                 protected SelectionPage(String pageName, String pageTitle, String pageDescription) {
215:                         super(pageName);
216:                         setTitle(pageTitle);
217:                         setDescription(pageDescription);
218:                 }
219:
220:                 @Override
221:                 public void createControl(Composite parent) {
222:                         final Composite composite = getSelectionComposite().createUI(parent);
223:•                        if (getSelectionComposite().getViewer() instanceof TreeViewer) {
224:                                 final TreeViewer tv = (TreeViewer) getSelectionComposite().getViewer();
225:                                 tv.expandToLevel(2);
226:                         }
227:                         getSelectionComposite().getViewer().addSelectionChangedListener(this::handleSelectionChanged);
228:                         getSelectionComposite().getViewer().addDoubleClickListener(this::handleDoubleClick);
229:                         setPageComplete(false);
230:                         setControl(composite);
231:
232:                 }
233:
234:                 /**
235:                  * Handle double click in the selection composite viewer. If the selection triggered by the double click allows
236:                  * to flip to the next page or finish the wizard, automatically do this.
237:                  *
238:                  * @param event The double click event
239:                  */
240:                 protected void handleDoubleClick(DoubleClickEvent event) {
241:•                        if (canFlipToNextPage()) {
242:                                 getContainer().showPage(getNextPage());
243:•                        } else if (canFinish() && performFinish()) {
244:                                 ((WizardDialog) getContainer()).close();
245:                         }
246:                 }
247:
248:                 /**
249:                  * Handles the composite's selection changes.
250:                  *
251:                  * @param event The {@link SelectionChangedEvent}
252:                  */
253:                 protected abstract void handleSelectionChanged(SelectionChangedEvent event);
254:
255:                 /**
256:                  * @return The {@link SelectionComposite} that provides the selection viewer
257:                  */
258:                 protected abstract SelectionComposite<? extends ColumnViewer> getSelectionComposite();
259:         }
260:
261:         /**
262:          * Page for selecting the sub {@link EClass}.
263:          *
264:          * @author Lucas Koehler
265:          *
266:          */
267:         class SubClassSelectionPage extends SelectionPage {
268:                 private final Set<EClass> availableEClasses;
269:                 private SelectionComposite<TreeViewer> selectionComposite;
270:
271:                 /**
272:                  * Create a new sub class selection page that allows to select one of the available e classes.
273:                  *
274:                  * @param pageName The page's unique name
275:                  * @param pageTitle The title shown for this wizard page
276:                  * @param pageDescription The description shown for this wizard page
277:                  * @param availableEClasses The set of selectable e classes
278:                  */
279:                 protected SubClassSelectionPage(String pageName, String pageTitle, String pageDescription,
280:                         Set<EClass> availableEClasses) {
281:                         super(pageName, pageTitle, pageDescription);
282:                         setTitle(pageTitle);
283:                         setDescription(pageDescription);
284:                         this.availableEClasses = availableEClasses;
285:                 }
286:
287:                 @Override
288:                 protected SelectionComposite<? extends ColumnViewer> getSelectionComposite() {
289:                         if (selectionComposite == null) {
290:                                 selectionComposite = CompositeFactory.getSelectModelClassComposite(new HashSet<EPackage>(),
291:                                         new HashSet<EPackage>(), availableEClasses);
292:                         }
293:                         return selectionComposite;
294:                 }
295:
296:                 @Override
297:                 public void createControl(Composite parent) {
298:                         super.createControl(parent);
299:                 }
300:
301:                 @Override
302:                 public void handleSelectionChanged(SelectionChangedEvent event) {
303:                         final IStructuredSelection sel = (IStructuredSelection) getSelectionComposite().getViewer()
304:                                 .getSelection();
305:
306:                         if (sel != null && !sel.isEmpty() && EClass.class.isInstance(sel.getFirstElement())) {
307:                                 setErrorMessage(null);
308:                                 setSubClass((EClass) sel.getFirstElement());
309:                                 setPageComplete(true);
310:                         } else {
311:                                 setErrorMessage(localizationService.getString(SelectSubclassAndTemplateWizard.class,
312:                                         MessageKeys.SelectSubclassAndTemplateWizard_selectEClass));
313:                                 setSubClass(null);
314:                                 setPageComplete(false);
315:                         }
316:                 }
317:         }
318:
319:         /**
320:          * Wizard page to select on template.
321:          *
322:          * @author Lucas Koehler
323:          *
324:          */
325:         class TemplateSelectionPage extends SelectionPage {
326:                 private SelectionComposite<TableViewer> selectionComposite;
327:
328:                 /**
329:                  * @param pageName The page's unique name
330:                  * @param pageTitle The title shown for this wizard page
331:                  * @param pageDescription The description shown for this wizard page
332:                  */
333:                 protected TemplateSelectionPage(String pageName, String pageTitle, String pageDescription) {
334:                         super(pageName, pageTitle, pageDescription);
335:                 }
336:
337:                 @Override
338:                 protected SelectionComposite<? extends ColumnViewer> getSelectionComposite() {
339:                         if (selectionComposite == null) {
340:                                 final Set<Template> templates = selectedSubClass != null
341:                                         ? getAvailableTemplates(selectedSubClass)
342:                                         : Collections.<Template> emptySet();
343:                                 selectionComposite = CompositeFactory.getTableSelectionComposite(templates, false);
344:                         }
345:                         return selectionComposite;
346:                 }
347:
348:                 /**
349:                  * Update the selection composite with the given Set of templates.
350:                  *
351:                  * @param availableTemplates The Set of selectable templates
352:                  */
353:                 public void updateSelectionComposite(Set<Template> availableTemplates) {
354:                         getSelectionComposite().getViewer().setInput(availableTemplates);
355:                         setPageComplete(false);
356:                 }
357:
358:                 @Override
359:                 public void handleSelectionChanged(SelectionChangedEvent event) {
360:                         final IStructuredSelection sel = (IStructuredSelection) getSelectionComposite().getViewer()
361:                                 .getSelection();
362:
363:                         if (sel != null && !sel.isEmpty()) {
364:                                 setPageComplete(true);
365:                         } else {
366:                                 setPageComplete(false);
367:                         }
368:                 }
369:         }
370: }