1 package org.andromda.core.mdr;
2
3 import java.io.IOException;
4 import java.net.URL;
5 import java.net.URLConnection;
6 import java.util.Iterator;
7
8 import javax.jmi.model.ModelPackage;
9 import javax.jmi.model.MofPackage;
10 import javax.jmi.reflect.RefPackage;
11 import javax.jmi.xmi.MalformedXMIException;
12
13 import org.andromda.core.common.RepositoryFacade;
14 import org.andromda.core.common.RepositoryReadException;
15 import org.netbeans.api.mdr.CreationFailedException;
16 import org.netbeans.api.mdr.MDRManager;
17 import org.netbeans.api.mdr.MDRepository;
18 import org.netbeans.api.xmi.XMIReader;
19 import org.netbeans.api.xmi.XMIReaderFactory;
20
21 /***
22 * Implements an AndroMDA object model repository by using the
23 * <a href="http://mdr.netbeans.org">NetBeans MetaDataRepository</a>.
24 *
25 * @author <A HREF="http://www.amowers.com">Anthony Mowers</A>
26 */
27 public class MDRepositoryFacade implements RepositoryFacade
28 {
29 protected final static String META_PACKAGE = "UML";
30
31 static {
32
33 System.setProperty(
34 "org.netbeans.mdr.storagemodel.StorageFactoryClassName",
35 "org.netbeans.mdr.persistence.memoryimpl.StorageFactoryImpl");
36
37 System.setProperty("org.netbeans.lib.jmi.Logger.fileName", "mdr.log");
38 };
39
40 protected URL metaModelURL;
41 protected URL modelURL;
42 protected RefPackage model;
43
44 /***
45 * Constructs a Facade around a netbeans MDR (MetaDataRepository).
46 */
47 public MDRepositoryFacade()
48 {
49
50 metaModelURL =
51 MDRepositoryFacade.class.getResource("/M2_DiagramInterchangeModel.xml");
52
53 modelURL = null;
54 model = null;
55 }
56
57 /***
58 * Opens the reposistory and prepares it to read in models.
59 *
60 * <p> All the file reads are done within the context of a transaction
61 * this seems to speed up the processing. </p>
62 *
63 * @see org.andromda.core.common.RepositoryFacade#open()
64 */
65 public void open()
66 {
67 MDRManager.getDefault().getDefaultRepository().beginTrans(true);
68 }
69
70 /***
71 * Closes the repository and reclaims all resources.
72 *
73 * <p> This should only be called after all the models has been read and all querys
74 * have completed. </p>
75 *
76 * @see org.andromda.core.common.RepositoryFacade#close()
77 */
78 public void close()
79 {
80 MDRManager.getDefault().getDefaultRepository().endTrans(true);
81 }
82
83 /***
84 * @see org.andromda.core.common.RepositoryFacade#readModel(URL)
85 */
86 public void readModel(URL modelURL, String[] moduleSearchPath)
87 throws RepositoryReadException, IOException
88 {
89 log("MDR: creating repository");
90
91 this.modelURL = modelURL;
92
93 MDRepository repository =
94 MDRManager.getDefault().getDefaultRepository();
95
96 try
97 {
98 MofPackage metaModel = loadMetaModel(metaModelURL, repository);
99
100 this.model = loadModel(modelURL, moduleSearchPath, metaModel, repository);
101 }
102 catch (CreationFailedException cfe)
103 {
104 throw new RepositoryReadException(
105 "unable to create metadata repository",
106 cfe);
107 }
108 catch (MalformedXMIException mxe)
109 {
110 throw new RepositoryReadException("malformed XMI data", mxe);
111 }
112 finally {
113 }
114
115 log("MDR: created repository");
116 }
117
118
119 /***
120 * @see org.andromda.core.common.RepositoryFacade#readModel(URL)
121 */
122 public void readModel(URL modelURL)
123 throws RepositoryReadException, IOException
124 {
125 String[] moduleSearchPath = { "modules", "profiles" };
126 readModel(modelURL, moduleSearchPath);
127 }
128
129 /***
130 * @see org.andromda.core.common.RepositoryFacade#getLastModified()
131 */
132 public long getLastModified()
133 {
134 long lastModified = 0;
135
136 try
137 {
138 URLConnection urlConnection = modelURL.openConnection();
139 lastModified = urlConnection.getLastModified();
140
141
142
143 }
144 catch (IOException ioe)
145 {
146
147 log(ioe);
148 }
149
150 return lastModified;
151 }
152
153 /***
154 * @see org.andromda.core.common.RepositoryFacade#getModel()
155 */
156 public Object getModel()
157 {
158 return this.model;
159 }
160
161 /***
162 * Loads a metamodel into the repository.
163 *
164 *@param repository MetaDataRepository
165 *@return MofPackage for newly loaded metamodel
166 *
167 *@exception CreationFailedException
168 *@exception IOException
169 *@exception MalformedXMIException
170 */
171 private static MofPackage loadMetaModel(
172 URL metaModelURL,
173 MDRepository repository)
174 throws CreationFailedException, IOException, MalformedXMIException
175 {
176 log("MDR: creating MetaModel using URL =" + metaModelURL.toExternalForm());
177
178
179
180 ModelPackage metaModelExtent =
181 (ModelPackage) repository.getExtent(metaModelURL.toExternalForm());
182
183 if (metaModelExtent == null)
184 {
185 metaModelExtent =
186 (ModelPackage) repository.createExtent(
187 metaModelURL.toExternalForm());
188 }
189
190 MofPackage metaModelPackage =
191 findPackage(META_PACKAGE, metaModelExtent);
192
193 if (metaModelPackage == null)
194 {
195 XMIReader xmiReader =
196 XMIReaderFactory.getDefault().createXMIReader();
197 xmiReader.read(metaModelURL.toExternalForm(),metaModelExtent);
198
199
200 metaModelPackage = findPackage(META_PACKAGE, metaModelExtent);
201 }
202
203 log("MDR: created MetaModel");
204 return metaModelPackage;
205 }
206
207 /***
208 * Loads a model into the repository and validates the model against
209 * the given metaModel.
210 *
211 *@param modelURL url of model
212 *@param repository netbeans MDR
213 *@param metaModel meta model of model
214 *@return populated model
215 *
216 *@exception CreationFailedException unable to create model in repository
217 *@exception IOException unable to read model
218 *@exception MalformedXMIException model violates metamodel
219 */
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259 /***
260 * Loads a model into the repository and validates the model against the
261 * given metaModel.
262 *
263 * @param modelURL url of model
264 * @param repository netbeans MDR
265 * @param metaModel meta model of model
266 * @return populated model
267 * @exception CreationFailedException unable to create model in repository
268 */
269 private static RefPackage loadModel(
270 URL modelURL,
271 MofPackage metaModel,
272 MDRepository repository)
273 throws CreationFailedException
274 {
275 String[] moduleSearchPath = { "modules" };
276 return loadModel(modelURL, moduleSearchPath, metaModel, repository);
277 }
278
279
280 /***
281 * The name (unique within the repository) for the new package extent
282 */
283 private static final String EXTENT_NAME = "MODEL";
284
285 /***
286 * Loads a model into the repository and validates the model against the
287 * given metaModel.
288 *
289 * @param modelURL url of model
290 * @param repository netbeans MDR
291 * @param metaModel meta model of model
292 * @return populated model
293 * @exception CreationFailedException unable to create model in repository
294 */
295 private static RefPackage loadModel(
296 URL modelURL,
297 String[] moduleSearchPath,
298 MofPackage metaModel,
299 MDRepository repository)
300 throws CreationFailedException
301 {
302 log("creating model");
303
304 RefPackage model = repository.getExtent(EXTENT_NAME);
305 if (model == null)
306 {
307 log("creating the new meta model");
308 model = repository.createExtent(EXTENT_NAME, metaModel);
309 }
310
311 log("creating model extent");
312 log("created model extent");
313
314 log("module search path: " + moduleSearchPath[0]);
315
316
317 XMIReader xmiReader =
318 XMIReaderFactory.getDefault().createXMIReader(
319 new MDRXmiReferenceResolver(
320 new RefPackage[] { model }, moduleSearchPath));
321
322 log("reading model XMI --> '" + modelURL + "'");
323
324 try
325 {
326 xmiReader.read(modelURL.toExternalForm(), model);
327 }
328 catch (Throwable th)
329 {
330 String errMsg = "Error performing MDRepository.loadModel";
331 log(errMsg + th);
332 throw new CreationFailedException(errMsg);
333 }
334 log("read XMI and created model");
335 return model;
336 }
337
338
339
340 /***
341 * Searches a meta model for the specified package.
342 *
343 *@param packageName name of package for which to search
344 *@param metaModel meta model to search
345 *@return MofPackage
346 */
347 private static MofPackage findPackage(
348 String packageName,
349 ModelPackage metaModel)
350 {
351 for (Iterator it = metaModel.getMofPackage().refAllOfClass().iterator();
352 it.hasNext();
353 )
354 {
355 javax.jmi.model.ModelElement temp =
356 (javax.jmi.model.ModelElement) it.next();
357
358 >if (temp.getName().equals(packageName))
359 {
360 return (MofPackage) temp;
361 }
362 }
363
364 return null;
365 }
366
367
368
369
370 static private void log(Object object)
371 {
372
373 }
374 }