/* * Copyright (c) 2012 Data Harmonisation Panel * * All rights reserved. This program and the accompanying materials are made * available under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * You should have received a copy of the GNU Lesser General Public License * along with this distribution. If not, see <http://www.gnu.org/licenses/>. * * Contributors: * Data Harmonisation Panel <http://www.dhpanel.eu> */ package eu.esdihumboldt.hale.common.core.io.util; import java.io.IOException; import java.io.InputStream; import java.io.PushbackInputStream; import java.util.zip.GZIPInputStream; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExecutableExtension; import org.eclipse.core.runtime.QualifiedName; import org.eclipse.core.runtime.content.IContentDescriber; import org.eclipse.core.runtime.content.IContentDescription; import org.eclipse.core.runtime.content.IContentType; /** * Detects if a stream is compressed with GZip. Optionally uses an internal * content describer to verify the uncompressed content of a stream. * * @author Simon Templer */ public class GZipContentDescriber implements IContentDescriber, IExecutableExtension { /** * The GZip content type identifier as specified in the plugin.xml */ public static final String GZIP_CONTENT_TYPE_ID = "eu.esdihumboldt.hale.common.core.gzip"; private final IContentDescriber internalContentDescriber; /** * Default constructor. */ public GZipContentDescriber() { this(null); } /** * Constructor using an internal content describer for the uncompressed * content. * * @param internalContentDescriber the content describer for the * uncompressed content */ public GZipContentDescriber(IContentDescriber internalContentDescriber) { super(); this.internalContentDescriber = internalContentDescriber; } /** * @see IContentDescriber#describe(InputStream, IContentDescription) */ @Override public int describe(InputStream contents, IContentDescription description) throws IOException { // we need a pushbackstream to look ahead PushbackInputStream pb = new PushbackInputStream(contents, 2); byte[] signature = new byte[2]; pb.read(signature); // read the signature pb.unread(signature); // push back the signature to the stream int head = (signature[0] & 0xff) | ((signature[1] << 8) & 0xff00); if (GZIPInputStream.GZIP_MAGIC == head) { if (internalContentDescriber == null) { // only check for GZip -> valid return VALID; } else { // test the compressed contents contents = new GZIPInputStream(pb); return internalContentDescriber.describe(contents, description); } } return INVALID; // not Gziped } /** * @see IContentDescriber#getSupportedOptions() */ @Override public QualifiedName[] getSupportedOptions() { if (internalContentDescriber != null) { return internalContentDescriber.getSupportedOptions(); } // no properties return new QualifiedName[0]; } /** * Determines if the given content type is a GZip content type. * * @param contentType the content type * @return <code>true</code> if the content type is the GZip content type or * it extends the GZip content type */ public static boolean isGZipContentType(IContentType contentType) { if (contentType == null) { return false; } if (GZIP_CONTENT_TYPE_ID.equals(contentType.getId())) { return true; } return isGZipContentType(contentType.getBaseType()); } /** * @see IExecutableExtension#setInitializationData(IConfigurationElement, * String, Object) */ @Override public void setInitializationData(IConfigurationElement config, String propertyName, Object data) throws CoreException { if (internalContentDescriber instanceof IExecutableExtension) { // forward initialization data for internal configuration ((IExecutableExtension) internalContentDescriber).setInitializationData(config, propertyName, data); } } }