All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.redhat.ceylon.cmr.impl.IOUtils Maven / Gradle / Ivy

There is a newer version: 1.3.3
Show newest version
/*
 * Copyright 2011 Red Hat inc. and third party contributors as noted 
 * by the author tags.
 * 
 * Licensed 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 com.redhat.ceylon.cmr.impl;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass;
import java.io.OutputStream;
import java.io.Serializable;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Enumeration;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

import com.redhat.ceylon.common.FileUtil;
import com.redhat.ceylon.model.cmr.ArtifactResult;


/**
 * I/O utils.
 *
 * @author Ales Justin
 * @author FroMage (for SHA1)
 */
public class IOUtils {

    private static final Logger log = Logger.getLogger(IOUtils.class.getName());
    private static final char[] Hexadecimal = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    /**
     * Safe close.
     *
     * @param c the closeable
     */
    public static void safeClose(Closeable c) {
        try {
            if (c != null) {
                c.close();
            }
        } catch (IOException ignored) {
        }
    }

    public static IOException toIOException(Throwable t) {
        return (t instanceof IOException ? (IOException) t : new IOException(t));
    }

    /**
     * Delete files recursively.
     *
     * @param file the current file or folder to delete
     */
    public static void deleteRecursively(File file) {
        if (file.isDirectory()) {
            for (File f : file.listFiles())
                deleteRecursively(f);
        }
        //noinspection ResultOfMethodCallIgnored
        file.delete();
    }

    /**
     * Copy stream.
     *
     * @param in       input stream
     * @param out      output stream
     * @param closeIn  do we close input stream
     * @param closeOut do we close output stream
     * @throws IOException for any I/O error
     */
    public static void copyStream(InputStream in, OutputStream out, boolean closeIn, boolean closeOut) throws IOException {
        try {
            copyStreamNoClose(in, out);
        } finally {
            if (closeIn) {
                safeClose(in);
            }
            if (closeOut) {
                safeClose(out);
            }
        }
    }

    private static void copyStreamNoClose(InputStream in, OutputStream out) throws IOException {
        final byte[] bytes = new byte[8192];
        int cnt;
        while ((cnt = in.read(bytes)) != -1) {
            out.write(bytes, 0, cnt);
        }
        out.flush();
    }

    static InputStream toInputStream(File file) throws IOException {
        return new FileInputStream(file);
    }

    static  InputStream toObjectStream(T content) throws IOException {
        if (content == null)
            throw new IllegalArgumentException("Null content");

        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
        final ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(content);
        oos.flush();
        return new ByteArrayInputStream(baos.toByteArray());
    }

