Skip to content

Package: ChangeBrokerImpl

ChangeBrokerImpl

nameinstructionbranchcomplexitylinemethod
ChangeBrokerImpl()
M: 0 C: 121
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 19
100%
M: 0 C: 1
100%
addNotificationProvider(NotificationProvider)
M: 0 C: 9
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
canDelete(EObject)
M: 0 C: 23
100%
M: 1 C: 3
75%
M: 1 C: 2
67%
M: 0 C: 6
100%
M: 0 C: 1
100%
continueNotification()
M: 0 C: 4
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
continueNotification(Object)
M: 0 C: 8
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
endNotify(Notification)
M: 0 C: 6
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
getNotificationProviders()
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%
getRegisteredObservers()
M: 0 C: 50
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 6
100%
M: 0 C: 1
100%
notify(Notification)
M: 0 C: 74
100%
M: 0 C: 8
100%
M: 0 C: 5
100%
M: 0 C: 11
100%
M: 0 C: 1
100%
notifyPostDelete(EObject)
M: 0 C: 16
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
notifyPreDelete(EObject)
M: 0 C: 16
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
removeNotificationProvider(NotificationProvider)
M: 0 C: 9
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
startNotify(Notification)
M: 0 C: 22
100%
M: 0 C: 6
100%
M: 0 C: 4
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
stopNotification()
M: 0 C: 4
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
stopNotification(Object)
M: 0 C: 6
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
subscribe(EMFObserver)
M: 0 C: 50
100%
M: 0 C: 10
100%
M: 0 C: 6
100%
M: 0 C: 11
100%
M: 0 C: 1
100%
subscribeToEClass(ChangeObserver, EClass)
M: 0 C: 16
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
subscribeToFeature(ChangeObserver, EStructuralFeature)
M: 0 C: 16
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
subscribeToTree(ChangeObserver, EClass)
M: 0 C: 16
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
unsubsribe(EMFObserver)
M: 0 C: 53
100%
M: 0 C: 10
100%
M: 0 C: 6
100%
M: 0 C: 10
100%
M: 0 C: 1
100%

Coverage

