Java tutorial
package org.codehaus.mojo.jsimport; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import org.apache.commons.io.FileUtils; import org.apache.maven.artifact.Artifact; /** * Processes an artifact and makes available one or more files depending on whether the artifact points to a js file or * a "-www.zip" file respectively. * * @author Christopher Hunt */ public class JsFileArtifactHandler { private List<File> files = new ArrayList<File>();; private File expansionFolder; /** * @param artifact the artifact to work with. It can either be for a JS file or a zip file with a classifier of * "www". * @param targetFolder the folder to merge non js files into. * @param workFolder the folder to store any meta data that will help us do things like avoiding unnecessary unzips * (given that it has been done before etc.). * @throws IOException if something goes wrong, particularly in the course of zip file expansion. */ public JsFileArtifactHandler(Artifact artifact, File targetFolder, File workFolder) throws IOException { if (artifact.getType().equals("js")) { files = new ArrayList<File>(1); files.add(artifact.getFile()); } else { assert artifact.getType().equals("zip") && artifact.getClassifier().equals("www"); File wwwZipFile = artifact.getFile(); files = expandWwwZipIntoTargetFolder(artifact, wwwZipFile, targetFolder, workFolder); } } private List<File> expandWwwZipIntoTargetFolder(Artifact artifact, File wwwZipFile, File targetFolder, File workFolder) throws IOException { List<File> jsFiles = new ArrayList<File>(); // FIXME: Need to consider scope here i.e. don't create a compile www-zip file for a test run. expansionFolder = new File(workFolder, "www-zip" + File.separator + wwwZipFile.getName()); // Don't expand if it is already expanded. if (wwwZipFile.lastModified() > expansionFolder.lastModified()) { String gavPath = artifact.getGroupId().replace('.', File.separatorChar) + File.separator + artifact.getArtifactId() + File.separator + artifact.getVersion(); File jsExpansionFolder = new File(expansionFolder, gavPath); FileInputStream fis = new FileInputStream(wwwZipFile); try { ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis)); ZipEntry entry; boolean firstEntryProcessed = false; int rootFolderPrefixPosn = 0; while ((entry = zis.getNextEntry()) != null) { // Any non-js files are simply copied into the target folder. js files are copied to a temporary // folder as something else needs to put them into the target folder (there may be processing a js // file along the way). However we ignore minified files when inflating as by convention, we don't // want them as part of the project - projects can minify later. String entryName = entry.getName().substring(rootFolderPrefixPosn); File entryFile = null; if (!entryName.endsWith("js")) { if (!entry.isDirectory()) { entryFile = new File(targetFolder, entryName); } else if (!firstEntryProcessed) { // Its a directory and it is the first thing in the zip file. We don't want to bother with // this directory when creating files as we're more interested in merging it into the // existing target folder. rootFolderPrefixPosn = entryName.length(); } } else if (!entryName.endsWith("-min.js")) { entryFile = new File(jsExpansionFolder, entryName); jsFiles.add(entryFile); } // If we have something interesting to inflate. if (entryFile != null) { entryFile.getParentFile().mkdirs(); FileOutputStream fos = new FileOutputStream(entryFile); BufferedOutputStream dest = null; try { int count; final int bufferSize = 2048; byte data[] = new byte[bufferSize]; dest = new BufferedOutputStream(fos, bufferSize); while ((count = zis.read(data, 0, bufferSize)) != -1) { dest.write(data, 0, count); } dest.flush(); } finally { dest.close(); } } firstEntryProcessed = true; } } finally { fis.close(); } // Override the directory's mod time as that will equal the time it was compressed initially. We're not // interested in that - we're interested to learn whether the source zip file is newer that the directory we // expand into. expansionFolder.setLastModified(wwwZipFile.lastModified()); } else { // Nothing changed. Just return a list of files that were previously expanded. Collection<File> existingFiles = FileUtils.listFiles(expansionFolder, new String[] { "js" }, true); for (File file : existingFiles) { if (!file.getName().endsWith("-min.js")) { jsFiles.add(file); } } } return jsFiles; } /** * @return a list of the files that were found associated with the artifact. */ public List<File> getFiles() { return files; } /** * @return the location where the files have been expanded to or null otherwise. */ public File getExpansionFolder() { return expansionFolder; } }