    static  T fromStream(Class contentType, InputStream inputStream) throws IOException {
        if (contentType == null)
            throw new IllegalArgumentException("Null content type!");
        if (inputStream == null)
            throw new IllegalArgumentException("Null input stream!");

        final ClassLoader cl = contentType.getClassLoader();
        try (ObjectInputStream ois = new ObjectInputStream(inputStream) {
            protected Class resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
                return cl.loadClass(desc.getName());
            }
        }) {
            Object result = ois.readObject();
            return contentType.cast(result);
        } catch (ClassNotFoundException e) {
            throw new IOException(e);
        }
    }

    static void writeToFile(File file, InputStream inputStream) throws IOException {
        copyStream(inputStream, new FileOutputStream(file), false, true);
    }

    static String sha1(InputStream is) {
        final MessageDigest digest;
        try {
            digest = MessageDigest.getInstance("SHA-1");
        } catch (NoSuchAlgorithmException e) {
            // can't happen, specs say SHA-1 must be implemented
            log.warning("Failed to get a SHA-1 message digest, your JRE does not follow the specs. No SHA-1 signature will be made");
            return null;
        }

        final byte[] buffer = new byte[1024];
        int read;
        try {
            while ((read = is.read(buffer)) != -1) {
                digest.update(buffer, 0, read);
            }
        } catch (IOException e) {
            log.warning("Failed to read input stream, no SHA-1 signature will be made");
            return null;
        } finally {
            safeClose(is);
        }
        return toHexString(digest.digest());
    }

    static String readSha1(InputStream is) throws IOException {
        final BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        try {
            return reader.readLine();
        } finally {
            safeClose(reader);
        }
    }

    static String toHexString(byte[] bytes) {
        final char[] chars = new char[bytes.length * 2];
        for (int b = 0, c = 0; b < bytes.length; b++) {
            int v = (int) bytes[b] & 0xFF;
            chars[c++] = Hexadecimal[v / 16];
            chars[c++] = Hexadecimal[v % 16];
        }
        return new String(chars);
    }

    public static class ZipRoot {
        public final File root;
        public final String prefix;

        public ZipRoot(File root, String prefix) {
            this.root = root;
            this.prefix = prefix;
        }
    }

    public static File zipFolder(File root) throws IOException {
        return zipFolders(new ZipRoot(root, ""));
    }

    public static File zipFolders(ZipRoot... zipRoots) throws IOException {
        for (ZipRoot zipRoot : zipRoots) {
            if (!zipRoot.root.isDirectory())
                throw new IOException("Zip root must be a folder");
        }
        File zipFile = File.createTempFile("ceylon-zipper-", ".zip");
        try {
            ZipOutputStream os = new ZipOutputStream(new FileOutputStream(zipFile));
            try {
                for (ZipRoot zipRoot : zipRoots) {
                    for (File f : zipRoot.root.listFiles()) {
                        zipInternal(zipRoot.prefix, f, os);
                    }
                }
            } finally {
                os.flush();
                os.close();
            }
            return zipFile;
        } catch (IOException x) {
            zipFile.delete();
            throw x;
        }
    }

    private static void zipInternal(String path, File file, ZipOutputStream os) throws IOException {
        String filePath;
        if(path.isEmpty())
            filePath = file.getName();
        else
            filePath = path + "/" + file.getName();
        if (file.isDirectory()) {
            for (File f : file.listFiles())
                zipInternal(filePath, f, os);
        } else {
            ZipEntry entry = new ZipEntry(filePath);
            os.putNextEntry(entry);
            try (FileInputStream in = new FileInputStream(file)) {
                copyStreamNoClose(in, os);
            }
            os.closeEntry();
        }
    }

    public enum UnzipFailure {
        DestinationNotDirectory,
        CannotCreateDestination,
        CopyError
    }
    
    @SuppressWarnings("serial")
    public static class UnzipException extends RuntimeException {
        public final UnzipFailure failure;
        public final File dir;
        public final String entryName;

        public UnzipException(UnzipFailure failure, File dir){
            this.failure = failure;
            this.dir = dir;
            this.entryName = null;
        }

        public UnzipException(UnzipFailure failure, String entryName, IOException e) {
            super(e);
            this.failure = failure;
            this.dir = null;
            this.entryName = entryName;
        }
    }
    
    public static void extractArchive(File zip, File dir) throws IOException {
        if (dir.exists()) {
            if (!dir.isDirectory()) {
                throw new UnzipException(UnzipFailure.DestinationNotDirectory, dir);
            }
        } else {
            mkdirs(dir);
        }

        try (ZipFile zf = new ZipFile(zip)) {
            Enumeration entries = zf.entries();
            while (entries.hasMoreElements()) {
                ZipEntry entry = entries.nextElement();
                String entryName = entry.getName();
                try {
                    File out = new File(dir, entryName);
                    if (entry.isDirectory()) {
                        mkdirs(out);
                        continue;
                    }
                    mkdirs(out.getParentFile());
                    try (InputStream zipIn = zf.getInputStream(entry)) {
                        try (BufferedOutputStream fileOut = new BufferedOutputStream(new FileOutputStream(out))) {
                            IOUtils.copyStream(zipIn, fileOut, false, false);
                        }
                    }
                } catch (IOException e) {
                    throw new UnzipException(UnzipFailure.CopyError, entryName, e);
                }
            }
        }
    }
    
    private static File mkdirs(File dir) {
        if (!dir.exists() && !FileUtil.mkdirs(dir)) {
            throw new UnzipException(UnzipFailure.CannotCreateDestination, dir);
        }
        return dir;
    }

    public static InputStream findDescriptor(ArtifactResult result, String descriptorPath) {
        try {
            File file = result.artifact();
            try (ZipFile zipFile = new ZipFile(file)) {
                ZipEntry zipEntry = zipFile.getEntry(descriptorPath);
                if (zipEntry != null) {
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    copyStream(zipFile.getInputStream(zipEntry), baos, true, true);
                    return new ByteArrayInputStream(baos.toByteArray());
                } else {
                    return null;
                }
            }
        } catch (Exception e) {
            throw new IllegalStateException(e);
        }
    }

    public static File toTempFile(InputStream inputStream) throws IOException {
        try {
            final File tempFile = File.createTempFile("ceylon-ioutils-", ".tmp");
            writeToFile(tempFile, inputStream);
            return tempFile;
        } finally {
            safeClose(inputStream);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy