Skip to content

Package: Preview$2

Preview$2

nameinstructionbranchcomplexitylinemethod
localize(String)
M: 2 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
{...}
M: 0 C: 6
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%

Coverage

1: /*******************************************************************************
2: * Copyright (c) 2011-2014 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: * Alexandra Buzila- initial API and implementation
13: ******************************************************************************/
14: package org.eclipse.emf.ecp.view.model.preview.common;
15:
16: import org.eclipse.core.runtime.IStatus;
17: import org.eclipse.core.runtime.Status;
18: import org.eclipse.emf.common.command.BasicCommandStack;
19: import org.eclipse.emf.common.notify.Adapter;
20: import org.eclipse.emf.common.notify.AdapterFactory;
21: import org.eclipse.emf.common.notify.Notification;
22: import org.eclipse.emf.common.util.TreeIterator;
23: import org.eclipse.emf.common.util.URI;
24: import org.eclipse.emf.ecore.EClass;
25: import org.eclipse.emf.ecore.EObject;
26: import org.eclipse.emf.ecore.EPackage;
27: import org.eclipse.emf.ecore.EStructuralFeature;
28: import org.eclipse.emf.ecore.EcoreFactory;
29: import org.eclipse.emf.ecore.impl.DynamicEObjectImpl;
30: import org.eclipse.emf.ecore.resource.Resource;
31: import org.eclipse.emf.ecore.resource.ResourceSet;
32: import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
33: import org.eclipse.emf.ecore.util.EContentAdapter;
34: import org.eclipse.emf.ecore.util.EcoreUtil;
35: import org.eclipse.emf.ecp.edit.spi.EMFDeleteServiceImpl;
36: import org.eclipse.emf.ecp.ui.view.ECPRendererException;
37: import org.eclipse.emf.ecp.ui.view.swt.ECPSWTView;
38: import org.eclipse.emf.ecp.ui.view.swt.ECPSWTViewRenderer;
39: import org.eclipse.emf.ecp.view.model.common.edit.provider.CustomReflectiveItemProviderAdapterFactory;
40: import org.eclipse.emf.ecp.view.spi.context.ViewModelContext;
41: import org.eclipse.emf.ecp.view.spi.context.ViewModelContextFactory;
42: import org.eclipse.emf.ecp.view.spi.model.LocalizationAdapter;
43: import org.eclipse.emf.ecp.view.spi.model.VControl;
44: import org.eclipse.emf.ecp.view.spi.model.VView;
45: import org.eclipse.emf.ecp.view.spi.model.VViewPackage;
46: import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
47: import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
48: import org.eclipse.jface.layout.GridDataFactory;
49: import org.eclipse.jface.layout.GridLayoutFactory;
50: import org.eclipse.swt.SWT;
51: import org.eclipse.swt.widgets.Composite;
52: import org.eclipse.swt.widgets.Control;
53: import org.eclipse.ui.internal.ErrorViewPart;
54:
55: /** This class renders the contents of a {@link VView} in a {@link Composite}. */
56: public class Preview {
57:
58:         private ECPSWTView render;
59:         private Adapter adapter;
60:         private VView view;
61:         private boolean updateAutomatic;
62:
63:         private final Composite parent;
64:         private Composite composite;
65:         private EObject dummyData;
66:
67:         /**
68:          * The constructor.
69:          *
70:          * @param parent - the {@link Composite} in which to render
71:          */
72:         public Preview(Composite parent) {
73:                 this.parent = parent;
74:         }
75:
76:         /**
77:          * Render the contents of the {@link VView}.
78:          *
79:          * @param view the {@link VView}
80:          * @param sampleData the sample data to be displayed in the view
81:          */
82:         public void render(final VView view, EObject sampleData) {
83:                 if (adapter != null) {
84:                         removeAdapter();
85:                 }
86:                 this.view = view;
87:                 if (sampleData != null) {
88:                         dummyData = sampleData;
89:                 }
90:                 internalRender(view);
91:         }
92:
93:         /** Adds adapter to listen to changes in the currently cached view model. */
94:         public void registerForViewModelChanges() {
95:                 if (view == null) {
96:                         return;
97:                 }
98:                 if (adapter != null) {
99:                         removeAdapter();
100:                 }
101:                 adapter = new EContentAdapter() {
102:
103:                         /**
104:                          * {@inheritDoc}
105:                          *
106:                          * @see org.eclipse.emf.ecore.util.EContentAdapter#notifyChanged(org.eclipse.emf.common.notify.Notification)
107:                          */
108:                         @Override
109:                         public void notifyChanged(Notification notification) {
110:                                 super.notifyChanged(notification);
111:                                 if (!updateAutomatic) {
112:                                         return;
113:                                 }
114:                                 if (notification.isTouch()) {
115:                                         return;
116:                                 }
117:
118:                                 if (EStructuralFeature.class.cast(notification.getFeature()).isTransient()) {
119:                                         return;
120:                                 }
121:
122:                                 if (VViewPackage.eINSTANCE.getDomainModelReference_ChangeListener() == notification.getFeature()) {
123:                                         return;
124:                                 }
125:
126:                                 internalRender(view);
127:                         }
128:                 };
129:                 view.eAdapters().add(adapter);
130:         }
131:
132:         private void internalRender(VView view) {
133:                 try {
134:                         if (view == null) {
135:                                 return;
136:                         }
137:                         clear();
138:                         final EClass myPreviewEClass = view.getRootEClass();
139:                         if (dummyData == null || dummyData.eClass() != myPreviewEClass) {
140:                                 if (myPreviewEClass == null || myPreviewEClass.eIsProxy()) {
141:                                         return;
142:                                 }
143:                                 if (myPreviewEClass.isAbstract() || myPreviewEClass.isInterface()) {
144:                                         final EPackage result = EcoreFactory.eINSTANCE.createEPackage();
145:                                         result.setName("dummy"); //$NON-NLS-1$
146:                                         result.setNsURI("dummy"); //$NON-NLS-1$
147:                                         result.setNsPrefix("dummy"); //$NON-NLS-1$
148:
149:                                         final EClass wrapper = EcoreFactory.eINSTANCE.createEClass();
150:                                         wrapper.getESuperTypes().add(myPreviewEClass);
151:                                         wrapper.setName(myPreviewEClass.getName());
152:                                         result.getEClassifiers().add(wrapper);
153:                                         dummyData = new DynamicEObjectImpl(wrapper);
154:                                 } else if (myPreviewEClass.getInstanceClass() == null) {
155:                                         dummyData = new DynamicEObjectImpl(myPreviewEClass);
156:                                 } else {
157:                                         dummyData = EcoreUtil.create(myPreviewEClass);
158:                                 }
159:                                 final ResourceSet resourceSet = new ResourceSetImpl();
160:                                 final AdapterFactoryEditingDomain domain = new AdapterFactoryEditingDomain(
161:                                         new ComposedAdapterFactory(new AdapterFactory[] {
162:                                                 new CustomReflectiveItemProviderAdapterFactory(),
163:                                                 new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE) }),
164:                                         new BasicCommandStack(), resourceSet);
165:                                 resourceSet.eAdapters().add(
166:                                         new AdapterFactoryEditingDomain.EditingDomainProvider(domain));
167:                                 final Resource resource = resourceSet.createResource(URI.createURI("VIRTUAL_URI")); //$NON-NLS-1$
168:                                 resource.getContents().add(dummyData);
169:                         }
170:
171:                         final VView copy = EcoreUtil.copy(view);
172:                         copy.eAdapters().add(new LocalizationAdapter() {
173:                                 @Override
174:                                 public String localize(String key) {
175:                                         return key;
176:                                 }
177:                         });
178:                         clearViewDiagnostics(copy);
179:                         final ViewModelContext viewModelContext = ViewModelContextFactory.INSTANCE.createViewModelContext(
180:                                 copy, dummyData, new EMFDeleteServiceImpl());
181:                         composite = createComposite(parent);
182:                         render = ECPSWTViewRenderer.INSTANCE.render(composite, viewModelContext);
183:                         composite.layout();
184:                         parent.layout();
185:                         // BEGIN SUPRESS CATCH EXCEPTION
186:                 } catch (final RuntimeException e) {
187:                         // END SUPRESS CATCH EXCEPTION
188:                         displayError(e);
189:                 } catch (final ECPRendererException ex) {
190:                         displayError(ex);
191:                 }
192:
193:         }
194:
195:         // FIXME move to e3 PreviewView
196:         @SuppressWarnings("restriction")
197:         private void displayError(Exception e) {
198:                 clear();
199:                 Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e));
200:                 final IStatus status = new Status(IStatus.ERROR, Activator.PLUGIN_ID,
201:                         "Rendering failed. Please re-check your model.", e); //$NON-NLS-1$
202:                 final ErrorViewPart part = new ErrorViewPart(status);
203:                 part.createPartControl(parent);
204:         }
205:
206:         /**
207:          *
208:          */
209:         public void removeAdapter() {
210:                 if (view == null || adapter == null) {
211:                         return;
212:                 }
213:                 for (final Adapter a : view.eAdapters()) {
214:                         if (a == adapter) {
215:                                 view.eAdapters().remove(adapter);
216:                                 adapter = null;
217:                                 return;
218:                         }
219:                 }
220:         }
221:
222:         /**
223:          * Removes the previous rendering result from the parent Composite.
224:          */
225:         public void clear() {
226:                 if (render != null) {
227:                         render.dispose();
228:                 }
229:                 if (composite != null) {
230:                         composite.dispose();
231:                         composite = null;
232:                 }
233:                 if (parent.isDisposed()) {
234:                         return;
235:                 }
236:                 for (final Control c : parent.getChildren()) {
237:                         c.dispose();
238:                 }
239:                 // clean previous view diagnostics
240:                 clearViewDiagnostics(view);
241:         }
242:
243:         private void clearViewDiagnostics(VView view) {
244:                 if (view == null) {
245:                         return;
246:                 }
247:                 final TreeIterator<EObject> eAllContents = view.eAllContents();
248:                 while (eAllContents.hasNext()) {
249:                         final EObject next = eAllContents.next();
250:                         if (VControl.class.isInstance(next)) {
251:                                 VControl.class.cast(next).setDiagnostic(null);
252:                                 next.eClass();
253:                         }
254:                 }
255:         }
256:
257:         /** Removes the cached view. */
258:         public void removeView() {
259:                 view = null;
260:                 removeAdapter();
261:         }
262:
263:         /**
264:          * Creates the composite.
265:          *
266:          * @param parent the parent
267:          * @return the composite
268:          */
269:         private Composite createComposite(Composite parent) {
270:                 final Composite composite = new Composite(parent, SWT.NONE);
271:                 parent.setBackgroundMode(SWT.INHERIT_FORCE);
272:                 composite.setBackground(parent.getBackground());
273:                 GridLayoutFactory.fillDefaults().numColumns(1).equalWidth(false).applyTo(composite);
274:                 GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).applyTo(composite);
275:                 return composite;
276:         }
277:
278:         /**
279:          * @return the canAutomaticallyRender
280:          */
281:         public boolean isUpdateAutomatic() {
282:                 return updateAutomatic;
283:         }
284:
285:         /**
286:          * @param canAutomaticallyRender the canAutomaticallyRender to set
287:          */
288:         public void setUpdateAutomatic(boolean canAutomaticallyRender) {
289:                 updateAutomatic = canAutomaticallyRender;
290:                 if (updateAutomatic && view != null) {
291:                         internalRender(view);
292:                         parent.layout();
293:                 }
294:         }
295:
296:         /**
297:          * Clears the data that is rendered in the preview.
298:          */
299:         public void cleanSampleData() {
300:                 dummyData = null;
301:         }
302:
303:         /**
304:          * @return the domain model {@link EObject} containing the data that is being rendered in the preview.
305:          */
306:         public EObject getSampleData() {
307:                 return dummyData;
308:         }
309: }