/**
* Copyright (c) 2012, The National Archives <pronom@nationalarchives.gsi.gov.uk>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the The National Archives nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package uk.gov.nationalarchives.droid.command;
import java.io.IOException;
import java.util.List;
import uk.gov.nationalarchives.droid.command.action.CommandExecutionException;
import uk.gov.nationalarchives.droid.command.archive.GZipArchiveContentIdentifier;
import uk.gov.nationalarchives.droid.command.archive.TarArchiveContentIdentifier;
import uk.gov.nationalarchives.droid.command.archive.ZipArchiveContentIdentifier;
import uk.gov.nationalarchives.droid.command.container.Ole2ContainerContentIdentifier;
import uk.gov.nationalarchives.droid.command.container.ZipContainerContentIdentifier;
import uk.gov.nationalarchives.droid.container.ContainerFileIdentificationRequestFactory;
import uk.gov.nationalarchives.droid.container.ContainerSignatureDefinitions;
import uk.gov.nationalarchives.droid.container.TriggerPuid;
import uk.gov.nationalarchives.droid.container.ole2.Ole2IdentifierEngine;
import uk.gov.nationalarchives.droid.container.zip.ZipIdentifierEngine;
import uk.gov.nationalarchives.droid.core.BinarySignatureIdentifier;
import uk.gov.nationalarchives.droid.core.interfaces.IdentificationRequest;
import uk.gov.nationalarchives.droid.core.interfaces.IdentificationResult;
import uk.gov.nationalarchives.droid.core.interfaces.IdentificationResultCollection;
import uk.gov.nationalarchives.droid.core.interfaces.archive.IdentificationRequestFactory;
/**
* File identification results printer.
*
* NB: This class is called recursively when archive files are opened
*
* @author rbrennan
*/
public class ResultPrinter {
private static final String R_SLASH = "/";
private static final String L_BRACKET = "(";
private static final String R_BRACKET = ")";
private static final String SPACE = " ";
private BinarySignatureIdentifier binarySignatureIdentifier;
private ContainerSignatureDefinitions containerSignatureDefinitions;
private List<TriggerPuid> triggerPuids;
private IdentificationRequestFactory requestFactory;
private String path;
private String slash;
private String slash1;
private String wrongSlash;
private boolean archives;
private final String OLE2_CONTAINER = "OLE2";
private final String ZIP_CONTAINER = "ZIP";
private final String ZIP_ARCHIVE = "x-fmt/263";
private final String JIP_ARCHIVE = "x-fmt/412";
private final String TAR_ARCHIVE = "x-fmt/265";
private final String GZIP_ARCHIVE = "x-fmt/266";
/**
* Store signature files.
*
* @param binarySignatureIdentifier binary signature identifier
* @param containerSignatureDefinitions container signatures
* @param path current file/container path
* @param slash local path element delimiter
* @param slash1 local first container prefix delimiter
* @param archives Should archives be examined?
*/
public ResultPrinter(final BinarySignatureIdentifier binarySignatureIdentifier,
final ContainerSignatureDefinitions containerSignatureDefinitions,
final String path, final String slash, final String slash1, boolean archives) {
this.binarySignatureIdentifier = binarySignatureIdentifier;
this.containerSignatureDefinitions = containerSignatureDefinitions;
this.path = path;
this.slash = slash;
this.slash1 = slash1;
this.wrongSlash = this.slash.equals(R_SLASH) ? "\\" : R_SLASH;
this.archives = archives;
if (containerSignatureDefinitions != null) {
triggerPuids = containerSignatureDefinitions.getTiggerPuids();
}
}
/**
* Output identification for this file.
*
* @param results identification Results
* @param request identification Request
*
* @throws CommandExecutionException if unexpected container type encountered
*/
public void print(final IdentificationResultCollection results,
final IdentificationRequest request) throws CommandExecutionException {
final String fileName = (path + request.getFileName()).replace(wrongSlash, slash);
final IdentificationResultCollection containerResults =
getContainerResults(results, request, fileName);
IdentificationResultCollection finalResults = new IdentificationResultCollection(request);
boolean container = false;
if (containerResults.getResults().size() > 0) {
container = true;
finalResults = containerResults;
} else if (results.getResults().size() > 0) {
finalResults = results;
}
if (finalResults.getResults().size() > 0) {
binarySignatureIdentifier.removeLowerPriorityHits(finalResults);
}
if (finalResults.getResults().size() > 0) {
for (IdentificationResult identResult : finalResults.getResults()) {
String puid = identResult.getPuid();
if (!container && JIP_ARCHIVE.equals(puid)) {
puid = ZIP_ARCHIVE;
}
System.out.println(fileName + "," + puid);
if (archives && !container) {
if (GZIP_ARCHIVE.equals(puid)) {
GZipArchiveContentIdentifier gzipArchiveIdentifier =
new GZipArchiveContentIdentifier(binarySignatureIdentifier,
containerSignatureDefinitions, path, slash, slash1);
gzipArchiveIdentifier.identify(results.getUri(), request);
} else if (TAR_ARCHIVE.equals(puid)) {
TarArchiveContentIdentifier tarArchiveIdentifier =
new TarArchiveContentIdentifier(binarySignatureIdentifier,
containerSignatureDefinitions, path, slash, slash1);
tarArchiveIdentifier.identify(results.getUri(), request);
} else if (ZIP_ARCHIVE.equals(puid) || JIP_ARCHIVE.equals(puid)) {
ZipArchiveContentIdentifier zipArchiveIdentifier =
new ZipArchiveContentIdentifier(binarySignatureIdentifier,
containerSignatureDefinitions, path, slash, slash1);
zipArchiveIdentifier.identify(results.getUri(), request);
}
}
}
} else {
System.out.println(fileName + ",Unknown");
}
}
private IdentificationResultCollection getContainerResults(
final IdentificationResultCollection results,
final IdentificationRequest request, final String fileName) throws CommandExecutionException {
IdentificationResultCollection containerResults =
new IdentificationResultCollection(request);
if (results.getResults().size() > 0 && containerSignatureDefinitions != null) {
for (IdentificationResult identResult : results.getResults()) {
String filePuid = identResult.getPuid();
if (filePuid != null) {
TriggerPuid containerPuid = getTriggerPuidByPuid(filePuid);
if (containerPuid != null) {
requestFactory = new ContainerFileIdentificationRequestFactory();
String containerType = containerPuid.getContainerType();
if (OLE2_CONTAINER.equals(containerType)) {
try {
Ole2ContainerContentIdentifier ole2Identifier =
new Ole2ContainerContentIdentifier();
ole2Identifier.init(containerSignatureDefinitions, containerType);
Ole2IdentifierEngine ole2IdentifierEngine = new Ole2IdentifierEngine();
ole2IdentifierEngine.setRequestFactory(requestFactory);
ole2Identifier.setIdentifierEngine(ole2IdentifierEngine);
containerResults = ole2Identifier.process(
request.getSourceInputStream(), containerResults);
} catch (IOException e) { // carry on after container i/o problems
System.err.println(e + SPACE + L_BRACKET + fileName + R_BRACKET);
}
} else if (ZIP_CONTAINER.equals(containerType)) {
try {
ZipContainerContentIdentifier zipIdentifier =
new ZipContainerContentIdentifier();
zipIdentifier.init(containerSignatureDefinitions, containerType);
ZipIdentifierEngine zipIdentifierEngine = new ZipIdentifierEngine();
zipIdentifierEngine.setRequestFactory(requestFactory);
zipIdentifier.setIdentifierEngine(zipIdentifierEngine);
containerResults = zipIdentifier.process(
request.getSourceInputStream(), containerResults);
} catch (IOException e) { // carry on after container i/o problems
System.err.println(e + SPACE + L_BRACKET + fileName + R_BRACKET);
}
} else {
throw new CommandExecutionException("Unknown container type: " + containerPuid);
}
}
}
}
}
return containerResults;
}
private TriggerPuid getTriggerPuidByPuid(final String puid) {
for (final TriggerPuid tp : triggerPuids) {
if (tp.getPuid().equals(puid)) {
return tp;
}
}
return null;
}
}