    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one
    003 * or more contributor license agreements.  See the NOTICE file
    004 * distributed with this work for additional information
    005 * regarding copyright ownership.  The ASF licenses this file
    006 * to you under the Apache License, Version 2.0 (the
    007 * "License"); you may not use this file except in compliance
    008 * with the License.  You may obtain a copy of the License at
    009 *
    010 *   https://www.apache.org/licenses/LICENSE-2.0
    011 *
    012 * Unless required by applicable law or agreed to in writing,
    013 * software distributed under the License is distributed on an
    014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    015 * KIND, either express or implied.  See the License for the
    016 * specific language governing permissions and limitations
    017 * under the License.
    018 */
    019package org.apache.commons.compress.archivers.zip;
    020
    021import java.util.zip.ZipException;
    022
    023import org.apache.commons.compress.utils.ByteUtils;
    024
    025/**
    026 * If this extra field is added as the very first extra field of the archive, Solaris will consider it an executable jar file.
    027 *
    028 * @Immutable
    029 */
    030public final class JarMarker implements ZipExtraField {
    031
    032    static final ZipShort ID = new ZipShort(0xCAFE);
    033    private static final ZipShort NULL = new ZipShort(0);
    034    private static final JarMarker DEFAULT = new JarMarker();
    035
    036    /**
    037     * Since JarMarker is stateless we can always use the same instance.
    038     *
    039     * @return the DEFAULT jarmaker.
    040     */
    041    public static JarMarker getInstance() {
    042        return DEFAULT;
    043    }
    044
    045    /** No-arg constructor */
    046    public JarMarker() {
    047        // empty
    048    }
    049
    050    /**
    051     * The actual data to put central directory - without Header-ID or length specifier.
    052     *
    053     * @return the data
    054     */
    055    @Override
    056    public byte[] getCentralDirectoryData() {
    057        return ByteUtils.EMPTY_BYTE_ARRAY;
    058    }
    059
    060    /**
    061     * Length of the extra field in the central directory - without Header-ID or length specifier.
    062     *
    063     * @return 0
    064     */
    065    @Override
    066    public ZipShort getCentralDirectoryLength() {
    067        return NULL;
    068    }
    069
    070    /**
    071     * The Header-ID.
    072     *
    073     * @return the header id
    074     */
    075    @Override
    076    public ZipShort getHeaderId() {
    077        return ID;
    078    }
    079
    080    /**
    081     * The actual data to put into local file data - without Header-ID or length specifier.
    082     *
    083     * @return the data
    084     */
    085    @Override
    086    public byte[] getLocalFileDataData() {
    087        return ByteUtils.EMPTY_BYTE_ARRAY;
    088    }
    089
    090    /**
    091     * Length of the extra field in the local file data - without Header-ID or length specifier.
    092     *
    093     * @return 0
    094     */
    095    @Override
    096    public ZipShort getLocalFileDataLength() {
    097        return NULL;
    098    }
    099
    100    /**
    101     * Doesn't do anything special since this class always uses the same data in central directory and local file data.
    102     */
    103    @Override
    104    public void parseFromCentralDirectoryData(final byte[] buffer, final int offset, final int length) throws ZipException {
    105        parseFromLocalFileData(buffer, offset, length);
    106    }
    107
    108    /**
    109     * Populate data from this array as if it was in local file data.
    110     *
    111     * @param data   an array of bytes
    112     * @param offset the start offset
    113     * @param length the number of bytes in the array from offset
    114     * @throws ZipException on error
    115     */
    116    @Override
    117    public void parseFromLocalFileData(final byte[] data, final int offset, final int length) throws ZipException {
    118        if (length != 0) {
    119            throw new ZipException("JarMarker doesn't expect any data");
    120        }
    121    }
    122}