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 }