Skip to content

Package: WorkspaceProvider$WorkspaceProjectObserver

WorkspaceProvider$WorkspaceProjectObserver

nameinstructionbranchcomplexitylinemethod
WorkspaceProvider.WorkspaceProjectObserver(WorkspaceProvider, InternalProject, WorkspaceProvider)
M: 0 C: 12
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
notifyChanged(Notification)
M: 17 C: 28
62%
M: 5 C: 3
38%
M: 3 C: 2
40%
M: 3 C: 8
73%
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: * Eugen Neufeld - initial API and implementation
13: ******************************************************************************/
14:
15: /*
16: * Copyright (c) 2011 Eike Stepper (Berlin, Germany) and others.
17: * All rights reserved. This program and the accompanying materials
18: * are made available under the terms of the Eclipse Public License 2.0
19: * which accompanies this distribution, and is available at
20: * https://www.eclipse.org/legal/epl-2.0/
21: * SPDX-License-Identifier: EPL-2.0
22: * Contributors:
23: * Eike Stepper - initial API and implementation
24: */
25: package org.eclipse.emf.ecp.workspace.internal.core;
26:
27: import java.io.IOException;
28: import java.util.Collection;
29: import java.util.Collections;
30: import java.util.HashMap;
31: import java.util.List;
32: import java.util.Map;
33:
34: import org.eclipse.emf.common.command.BasicCommandStack;
35: import org.eclipse.emf.common.command.Command;
36: import org.eclipse.emf.common.command.CommandStack;
37: import org.eclipse.emf.common.notify.Notification;
38: import org.eclipse.emf.common.notify.Notifier;
39: import org.eclipse.emf.common.util.EList;
40: import org.eclipse.emf.common.util.URI;
41: import org.eclipse.emf.common.util.WrappedException;
42: import org.eclipse.emf.ecore.EObject;
43: import org.eclipse.emf.ecore.EReference;
44: import org.eclipse.emf.ecore.resource.Resource;
45: import org.eclipse.emf.ecore.resource.ResourceSet;
46: import org.eclipse.emf.ecore.util.EContentAdapter;
47: import org.eclipse.emf.ecore.util.EcoreUtil;
48: import org.eclipse.emf.ecore.xmi.XMLResource;
49: import org.eclipse.emf.ecp.core.ECPProject;
50: import org.eclipse.emf.ecp.core.ECPRepository;
51: import org.eclipse.emf.ecp.core.util.ECPContainer;
52: import org.eclipse.emf.ecp.core.util.ECPModelContextAdapter;
53: import org.eclipse.emf.ecp.spi.core.DefaultProvider;
54: import org.eclipse.emf.ecp.spi.core.InternalProject;
55: import org.eclipse.emf.ecp.spi.core.InternalProvider;
56: import org.eclipse.emf.ecp.spi.core.util.InternalChildrenList;
57: import org.eclipse.emf.edit.command.ChangeCommand;
58: import org.eclipse.emf.edit.command.DeleteCommand;
59: import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
60: import org.eclipse.emf.edit.domain.EditingDomain;
61:
62: /**
63: * @author Eike Stepper
64: * @author Tobias Verhoeven
65: */
66: public class WorkspaceProvider extends DefaultProvider {
67:
68:         /** The Provider Name. */
69:         public static final String NAME = "org.eclipse.emf.ecp.workspace.provider"; //$NON-NLS-1$
70:
71:         /** Root URI Property Name. */
72:         public static final String PROP_ROOT_URI = "rootURI"; //$NON-NLS-1$
73:
74:         /** Constant which is used to indicated the the {@link #PROP_ROOT_URI root uri} is not existing yet. */
75:         public static final String VIRTUAL_ROOT_URI = "VIRTUAL_URI"; //$NON-NLS-1$
76:
77:         /**
78:          * The Workspace Provider Instance.
79:          *
80:          * @deprecated use ECPUtil.getECPProviderRegistry().getProvider(WorkspaceProvider.NAME) instead
81:          *
82:          */
83:         @Deprecated
84:         static WorkspaceProvider INSTANCE;
85:
86:         /**
87:          * Instantiates a new workspace provider.
88:          */
89:         public WorkspaceProvider() {
90:                 super(NAME);
91:                 INSTANCE = this;
92:                 // WORKSPACE.addResourceChangeListener(this);
93:         }
94:
95:         /** {@inheritDoc} */
96:         @Override
97:         public void handleLifecycle(ECPContainer context, LifecycleEvent event) {
98:                 switch (event) {
99:                 case INIT:
100:                         handleInit(context);
101:                         break;
102:                 case DISPOSE:
103:                         handelDispose(context);
104:                         break;
105:                 case CREATE:
106:                         handleCreate(context);
107:                         break;
108:                 case REMOVE:
109:                         handleRemove(context);
110:                         break;
111:                 default:
112:                         break;
113:                 }
114:         }
115:
116:         private void handleInit(ECPContainer context) {
117:                 if (context instanceof InternalProject) {
118:                         final InternalProject project = (InternalProject) context;
119:                         final EditingDomain editingDomain = project.getEditingDomain();
120:                         editingDomain.getResourceSet().eAdapters().add(new WorkspaceProjectObserver(project, this));
121:                 }
122:
123:         }
124:
125:         private void handleRemove(ECPContainer context) {
126:                 // TODO Auto-generated method stub
127:
128:         }
129:
130:         private void handleCreate(ECPContainer context) {
131:                 // TODO Auto-generated method stub
132:
133:         }
134:
135:         private void handelDispose(ECPContainer context) {
136:                 // TODO Auto-generated method stub
137:
138:         }
139:
140:         @Override
141:         protected void doDispose() {
142:                 try {
143:                         // WORKSPACE.removeResourceChangeListener(this);
144:                         super.doDispose();
145:                 } finally {
146:                         INSTANCE = null;
147:                 }
148:         }
149:
150:         @Override
151:         public boolean hasCreateRepositorySupport() {
152:                 return false;
153:         }
154:
155:         @Override
156:         public void fillChildren(ECPContainer context, Object parent, InternalChildrenList childrenList) {
157:                 if (parent instanceof ECPRepository) {
158:                 } else if (parent instanceof ECPProject) {
159:                         final ECPProject project = (ECPProject) parent;
160:                         final String rootURI = project.getProperties().getValue(PROP_ROOT_URI);
161:
162:                         final ResourceSet resourceSet = project.getEditingDomain().getResourceSet();
163:
164:                         final URI uri = URI.createURI(rootURI);
165:                         if (uri.hasFragment()) {
166:                                 final EObject eObject = resourceSet.getEObject(uri, true);
167:                                 super.fillChildren(context, eObject, childrenList);
168:                         } else {
169:                                 final Resource resource = resourceSet.getResource(uri, true);
170:                                 childrenList.addChildren(resource.getContents());
171:                         }
172:
173:                 } else {
174:                         super.fillChildren(context, parent, childrenList);
175:                 }
176:         }
177:
178:         /** {@inheritDoc} */
179:         @Override
180:         public EList<? extends Object> getElements(InternalProject project) {
181:                 boolean demandLoad = true;
182:                 if (project.getProperties().getValue(PROP_ROOT_URI).equals(VIRTUAL_ROOT_URI)) {
183:                         demandLoad = false;
184:                 }
185:                 final ResourceSet resourceSet = project.getEditingDomain().getResourceSet();
186:                 return resourceSet.getResource(
187:                         URI.createURI(project.getProperties().getValue(PROP_ROOT_URI)), demandLoad).getContents();
188:                 // TODO: implement WorkspaceProvider.addRootElement(project, rootElement)
189:         }
190:
191:         @Override
192:         public boolean contains(InternalProject project, Object object) {
193:                 // TODO: optimize
194:                 if (object instanceof EObject) {
195:                         final EObject eObject = (EObject) object;
196:                         final EObject root = EcoreUtil.getRootContainer(eObject);
197:                         if (root == null || root.eResource() == null) {
198:                                 return false;
199:                         }
200:
201:                         return root.eResource().equals(getRoot(project));
202:                 }
203:                 return false;
204:         }
205:
206:         /**
207:          * Reloads the project.
208:          *
209:          * @param project the project to be reloaded.
210:          */
211:         public void reload(InternalProject project) {
212:                 final List<Resource> resources = project.getEditingDomain().getResourceSet().getResources();
213:                 for (final Resource resource : resources) {
214:                         if (resource.equals(getRoot(project)) && resource.isLoaded()) {
215:                                 resource.unload();
216:
217:                                 try {
218:                                         resource.load(Collections.EMPTY_MAP);
219:                                 } catch (final IOException ex) {
220:                                         // TODO Auto-generated catch block
221:                                         ex.printStackTrace();
222:                                 }
223:                         }
224:                 }
225:         }
226:
227:         /** {@inheritDoc} */
228:         @Override
229:         public void cloneProject(final InternalProject projectToClone, InternalProject targetProject) {
230:                 throw new UnsupportedOperationException();
231:         }
232:
233:         /** {@inheritDoc} */
234:         // FIXME
235:         @Override
236:         public Notifier getRoot(InternalProject project) {
237:                 boolean demandLoad = true;
238:                 if (project.getProperties().getValue(PROP_ROOT_URI).equals(VIRTUAL_ROOT_URI)) {
239:                         demandLoad = false;
240:                 }
241:                 return project.getEditingDomain().getResourceSet()
242:                         .getResource(URI.createURI(project.getProperties().getValue(PROP_ROOT_URI)), demandLoad);
243:         }
244:
245:         @Override
246:         public void doSave(InternalProject project) {
247:                 try {
248:                         final Map<Object, Object> saveOptions = new HashMap<Object, Object>();
249:                         saveOptions.put(Resource.OPTION_SAVE_ONLY_IF_CHANGED, Resource.OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER);
250:                         saveOptions.put(XMLResource.OPTION_ENCODING, "UTF-8"); //$NON-NLS-1$
251:                         final List<Resource> resources = project.getEditingDomain().getResourceSet().getResources();
252:                         for (final Resource resource : resources) {
253:                                 resource.save(saveOptions);
254:                         }
255:                         ((BasicCommandStack) project.getEditingDomain().getCommandStack()).saveIsDone();
256:                 } catch (final IOException ex) {
257:                         // TODO Auto-generated catch block
258:                         ex.printStackTrace();
259:                 }
260:                 super.doSave(project);
261:         }
262:
263:         @Override
264:         public boolean isDirty(InternalProject project) {
265:                 return ((BasicCommandStack) project.getEditingDomain().getCommandStack()).isSaveNeeded();
266:         }
267:
268:         @Override
269:         public EditingDomain createEditingDomain(final InternalProject project) {
270:
271:                 final CommandStack commandStack = new BasicCommandStack();
272:                 final EditingDomain editingDomain = new AdapterFactoryEditingDomain(InternalProvider.EMF_ADAPTER_FACTORY,
273:                         commandStack);
274:
275:                 editingDomain.getResourceSet().eAdapters().add(new ECPModelContextAdapter(project));
276:                 final URI uri = URI.createURI(project.getProperties().getValue(PROP_ROOT_URI));
277:                 if (project.getProperties().getValue(PROP_ROOT_URI).equals(VIRTUAL_ROOT_URI)) {
278:                         editingDomain.getResourceSet().createResource(uri);
279:                 } else {
280:                         try {
281:                                 editingDomain.getResourceSet().getResource(uri, true);
282:                         } catch (final WrappedException we) {
283:                                 project.close();
284:                         }
285:                 }
286:
287:                 return editingDomain;
288:         }
289:
290:         @Override
291:         public ECPContainer getModelContext(Object element) {
292:                 return super.getModelContext(element);
293:         }
294:
295:         @Override
296:         public boolean hasCreateProjectWithoutRepositorySupport() {
297:                 return true;
298:         }
299:
300:         /**
301:          * Observes changes in a projects resource and notifies the project.
302:          */
303:         private class WorkspaceProjectObserver extends EContentAdapter {
304:
305:                 private final InternalProject project;
306:                 private final WorkspaceProvider provider;
307:
308:                 WorkspaceProjectObserver(InternalProject project, WorkspaceProvider provider) {
309:                         this.project = project;
310:                         this.provider = provider;
311:                 }
312:
313:                 @Override
314:                 public void notifyChanged(Notification notification) {
315:                         super.notifyChanged(notification);
316:
317:•                        if (notification.getNotifier() instanceof EObject) {
318:                                 provider.notifyProviderChangeListeners(notification);
319:                                 final EObject eObject = (EObject) notification.getNotifier();
320:                                 project.notifyObjectsChanged((Collection) Collections.singleton(eObject), false);
321:
322:                                 final Object feature = notification.getFeature();
323:•                                if (feature instanceof EReference) {
324:                                         final EReference eReference = (EReference) feature;
325:
326:•                                        if (eReference.isContainment() && notification.getNewValue() instanceof EObject) {
327:                                                 project.notifyObjectsChanged(Collections.singleton(notification.getNewValue()), true);
328:                                         }
329:
330:                                 }
331:
332:                         }
333:                 }
334:         }
335:
336:         /**
337:          * {@inheritDoc}
338:          *
339:          * @see org.eclipse.emf.ecp.spi.core.InternalProvider#isThreadSafe()
340:          */
341:         @Override
342:         public boolean isThreadSafe() {
343:                 return false;
344:         }
345:
346:         /**
347:          * {@inheritDoc}
348:          *
349:          * @see org.eclipse.emf.ecp.spi.core.DefaultProvider#doDelete(org.eclipse.emf.ecp.spi.core.InternalProject,
350:          * java.util.Collection)
351:          */
352:         @Override
353:         public void doDelete(InternalProject project, final Collection<Object> objects) {
354:                 final Command deleteCommand = DeleteCommand.create(project.getEditingDomain(), objects);
355:                 if (deleteCommand.canExecute()) {
356:                         project.getEditingDomain().getCommandStack().execute(deleteCommand);
357:                         return;
358:                 }
359:
360:                 /*
361:                  * the default DeleteCommand cannot be executed for whatever reason.
362:                  * Wrap an EcoreUtil.delete in a change command for undo support.
363:                  */
364:                 final Command changeCommand = new ChangeCommand(project.getEditingDomain().getResourceSet()) {
365:                         @Override
366:                         protected void doExecute() {
367:                                 for (final Object object : objects) {
368:                                         final Object unwrap = AdapterFactoryEditingDomain.unwrap(object);
369:                                         if (!EObject.class.isInstance(unwrap)) {
370:                                                 continue;
371:                                         }
372:                                         EcoreUtil.delete(EObject.class.cast(unwrap), true);
373:                                 }
374:                         }
375:                 };
376:                 if (changeCommand.canExecute()) {
377:                         project.getEditingDomain().getCommandStack().execute(changeCommand);
378:                         return;
379:                 }
380:
381:                 // unexpected
382:                 throw new IllegalStateException("Delete was not successful."); //$NON-NLS-1$
383:
384:         }
385: }