1: /*******************************************************************************
2: * Copyright (c) 2011-2015 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: * Jonas - initial API and implementation
13: * Johannes Faltermeier - - initial API and implementation
14: ******************************************************************************/
15: package org.eclipse.emf.ecp.changebroker.internal;
16:
17: import java.util.LinkedHashSet;
18: import java.util.Set;
19: import java.util.concurrent.CopyOnWriteArraySet;
20:
21: import org.eclipse.emf.common.notify.Notification;
22: import org.eclipse.emf.ecore.EClass;
23: import org.eclipse.emf.ecore.EObject;
24: import org.eclipse.emf.ecore.EStructuralFeature;
25: import org.eclipse.emf.ecp.changebroker.spi.ChangeBroker;
26: import org.eclipse.emf.ecp.changebroker.spi.ChangeObserver;
27: import org.eclipse.emf.ecp.changebroker.spi.EMFObserver;
28: import org.eclipse.emf.ecp.changebroker.spi.NotificationProvider;
29: import org.eclipse.emf.ecp.changebroker.spi.NotificationReceiver;
30: import org.eclipse.emf.ecp.changebroker.spi.PostDeleteObserver;
31: import org.eclipse.emf.ecp.changebroker.spi.PreDeleteObserver;
32: import org.eclipse.emf.ecp.changebroker.spi.ReadOnlyChangeObserver;
33: import org.eclipse.emf.ecp.changebroker.spi.VetoableDeleteObserver;
34:
35: /**
36: *
37: * Implementation of a {@link ChangeBroker}.
38: * Registers itself as a {@link NotificationReceiver} at all {@link NotificationProvider providers}. Once it
39: * gets notified it forwards the notification to all of the brokers notification receivers, as applicable.
40: *
41: * @author Jonas
42: * @author jfaltermeier
43: *
44: */
45: public class ChangeBrokerImpl implements ChangeBroker, NotificationReceiver {
46:
47:         private final Set<NotificationProvider> providers = new CopyOnWriteArraySet<NotificationProvider>();
48:         private boolean stopNotifyingEMFObservers;
49:         private final Set<Object> blocker = new CopyOnWriteArraySet<Object>();
50:
51:         private final Set<Notification> runningNotifications = new LinkedHashSet<Notification>();
52:
53:         private final NoStrategy noStrategy = new NoStrategy();
54:         private final EClassStrategy eClassStrategy = new EClassStrategy();
55:         private final ContainingEClassStrategy containingEClassStrategy = new ContainingEClassStrategy();
56:         private final FeatureStrategy featureStrategy = new FeatureStrategy();
57:         private final Strategy[] strategies;
58:
59:         private final NoStrategy readOnlyNoStrategy = new NoStrategy();
60:         private final EClassStrategy readOnlyEClassStrategy = new EClassStrategy();
61:         private final ContainingEClassStrategy readOnlyContainingEClassStrategy = new ContainingEClassStrategy();
62:         private final FeatureStrategy readOnlyFeatureStrategy = new FeatureStrategy();
63:         private final Strategy[] readOnlyStrategies;
64:
65:         private final Set<PreDeleteObserver> preDeleteObserver = new CopyOnWriteArraySet<PreDeleteObserver>();
66:         private final Set<PostDeleteObserver> postDeleteObserver = new CopyOnWriteArraySet<PostDeleteObserver>();
67:         private final Set<VetoableDeleteObserver> vetoableDeleteObserver = new CopyOnWriteArraySet<VetoableDeleteObserver>();
68:
69:         /**
70:          * Default constructor.
71:          */
72:         public ChangeBrokerImpl() {
73:                 strategies = new Strategy[] { noStrategy, eClassStrategy, containingEClassStrategy, featureStrategy };
74:                 readOnlyStrategies = new Strategy[] { readOnlyNoStrategy, readOnlyEClassStrategy,
75:                         readOnlyContainingEClassStrategy, readOnlyFeatureStrategy };
76:         }
77:
78:         /**
79:          * Adds a notification provider.
80:          *
81:          * @param provider the provider
82:          */
83:         public void addNotificationProvider(NotificationProvider provider) {
84:•                if (providers.add(provider)) {
85:                         provider.addReceiver(this);
86:                 }
87:         }
88:
89:         /**
90:          * Removes a notification provider.
91:          *
92:          * @param provider the provider
93:          */
94:         public void removeNotificationProvider(NotificationProvider provider) {
95:•                if (providers.remove(provider)) {
96:                         provider.removeReceiver(this);
97:                 }
98:         }
99:
100:         /**
101:          * {@inheritDoc}
102:          *
103:          * @see org.eclipse.emf.ecp.changebroker.spi.ChangeObserver#handleNotification(org.eclipse.emf.common.notify.Notification)
104:          */
105:         @Override
106:         public void notify(Notification notification) {
107:                 final boolean includeEMFObservers = startNotify(notification);
108:
109:                 final Set<ChangeObserver> observers = new LinkedHashSet<ChangeObserver>();
110:•                for (final Strategy strategy : readOnlyStrategies) {
111:                         observers.addAll(strategy.getObservers(notification));
112:                 }
113:•                if (includeEMFObservers) {
114:•                        for (final Strategy strategy : strategies) {
115:                                 observers.addAll(strategy.getObservers(notification));
116:                         }
117:                 }
118:•                for (final ChangeObserver observer : observers) {
119:                         observer.handleNotification(notification);
120:                 }
121:
122:                 endNotify(notification);
123:         }
124:
125:         private synchronized boolean startNotify(Notification notification) {
126:•                final boolean includeEMFObservers = !stopNotifyingEMFObservers && runningNotifications.isEmpty()
127:•                        && blocker.isEmpty();
128:                 runningNotifications.add(notification);
129:                 return includeEMFObservers;
130:         }
131:
132:         private synchronized void endNotify(Notification notification) {
133:                 runningNotifications.remove(notification);
134:         }
135:
136:         /**
137:          * {@inheritDoc}
138:          *
139:          * @see org.eclipse.emf.ecp.changebroker.spi.ChangeBroker#subscribe(org.eclipse.emf.ecp.changebroker.spi.EMFObserver)
140:          */
141:         @Override
142:         public void subscribe(EMFObserver observer) {
143:•                if (ReadOnlyChangeObserver.class.isInstance(observer)) {
144:                         readOnlyNoStrategy.register((ChangeObserver) observer);
145:•                } else if (ChangeObserver.class.isInstance(observer)) {
146:                         noStrategy.register((ChangeObserver) observer);
147:                 }
148:•                if (PreDeleteObserver.class.isInstance(observer)) {
149:                         preDeleteObserver.add((PreDeleteObserver) observer);
150:                 }
151:•                if (PostDeleteObserver.class.isInstance(observer)) {
152:                         postDeleteObserver.add((PostDeleteObserver) observer);
153:                 }
154:•                if (VetoableDeleteObserver.class.isInstance(observer)) {
155:                         vetoableDeleteObserver.add((VetoableDeleteObserver) observer);
156:                 }
157:
158:         }
159:
160:         /**
161:          * {@inheritDoc}
162:          *
163:          * @see org.eclipse.emf.ecp.changebroker.spi.ChangeBroker#subscribeToEClass(org.eclipse.emf.ecp.changebroker.spi.ChangeObserver,
164:          * org.eclipse.emf.ecore.EClass)
165:          */
166:         @Override
167:         public void subscribeToEClass(ChangeObserver observer, EClass eClass) {
168:•                if (ReadOnlyChangeObserver.class.isInstance(observer)) {
169:                         readOnlyEClassStrategy.register(observer, eClass);
170:                 } else {
171:                         eClassStrategy.register(observer, eClass);
172:                 }
173:         }
174:
175:         /**
176:          * {@inheritDoc}
177:          *
178:          * @see org.eclipse.emf.ecp.changebroker.spi.ChangeBroker#subscribeToTree(org.eclipse.emf.ecp.changebroker.spi.ChangeObserver,
179:          * org.eclipse.emf.ecore.EClass)
180:          */
181:         @Override
182:         public void subscribeToTree(ChangeObserver observer, EClass eClass) {
183:•                if (ReadOnlyChangeObserver.class.isInstance(observer)) {
184:                         readOnlyContainingEClassStrategy.register(observer, eClass);
185:                 } else {
186:                         containingEClassStrategy.register(observer, eClass);
187:                 }
188:         }
189:
190:         /**
191:          * {@inheritDoc}
192:          *
193:          * @see org.eclipse.emf.ecp.changebroker.spi.ChangeBroker#subscribeToFeature(org.eclipse.emf.ecp.changebroker.spi.ChangeObserver,
194:          * org.eclipse.emf.ecore.EStructuralFeature)
195:          */
196:         @Override
197:         public void subscribeToFeature(ChangeObserver observer, EStructuralFeature feature) {
198:•                if (ReadOnlyChangeObserver.class.isInstance(observer)) {
199:                         readOnlyFeatureStrategy.register(observer, feature);
200:                 } else {
201:                         featureStrategy.register(observer, feature);
202:                 }
203:         }
204:
205:         /**
206:          *
207:          * {@inheritDoc}
208:          *
209:          * @see org.eclipse.emf.ecp.changebroker.spi.ChangeBroker#unsubsribe(org.eclipse.emf.ecp.changebroker.spi.EMFObserver)
210:          */
211:         @Override
212:         public void unsubsribe(EMFObserver receiver) {
213:•                if (ChangeObserver.class.isInstance(receiver)) {
214:•                        for (final Strategy strategy : strategies) {
215:                                 strategy.deregister((ChangeObserver) receiver);
216:                         }
217:                 }
218:•                if (PreDeleteObserver.class.isInstance(receiver)) {
219:                         preDeleteObserver.remove(receiver);
220:                 }
221:•                if (PostDeleteObserver.class.isInstance(receiver)) {
222:                         postDeleteObserver.remove(receiver);
223:                 }
224:•                if (VetoableDeleteObserver.class.isInstance(receiver)) {
225:                         vetoableDeleteObserver.remove(receiver);
226:                 }
227:
228:         }
229:
230:         /**
231:          * {@inheritDoc}
232:          *
233:          * @see org.eclipse.emf.ecp.changebroker.spi.ChangeBroker#stopNotification()
234:          */
235:         @Override
236:         public void stopNotification() {
237:                 stopNotifyingEMFObservers = true;
238:         }
239:
240:         /**
241:          * {@inheritDoc}
242:          *
243:          * @see org.eclipse.emf.ecp.changebroker.spi.ChangeBroker#continueNotification()
244:          */
245:         @Override
246:         public void continueNotification() {
247:                 stopNotifyingEMFObservers = false;
248:         }
249:
250:         /**
251:          * For testing purposes.
252:          *
253:          * @return all registered providers
254:          */
255:         public Set<NotificationProvider> getNotificationProviders() {
256:                 return new LinkedHashSet<NotificationProvider>(providers);
257:         }
258:
259:         /**
260:          * For testing purposes.
261:          *
262:          * @return all registered observers
263:          */
264:         public Set<ChangeObserver> getRegisteredObservers() {
265:                 final LinkedHashSet<ChangeObserver> hashSet = new LinkedHashSet<ChangeObserver>();
266:•                for (final Strategy strategy : strategies) {
267:                         hashSet.addAll(strategy.getAllObservers());
268:                 }
269:•                for (final Strategy strategy : readOnlyStrategies) {
270:                         hashSet.addAll(strategy.getAllObservers());
271:                 }
272:                 return hashSet;
273:         }
274:
275:         /**
276:          *
277:          * {@inheritDoc}
278:          *
279:          * @see org.eclipse.emf.ecp.changebroker.spi.ChangeBroker#stopNotification(java.lang.Object)
280:          */
281:         @Override
282:         public void stopNotification(Object blocker) {
283:                 this.blocker.add(blocker);
284:         }
285:
286:         /**
287:          *
288:          * {@inheritDoc}
289:          *
290:          * @see org.eclipse.emf.ecp.changebroker.spi.ChangeBroker#continueNotification(java.lang.Object)
291:          */
292:         @Override
293:         public void continueNotification(Object blocker) {
294:                 this.blocker.remove(blocker);
295:                 continueNotification();
296:         }
297:
298:         /**
299:          * @param toBeDeleted The {@link EObject} to be deleted
300:          */
301:         @Override
302:         public void notifyPreDelete(EObject toBeDeleted) {
303:•                for (final PreDeleteObserver observer : preDeleteObserver) {
304:                         observer.preDelete(toBeDeleted);
305:                 }
306:
307:         }
308:
309:         /**
310:          * @param toBeDeleted The deleted {@link EObject}
311:          */
312:         @Override
313:         public void notifyPostDelete(EObject toBeDeleted) {
314:•                for (final PostDeleteObserver observer : postDeleteObserver) {
315:                         observer.postDelete(toBeDeleted);
316:                 }
317:
318:         }
319:
320:         /**
321:          * @param toBeDeleted The {@link EObject} to be deleted
322:          * @return if the element can be deleted meaning if no {@link VetoableDeleteObserver} has returned false
323:          */
324:         @Override
325:         public boolean canDelete(EObject toBeDeleted) {
326:                 boolean canDelete = true;
327:•                for (final VetoableDeleteObserver observer : vetoableDeleteObserver) {
328:                         canDelete = observer.canDelete(toBeDeleted);
329:•                        if (!canDelete) {
330:                                 break;
331:                         }
332:                 }
333:                 return canDelete;
334:         }
335:
336: }