001: package org.andromda.repositories.emf;
002:
003: import org.andromda.core.common.ResourceFinder;
004: import org.andromda.core.metafacade.ModelAccessFacade;
005: import org.andromda.core.repository.RepositoryFacade;
006: import org.andromda.core.repository.RepositoryFacadeException;
007: import org.eclipse.emf.common.util.URI;
008: import org.eclipse.emf.ecore.resource.Resource;
009: import org.eclipse.emf.ecore.resource.ResourceSet;
010: import org.eclipse.emf.ecore.util.EcoreUtil;
011:
012: import java.io.IOException;
013: import java.io.InputStream;
014: import java.net.URL;
015: import java.util.ArrayList;
016: import java.util.Arrays;
017: import java.util.HashMap;
018: import java.util.List;
019: import java.util.Map;
020:
021: /**
022: * An abtract EMF {@link RepositoryFacade} instance that should be extended by any repository wishing to load EMF models.
023: *
024: * @author Steve Jerman
025: * @author Chad Brandon
026: */
027: public abstract class EMFRepositoryFacade implements RepositoryFacade {
028: /**
029: * Stores the resources (i.e. models) loaded into EMF.
030: */
031: private ResourceSet resourceSet;
032:
033: protected ModelAccessFacade modelFacade;
034:
035: /**
036: * Stores the actual loaded model.
037: */
038: protected Resource model;
039:
040: /**
041: * The options for loading the model.
042: */
043: private Map loadOptions = new HashMap();
044:
045: /**
046: * Gets the current load options.
047: *
048: * @return the load options.
049: */
050: protected Map getLoadOptions() {
051: return this .loadOptions;
052: }
053:
054: /**
055: * Reads the model with the given <code>uri</code>.
056: *
057: * @param uri the URI to the model
058: */
059: protected void readModel(final String uri) {
060: try {
061: model = resourceSet.createResource(EMFRepositoryFacadeUtils
062: .createUri(uri));
063: if (model == null) {
064: throw new RepositoryFacadeException("'" + uri
065: + "' is an invalid model");
066: }
067: model.load(this .getLoadOptions());
068: EcoreUtil.resolveAll(model);
069: } catch (final Exception exception) {
070: throw new RepositoryFacadeException(exception);
071: }
072: }
073:
074: /**
075: * @see org.andromda.core.repository.RepositoryFacade#open()
076: */
077: public void open() {
078: this .resourceSet = this .createNewResourceSet();
079: }
080:
081: /**
082: * Creates and returns a new resource suitable suitable for loading models into EMF.
083: * This callback is used when (re-)initializing this repository so that it can be reused between different
084: * AndroMDA runs, once a resource set is used for a model it becomes 'polluted' so that subsequent models
085: * will see things from the previous runs, which might mess up the processing.
086: *
087: * @return a new resource set to be used by this repository
088: */
089: protected abstract ResourceSet createNewResourceSet();
090:
091: /**
092: * @see org.andromda.core.repository.RepositoryFacade#close()
093: */
094: public void close() {
095: }
096:
097: /**
098: * The path to any modules found on the classpath.
099: */
100: private static final String MODULES_PATH = "META-INF/emf/modules";
101:
102: /**
103: * @see org.andromda.core.repository.RepositoryFacade#readModel(java.lang.String[], java.lang.String[])
104: */
105: public final void readModel(String[] modelUris,
106: String[] moduleSearchPaths) {
107: if (modelUris == null || modelUris.length == 0) {
108: throw new RepositoryFacadeException("No model specified.");
109: }
110: final List moduleSearchPathList = new ArrayList();
111: if (moduleSearchPaths != null) {
112: moduleSearchPathList.addAll(Arrays
113: .asList(moduleSearchPaths));
114: }
115:
116: // - first add the default module search paths maps that are found on the classpath
117: final URL[] classpathSearchPaths = ResourceFinder
118: .findResources(MODULES_PATH);
119:
120: if (classpathSearchPaths != null) {
121: final int numberOfClasspathSearchPaths = classpathSearchPaths.length;
122: for (int ctr = 0; ctr < numberOfClasspathSearchPaths; ctr++) {
123: final URL classpathSearchPath = classpathSearchPaths[ctr];
124: if (classpathSearchPath != null) {
125: moduleSearchPathList.add(classpathSearchPath
126: .toString());
127: }
128: }
129: }
130: this .resourceSet.setURIConverter(new EMFURIConverter(
131: moduleSearchPathList));
132: if (modelUris.length > 0) {
133: final int numberOfModelUris = modelUris.length;
134: for (int ctr = 0; ctr < numberOfModelUris; ctr++) {
135: this .readModel(modelUris[ctr]);
136: }
137: }
138: }
139:
140: /**
141: * @see org.andromda.core.repository.RepositoryFacade#readModel(java.io.InputStream[], java.lang.String[], java.lang.String[])
142: */
143: public void readModel(InputStream[] stream, String[] modelUri,
144: String[] moduleSearchPaths) {
145: this .readModel(modelUri, moduleSearchPaths);
146: }
147:
148: /**
149: * @see org.andromda.core.repository.RepositoryFacade#writeModel(java.lang.Object, java.lang.String, java.lang.String, java.lang.String)
150: */
151: public void writeModel(Object model, String location,
152: String version, String encoding) {
153: this .writeModel(model, location, "");
154: }
155:
156: /**
157: * @see org.andromda.core.repository.RepositoryFacade#writeModel(java.lang.Object, java.lang.String, java.lang.String)
158: */
159: public void writeModel(Object model, String location, String version) {
160: final org.eclipse.emf.ecore.EModelElement element = (org.eclipse.emf.ecore.EModelElement) model;
161: final Resource resource = element.eResource();
162: final URI uri = URI.createURI(location);
163: resource.setURI(uri);
164: try {
165: resource.save(null);
166: } catch (IOException exception) {
167: throw new RepositoryFacadeException("Could not save model",
168: exception);
169: }
170: }
171:
172: /**
173: * @see org.andromda.core.repository.RepositoryFacade#clear()
174: */
175: public void clear() {
176: this.model = null;
177: this.resourceSet = this.createNewResourceSet();
178: }
179: }
|