// $Id: EUMLModelImplementation.java 18244 2010-04-12 17:34:46Z tfmorris $
/*******************************************************************************
* Copyright (c) 2007,2010 Tom Morris and other contributors
* 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:
* Tom Morris - initial implementation
* Bogdan Pistol - undo support
* thn
*
* This implementation uses ideas and code snippets from the
* "org.eclipse.uml2.uml.editor.presentation" package.
*
* The package "org.eclipse.uml2.uml.editor.presentation" is part of the
* Eclipse UML2 plugin and it is available under the terms of
* the Eclipse Public License v1.0.
*****************************************************************************/
package org.argouml.model.euml;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import org.argouml.model.DiagramInterchangeModel;
import org.argouml.model.ModelImplementation;
import org.argouml.model.UmlException;
import org.eclipse.emf.common.command.BasicCommandStack;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.provider.EcoreItemProviderAdapterFactory;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.uml2.common.edit.domain.UML2AdapterFactoryEditingDomain;
import org.eclipse.uml2.uml.UMLPackage;
import org.eclipse.uml2.uml.edit.providers.UMLItemProviderAdapterFactory;
import org.eclipse.uml2.uml.edit.providers.UMLReflectiveItemProviderAdapterFactory;
import org.eclipse.uml2.uml.edit.providers.UMLResourceItemProviderAdapterFactory;
import org.eclipse.uml2.uml.resource.UML22UMLExtendedMetaData;
import org.eclipse.uml2.uml.resource.UML22UMLResource;
import org.eclipse.uml2.uml.resource.UMLResource;
import org.eclipse.uml2.uml.resource.XMI2UMLExtendedMetaData;
import org.eclipse.uml2.uml.resource.XMI2UMLResource;
/**
* Eclipse UML2 implementation of the ArgoUML Model subsystem. Although built on
* the Eclipse UML2 plugin which is, in turn, built on eCore and the Eclipse
* Modeling Framework (EMF), the only things required from Eclipse are the five
* Jars which implement UML2, eCore, and the subset of EMF needed for to support
* them.
* <p>
* The implementation of this subsystem was generously sponsored by Google as
* part of the Google Summer of Code 2007. A large part of the implementation was
* built by the sponsored student, Bogdan Ciprian Pistol, who was mentored by
* Tom Morris.
* <p>
* This implementation uses ideas and code snippets from the
* "org.eclipse.uml2.uml.editor.presentation" package which is part of the
* Eclipse UML2 plugin.
*
* @author Bogdan Ciprian Pistol
* @author Tom Morris <tfmorris@gmail.com>
* @since ArgoUML 0.25.4, May 2007
*/
public class EUMLModelImplementation implements ModelImplementation {
private static final Logger LOG =
Logger.getLogger(EUMLModelImplementation.class);
private ActivityGraphsFactoryEUMLlImpl theActivityGraphsFactory;
private ActivityGraphsHelperEUMLImpl theActivityGraphsHelper;
private AggregationKindEUMLImpl theAggregationKind;
@SuppressWarnings("deprecation")
private ChangeableKindEUMLImpl theChangeableKind;
private CollaborationsFactoryEUMLImpl theCollaborationsFactory;
private CollaborationsHelperEUMLImpl theCollaborationsHelper;
private CommonBehaviorFactoryEUMLImpl theCommonBehaviorFactory;
private CommonBehaviorHelperEUMLImpl theCommonBehaviorHelper;
private ConcurrencyKindEUMLImpl theConcurrencyKind;
private CopyHelperEUMLImpl theCopyHelper;
private CoreFactoryEUMLImpl theCoreFactory;
private CoreHelperEUMLImpl theCoreHelper;
private DataTypesFactoryEUMLImpl theDataTypesFactory;
private DataTypesHelperEUMLImpl theDataTypesHelper;
private DirectionKindEUMLImpl theDirectionKind;
private ExtensionMechanismsFactoryEUMLImpl theExtensionMechanismsFactory;
private ExtensionMechanismsHelperEUMLImpl theExtensionMechanismsHelper;
private FacadeEUMLImpl theFacade;
private MetaTypesEUMLImpl theMetaTypes;
private ModelEventPumpEUMLImpl theModelEventPump;
private ModelManagementFactoryEUMLImpl theModelManagementFactory;
private ModelManagementHelperEUMLImpl theModelManagementHelper;
private OrderingKindEUMLImpl theOrderingKind;
private PseudostateKindEUMLImpl thePseudostateKind;
@SuppressWarnings("deprecation")
private ScopeKindEUMLImpl theScopeKind;
private StateMachinesFactoryEUMLImpl theStateMachinesFactory;
private StateMachinesHelperEUMLImpl theStateMachinesHelper;
private UmlFactoryEUMLImpl theUmlFactory;
private UmlHelperEUMLImpl theUmlHelper;
private UseCasesFactoryEUMLImpl theUseCasesFactory;
private UseCasesHelperEUMLImpl theUseCasesHelper;
private VisibilityKindEUMLImpl theVisibilityKind;
private CommandStackImpl theCommandStack;
/**
* This keeps track of the editing domain that is used to track all changes
* to the model.
* <p>
* TODO: This probably needs to be a set of EditingDomain so that we can
* manage an EditingDomain per project.
*/
private AdapterFactoryEditingDomain editingDomain;
/**
* Map of which resources are read-only.
* <p>
* TODO: This needs to be managed per EditingDomain.
*/
private Map<Resource,Boolean> readOnlyMap =
new HashMap<Resource, Boolean>();
/**
* Constructor.
*/
public EUMLModelImplementation() {
initializeEditingDomain();
LOG.debug("EUML Init - editing domain initialized"); //$NON-NLS-1$
}
/**
* This sets up the editing domain for the model editor.
*
* TODO: We probably need an EditingDomain per Argo project so that we can
* keep the ResourceSets separate.
*/
private void initializeEditingDomain() {
// If the eUML.resources system property is defined then we are in a
// stand alone application, else we're in an Eclipse plug in.
// The eUML.resource should contain the path to the
// org.eclipse.uml2.uml.resource jar plugin.
String path = System.getProperty("eUML.resources"); //$NON-NLS-1$
BasicCommandStack commandStack = new BasicCommandStack() {
@Override
protected void handleError(Exception exception) {
super.handleError(exception);
throw new RuntimeException(exception);
}
};
List<AdapterFactory> factories = new ArrayList<AdapterFactory>();
factories.add(new UMLResourceItemProviderAdapterFactory());
factories.add(new UMLItemProviderAdapterFactory());
factories.add(new EcoreItemProviderAdapterFactory());
factories.add(new UMLReflectiveItemProviderAdapterFactory());
ComposedAdapterFactory adapterFactory = new ComposedAdapterFactory(
factories);
// TODO: This will need to be adapted to send undo/redo commands back
// to our consumer (e.g. ArgoUML) if a new undo mechanism is implemented
// for the Model subsystem - tfm
editingDomain = new UML2AdapterFactoryEditingDomain(
adapterFactory, commandStack, readOnlyMap);
ResourceSet resourceSet = editingDomain.getResourceSet();
Map<String, Object> extensionToFactoryMap =
resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap();
Map<URI, URI> uriMap = resourceSet.getURIConverter().getURIMap();
if (path != null) {
try {
FileInputStream in = new FileInputStream(path);
in.close();
} catch (IOException e) {
throw (new RuntimeException(e));
}
path = path.replace('\\', '/');
// These lines were one cause for issue 5915: (Were they needed?)
// TODO: Review - tfm
//if (Character.isLetter(path.charAt(0))) {
// path = '/' + path;
//}
URI uri = URI.createURI("jar:file:" + path + "!/"); //$NON-NLS-1$ //$NON-NLS-2$
LOG.debug("eUML.resource URI --> " + uri); //$NON-NLS-1$
resourceSet.getPackageRegistry().put(
UMLPackage.eNS_URI, UMLPackage.eINSTANCE);
resourceSet.getPackageRegistry().put(
EcorePackage.eNS_URI, EcorePackage.eINSTANCE);
// For the .uml files in the eclipse jar files, we need this:
extensionToFactoryMap.put(
UMLResource.FILE_EXTENSION, UMLResource.Factory.INSTANCE);
uriMap.put(
URI.createURI(UMLResource.LIBRARIES_PATHMAP),
uri.appendSegment("libraries").appendSegment("")); //$NON-NLS-1$ //$NON-NLS-2$
uriMap.put(
URI.createURI(UMLResource.METAMODELS_PATHMAP),
uri.appendSegment("metamodels").appendSegment("")); //$NON-NLS-1$//$NON-NLS-2$
uriMap.put(
URI.createURI(UMLResource.PROFILES_PATHMAP),
uri.appendSegment("profiles").appendSegment("")); //$NON-NLS-1$//$NON-NLS-2$
}
extensionToFactoryMap.put(
UML22UMLResource.FILE_EXTENSION,
UML22UMLResource.Factory.INSTANCE);
extensionToFactoryMap.put(
XMI2UMLResource.FILE_EXTENSION,
XMI2UMLResource.Factory.INSTANCE);
uriMap.putAll(UML22UMLExtendedMetaData.getURIMap());
uriMap.putAll(XMI2UMLExtendedMetaData.getURIMap());
}
/**
* Getter for {@link #editingDomain the Editing Domain}
*
* @return the editing domain of the current EUMLModelImplementation
* instance
*/
public EditingDomain getEditingDomain() {
return editingDomain;
}
/**
* @return the read only map for resources in the EditingDomain
*/
public Map<Resource, Boolean> getReadOnlyMap() {
return readOnlyMap;
}
public ActivityGraphsFactoryEUMLlImpl getActivityGraphsFactory() {
if (theActivityGraphsFactory == null) {
theActivityGraphsFactory =
new ActivityGraphsFactoryEUMLlImpl(this);
}
return theActivityGraphsFactory;
}
public ActivityGraphsHelperEUMLImpl getActivityGraphsHelper() {
if (theActivityGraphsHelper == null) {
theActivityGraphsHelper = new ActivityGraphsHelperEUMLImpl(this);
}
return theActivityGraphsHelper;
}
public AggregationKindEUMLImpl getAggregationKind() {
if (theAggregationKind == null) {
theAggregationKind = new AggregationKindEUMLImpl();
}
return theAggregationKind;
}
@SuppressWarnings("deprecation")
public ChangeableKindEUMLImpl getChangeableKind() {
if (theChangeableKind == null) {
theChangeableKind = new ChangeableKindEUMLImpl();
}
return theChangeableKind;
}
public CollaborationsFactoryEUMLImpl getCollaborationsFactory() {
if (theCollaborationsFactory == null) {
theCollaborationsFactory = new CollaborationsFactoryEUMLImpl(this);
}
return theCollaborationsFactory;
}
public CollaborationsHelperEUMLImpl getCollaborationsHelper() {
if (theCollaborationsHelper == null) {
theCollaborationsHelper = new CollaborationsHelperEUMLImpl(this);
}
return theCollaborationsHelper;
}
public CommonBehaviorFactoryEUMLImpl getCommonBehaviorFactory() {
if (theCommonBehaviorFactory == null) {
theCommonBehaviorFactory = new CommonBehaviorFactoryEUMLImpl(this);
}
return theCommonBehaviorFactory;
}
public CommonBehaviorHelperEUMLImpl getCommonBehaviorHelper() {
if (theCommonBehaviorHelper == null) {
theCommonBehaviorHelper = new CommonBehaviorHelperEUMLImpl(this);
}
return theCommonBehaviorHelper;
}
public ConcurrencyKindEUMLImpl getConcurrencyKind() {
if (theConcurrencyKind == null) {
theConcurrencyKind = new ConcurrencyKindEUMLImpl();
}
return theConcurrencyKind;
}
public CopyHelperEUMLImpl getCopyHelper() {
if (theCopyHelper == null) {
theCopyHelper = new CopyHelperEUMLImpl(this);
}
return theCopyHelper;
}
public CoreFactoryEUMLImpl getCoreFactory() {
if (theCoreFactory == null) {
theCoreFactory = new CoreFactoryEUMLImpl(this);
}
return theCoreFactory;
}
public CoreHelperEUMLImpl getCoreHelper() {
if (theCoreHelper == null) {
theCoreHelper = new CoreHelperEUMLImpl(this);
}
return theCoreHelper;
}
public DataTypesFactoryEUMLImpl getDataTypesFactory() {
if (theDataTypesFactory == null) {
theDataTypesFactory = new DataTypesFactoryEUMLImpl(this);
}
return theDataTypesFactory;
}
public DataTypesHelperEUMLImpl getDataTypesHelper() {
if (theDataTypesHelper == null) {
theDataTypesHelper = new DataTypesHelperEUMLImpl(this);
}
return theDataTypesHelper;
}
public DirectionKindEUMLImpl getDirectionKind() {
if (theDirectionKind == null) {
theDirectionKind = new DirectionKindEUMLImpl();
}
return theDirectionKind;
}
public ExtensionMechanismsFactoryEUMLImpl getExtensionMechanismsFactory() {
if (theExtensionMechanismsFactory == null) {
theExtensionMechanismsFactory =
new ExtensionMechanismsFactoryEUMLImpl(this);
}
return theExtensionMechanismsFactory;
}
public ExtensionMechanismsHelperEUMLImpl getExtensionMechanismsHelper() {
if (theExtensionMechanismsHelper == null) {
theExtensionMechanismsHelper =
new ExtensionMechanismsHelperEUMLImpl(this);
}
return theExtensionMechanismsHelper;
}
public FacadeEUMLImpl getFacade() {
if (theFacade == null) {
theFacade = new FacadeEUMLImpl(this);
}
return theFacade;
}
public MetaTypesEUMLImpl getMetaTypes() {
if (theMetaTypes == null) {
theMetaTypes = new MetaTypesEUMLImpl(this);
}
return theMetaTypes;
}
public ModelEventPumpEUMLImpl getModelEventPump() {
if (theModelEventPump == null) {
theModelEventPump = new ModelEventPumpEUMLImpl(this);
}
return theModelEventPump;
}
public ModelManagementFactoryEUMLImpl getModelManagementFactory() {
if (theModelManagementFactory == null) {
theModelManagementFactory =
new ModelManagementFactoryEUMLImpl(this);
}
return theModelManagementFactory;
}
public ModelManagementHelperEUMLImpl getModelManagementHelper() {
if (theModelManagementHelper == null) {
theModelManagementHelper = new ModelManagementHelperEUMLImpl(this);
}
return theModelManagementHelper;
}
public OrderingKindEUMLImpl getOrderingKind() {
if (theOrderingKind == null) {
theOrderingKind = new OrderingKindEUMLImpl();
}
return theOrderingKind;
}
public PseudostateKindEUMLImpl getPseudostateKind() {
if (thePseudostateKind == null) {
thePseudostateKind = new PseudostateKindEUMLImpl();
}
return thePseudostateKind;
}
@SuppressWarnings("deprecation")
public ScopeKindEUMLImpl getScopeKind() {
if (theScopeKind == null) {
theScopeKind = new ScopeKindEUMLImpl();
}
return theScopeKind;
}
public StateMachinesFactoryEUMLImpl getStateMachinesFactory() {
if (theStateMachinesFactory == null) {
theStateMachinesFactory = new StateMachinesFactoryEUMLImpl(this);
}
return theStateMachinesFactory;
}
public StateMachinesHelperEUMLImpl getStateMachinesHelper() {
if (theStateMachinesHelper == null) {
theStateMachinesHelper = new StateMachinesHelperEUMLImpl(this);
}
return theStateMachinesHelper;
}
public UmlFactoryEUMLImpl getUmlFactory() {
if (theUmlFactory == null) {
theUmlFactory = new UmlFactoryEUMLImpl(this);
}
return theUmlFactory;
}
public UmlHelperEUMLImpl getUmlHelper() {
if (theUmlHelper == null) {
theUmlHelper = new UmlHelperEUMLImpl(this);
}
return theUmlHelper;
}
public UseCasesFactoryEUMLImpl getUseCasesFactory() {
if (theUseCasesFactory == null) {
theUseCasesFactory = new UseCasesFactoryEUMLImpl(this);
}
return theUseCasesFactory;
}
public UseCasesHelperEUMLImpl getUseCasesHelper() {
if (theUseCasesHelper == null) {
theUseCasesHelper = new UseCasesHelperEUMLImpl(this);
}
return theUseCasesHelper;
}
public VisibilityKindEUMLImpl getVisibilityKind() {
if (theVisibilityKind == null) {
theVisibilityKind = new VisibilityKindEUMLImpl();
}
return theVisibilityKind;
}
public XmiReaderEUMLImpl getXmiReader() throws UmlException {
return new XmiReaderEUMLImpl(this);
}
public XmiWriterEUMLImpl getXmiWriter(Object model, OutputStream stream,
String version) throws UmlException {
return new XmiWriterEUMLImpl(this, model, stream, version);
}
public DiagramInterchangeModel getDiagramInterchangeModel() {
return null;
}
private CommandStackImpl getCommandStack() {
if (theCommandStack == null) {
theCommandStack = new CommandStackImpl(this);
}
return theCommandStack;
}
/**
* Unload all resources in the editing domain and clear the read only map.
*/
void clearEditingDomain() {
for (Resource resource
: editingDomain.getResourceSet().getResources()) {
unloadResource(resource);
}
}
void unloadResource(Resource resource) {
resource.unload();
readOnlyMap.remove(resource);
}
}