View Javadoc
1   package org.andromda.repositories.emf.uml22;
2   
3   import java.util.Set;
4   import java.util.TreeSet;
5   import org.apache.log4j.Logger;
6   import org.eclipse.emf.common.util.URI;
7   import org.eclipse.emf.ecore.EObject;
8   import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
9   
10  /**
11   * Special resource set implementation that can resolve proxies
12   * created by Rational Software Modeler. RSM uses a special syntax
13   * (e.g. "resource.emx#someXmiId?someNonstandardString") that cannot
14   * be resolved by standard EMF resource sets.
15   *
16   * @author Matthias Bohlen
17   * @author Bob Fields Check for timeouts only once, add logger
18   *
19   */
20  public class EMXProxyResolvingResourceSet extends ResourceSetImpl
21  {
22      /**
23       * The logger instance.
24       */
25      private static final Logger logger = Logger.getLogger(EMXProxyResolvingResourceSet.class);
26  
27      /**
28       *
29       */
30      private static Set<String> connectExceptions = new TreeSet<String>();
31      /**
32       * @see org.eclipse.emf.ecore.resource.impl.ResourceSetImpl#getEObject(org.eclipse.emf.common.util.URI, boolean)
33       */
34      public EObject getEObject(URI uri, boolean loadOnDemand)
35      {
36          EObject possiblyResolvedObject = null;
37          // We see ConnectExceptions when loading metamodels behind a proxy server. Don't try more than once.
38          // No need to validate external schema elements, it's just a performance drag.
39          if (connectExceptions.contains(uri.toString()))
40          {
41              return possiblyResolvedObject;
42          }
43          long now = System.currentTimeMillis();
44          try
45          {
46              // Allow both UML2 v2 and v3+ profile references. Changed from Standard.profile.uml to StandardL2.profile.uml and StandardL3.profile.uml in v3
47              //if (uri.toString().contains("Standard.profile.uml"))
48              //{
49                  /*String newUri = uri.toString().replace("Standard.profile.uml", "StandardL2.profile.uml");
50                  possiblyResolvedObject = super.getEObject(URI.createURI(newUri), loadOnDemand);*/
51                  //uri = URI.createURI(uri.toString().replace("Standard.profile.uml", "StandardL3.profile.uml"));
52              //}
53              possiblyResolvedObject = super.getEObject(uri, loadOnDemand);
54          }
55          catch (Exception e)
56          {
57              // This will point out invalid model references....
58              if (uri.toString().indexOf('?')<0)
59              {
60                  if (e.getMessage().contains("FileNotFoundException"))
61                  {
62                      // MagicDraw and Standard Profiles generally not needed, exporting them takes lots of space
63                      // Don't need entire stack trace if referenced file is not found, message is enough.
64                      logger.warn("Referenced model FileNotFound: " + uri + " " + (System.currentTimeMillis() - now) + " ms: " +
65                              uri.toString() + " " + (e.getCause() != null ? e.getCause().getMessage() : e.getMessage()));
66                  }
67                  else
68                  {
69                      logger.error("Could not load referenced model uri " + " " + (System.currentTimeMillis() - now) + "ms: " +
70                              uri.toString() + " " + (e.getCause() != null ? e.getCause().getMessage() : e.getMessage()), e.getCause());
71                  }
72              }
73              if (!connectExceptions.contains(uri.toString()))
74              {
75                  connectExceptions.add(uri.toString());
76              }
77          }
78          if (possiblyResolvedObject == null)
79          {
80              // if it is still a proxy, try this special fix for RSM:
81              String uriString = uri.toString();
82              int separatorIndex = uriString.lastIndexOf('?');
83              if (separatorIndex > 0)
84              {
85                  uriString = uriString.substring(0, separatorIndex);
86                  if (!connectExceptions.contains(uriString))
87                  {
88                      try
89                      {
90                          possiblyResolvedObject = super.getEObject(URI.createURI(uriString), loadOnDemand);
91                      }
92                      catch (Exception e)
93                      {
94                          // No need to log this - it doesn't matter for andromda anyway.
95                          //logger.warn("ConnectException "  + (System.currentTimeMillis() - now) + "ms for uri " + uriString);
96                          if (!connectExceptions.contains(uriString))
97                          {
98                              connectExceptions.add(uri.toString());
99                          }
100                     }
101                 }
102             }
103         }
104         return possiblyResolvedObject;
105     }
106 }