View Javadoc
1   package org.andromda.repositories.emf;
2   
3   import java.io.InputStream;
4   import java.net.URL;
5   import java.util.Date;
6   import java.util.HashMap;
7   import java.util.List;
8   import java.util.Map;
9   import org.andromda.core.common.AndroMDALogger;
10  import org.andromda.core.common.ResourceUtils;
11  import org.apache.log4j.Logger;
12  import org.eclipse.emf.common.util.URI;
13  import org.eclipse.emf.ecore.resource.impl.ExtensibleURIConverterImpl;
14  
15  /**
16   * Extends the default URIConverterImpl to be able to discover the physical path of URIs when
17   * given the moduleSearchPaths.
18   *
19   * @author Chad Brandon
20   * @author Bob Fields
21   */
22  public class EMFURIConverter
23      extends ExtensibleURIConverterImpl
24      // Use URIConverterImpl for UML2 2.x
25  {
26      /**
27       * Creates a new instance of EMFURIConverter taking the <code>moduleSearchPaths</code>
28       * and the existing URI Map as arguments. These are the paths used to attempt to normalize a given URI during
29       * the call to {@link #normalize(URI)} provided that it couldn't be found in the normal manner.
30       *
31       * @param moduleSearchPaths the paths to search for modules.
32       * @param uriMap
33       */
34      public EMFURIConverter(final List<String> moduleSearchPaths, Map<URI, URI> uriMap)
35      {
36          this.normalizedUris = uriMap;
37          this.moduleSearchPaths = moduleSearchPaths;
38          if (logger.isDebugEnabled())
39          {
40              for (final String path : moduleSearchPaths)
41              {
42                  logger.debug("Model search path:" + path);
43              }
44          }
45      }
46  
47      /**
48       * Creates a new instance of EMFURIConverter taking the <code>moduleSearchPaths</code>
49       * as an argument. These are the paths used to attempt to normalize a given URI during
50       * the call to {@link #normalize(URI)} provided that it couldn't be found in the normal manner.
51       *
52       * @param moduleSearchPaths the paths to search for modules.
53       */
54      public EMFURIConverter(final List<String> moduleSearchPaths)
55      {
56          this.moduleSearchPaths = moduleSearchPaths;
57          if (logger.isDebugEnabled())
58          {
59              for (final String path : moduleSearchPaths)
60              {
61                  logger.debug("Model search path:" + path);
62              }
63          }
64      }
65  
66      /**
67       * Stores the module search paths.
68       */
69      private List<String> moduleSearchPaths;
70  
71      /**
72       * Stores the URIs that have been normalized.
73       */
74      private Map<URI, URI> normalizedUris = new HashMap<URI, URI>();
75  
76      /**
77       * The logger instance.
78       */
79      private static final Logger logger = Logger.getLogger(EMFURIConverter.class);
80  
81      /**
82       * Overridden to provide the normalization of uris given the module search paths.
83       *
84       * @see org.eclipse.emf.ecore.resource.URIConverter#normalize(org.eclipse.emf.common.util.URI)
85       */
86      public URI normalize(final URI uri)
87      {
88          URI normalizedUri = super.normalize(uri);
89          if (normalizedUri.equals(uri))
90          {
91              if (this.moduleSearchPaths != null)
92              {
93                  if (!this.normalizedUris.containsKey(uri))
94                  {
95                      final String resourceName = uri.toString().replaceAll(
96                              ".*(\\\\+|/)",
97                              "");
98                      for (final String searchPath : moduleSearchPaths)
99                      {
100                         Date now1 = new Date();
101                         final URI fileURI = EMFRepositoryFacadeUtils.createUri(ResourceUtils.normalizePath(searchPath));
102                         long ms1 = new Date().getTime() - now1.getTime();
103                         if (fileURI != null && fileURI.lastSegment() != null && fileURI.lastSegment().equals(resourceName))
104                         {
105                             String ms = (ms1 > 100 ? ms1 + " ms" : "");
106                             AndroMDALogger.info("referenced model --> '" + fileURI + "' " + ms);
107                             normalizedUri = fileURI;
108                             this.normalizedUris.put(
109                                 uri,
110                                 normalizedUri);
111                             break;
112                         }
113 
114                         final String completePath = ResourceUtils.normalizePath(searchPath + '/' + resourceName);
115 
116                         try
117                         {
118                             Date now = new Date();
119                             InputStream stream;
120                             URL url = ResourceUtils.toURL(completePath);
121                             if (url != null)
122                             {
123                                 try
124                                 {
125                                     stream = url.openStream();
126                                     stream.close();
127                                     long ms2 = new Date().getTime() - now.getTime();
128                                     String ms = (ms2 > 100 ? ms2 + " ms" : "");
129                                     AndroMDALogger.info("referenced model --> '" + url + "' " + ms);
130                                 }
131                                 catch (final Exception exception)
132                                 {
133                                     url = null;
134                                 }
135                                 finally
136                                 {
137                                     stream = null;
138                                 }
139                                 if (url != null)
140                                 {
141                                     long ms2 = new Date().getTime() - now.getTime();
142                                     normalizedUri = EMFRepositoryFacadeUtils.createUri(url.toString());
143                                     this.normalizedUris.put(
144                                         uri,
145                                         normalizedUri);
146                                     if (AndroMDALogger.isDebugEnabled())
147                                     {
148                                         AndroMDALogger.debug("loaded model --> '" + url + "' " + ms2 + " ms");
149                                     }
150                                     break;
151                                 }
152                             }
153                         }
154                         catch (final Exception exception)
155                         {
156                             logger.debug(
157                                 "Caught exception in EMFURIConverter",
158                                 exception);
159                         }
160                         long ms2 = new Date().getTime() - now1.getTime();
161                         String ms = (ms2 > 100 ? ms2 + " ms" : "");
162                         if (AndroMDALogger.isDebugEnabled())
163                         {
164                             AndroMDALogger.debug("loaded model --> '" + fileURI + "' " + ms);
165                         }
166                     }
167 
168                     // - if the normalized URI isn't part of the module search path,
169                     //   still store it so we don't continue to look it up each time (which is really slow)
170                     if (!this.normalizedUris.containsKey(uri))
171                     {
172                         this.normalizedUris.put(
173                             uri,
174                             normalizedUri);
175                     }
176                 }
177                 else
178                 {
179                     normalizedUri = this.normalizedUris.get(uri);
180                 }
181             }
182         }
183 
184         return normalizedUri;
185     }
186 }