1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package util.build; 18 19 import java.io.BufferedInputStream; 20 import java.io.File; 21 import java.io.FileInputStream; 22 import java.io.FileOutputStream; 23 import java.io.IOException; 24 import java.nio.file.Files; 25 import java.nio.file.Path; 26 import java.nio.file.Paths; 27 import java.util.jar.JarEntry; 28 import java.util.jar.JarOutputStream; 29 30 /** 31 * JarBuildStep takes a single input file and embeds it into a (new) jar file as a single entry. 32 */ 33 public class JarBuildStep extends BuildStep { 34 35 String outputJarEntryName; 36 private final boolean deleteInputFileAfterBuild; 37 JarBuildStep(BuildFile inputFile, String outputJarEntryName, BuildFile outputJarFile, boolean deleteInputFileAfterBuild)38 public JarBuildStep(BuildFile inputFile, String outputJarEntryName, 39 BuildFile outputJarFile, boolean deleteInputFileAfterBuild) { 40 super(inputFile, outputJarFile); 41 this.outputJarEntryName = outputJarEntryName; 42 this.deleteInputFileAfterBuild = deleteInputFileAfterBuild; 43 } 44 45 @Override build()46 boolean build() { 47 if (super.build()) { 48 File tempFile = new File(inputFile.folder, outputJarEntryName); 49 try { 50 if (!inputFile.fileName.equals(tempFile)) { 51 copyFile(inputFile.fileName, tempFile); 52 } else { 53 tempFile = null; 54 } 55 } catch (IOException e) { 56 System.err.println("io exception:"+e.getMessage()); 57 e.printStackTrace(); 58 return false; 59 } 60 61 File outDir = outputFile.fileName.getParentFile(); 62 if (!outDir.exists() && !outDir.mkdirs()) { 63 System.err.println("failed to create output dir: " 64 + outDir.getAbsolutePath()); 65 return false; 66 } 67 68 // Find the input. We'll need to look into the input folder, but check with the 69 // (relative) destination filename (this is effectively removing the inputFile folder 70 // from the entry path in the jar file). 71 Path absoluteInputPath = Paths.get(inputFile.folder.getAbsolutePath()) 72 .resolve(outputJarEntryName); 73 File absoluteInputFile = absoluteInputPath.toFile(); 74 if (!absoluteInputFile.exists()) { 75 // Something went wrong. 76 throw new IllegalArgumentException(absoluteInputFile.getAbsolutePath()); 77 } 78 79 // Use a JarOutputStream to create the output jar file. 80 File jarOutFile = outputFile.fileName; 81 try (JarOutputStream jarOut = new JarOutputStream(new FileOutputStream(jarOutFile))) { 82 // Create the JAR entry for the file. Use destFileName, and copy the timestamp 83 // from the input. 84 JarEntry entry = new JarEntry(outputJarEntryName); 85 entry.setTime(absoluteInputFile.lastModified()); 86 87 // Push the entry. The stream will then be ready to accept content. 88 jarOut.putNextEntry(entry); 89 90 // Copy absoluteInputFile into the jar file. 91 Files.copy(absoluteInputPath, jarOut); 92 93 // Finish the entry. 94 jarOut.closeEntry(); 95 96 // (Implicitly close the stream, finishing the jar file.) 97 } catch (Exception e) { 98 System.err.println("exception in JarBuildStep for " + 99 outputFile.fileName.getAbsolutePath() + ", " + outputJarEntryName); 100 e.printStackTrace(System.err); 101 jarOutFile.delete(); 102 return false; 103 } 104 105 // Clean up. 106 if (tempFile != null) { 107 tempFile.delete(); 108 } 109 if (deleteInputFileAfterBuild) { 110 inputFile.fileName.delete(); 111 } 112 113 return true; 114 } 115 return false; 116 } 117 118 @Override hashCode()119 public int hashCode() { 120 return inputFile.hashCode() ^ outputFile.hashCode() 121 ^ outputJarEntryName.hashCode(); 122 } 123 124 @Override equals(Object obj)125 public boolean equals(Object obj) { 126 if (super.equals(obj)) { 127 JarBuildStep other = (JarBuildStep) obj; 128 return inputFile.equals(other.inputFile) 129 && outputFile.equals(other.outputFile) 130 && outputJarEntryName.equals(other.outputJarEntryName); 131 132 } 133 return false; 134 } 135 136 } 137