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.logging.log4j.core.appender.rolling.helper;
018    
019    import java.io.File;
020    import java.io.FileInputStream;
021    import java.io.FileOutputStream;
022    import java.io.IOException;
023    
024    import java.util.zip.ZipEntry;
025    import java.util.zip.ZipOutputStream;
026    
027    
028    /**
029     * Compresses a file using Zip compression.
030     */
031    public final class ZipCompressAction extends AbstractAction {
032    
033        private static final int BUF_SIZE = 8102;
034    
035        /**
036         * Source file.
037         */
038        private final File source;
039    
040        /**
041         * Destination file.
042         */
043        private final File destination;
044    
045        /**
046         * If true, attempt to delete file on completion.
047         */
048        private final boolean deleteSource;
049    
050        /**
051         * Create new instance of GZCompressAction.
052         *
053         * @param source       file to compress, may not be null.
054         * @param destination  compressed file, may not be null.
055         * @param deleteSource if true, attempt to delete file on completion.  Failure to delete
056         *                     does not cause an exception to be thrown or affect return value.
057         */
058        public ZipCompressAction(final File source, final File destination, final boolean deleteSource) {
059            if (source == null) {
060                throw new NullPointerException("source");
061            }
062    
063            if (destination == null) {
064                throw new NullPointerException("destination");
065            }
066    
067            this.source = source;
068            this.destination = destination;
069            this.deleteSource = deleteSource;
070        }
071    
072        /**
073         * Compress.
074         *
075         * @return true if successfully compressed.
076         * @throws IOException on IO exception.
077         */
078        @Override
079        public boolean execute() throws IOException {
080            return execute(source, destination, deleteSource);
081        }
082    
083        /**
084         * Compress a file.
085         *
086         * @param source       file to compress, may not be null.
087         * @param destination  compressed file, may not be null.
088         * @param deleteSource if true, attempt to delete file on completion.  Failure to delete
089         *                     does not cause an exception to be thrown or affect return value.
090         * @return true if source file compressed.
091         * @throws IOException on IO exception.
092         */
093        public static boolean execute(final File source, final File destination, final boolean deleteSource)
094            throws IOException {
095            if (source.exists()) {
096                FileInputStream fis = new FileInputStream(source);
097                FileOutputStream fos = new FileOutputStream(destination);
098                ZipOutputStream zos = new ZipOutputStream(fos);
099    
100                ZipEntry zipEntry = new ZipEntry(source.getName());
101                zos.putNextEntry(zipEntry);
102    
103                byte[] inbuf = new byte[BUF_SIZE];
104                int n;
105    
106                while ((n = fis.read(inbuf)) != -1) {
107                    zos.write(inbuf, 0, n);
108                }
109    
110                zos.close();
111                fis.close();
112    
113                if (deleteSource && !source.delete()) {
114                    LOGGER.warn("Unable to delete " + source.toString() + '.');
115                }
116    
117                return true;
118            }
119    
120            return false;
121        }
122    
123        /**
124         * Capture exception.
125         *
126         * @param ex exception.
127         */
128        @Override
129        protected void reportException(final Exception ex) {
130            LOGGER.warn("Exception during compression of '" + source.toString() + "'.", ex);
131        }
132    }