View Javadoc

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          // configure MDR to use an in-memory storage implementation
33          System.setProperty(
34              "org.netbeans.mdr.storagemodel.StorageFactoryClassName",
35              "org.netbeans.mdr.persistence.memoryimpl.StorageFactoryImpl");
36          // set the logging so output does not go to standard out
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          // the default metamodel is now UML 1.4 plus UML 2.0 diagram extensions
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             // perhaps there should be a corresponding close
141             // to match the open.
142             // But, where is the close in the URL API?
143         }
144         catch (IOException ioe)
145         {
146             // log and then eat the exception
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         // Use the metaModelURL as the name for the repository extent.
179         // This ensures we can load mutiple metamodels without them colliding.
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             // locate the UML package definition that was just loaded in
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     private static RefPackage loadModel(
222         URL modelURL,
223         MofPackage metaModel,
224         MDRepository repository)
225         throws CreationFailedException, IOException, MalformedXMIException
226     {
227         log("MDR: creating Model");
228 
229         RefPackage model = repository.getExtent("MODEL");
230         if (model != null)
231         {
232             log("MDR: deleting exising model");
233             model.refDelete();
234         }
235 
236         log("MDR: creating model extent");
237         model = repository.createExtent("MODEL", metaModel);
238         log("MDR: created model extent");
239 
240         XMIReader xmiReader = XMIReaderFactory.getDefault().createXMIReader();
241 
242         log("MDR: reading XMI - " + modelURL.toExternalForm());
243         try
244         {
245             xmiReader.read(modelURL.toExternalForm(), model);
246         }
247         catch (Exception e)
248         {
249             e.printStackTrace();
250             throw new IOException("could not read XMI");
251         }
252         log("MDR: read XMI ");
253 
254         log("MDR: created Model");
255         return model;
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     // A method used to do logging.
369     // Currently stubbed out until a logging technology is selected.
370     static private void log(Object object)
371     {
372         //System.out.println("log: " + (String) object);
373     }
374 }