Skip to content

Package: EMFStoreDirtyObserver$1

EMFStoreDirtyObserver$1

nameinstructionbranchcomplexitylinemethod
run()
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
{...}
M: 9 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%

Coverage

1: /*******************************************************************************
2: * Copyright (c) 2011-2012 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: package org.eclipse.emf.ecp.emfstore.internal.ui.decorator;
16:
17: import java.util.HashMap;
18: import java.util.HashSet;
19: import java.util.Map;
20: import java.util.Set;
21:
22: import org.eclipse.emf.ecore.EObject;
23: import org.eclipse.emf.ecp.spi.core.InternalProject;
24: import org.eclipse.emf.emfstore.internal.client.model.ProjectSpace;
25: import org.eclipse.emf.emfstore.internal.client.observers.OperationObserver;
26: import org.eclipse.emf.emfstore.internal.common.model.ModelElementId;
27: import org.eclipse.emf.emfstore.internal.common.model.Project;
28: import org.eclipse.emf.emfstore.internal.server.model.versioning.operations.AbstractOperation;
29: import org.eclipse.emf.emfstore.internal.server.model.versioning.operations.CreateDeleteOperation;
30: import org.eclipse.emf.emfstore.server.ESCloseableIterable;
31: import org.eclipse.swt.widgets.Display;
32: import org.eclipse.ui.IDecoratorManager;
33: import org.eclipse.ui.PlatformUI;
34:
35: /**
36: * Project change observer that marks elements as dirty.
37: *
38: * @author Tobias Verhoeven
39: */
40: public class EMFStoreDirtyObserver implements OperationObserver {
41:
42:         private static final String DIRTYDECORATORID = "org.eclipse.emf.ecp.emfstore.ui.decorators.EMFStoreDirtyDecorator"; //$NON-NLS-1$
43:         private ProjectSpace projectSpace;
44:         private InternalProject internalProject;
45:         private final Map<ModelElementId, Integer> modelElementIdToOperationCount = new HashMap<ModelElementId, Integer>();
46:         private Set<EObject> lastAffected;
47:         private int operations;
48:
49:         /**
50:          * Default constructor.
51:          *
52:          * @param projectSpace the ProjectSpace of the decorator
53:          * @param project the ecpproject of the decorator
54:          */
55:         public EMFStoreDirtyObserver(ProjectSpace projectSpace, InternalProject project) {
56:                 this.projectSpace = projectSpace;
57:                 internalProject = project;
58:
59:                 if (!projectSpace.isShared()) {
60:                         return;
61:                 }
62:                 initCachedTree(projectSpace);
63:         }
64:
65:         private void initCachedTree(ProjectSpace ps) {
66:                 @SuppressWarnings("restriction")
67:                 final ESCloseableIterable<AbstractOperation> operationIterator = ps.getLocalChangePackage().operations();
68:                 for (final AbstractOperation operation : operationIterator.iterable()) {
69:                         operations++;
70:                         for (final ModelElementId modelElementId : operation.getAllInvolvedModelElements()) {
71:                                 final EObject element = ps.getProject().getModelElement(modelElementId);
72:                                 if (element != null) {
73:                                         EMFStoreDirtyDecoratorCachedTree.getInstance(internalProject).addOperation(element);
74:                                 }
75:                         }
76:                         removeDeletedElementsFromCachedTree(ps, operation);
77:                 }
78:                 operationIterator.close();
79:         }
80:
81:         /** {@inheritDoc} */
82:         @Override
83:         public void operationExecuted(ProjectSpace projectSpace, AbstractOperation operation) {
84:                 operations++;
85:                 if (!projectSpace.isShared()) {
86:                         return;
87:                 }
88:
89:                 lastAffected = new HashSet<EObject>();
90:                 for (final ModelElementId modelElementId : operation.getAllInvolvedModelElements()) {
91:                         final Project project = projectSpace.getProject();
92:
93:                         final EObject element = project.getModelElement(modelElementId);
94:
95:                         if (element != null) {
96:                                 lastAffected.add(element);
97:                                 lastAffected
98:                                         .addAll(EMFStoreDirtyDecoratorCachedTree.getInstance(internalProject).addOperation(element));
99:                         }
100:                         removeDeletedElementsFromCachedTree(projectSpace, operation);
101:                 }
102:                 updateDecoration();
103:         }
104:
105:         /** {@inheritDoc} */
106:         @Override
107:         public void operationUndone(ProjectSpace projectSpace, AbstractOperation operation) {
108:                 operations--;
109:                 if (!projectSpace.isShared()) {
110:                         return;
111:                 }
112:                 lastAffected = new HashSet<EObject>();
113:
114:                 for (final ModelElementId modelElementId : operation.getAllInvolvedModelElements()) {
115:                         final Project project = projectSpace.getProject();
116:                         final EObject element = project.get(modelElementId);
117:
118:                         if (element != null) {
119:                                 lastAffected.add(element);
120:                                 lastAffected.addAll(EMFStoreDirtyDecoratorCachedTree.getInstance(internalProject).removeOperation(
121:                                         element));
122:                         }
123:                 }
124:                 initializeRestoredDeletedElement(operation);
125:                 updateDecoration();
126:         }
127:
128:         private void updateDecoration() {
129:                 // TODO remove dependency to workbench
130:                 final IDecoratorManager decoratorManager = PlatformUI.getWorkbench().getDecoratorManager();
131:                 if (decoratorManager != null) {
132:                         Display.getDefault().syncExec(new Runnable() {
133:
134:                                 @Override
135:                                 public void run() {
136:                                         decoratorManager.update(DIRTYDECORATORID);
137:                                 }
138:                         });
139:
140:                 }
141:         }
142:
143:         /**
144:          * @param projectSpace
145:          * @param operation
146:          */
147:         private void removeDeletedElementsFromCachedTree(ProjectSpace projectSpace, AbstractOperation operation) {
148:                 if (operation instanceof CreateDeleteOperation) {
149:                         final CreateDeleteOperation cdo = (CreateDeleteOperation) operation;
150:
151:                         if (cdo.isDelete()) {
152:
153:                                 modelElementIdToOperationCount.put(cdo.getModelElementId(), EMFStoreDirtyDecoratorCachedTree
154:                                         .getInstance(internalProject).getOwnValue(projectSpace.getProject().get(cdo.getModelElementId())));
155:
156:                                 EMFStoreDirtyDecoratorCachedTree.getInstance(internalProject).remove(
157:                                         projectSpace.getProject().get(cdo.getModelElementId()));
158:                                 // TODO: consider containments
159:                         }
160:                 }
161:         }
162:
163:         /**
164:          * @param operation
165:          */
166:         private void initializeRestoredDeletedElement(AbstractOperation operation) {
167:                 if (operation instanceof CreateDeleteOperation) {
168:                         final CreateDeleteOperation cdo = (CreateDeleteOperation) operation;
169:
170:                         if (cdo.isDelete()) {
171:                                 lastAffected.addAll(EMFStoreDirtyDecoratorCachedTree.getInstance(internalProject).setOperationCount(
172:                                         projectSpace.getProject().get(cdo.getModelElementId()),
173:                                         modelElementIdToOperationCount.get(cdo.getModelElementId().toAPI())));
174:
175:                                 modelElementIdToOperationCount.remove(projectSpace.getProject().get(cdo.getModelElementId()));
176:                                 // TODO: consider containments
177:                         }
178:                 }
179:         }
180:
181:         /**
182:          * The Collection of {@link EObject} that were affected during last operation.
183:          *
184:          * @return a {@link Set} of {@link EObject} affected or null if none
185:          */
186:         public Set<EObject> getLastAffected() {
187:                 return lastAffected;
188:         }
189:
190:         /**
191:          * Clears the cache of deleted elements and resets the operation count to 0.
192:          */
193:         public void clearObserverCache() {
194:                 modelElementIdToOperationCount.clear();
195:                 operations = 0;
196:         }
197:
198:         /**
199:          * Returns weather the observed projectSpac is dirty.
200:          *
201:          * @return true, if is dirty.
202:          */
203:         public boolean isDirty() {
204:                 return operations > 0;
205:         }
206: }