/** * JHOVE2 - Next-generation architecture for format-aware characterization * * Copyright (c) 2010 by The Regents of the University of California, * Ithaka Harbors, Inc., and The Board of Trustees of the Leland Stanford * Junior University. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * o Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * o 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. * * o Neither the name of the University of California/California Digital * Library, Ithaka Harbors/Portico, or Stanford University, 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 OWNER 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 org.jhove2.app; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.jhove2.config.spring.SpringConfigInfo; import org.jhove2.core.Invocation; import org.jhove2.core.JHOVE2; import org.jhove2.core.JHOVE2Exception; import org.jhove2.core.app.AbstractApplication; import org.jhove2.core.io.Input; import org.jhove2.core.io.Input.Type; import org.jhove2.core.source.Source; import org.jhove2.module.display.Displayer; import org.jhove2.persist.ApplicationModuleAccessor; import org.jhove2.persist.PersistenceManager; import org.jhove2.persist.PersistenceManagerUtil; import com.sleepycat.persist.model.Persistent; /** * Official JHOVE2 command line application. * * @author mstrong, slabrams, smorrissey */ @Persistent public class JHOVE2CommandLine extends AbstractApplication { /** JHOVE2 application version identifier. */ public static final String VERSION = "2.0.0"; /** JHOVE2 application release date. */ public static final String RELEASE = "2010-09-10"; /** JHOVE2 application rights statement. */ public static final String RIGHTS = "Copyright 2010 by The Regents of the University of California, " + "Ithaka Harbors, Inc., and The Board of Trustees of the Leland " + "Stanford Junior University. " + "Available under the terms of the BSD license."; /** Usage statement return code. */ public static final int EUSAGE = 1; /** Caught exception return code. */ public static final int EEXCEPTION = -1; protected String persistenceMgrFactoryName; /** * Instantiate a new <code>JHOVE2CommandLine</code>. * @throws JHOVE2Exception */ public JHOVE2CommandLine() throws JHOVE2Exception { /* Super constructor creates {@link org.jhove2.core.AppConfigInfo} with * JHOVE2 default settings, and the JHOVE2 default displayer with * default displayer settings. */ this(null); } /** * Instantiate a new <code>JHOVE2CommandLine</code>. * @param ApplicationModuleAccessor * @throws JHOVE2Exception */ public JHOVE2CommandLine(ApplicationModuleAccessor applicationModuleAccessor) throws JHOVE2Exception { /* Super constructor creates {@link org.jhove2.core.AppConfigInfo} with * JHOVE2 default settings, and the JHOVE2 default displayer with * default displayer settings. */ super(VERSION, RELEASE, RIGHTS, Scope.Generic, applicationModuleAccessor); } /** * Main entry point for the JHOVE2 command line application. Creates a * {@linkplain org.jhove2.core.source.FileSetSource file set source unit} * from the files specified on the command line. This file set is passed to * the {@link JHOVE2} object for characterization; this initiates a search * for all unitary and aggregate source units within the file set; these * are characterized in turn. * * @param args Command line arguments */ public static void main(String[] args) { PersistenceManager persistenceManager = null; try { SpringConfigInfo factory = new SpringConfigInfo(); /* Create PersistenceManagerFactory; will be used by ApplicationModuleAccessor to * manage persistence. */ PersistenceManagerUtil.createPersistenceManagerFactory(factory); persistenceManager = PersistenceManagerUtil.getPersistenceManagerFactory().getInstance(); persistenceManager.initialize(); /* Create and initialize the JHOVE2 command-line application. */ JHOVE2CommandLine app = SpringConfigInfo.getReportable(JHOVE2CommandLine.class, "JHOVE2CommandLine"); /* Make sure there is a default displayer. */ Displayer displayer = app.getDisplayer(); if (displayer == null) { Class defaultDisplayerClass = (Class) Class.forName(Displayer.DEFAULT_DISPLAYER_CLASS); displayer = (Displayer)SpringConfigInfo.getReportable(defaultDisplayerClass, "Text"); displayer = app.setDisplayer(displayer); } app.getDisplayer().setConfigInfo(factory); app.setDateTime(new Date()); /* Parse the application command line and update the default (or * Spring-wired) settings in {@link org.jhove2.core.AppConfigInfo} * with any command line options. */ List<String> names = app.parse(args); app = (JHOVE2CommandLine) app.getModuleAccessor().persistModule(app); /* Create and initialize the JHOVE2 framework and register it with * the application. */ JHOVE2 jhove2 = SpringConfigInfo.getReportable(JHOVE2.class, "JHOVE2"); Invocation inv = app.getInvocation(); jhove2.setInvocation(inv); jhove2.setInstallation(app.getInstallation()); /* Create a FileSet source unit out of all files, directories, and * URLS specified on the command line, or a single File, Directory, or * URL if only one is specified. */ Source source = jhove2.getSourceFactory().getSource(jhove2, names); app = (JHOVE2CommandLine) source.addModule(app); jhove2 = (JHOVE2) source.addModule(jhove2); displayer = app.getDisplayer(); /* displayer might have been updated by parse method; */ displayer.setConfigInfo(factory); displayer = (Displayer) source.addModule(displayer); displayer = app.setDisplayer(displayer); /* this will persist the updated Displayer linked to app */ /* Characterize the FileSet source unit (and all subsidiary * source units that it encapsulates. */ jhove2 = (JHOVE2) jhove2.getModuleAccessor().startTimerInfo(jhove2); Input input = source.getInput(jhove2); try { source = jhove2.characterize(source, input); } finally { if (input != null) { input.close(); } } jhove2 = (JHOVE2) jhove2.getModuleAccessor().endTimerInfo(jhove2); /* Display characterization information for the FileSet. */ app.getDisplayer().display(source); } catch (Exception e) { System.err.println(e.getMessage()); e.printStackTrace(System.err); System.exit(EEXCEPTION); } finally{ if (persistenceManager != null){ try{ persistenceManager.close(); } catch (JHOVE2Exception je){ System.err.println(je.getMessage()); je.printStackTrace(System.err); System.exit(EEXCEPTION); } } } } /** * * Parse the JHOVE2 application command line and update the default values * in the {@link org.jhove2.core.Invocation} object with any * command-line settings; and construct the list of formatted object names, * which may be files, directories, or URLs, to be processed by the * application. Also save the commandLine string as an instance member. * * For command line options and usage, refer to the <i>JHOVE2 User's Guide</i>. * * @param args * Command line arguments * @return Formatted object names * @throws JHOVE2Exception */ public List<String> parse(String[] args) throws JHOVE2Exception { Parser parser = new Parser(JHOVE2CommandLine.class.getName()); ArrayList<String> names = new ArrayList<String>(); boolean showIdentifiers = this.getDisplayer().getShowIdentifiers(); String filePathname = null; Integer bufferSize = null; String bufferType = null; String displayerType = null; Integer failFastLimit = null; String tempDirectory = null; String[] otherArgs = null; Invocation config = this.getInvocation(); StringBuffer bufferTypeValues = new StringBuffer(""); for (Input.Type i : Input.Type.values()) { if (i.ordinal() > 0) bufferTypeValues.append("|"); bufferTypeValues.append(i.toString()); } String[] displayers = SpringConfigInfo.getReportableNames(Displayer.class); StringBuffer displayerValues = new StringBuffer(""); for (int i=0;i<displayers.length;i++){ if (i>0) displayerValues.append("|"); displayerValues.append(displayers[i]); } /* set the command line options */ Parser.Option showIdentifiersO = parser.addHelp((parser.addBooleanOption('i',"show-identifiers")), "Show identifiers"); Parser.Option setCalcDigestsO = parser.addHelp(parser.addBooleanOption('k', "calc-digests"), "Calculate message digests"); Parser.Option bufferSizeO = parser.addHelp(parser.addIntegerOption('b', "buffer-size"), "<buffersize>", "I/O buffer size (default=" + Invocation.DEFAULT_BUFFER_SIZE + ")"); Parser.Option bufferTypeO = parser.addHelp(parser.addStringOption('B', "buffer-type"), bufferTypeValues.toString(), "I/O buffer type (default=Direct)"); Parser.Option displayerTypeO = parser.addHelp(parser.addStringOption('d', "display"), displayerValues.toString(), "Display format"); /************** TODO: Fail fast processing is not yet enable. ****************/ /***************************************************************************** Parser.Option failFastLimitO = parser.addHelp(parser.addIntegerOption('f', "fail-fast"), "<failFastLimit>", "Fail fast limit (default=0; " + "no limit on the number of reported errors)"); *****************************************************************************/ Parser.Option tempDirectoryO = parser.addHelp(parser.addStringOption('t', "temp"), "<tempDirectory>", "Temporary file directory (default=java.io.tmpdir)"); Parser.Option deleteTempFilesO = parser.addHelp(parser.addBooleanOption('T', "save-temp-files"), "Save temporary files"); Parser.Option filePathnameO = parser.addHelp(parser.addStringOption('o', "output"), "<outfile>", "Output file (default=standard output unit)"); Parser.Option helpO = parser.addHelp(parser.addBooleanOption('h', "help"), "Show this help message"); try { parser.parse(args); /* Test for valid option values */ if ((bufferType = (String)parser.getOptionValue(bufferTypeO)) != null) { if (bufferTypeValues.indexOf(bufferType) == -1) { throw new Parser.IllegalOptionValueException(bufferTypeO, bufferType); } else { config.setBufferType(Type.valueOf(bufferType)); } } displayerType = (String)parser.getOptionValue(displayerTypeO); if (displayerType != null) { if (displayerValues.indexOf(displayerType) == -1) { throw new Parser.IllegalOptionValueException(displayerTypeO, displayerType); } else { Displayer displayer = (Displayer)SpringConfigInfo.getReportable(Displayer.class, displayerType); displayer = this.setDisplayer(displayer); } } otherArgs = parser.getRemainingArgs(); /* ensure there is at least one file in command line */ if (otherArgs.length < 1) { parser.getUsage(); System.exit(EUSAGE); } } catch ( Parser.OptionException e ) { System.err.println(e.getMessage()); parser.getUsage(); System.exit(EUSAGE); } /* get the options and values */ if ((Boolean)parser.getOptionValue(setCalcDigestsO) != null) { config.setCalcDigests(true); } if ((bufferSize = (Integer)parser.getOptionValue(bufferSizeO)) != null) { config.setBufferSize(bufferSize.intValue()); } // bufferTypeO and displayerTypeO already used above to set config.BufferType and this.Displayer /************* TODO: Fail fast processing is not yet enabled. ****************/ /***************************************************************************** if ((failFastLimit = (Integer)parser.getOptionValue(failFastLimitO)) != null) { config.setFailFastLimit(failFastLimit.intValue()); } *****************************************************************************/ /* Displayer will have been set either to Default displayer by constructor, * or to some other displayer by the handling of the displayerType0 option above */ Displayer displayer = this.getDisplayer(); if ((Boolean)parser.getOptionValue(showIdentifiersO) != null) { showIdentifiers = true; displayer.setShowIdentifiers(showIdentifiers); } if ((tempDirectory = (String)parser.getOptionValue(tempDirectoryO)) != null) { config.setTempDirectory(tempDirectory); } if ((filePathname = (String)parser.getOptionValue(filePathnameO)) != null) { displayer.setFilePathname(filePathname); } if ((Boolean)parser.getOptionValue(deleteTempFilesO) != null) { config.setDeleteTempFiles(false); } if ( Boolean.TRUE.equals(parser.getOptionValue(helpO))) { parser.getUsage(); System.exit(0); } displayer = this.setDisplayer(displayer); /* process remaining arguments */ for (int i = 0; i < otherArgs.length; ++i ) { names.add(otherArgs[i]); } /* save the command line string */ for (int i = 0; i < args.length; i++) { if (i == 0) { this.commandLine = args[i]; } else { this.commandLine += " " + args[i]; } } return names; } /** * @return the persistenceMgrFactoryName */ public String getPersistenceMgrFactoryName() { return persistenceMgrFactoryName; } /** * @param persistenceMgrFactoryName the persistenceMgrFactoryName to set */ public void setPersistenceMgrFactoryName(String persistenceMgrFactoryName) { this.persistenceMgrFactoryName = persistenceMgrFactoryName; } }