package org.dresdenocl.metamodels.xsd.internal.model; import java.util.Collection; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.EcoreFactory; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.xsd.XSDSchema; import org.eclipse.xsd.ecore.XSDEcoreBuilder; import org.dresdenocl.metamodels.ecore.internal.model.EcoreAdapterFactory; 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; /** * If the root of the model is a single {@link XSDSchema}, a corresponding * {@link XSDNamespace} adapter will be created. If there are several root * packages, a new "virtual" root namespace will be created. * * @author Michael Thiele * * @generated */ public class XSDModel extends AbstractModel implements IModel { // the resource containing the corresponding XSD model private org.eclipse.emf.ecore.resource.Resource resource; // the adapter for the top package of the associated XSD model private Namespace rootNamespace; /** * <p> * The {@link EcoreAdapterFactory} used to create nested elements. * </p> */ private EcoreAdapterFactory factory = new EcoreAdapterFactory(); /** * Creates a new <code>XSDModel</code> adapting the given {@link XSDSchema}. * * @param resource * the {@link org.eclipse.emf.ecore.resource.Resource} containing the * model * * @generated */ public XSDModel(org.eclipse.emf.ecore.resource.Resource resource, IMetamodel metamodel) { super(resource.getURI().toString(), metamodel); // initialize this.resource = resource; } /* * (non-Javadoc) * @see org.dresdenocl.model.IModel#dispose() */ public void dispose() { /* Unload the resource to remove external contents. */ this.resource.unload(); /* Reset the root name space to avoid caching. */ this.rootNamespace = null; } /** * This method lazily creates a {@link Namespace} adapter for the virtual root * package in the associated XSD model. Thus, any possible resource loading * errors will not happen until this method is called for the first time. * * @throws ModelAccessException * if an error occurs when creating the adapter for the top * namespace * * @see org.dresdenocl.model.IModel#getRootNamespace() * * @generated */ public Namespace getRootNamespace() throws ModelAccessException { if (rootNamespace == null) { rootNamespace = createRootNamespace(); } return rootNamespace; } /** * 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. * * @return a <code>Namespace</code> instance * * @throws ModelAccessException * if an error occurs while loading the adapted XSD model * * @generated NOT */ protected Namespace createRootNamespace() throws ModelAccessException { /* * Code adapted fromhttp://wiki.eclipse.org/index.php/ * Generating_Dynamic_Ecore_from_XML_Schema */ ResourceSet resourceSet = resource.getResourceSet(); XSDEcoreBuilder xsdEcoreBuilder = new XSDEcoreBuilder(); Collection<EObject> ePackages = xsdEcoreBuilder.generate(resource.getURI()); for (EObject element : ePackages) { EPackage ePackage = (EPackage) element; resourceSet.getPackageRegistry().put(ePackage.getNsURI(), ePackage); } /* * End: Code adapted from Eclipse Wiki */ // create a new package to serve as the root package EPackage rootPackage = EcoreFactory.eINSTANCE.createEPackage(); rootPackage.setName(ModelConstants.ROOT_PACKAGE_NAME); // add all sub-packages and subtypes to the new root package for (Object object : ePackages) { rootPackage.getESubpackages().add((EPackage) object); } return factory.createNamespace(rootPackage); } /** * Overridden to base equality check on the URI of the associated resource. * * @see java.lang.Object#equals(java.lang.Object) * * @generated */ @Override public boolean equals(Object obj) { if (obj instanceof XSDModel) { return resource.equals(((XSDModel) obj).resource); } return false; } /** * Overridden to base the hash code on the URI of the associated resource. * * @see java.lang.Object#hashCode() * * @generated */ @Override public int hashCode() { return resource.hashCode(); } /** * Returns a String representation of this <code>XSDModel</code>. * * @see java.lang.Object#toString() * * @generated */ @Override public String toString() { return resource.toString(); } }