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 */ 018package org.apache.commons.compress.archivers.zip; 019 020import java.util.zip.ZipException; 021 022/** 023 * If this extra field is added as the very first extra field of the 024 * archive, Solaris will consider it an executable jar file. 025 * @Immutable 026 */ 027public final class JarMarker implements ZipExtraField { 028 029 private static final ZipShort ID = new ZipShort(0xCAFE); 030 private static final ZipShort NULL = new ZipShort(0); 031 private static final byte[] NO_BYTES = new byte[0]; 032 private static final JarMarker DEFAULT = new JarMarker(); 033 034 /** No-arg constructor */ 035 public JarMarker() { 036 // empty 037 } 038 039 /** 040 * Since JarMarker is stateless we can always use the same instance. 041 * @return the DEFAULT jarmaker. 042 */ 043 public static JarMarker getInstance() { 044 return DEFAULT; 045 } 046 047 /** 048 * The Header-ID. 049 * @return the header id 050 */ 051 @Override 052 public ZipShort getHeaderId() { 053 return ID; 054 } 055 056 /** 057 * Length of the extra field in the local file data - without 058 * Header-ID or length specifier. 059 * @return 0 060 */ 061 @Override 062 public ZipShort getLocalFileDataLength() { 063 return NULL; 064 } 065 066 /** 067 * Length of the extra field in the central directory - without 068 * Header-ID or length specifier. 069 * @return 0 070 */ 071 @Override 072 public ZipShort getCentralDirectoryLength() { 073 return NULL; 074 } 075 076 /** 077 * The actual data to put into local file data - without Header-ID 078 * or length specifier. 079 * @return the data 080 */ 081 @Override 082 public byte[] getLocalFileDataData() { 083 return NO_BYTES; 084 } 085 086 /** 087 * The actual data to put central directory - without Header-ID or 088 * length specifier. 089 * @return the data 090 */ 091 @Override 092 public byte[] getCentralDirectoryData() { 093 return NO_BYTES; 094 } 095 096 /** 097 * Populate data from this array as if it was in local file data. 098 * @param data an array of bytes 099 * @param offset the start offset 100 * @param length the number of bytes in the array from offset 101 * 102 * @throws ZipException on error 103 */ 104 @Override 105 public void parseFromLocalFileData(final byte[] data, final int offset, final int length) 106 throws ZipException { 107 if (length != 0) { 108 throw new ZipException("JarMarker doesn't expect any data"); 109 } 110 } 111 112 /** 113 * Doesn't do anything special since this class always uses the 114 * same data in central directory and local file data. 115 */ 116 @Override 117 public void parseFromCentralDirectoryData(final byte[] buffer, final int offset, 118 final int length) 119 throws ZipException { 120 parseFromLocalFileData(buffer, offset, length); 121 } 122}