001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.geronimo.kernel.repository;
018
019 import java.io.InputStream;
020 import java.io.File;
021 import java.io.IOException;
022 import java.io.FileOutputStream;
023 import java.io.OutputStream;
024 import java.util.zip.ZipInputStream;
025 import java.util.zip.ZipEntry;
026
027 import org.apache.geronimo.kernel.repository.ArtifactTypeHandler;
028 import org.apache.geronimo.kernel.repository.Artifact;
029 import org.apache.geronimo.kernel.repository.FileWriteMonitor;
030 import org.apache.geronimo.kernel.config.IOUtil;
031
032 /**
033 * @version $Rev: 476049 $ $Date: 2006-11-17 15:35:17 +1100 (Fri, 17 Nov 2006) $
034 */
035 public class UnpackArtifactTypeHandler implements ArtifactTypeHandler {
036 private final static int TRANSFER_NOTIFICATION_SIZE = 10240; // announce every this many bytes
037 private final static int TRANSFER_BUF_SIZE = 10240; // try this many bytes at a time
038
039 public void install(InputStream source, int size, Artifact artifact, FileWriteMonitor monitor, File target) throws IOException {
040 // assure that the target directory exists
041 File parent = target.getParentFile();
042 if (!parent.exists() && !parent.mkdirs()) {
043 throw new RuntimeException("Unable to create directory " + parent.getAbsolutePath());
044 }
045
046 // copy it
047 if (monitor != null) {
048 monitor.writeStarted(artifact.toString(), size);
049 }
050
051 int total = 0;
052 ZipInputStream in = new ZipInputStream(source);
053 try {
054
055 int threshold = UnpackArtifactTypeHandler.TRANSFER_NOTIFICATION_SIZE;
056 byte[] buffer = new byte[TRANSFER_BUF_SIZE];
057
058 for (ZipEntry entry = in.getNextEntry(); entry != null; entry = in.getNextEntry()) {
059 File file = new File(target, entry.getName());
060 if (entry.isDirectory()) {
061 file.mkdirs();
062 } else {
063 if (!entry.getName().equals("META-INF/startup-jar")) {
064 file.getParentFile().mkdirs();
065 OutputStream out = new FileOutputStream(file);
066 try {
067 int count;
068 while ((count = in.read(buffer)) > 0) {
069 out.write(buffer, 0, count);
070 if (monitor != null) {
071 total += count;
072 if (total > threshold) {
073 threshold += UnpackArtifactTypeHandler.TRANSFER_NOTIFICATION_SIZE;
074 monitor.writeProgress(total);
075 }
076 }
077 }
078 } finally {
079 IOUtil.flush(out);
080 out.close();
081 }
082 in.closeEntry();
083 }
084 }
085 }
086 } catch (IOException e) {
087 IOUtil.recursiveDelete(target);
088 throw e;
089 } finally {
090 in.close();
091 if (monitor != null) {
092 monitor.writeComplete(total);
093 }
094 }
095 }
096 }