/** * JHOVE2 - Next-generation architecture for format-aware characterization * * Copyright (c) 2009 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.util.documenter; import java.io.File; import java.util.ArrayList; import java.util.List; import org.jhove2.app.util.documenter.displayer.DocumentationDisplayer; import org.jhove2.app.util.documenter.displayer.DocumentationDisplayerFactory; import org.jhove2.app.util.traverser.ReportableTypeTraverser; import org.jhove2.config.ConfigInfo; import org.jhove2.config.spring.SpringConfigInfo; import org.jhove2.core.Document; import org.jhove2.core.I8R; import org.jhove2.core.JHOVE2Exception; import org.jhove2.core.format.Format; import org.jhove2.core.reportable.Reportable; import org.jhove2.module.Module; import org.jhove2.module.format.FormatModule; import org.jhove2.module.format.FormatProfile; import org.jhove2.persist.PersistenceManager; import org.jhove2.persist.PersistenceManagerUtil; /** * Intended to collection information about FormatModule, its Format, any Profiles and Profile Formats, * any specifications associated with the format, and the Reportable properties of the FormatModule. * The latter comes from static analysis of the Java class; other information comes for the Spring * Bean in the JHOVE2 configuration files * * @author smorrissey */ public class FormatModuleDocumenter implements ModuleDocumenter { public static final String DEFAULT_DISPLAY = "org.jhove2.app.util.documenter.displayer.FormatModuleTabDelimDisplayer"; /** Usage string */ public static final String USAGE = "USAGE: java -cp CLASSPATH" + FormatModuleDocumenter.class.getName() + " fully-qualified-format-module-class-name output-dir-path" + " {optional} fully-qualified-display-class-name (default " + DEFAULT_DISPLAY + ")}"; /** Fully-qualified class name for which properties file is to be generated */ /** Error return code for erroneous command line invocation */ public static final int EUSAGE = 1; /** Error return code if any exception is thrown while executing program */ public static final int EEXCEPTION = 2; /** Return code for successful execution */ public static final int SUCCESS = 0; /** FormatModule instance to be documented */ protected FormatModule formatModule; /** FormatProfiles associated with module */ protected List<FormatProfile> formatProfiles; /** Format associated with module */ protected Format format; /** Formats associated with module profiles */ protected List<Format> formatProfileFormats; /** container for Format info*/ protected FormatIdDoc formatDoc; /** list of containers for profile formats info */ protected List<FormatIdDoc> formatProfilesDocs; /** container for information about format module */ protected FormatModuleIdDoc formatModuleIdDoc; /** list of containers for information about FormatProfiles */ protected List<FormatModuleIdDoc> formatProfilesIdDocs; /** traverser that collections reportable properties documentation information */ protected ReportableTypeTraverser properties; /** displayer that serializes documentation information*/ protected DocumentationDisplayer displayer; /** * main method * Extracts information and displays it * Requires Spring bean to have been configured for the FormatModule being documented * @param args arguments * fully-qualified-format-module-class-name * output-dir-path * {optional} fully-qualified-display-class-name */ public static void main(String[]args) { if (args.length < 2){ System.out.println(USAGE); System.exit(EUSAGE); } FormatModuleDocumenter fdoc = new FormatModuleDocumenter(); String classname = args[0]; String outputDirName = args[1]; File outputDir = new File(outputDirName); FormatModule module = null; ConfigInfo config = new SpringConfigInfo(); if (!outputDir.exists()){ System.out.println("Output directory " + outputDirName + " does not exist"); System.exit(EEXCEPTION); } try { PersistenceManagerUtil.createPersistenceManagerFactory(config); PersistenceManager persistenceManager = PersistenceManagerUtil.getPersistenceManagerFactory().getInstance(); persistenceManager.initialize(); } catch (JHOVE2Exception e) { System.out.println("Unable to initialize a persistence manageer"); System.exit(EEXCEPTION); } try { Class modClass = Class.forName(classname); module = (FormatModule) config.getReportable(modClass); } catch (Exception e) { System.out.println("Unable to get bean for class " + classname); e.printStackTrace(); System.exit(EEXCEPTION); } String displayClass = DEFAULT_DISPLAY; if (args.length > 2){ displayClass = args[2]; } try { fdoc.displayer = new DocumentationDisplayerFactory().getDocumentationDisplayer(displayClass); fdoc.displayer.setOutputDir(outputDir); } catch (JHOVE2Exception e) { System.out.println("Exception thrown while creating documentation displayer " + displayClass + ": " + e.getMessage()); e.printStackTrace(); System.exit(EEXCEPTION); } try { fdoc.documentModule(module); } catch (JHOVE2Exception e) { System.out.println("Exception thrown while documenting module " + classname + ": " + e.getMessage()); System.exit(EEXCEPTION); } try { fdoc.displayer.displayDocumentation(fdoc); } catch (JHOVE2Exception e) { System.out.println("Exception thrown while displaying documention: " + e.getMessage()); e.printStackTrace(); System.exit(EEXCEPTION); } System.out.println("FormatModuleDocumenter successfully completed:"); System.out.println("\t generated files can be found in directory " + outputDirName); System.exit(SUCCESS); } public FormatModuleDocumenter (){ super(); this.formatProfiles = new ArrayList<FormatProfile>(); this.formatProfileFormats = new ArrayList<Format>(); this.formatProfilesDocs = new ArrayList<FormatIdDoc>(); this.formatProfilesIdDocs = new ArrayList<FormatModuleIdDoc>(); } /** * Entry point for extraction of documentation information about module * @param Module to be documented */ public void documentModule(Reportable reportable) throws JHOVE2Exception { this.formatModule = (FormatModule)reportable; this.format = this.formatModule.getFormat(); this.formatProfiles = this.formatModule.getProfiles(); this.formatModuleIdDoc = this.documentFormatModuleIdInfo(this.formatModule); for (FormatProfile profile:this.formatProfiles){ this.getFormatProfileFormats().add(profile.getFormat()); this.getFormatProfilesIdDocs().add(this.documentFormatModuleIdInfo(profile)); } this.formatDoc = this.documentFormatIdInfo(this.format); for (Format format:this.getFormatProfileFormats()){ this.getFormatProfilesDocs().add(this.documentFormatIdInfo(format)); } this.properties = new ReportableTypeTraverser(reportable.getClass().getCanonicalName(),true); this.properties.extractDocInfo(); return; } /** * Extracts basic identifying information about format module or profile * Intended for Section 2 (Identification) in Format Module Specification Document * @param formatModule * @return FormatModuleIdDoc basic identifying information about format module * @throws JHOVE2Exception */ public FormatModuleIdDoc documentFormatModuleIdInfo(Module formatModule) throws JHOVE2Exception { FormatModuleIdDoc formatIdDoc = new FormatModuleIdDoc(); formatIdDoc.moduleName = formatModule.getReportableName(); formatIdDoc.moduleId = formatModule.getReportableIdentifier().toString(); formatIdDoc.moduleClassName = formatModule.getClass().getCanonicalName(); return formatIdDoc; } /** * Extracts basic identifying information about format or profile format * Intended for Section 2 (Identification) in Format Module Specification Document * @param format Format to be documented * @return FormatIdDoc with basic identifying information about format or profile format * @throws JHOVE2Exception */ public FormatIdDoc documentFormatIdInfo(Format format) throws JHOVE2Exception { FormatIdDoc formatIdDoc = new FormatIdDoc(); formatIdDoc.canonicalFormatName = format.getName(); formatIdDoc.canonicalFormatIdentifier = format.getIdentifier().toString(); if (format.getAliasNames()!= null){ formatIdDoc.aliasFormatNames.addAll(format.getAliasNames()); } if (format.getAliasIdentifiers()!= null){ for (I8R id:format.getAliasIdentifiers()){ String idString = id.toString(); formatIdDoc.aliasFormatIdentifiers.add(idString); } } if (format.getSpecifications()!= null){ for (Document doc:format.getSpecifications()){ Document.Intention intent = doc.getIntention(); if (!formatIdDoc.references.containsKey(intent)){ List<ReferenceDoc> refDocs = new ArrayList<ReferenceDoc>(); formatIdDoc.references.put(intent, refDocs); } List<ReferenceDoc> refDocs = formatIdDoc.references.get(intent); ReferenceDoc refDoc = new ReferenceDoc(); refDoc.refName = doc.getTitle(); refDoc.biblioInfo = this.createBiblioInfo(doc); for (I8R id:doc.getIdentifiers()){ String idString = id.toString(); refDoc.identifiers.add(idString); } refDocs.add(refDoc); } } return formatIdDoc; } /** * Create bibliographic string with information about a Format reference * Intended for section 3 (References) of format module specification * @param doc Document object for a reference associated with a Format * @return bibliographic string with information about a Format reference */ public String createBiblioInfo(Document doc) { String authors = doc.getAuthor(); String date = doc.getDate(); String edition = doc.getEdition(); String publisher = doc.getPublisher(); String title = doc.getTitle(); StringBuffer sbBib = new StringBuffer(); if (authors != null && authors.length()>0){ sbBib.append(authors); sbBib.append(". "); } if (title != null && title.length()>0){ sbBib.append(title); if (edition != null && edition.length()>0){ sbBib.append(" "); sbBib.append(edition); } sbBib.append(". "); } if (!(date==null && publisher==null)){ sbBib.append("("); if (publisher !=null){ sbBib.append(publisher); if (date != null){ sbBib.append(", "); sbBib.append(date); } } else { sbBib.append(date); } sbBib.append(")"); } return sbBib.toString(); } /** * @return the formatModule */ public FormatModule getFormatModule() { return formatModule; } /** * @return the formatProfiles */ public List<FormatProfile> getFormatProfiles() { return formatProfiles; } /** * @return the format */ public Format getFormat() { return format; } /** * @return the formatProfileFormats */ public List<Format> getFormatProfileFormats() { return formatProfileFormats; } /** * @return the formatDoc */ public FormatIdDoc getFormatDoc() { return formatDoc; } /** * @return the formatProfilesDocs */ public List<FormatIdDoc> getFormatProfilesDocs() { return formatProfilesDocs; } /** * @return the formatModuleIdDoc */ public FormatModuleIdDoc getFormatModuleIdDoc() { return formatModuleIdDoc; } /** * @return the formatProfilesIdDocs */ public List<FormatModuleIdDoc> getFormatProfilesIdDocs() { return formatProfilesIdDocs; } /** * @return the properties */ public ReportableTypeTraverser getProperties() { return properties; } /** * @param formatModule the formatModule to set */ public void setFormatModule(FormatModule formatModule) { this.formatModule = formatModule; } /** * @param formatProfiles the formatProfiles to set */ public void setFormatProfiles(List<FormatProfile> formatProfiles) { this.formatProfiles = formatProfiles; } /** * @param format the format to set */ public void setFormat(Format format) { this.format = format; } /** * @param formatProfileFormats the formatProfileFormats to set */ public void setFormatProfileFormats(List<Format> formatProfileFormats) { this.formatProfileFormats = formatProfileFormats; } /** * @param formatDoc the formatDoc to set */ public void setFormatDoc(FormatIdDoc formatDoc) { this.formatDoc = formatDoc; } /** * @param formatProfilesDocs the formatProfilesDocs to set */ public void setFormatProfilesDocs(List<FormatIdDoc> formatProfilesDocs) { this.formatProfilesDocs = formatProfilesDocs; } /** * @param formatModuleIdDoc the formatModuleIdDoc to set */ public void setFormatModuleIdDoc(FormatModuleIdDoc formatModuleIdDoc) { this.formatModuleIdDoc = formatModuleIdDoc; } /** * @param formatProfilesIdDocs the formatProfilesIdDocs to set */ public void setFormatProfilesIdDocs(List<FormatModuleIdDoc> formatProfilesIdDocs) { this.formatProfilesIdDocs = formatProfilesIdDocs; } /** * @param properties the properties to set */ public void setProperties(ReportableTypeTraverser properties) { this.properties = properties; } }