001: package org.andromda.maven.plugin;
002:
003: import java.io.File;
004: import java.io.InputStream;
005: import java.net.MalformedURLException;
006: import java.net.URL;
007: import java.text.Format;
008: import java.text.SimpleDateFormat;
009: import java.util.Date;
010: import java.util.List;
011:
012: import org.andromda.core.common.ResourceUtils;
013: import org.andromda.core.configuration.Configuration;
014: import org.andromda.core.configuration.Model;
015: import org.andromda.core.configuration.Repository;
016: import org.apache.maven.plugin.MojoExecutionException;
017:
018: import org.apache.commons.lang.StringUtils;
019:
020: /**
021: * Exports the MagicDraw project file to EMF XMI
022: * (requires valid MagicDraw installation in MD_HOME, but
023: * only if target files are not up-to-date)
024: *
025: * @goal export2emf
026: * @phase generate-sources
027: * @author Jens Vagts
028: */
029: public class MagicDrawExportEMFXMIMojo extends AbstractAndroMDAMojo {
030: /**
031: * Name of the environment variable pointing to the MagicDraw home directory
032: */
033: private final String MD_HOME = "MD_HOME";
034:
035: /**
036: * The home/root directory of the magicdraw installation.
037: *
038: * @parameter expression="${magicDrawHome}"
039: */
040: private String magicDrawHome;
041:
042: /**
043: * @see org.andromda.maven.plugin.AbstractAndroMDAMojo#execute(org.andromda.core.configuration.Configuration)
044: */
045: public void execute(final Configuration configuration)
046: throws MojoExecutionException {
047: try {
048: //export each file (uri) of each model in each repository
049: final Repository[] repositories = configuration
050: .getRepositories();
051: if (repositories == null || repositories.length == 0) {
052: getLog()
053: .info(
054: "No repositories for export in configuration defined.");
055: return;
056: }
057: int repositoryCount = repositories.length;
058: for (int ctr = 0; ctr < repositoryCount; ctr++) {
059: final Repository repository = repositories[ctr];
060: if (repository != null) {
061: final Model[] models = repository.getModels();
062: final int modelCount = models.length;
063: for (int ctr2 = 0; ctr2 < modelCount; ctr2++) {
064: final Model model = models[ctr2];
065: if ("emf-uml2".equals(model.getType())) {
066: String[] uris = model.getUris();
067: for (int u = 0; u < uris.length; u++) {
068: exportFile(uris[u]);
069: }
070: }
071: }
072: }
073: }
074:
075: } catch (Throwable throwable) {
076: throw new MojoExecutionException(
077: "Error exporting MagicDraw project file to EMF XMI",
078: throwable);
079: }
080: }
081:
082: private void exportFile(String dest) throws Exception {
083: final String UML2EXT = ".uml2";
084: final String MDEXT1 = ".xml.zip";
085: final String MDEXT2 = ".mdzip";
086:
087: //get the source file name from the destination name (we expect xml.zip)
088: if (!dest.endsWith(UML2EXT)) {
089: getLog()
090: .warn(
091: "Ignoring model file "
092: + dest
093: + ", since it seems not to be of type 'uml2'");
094: return;
095: }
096:
097: //check for first MD extension
098: //(use URL.getFile() to get rid of spaces in file name)
099: 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(
105: "Invalid source model file name [" + source + "]: "
106: + e.getMessage());
107: }
108:
109: //check for for second MD extension
110: File sourceFile = new File(sourceUrl.getFile());
111: if (sourceFile == null || !sourceFile.exists()) {
112: source = StringUtils.replace(dest, UML2EXT, MDEXT2);
113: try {
114: sourceUrl = new URL(ResourceUtils.normalizePath(source));
115: } catch (MalformedURLException e) {
116: throw new MojoExecutionException(
117: "Invalid source model file name [" + source
118: + "]: " + e.getMessage());
119: }
120: }
121: sourceFile = new File(sourceUrl.getFile());
122: if (sourceFile == null || !sourceFile.exists()) {
123: throw new MojoExecutionException("Model file [" + source
124: + "] does not exist");
125: }
126:
127: //check for destination (emf) file
128: URL destUrl = null;
129: try {
130: destUrl = new URL(ResourceUtils.normalizePath(dest));
131: } catch (MalformedURLException e) {
132: throw new MojoExecutionException(
133: "Invalid destination model file name [" + dest
134: + "]: " + e.getMessage());
135: }
136:
137: File destFile = new File(destUrl.getFile());
138: if (destFile == null || !destFile.exists()) {
139: getLog().debug("No old model file [" + dest + "] existing");
140: } else {
141: if (getLog().isDebugEnabled()) {
142: Format formatter = new SimpleDateFormat(
143: "yyyy-MM-dd HH:mm:ss");
144: getLog().debug(
145: "- MagicDraw model file ["
146: + sourceFile.getName()
147: + "] date = "
148: + formatter.format(new Date(sourceFile
149: .lastModified())));
150: getLog().debug(
151: "- EMF model file ["
152: + destFile.getName()
153: + "] date = "
154: + formatter.format(new Date(destFile
155: .lastModified())));
156: }
157: if (destFile.lastModified() >= sourceFile.lastModified()) {
158: getLog()
159: .info("Model file [" + dest + "] is up-to-date");
160: return;
161: }
162: }
163:
164: //check for valid magic draw installation
165: checkForMagicDraw();
166:
167: //perform the export via MagicDraw
168: getLog().info("Exporting model file [" + source + "] ...");
169: String command = "\"" + exporterPath + "\""
170: + " project_file=\"" + sourceFile.getPath() + "\""
171: + " destination_dir=\"" + sourceFile.getParent() + "\""
172: + " load_all_modules=true";
173: Process process = Runtime.getRuntime().exec(command);
174:
175: //since at least the windows version forks the magicdraw process,
176: //we have to synchronize via input stream reading
177: InputStream is = process.getInputStream();
178: final byte[] buf = new byte[128];
179: int length;
180: while ((length = is.read(buf)) > 0) {
181: getLog().info(new String(buf, 0, length));
182: }
183: process.waitFor();
184: process.destroy();
185: int err = process.exitValue();
186: if (err != 0) {
187: throw new MojoExecutionException(
188: "MagicDraw export returned error code " + err);
189: }
190: getLog().info("Successfully exported model file.");
191: }
192:
193: /**
194: * only check once for magic draw installation
195: */
196: private boolean checkedMagicDraw = false;
197:
198: /**
199: * The export executeable file extension (.exe for Windows, nothing for *ix)
200: */
201: private String exportExt = "";
202:
203: /**
204: * The full path name to the exporter plugin executeable
205: */
206: private String exporterPath;
207:
208: private void checkForMagicDraw() throws MojoExecutionException {
209: if (!checkedMagicDraw) {
210: if (magicDrawHome == null) {
211: magicDrawHome = System.getenv(MD_HOME);
212: }
213:
214: if (magicDrawHome == null) {
215: throw new MojoExecutionException(
216: "MagicDraw home directory not defined: please define either a configuration variable \"magicDrawHome\" in your pom or the environment variable \""
217: + MD_HOME + "\"!");
218: }
219:
220: File home = new File(magicDrawHome);
221: if (home == null || !home.exists()) {
222: throw new MojoExecutionException(
223: "Invalid MagicDraw home directory specified: "
224: + magicDrawHome);
225: }
226:
227: //check for running os
228: String os = System.getProperty("os.name");
229: if (os.indexOf("Windows") != -1) {
230: exportExt = ".exe";
231: }
232:
233: //check for plugin name (has changed from MD 11.5 to 11.6)
234: String pluginName115 = "com.nomagic.magicdraw.emfuml2export";
235: String pluginName116 = "com.nomagic.magicdraw.emfuml2xmi";
236: exporterPath = magicDrawHome + File.separator + "plugins"
237: + File.separator + pluginName116 + File.separator
238: + "exportEMFXMI" + exportExt;
239: File exporter = new File(exporterPath);
240: if (exporter == null || !exporter.exists()) {
241: exporterPath = magicDrawHome + File.separator
242: + "plugins" + File.separator + pluginName115
243: + File.separator + "exportEMFXMI" + exportExt;
244: }
245:
246: exporter = new File(exporterPath);
247: if (exporter == null || !exporter.exists()) {
248: throw new MojoExecutionException(
249: "No exporter plugin found in MagicDraw home directory "
250: + magicDrawHome);
251: }
252:
253: checkedMagicDraw = true;
254: }
255: }
256: }
|