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