View Javadoc
1   package org.andromda.maven.plugin;
2   
3   import java.io.File;
4   import java.io.InputStream;
5   import java.net.MalformedURLException;
6   import java.net.URL;
7   import java.text.Format;
8   import java.text.SimpleDateFormat;
9   import java.util.Date;
10  import org.andromda.core.common.ResourceUtils;
11  import org.andromda.core.configuration.Configuration;
12  import org.andromda.core.configuration.Model;
13  import org.andromda.core.configuration.Repository;
14  import org.apache.commons.lang.StringUtils;
15  import org.apache.maven.plugin.MojoExecutionException;
16  
17  /**
18   * Exports the MagicDraw project file to EMF XMI
19   * (requires valid MagicDraw installation in MD_HOME, but
20   * only if target files are not up-to-date)
21   *
22   * @goal export2emf
23   * @phase generate-sources
24   * @author Jens Vagts
25   */
26  public class MagicDrawExportEMFXMIMojo
27      extends AbstractAndroMDAMojo
28  {
29      /**
30       * Name of the environment variable pointing to the MagicDraw home directory
31       */
32      private final String MD_HOME = "MD_HOME";
33  
34      /**
35       * The home/root directory of the magicdraw installation.
36       *
37       * @parameter expression="${magicDrawHome}"
38       */
39      private String magicDrawHome;
40  
41      /**
42       * @see org.andromda.maven.plugin.AbstractAndroMDAMojo#execute(org.andromda.core.configuration.Configuration)
43       */
44      public void execute(final Configuration configuration)
45          throws MojoExecutionException
46      {
47          try
48          {
49              //export each file (uri) of each model in each repository
50              final Repository[] repositories = configuration.getRepositories();
51              if (repositories == null || repositories.length == 0) {
52                  getLog().info("No repositories for export in configuration defined.");
53                  return;
54              }
55              int repositoryCount = repositories.length;
56              for (int ctr = 0; ctr < repositoryCount; ctr++)
57              {
58                  final Repository repository = repositories[ctr];
59                  if (repository != null)
60                  {
61                      final Model[] models = repository.getModels();
62                      final int modelCount = models.length;
63                      for (int ctr2 = 0; ctr2 < modelCount; ctr2++)
64                      {
65                          final Model model = models[ctr2];
66                          if ("emf-uml2".equals(model.getType()))
67                          {
68                              String[] uris = model.getUris();
69                              for (int u = 0; u < uris.length; u++)
70                              {
71                                  exportFile(uris[u]);
72                              }
73                          }
74                      }
75                  }
76              }
77  
78          }
79          catch (Throwable throwable)
80          {
81              throw new MojoExecutionException("Error exporting MagicDraw project file to EMF XMI", throwable);
82          }
83      }
84  
85      private void exportFile(String dest) throws Exception {
86          final String UML2EXT = ".uml2";
87          final String MDEXT1 = ".xml.zip";
88          final String MDEXT2 = ".mdzip";
89  
90          //get the source file name from the destination name (we expect xml.zip)
91          if (!dest.endsWith(UML2EXT))
92          {
93              getLog().warn("Ignoring model file " + dest + ", since it seems not to be of type 'uml2'");
94              return;
95          }
96  
97          //check for first MD extension
98          //(use URL.getFile() to get rid of spaces in file name)
99          String source = StringUtils.replace(dest, UML2EXT, MDEXT1);
100         URL sourceUrl = null;
101         try {
102             sourceUrl = new URL(ResourceUtils.normalizePath(source));
103         } catch (MalformedURLException e) {
104             throw new MojoExecutionException("Invalid source model file name [" + source + "]: " + e.getMessage());
105         }
106 
107         //check for for second MD extension
108         File sourceFile = new File(sourceUrl.getFile());
109         if (!sourceFile.exists())
110         {
111             source = StringUtils.replace(dest, UML2EXT, MDEXT2);
112             try {
113                 sourceUrl = new URL(ResourceUtils.normalizePath(source));
114             } catch (MalformedURLException e) {
115                 throw new MojoExecutionException("Invalid source model file name [" + source + "]: " + e.getMessage());
116             }
117         }
118         sourceFile = new File(sourceUrl.getFile());
119         if (!sourceFile.exists())
120         {
121             throw new MojoExecutionException("Model file [" + source + "] does not exist");
122         }
123 
124         //check for destination (emf) file
125         URL destUrl = null;
126         try {
127             destUrl = new URL(ResourceUtils.normalizePath(dest));
128         } catch (MalformedURLException e) {
129             throw new MojoExecutionException("Invalid destination model file name [" + dest + "]: " + e.getMessage());
130         }
131 
132         File destFile = new File(destUrl.getFile());
133         if (!destFile.exists())
134         {
135             getLog().debug("No old model file [" + dest + "] existing");
136         }
137         else
138         {
139             if (getLog().isDebugEnabled())
140             {
141                 Format formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
142                 getLog().debug("- MagicDraw model file ["+sourceFile.getName()+"] date = " + formatter.format(new Date(sourceFile.lastModified())));
143                 getLog().debug("- EMF model file ["+destFile.getName()+"] date = " + formatter.format(new Date(destFile.lastModified())));
144             }
145             if (destFile.lastModified() >= sourceFile.lastModified())
146             {
147                 getLog().info("Model file [" + dest + "] is up-to-date");
148                 return;
149             }
150         }
151 
152         //check for valid magic draw installation
153         checkForMagicDraw();
154 
155         //perform the export via MagicDraw
156         getLog().info("Exporting model file [" + source + "] ...");
157         String command = '\"' + exporterPath + '\"'
158                 + " project_file=\"" + sourceFile.getPath() + '\"'
159                 + " destination_dir=\"" + sourceFile.getParent() + '\"'
160                 + " load_all_modules=true";
161         Process process = Runtime.getRuntime().exec(command);
162 
163         //since at least the windows version forks the magicdraw process,
164         //we have to synchronize via input stream reading
165         InputStream is = process.getInputStream();
166         final byte[] buf = new byte[128];
167         int length;
168         while ((length = is.read(buf)) > 0)
169         {
170             getLog().info(new String(buf, 0, length));
171         }
172         process.waitFor();
173         process.destroy();
174         int err = process.exitValue();
175         if (err != 0)
176         {
177             throw new MojoExecutionException("MagicDraw export returned error code " + err);
178         }
179         getLog().info("Successfully exported model file.");
180     }
181 
182     /**
183      * only check once for magic draw installation
184      */
185     private boolean checkedMagicDraw = false;
186 
187     /**
188      * The export executable file extension (.exe for Windows, nothing for *ix)
189      */
190     private String exportExt = "";
191 
192     /**
193      * The full path name to the exporter plugin executable
194      */
195     private String exporterPath;
196 
197     private void checkForMagicDraw() throws MojoExecutionException
198     {
199         if (!checkedMagicDraw)
200         {
201             if (magicDrawHome == null)
202             {
203                 magicDrawHome = System.getenv(MD_HOME);
204             }
205 
206             if (magicDrawHome == null)
207             {
208                 throw new MojoExecutionException("MagicDraw home directory not defined: please define either a configuration variable \"magicDrawHome\" in your pom or the environment variable \""+ MD_HOME + "\"!");
209             }
210 
211             File home = new File(magicDrawHome);
212             if (!home.exists())
213             {
214                 throw new MojoExecutionException("Invalid MagicDraw home directory specified: " + magicDrawHome);
215             }
216 
217             //check for running os
218             String os = System.getProperty("os.name");
219             if (os.contains("Windows"))
220             {
221                 exportExt = ".exe";
222             }
223 
224             //check for plugin name (has changed from MD 11.5 to 11.6)
225             String pluginName115 = "com.nomagic.magicdraw.emfuml2export";
226             String pluginName116 = "com.nomagic.magicdraw.emfuml2xmi";
227             String pluginName15 = "com.nomagic.magicdraw.emfuml2xmi_v1";
228             exporterPath = magicDrawHome
229             + File.separator + "plugins"
230             + File.separator + pluginName15
231             + File.separator + "exportEMFXMI" + exportExt;
232             File exporter = new File(exporterPath);
233             if (!exporter.exists())
234             {
235                 exporterPath = magicDrawHome
236                     + File.separator + "plugins"
237                     + File.separator + pluginName116
238                     + File.separator + "exportEMFXMI" + exportExt;
239                 exporter = new File(exporterPath);
240                 if (!exporter.exists())
241                 {
242                     exporterPath = magicDrawHome
243                     + File.separator + "plugins"
244                     + File.separator + pluginName115
245                     + File.separator + "exportEMFXMI" + exportExt;
246                 }
247             }
248 
249             exporter = new File(exporterPath);
250             if (!exporter.exists())
251             {
252                 throw new MojoExecutionException("No exporter plugin found in MagicDraw home directory " + magicDrawHome);
253             }
254 
255             checkedMagicDraw = true;
256         }
257     }
258 }