| /* |
| * 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. |
| */ |
| package org.apache.felix.deploymentadmin; |
| |
| import java.io.BufferedReader; |
| import java.io.Closeable; |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileOutputStream; |
| import java.io.FileReader; |
| import java.io.FileWriter; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.OutputStream; |
| import java.io.PrintWriter; |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.jar.Attributes; |
| import java.util.jar.Manifest; |
| import java.util.jar.Attributes.Name; |
| import java.util.zip.GZIPInputStream; |
| import java.util.zip.GZIPOutputStream; |
| |
| public class Utils { |
| public static Manifest readManifest(File manifestFile) throws IOException { |
| InputStream is = null; |
| Manifest mf = null; |
| try { |
| is = new GZIPInputStream(new FileInputStream(manifestFile)); |
| mf = new Manifest(is); |
| } |
| finally { |
| closeSilently(is); |
| } |
| return mf; |
| } |
| |
| public static void readUntilEndOfStream(InputStream is) throws IOException { |
| byte[] buffer = new byte[1024]; |
| int c = is.read(buffer); |
| while (c != -1) { |
| c = is.read(buffer); |
| } |
| } |
| |
| public static boolean replace(File target, File source) { |
| return delete(target, true /* deleteRoot */) && rename(source, target); |
| } |
| |
| public static boolean copy(File from, File to) { |
| boolean result = true; |
| if (from.isDirectory()) { |
| if (!to.isDirectory()) { |
| if (!to.mkdirs()) { |
| return false; |
| } |
| File[] files = from.listFiles(); |
| if (files == null) { |
| return false; |
| } |
| for (int i = 0; i < files.length; i++) { |
| result &= copy(files[i], new File(to, files[i].getName())); |
| } |
| } |
| } |
| else { |
| InputStream input = null; |
| OutputStream output = null; |
| try { |
| input = new FileInputStream(from); |
| output = new FileOutputStream(to); |
| byte[] buffer = new byte[4096]; |
| for (int i = input.read(buffer); i > -1; i = input.read(buffer)) { |
| output.write(buffer, 0, i); |
| } |
| } |
| catch (IOException e) { |
| return false; |
| } |
| finally { |
| if (!closeSilently(output)) { |
| result = false; |
| } |
| if (!closeSilently(input)) { |
| result = false; |
| } |
| } |
| } |
| return result; |
| } |
| |
| public static boolean rename(File from, File to) { |
| if (!from.renameTo(to)) { |
| if (copy(from, to)) { |
| if (!delete(from, true /* deleteRoot */)) { |
| return false; |
| } |
| } |
| else { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| public static boolean delete(File root, boolean deleteRoot) { |
| boolean result = true; |
| if (root.isDirectory()) { |
| File[] files = root.listFiles(); |
| for (int i = 0; i < files.length; i++) { |
| if (files[i].isDirectory()) { |
| result &= delete(files[i], true); |
| } |
| else { |
| result &= files[i].delete(); |
| } |
| } |
| } |
| if (deleteRoot) { |
| if (root.exists()) { |
| result &= root.delete(); |
| } |
| } |
| return result; |
| } |
| |
| public static void merge(File targetIndex, File target, File sourceIndex, File source) throws IOException { |
| List targetFiles = readIndex(targetIndex); |
| List sourceFiles = readIndex(sourceIndex); |
| List result = new ArrayList(targetFiles); |
| |
| File manifestFile = new File(source, (String) sourceFiles.remove(0)); |
| Manifest resultManifest = Utils.readManifest(manifestFile); |
| |
| resultManifest.getMainAttributes().remove(new Name(Constants.DEPLOYMENTPACKAGE_FIXPACK)); |
| |
| for (Iterator i = result.iterator(); i.hasNext();) { |
| String targetFile = (String) i.next(); |
| if (!"META-INF/MANIFEST.MF".equals(targetFile) && !resultManifest.getEntries().containsKey(targetFile)) { |
| i.remove(); |
| } |
| } |
| |
| for (Iterator iter = sourceFiles.iterator(); iter.hasNext();) { |
| String path = (String) iter.next(); |
| File from = new File(source, path); |
| File to = new File(target, path); |
| if (targetFiles.contains(path)) { |
| if (!to.delete()) { |
| throw new IOException("Could not delete " + to); |
| } |
| } |
| else { |
| result.add(path); |
| } |
| if (!rename(from, to)) { |
| throw new IOException("Could not rename " + from + " to " + to); |
| } |
| } |
| |
| targetFiles.removeAll(sourceFiles); |
| |
| for (Iterator iter = resultManifest.getEntries().keySet().iterator(); iter.hasNext();) { |
| String path = (String) iter.next(); |
| Attributes sourceAttribute = (Attributes) resultManifest.getEntries().get(path); |
| if ("true".equals(sourceAttribute.remove(new Name(Constants.DEPLOYMENTPACKAGE_MISSING)))) { |
| targetFiles.remove(path); |
| } |
| } |
| |
| for (Iterator iter = targetFiles.iterator(); iter.hasNext();) { |
| String path = (String) iter.next(); |
| File targetFile = new File(target, path); |
| if (!targetFile.delete()) { |
| throw new IOException("Could not delete " + targetFile); |
| } |
| } |
| |
| GZIPOutputStream outputStream = new GZIPOutputStream(new FileOutputStream(new File(target, "META-INF/MANIFEST.MF"))); |
| try { |
| resultManifest.write(outputStream); |
| } finally { |
| outputStream.close(); |
| } |
| writeIndex(targetIndex, result); |
| } |
| |
| public static List readIndex(File index) throws IOException { |
| BufferedReader reader = null; |
| try { |
| reader = new BufferedReader(new FileReader(index)); |
| List result = new ArrayList(); |
| for (String line = reader.readLine(); line != null; line = reader.readLine()) { |
| result.add(line); |
| } |
| return result; |
| } |
| finally { |
| closeSilently(reader); |
| } |
| } |
| |
| static boolean closeSilently(Closeable closeable) { |
| if (closeable != null) { |
| try { |
| closeable.close(); |
| } |
| catch (IOException exception) { |
| // Ignore; nothing we can do about this... |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| private static void writeIndex(File index, List input) throws IOException { |
| PrintWriter writer = null; |
| try { |
| writer = new PrintWriter(new FileWriter(index)); |
| for (Iterator iterator = input.iterator(); iterator.hasNext();) { |
| writer.println(iterator.next()); |
| } |
| } |
| finally { |
| closeSilently(writer); |
| } |
| } |
| } |