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 }