001: package org.andromda.repositories.emf;
002:
003: import java.io.InputStream;
004:
005: import java.net.URL;
006:
007: import java.util.HashMap;
008: import java.util.Iterator;
009: import java.util.List;
010: import java.util.Map;
011:
012: import org.andromda.core.common.AndroMDALogger;
013: import org.andromda.core.common.ResourceUtils;
014: import org.apache.log4j.Logger;
015: import org.eclipse.emf.common.util.URI;
016: import org.eclipse.emf.ecore.resource.impl.URIConverterImpl;
017:
018: /**
019: * Extends the default URIConverterImpl to be able to discover the physical path of URIs when
020: * given the moduleSearchPaths.
021: *
022: * @author Chad Brandon
023: */
024: public class EMFURIConverter extends URIConverterImpl {
025: /**
026: * Creates a new instance of EMFURIConvert taking the <code>moduleSearchPaths</code>
027: * as an argument. These are the paths used to attempt to normalize a given URI during
028: * the call to {@link #normalize(URI)} provided that it couldn't be found in the normal manner.
029: *
030: * @param moduleSearchPaths the paths to search for modules.
031: */
032: public EMFURIConverter(final List moduleSearchPaths) {
033: this .moduleSearchPaths = moduleSearchPaths;
034: if (logger.isDebugEnabled()) {
035: for (final Iterator pathIterator = this .moduleSearchPaths
036: .iterator(); pathIterator.hasNext();) {
037: logger
038: .debug("Model search path:"
039: + pathIterator.next());
040: }
041: }
042: }
043:
044: /**
045: * Stores the module search paths.
046: */
047: private List moduleSearchPaths;
048:
049: /**
050: * Stores the URIs that have been normalized.
051: */
052: private final Map normalizedUris = new HashMap();
053:
054: /**
055: * The logger instance.
056: */
057: private static Logger logger = Logger
058: .getLogger(EMFURIConverter.class);
059:
060: /**
061: * Overridden to provide the normalization of uris given the module search paths.
062: *
063: * @see org.eclipse.emf.ecore.resource.URIConverter#normalize(org.eclipse.emf.common.util.URI)
064: */
065: public URI normalize(final URI uri) {
066: URI normalizedUri = super .normalize(uri);
067: if (normalizedUri.equals(uri)) {
068: if (this .moduleSearchPaths != null) {
069: if (!this .normalizedUris.containsKey(uri)) {
070: final String resourceName = uri.toString()
071: .replaceAll(".*(\\\\+|/)", "");
072: for (final Iterator iterator = this .moduleSearchPaths
073: .iterator(); iterator.hasNext();) {
074: final String searchPath = (String) iterator
075: .next();
076: final URI fileURI = EMFRepositoryFacadeUtils
077: .createUri(ResourceUtils
078: .normalizePath(searchPath));
079: if (fileURI.lastSegment().equals(resourceName)) {
080: AndroMDALogger
081: .info("referenced model --> '"
082: + fileURI + "'");
083: normalizedUri = fileURI;
084: this .normalizedUris.put(uri, normalizedUri);
085: break;
086: }
087:
088: final String completePath = ResourceUtils
089: .normalizePath(searchPath + '/'
090: + resourceName);
091:
092: try {
093: InputStream stream;
094: URL url = ResourceUtils.toURL(completePath);
095: if (url != null) {
096: try {
097: stream = url.openStream();
098: stream.close();
099: AndroMDALogger
100: .info("referenced model --> '"
101: + url + "'");
102: } catch (final Exception exception) {
103: url = null;
104: } finally {
105: stream = null;
106: }
107: if (url != null) {
108: normalizedUri = EMFRepositoryFacadeUtils
109: .createUri(url.toString());
110: this .normalizedUris.put(uri,
111: normalizedUri);
112: break;
113: }
114: }
115: } catch (final Exception exception) {
116: logger
117: .debug(
118: "Caught exception in EMFURIConverter",
119: exception);
120: }
121: }
122:
123: // - if the normalized URI isn't part of the module search path,
124: // still store it so we don't continue to look it up each time (which is really slow)
125: if (!this .normalizedUris.containsKey(uri)) {
126: this .normalizedUris.put(uri, normalizedUri);
127: }
128: } else {
129: normalizedUri = (URI) this.normalizedUris.get(uri);
130: }
131: }
132: }
133:
134: return normalizedUri;
135: }
136: }
|