/* Copyright (C) 2012 by Bjoern Freitag (bjoern.freitag@mailbox.tu-dresden.de) * * This file is part of the CWM Meta Model of Dresden OCL2 for Eclipse. Dresden * OCL2 for Eclipse is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your * option) any later version. Dresden OCL2 for Eclipse is distributed in the * hope that it will be useful, but WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU Lesser General Public License for more details. You should have * received a copy of the GNU Lesser General Public License along with Dresden * OCL2 for Eclipse. If not, see <http://www.gnu.org/licenses/>. */ package org.dresdenocl.metamodels.cwmrelational.internal.model; import java.io.IOException; import java.util.HashSet; import java.util.List; import java.util.Set; import org.apache.log4j.Logger; import org.dresdenocl.metamodels.cwmrelational.CWMMetamodelPlugin; import org.dresdenocl.model.IModel; import org.dresdenocl.model.ModelAccessException; import org.dresdenocl.model.ModelConstants; import org.dresdenocl.model.base.AbstractModel; import org.dresdenocl.model.metamodel.IMetamodel; import org.dresdenocl.pivotmodel.Namespace; import org.dresdenocl.pivotmodel.PivotModelFactory; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.osgi.util.NLS; import orgomg.cwm.objectmodel.core.ModelElement; import orgomg.cwm.resource.relational.Catalog; import orgomg.cwm.resource.relational.Schema; /** * <p> * If the root of the model is a single {@link Catalog}, a * corresponding {@link CWMPackage} adapter will be created. If there are * several root packages or a single {@link Schema}, a new "virtual" root namespace will be created. * </p> * * @author Bjoern Freitag * * @generated NOT */ public class CWMModel extends AbstractModel implements IModel { /** * <p> * A {@link Logger} for this class. * </p> * * @generated NOT */ private static final Logger LOGGER = CWMMetamodelPlugin .getLogger(CWMModel.class); /** The resource containing the corresponding CWM model. */ private Resource resource; /** The adapter for the top package of the associated CWM model. */ private Namespace rootNamespace; /** The {@link CWMAdapterFactory} of this {@link CWMModel}. */ private CWMAdapterFactory factory; /** * <p> * Creates a new {@link CWMModel} adapting the given * {@link orgomg.cwm.resource.relational.Schema}. * * @param resource * The {@link Resource} containing the model. * * @generated NOT */ public CWMModel(Resource resource, IMetamodel metamodel) { super(resource.getURI().toString(), metamodel); /* Initialize. */ this.resource = resource; } /* * (non-Javadoc) * * @see tudresden.ocl20.pivot.model.IModel#dispose() */ public void dispose() { /* Unload referenced resources and the resource. */ Set<Resource> resourcesToUnload = new HashSet<Resource>(); resourcesToUnload.add(this.resource); for (EObject eObject : EcoreUtil.ExternalCrossReferencer.find( this.resource).keySet()) { resourcesToUnload.add(eObject.eResource()); } // end for. for (Resource resource : resourcesToUnload) { if (resource != null && resource.isLoaded()) resource.unload(); // no else. } // end for. /* Reset the root name space to avoid caching. */ this.rootNamespace = null; /* Reset the factory as well. */ this.factory = null; } /** * <p> * This method lazily creates a {@link Namespace} adapter for the virtual * root package in the associated UML2 model. Thus, any possible resource * loading errors will not happen until this method is called for the first * time. * </p> * * @throws ModelAccessException * if an error occurs when creating the adapter for the top * namespace * * @see tudresden.ocl20.pivot.model.IModel#getRootNamespace() * * @generated */ public Namespace getRootNamespace() throws ModelAccessException { if (rootNamespace == null) { rootNamespace = createRootNamespace(); } return rootNamespace; } /** * <p> * Overridden to base equality check on the URI of the associated resource. * </p> * * @see java.lang.Object#equals(java.lang.Object) * * @generated NOT */ @Override public boolean equals(Object anObject) { boolean result; /* Check if the given Object is a UML2Model. */ if (anObject instanceof CWMModel) { result = resource.getURI().equals( ((CWMModel) anObject).resource.getURI()); } else { result = false; } return result; } /** * <p> * Overridden to base the hash code on the URI of the associated resource. * </p> * * @see java.lang.Object#hashCode() * * @generated NOT */ @Override public int hashCode() { return this.resource.getURI().hashCode(); } /** * <p> * Returns a String representation of this {@link CWMModel}. * </p> * * @see java.lang.Object#toString() * * @generated NOT */ @Override public String toString() { return this.resource.getURI().toString(); } /** * <p> * Returns the {@link CWMAdapterFactory} of this {@link CWMModel}.</p< * * @return The {@link CWMAdapterFactory} of this {@link CWMModel}. */ public CWMAdapterFactory getFactory() { return this.factory; } /** * <p> * Helper method that creates the adapter for the root namespace. If there * is only one top-level namespace possible, then this method should just * return the adapter for the top-level namespace, else it should create a * new "virtual" root namespace. * </p> * * @return A {@link Namespace} instance * * @throws ModelAccessException * If an error occurs while loading the adapted CWM model. * * @generated NOT */ private Namespace createRootNamespace() throws ModelAccessException { if (this.rootNamespace == null) { /** load the resource. */ if (!resource.isLoaded()) { if (LOGGER.isInfoEnabled()) { LOGGER.info(NLS.bind( CWMModelMessages.CWMModel_LoadingCWMModel, resource.getURI())); } /* Try to load the resource. */ try { resource.load(null); } catch (IOException e) { throw new ModelAccessException( "Error while loading resource from " + resource.getURI(), e); //$NON-NLS-1$ } } // no else. /* Resolve all probably contained proxies of the resource. */ EcoreUtil.resolveAll(resource); /* Get the root packages. */ List<EObject> rootPackages; rootPackages = resource.getContents(); /* Create a new package to serve as the root package. */ this.rootNamespace = PivotModelFactory.eINSTANCE.createNamespace(); this.rootNamespace.setName(ModelConstants.ROOT_PACKAGE_NAME); this.factory = new CWMAdapterFactory(this.rootNamespace); /** Add all sub-packages and sub-types to the new root package. */ for (EObject eObject : rootPackages) { /* * Models should not be added themselves. Add their contained * packages instead. */ if (eObject instanceof Schema) { Namespace namespace = this.factory.createNamespace((Schema) eObject, this.rootNamespace); this.rootNamespace.addNestedNamespace(namespace); // end for. } else if (eObject instanceof Catalog) { for (ModelElement cwmType : ((Catalog) eObject).getOwnedElement()) { if (cwmType instanceof Schema) { Namespace namespace = this.factory.createNamespace(((Schema) cwmType),this.rootNamespace); this.rootNamespace.addNestedNamespace(namespace); } } } } // end for. } // no else. return this.rootNamespace; } }