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