001package org.andromda.maven.plugin.modelarchiver; 002 003import java.io.File; 004import java.io.FileInputStream; 005import java.io.FileOutputStream; 006import java.io.IOException; 007import java.util.zip.ZipEntry; 008import java.util.zip.ZipOutputStream; 009import org.apache.commons.io.FileUtils; 010import org.apache.commons.io.FilenameUtils; 011import org.apache.commons.io.IOUtils; 012import org.apache.maven.plugin.MojoExecutionException; 013import org.codehaus.plexus.archiver.ArchiverException; 014import org.codehaus.plexus.archiver.UnArchiver; 015 016/** 017 * Builds archived model xml.zip files. 018 * 019 * @author Chad Brandon 020 * @version $Id: $ 021 * @goal xml.zip 022 * @phase package 023 * @description builds a versioned xml.zip 024 */ 025public class XmiZipArchiverMojo 026 extends BaseArchiveMojo 027{ 028 private static final String ARTIFACT_TYPE = "xml.zip"; 029 030 /** 031 * The extensions to search for when doing replacement of embedded model HREF references 032 * within the archived model file from non-versioned to versioned references. 033 * 034 * @parameter expression=".xml,.xml.zip,.xmi" 035 * @required 036 */ 037 protected String replacementExtensions; 038 039 /** 040 * The pattern of the archived model files that should be extracted 041 * before being re-created as versioned model archives. 042 * 043 * @parameter expression=".*(\\.xml\\.zip)" 044 * @required 045 * @readonly 046 */ 047 private String modelArchivePattern; 048 049 /** 050 * The pattern of the non-archived model file(s) that should be archived. 051 * 052 * @parameter expression=".*(\\.xml|\\.xmi)" 053 * @required 054 * @readonly 055 */ 056 private String modelFilePattern; 057 058 /** 059 * Whether or not to do replacement of embedded model HREF reference extensions. 060 * 061 * @parameter expression="true" 062 * @required 063 */ 064 protected boolean replaceExtensions; 065 066 /** 067 * Whether or not the model should be attached as new artifact. 068 * 069 * @parameter expression="false" 070 */ 071 private boolean attachArtifact; 072 073 /** 074 * <p>execute</p> 075 * 076 * @throws org.apache.maven.plugin.MojoExecutionException 077 * if any. 078 * @see org.apache.maven.plugin.Mojo#execute() 079 */ 080 public void execute() 081 throws MojoExecutionException 082 { 083 if (getLog().isDebugEnabled()) 084 { 085 getLog().debug(" ======= XmlZipArchiverMojo settings ======="); 086 getLog().debug("modelSourceDirectory[" + modelSourceDirectory + ']'); 087 getLog().debug("workDirectory[" + workDirectory + ']'); 088 getLog().debug("outputDirectory[" + outputDirectory + ']'); 089 getLog().debug("finalName[" + finalName + ']'); 090 getLog().debug("replaceExtensions[" + replaceExtensions + ']'); 091 getLog().debug("version[" + this.project.getVersion() + ']'); 092 getLog().debug("extension[" + this.replacementExtensions + ']'); 093 getLog().debug("extensionPattern[" + "((\\-" + this.project.getVersion() + ")?)" + this.replacementExtensions + ']'); 094 getLog().debug("newExtension[" + "\\-" + this.project.getVersion() + this.replacementExtensions + ']'); 095 getLog().debug("attachArtifact[" + attachArtifact + ']'); 096 } 097 098 try 099 { 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}