View Javadoc
1   package org.andromda.maven.plugin.modelarchiver;
2   
3   import java.io.File;
4   import java.io.FileInputStream;
5   import java.io.FileOutputStream;
6   import java.io.IOException;
7   import java.util.zip.ZipEntry;
8   import java.util.zip.ZipOutputStream;
9   import org.apache.commons.io.FileUtils;
10  import org.apache.commons.io.FilenameUtils;
11  import org.apache.commons.io.IOUtils;
12  import org.apache.maven.plugin.MojoExecutionException;
13  import org.codehaus.plexus.archiver.ArchiverException;
14  import org.codehaus.plexus.archiver.UnArchiver;
15  
16  /**
17   * Builds archived model xml.zip files.
18   *
19   * @author Chad Brandon
20   * @version $Id: $
21   * @goal xml.zip
22   * @phase package
23   * @description builds a versioned xml.zip
24   */
25  public class XmiZipArchiverMojo
26          extends BaseArchiveMojo
27  {
28      private static final String ARTIFACT_TYPE = "xml.zip";
29  
30      /**
31       * The extensions to search for when doing replacement of embedded model HREF references
32       * within the archived model file from non-versioned to versioned references.
33       *
34       * @parameter expression=".xml,.xml.zip,.xmi"
35       * @required
36       */
37      protected String replacementExtensions;
38  
39      /**
40       * The pattern of the archived model files that should be extracted
41       * before being re-created as versioned model archives.
42       *
43       * @parameter expression=".*(\\.xml\\.zip)"
44       * @required
45       * @readonly
46       */
47      private String modelArchivePattern;
48  
49      /**
50       * The pattern of the non-archived model file(s) that should be archived.
51       *
52       * @parameter expression=".*(\\.xml|\\.xmi)"
53       * @required
54       * @readonly
55       */
56      private String modelFilePattern;
57  
58      /**
59       * Whether or not to do replacement of embedded model HREF reference extensions.
60       *
61       * @parameter expression="true"
62       * @required
63       */
64      protected boolean replaceExtensions;
65  
66      /**
67       * Whether or not the model should be attached as new artifact.
68       *
69       * @parameter expression="false"
70       */
71      private boolean attachArtifact;
72  
73      /**
74       * <p>execute</p>
75       *
76       * @throws org.apache.maven.plugin.MojoExecutionException
77       *          if any.
78       * @see org.apache.maven.plugin.Mojo#execute()
79       */
80      public void execute()
81              throws MojoExecutionException
82      {
83          if (getLog().isDebugEnabled())
84          {
85              getLog().debug(" ======= XmlZipArchiverMojo settings =======");
86              getLog().debug("modelSourceDirectory[" + modelSourceDirectory + ']');
87              getLog().debug("workDirectory[" + workDirectory + ']');
88              getLog().debug("outputDirectory[" + outputDirectory + ']');
89              getLog().debug("finalName[" + finalName + ']');
90              getLog().debug("replaceExtensions[" + replaceExtensions + ']');
91              getLog().debug("version[" + this.project.getVersion() + ']');
92              getLog().debug("extension[" + this.replacementExtensions + ']');
93              getLog().debug("extensionPattern[" + "((\\-" + this.project.getVersion() + ")?)" + this.replacementExtensions + ']');
94              getLog().debug("newExtension[" + "\\-" + this.project.getVersion() + this.replacementExtensions + ']');
95              getLog().debug("attachArtifact[" + attachArtifact + ']');
96          }
97  
98          try
99          {
100             final File buildDirectory = this.workDirectory;
101             if (buildDirectory.exists())
102             {
103                 // old files in directory are not automatically deleted.
104                 deleteFiles(buildDirectory.getAbsolutePath(), ARTIFACT_TYPE);
105                 FileUtils.deleteDirectory(new File(buildDirectory, "models"));
106             }
107             // - the directory which to extract the model file
108             final File modelExtractDirectory = new File(buildDirectory, "models/xmi");
109             modelExtractDirectory.mkdirs();
110 
111             if (modelSourceDirectory.exists())
112             {
113                 getLog().info("Copy xml.zip resources to " + modelExtractDirectory.getAbsolutePath());
114                 final File[] modelFiles = modelSourceDirectory.listFiles();
115                 for (final File file : modelFiles)
116                 {
117                     if (file.isFile() && file.toString().matches(this.modelArchivePattern))
118                     {
119                         // - extract model file
120                         this.unpack(file, modelExtractDirectory);
121 
122                         final File[] extractedModelFiles = modelExtractDirectory.listFiles();
123                         for (final File extractedFile : extractedModelFiles)
124                         {
125                             final String extractedFilePath = extractedFile.toString();
126                             if (extractedFile.isFile() && extractedFilePath.matches(this.modelFilePattern))
127                             {
128                                 final File newFile =
129                                         new File(modelExtractDirectory,
130                                                 this.finalName + '.' + FilenameUtils.getExtension(extractedFile.getName()));
131                                 extractedFile.renameTo(newFile);
132 
133                                 if (replaceExtensions)
134                                 {
135                                     getLog().info("Replace extensions in " + newFile);
136                                     replaceExtensions(this.replacementExtensions, newFile);
137                                 }
138 
139                                 final File xmlZipFile = new File(buildDirectory, this.finalName + '.' + ARTIFACT_TYPE);
140                                 this.writeModelArchive(xmlZipFile, newFile);
141                             }
142                         }
143                     }
144                 }
145             }
146 
147             final File xmlZipFile = new File(buildDirectory, this.finalName + "." + ARTIFACT_TYPE);
148             if (!this.attachArtifact)
149             {
150                 setArtifactFile(xmlZipFile);
151             }
152             else
153             {
154                 //Attach artifact
155                 projectHelper.attachArtifact(project, ARTIFACT_TYPE, xmlZipFile);
156             }
157         }
158         catch (final Throwable throwable)
159         {
160             throw new MojoExecutionException("Error assembling model", throwable);
161         }
162     }
163 
164     /**
165      * Unpacks the archive file.
166      *
167      * @param file     File to be unpacked.
168      * @param location Location where to put the unpacked files.
169      * @throws MojoExecutionException if IOException or ArchiverException from unArchiver.extract()
170      */
171     private void unpack(
172             final File file,
173             final File location)
174             throws MojoExecutionException
175     {
176         final String archiveExt = FilenameUtils.getExtension(file.getAbsolutePath()).toLowerCase();
177         try
178         {
179             final UnArchiver unArchiver;
180             unArchiver = this.archiverManager.getUnArchiver(archiveExt);
181             unArchiver.setSourceFile(file);
182             unArchiver.setDestDirectory(location);
183             unArchiver.extract();
184         }
185         catch (Throwable throwable)
186         {
187             if (throwable instanceof IOException || throwable instanceof ArchiverException)
188             {
189                 throw new MojoExecutionException("Error unpacking file: " + file + "to: " + location, throwable);
190             }
191         }
192     }
193 
194     /**
195      * Writes the given given <code>model</code> archive file and includes
196      * the file given by the <code>model</code>
197      *
198      * @param modelArchive the model archive.
199      * @param model        the file of model to write.
200      * @throws IOException
201      */
202     private void writeModelArchive(
203             final File modelArchive,
204             final File model)
205             throws IOException
206     {
207         final ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(modelArchive));
208         final ZipEntry zipEntry = new ZipEntry(model.getName());
209         zipEntry.setMethod(ZipEntry.DEFLATED);
210         zipOutputStream.putNextEntry(zipEntry);
211         final FileInputStream inputStream = new FileInputStream(model);
212 
213         IOUtils.copy(inputStream, zipOutputStream);
214 
215         zipOutputStream.closeEntry();
216 
217         IOUtils.closeQuietly(inputStream);
218         IOUtils.closeQuietly(zipOutputStream);
219     }
220 }