| /** |
| * |
| * Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany) |
| * |
| * 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: |
| * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation |
| */ |
| package org.eclipse.osbp.ide.core.ui.softwarefactory.extender; |
| |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.concurrent.ConcurrentHashMap; |
| import java.util.concurrent.CopyOnWriteArraySet; |
| |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IWorkspace; |
| import org.eclipse.emf.common.util.URI; |
| import org.eclipse.osbp.ide.core.ui.softwarefactory.builder.OSBP2Builder; |
| import org.eclipse.osbp.ide.core.ui.softwarefactory.extender.IModelExtenderProvider.Event.Listener; |
| import org.eclipse.xtext.builder.builderState.IBuilderState; |
| import org.eclipse.xtext.naming.QualifiedName; |
| import org.eclipse.xtext.resource.IResourceDescription; |
| import org.eclipse.xtext.resource.IResourceDescription.Delta; |
| |
| import com.google.inject.Inject; |
| import com.google.inject.Singleton; |
| |
| @Singleton |
| public class ModelExtenderEventSource implements IModelExtenderProvider.Event.Source, IResourceDescription.Event.Listener { |
| |
| private CopyOnWriteArraySet<IModelExtenderProvider.Event.Listener> listenerList; |
| private ConcurrentHashMap<IModelExtenderProvider.Event.Listener, ConcurrentHashMap<String, ModelInstanceDescription>> packageDeltaMap; |
| private Set<String> pending = new CopyOnWriteArraySet<String>(); |
| |
| /** The adapter. */ |
| private IModelExtenderAdapter adapter; |
| |
| @Inject |
| protected IWorkspace workspace; |
| |
| @Inject |
| private IBuilderState builderState; |
| |
| @Inject |
| public ModelExtenderEventSource() { |
| listenerList = new CopyOnWriteArraySet<IModelExtenderProvider.Event.Listener>(); |
| packageDeltaMap = new ConcurrentHashMap<IModelExtenderProvider.Event.Listener, ConcurrentHashMap<String, ModelInstanceDescription>>(); |
| } |
| |
| @Override |
| public void addListener(IModelExtenderProvider.Event.Listener listener) { |
| packageDeltaMap.put(listener, new ConcurrentHashMap<String, ModelInstanceDescription>()); |
| listenerList.add(listener); |
| // request builderstate notification |
| builderState.addListener(this); |
| } |
| |
| @Override |
| public void removeListener(IModelExtenderProvider.Event.Listener listener) { |
| listenerList.remove(listener); |
| packageDeltaMap.remove(listener); |
| builderState.removeListener(this); |
| } |
| |
| public ConcurrentHashMap<IModelExtenderProvider.Event.Listener, ConcurrentHashMap<String, ModelInstanceDescription>> getPackageDeltaMap() { |
| return packageDeltaMap; |
| } |
| |
| public void setPackageDeltaMap( |
| ConcurrentHashMap<IModelExtenderProvider.Event.Listener, ConcurrentHashMap<String, ModelInstanceDescription>> packageDeltaMap) { |
| this.packageDeltaMap = packageDeltaMap; |
| } |
| |
| public Collection<IModelExtenderProvider.Event.Listener> getListenerList() { |
| return listenerList; |
| } |
| |
| @Override |
| public void notifyListeners(IModelExtenderProvider.Event event) { |
| if (event == null) |
| throw new IllegalArgumentException("event may not be null"); |
| for (IModelExtenderProvider.Event.Listener listener : listenerList) { |
| listener.modelExtended(event); |
| } |
| } |
| |
| @Override |
| public void addExtension(Listener listener, BaseExtender baseExtender) throws Exception { |
| addExtension(listener, baseExtender.getExtension(), baseExtender.getAdapter()); |
| } |
| |
| @Override |
| public void addExtension(IModelExtenderProvider.Event.Listener listener, String extension, IModelExtenderAdapter adapter) throws Exception { |
| this.adapter = adapter; |
| ModelInstanceDescription pd = new ModelInstanceDescription(); |
| String projectPath = adapter.getModelPath(extension); |
| pd.setModelPath(projectPath); |
| if (projectPath != null) { |
| URI path = URI.createFileURI(projectPath); |
| // find the bundle segment |
| for (IProject proj : workspace.getRoot().getProjects()) { |
| String modelFile = null; |
| for (int i = 0; i < path.segmentCount(); i++) { |
| if (modelFile != null) { |
| modelFile += "/" + path.segment(i); |
| } |
| if (proj.getName().equals(path.segment(i))) { |
| pd.setProject(proj); |
| modelFile = ""; |
| } |
| } |
| if (modelFile != null) { |
| pd.setModelFile(modelFile); |
| break; |
| } |
| } |
| try { |
| pd.setModelURI(URI.createPlatformResourceURI(pd.getProject().getFullPath().toString() + pd.getModelFile(), false)); |
| } catch (NullPointerException npe){ |
| throw new Exception("No project found for the extension: '" + extension + "'. \nPossible reasons: \n1. Incorrect path to the model. \n2. Not existing bundle containing this model."); |
| } |
| } |
| packageDeltaMap.get(listener).put(extension, pd); |
| } |
| |
| @Override |
| public Map<String, ModelInstanceDescription> getModelInstanceDescriptionMap(IModelExtenderProvider.Event.Listener listener) { |
| return packageDeltaMap.get(listener); |
| } |
| |
| @Override |
| public Set<String> getPending() { |
| return pending; |
| } |
| |
| @Override |
| public void descriptionsChanged(org.eclipse.xtext.resource.IResourceDescription.Event event) { |
| Map<String, IResourceDescription> toBeRebuilt = new HashMap<String, IResourceDescription>(); |
| for (Delta delta : event.getDeltas()) { |
| if ((delta.haveEObjectDescriptionsChanged() && delta.getNew() != null) || authorizationChanged(delta)) { |
| toBeRebuilt.put(delta.getUri().fileExtension(), delta.getNew()); |
| } |
| } |
| for (String extension : toBeRebuilt.keySet()) { |
| for (Listener listener : getListenerList()) { |
| Map<String, ModelInstanceDescription> modelInstanceDecriptionMap = getModelInstanceDescriptionMap(listener); |
| if (modelInstanceDecriptionMap.containsKey(extension)) { |
| if (modelInstanceDecriptionMap.get(extension).isDone()) { |
| if (!modelInstanceDecriptionMap.get(extension).isBuilt()) { |
| modelInstanceDecriptionMap.get(extension).setResourceDescription(toBeRebuilt.get(extension)); |
| if (!contains(extension)) { |
| pending.add(extension); |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| boolean authorizationChanged(Delta delta) { |
| if (delta.getUri().fileExtension().contains(OSBP2Builder.AUTHORIZATION_MODEL_EXTENSION)) { |
| return (contains(delta.getNew().getImportedNames()) && !contains(delta.getOld().getImportedNames())); |
| } |
| return false; |
| } |
| |
| boolean contains(Iterable<QualifiedName> iterable) { |
| String identifier = adapter.getIdentifier().toLowerCase(); |
| for (QualifiedName qn : iterable) { |
| boolean idFound = qn.getLastSegment().contains(identifier); |
| if (idFound) |
| return idFound; |
| } |
| return false; |
| } |
| |
| boolean contains(String extension) { |
| for (String ext : pending) { |
| if (ext.equals(extension)) { |
| return true; |
| } |
| } |
| return false; |
| } |
| } |