1 package org.andromda.repositories.mdr;
2
3 import java.io.File;
4 import java.io.InputStream;
5 import java.net.MalformedURLException;
6 import java.net.URL;
7 import java.util.ArrayList;
8 import java.util.Collection;
9 import java.util.HashMap;
10 import java.util.Map;
11 import javax.jmi.reflect.RefPackage;
12 import org.andromda.core.common.AndroMDALogger;
13 import org.andromda.core.common.ResourceUtils;
14 import org.apache.commons.lang.StringUtils;
15 import org.apache.log4j.Logger;
16 import org.netbeans.api.xmi.XMIInputConfig;
17 import org.netbeans.lib.jmi.xmi.XmiContext;
18
19
20
21
22
23
24
25
26
27 public class MDRXmiReferenceResolverContext
28 extends XmiContext
29 {
30 private String[] moduleSearchPaths;
31 private static final Logger logger = Logger.getLogger(MDRXmiReferenceResolverContext.class);
32 private static final Map<String, URL> urlMap = new HashMap<String, URL>();
33
34
35
36
37
38
39
40
41 public MDRXmiReferenceResolverContext(
42 RefPackage[] extents,
43 XMIInputConfig config,
44 String[] moduleSearchPaths)
45 {
46 super(extents, config);
47 this.moduleSearchPaths = moduleSearchPaths;
48 }
49
50
51
52
53 public URL toURL(final String systemId)
54 {
55 if (logger.isDebugEnabled())
56 {
57 logger.debug("attempting to resolve Xmi Href --> '" + systemId + '\'');
58 }
59
60 final String suffix = this.getSuffix(systemId);
61
62
63
64 String exts = "\\.jar|\\.zip";
65 String suffixWithExt = suffix.replaceAll(exts, "");
66 URL modelUrl = urlMap.get(suffixWithExt);
67
68
69 if (modelUrl == null)
70 {
71
72 modelUrl = this.getValidURL(systemId);
73 if (modelUrl == null)
74 {
75
76 final String modelUrlAsString = this.findModuleUrl(suffix);
77 if (StringUtils.isNotBlank(modelUrlAsString))
78 {
79 modelUrl = this.getValidURL(modelUrlAsString);
80 }
81 if (modelUrl == null)
82 {
83
84 modelUrl = this.findModelUrlOnClasspath(systemId);
85 }
86 if (modelUrl == null)
87 {
88
89 modelUrl = super.toURL(systemId);
90 }
91 }
92
93
94
95
96 if (modelUrl != null)
97 {
98 urlMap.put(suffixWithExt, modelUrl);
99 }
100 }
101 if (modelUrl != null && !this.loggedReferencedModels.contains(modelUrl))
102 {
103 AndroMDALogger.info("referenced model --> '" + modelUrl + '\'');
104 this.loggedReferencedModels.add(modelUrl);
105 }
106 return modelUrl;
107 }
108
109
110
111
112 private final Collection<URL> loggedReferencedModels = new ArrayList<URL>();
113
114
115
116
117
118
119
120 private final String findModuleUrl(final String moduleName)
121 {
122 String moduleUrl = null;
123 if (this.moduleSearchPaths != null)
124 {
125 if (logger.isDebugEnabled())
126 {
127 logger.debug("findModuleURL: moduleSearchPath.length=" + moduleSearchPaths.length);
128 }
129 for (int ctr = 0; ctr < moduleSearchPaths.length; ctr++)
130 {
131 final String moduleSearchPath = moduleSearchPaths[ctr];
132 if (StringUtils.isNotBlank(moduleSearchPath))
133 {
134 if (moduleSearchPath.endsWith(moduleName))
135 {
136 moduleUrl = moduleSearchPath;
137 }
138 else
139 {
140 final File candidate = new File(moduleSearchPath, moduleName);
141 if (logger.isDebugEnabled())
142 {
143 logger.debug("candidate '" + candidate.toString() + "' exists=" + candidate.exists());
144 }
145 if (candidate.exists())
146 {
147 try
148 {
149 moduleUrl = candidate.toURI().toURL().toExternalForm();
150 }
151 catch (final MalformedURLException exception)
152 {
153
154 }
155 }
156 }
157 if (moduleUrl != null && moduleName.endsWith(".zip") || moduleName.endsWith(".jar"))
158 {
159
160 moduleUrl = "jar:" + moduleUrl + "!/" + moduleName.substring(0, moduleName.length() - 4);
161 }
162
163 if (StringUtils.isNotBlank(moduleUrl))
164 {
165 break;
166 }
167 }
168 }
169 }
170 return moduleUrl;
171 }
172
173
174
175
176
177
178
179 private final String getSuffix(String systemId)
180 {
181 int lastSlash = systemId.lastIndexOf('/');
182 if (lastSlash > 0)
183 {
184 String suffix = systemId.substring(lastSlash + 1);
185 return suffix;
186 }
187 return systemId;
188 }
189
190
191
192
193 protected static final String[] CLASSPATH_MODEL_SUFFIXES = new String[] {"xml", "xmi"};
194
195
196
197
198
199
200
201 private final URL findModelUrlOnClasspath(final String systemId)
202 {
203 String modelName = StringUtils.substringAfterLast(systemId, "/");
204 String dot = ".";
205
206
207
208 modelName = StringUtils.substringBeforeLast(modelName, dot);
209
210 URL modelUrl = null;
211 if (StringUtils.isNotBlank(modelName))
212 {
213 modelUrl = ResourceUtils.getResource(modelName);
214 if (modelUrl == null)
215 {
216 if (CLASSPATH_MODEL_SUFFIXES != null && CLASSPATH_MODEL_SUFFIXES.length > 0)
217 {
218 int suffixNum = CLASSPATH_MODEL_SUFFIXES.length;
219 for (int ctr = 0; ctr < suffixNum; ctr++)
220 {
221 if (logger.isDebugEnabled())
222 {
223 logger.debug("searching for model reference --> '" + modelUrl + '\'');
224 }
225 String suffix = CLASSPATH_MODEL_SUFFIXES[ctr];
226 modelUrl = ResourceUtils.getResource(modelName + dot + suffix);
227 if (modelUrl != null)
228 {
229 break;
230 }
231 }
232 }
233 }
234 }
235 return modelUrl;
236 }
237
238
239
240
241
242
243
244 private final URL getValidURL(final String systemId)
245 {
246 InputStream stream = null;
247 URL url = null;
248 try
249 {
250 url = new URL(systemId);
251 stream = url.openStream();
252 stream.close();
253 }
254 catch (final Exception exception)
255 {
256 url = null;
257 }
258 finally
259 {
260 stream = null;
261 }
262 return url;
263 }
264 }