Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 46c9ec3abab3a932ab61c54da2743e07ebce3fcb (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*******************************************************************************
 * Copyright (c) 2010 THALES GLOBAL SERVICES.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Obeo - initial API and implementation
 *******************************************************************************/
package org.eclipse.sirius.business.api.tool;

import java.util.Collection;
import java.util.Collections;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.transaction.DemultiplexingListener;
import org.eclipse.emf.transaction.NotificationFilter;
import org.eclipse.emf.transaction.ResourceSetChangeEvent;
import org.eclipse.emf.transaction.TransactionalEditingDomain;

import org.eclipse.sirius.common.tools.api.interpreter.EvaluationException;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter;
import org.eclipse.sirius.common.tools.api.util.StringUtil;
import org.eclipse.sirius.DRepresentation;
import org.eclipse.sirius.SiriusPlugin;
import org.eclipse.sirius.description.tool.FeatureChangeListener;
import org.eclipse.sirius.description.tool.ToolFilterDescription;
import org.eclipse.sirius.tools.api.interpreter.InterpreterUtil;
import org.eclipse.sirius.ecore.extender.business.api.accessor.ModelAccessor;

/**
 * A resource set listener for a tool description filter. When one or several
 * notifications match the elements to listen and features specified by the the
 * tool
 * 
 * @author mchauvin
 * @since 2.7
 */
public class ToolFilterDescriptionListener extends DemultiplexingListener {

    private ToolFilterDescription filter;

    private boolean shoudUpdate;

    private Runnable updateRunnable;

    /**
     * Create a new instance.
     * 
     * @param filter
     *            the filter from which to create a resource set listener
     * @param representation
     *            the representation to use as context for elements to listen
     *            computation
     */
    public ToolFilterDescriptionListener(final ToolFilterDescription filter, final DRepresentation representation) {
        super(ToolFilterDescriptionListener.getFilter(representation, filter));
        this.filter = filter;
    }

    /**
     * Set the runnable which will be called when the notifications matches the
     * elements to listen and associated features.
     * 
     * @param runnable
     *            the runnable to call
     */
    public void setUpdateRunnable(final Runnable runnable) {
        this.updateRunnable = runnable;
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.emf.transaction.DemultiplexingListener#resourceSetChanged(org.eclipse.emf.transaction.ResourceSetChangeEvent)
     */
    @Override
    public void resourceSetChanged(ResourceSetChangeEvent event) {
        shoudUpdate = false;
        super.resourceSetChanged(event);
        if (shoudUpdate) {
            updateRunnable.run();
        }

    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.emf.transaction.DemultiplexingListener#handleNotification(org.eclipse.emf.transaction.TransactionalEditingDomain,
     *      org.eclipse.emf.common.notify.Notification)
     */
    @Override
    protected void handleNotification(TransactionalEditingDomain domain, Notification notification) {
        if (notification.getNotifier() instanceof EObject) {
            final EObject notifier = (EObject) notification.getNotifier();
            final EStructuralFeature feature = (EStructuralFeature) notification.getFeature();
            final ModelAccessor accessor = getModelAccessor(domain);

            for (final FeatureChangeListener listener : filter.getListeners()) {
                if (accessor.eInstanceOf(notifier, listener.getDomainClass())) {
                    if (feature.getName().equals(listener.getFeatureName())) {
                        shoudUpdate = true;
                    }
                }
            }
        }
    }

    private ModelAccessor getModelAccessor(TransactionalEditingDomain domain) {
        return SiriusPlugin.getDefault().getModelAccessorRegistry().getModelAccessor(domain.getResourceSet());
    }

    private static NotificationFilter getFilter(final DRepresentation representation, ToolFilterDescription filter) {
        final Collection<EObject> elementsToListen = ToolFilterDescriptionListener.elementsToListen(representation, filter.getElementsToListen());
        NotificationFilter notificationFilter = NotificationFilter.NOT_TOUCH;
        for (final EObject eObject : elementsToListen) {
            notificationFilter = notificationFilter.and(NotificationFilter.createNotifierFilter(eObject));
        }
        return notificationFilter;
    }

    private static Collection<EObject> elementsToListen(final DRepresentation representation, final String elementsToListen) {
        final IInterpreter interpreter = InterpreterUtil.getInterpreter(representation);
        Collection<EObject> semanticCandidates = Collections.emptySet();
        try {
            if (interpreter != null && !StringUtil.isEmpty(elementsToListen)) {
                semanticCandidates = interpreter.evaluateCollection(representation, elementsToListen);
            }
        } catch (final EvaluationException exception) {
            // TODO log something
        }
        return semanticCandidates;
    }

}

Back to the top