View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements. See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache license, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License. You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the license for the specific language governing permissions and
15   * limitations under the license.
16   */
17  package org.apache.logging.log4j.core.appender.rolling.action;
18  
19  import java.io.File;
20  import java.io.FileInputStream;
21  import java.io.FileOutputStream;
22  import java.io.IOException;
23  import java.util.Objects;
24  import java.util.zip.ZipEntry;
25  import java.util.zip.ZipOutputStream;
26  
27  /**
28   * Compresses a file using Zip compression.
29   */
30  public final class ZipCompressAction extends AbstractAction {
31  
32      private static final int BUF_SIZE = 8192;
33  
34      /**
35       * Source file.
36       */
37      private final File source;
38  
39      /**
40       * Destination file.
41       */
42      private final File destination;
43  
44      /**
45       * If true, attempts to delete file on completion.
46       */
47      private final boolean deleteSource;
48  
49      /**
50       * Compression level.
51       */
52      private final int level;
53  
54      /**
55       * Creates new instance of GzCompressAction.
56       *
57       * @param source file to compress, may not be null.
58       * @param destination compressed file, may not be null.
59       * @param deleteSource if true, attempt to delete file on completion. Failure to delete does not cause an exception
60       *            to be thrown or affect return value.
61       * @param level TODO
62       */
63      public ZipCompressAction(final File source, final File destination, final boolean deleteSource, final int level) {
64          Objects.requireNonNull(source, "source");
65          Objects.requireNonNull(destination, "destination");
66  
67          this.source = source;
68          this.destination = destination;
69          this.deleteSource = deleteSource;
70          this.level = level;
71      }
72  
73      /**
74       * Compresses.
75       *
76       * @return true if successfully compressed.
77       * @throws IOException on IO exception.
78       */
79      @Override
80      public boolean execute() throws IOException {
81          return execute(source, destination, deleteSource, level);
82      }
83  
84      /**
85       * Compresses a file.
86       *
87       * @param source file to compress, may not be null.
88       * @param destination compressed file, may not be null.
89       * @param deleteSource if true, attempt to delete file on completion. Failure to delete does not cause an exception
90       *            to be thrown or affect return value.
91       * @param level the compression level
92       * @return true if source file compressed.
93       * @throws IOException on IO exception.
94       */
95      public static boolean execute(final File source, final File destination, final boolean deleteSource,
96              final int level) throws IOException {
97          if (source.exists()) {
98              try (final FileInputStream fis = new FileInputStream(source);
99                      final ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(destination))) {
100                 zos.setLevel(level);
101 
102                 final ZipEntry zipEntry = new ZipEntry(source.getName());
103                 zos.putNextEntry(zipEntry);
104 
105                 final byte[] inbuf = new byte[BUF_SIZE];
106                 int n;
107 
108                 while ((n = fis.read(inbuf)) != -1) {
109                     zos.write(inbuf, 0, n);
110                 }
111             }
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      * Captures 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 
133     @Override
134     public String toString() {
135         return ZipCompressAction.class.getSimpleName() + '[' + source + " to " + destination
136                 + ", level=" + level + ", deleteSource=" + deleteSource + ']';
137     }
138 
139     public File getSource() {
140         return source;
141     }
142 
143     public File getDestination() {
144         return destination;
145     }
146 
147     public boolean isDeleteSource() {
148         return deleteSource;
149     }
150 
151     public int getLevel() {
152         return level;
153     }
154 }