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.commons.compress.archivers.zip;
18  
19  import java.util.zip.ZipException;
20  
21  import org.apache.commons.compress.utils.ByteUtils;
22  
23  /**
24   * If this extra field is added as the very first extra field of the archive, Solaris will consider it an executable jar file.
25   *
26   * @Immutable
27   */
28  public final class JarMarker implements ZipExtraField {
29  
30      static final ZipShort ID = new ZipShort(0xCAFE);
31      private static final ZipShort NULL = new ZipShort(0);
32      private static final JarMarker DEFAULT = new JarMarker();
33  
34      /**
35       * Since JarMarker is stateless we can always use the same instance.
36       *
37       * @return the DEFAULT jarmaker.
38       */
39      public static JarMarker getInstance() {
40          return DEFAULT;
41      }
42  
43      /** No-arg constructor */
44      public JarMarker() {
45          // empty
46      }
47  
48      /**
49       * The actual data to put central directory - without Header-ID or length specifier.
50       *
51       * @return the data
52       */
53      @Override
54      public byte[] getCentralDirectoryData() {
55          return ByteUtils.EMPTY_BYTE_ARRAY;
56      }
57  
58      /**
59       * Length of the extra field in the central directory - without Header-ID or length specifier.
60       *
61       * @return 0
62       */
63      @Override
64      public ZipShort getCentralDirectoryLength() {
65          return NULL;
66      }
67  
68      /**
69       * The Header-ID.
70       *
71       * @return the header id
72       */
73      @Override
74      public ZipShort getHeaderId() {
75          return ID;
76      }
77  
78      /**
79       * The actual data to put into local file data - without Header-ID or length specifier.
80       *
81       * @return the data
82       */
83      @Override
84      public byte[] getLocalFileDataData() {
85          return ByteUtils.EMPTY_BYTE_ARRAY;
86      }
87  
88      /**
89       * Length of the extra field in the local file data - without Header-ID or length specifier.
90       *
91       * @return 0
92       */
93      @Override
94      public ZipShort getLocalFileDataLength() {
95          return NULL;
96      }
97  
98      /**
99       * Doesn't do anything special since this class always uses the same data in central directory and local file data.
100      */
101     @Override
102     public void parseFromCentralDirectoryData(final byte[] buffer, final int offset, final int length) throws ZipException {
103         parseFromLocalFileData(buffer, offset, length);
104     }
105 
106     /**
107      * Populate data from this array as if it was in local file data.
108      *
109      * @param data   an array of bytes
110      * @param offset the start offset
111      * @param length the number of bytes in the array from offset
112      *
113      * @throws ZipException on error
114      */
115     @Override
116     public void parseFromLocalFileData(final byte[] data, final int offset, final int length) throws ZipException {
117         if (length != 0) {
118             throw new ZipException("JarMarker doesn't expect any data");
119         }
120     }
121 }