diff --git a/jhove-apps/src/main/java/edu/harvard/hul/ois/jhove/viewer/RepTreeRoot.java b/jhove-apps/src/main/java/edu/harvard/hul/ois/jhove/viewer/RepTreeRoot.java index c3bbc9900..49448e035 100644 --- a/jhove-apps/src/main/java/edu/harvard/hul/ois/jhove/viewer/RepTreeRoot.java +++ b/jhove-apps/src/main/java/edu/harvard/hul/ois/jhove/viewer/RepTreeRoot.java @@ -29,6 +29,7 @@ import edu.harvard.hul.ois.jhove.Rational; import edu.harvard.hul.ois.jhove.RepInfo; import edu.harvard.hul.ois.jhove.TextMDMetadata; +import edu.harvard.hul.ois.jhove.handler.Handlers; /** * This subclass of DefaultMutableTreeNode simply adds a method for constructing @@ -48,6 +49,7 @@ public class RepTreeRoot extends DefaultMutableTreeNode { /* Sample rate. */ private double _sampleRate; + private String reportingModule = ""; /** * Constructor. @@ -255,7 +257,8 @@ private void snarfRepInfo() { // leaf children. DefaultMutableTreeNode moduleNode = new DefaultMutableTreeNode( "Module"); - moduleNode.add(new DefaultMutableTreeNode(module.getName(), false)); + this.reportingModule = module.getName(); + moduleNode.add(new DefaultMutableTreeNode(this.reportingModule, false)); moduleNode.add(new DefaultMutableTreeNode("Release: " + module.getRelease(), false)); moduleNode.add(new DefaultMutableTreeNode("Date: " @@ -350,6 +353,8 @@ private void snarfRepInfo() { if (msg.getId() != null && !msg.getId().isEmpty()) { mNode.add(new DefaultMutableTreeNode("ID: " + msg.getId())); + mNode.add(new DefaultMutableTreeNode("InfoLink: " + + Handlers.makeInfoLink(this.reportingModule, msg.getId()))); } String subMessage = msg.getSubMessage(); diff --git a/jhove-bbt/scripts/create-1.32-target.sh b/jhove-bbt/scripts/create-1.32-target.sh index 6857fa33d..5514bf82e 100755 --- a/jhove-bbt/scripts/create-1.32-target.sh +++ b/jhove-bbt/scripts/create-1.32-target.sh @@ -57,9 +57,9 @@ echo " - copying ${baselineRoot} baseline to ${targetRoot}" cp -R "${baselineRoot}" "${targetRoot}" # Patch release details of the reporting module in the audit file -find "${targetRoot}" -type f -name "audit.jhove.xml" -exec sed -i 's/outputHandler release="1.11">XML/outputHandler release="1.12">XML/' {} \; -find "${targetRoot}" -type f -name "audit.jhove.xml" -exec sed -i 's/outputHandler release="1.2">JSON/outputHandler release="1.3">JSON/' {} \; -find "${targetRoot}" -type f -name "audit.jhove.xml" -exec sed -i 's/outputHandler release="1.6">TEXT/outputHandler release="1.7">TEXT/' {} \; +find "${targetRoot}" -type f -name "audit.jhove.xml" -exec sed -i 's/outputHandler release="1.11">XML/outputHandler release="1.13">XML/' {} \; +find "${targetRoot}" -type f -name "audit.jhove.xml" -exec sed -i 's/outputHandler release="1.2">JSON/outputHandler release="1.4">JSON/' {} \; +find "${targetRoot}" -type f -name "audit.jhove.xml" -exec sed -i 's/outputHandler release="1.6">TEXT/outputHandler release="1.8">TEXT/' {} \; # Update release details for HTML module find "${targetRoot}" -type f -name "*.html.jhove.xml" -exec sed -i 's/HTML-hul<\/reportingModule>/HTML-hul<\/reportingModule>/' {} \; @@ -211,3 +211,84 @@ do cp "${candidateRoot}/${filename}" "${targetRoot}/${filename}" fi done + +declare -a wiki_link_affected=("errors/modules/PDF-hul/pdf-hul-73-bug-size-int.pdf.jhove.xml" + "errors/modules/PDF-hul/pdf-hul-52-govdocs-983827.pdf.jhove.xml" + "errors/modules/PDF-hul/pdf-hul-79-govdocs-095305.pdf.jhove.xml" + "errors/modules/PDF-hul/pdf-hul-43-govdocs-486355.pdf.jhove.xml" + "errors/modules/PDF-hul/pdf-hul-34-govdocs-259511.pdf.jhove.xml" + "errors/modules/PDF-hul/pdf-hul-82-govdocs-333472.pdf.jhove.xml" + "errors/modules/PDF-hul/pdf-hul-51-govdocs-085551.pdf.jhove.xml" + "errors/modules/PDF-hul/pdf-hul-76-372051162.pdf.jhove.xml" + "errors/modules/PDF-hul/pdf-hul-61-CERN-2005-009.pdf.jhove.xml" + "errors/modules/PDF-hul/pdf-hul-29-govdocs-375118.pdf.jhove.xml" + "errors/modules/PDF-hul/pdf-hul-13-govdocs-346874.pdf.jhove.xml" + "errors/modules/PDF-hul/pdf-hul-9-govdocs-065694.pdf.jhove.xml" + "errors/modules/PDF-hul/pdf-hul-1-govdocs-519846.pdf.jhove.xml" + "errors/modules/PDF-hul/pdf-hul-86-govdocs-445892.pdf.jhove.xml" + "errors/modules/PDF-hul/pdf-hul-62-567147525.pdf.jhove.xml" + "errors/modules/PDF-hul/corruptionOneByteMissing.pdf.jhove.xml" + "errors/modules/PDF-hul/pdf-hul-76-govdocs-289573.pdf.jhove.xml" + "errors/modules/PDF-hul/pdf-hul-35-govdocs-156429.pdf.jhove.xml" + "errors/modules/PDF-hul/pdf-hul-5-govdocs-659152.pdf.jhove.xml" + "errors/modules/PDF-hul/pdf-hul-49-32932439X.pdf.jhove.xml" + "errors/modules/JPEG2000-hul/signature_corrupted.jp2.jhove.xml" + "errors/modules/JPEG2000-hul/隨機中國文字.jp2.jhove.xml" + "errors/modules/JPEG2000-hul/bitwiser-icc-corrupted-tagcount-1984.jp2.jhove.xml" + "errors/modules/JPEG2000-hul/missing_null_terminator_in_urlbox.jp2.jhove.xml" + "errors/modules/JPEG2000-hul/ランダム日本語テキスト.jp2.jhove.xml" + "errors/modules/JPEG2000-hul/invalid_character_in_xml.jp2.jhove.xml" + "errors/modules/JPEG2000-hul/is_codestream.jp2.jhove.xml" + "errors/modules/JPEG2000-hul/truncated_at_byte_5000.jp2.jhove.xml" + "errors/modules/JPEG2000-hul/bitwiser-icc-corrupted-tagcount-1971.jp2.jhove.xml" + "errors/modules/JPEG2000-hul/openJPEG15.jp2.jhove.xml" + "errors/modules/JPEG2000-hul/meth_is_2_no_icc.jp2.jhove.xml" + "errors/modules/JPEG2000-hul/bitwiser-icc-corrupted-tagcount-1999.jp2.jhove.xml" + "errors/modules/JPEG2000-hul/is_jpeg.jp2.jhove.xml" + "errors/modules/JPEG2000-hul/bitwiser-icc-corrupted-tagcount-1920.jp2.jhove.xml" + "errors/modules/JPEG2000-hul/triggerUnboundLocalError.jp2.jhove.xml" + "errors/modules/JPEG2000-hul/README.md.jhove.xml" + "errors/modules/JPEG2000-hul/last_byte_missing.jp2.jhove.xml" + "errors/modules/JPEG2000-hul/bitwiser-icc-corrupted-tagcount-1951.jp2.jhove.xml" + "errors/modules/JPEG2000-hul/is_jpm.jp2.jhove.xml" + "errors/modules/JPEG2000-hul/bitwiser-icc-corrupted-tagcount-1961.jp2.jhove.xml" + "errors/modules/JPEG2000-hul/bitwiser-icc-corrupted-tagcount-2011.jp2.jhove.xml" + "errors/modules/JPEG2000-hul/empty.jp2.jhove.xml" + "errors/modules/JPEG2000-hul/height_image_header_damaged.jp2.jhove.xml" + "errors/modules/JPEG2000-hul/palettedImage.jp2.jhove.xml" + "errors/modules/JPEG2000-hul/bitwiser-icc-corrupted-tagcount-1937.jp2.jhove.xml" + "errors/modules/JPEG2000-hul/data_missing_in_last_tilepart.jp2.jhove.xml" + "errors/modules/JPEG2000-hul/bitwiser-icc-corrupted-tagcount-1911.jp2.jhove.xml" + "errors/modules/JPEG2000-hul/bitwiser-icc-corrupted-tagcount-2021.jp2.jhove.xml" + "errors/modules/JPEG2000-hul/reference.jp2.jhove.xml" + "regression/modules/JPEG-hul/19_e190014.jpg.jhove.xml" + "regression/modules/PDF-hul/issue_662.pdf.jhove.xml" + "regression/modules/PDF-hul/pdf-hul-55-govdocs-616137.pdf.jhove.xml" + "regression/modules/PDF-hul/class-cast.pdf.jhove.xml" + "regression/modules/PDF-hul/null-string.pdf.jhove.xml" + "regression/modules/PDF-hul/issue_473_a.pdf.jhove.xml" + "regression/modules/PDF-hul/extensions-adbe-other.pdf.jhove.xml" + "regression/modules/PDF-hul/pdf-hul-59-govdocs-681811.pdf.jhove.xml" + "regression/modules/PDF-hul/issue_645.pdf.jhove.xml" + "regression/modules/PDF-hul/null-string-sig-2.pdf.jhove.xml" + "regression/modules/PDF-hul/issue_531.pdf.jhove.xml" + "regression/modules/PDF-hul/null-string-sig-1.pdf.jhove.xml" + "regression/modules/PDF-hul/pdf-hul-65-847453723.pdf.jhove.xml" + "regression/modules/PDF-hul/pdf-hul-40-govdocs-088919.pdf.jhove.xml" + "examples/modules/PDF-hul/AA_Banner.pdf.jhove.xml" + "examples/modules/TIFF-hul/fax2d.g3.jhove.xml" + "examples/modules/TIFF-hul/chase-tif-f.tif.jhove.xml" + "examples/modules/TIFF-hul/g3test.g3.jhove.xml" + "examples/modules/TIFF-hul/smallliz.tif.jhove.xml" + "examples/modules/TIFF-hul/zackthecat.tif.jhove.xml" + "examples/modules/HTML-hul/Validate3.2.html.jhove.xml" + "examples/modules/HTML-hul/Validate4.0Trans.html.jhove.xml" + "examples/modules/HTML-hul/Validate4.0Frameset.html.jhove.xml" + "examples/modules/HTML-hul/Validate4.01Trans.html.jhove.xml" + "examples/modules/HTML-hul/Validate4.01Frameset.html.jhove.xml") +for filename in "${wiki_link_affected[@]}" +do + if [[ -f "${candidateRoot}/${filename}" ]]; then + cp "${candidateRoot}/${filename}" "${targetRoot}/${filename}" + fi +done diff --git a/jhove-core/src/main/java/edu/harvard/hul/ois/jhove/handler/Handlers.java b/jhove-core/src/main/java/edu/harvard/hul/ois/jhove/handler/Handlers.java new file mode 100644 index 000000000..99855fbbc --- /dev/null +++ b/jhove-core/src/main/java/edu/harvard/hul/ois/jhove/handler/Handlers.java @@ -0,0 +1,12 @@ +package edu.harvard.hul.ois.jhove.handler; + +public class Handlers { + private Handlers() { + throw new AssertionError("Instantiating utility class..."); + } + + public static final String makeInfoLink(final String reportingModule, final String jhoveId) { + return String.format("https://github.com/openpreserve/jhove/wiki/%s-Messages#%s", + reportingModule, jhoveId.toLowerCase()); + } +} diff --git a/jhove-core/src/main/java/edu/harvard/hul/ois/jhove/handler/JsonHandler.java b/jhove-core/src/main/java/edu/harvard/hul/ois/jhove/handler/JsonHandler.java index e6cfa2cc6..ec907b796 100644 --- a/jhove-core/src/main/java/edu/harvard/hul/ois/jhove/handler/JsonHandler.java +++ b/jhove-core/src/main/java/edu/harvard/hul/ois/jhove/handler/JsonHandler.java @@ -60,2058 +60,2062 @@ * */ public class JsonHandler extends HandlerBase { - /****************************************************************** - * PRIVATE CLASS FIELDS. - ******************************************************************/ - - /** Handler name. */ - private static final String NAME = "JSON"; - - /** Handler release identifier. */ - private static final String RELEASE = "1.3"; - - /** String release. */ - private static final String RELEASE_CONSTANT = "release"; - - /** Handler release date. */ - private static final int[] DATE = { 2024, 8, 22 }; - - private static final String DATE_CONSTANT = "date"; - - /** well-formed. */ - private static final String WELL_FORMED = "Well-Formed"; - - /** not well-formed. */ - private static final String NOT_WELL_FORMED = "Not well-formed"; - - /** mix:tiles. */ - private static final String MIX_TILES = "mix:tiles"; - - /** mix:extraSamples. */ - private static final String MIX_EXTRA_SAMPLES = "mix:extraSamples"; - - /** mix:grayResponseUnit. */ - private static final String MIX_GRAY_RESPONSE_UNIT = "mix:grayResponseUnit"; - - /** Handler NTSC_NON_DROP_FRAME. */ - private static final String NTSC_NON_DROP_FRAME = "NTSC_NON_DROP_FRAME"; - - /** Handler note. */ - private static final String NOTE = ""; - - /** Handler rights statement. */ - private static final String RIGHTS = "Version 1.0 release by Open Preservation Foundation. " - + "Released under the GNU Lesser General Public License."; - - /****************************************************************** - * PRIVATE INSTANCE FIELDS. - ******************************************************************/ - - /** Main JSON builder */ - private JsonObjectBuilder jhoveBuilder; - private JsonArrayBuilder repInfosBuilder; - - /* Sample rate. */ - private double _sampleRate; - - /****************************************************************** - * CLASS CONSTRUCTOR. - ******************************************************************/ - - /** - * Creates an JsonHandler. - */ - public JsonHandler() { - super(NAME, RELEASE, DATE, NOTE, RIGHTS); - _vendor = Agent.bnfInstance(); - } - - /** Constructor for use by subclasses. */ - public JsonHandler(String name, String release, int[] date, String note, - String rights) { - super(name, release, date, note, rights); - _vendor = Agent.bnfInstance(); - } - - /****************************************************************** - * PUBLIC INSTANCE METHODS. - ******************************************************************/ - - /** - * Outputs minimal information about the application - */ - @Override - public void show() { - _level--; - } - - /** - * Outputs detailed information about the application, including - * configuration, available modules and handlers, etc. - */ - @Override - public void show(App app) { - JsonObjectBuilder appBuilder = Json.createObjectBuilder(); - - JsonObjectBuilder apiBuilder = Json.createObjectBuilder(); - apiBuilder.add("version", app.getRelease()); - apiBuilder.add(DATE_CONSTANT, date.format(_je.getDate())); - appBuilder.add("api", apiBuilder); - - String configFile = _je.getConfigFile(); - if (configFile != null) { - appBuilder.add("configuration", configFile); - } - String s = _je.getSaxClass(); - if (s != null) { - appBuilder.add("saxParser", s); - } - s = _je.getJhoveHome(); - if (s != null) { - appBuilder.add("jhoveHome", s); - } - s = _je.getEncoding(); - if (s != null) { - appBuilder.add("encoding", s); - } - s = _je.getTempDirectory(); - if (s != null) { - appBuilder.add("tempDirectory", s); - } - appBuilder.add("bufferSize", _je.getBufferSize()); - - JsonArrayBuilder modulesBuilder = Json.createArrayBuilder(); - for (String modKey : _je.getModuleMap().keySet()) { - Module module = _je.getModule(modKey); - modulesBuilder.add(Json.createObjectBuilder() - .add("module", module.getName()) - .add(RELEASE_CONSTANT, module.getRelease())); - - } - appBuilder.add("modules", modulesBuilder); - - JsonArrayBuilder oHandlersBuilder = Json.createArrayBuilder(); - for (String handlerKey : _je.getHandlerMap().keySet()) { - OutputHandler handler = _je.getHandler(handlerKey); - oHandlersBuilder.add(Json.createObjectBuilder() - .add("outputHandler", handler.getName()) - .add(RELEASE_CONSTANT, handler.getRelease())); - } - appBuilder.add("outputHandlers", oHandlersBuilder); - - appBuilder.add("usage", app.getUsage()); - appBuilder.add("rights", app.getRights()); - - jhoveBuilder.add("app", appBuilder); - } - - /** - * Outputs information about the OutputHandler specified in the parameter - */ - @Override - public void show(OutputHandler handler) { - JsonObjectBuilder outputHandlerBuilder = Json.createObjectBuilder(); - outputHandlerBuilder.add("name", handler.getName()); - outputHandlerBuilder.add(RELEASE_CONSTANT, handler.getRelease()); - outputHandlerBuilder.add(DATE_CONSTANT, date.format(handler.getDate())); - List list = handler.getSpecification(); - int n = list.size(); - if (n > 0) { - JsonArrayBuilder specBuilder = Json.createArrayBuilder(); - for (int i = 0; i < n; i++) { - specBuilder.add(showDocument(list.get(i))); - } - outputHandlerBuilder.add("specifications", specBuilder); - } - Agent vendor = handler.getVendor(); - if (vendor != null) { - outputHandlerBuilder.add("vendor", showAgent(vendor, "Vendor")); - } - String s; - if ((s = handler.getNote()) != null) { - outputHandlerBuilder.add("note", s); - } - if ((s = handler.getRights()) != null) { - outputHandlerBuilder.add("rights", s); - } - - jhoveBuilder.add("handler", outputHandlerBuilder); - } - - /** - * Outputs information about a Module - */ - @Override - public void show(Module module) { - JsonObjectBuilder modBuilder = Json.createObjectBuilder(); - modBuilder.add("name", module.getName()); - modBuilder.add(RELEASE_CONSTANT, module.getRelease()); - modBuilder - .add(DATE_CONSTANT, HandlerBase.date.format(module.getDate())); - - String[] ss = module.getFormat(); - if (ss.length > 0) { - modBuilder.add("formats", showArray(ss)); - } - String s = module.getCoverage(); - if (s != null) { - modBuilder.add("coverage", s); - } - ss = module.getMimeType(); - if (ss.length > 0) { - modBuilder.add("mimeTypes", showArray(ss)); - } - List list1 = module.getSignature(); - if (list1 != null && !list1.isEmpty()) { - JsonArrayBuilder sigBuilder = Json.createArrayBuilder(); - for (Signature sig : list1) { - sigBuilder.add(showSignature(sig)); - } - modBuilder.add("signatures", sigBuilder); - } - List list2 = module.getSpecification(); - if (list2 != null && !list2.isEmpty()) { - JsonArrayBuilder docBuilder = Json.createArrayBuilder(); - for (Document doc : list2) { - docBuilder.add(showDocument(doc)); - } - modBuilder.add("specifications", docBuilder); - } - List ftr = module.getFeatures(); - if (ftr != null && !ftr.isEmpty()) { - JsonArrayBuilder featuresBuilder = Json.createArrayBuilder(); - for (String f : ftr) { - featuresBuilder.add(f); - } - modBuilder.add("features", featuresBuilder); - } - - JsonObjectBuilder methodBuilder = Json.createObjectBuilder(); - if ((s = module.getWellFormedNote()) != null) { - methodBuilder.add("wellFormed", s); - } - if ((s = module.getValidityNote()) != null) { - methodBuilder.add("validity", s); - } - if ((s = module.getRepInfoNote()) != null) { - methodBuilder.add("repInfo", s); - } - modBuilder.add("methodology", methodBuilder); - - Agent vendor = module.getVendor(); - if (vendor != null) { - modBuilder.add("vendor", showAgent(vendor, "Vendor")); - } - if ((s = module.getNote()) != null) { - modBuilder.add("note", s); - } - if ((s = module.getRights()) != null) { - modBuilder.add("rights", s); - } - - jhoveBuilder.add("module", modBuilder); - } - - /** - * Outputs the information contained in a RepInfo object - */ - @Override - public void show(RepInfo info) { - JsonObjectBuilder infoBuilder = Json.createObjectBuilder(); - - Module module = info.getModule(); - _logger.info("Reporting RepInfo"); - if (_je.getSignatureFlag()) { - _logger.info("Checking signatures only"); - } - infoBuilder.add("uri", info.getUri()); - - if (module != null) { - infoBuilder.add( - "reportingModule", - Json.createObjectBuilder().add("name", module.getName()) - .add(RELEASE_CONSTANT, module.getRelease()) - .add(DATE_CONSTANT, date.format(module.getDate()))); - } - Date date = info.getCreated(); - if (date != null) { - infoBuilder.add("created", toDateTime(date)); - } - date = info.getLastModified(); - if (date != null) { - infoBuilder.add("lastModified", toDateTime(date)); - } - long size = info.getSize(); - if (size > -1) { - infoBuilder.add("size", size); - } - String s = info.getFormat(); - if (s != null) { - infoBuilder.add("format", s); - } - if ((s = info.getVersion()) != null) { - infoBuilder.add("version", s); - } - String wfStr; - if (!_je.getSignatureFlag()) { - switch (info.getWellFormed()) { - case RepInfo.TRUE: - wfStr = WELL_FORMED; - break; - - case RepInfo.FALSE: - wfStr = NOT_WELL_FORMED; - break; - - default: - wfStr = "Unknown"; - break; - } - // If it's well-formed, append validity information - if (info.getWellFormed() == RepInfo.TRUE) { - switch (info.getValid()) { - case RepInfo.TRUE: - wfStr += " and valid"; - break; - - case RepInfo.FALSE: - wfStr += ", but not valid"; - break; - - default: - // case UNDETERMINED: add nothing - break; - } - } - _logger.info("Validity/WF status: " + wfStr); - infoBuilder.add("status", wfStr); - } else { - // If we aren't checking signatures, we still need to say something. - switch (info.getWellFormed()) { - case RepInfo.TRUE: - wfStr = WELL_FORMED; - break; - - default: - wfStr = NOT_WELL_FORMED; - break; - } - infoBuilder.add("status", wfStr); - } - - List list1 = info.getSigMatch(); - if (list1 != null && !list1.isEmpty()) { - JsonArrayBuilder sigBuilder = Json.createArrayBuilder(); - for (String sigm : list1) { - sigBuilder.add(sigm); - } - infoBuilder.add("sigMatch", sigBuilder); - } - - List list2 = info.getMessage(); - if (list2 != null && !list2.isEmpty()) { - JsonArrayBuilder msgBuilder = Json.createArrayBuilder(); - for (Message msg : list2) { - msgBuilder.add(showMessage(msg)); - } - infoBuilder.add("messages", msgBuilder); - } - - s = info.getMimeType(); - if (s != null) { - infoBuilder.add("mimeType", s); - } - - List list3 = info.getProfile(); - if (list3 != null && !list3.isEmpty()) { - JsonArrayBuilder profBuilder = Json.createArrayBuilder(); - for (String prof : list3) { - profBuilder.add(prof); - } - infoBuilder.add("profiles", profBuilder); - } - - Map map = info.getProperty(); - if (map != null && !map.isEmpty()) { - JsonArrayBuilder propBuilder = Json.createArrayBuilder(); - for (String key : map.keySet()) { - Property property = info.getProperty(key); - propBuilder.add(showProperty(property)); - } - infoBuilder.add("properties", propBuilder); - } - - List list4 = info.getChecksum(); - if (list4 != null && !list4.isEmpty()) { - JsonArrayBuilder checksumBuilder = Json.createArrayBuilder(); - for (Checksum ck : list4) { - checksumBuilder.add(showChecksum(ck)); - } - infoBuilder.add("properties", checksumBuilder); - } - - if ((s = info.getNote()) != null) { - infoBuilder.add("note", s); - } - - // Store the infoBuilder in the array of repInfos - if (repInfosBuilder == null) { - repInfosBuilder = Json.createArrayBuilder(); - } - repInfosBuilder.add(infoBuilder); - } - - /****************************************************************** - * PRIVATE INSTANCE METHODS. - ******************************************************************/ - protected JsonObjectBuilder showAgent(Agent agent, String label) { - JsonObjectBuilder agentBuilder = Json.createObjectBuilder(); - agentBuilder.add("kind", label); - agentBuilder.add("name", agent.getName()); - agentBuilder.add("type", agent.getType().toString()); - String s = agent.getAddress(); - if (s != null) { - agentBuilder.add("address", s); - } - if ((s = agent.getTelephone()) != null) { - agentBuilder.add("telephone", s); - } - if ((s = agent.getFax()) != null) { - agentBuilder.add("fax", s); - } - if ((s = agent.getEmail()) != null) { - agentBuilder.add("email", s); - } - if ((s = agent.getWeb()) != null) { - agentBuilder.add("web", s); - } - return agentBuilder; - } - - protected JsonObjectBuilder showChecksum(Checksum checksum) { - return Json.createObjectBuilder().add("checksum", checksum.getValue()) - .add("type", checksum.getType().toString()); - } - - protected JsonObjectBuilder showDocument(Document document) { - JsonObjectBuilder docBuilder = Json.createObjectBuilder(); - docBuilder.add("title", document.getTitle()); - docBuilder.add("type", document.getType().toString()); - List list1 = document.getAuthor(); - if (list1 != null && !list1.isEmpty()) { - JsonArrayBuilder autBuilder = Json.createArrayBuilder(); - for (Agent ag : list1) { - autBuilder.add(showAgent(ag, "Author")); - } - docBuilder.add("authors", autBuilder); - } - List list2 = document.getPublisher(); - if (list2 != null && !list2.isEmpty()) { - JsonArrayBuilder pubBuilder = Json.createArrayBuilder(); - for (Agent ag : list2) { - pubBuilder.add(showAgent(ag, "Publisher")); - } - docBuilder.add("publishers", pubBuilder); - } - String s = document.getEdition(); - if (s != null) { - docBuilder.add("edition", s); - } - if ((s = document.getDate()) != null) { - docBuilder.add(DATE_CONSTANT, s); - } - if ((s = document.getEnumeration()) != null) { - docBuilder.add("enumeration", s); - } - if ((s = document.getPages()) != null) { - docBuilder.add("pages", s); - } - List list3 = document.getIdentifier(); - if (list3 != null && !list3.isEmpty()) { - JsonArrayBuilder idBuilder = Json.createArrayBuilder(); - for (Identifier id : list3) { - idBuilder.add(showIdentifier(id)); - } - docBuilder.add("identifiers", idBuilder); - } - if ((s = document.getNote()) != null) { - docBuilder.add("note", s); - } - return docBuilder; - } - - /** - * Do the final output. This should be in a suitable format for including - * multiple files between the header and the footer, and the XML of the - * header and footer must balance out. - */ - @Override - public void showFooter() { - if (repInfosBuilder != null) { - jhoveBuilder.add("repInfo", repInfosBuilder); - } - - JsonObjectBuilder mainBuilder = Json.createObjectBuilder(); - mainBuilder.add("jhove", jhoveBuilder); - JsonObject jsonObject = mainBuilder.build(); - - JsonWriter jsonWriter = Json.createWriter(_writer); - jsonWriter.writeObject(jsonObject); - jsonWriter.close(); - } - - /** - * Do the initial output. This should be in a suitable format for including - * multiple files between the header and the footer, and the XML of the - * header and footer must balance out. - */ - @Override - public void showHeader() { - jhoveBuilder = Json.createObjectBuilder(); - jhoveBuilder.add("name", _app.getName()); - jhoveBuilder.add(RELEASE_CONSTANT, _app.getRelease()); - jhoveBuilder - .add(DATE_CONSTANT, HandlerBase.date.format(_app.getDate())); - jhoveBuilder.add("executionTime", toDateTime(new Date())); - repInfosBuilder = null; - } - - protected JsonObjectBuilder showIdentifier(Identifier identifier) { - JsonObjectBuilder idBuilder = Json.createObjectBuilder(); - idBuilder.add("value", identifier.getValue()); - idBuilder.add("type", identifier.getType().toString()); - String note = identifier.getNote(); - if (note != null) { - idBuilder.add("note", note); - } - return idBuilder; - } - - protected JsonObjectBuilder showMessage(Message message) { - JsonObjectBuilder msgBuilder = Json.createObjectBuilder(); - - msgBuilder.add("message", message.getMessage()); - String submsg = message.getSubMessage(); - if (submsg != null) { - msgBuilder.add("subMessage", submsg); - } - long offset = message.getOffset(); - if (offset > -1) { - msgBuilder.add("offset", offset); - } - if (!message.getPrefix().isEmpty()) { - msgBuilder.add("severity", message.getPrefix().toLowerCase()); - } - String id = message.getJhoveMessage().getId(); - if (!(id == null || id.isEmpty() || JhoveMessages.NO_ID.equals(id))) { - msgBuilder.add("id", message.getId()); - } - return msgBuilder; - } - - protected JsonObjectBuilder showSignature(Signature signature) { - JsonObjectBuilder sigBuilder = Json.createObjectBuilder(); - - String sigValue; - if (signature.isStringValue()) { - sigValue = signature.getValueString(); - } else { - sigValue = signature.getValueHexString(); - } - sigBuilder.add("type", signature.getType().toString()); - sigBuilder.add("value", sigValue); - if (SignatureType.MAGIC.equals(signature.getType()) - && ((InternalSignature) signature).hasFixedOffset()) { - sigBuilder - .add("offset", - "0x" - + Integer - .toHexString(((InternalSignature) signature) - .getOffset())); - } - String note = signature.getNote(); - if (note != null) { - sigBuilder.add("note", note); - - } - String use = signature.getUse().toString(); - if (use != null) { - sigBuilder.add("use", use); - } - return sigBuilder; - } - - /* Do special conversions on values as needed. */ - protected String valueToString(Object obj) { - if (obj instanceof Date) { - return toDateTime((Date) obj); - } - return obj.toString(); - } - - protected JsonObjectBuilder showProperty(Property property) { - JsonObjectBuilder propBuilder = Json.createObjectBuilder(); - - PropertyArity arity = property.getArity(); - switch (arity) { - case SCALAR: - return showScalarProperty(property); - case ARRAY: - return showArrayProperty(property); - case LIST: - return showListProperty(property); - case MAP: - return showMapProperty(property); - case SET: - return showSetProperty(property); - default: - return propBuilder; - } - } - - protected JsonObjectBuilder showScalarProperty(Property property) { - JsonObjectBuilder propBuilder = Json.createObjectBuilder(); - - PropertyType propType = property.getType(); - switch (propType) { - case BOOLEAN: - Boolean b = (Boolean) property.getValue(); - propBuilder.add(property.getName(), b.booleanValue()); - break; - case BYTE: - case CHARACTER: - case OBJECT: - propBuilder.add(property.getName(), property.getValue().toString()); - break; - case DATE: - Date dt = (Date) property.getValue(); - propBuilder.add(property.getName(), toDateTime(dt)); - break; - case DOUBLE: - Double d = (Double) property.getValue(); - propBuilder.add(property.getName(), d.doubleValue()); - break; - case FLOAT: - Float f = (Float) property.getValue(); - propBuilder.add(property.getName(), f.floatValue()); - break; - case INTEGER: - Integer i = (Integer) property.getValue(); - propBuilder.add(property.getName(), i.intValue()); - break; - case LONG: - Long l = (Long) property.getValue(); - propBuilder.add(property.getName(), l.longValue()); - break; - case AESAUDIOMETADATA: - propBuilder - .add(property.getName(), - showAESAudioMetadata((AESAudioMetadata) property - .getValue())); - break; - case NISOIMAGEMETADATA: - propBuilder.add(property.getName(), - showNisoImageMetadata((NisoImageMetadata) property - .getValue())); - break; - case TEXTMDMETADATA: - propBuilder.add(property.getName(), - showTextMDMetadata((TextMDMetadata) property.getValue())); - break; - case SHORT: - Short s = (Short) property.getValue(); - propBuilder.add(property.getName(), s.shortValue()); - break; - case STRING: - propBuilder.add(property.getName(), (String) property.getValue()); - break; - case RATIONAL: - propBuilder.add(property.getName(), - showRational((Rational) property.getValue())); - break; - case PROPERTY: - Property property2 = (Property) property.getValue(); - propBuilder.add(property.getName(), showProperty(property2)); - break; - default: - propBuilder.add(property.getName(), property.getValue().toString()); - break; - } - return propBuilder; - } - - protected JsonObjectBuilder showListProperty(Property property) { - JsonObjectBuilder propBuilder = Json.createObjectBuilder(); - List propList = (List) property.getValue(); - JsonArrayBuilder lPropBuilder = Json.createArrayBuilder(); - PropertyType type = property.getType(); - - ListIterator iter = propList.listIterator(); - while (iter.hasNext()) { - Object val = iter.next(); - switch (type) { - case BOOLEAN: - lPropBuilder.add(((Boolean) val).booleanValue()); - break; - case BYTE: - lPropBuilder.add(valueToString(val)); - break; - case CHARACTER: - lPropBuilder.add(valueToString(val)); - break; - case DATE: - lPropBuilder.add(valueToString(val)); - break; - case DOUBLE: - lPropBuilder.add(((Double) val).doubleValue()); - break; - case FLOAT: - lPropBuilder.add(((Float) val).floatValue()); - break; - case INTEGER: - lPropBuilder.add(((Integer) val).intValue()); - break; - case LONG: - lPropBuilder.add(((Long) val).longValue()); - break; - case OBJECT: - lPropBuilder.add(valueToString(val)); - break; - case SHORT: - lPropBuilder.add(((Short) val).shortValue()); - break; - case STRING: - lPropBuilder.add(valueToString(val)); - break; - case RATIONAL: - lPropBuilder.add(showRational((Rational) val)); - break; - case PROPERTY: - lPropBuilder.add(showProperty((Property) val)); - break; - case NISOIMAGEMETADATA: - lPropBuilder - .add(showNisoImageMetadata((NisoImageMetadata) property - .getValue())); - break; - case AESAUDIOMETADATA: - lPropBuilder - .add(showAESAudioMetadata((AESAudioMetadata) property - .getValue())); - break; - case TEXTMDMETADATA: - lPropBuilder.add(showTextMDMetadata((TextMDMetadata) property - .getValue())); - break; - default: - break; - } - } - propBuilder.add(property.getName(), lPropBuilder); - return propBuilder; - } - - protected JsonObjectBuilder showSetProperty(Property property) { - JsonObjectBuilder propBuilder = Json.createObjectBuilder(); - Set propSet = (Set) property.getValue(); - JsonArrayBuilder lPropBuilder = Json.createArrayBuilder(); - PropertyType type = property.getType(); - - Iterator iter = propSet.iterator(); - while (iter.hasNext()) { - Object val = iter.next(); - switch (type) { - case BOOLEAN: - lPropBuilder.add(((Boolean) val).booleanValue()); - break; - case BYTE: - lPropBuilder.add(valueToString(val)); - break; - case CHARACTER: - lPropBuilder.add(valueToString(val)); - break; - case DATE: - lPropBuilder.add(valueToString(val)); - break; - case DOUBLE: - lPropBuilder.add(((Double) val).doubleValue()); - break; - case FLOAT: - lPropBuilder.add(((Float) val).floatValue()); - break; - case INTEGER: - lPropBuilder.add(((Integer) val).intValue()); - break; - case LONG: - lPropBuilder.add(((Long) val).longValue()); - break; - case OBJECT: - lPropBuilder.add(valueToString(val)); - break; - case SHORT: - lPropBuilder.add(((Short) val).shortValue()); - break; - case STRING: - lPropBuilder.add(valueToString(val)); - break; - case RATIONAL: - lPropBuilder.add(showRational((Rational) val)); - break; - case PROPERTY: - lPropBuilder.add(showProperty((Property) val)); - break; - case NISOIMAGEMETADATA: - lPropBuilder - .add(showNisoImageMetadata((NisoImageMetadata) property - .getValue())); - break; - case AESAUDIOMETADATA: - lPropBuilder - .add(showAESAudioMetadata((AESAudioMetadata) property - .getValue())); - break; - case TEXTMDMETADATA: - lPropBuilder.add(showTextMDMetadata((TextMDMetadata) property - .getValue())); - break; - default: - break; - } - } - propBuilder.add(property.getName(), lPropBuilder); - return propBuilder; - } - - protected JsonObjectBuilder showMapProperty(Property property) { - JsonObjectBuilder propBuilder = Json.createObjectBuilder(); - JsonObjectBuilder lPropBuilder = Json.createObjectBuilder(); - Map propMap = (Map) property.getValue(); - PropertyType type = property.getType(); - Iterator keyIter = propMap.keySet().iterator(); - while (keyIter.hasNext()) { - Object key = keyIter.next(); - String keystr = key.toString(); - Object val = propMap.get(key); - switch (type) { - case BOOLEAN: - lPropBuilder.add(keystr, ((Boolean) val).booleanValue()); - break; - case BYTE: - lPropBuilder.add(keystr, valueToString(val)); - break; - case CHARACTER: - lPropBuilder.add(keystr, valueToString(val)); - break; - case DATE: - lPropBuilder.add(keystr, valueToString(val)); - break; - case DOUBLE: - lPropBuilder.add(keystr, ((Double) val).doubleValue()); - break; - case FLOAT: - lPropBuilder.add(keystr, ((Float) val).floatValue()); - break; - case INTEGER: - lPropBuilder.add(keystr, ((Integer) val).intValue()); - break; - case LONG: - lPropBuilder.add(keystr, ((Long) val).longValue()); - break; - case OBJECT: - lPropBuilder.add(keystr, valueToString(val)); - break; - case SHORT: - lPropBuilder.add(keystr, ((Short) val).shortValue()); - break; - case STRING: - lPropBuilder.add(keystr, valueToString(val)); - break; - case RATIONAL: - lPropBuilder.add(keystr, showRational((Rational) val)); - break; - case PROPERTY: - lPropBuilder.add(keystr, showProperty((Property) val)); - break; - case NISOIMAGEMETADATA: - lPropBuilder.add(keystr, - showNisoImageMetadata((NisoImageMetadata) property - .getValue())); - break; - case AESAUDIOMETADATA: - lPropBuilder.add(keystr, - showAESAudioMetadata((AESAudioMetadata) property - .getValue())); - break; - case TEXTMDMETADATA: - lPropBuilder - .add(keystr, - showTextMDMetadata((TextMDMetadata) property - .getValue())); - break; - default: - break; - } - } - propBuilder.add(property.getName(), lPropBuilder); - return propBuilder; - } - - /** - * Gives the length (number of elements) of a property - */ - protected int propertyLength(Property property) { - int n = 0; - try { - switch (property.getArity()) { - case SET: - Set propSet = (Set) property.getValue(); - n = propSet.size(); - break; - case LIST: - List propList = (List) property.getValue(); - n = propList.size(); - break; - case MAP: - Map propMap = (Map) property.getValue(); - n = propMap.size(); - break; - case ARRAY: - // Ack! Is there any easy way to do this? - switch (property.getType()) { - case BOOLEAN: - boolean[] boolArray = (boolean[]) property.getValue(); - n = boolArray.length; - break; - case BYTE: - byte[] byteArray = (byte[]) property.getValue(); - n = byteArray.length; - break; - case CHARACTER: - char[] charArray = (char[]) property.getValue(); - n = charArray.length; - break; - case DATE: - Date[] dateArray = (Date[]) property.getValue(); - n = dateArray.length; - break; - case DOUBLE: - double[] doubleArray = (double[]) property.getValue(); - n = doubleArray.length; - break; - case FLOAT: - float[] floatArray = (float[]) property.getValue(); - n = floatArray.length; - break; - case INTEGER: - int[] intArray = (int[]) property.getValue(); - n = intArray.length; - break; - case LONG: - long[] longArray = (long[]) property.getValue(); - n = longArray.length; - break; - case OBJECT: - Object[] objArray = (Object[]) property.getValue(); - n = objArray.length; - break; - case SHORT: - short[] shortArray = (short[]) property.getValue(); - n = shortArray.length; - break; - case STRING: - String[] stringArray = (String[]) property.getValue(); - n = stringArray.length; - break; - case RATIONAL: - Rational[] rationalArray = (Rational[]) property.getValue(); - n = rationalArray.length; - break; - case PROPERTY: - Property[] propArray = (Property[]) property.getValue(); - n = propArray.length; - break; - case NISOIMAGEMETADATA: - NisoImageMetadata[] nisoArray = (NisoImageMetadata[]) property - .getValue(); - n = nisoArray.length; - break; - case AESAUDIOMETADATA: - AESAudioMetadata[] aesArray = (AESAudioMetadata[]) property - .getValue(); - n = aesArray.length; - break; - case TEXTMDMETADATA: - TextMDMetadata[] textMDArray = (TextMDMetadata[]) property - .getValue(); - n = textMDArray.length; - break; - default: - Object[] array2 = (Object[]) property.getValue(); - n = array2.length; - break; - } - break; - default: - if (property.getValue().toString().length() == 0) { - n = 0; - } else { - n = 1; - } - break; - } - } catch (Exception e) { - // If something goes seriously wrong, return true to punt the - // property - return 0; - } - return n; - } - - /* - * The array property has so many special cases of its own that we break it - * out of showProperty - */ - protected JsonObjectBuilder showArrayProperty(Property property) { - boolean[] boolArray = null; - byte[] byteArray = null; - char[] charArray = null; - java.util.Date[] dateArray = null; - double[] doubleArray = null; - float[] floatArray = null; - int[] intArray = null; - long[] longArray = null; - Object[] objArray = null; - Property[] propArray = null; - short[] shortArray = null; - String[] stringArray = null; - Rational[] rationalArray = null; - NisoImageMetadata[] nisoArray = null; - AESAudioMetadata[] aesArray = null; - TextMDMetadata[] textMDArray = null; - int n = 0; - - PropertyType propType = property.getType(); - switch (propType) { - case BOOLEAN: - boolArray = (boolean[]) property.getValue(); - n = boolArray.length; - break; - case BYTE: - byteArray = (byte[]) property.getValue(); - n = byteArray.length; - break; - case CHARACTER: - charArray = (char[]) property.getValue(); - n = charArray.length; - break; - case DATE: - dateArray = (Date[]) property.getValue(); - n = dateArray.length; - break; - case DOUBLE: - doubleArray = (double[]) property.getValue(); - n = doubleArray.length; - break; - case FLOAT: - floatArray = (float[]) property.getValue(); - n = floatArray.length; - break; - case INTEGER: - intArray = (int[]) property.getValue(); - n = intArray.length; - break; - case LONG: - longArray = (long[]) property.getValue(); - n = longArray.length; - break; - case OBJECT: - objArray = (Object[]) property.getValue(); - n = objArray.length; - break; - case SHORT: - shortArray = (short[]) property.getValue(); - n = shortArray.length; - break; - case STRING: - stringArray = (String[]) property.getValue(); - n = stringArray.length; - break; - case RATIONAL: - rationalArray = (Rational[]) property.getValue(); - n = rationalArray.length; - break; - case PROPERTY: - propArray = (Property[]) property.getValue(); - n = propArray.length; - break; - case NISOIMAGEMETADATA: - nisoArray = (NisoImageMetadata[]) property.getValue(); - n = nisoArray.length; - break; - case AESAUDIOMETADATA: - aesArray = (AESAudioMetadata[]) property.getValue(); - n = aesArray.length; - break; - case TEXTMDMETADATA: - textMDArray = (TextMDMetadata[]) property.getValue(); - n = textMDArray.length; - break; - default: - break; - } - - JsonArrayBuilder arrayBuilder = Json.createArrayBuilder(); - for (int i = 0; i < n; i++) { - switch (propType) { - case BOOLEAN: - arrayBuilder.add(boolArray[i]); - break; - case BYTE: - arrayBuilder.add(String.valueOf(byteArray[i])); - break; - case CHARACTER: - arrayBuilder.add(String.valueOf(charArray[i])); - break; - case DATE: - arrayBuilder.add(dateArray[i].toString()); - break; - case DOUBLE: - arrayBuilder.add(doubleArray[i]); - break; - case FLOAT: - arrayBuilder.add(floatArray[i]); - break; - case INTEGER: - arrayBuilder.add(intArray[i]); - break; - case LONG: - arrayBuilder.add(longArray[i]); - break; - case OBJECT: - arrayBuilder.add(valueToString(objArray[i])); - break; - case SHORT: - arrayBuilder.add(shortArray[i]); - break; - case STRING: - arrayBuilder.add(stringArray[i]); - break; - case RATIONAL: - arrayBuilder.add(rationalArray[i].toString()); - break; - case PROPERTY: - arrayBuilder.add(showProperty(propArray[i])); - break; - case NISOIMAGEMETADATA: - arrayBuilder.add(showNisoImageMetadata(nisoArray[i])); - break; - case AESAUDIOMETADATA: - arrayBuilder.add(showAESAudioMetadata(aesArray[i])); - break; - case TEXTMDMETADATA: - arrayBuilder.add(showTextMDMetadata(textMDArray[i])); - break; - default: - arrayBuilder.add(""); - break; - } - } - return Json.createObjectBuilder().add(property.getName(), arrayBuilder); - } - - /* - * Output the textMD metadata, which is its own special kind of property. - */ - protected JsonObjectBuilder showTextMDMetadata(TextMDMetadata textMD) { - JsonObjectBuilder textmdBuilder = Json.createObjectBuilder(); - addStringToJson(textmdBuilder, "textmd:charset", textMD.getCharset()); - addStringToJson(textmdBuilder, "textmd:byte_order", textMD.getByte_orderString()); - addStringToJson(textmdBuilder, "textmd:byte_size", textMD.getByte_size()); - addStringToJson(textmdBuilder, "textmd:character_size", textMD.getCharacter_size()); - addStringToJson(textmdBuilder, "textmd:linebreak", textMD.getLinebreakString()); - addStringToJson(textmdBuilder, "textmd:language", textMD.getLanguage()); - addStringToJson(textmdBuilder, "textmd:markup_basis", textMD.getMarkup_basis()); - addStringToJson(textmdBuilder, "textmd:markup_basis_version", textMD.getMarkup_basis_version()); - addStringToJson(textmdBuilder, "textmd:markup_language", textMD.getMarkup_language()); - addStringToJson(textmdBuilder, "textmd:markup_language_version", textMD.getMarkup_language_version()); - return textmdBuilder; - } - - /** - * Display the NISO image metadata formatted according to the MIX schema. - * The schema which is used may be 0.2 or 1.0 or 2.0, depending on the - * module parameters. - * - * @param niso - * NISO image metadata - */ - protected JsonObjectBuilder showNisoImageMetadata(NisoImageMetadata niso) { - if ("0.2".equals(_je.getMixVersion())) { - return null; // don't handle mix version 0.2 - } else if ("1.0".equals(_je.getMixVersion())) { - return showNisoImageMetadata(niso, true); - } else { - return showNisoImageMetadata(niso, false); - } - } - - /** - * Display the NISO image metadata formatted according to the MIX 1.0 - * schema. - */ - protected JsonObjectBuilder showNisoImageMetadata(NisoImageMetadata niso, - boolean bMix10) { - JsonObjectBuilder mixBuilder = Json.createObjectBuilder(); - - JsonObjectBuilder ob = showNisoBasicDigitalObjectInformation(niso, - bMix10); - if (ob != null) { - mixBuilder.add("mix:BasicDigitalObjectInformation", ob); - } - ob = showNisoBasicImageInformation(niso, bMix10); - if (ob != null) { - mixBuilder.add("mix:BasicImageInformation", ob); - } - ob = showNisoImageCaptureMetadata(niso, bMix10); - if (ob != null) { - mixBuilder.add("mix:ImageCaptureMetadata", ob); - } - ob = showNisoImageAssessmentMetadata(niso, bMix10); - if (ob != null) { - mixBuilder.add("mix:ImageAssessmentMetadata", ob); - } - ob = showChangeHistory(niso, bMix10); - if (ob != null) { - mixBuilder.add("mix:ChangeHistory", ob); - } - return mixBuilder; - } - - /* - * The NISO Metadata output is split into multiple functions so that they're - * merely outrageously big rather than disgustingly big - */ - /* Top level element 1 of 5: BasicDigitalObjectInformation */ - protected JsonObjectBuilder showNisoBasicDigitalObjectInformation( - NisoImageMetadata niso, boolean bMix10) { - JsonObjectBuilder mixBuilder = Json.createObjectBuilder(); - - String s = niso.getImageIdentifier(); - if (s != null) { - mixBuilder.add( - "mix:ObjectIdentifier", - Json.createObjectBuilder() - .add("mix:objectIdentifierType", "JHOVE") - .add("mix:objectIdentifierValue", s)); - } - long ln = niso.getFileSize(); - if (ln != NisoImageMetadata.NULL) { - mixBuilder.add("mix:fileSize", ln); - } - if ((s = niso.getMimeType()) != null) { - mixBuilder.add("mix:formatName", s); - } - if ((s = niso.getByteOrder()) != null) { - // Convert strings to MIX 1.0 form - if (s.startsWith("big")) { - s = bMix10 ? "big_endian" : "big endian"; - } else if (s.startsWith("little")) { - s = bMix10 ? "little_endian" : "little endian"; - } - mixBuilder.add("mix:byteOrder", s); - } - int comp = niso.getCompressionScheme(); - int level = niso.getCompressionLevel(); - String compStr; - switch (comp) { - case 1: - compStr = "Uncompressed"; - break; - case 2: - compStr = "CCITT 1D"; - break; - case 3: - compStr = "Group 3 Fax"; - break; - case 4: - compStr = "Group 4 Fax"; - break; - case 5: - compStr = "LZW"; - break; - case 6: - compStr = "JPEG"; - break; - case 32773: - compStr = "PackBits"; - break; - case 34713: - compStr = "JPEG2000 Lossy"; - break; - case 34714: - compStr = "JPEG2000 Lossless"; - break; - default: - compStr = "Unknown"; - break; - } - if (comp != NisoImageMetadata.NULL) { - if (comp == 34713 || comp == 34714) { - mixBuilder.add("mix:compressionScheme", - compressionSchemeToString(comp)); - if (level != NisoImageMetadata.NULL) { - mixBuilder.add("mix:compressionRatio", level); - } - } else if (bMix10) { - mixBuilder.add("mix:compressionScheme", Integer.toString(comp)); - } else { - mixBuilder.add("mix:compressionScheme", compStr); - } - } - int n = niso.getChecksumMethod(); - s = niso.getChecksumValue(); - if (n != NisoImageMetadata.NULL || s != null) { - if (n != NisoImageMetadata.NULL) { - mixBuilder.add("mix:messageDigestAlgorithm", n); - } - if (s != null) { - mixBuilder.add("mix:messageDigest", s); - } - } - return mixBuilder; - } - - /* 1.0, Top level element 2 of 5: BasicImageInformation */ - protected JsonObjectBuilder showNisoBasicImageInformation( - NisoImageMetadata niso, boolean bMix10) { - JsonObjectBuilder mixBuilder = Json.createObjectBuilder(); - boolean hasBuilder = false; - long ln = niso.getImageWidth(); - if (ln != NisoImageMetadata.NULL) { - mixBuilder.add("mix:imageWidth", ln); - hasBuilder = true; - } - ln = niso.getImageLength(); - if (ln != NisoImageMetadata.NULL) { - mixBuilder.add("mix:imageHeight", ln); - hasBuilder = true; - } - int n = niso.getColorSpace(); - if (n != NisoImageMetadata.NULL) { - if (bMix10) { - mixBuilder.add("mix:colorSpace", n); - } else { - mixBuilder.add("mix:colorSpace", - photometricInterpretationToString(n)); - } - hasBuilder = true; - } - String s = niso.getProfileName(); - String s2 = niso.getProfileURL(); - if (s != null || s2 != null) { - JsonObjectBuilder iccBuilder = Json.createObjectBuilder(); - addStringToJson(iccBuilder, "mix:iccProfileName", s); - addStringToJson(iccBuilder, "mix:iccProfileURL", s2); - mixBuilder.add("mix:IccProfile", iccBuilder); - hasBuilder = true; - } - int[] iarray = niso.getYCbCrSubSampling(); - n = niso.getYCbCrPositioning(); - Rational[] rarray = niso.getYCbCrCoefficients(); - if (iarray != null || n != NisoImageMetadata.NULL || rarray != null) { - JsonObjectBuilder yccBuilder = Json.createObjectBuilder(); - if (iarray != null && iarray.length >= 2) { - yccBuilder.add( - "mix:YCbCrSubSampling", - Json.createObjectBuilder() - .add("mix:yCbCrSubsampleHoriz", iarray[0]) - .add("mix:yCbCrSubsampleVert", iarray[1])); - } - addNisoIntToJson(yccBuilder, "mix:yCbCrPositioning", n); - if (rarray != null) { - if (bMix10) { - yccBuilder.add("mix:yCbCrCoefficients", showArray(rarray)); - } else { - yccBuilder - .add("mix:yCbCrCoefficients", - Json.createObjectBuilder() - .add("mix:lumaRed", - showRational(rarray[0])) - .add("mix:lumaGreen", - showRational(rarray[1])) - .add("mix:lumaBlue", - showRational(rarray[2]))); - } - } - mixBuilder.add("mix:YCbCr", yccBuilder); - hasBuilder = true; - } - rarray = niso.getReferenceBlackWhite(); - if (rarray != null) { - if (bMix10) { - mixBuilder.add("mix:referenceBlackWhite", showArray(rarray)); - } else { - JsonArrayBuilder aBuilder = Json.createArrayBuilder(); - for (int i = 0; i < rarray.length - 1; i += 2) { - JsonObjectBuilder cBuilder = Json.createObjectBuilder(); - // Tricky here. - // The reference BW might be given as either RGB or yCbCr. - String pi; - if (niso.getColorSpace() == 6) { // yCbCr - switch (i) { - case 0: - pi = "Y"; - break; - case 2: - pi = "Cb"; - break; - case 4: - default: - pi = "Cr"; - break; - } - } else { - switch (i) { // otherwise assume RGB - case 0: - pi = "R"; - break; - case 2: - pi = "G"; - break; - case 4: - default: - pi = "B"; - break; - } - } - cBuilder.add("mix:componentPhotometricInterpretation", pi); - cBuilder.add("mix:footroom", showRational(rarray[i])); - cBuilder.add("mix:headroom", showRational(rarray[i + 1])); - aBuilder.add(cBuilder); - } - mixBuilder.add("mix:ReferenceBlackWhite", aBuilder); - } - hasBuilder = true; - } - // SpecialFormatCharacteristics limited to JPEG2000 - int lay = niso.getJp2Layers(); - int lev = niso.getJp2ResolutionLevels(); - String sizTiles = niso.getJp2Tiles(); - if (sizTiles != null || lay != NisoImageMetadata.NULL - || lev != NisoImageMetadata.NULL) { - JsonObjectBuilder jp2Builder = Json.createObjectBuilder(); - if (sizTiles != null) { - if (bMix10) { - jp2Builder.add(MIX_TILES, sizTiles); - } else { - String[] sizes = sizTiles.split("x"); - jp2Builder.add(MIX_TILES, showArray(sizes)); - } - } - addNisoIntToJson(jp2Builder, "mix:qualityLayers", lay); - addNisoIntToJson(jp2Builder, "mix:resolutionLevels", lev); - mixBuilder.add("mix:JPEG2000", jp2Builder); - hasBuilder = true; - } - - return hasBuilder ? mixBuilder : null; - } - - /* 1.0, Top level element 3 of 5: ImageCaptureMetadata */ - protected JsonObjectBuilder showNisoImageCaptureMetadata( - NisoImageMetadata niso, boolean bMix10) { - JsonObjectBuilder mixBuilder = Json.createObjectBuilder(); - boolean hasBuilder = false; - - hasBuilder |= addStringToJson(mixBuilder, "mix:sourceType", niso.getSourceType()); - hasBuilder |= addStringToJson(mixBuilder, "mix:sourceIDValue", niso.getSourceID()); - double d = niso.getSourceXDimension(); - int n = niso.getSourceXDimensionUnit(); - if (d != NisoImageMetadata.NILL || n != NisoImageMetadata.NULL) { - // Assume that both X and Y exist, or neither - addNisoDoubleToJson(mixBuilder, "mix:sourceXDimensionValue", d); - addNisoIntToJson(mixBuilder, "mix:sourceXDimensionUnit", n); - addNisoDoubleToJson(mixBuilder, "mix:sourceYDimensionValue", niso.getSourceYDimension()); - addNisoIntToJson(mixBuilder, "mix:sourceYDimensionUnit", niso.getSourceYDimensionUnit()); - hasBuilder = true; - } - - hasBuilder |= addStringToJson(mixBuilder, "mix:dateTimeCreated", niso.getDateTimeCreated()); - hasBuilder |= addStringToJson(mixBuilder, "mix:imageProducer", niso.getImageProducer()); - hasBuilder |= addStringToJson(mixBuilder, "mix:captureDevice", niso.getDeviceSource()); - hasBuilder |= addStringToJson(mixBuilder, "mix:scannerManufacturer", niso.getScannerManufacturer()); - - String model = niso.getScannerModelName(); - String modelNum = niso.getScannerModelNumber(); - String serNum = niso.getScannerModelSerialNo(); - if (model != null || modelNum != null || serNum != null) { - hasBuilder = true; - JsonObjectBuilder smBuilder = Json.createObjectBuilder(); - addStringToJson(smBuilder, "mix:scannerModelName", model); - addStringToJson(smBuilder, "mix:scannerModelNumber", modelNum); - addStringToJson(smBuilder, "mix:scannerModelSerialNo", serNum); - mixBuilder.add("mix:ScannerModel", smBuilder); - } - double xres = niso.getXPhysScanResolution(); - double yres = niso.getYPhysScanResolution(); - if (xres != NisoImageMetadata.NULL && yres != NisoImageMetadata.NULL) { - double res = (xres > yres ? xres : yres); - if (bMix10) { - mixBuilder.add("mix:maximumOpticalResolution", res); - } else { - mixBuilder.add( - "mix:MaximumOpticalResolution", - Json.createObjectBuilder() - .add("mix:xOpticalResolution", xres) - .add("mix:yOpticalResolution", yres) - .add("mix:resolutionUnit", ".in")); - } - hasBuilder = true; - } - if (addStringToJson(mixBuilder, "mix:scanningSoftwareName", niso.getScanningSoftware())) { - hasBuilder = true; - addStringToJson(mixBuilder, "mix:scanningSoftwareVersionNo", niso.getScanningSoftwareVersionNo()); - } - - // Now we'll hear from the digital cameras. - hasBuilder |= addStringToJson(mixBuilder, "mix:digitalCameraManufacturer", niso.getDigitalCameraManufacturer()); - String dcmodel = niso.getDigitalCameraModelName(); - String dcmodelNum = niso.getDigitalCameraModelNumber(); - String dcserNum = niso.getDigitalCameraModelSerialNo(); - if (dcmodel != null || dcmodelNum != null || dcserNum != null) { - hasBuilder = true; - JsonObjectBuilder smBuilder = Json.createObjectBuilder(); - addStringToJson(smBuilder, "mix:digitalCameraModelName", dcmodel); - addStringToJson(smBuilder, "mix:digitalCameraModelNumber", dcmodelNum); - addStringToJson(smBuilder, "mix:mix:digitalCameraModelSerialNo", dcserNum); - mixBuilder.add("mix:DigitalCameraModel", smBuilder); - } - - // Nest a buffer for CameraCaptureSettings - JsonObjectBuilder ccsBuilder = Json.createObjectBuilder(); - boolean useCcSetBuf = false; - useCcSetBuf |= addNisoDoubleToJson(ccsBuilder, "mix:fNumber", niso.getFNumber()); - useCcSetBuf |= addNisoDoubleToJson(ccsBuilder, "mix:exposureTime", niso.getExposureTime()); - n = niso.getExposureProgram(); - if (n != NisoImageMetadata.NULL) { - if (bMix10) { - ccsBuilder.add("mix:exposureProgram", n); - } else { - if (n > 8 || n < 0) { - n = 0; // force "Not defined" for bad value - } - ccsBuilder.add("mix:exposureProgram", - NisoImageMetadata.EXPOSURE_PROGRAM[n]); - } - useCcSetBuf = true; - } - useCcSetBuf |= addStringToJson(ccsBuilder, "mix:exifVersion", niso.getExifVersion()); - useCcSetBuf |= addRationalToJson(ccsBuilder, "mix:brightnessValue", niso.getBrightness()); - useCcSetBuf |= addRationalToJson(ccsBuilder, "mix:exposureBiasValue", niso.getExposureBias()); - useCcSetBuf |= addRationalToJson(ccsBuilder, "mix:maxApertureValue", niso.getMaxApertureValue()); - double[] darray = niso.getSubjectDistance(); - if (darray != null) { - ccsBuilder.add("mix:subjectDistance", showArray(darray)); - useCcSetBuf = true; - } - n = niso.getMeteringMode(); - if (n != NisoImageMetadata.NULL) { - if (bMix10) { - ccsBuilder.add("mix:meteringMode", n); - } else { - String s = meteringModeToString(n); - if (s.startsWith("Center weighted")) { - s = "Center weighted Average"; - } - ccsBuilder.add("mix:MeteringMode", s); - } - useCcSetBuf = true; - } - n = niso.getFlash(); - if (n != NisoImageMetadata.NULL) { - // First bit (0 = Flash did not fire, 1 = Flash fired) - int firstBit = n & 1; - ccsBuilder.add("mix:flash", NisoImageMetadata.FLASH_20[firstBit]); - useCcSetBuf = true; - } - useCcSetBuf |= addNisoDoubleToJson(ccsBuilder, "mix:focalLength", niso.getFocalLength()); - useCcSetBuf |= addRationalToJson(ccsBuilder, "mix:flashEnergy", niso.getFlashEnergy()); - useCcSetBuf |= addNisoIntToJson(ccsBuilder, "mix:backLight", niso.getBackLight()); - useCcSetBuf |= addNisoDoubleToJson(ccsBuilder, "mix:exposureIndex", niso.getExposureIndex()); - useCcSetBuf |= addNisoIntToJson(ccsBuilder, "mix:autoFocus", niso.getAutoFocus()); - useCcSetBuf |= addNisoDoubleToJson(ccsBuilder, "mix:xPrintAspectRatio", niso.getXPrintAspectRatio()); - useCcSetBuf |= addNisoDoubleToJson(ccsBuilder, "mix:yPrintAspectRatio", niso.getYPrintAspectRatio()); - if (useCcSetBuf) { - mixBuilder.add("mix:CameraCaptureSettings", ccsBuilder); - hasBuilder = true; - } - - n = niso.getOrientation(); - if (n != NisoImageMetadata.NULL) { - if (n > 9 || n < 1) { - n = 9; // force "unknown" for reserved value - } - if (bMix10) { - mixBuilder.add("mix:orientation", n); - } else { - final String[] orient = { "", "normal*", - "normal, image flipped", "normal, rotated 180\u00B0", - "normal, image flipped, rotated 180\u00B0", - "normal, image flipped, rotated cw 90\u00B0", - "normal, rotated ccw 90\u00B0", - "normal, image flipped, rotated ccw 90\u00B0", - "normal, rotated cw 90\u00B0", "unknown" }; - mixBuilder.add("mix:orientation", orient[n]); - } - hasBuilder = true; - } - hasBuilder |= addStringToJson(mixBuilder, "mix:methodology", niso.getMethodology()); - return hasBuilder ? mixBuilder : null; - } - - /* 1.0, Top level element 4 of 5: ImageAssessmentMetadata */ - protected JsonObjectBuilder showNisoImageAssessmentMetadata( - NisoImageMetadata niso, boolean bMix10) { - JsonObjectBuilder mixBuilder = Json.createObjectBuilder(); - boolean hasBuilder = false; - - JsonObjectBuilder smBuilder = Json.createObjectBuilder(); - boolean useMetricsBuf = false; - useMetricsBuf |= addNisoIntToJson(smBuilder, "mix:samplingFrequencyPlane", niso.getSamplingFrequencyPlane()); - int n = niso.getSamplingFrequencyUnit(); - if (n != NisoImageMetadata.NULL) { - if (bMix10) { - smBuilder.add("mix:samplingFrequencyUnit", n); - } else { - final String sfu[] = { null, "no absolute unit of measurement", - "in.", "cm" }; - if (n < 1 || n > 3) { - n = 1; - } - smBuilder.add("mix:samplingFrequencyUnit", sfu[n]); - } - useMetricsBuf = true; - } - useMetricsBuf |= addRationalToJson(smBuilder, "mix:xSamplingFrequency", niso.getXSamplingFrequency()); - useMetricsBuf |= addRationalToJson(smBuilder, "mix:ySamplingFrequency", niso.getYSamplingFrequency()); - if (useMetricsBuf) { - mixBuilder.add("mix:SpatialMetrics", smBuilder); - hasBuilder = true; - } - - JsonObjectBuilder imeBuilder = Json.createObjectBuilder(); - boolean useColorEncBuf = false; - - int[] iarray = niso.getBitsPerSample(); - if (iarray != null) { - imeBuilder.add("mix:bitsPerSample", showArray(iarray)); - imeBuilder.add("mix:bitsPerSampleUnit", "integer"); - // bitsPerSampleUnit can also be floating point. Don't ask me why. - useColorEncBuf = true; - } - useColorEncBuf |= addNisoIntToJson(imeBuilder, "mix:samplesPerPixel", niso.getSamplesPerPixel()); - iarray = niso.getExtraSamples(); - if (iarray != null) { - // extraSamples must be limited to - // 0, 1, 2, or 3. - n = iarray[0]; - if (n >= 0 && n <= 3) { - if (bMix10) { - imeBuilder.add(MIX_EXTRA_SAMPLES, showArray(iarray)); - } else { - String[] sarray = new String[iarray.length]; - for (int ii = 0; ii < iarray.length; ii++) { - sarray[ii] = NisoImageMetadata.EXTRA_SAMPLE_20[iarray[ii]]; - imeBuilder.add(MIX_EXTRA_SAMPLES, showArray(sarray)); - } - - } - useColorEncBuf = true; - } - } - - useColorEncBuf |= addStringToJson(imeBuilder, "mix:colormapReference", niso.getColormapReference()); - - // This is complete nonsense, but it's what the spec says - iarray = niso.getGrayResponseCurve(); - if (iarray != null) { - imeBuilder.add("mix:grayResponseCurve", showArray(iarray)); - useColorEncBuf = true; - } - - n = niso.getGrayResponseUnit(); - if (n != NisoImageMetadata.NULL) { - if (bMix10) { - imeBuilder.add(MIX_GRAY_RESPONSE_UNIT, n); - } else if (n > 0 && n <= 5) { - // Convert integer to text value; only values 1-5 are legal - imeBuilder.add(MIX_GRAY_RESPONSE_UNIT, - NisoImageMetadata.GRAY_RESPONSE_UNIT_20[n - 1]); - } - useColorEncBuf = true; - } - - Rational r = niso.getWhitePointXValue(); - Rational r2 = niso.getWhitePointYValue(); - if (r != null && r2 != null) { - imeBuilder.add( - "mix:WhitePoint", - Json.createObjectBuilder() - .add("mix:whitePointXValue", showRational(r)) - .add("mix:whitePointYValue", showRational(r2))); - useColorEncBuf = true; - } - - // A chromaticities buffer to go in the color encoding buffer. - JsonObjectBuilder pcBuilder = Json.createObjectBuilder(); - boolean useChromaBuf = false; - useChromaBuf |= addRationalToJson(pcBuilder, "mix:primaryChromaticitiesRedX", - niso.getPrimaryChromaticitiesRedX()); - useChromaBuf |= addRationalToJson(pcBuilder, "mix:primaryChromaticitiesRedY", - niso.getPrimaryChromaticitiesRedY()); - useChromaBuf |= addRationalToJson(pcBuilder, "mix:primaryChromaticitiesGreenX", - niso.getPrimaryChromaticitiesGreenX()); - useChromaBuf |= addRationalToJson(pcBuilder, "mix:primaryChromaticitiesGreenY", - niso.getPrimaryChromaticitiesGreenY()); - useChromaBuf |= addRationalToJson(pcBuilder, "mix:primaryChromaticitiesBlueX", - niso.getPrimaryChromaticitiesBlueX()); - useChromaBuf |= addRationalToJson(pcBuilder, "mix:primaryChromaticitiesBlueY", - niso.getPrimaryChromaticitiesBlueY()); - if (useChromaBuf) { - imeBuilder.add("mix:PrimaryChromaticities", pcBuilder); - useColorEncBuf = true; - } - - if (useColorEncBuf) { - mixBuilder.add("mix:ImageColorEncoding", imeBuilder); - hasBuilder = true; - } - - JsonObjectBuilder tdBuilder = Json.createObjectBuilder(); - boolean useTargetBuf = false; - useTargetBuf |= addNisoIntToJson(tdBuilder, "mix:targetType", niso.getTargetType()); - useTargetBuf |= addStringToJson(tdBuilder, "mix:targetManufacturer", niso.getTargetIDManufacturer()); - useTargetBuf |= addStringToJson(tdBuilder, "mix:targetName", niso.getTargetIDName()); - useTargetBuf |= addStringToJson(tdBuilder, "mix:targetNo", niso.getTargetIDNo()); - useTargetBuf |= addStringToJson(tdBuilder, "mix:targetMedia", niso.getTargetIDMedia()); - useTargetBuf |= addStringToJson(tdBuilder, "mix:externalTarget", niso.getImageData()); - useTargetBuf |= addStringToJson(tdBuilder, "mix:performanceData", niso.getPerformanceData()); - if (useTargetBuf) { - mixBuilder.add("mix:TargetData", tdBuilder); - hasBuilder = true; - } - return hasBuilder ? mixBuilder : null; - } - - /* 1.0, Top level element 5 of 5: ChangeHistory (without time travel) */ - protected JsonObjectBuilder showChangeHistory(NisoImageMetadata niso, - boolean bMix10) { - JsonObjectBuilder mixBuilder = Json.createObjectBuilder(); - boolean hasBuilder = false; - - hasBuilder |= addStringToJson(mixBuilder, "mix:sourceData", niso.getSourceData()); - hasBuilder |= addStringToJson(mixBuilder, "mix:processingAgency", niso.getProcessingAgency()); - - JsonObjectBuilder psBuilder = Json.createObjectBuilder(); - boolean useSftwBuf = false; - useSftwBuf |= addStringToJson(psBuilder, "mix:processingSoftwareName", niso.getProcessingSoftwareName()); - useSftwBuf |= addStringToJson(psBuilder, "mix:processingSoftwareVersion", niso.getProcessingSoftwareVersion()); - useSftwBuf |= addStringToJson(psBuilder, "mix:processingOperatingSystemName", niso.getOS()); - useSftwBuf |= addStringToJson(psBuilder, "mix:processingOperatingSystemVersion", niso.getOSVersion()); - if (useSftwBuf) { - mixBuilder.add("mix:ProcessingSoftware", psBuilder); - hasBuilder = true; - } - - String[] sarray = niso.getProcessingActions(); - if (sarray != null) { - mixBuilder.add("mix:processingActions", showArray(sarray)); - hasBuilder = true; - } - return hasBuilder ? mixBuilder : null; - } - - /** - * Convert the metering mode value to one of the suggested values for MIX - * 2.0 - */ - private String meteringModeToString(int n) { - String s = NisoImageMetadata.METERING_MODE[1]; - if (n >= 1 && n <= 6) { - s = NisoImageMetadata.METERING_MODE[n]; - } - // Capitalize first letter - return s.substring(0, 1).toUpperCase(Locale.ROOT) + s.substring(1); - } - - /** - * Convert the color space value (which is based on the TIFF - * PhotometricInterpretation convention) to one of the suggested values for - * MIX 2.0 - */ - private String photometricInterpretationToString(int n) { - switch (n) { - case 0: - return "WhiteIsZero"; - case 1: - return "BlackIsZero"; - case 2: - return "RGB"; - case 3: - return "PaletteColor"; - case 4: - return "TransparencyMask"; - case 5: - return "CMYK"; - case 6: - return "YCbCr"; - case 8: - return "CIELab"; - case 9: - return "ICCLab"; - case 10: - return "ITULab"; - case 32803: - return "CFA"; - case 34892: - return "LinearRaw"; - default: - return "Unknown"; - } - } - - /** - * Convert compression scheme value (based on the TIFF compression - * convention) to a label - */ - private String compressionSchemeToString(int n) { - for (int i = 0; i < NisoImageMetadata.COMPRESSION_SCHEME_INDEX.length; i++) { - if (n == NisoImageMetadata.COMPRESSION_SCHEME_INDEX[i]) - return NisoImageMetadata.COMPRESSION_SCHEME[i]; - } - return Integer.toString(n); - } - - /** - * Display the audio metadata formatted according to the AES schema. - * - * @param aes AES audio metadata - * @return Json - */ - protected JsonObjectBuilder showAESAudioMetadata(AESAudioMetadata aes) { - JsonObjectBuilder aesBuilder = Json.createObjectBuilder(); - - _sampleRate = aes.getSampleRate(); - - addStringToJson(aesBuilder, "aes:analogDigitalFlag", aes.getAnalogDigitalFlag()); - addStringToJson(aesBuilder, "aes:schemaVersion", aes.getSchemaVersion()); - addStringToJson(aesBuilder, "aes:format", aes.getFormat()); - addStringToJson(aesBuilder, "aes:specificationVersion", aes.getSpecificationVersion()); - addStringToJson(aesBuilder, "aes:appSpecificData", aes.getAppSpecificData()); - addStringToJson(aesBuilder, "aes:audioDataEncoding", aes.getAudioDataEncoding()); - int in = aes.getByteOrder(); - if (in != AESAudioMetadata.NULL) { - aesBuilder.add("aes:byteOrder", - (in == AESAudioMetadata.BIG_ENDIAN ? "BIG_ENDIAN" - : "LITTLE_ENDIAN")); - } - long lin = aes.getFirstSampleOffset(); - if (lin != AESAudioMetadata.NULL) { - aesBuilder.add("aes:firstSampleOffset", lin); - } - String[] use = aes.getUse(); - if (use != null) { - aesBuilder.add( - "aes:use", - Json.createObjectBuilder().add("aes:useType", use[0]) - .add("aes:otherType", use[1])); - } - if (addStringToJson(aesBuilder, "aes:primaryIdentifier", aes.getPrimaryIdentifier())) { - addStringToJson(aesBuilder, "aes:primaryIdentifierType", aes.getPrimaryIdentifierType()); - } - List facelist = aes.getFaceList(); - if (facelist != null && !facelist.isEmpty()) { - // Add the face information, which is mostly filler. - AESAudioMetadata.Face f = facelist.get(0); - JsonObjectBuilder faceBuilder = Json.createObjectBuilder(); - - AESAudioMetadata.TimeDesc startTime = f.getStartTime(); - if (startTime != null) { - faceBuilder.add("aes:timeline", - writeAESTimeRange(startTime, f.getDuration())); - } - int nchan = aes.getNumChannels(); - if (nchan != AESAudioMetadata.NULL) { - faceBuilder.add("aes:numChannels", nchan); - } - JsonArrayBuilder streamsBuilder = Json.createArrayBuilder(); - for (int ch = 0; ch < nchan; ch++) { - // write a stream description for each channel - streamsBuilder.add(Json.createObjectBuilder() - .add("aes:channelNum", ch)); - } - faceBuilder.add("aes:streams", streamsBuilder); - aesBuilder.add("aes:face", faceBuilder); - } - - showAesFormatList(aes.getFormatList(), aesBuilder); - return aesBuilder; - } - - private void showAesFormatList(List flist, - JsonObjectBuilder aesBuilder) { - if (flist == null || flist.isEmpty()) { - return; - } - // In the general case, a FormatList can contain multiple - // FormatRegions. This doesn't happen with any of the current - // modules; if it's needed in the future, simply set up an - // iteration loop on formatList. - AESAudioMetadata.FormatRegion rgn = flist.get(0); - int bitDepth = rgn.getBitDepth(); - double sampleRate = rgn.getSampleRate(); - int wordSize = rgn.getWordSize(); - String[] bitRed = rgn.getBitrateReduction(); - // Build a FormatRegion subtree if at least one piece of data - // that goes into it is present. - JsonArrayBuilder formatListBuilder = Json.createArrayBuilder(); - JsonObjectBuilder formatRegionBuilder = Json.createObjectBuilder(); - if (bitDepth != AESAudioMetadata.NULL - || sampleRate != AESAudioMetadata.NILL - || wordSize != AESAudioMetadata.NULL) { - if (bitDepth != AESAudioMetadata.NULL) { - formatRegionBuilder.add("aes:bitDepth", bitDepth); - } - if (sampleRate != AESAudioMetadata.NILL) { - formatRegionBuilder.add("aes:sampleRate", sampleRate); - } - if (wordSize != AESAudioMetadata.NULL) { - formatRegionBuilder.add("aes:wordSize", wordSize); - } - if (bitRed != null) { - formatRegionBuilder.add( - "aes:bitrateReduction", - Json.createObjectBuilder() - .add("aes:codecName", bitRed[0]) - .add("aes:codecNameVersion", bitRed[1]) - .add("aes:codecCreatorApplication", - bitRed[2]) - .add("aes:codecCreatorApplicationVersion", - bitRed[3]) - .add("aes:codecQuality", bitRed[4]) - .add("aes:dataRate", bitRed[5]) - .add("aes:dataRateMode", bitRed[6])); - } - - formatListBuilder.add(formatRegionBuilder); - aesBuilder.add("aes:formatList", formatListBuilder); - } - } - - /* - * Break out the writing of a timeRangeType element. This always gives a - * start time of 0. This is all FAKE DATA for the moment. - */ - private JsonObjectBuilder writeAESTimeRange( - AESAudioMetadata.TimeDesc start, AESAudioMetadata.TimeDesc duration) { - JsonObjectBuilder timerangeBuilder = Json.createObjectBuilder(); + /****************************************************************** + * PRIVATE CLASS FIELDS. + ******************************************************************/ + + /** Handler name. */ + private static final String NAME = "JSON"; + + /** Handler release identifier. */ + private static final String RELEASE = "1.4"; + + /** String release. */ + private static final String RELEASE_CONSTANT = "release"; + + /** Handler release date. */ + private static final int[] DATE = { 2024, 11, 19 }; + + private static final String DATE_CONSTANT = "date"; + + /** well-formed. */ + private static final String WELL_FORMED = "Well-Formed"; + + /** not well-formed. */ + private static final String NOT_WELL_FORMED = "Not well-formed"; + + /** mix:tiles. */ + private static final String MIX_TILES = "mix:tiles"; + + /** mix:extraSamples. */ + private static final String MIX_EXTRA_SAMPLES = "mix:extraSamples"; + + /** mix:grayResponseUnit. */ + private static final String MIX_GRAY_RESPONSE_UNIT = "mix:grayResponseUnit"; + + /** Handler NTSC_NON_DROP_FRAME. */ + private static final String NTSC_NON_DROP_FRAME = "NTSC_NON_DROP_FRAME"; + + /** Handler note. */ + private static final String NOTE = ""; + + /** Handler rights statement. */ + private static final String RIGHTS = "Version 1.0 release by Open Preservation Foundation. " + + "Released under the GNU Lesser General Public License."; + + /****************************************************************** + * PRIVATE INSTANCE FIELDS. + ******************************************************************/ + + /** Main JSON builder */ + private JsonObjectBuilder jhoveBuilder; + private JsonArrayBuilder repInfosBuilder; + + /* Sample rate. */ + private double _sampleRate; + private String reportingModule = ""; + + /****************************************************************** + * CLASS CONSTRUCTOR. + ******************************************************************/ + + /** + * Creates an JsonHandler. + */ + public JsonHandler() { + super(NAME, RELEASE, DATE, NOTE, RIGHTS); + _vendor = Agent.bnfInstance(); + } + + /** Constructor for use by subclasses. */ + public JsonHandler(String name, String release, int[] date, String note, + String rights) { + super(name, release, date, note, rights); + _vendor = Agent.bnfInstance(); + } + + /****************************************************************** + * PUBLIC INSTANCE METHODS. + ******************************************************************/ + + /** + * Outputs minimal information about the application + */ + @Override + public void show() { + _level--; + } + + /** + * Outputs detailed information about the application, including + * configuration, available modules and handlers, etc. + */ + @Override + public void show(App app) { + JsonObjectBuilder appBuilder = Json.createObjectBuilder(); + + JsonObjectBuilder apiBuilder = Json.createObjectBuilder(); + apiBuilder.add("version", app.getRelease()); + apiBuilder.add(DATE_CONSTANT, date.format(_je.getDate())); + appBuilder.add("api", apiBuilder); + + String configFile = _je.getConfigFile(); + if (configFile != null) { + appBuilder.add("configuration", configFile); + } + String s = _je.getSaxClass(); + if (s != null) { + appBuilder.add("saxParser", s); + } + s = _je.getJhoveHome(); + if (s != null) { + appBuilder.add("jhoveHome", s); + } + s = _je.getEncoding(); + if (s != null) { + appBuilder.add("encoding", s); + } + s = _je.getTempDirectory(); + if (s != null) { + appBuilder.add("tempDirectory", s); + } + appBuilder.add("bufferSize", _je.getBufferSize()); + + JsonArrayBuilder modulesBuilder = Json.createArrayBuilder(); + for (String modKey : _je.getModuleMap().keySet()) { + Module module = _je.getModule(modKey); + modulesBuilder.add(Json.createObjectBuilder() + .add("module", module.getName()) + .add(RELEASE_CONSTANT, module.getRelease())); + + } + appBuilder.add("modules", modulesBuilder); + + JsonArrayBuilder oHandlersBuilder = Json.createArrayBuilder(); + for (String handlerKey : _je.getHandlerMap().keySet()) { + OutputHandler handler = _je.getHandler(handlerKey); + oHandlersBuilder.add(Json.createObjectBuilder() + .add("outputHandler", handler.getName()) + .add(RELEASE_CONSTANT, handler.getRelease())); + } + appBuilder.add("outputHandlers", oHandlersBuilder); + + appBuilder.add("usage", app.getUsage()); + appBuilder.add("rights", app.getRights()); + + jhoveBuilder.add("app", appBuilder); + } + + /** + * Outputs information about the OutputHandler specified in the parameter + */ + @Override + public void show(OutputHandler handler) { + JsonObjectBuilder outputHandlerBuilder = Json.createObjectBuilder(); + outputHandlerBuilder.add("name", handler.getName()); + outputHandlerBuilder.add(RELEASE_CONSTANT, handler.getRelease()); + outputHandlerBuilder.add(DATE_CONSTANT, date.format(handler.getDate())); + List list = handler.getSpecification(); + int n = list.size(); + if (n > 0) { + JsonArrayBuilder specBuilder = Json.createArrayBuilder(); + for (int i = 0; i < n; i++) { + specBuilder.add(showDocument(list.get(i))); + } + outputHandlerBuilder.add("specifications", specBuilder); + } + Agent vendor = handler.getVendor(); + if (vendor != null) { + outputHandlerBuilder.add("vendor", showAgent(vendor, "Vendor")); + } + String s; + if ((s = handler.getNote()) != null) { + outputHandlerBuilder.add("note", s); + } + if ((s = handler.getRights()) != null) { + outputHandlerBuilder.add("rights", s); + } + + jhoveBuilder.add("handler", outputHandlerBuilder); + } + + /** + * Outputs information about a Module + */ + @Override + public void show(Module module) { + JsonObjectBuilder modBuilder = Json.createObjectBuilder(); + modBuilder.add("name", module.getName()); + modBuilder.add(RELEASE_CONSTANT, module.getRelease()); + modBuilder + .add(DATE_CONSTANT, HandlerBase.date.format(module.getDate())); + + String[] ss = module.getFormat(); + if (ss.length > 0) { + modBuilder.add("formats", showArray(ss)); + } + String s = module.getCoverage(); + if (s != null) { + modBuilder.add("coverage", s); + } + ss = module.getMimeType(); + if (ss.length > 0) { + modBuilder.add("mimeTypes", showArray(ss)); + } + List list1 = module.getSignature(); + if (list1 != null && !list1.isEmpty()) { + JsonArrayBuilder sigBuilder = Json.createArrayBuilder(); + for (Signature sig : list1) { + sigBuilder.add(showSignature(sig)); + } + modBuilder.add("signatures", sigBuilder); + } + List list2 = module.getSpecification(); + if (list2 != null && !list2.isEmpty()) { + JsonArrayBuilder docBuilder = Json.createArrayBuilder(); + for (Document doc : list2) { + docBuilder.add(showDocument(doc)); + } + modBuilder.add("specifications", docBuilder); + } + List ftr = module.getFeatures(); + if (ftr != null && !ftr.isEmpty()) { + JsonArrayBuilder featuresBuilder = Json.createArrayBuilder(); + for (String f : ftr) { + featuresBuilder.add(f); + } + modBuilder.add("features", featuresBuilder); + } + + JsonObjectBuilder methodBuilder = Json.createObjectBuilder(); + if ((s = module.getWellFormedNote()) != null) { + methodBuilder.add("wellFormed", s); + } + if ((s = module.getValidityNote()) != null) { + methodBuilder.add("validity", s); + } + if ((s = module.getRepInfoNote()) != null) { + methodBuilder.add("repInfo", s); + } + modBuilder.add("methodology", methodBuilder); + + Agent vendor = module.getVendor(); + if (vendor != null) { + modBuilder.add("vendor", showAgent(vendor, "Vendor")); + } + if ((s = module.getNote()) != null) { + modBuilder.add("note", s); + } + if ((s = module.getRights()) != null) { + modBuilder.add("rights", s); + } + + jhoveBuilder.add("module", modBuilder); + } + + /** + * Outputs the information contained in a RepInfo object + */ + @Override + public void show(RepInfo info) { + JsonObjectBuilder infoBuilder = Json.createObjectBuilder(); + + Module module = info.getModule(); + _logger.info("Reporting RepInfo"); + if (_je.getSignatureFlag()) { + _logger.info("Checking signatures only"); + } + infoBuilder.add("uri", info.getUri()); + + if (module != null) { + this.reportingModule = module.getName(); + infoBuilder.add( + "reportingModule", + Json.createObjectBuilder().add("name", this.reportingModule) + .add(RELEASE_CONSTANT, module.getRelease()) + .add(DATE_CONSTANT, date.format(module.getDate()))); + } + Date date = info.getCreated(); + if (date != null) { + infoBuilder.add("created", toDateTime(date)); + } + date = info.getLastModified(); + if (date != null) { + infoBuilder.add("lastModified", toDateTime(date)); + } + long size = info.getSize(); + if (size > -1) { + infoBuilder.add("size", size); + } + String s = info.getFormat(); + if (s != null) { + infoBuilder.add("format", s); + } + if ((s = info.getVersion()) != null) { + infoBuilder.add("version", s); + } + String wfStr; + if (!_je.getSignatureFlag()) { + switch (info.getWellFormed()) { + case RepInfo.TRUE: + wfStr = WELL_FORMED; + break; + + case RepInfo.FALSE: + wfStr = NOT_WELL_FORMED; + break; + + default: + wfStr = "Unknown"; + break; + } + // If it's well-formed, append validity information + if (info.getWellFormed() == RepInfo.TRUE) { + switch (info.getValid()) { + case RepInfo.TRUE: + wfStr += " and valid"; + break; + + case RepInfo.FALSE: + wfStr += ", but not valid"; + break; + + default: + // case UNDETERMINED: add nothing + break; + } + } + _logger.info("Validity/WF status: " + wfStr); + infoBuilder.add("status", wfStr); + } else { + // If we aren't checking signatures, we still need to say something. + switch (info.getWellFormed()) { + case RepInfo.TRUE: + wfStr = WELL_FORMED; + break; + + default: + wfStr = NOT_WELL_FORMED; + break; + } + infoBuilder.add("status", wfStr); + } + + List list1 = info.getSigMatch(); + if (list1 != null && !list1.isEmpty()) { + JsonArrayBuilder sigBuilder = Json.createArrayBuilder(); + for (String sigm : list1) { + sigBuilder.add(sigm); + } + infoBuilder.add("sigMatch", sigBuilder); + } + + List list2 = info.getMessage(); + if (list2 != null && !list2.isEmpty()) { + JsonArrayBuilder msgBuilder = Json.createArrayBuilder(); + for (Message msg : list2) { + msgBuilder.add(showMessage(msg)); + } + infoBuilder.add("messages", msgBuilder); + } + + s = info.getMimeType(); + if (s != null) { + infoBuilder.add("mimeType", s); + } + + List list3 = info.getProfile(); + if (list3 != null && !list3.isEmpty()) { + JsonArrayBuilder profBuilder = Json.createArrayBuilder(); + for (String prof : list3) { + profBuilder.add(prof); + } + infoBuilder.add("profiles", profBuilder); + } + + Map map = info.getProperty(); + if (map != null && !map.isEmpty()) { + JsonArrayBuilder propBuilder = Json.createArrayBuilder(); + for (String key : map.keySet()) { + Property property = info.getProperty(key); + propBuilder.add(showProperty(property)); + } + infoBuilder.add("properties", propBuilder); + } + + List list4 = info.getChecksum(); + if (list4 != null && !list4.isEmpty()) { + JsonArrayBuilder checksumBuilder = Json.createArrayBuilder(); + for (Checksum ck : list4) { + checksumBuilder.add(showChecksum(ck)); + } + infoBuilder.add("properties", checksumBuilder); + } + + if ((s = info.getNote()) != null) { + infoBuilder.add("note", s); + } + + // Store the infoBuilder in the array of repInfos + if (repInfosBuilder == null) { + repInfosBuilder = Json.createArrayBuilder(); + } + repInfosBuilder.add(infoBuilder); + } + + /****************************************************************** + * PRIVATE INSTANCE METHODS. + ******************************************************************/ + protected JsonObjectBuilder showAgent(Agent agent, String label) { + JsonObjectBuilder agentBuilder = Json.createObjectBuilder(); + agentBuilder.add("kind", label); + agentBuilder.add("name", agent.getName()); + agentBuilder.add("type", agent.getType().toString()); + String s = agent.getAddress(); + if (s != null) { + agentBuilder.add("address", s); + } + if ((s = agent.getTelephone()) != null) { + agentBuilder.add("telephone", s); + } + if ((s = agent.getFax()) != null) { + agentBuilder.add("fax", s); + } + if ((s = agent.getEmail()) != null) { + agentBuilder.add("email", s); + } + if ((s = agent.getWeb()) != null) { + agentBuilder.add("web", s); + } + return agentBuilder; + } + + protected JsonObjectBuilder showChecksum(Checksum checksum) { + return Json.createObjectBuilder().add("checksum", checksum.getValue()) + .add("type", checksum.getType().toString()); + } + + protected JsonObjectBuilder showDocument(Document document) { + JsonObjectBuilder docBuilder = Json.createObjectBuilder(); + docBuilder.add("title", document.getTitle()); + docBuilder.add("type", document.getType().toString()); + List list1 = document.getAuthor(); + if (list1 != null && !list1.isEmpty()) { + JsonArrayBuilder autBuilder = Json.createArrayBuilder(); + for (Agent ag : list1) { + autBuilder.add(showAgent(ag, "Author")); + } + docBuilder.add("authors", autBuilder); + } + List list2 = document.getPublisher(); + if (list2 != null && !list2.isEmpty()) { + JsonArrayBuilder pubBuilder = Json.createArrayBuilder(); + for (Agent ag : list2) { + pubBuilder.add(showAgent(ag, "Publisher")); + } + docBuilder.add("publishers", pubBuilder); + } + String s = document.getEdition(); + if (s != null) { + docBuilder.add("edition", s); + } + if ((s = document.getDate()) != null) { + docBuilder.add(DATE_CONSTANT, s); + } + if ((s = document.getEnumeration()) != null) { + docBuilder.add("enumeration", s); + } + if ((s = document.getPages()) != null) { + docBuilder.add("pages", s); + } + List list3 = document.getIdentifier(); + if (list3 != null && !list3.isEmpty()) { + JsonArrayBuilder idBuilder = Json.createArrayBuilder(); + for (Identifier id : list3) { + idBuilder.add(showIdentifier(id)); + } + docBuilder.add("identifiers", idBuilder); + } + if ((s = document.getNote()) != null) { + docBuilder.add("note", s); + } + return docBuilder; + } + + /** + * Do the final output. This should be in a suitable format for including + * multiple files between the header and the footer, and the XML of the + * header and footer must balance out. + */ + @Override + public void showFooter() { + if (repInfosBuilder != null) { + jhoveBuilder.add("repInfo", repInfosBuilder); + } + + JsonObjectBuilder mainBuilder = Json.createObjectBuilder(); + mainBuilder.add("jhove", jhoveBuilder); + JsonObject jsonObject = mainBuilder.build(); + + JsonWriter jsonWriter = Json.createWriter(_writer); + jsonWriter.writeObject(jsonObject); + jsonWriter.close(); + } + + /** + * Do the initial output. This should be in a suitable format for including + * multiple files between the header and the footer, and the XML of the + * header and footer must balance out. + */ + @Override + public void showHeader() { + jhoveBuilder = Json.createObjectBuilder(); + jhoveBuilder.add("name", _app.getName()); + jhoveBuilder.add(RELEASE_CONSTANT, _app.getRelease()); + jhoveBuilder + .add(DATE_CONSTANT, HandlerBase.date.format(_app.getDate())); + jhoveBuilder.add("executionTime", toDateTime(new Date())); + repInfosBuilder = null; + } + + protected JsonObjectBuilder showIdentifier(Identifier identifier) { + JsonObjectBuilder idBuilder = Json.createObjectBuilder(); + idBuilder.add("value", identifier.getValue()); + idBuilder.add("type", identifier.getType().toString()); + String note = identifier.getNote(); + if (note != null) { + idBuilder.add("note", note); + } + return idBuilder; + } + + protected JsonObjectBuilder showMessage(Message message) { + JsonObjectBuilder msgBuilder = Json.createObjectBuilder(); + + msgBuilder.add("message", message.getMessage()); + String submsg = message.getSubMessage(); + if (submsg != null) { + msgBuilder.add("subMessage", submsg); + } + long offset = message.getOffset(); + if (offset > -1) { + msgBuilder.add("offset", offset); + } + if (!message.getPrefix().isEmpty()) { + msgBuilder.add("severity", message.getPrefix().toLowerCase()); + } + String id = message.getJhoveMessage().getId(); + if (!(id == null || id.isEmpty() || JhoveMessages.NO_ID.equals(id))) { + msgBuilder.add("id", message.getId()); + msgBuilder.add("infoLink", Handlers.makeInfoLink(this.reportingModule, id)); + } + return msgBuilder; + } + + protected JsonObjectBuilder showSignature(Signature signature) { + JsonObjectBuilder sigBuilder = Json.createObjectBuilder(); + + String sigValue; + if (signature.isStringValue()) { + sigValue = signature.getValueString(); + } else { + sigValue = signature.getValueHexString(); + } + sigBuilder.add("type", signature.getType().toString()); + sigBuilder.add("value", sigValue); + if (SignatureType.MAGIC.equals(signature.getType()) + && ((InternalSignature) signature).hasFixedOffset()) { + sigBuilder + .add("offset", + "0x" + + Integer + .toHexString(((InternalSignature) signature) + .getOffset())); + } + String note = signature.getNote(); + if (note != null) { + sigBuilder.add("note", note); + + } + String use = signature.getUse().toString(); + if (use != null) { + sigBuilder.add("use", use); + } + return sigBuilder; + } + + /* Do special conversions on values as needed. */ + protected String valueToString(Object obj) { + if (obj instanceof Date) { + return toDateTime((Date) obj); + } + return obj.toString(); + } + + protected JsonObjectBuilder showProperty(Property property) { + JsonObjectBuilder propBuilder = Json.createObjectBuilder(); + + PropertyArity arity = property.getArity(); + switch (arity) { + case SCALAR: + return showScalarProperty(property); + case ARRAY: + return showArrayProperty(property); + case LIST: + return showListProperty(property); + case MAP: + return showMapProperty(property); + case SET: + return showSetProperty(property); + default: + return propBuilder; + } + } + + protected JsonObjectBuilder showScalarProperty(Property property) { + JsonObjectBuilder propBuilder = Json.createObjectBuilder(); + + PropertyType propType = property.getType(); + switch (propType) { + case BOOLEAN: + Boolean b = (Boolean) property.getValue(); + propBuilder.add(property.getName(), b.booleanValue()); + break; + case BYTE: + case CHARACTER: + case OBJECT: + propBuilder.add(property.getName(), property.getValue().toString()); + break; + case DATE: + Date dt = (Date) property.getValue(); + propBuilder.add(property.getName(), toDateTime(dt)); + break; + case DOUBLE: + Double d = (Double) property.getValue(); + propBuilder.add(property.getName(), d.doubleValue()); + break; + case FLOAT: + Float f = (Float) property.getValue(); + propBuilder.add(property.getName(), f.floatValue()); + break; + case INTEGER: + Integer i = (Integer) property.getValue(); + propBuilder.add(property.getName(), i.intValue()); + break; + case LONG: + Long l = (Long) property.getValue(); + propBuilder.add(property.getName(), l.longValue()); + break; + case AESAUDIOMETADATA: + propBuilder + .add(property.getName(), + showAESAudioMetadata((AESAudioMetadata) property + .getValue())); + break; + case NISOIMAGEMETADATA: + propBuilder.add(property.getName(), + showNisoImageMetadata((NisoImageMetadata) property + .getValue())); + break; + case TEXTMDMETADATA: + propBuilder.add(property.getName(), + showTextMDMetadata((TextMDMetadata) property.getValue())); + break; + case SHORT: + Short s = (Short) property.getValue(); + propBuilder.add(property.getName(), s.shortValue()); + break; + case STRING: + propBuilder.add(property.getName(), (String) property.getValue()); + break; + case RATIONAL: + propBuilder.add(property.getName(), + showRational((Rational) property.getValue())); + break; + case PROPERTY: + Property property2 = (Property) property.getValue(); + propBuilder.add(property.getName(), showProperty(property2)); + break; + default: + propBuilder.add(property.getName(), property.getValue().toString()); + break; + } + return propBuilder; + } + + protected JsonObjectBuilder showListProperty(Property property) { + JsonObjectBuilder propBuilder = Json.createObjectBuilder(); + List propList = (List) property.getValue(); + JsonArrayBuilder lPropBuilder = Json.createArrayBuilder(); + PropertyType type = property.getType(); + + ListIterator iter = propList.listIterator(); + while (iter.hasNext()) { + Object val = iter.next(); + switch (type) { + case BOOLEAN: + lPropBuilder.add(((Boolean) val).booleanValue()); + break; + case BYTE: + lPropBuilder.add(valueToString(val)); + break; + case CHARACTER: + lPropBuilder.add(valueToString(val)); + break; + case DATE: + lPropBuilder.add(valueToString(val)); + break; + case DOUBLE: + lPropBuilder.add(((Double) val).doubleValue()); + break; + case FLOAT: + lPropBuilder.add(((Float) val).floatValue()); + break; + case INTEGER: + lPropBuilder.add(((Integer) val).intValue()); + break; + case LONG: + lPropBuilder.add(((Long) val).longValue()); + break; + case OBJECT: + lPropBuilder.add(valueToString(val)); + break; + case SHORT: + lPropBuilder.add(((Short) val).shortValue()); + break; + case STRING: + lPropBuilder.add(valueToString(val)); + break; + case RATIONAL: + lPropBuilder.add(showRational((Rational) val)); + break; + case PROPERTY: + lPropBuilder.add(showProperty((Property) val)); + break; + case NISOIMAGEMETADATA: + lPropBuilder + .add(showNisoImageMetadata((NisoImageMetadata) property + .getValue())); + break; + case AESAUDIOMETADATA: + lPropBuilder + .add(showAESAudioMetadata((AESAudioMetadata) property + .getValue())); + break; + case TEXTMDMETADATA: + lPropBuilder.add(showTextMDMetadata((TextMDMetadata) property + .getValue())); + break; + default: + break; + } + } + propBuilder.add(property.getName(), lPropBuilder); + return propBuilder; + } + + protected JsonObjectBuilder showSetProperty(Property property) { + JsonObjectBuilder propBuilder = Json.createObjectBuilder(); + Set propSet = (Set) property.getValue(); + JsonArrayBuilder lPropBuilder = Json.createArrayBuilder(); + PropertyType type = property.getType(); + + Iterator iter = propSet.iterator(); + while (iter.hasNext()) { + Object val = iter.next(); + switch (type) { + case BOOLEAN: + lPropBuilder.add(((Boolean) val).booleanValue()); + break; + case BYTE: + lPropBuilder.add(valueToString(val)); + break; + case CHARACTER: + lPropBuilder.add(valueToString(val)); + break; + case DATE: + lPropBuilder.add(valueToString(val)); + break; + case DOUBLE: + lPropBuilder.add(((Double) val).doubleValue()); + break; + case FLOAT: + lPropBuilder.add(((Float) val).floatValue()); + break; + case INTEGER: + lPropBuilder.add(((Integer) val).intValue()); + break; + case LONG: + lPropBuilder.add(((Long) val).longValue()); + break; + case OBJECT: + lPropBuilder.add(valueToString(val)); + break; + case SHORT: + lPropBuilder.add(((Short) val).shortValue()); + break; + case STRING: + lPropBuilder.add(valueToString(val)); + break; + case RATIONAL: + lPropBuilder.add(showRational((Rational) val)); + break; + case PROPERTY: + lPropBuilder.add(showProperty((Property) val)); + break; + case NISOIMAGEMETADATA: + lPropBuilder + .add(showNisoImageMetadata((NisoImageMetadata) property + .getValue())); + break; + case AESAUDIOMETADATA: + lPropBuilder + .add(showAESAudioMetadata((AESAudioMetadata) property + .getValue())); + break; + case TEXTMDMETADATA: + lPropBuilder.add(showTextMDMetadata((TextMDMetadata) property + .getValue())); + break; + default: + break; + } + } + propBuilder.add(property.getName(), lPropBuilder); + return propBuilder; + } + + protected JsonObjectBuilder showMapProperty(Property property) { + JsonObjectBuilder propBuilder = Json.createObjectBuilder(); + JsonObjectBuilder lPropBuilder = Json.createObjectBuilder(); + Map propMap = (Map) property.getValue(); + PropertyType type = property.getType(); + Iterator keyIter = propMap.keySet().iterator(); + while (keyIter.hasNext()) { + Object key = keyIter.next(); + String keystr = key.toString(); + Object val = propMap.get(key); + switch (type) { + case BOOLEAN: + lPropBuilder.add(keystr, ((Boolean) val).booleanValue()); + break; + case BYTE: + lPropBuilder.add(keystr, valueToString(val)); + break; + case CHARACTER: + lPropBuilder.add(keystr, valueToString(val)); + break; + case DATE: + lPropBuilder.add(keystr, valueToString(val)); + break; + case DOUBLE: + lPropBuilder.add(keystr, ((Double) val).doubleValue()); + break; + case FLOAT: + lPropBuilder.add(keystr, ((Float) val).floatValue()); + break; + case INTEGER: + lPropBuilder.add(keystr, ((Integer) val).intValue()); + break; + case LONG: + lPropBuilder.add(keystr, ((Long) val).longValue()); + break; + case OBJECT: + lPropBuilder.add(keystr, valueToString(val)); + break; + case SHORT: + lPropBuilder.add(keystr, ((Short) val).shortValue()); + break; + case STRING: + lPropBuilder.add(keystr, valueToString(val)); + break; + case RATIONAL: + lPropBuilder.add(keystr, showRational((Rational) val)); + break; + case PROPERTY: + lPropBuilder.add(keystr, showProperty((Property) val)); + break; + case NISOIMAGEMETADATA: + lPropBuilder.add(keystr, + showNisoImageMetadata((NisoImageMetadata) property + .getValue())); + break; + case AESAUDIOMETADATA: + lPropBuilder.add(keystr, + showAESAudioMetadata((AESAudioMetadata) property + .getValue())); + break; + case TEXTMDMETADATA: + lPropBuilder + .add(keystr, + showTextMDMetadata((TextMDMetadata) property + .getValue())); + break; + default: + break; + } + } + propBuilder.add(property.getName(), lPropBuilder); + return propBuilder; + } + + /** + * Gives the length (number of elements) of a property + */ + protected int propertyLength(Property property) { + int n = 0; + try { + switch (property.getArity()) { + case SET: + Set propSet = (Set) property.getValue(); + n = propSet.size(); + break; + case LIST: + List propList = (List) property.getValue(); + n = propList.size(); + break; + case MAP: + Map propMap = (Map) property.getValue(); + n = propMap.size(); + break; + case ARRAY: + // Ack! Is there any easy way to do this? + switch (property.getType()) { + case BOOLEAN: + boolean[] boolArray = (boolean[]) property.getValue(); + n = boolArray.length; + break; + case BYTE: + byte[] byteArray = (byte[]) property.getValue(); + n = byteArray.length; + break; + case CHARACTER: + char[] charArray = (char[]) property.getValue(); + n = charArray.length; + break; + case DATE: + Date[] dateArray = (Date[]) property.getValue(); + n = dateArray.length; + break; + case DOUBLE: + double[] doubleArray = (double[]) property.getValue(); + n = doubleArray.length; + break; + case FLOAT: + float[] floatArray = (float[]) property.getValue(); + n = floatArray.length; + break; + case INTEGER: + int[] intArray = (int[]) property.getValue(); + n = intArray.length; + break; + case LONG: + long[] longArray = (long[]) property.getValue(); + n = longArray.length; + break; + case OBJECT: + Object[] objArray = (Object[]) property.getValue(); + n = objArray.length; + break; + case SHORT: + short[] shortArray = (short[]) property.getValue(); + n = shortArray.length; + break; + case STRING: + String[] stringArray = (String[]) property.getValue(); + n = stringArray.length; + break; + case RATIONAL: + Rational[] rationalArray = (Rational[]) property.getValue(); + n = rationalArray.length; + break; + case PROPERTY: + Property[] propArray = (Property[]) property.getValue(); + n = propArray.length; + break; + case NISOIMAGEMETADATA: + NisoImageMetadata[] nisoArray = (NisoImageMetadata[]) property + .getValue(); + n = nisoArray.length; + break; + case AESAUDIOMETADATA: + AESAudioMetadata[] aesArray = (AESAudioMetadata[]) property + .getValue(); + n = aesArray.length; + break; + case TEXTMDMETADATA: + TextMDMetadata[] textMDArray = (TextMDMetadata[]) property + .getValue(); + n = textMDArray.length; + break; + default: + Object[] array2 = (Object[]) property.getValue(); + n = array2.length; + break; + } + break; + default: + if (property.getValue().toString().length() == 0) { + n = 0; + } else { + n = 1; + } + break; + } + } catch (Exception e) { + // If something goes seriously wrong, return true to punt the + // property + return 0; + } + return n; + } + + /* + * The array property has so many special cases of its own that we break it + * out of showProperty + */ + protected JsonObjectBuilder showArrayProperty(Property property) { + boolean[] boolArray = null; + byte[] byteArray = null; + char[] charArray = null; + java.util.Date[] dateArray = null; + double[] doubleArray = null; + float[] floatArray = null; + int[] intArray = null; + long[] longArray = null; + Object[] objArray = null; + Property[] propArray = null; + short[] shortArray = null; + String[] stringArray = null; + Rational[] rationalArray = null; + NisoImageMetadata[] nisoArray = null; + AESAudioMetadata[] aesArray = null; + TextMDMetadata[] textMDArray = null; + int n = 0; + + PropertyType propType = property.getType(); + switch (propType) { + case BOOLEAN: + boolArray = (boolean[]) property.getValue(); + n = boolArray.length; + break; + case BYTE: + byteArray = (byte[]) property.getValue(); + n = byteArray.length; + break; + case CHARACTER: + charArray = (char[]) property.getValue(); + n = charArray.length; + break; + case DATE: + dateArray = (Date[]) property.getValue(); + n = dateArray.length; + break; + case DOUBLE: + doubleArray = (double[]) property.getValue(); + n = doubleArray.length; + break; + case FLOAT: + floatArray = (float[]) property.getValue(); + n = floatArray.length; + break; + case INTEGER: + intArray = (int[]) property.getValue(); + n = intArray.length; + break; + case LONG: + longArray = (long[]) property.getValue(); + n = longArray.length; + break; + case OBJECT: + objArray = (Object[]) property.getValue(); + n = objArray.length; + break; + case SHORT: + shortArray = (short[]) property.getValue(); + n = shortArray.length; + break; + case STRING: + stringArray = (String[]) property.getValue(); + n = stringArray.length; + break; + case RATIONAL: + rationalArray = (Rational[]) property.getValue(); + n = rationalArray.length; + break; + case PROPERTY: + propArray = (Property[]) property.getValue(); + n = propArray.length; + break; + case NISOIMAGEMETADATA: + nisoArray = (NisoImageMetadata[]) property.getValue(); + n = nisoArray.length; + break; + case AESAUDIOMETADATA: + aesArray = (AESAudioMetadata[]) property.getValue(); + n = aesArray.length; + break; + case TEXTMDMETADATA: + textMDArray = (TextMDMetadata[]) property.getValue(); + n = textMDArray.length; + break; + default: + break; + } + + JsonArrayBuilder arrayBuilder = Json.createArrayBuilder(); + for (int i = 0; i < n; i++) { + switch (propType) { + case BOOLEAN: + arrayBuilder.add(boolArray[i]); + break; + case BYTE: + arrayBuilder.add(String.valueOf(byteArray[i])); + break; + case CHARACTER: + arrayBuilder.add(String.valueOf(charArray[i])); + break; + case DATE: + arrayBuilder.add(dateArray[i].toString()); + break; + case DOUBLE: + arrayBuilder.add(doubleArray[i]); + break; + case FLOAT: + arrayBuilder.add(floatArray[i]); + break; + case INTEGER: + arrayBuilder.add(intArray[i]); + break; + case LONG: + arrayBuilder.add(longArray[i]); + break; + case OBJECT: + arrayBuilder.add(valueToString(objArray[i])); + break; + case SHORT: + arrayBuilder.add(shortArray[i]); + break; + case STRING: + arrayBuilder.add(stringArray[i]); + break; + case RATIONAL: + arrayBuilder.add(rationalArray[i].toString()); + break; + case PROPERTY: + arrayBuilder.add(showProperty(propArray[i])); + break; + case NISOIMAGEMETADATA: + arrayBuilder.add(showNisoImageMetadata(nisoArray[i])); + break; + case AESAUDIOMETADATA: + arrayBuilder.add(showAESAudioMetadata(aesArray[i])); + break; + case TEXTMDMETADATA: + arrayBuilder.add(showTextMDMetadata(textMDArray[i])); + break; + default: + arrayBuilder.add(""); + break; + } + } + return Json.createObjectBuilder().add(property.getName(), arrayBuilder); + } + + /* + * Output the textMD metadata, which is its own special kind of property. + */ + protected JsonObjectBuilder showTextMDMetadata(TextMDMetadata textMD) { + JsonObjectBuilder textmdBuilder = Json.createObjectBuilder(); + addStringToJson(textmdBuilder, "textmd:charset", textMD.getCharset()); + addStringToJson(textmdBuilder, "textmd:byte_order", textMD.getByte_orderString()); + addStringToJson(textmdBuilder, "textmd:byte_size", textMD.getByte_size()); + addStringToJson(textmdBuilder, "textmd:character_size", textMD.getCharacter_size()); + addStringToJson(textmdBuilder, "textmd:linebreak", textMD.getLinebreakString()); + addStringToJson(textmdBuilder, "textmd:language", textMD.getLanguage()); + addStringToJson(textmdBuilder, "textmd:markup_basis", textMD.getMarkup_basis()); + addStringToJson(textmdBuilder, "textmd:markup_basis_version", textMD.getMarkup_basis_version()); + addStringToJson(textmdBuilder, "textmd:markup_language", textMD.getMarkup_language()); + addStringToJson(textmdBuilder, "textmd:markup_language_version", textMD.getMarkup_language_version()); + return textmdBuilder; + } + + /** + * Display the NISO image metadata formatted according to the MIX schema. + * The schema which is used may be 0.2 or 1.0 or 2.0, depending on the + * module parameters. + * + * @param niso + * NISO image metadata + */ + protected JsonObjectBuilder showNisoImageMetadata(NisoImageMetadata niso) { + if ("0.2".equals(_je.getMixVersion())) { + return null; // don't handle mix version 0.2 + } else if ("1.0".equals(_je.getMixVersion())) { + return showNisoImageMetadata(niso, true); + } else { + return showNisoImageMetadata(niso, false); + } + } + + /** + * Display the NISO image metadata formatted according to the MIX 1.0 + * schema. + */ + protected JsonObjectBuilder showNisoImageMetadata(NisoImageMetadata niso, + boolean bMix10) { + JsonObjectBuilder mixBuilder = Json.createObjectBuilder(); + + JsonObjectBuilder ob = showNisoBasicDigitalObjectInformation(niso, + bMix10); + if (ob != null) { + mixBuilder.add("mix:BasicDigitalObjectInformation", ob); + } + ob = showNisoBasicImageInformation(niso, bMix10); + if (ob != null) { + mixBuilder.add("mix:BasicImageInformation", ob); + } + ob = showNisoImageCaptureMetadata(niso, bMix10); + if (ob != null) { + mixBuilder.add("mix:ImageCaptureMetadata", ob); + } + ob = showNisoImageAssessmentMetadata(niso, bMix10); + if (ob != null) { + mixBuilder.add("mix:ImageAssessmentMetadata", ob); + } + ob = showChangeHistory(niso, bMix10); + if (ob != null) { + mixBuilder.add("mix:ChangeHistory", ob); + } + return mixBuilder; + } + + /* + * The NISO Metadata output is split into multiple functions so that they're + * merely outrageously big rather than disgustingly big + */ + /* Top level element 1 of 5: BasicDigitalObjectInformation */ + protected JsonObjectBuilder showNisoBasicDigitalObjectInformation( + NisoImageMetadata niso, boolean bMix10) { + JsonObjectBuilder mixBuilder = Json.createObjectBuilder(); + + String s = niso.getImageIdentifier(); + if (s != null) { + mixBuilder.add( + "mix:ObjectIdentifier", + Json.createObjectBuilder() + .add("mix:objectIdentifierType", "JHOVE") + .add("mix:objectIdentifierValue", s)); + } + long ln = niso.getFileSize(); + if (ln != NisoImageMetadata.NULL) { + mixBuilder.add("mix:fileSize", ln); + } + if ((s = niso.getMimeType()) != null) { + mixBuilder.add("mix:formatName", s); + } + if ((s = niso.getByteOrder()) != null) { + // Convert strings to MIX 1.0 form + if (s.startsWith("big")) { + s = bMix10 ? "big_endian" : "big endian"; + } else if (s.startsWith("little")) { + s = bMix10 ? "little_endian" : "little endian"; + } + mixBuilder.add("mix:byteOrder", s); + } + int comp = niso.getCompressionScheme(); + int level = niso.getCompressionLevel(); + String compStr; + switch (comp) { + case 1: + compStr = "Uncompressed"; + break; + case 2: + compStr = "CCITT 1D"; + break; + case 3: + compStr = "Group 3 Fax"; + break; + case 4: + compStr = "Group 4 Fax"; + break; + case 5: + compStr = "LZW"; + break; + case 6: + compStr = "JPEG"; + break; + case 32773: + compStr = "PackBits"; + break; + case 34713: + compStr = "JPEG2000 Lossy"; + break; + case 34714: + compStr = "JPEG2000 Lossless"; + break; + default: + compStr = "Unknown"; + break; + } + if (comp != NisoImageMetadata.NULL) { + if (comp == 34713 || comp == 34714) { + mixBuilder.add("mix:compressionScheme", + compressionSchemeToString(comp)); + if (level != NisoImageMetadata.NULL) { + mixBuilder.add("mix:compressionRatio", level); + } + } else if (bMix10) { + mixBuilder.add("mix:compressionScheme", Integer.toString(comp)); + } else { + mixBuilder.add("mix:compressionScheme", compStr); + } + } + int n = niso.getChecksumMethod(); + s = niso.getChecksumValue(); + if (n != NisoImageMetadata.NULL || s != null) { + if (n != NisoImageMetadata.NULL) { + mixBuilder.add("mix:messageDigestAlgorithm", n); + } + if (s != null) { + mixBuilder.add("mix:messageDigest", s); + } + } + return mixBuilder; + } + + /* 1.0, Top level element 2 of 5: BasicImageInformation */ + protected JsonObjectBuilder showNisoBasicImageInformation( + NisoImageMetadata niso, boolean bMix10) { + JsonObjectBuilder mixBuilder = Json.createObjectBuilder(); + boolean hasBuilder = false; + long ln = niso.getImageWidth(); + if (ln != NisoImageMetadata.NULL) { + mixBuilder.add("mix:imageWidth", ln); + hasBuilder = true; + } + ln = niso.getImageLength(); + if (ln != NisoImageMetadata.NULL) { + mixBuilder.add("mix:imageHeight", ln); + hasBuilder = true; + } + int n = niso.getColorSpace(); + if (n != NisoImageMetadata.NULL) { + if (bMix10) { + mixBuilder.add("mix:colorSpace", n); + } else { + mixBuilder.add("mix:colorSpace", + photometricInterpretationToString(n)); + } + hasBuilder = true; + } + String s = niso.getProfileName(); + String s2 = niso.getProfileURL(); + if (s != null || s2 != null) { + JsonObjectBuilder iccBuilder = Json.createObjectBuilder(); + addStringToJson(iccBuilder, "mix:iccProfileName", s); + addStringToJson(iccBuilder, "mix:iccProfileURL", s2); + mixBuilder.add("mix:IccProfile", iccBuilder); + hasBuilder = true; + } + int[] iarray = niso.getYCbCrSubSampling(); + n = niso.getYCbCrPositioning(); + Rational[] rarray = niso.getYCbCrCoefficients(); + if (iarray != null || n != NisoImageMetadata.NULL || rarray != null) { + JsonObjectBuilder yccBuilder = Json.createObjectBuilder(); + if (iarray != null && iarray.length >= 2) { + yccBuilder.add( + "mix:YCbCrSubSampling", + Json.createObjectBuilder() + .add("mix:yCbCrSubsampleHoriz", iarray[0]) + .add("mix:yCbCrSubsampleVert", iarray[1])); + } + addNisoIntToJson(yccBuilder, "mix:yCbCrPositioning", n); + if (rarray != null) { + if (bMix10) { + yccBuilder.add("mix:yCbCrCoefficients", showArray(rarray)); + } else { + yccBuilder + .add("mix:yCbCrCoefficients", + Json.createObjectBuilder() + .add("mix:lumaRed", + showRational(rarray[0])) + .add("mix:lumaGreen", + showRational(rarray[1])) + .add("mix:lumaBlue", + showRational(rarray[2]))); + } + } + mixBuilder.add("mix:YCbCr", yccBuilder); + hasBuilder = true; + } + rarray = niso.getReferenceBlackWhite(); + if (rarray != null) { + if (bMix10) { + mixBuilder.add("mix:referenceBlackWhite", showArray(rarray)); + } else { + JsonArrayBuilder aBuilder = Json.createArrayBuilder(); + for (int i = 0; i < rarray.length - 1; i += 2) { + JsonObjectBuilder cBuilder = Json.createObjectBuilder(); + // Tricky here. + // The reference BW might be given as either RGB or yCbCr. + String pi; + if (niso.getColorSpace() == 6) { // yCbCr + switch (i) { + case 0: + pi = "Y"; + break; + case 2: + pi = "Cb"; + break; + case 4: + default: + pi = "Cr"; + break; + } + } else { + switch (i) { // otherwise assume RGB + case 0: + pi = "R"; + break; + case 2: + pi = "G"; + break; + case 4: + default: + pi = "B"; + break; + } + } + cBuilder.add("mix:componentPhotometricInterpretation", pi); + cBuilder.add("mix:footroom", showRational(rarray[i])); + cBuilder.add("mix:headroom", showRational(rarray[i + 1])); + aBuilder.add(cBuilder); + } + mixBuilder.add("mix:ReferenceBlackWhite", aBuilder); + } + hasBuilder = true; + } + // SpecialFormatCharacteristics limited to JPEG2000 + int lay = niso.getJp2Layers(); + int lev = niso.getJp2ResolutionLevels(); + String sizTiles = niso.getJp2Tiles(); + if (sizTiles != null || lay != NisoImageMetadata.NULL + || lev != NisoImageMetadata.NULL) { + JsonObjectBuilder jp2Builder = Json.createObjectBuilder(); + if (sizTiles != null) { + if (bMix10) { + jp2Builder.add(MIX_TILES, sizTiles); + } else { + String[] sizes = sizTiles.split("x"); + jp2Builder.add(MIX_TILES, showArray(sizes)); + } + } + addNisoIntToJson(jp2Builder, "mix:qualityLayers", lay); + addNisoIntToJson(jp2Builder, "mix:resolutionLevels", lev); + mixBuilder.add("mix:JPEG2000", jp2Builder); + hasBuilder = true; + } + + return hasBuilder ? mixBuilder : null; + } + + /* 1.0, Top level element 3 of 5: ImageCaptureMetadata */ + protected JsonObjectBuilder showNisoImageCaptureMetadata( + NisoImageMetadata niso, boolean bMix10) { + JsonObjectBuilder mixBuilder = Json.createObjectBuilder(); + boolean hasBuilder = false; + + hasBuilder |= addStringToJson(mixBuilder, "mix:sourceType", niso.getSourceType()); + hasBuilder |= addStringToJson(mixBuilder, "mix:sourceIDValue", niso.getSourceID()); + double d = niso.getSourceXDimension(); + int n = niso.getSourceXDimensionUnit(); + if (d != NisoImageMetadata.NILL || n != NisoImageMetadata.NULL) { + // Assume that both X and Y exist, or neither + addNisoDoubleToJson(mixBuilder, "mix:sourceXDimensionValue", d); + addNisoIntToJson(mixBuilder, "mix:sourceXDimensionUnit", n); + addNisoDoubleToJson(mixBuilder, "mix:sourceYDimensionValue", niso.getSourceYDimension()); + addNisoIntToJson(mixBuilder, "mix:sourceYDimensionUnit", niso.getSourceYDimensionUnit()); + hasBuilder = true; + } + + hasBuilder |= addStringToJson(mixBuilder, "mix:dateTimeCreated", niso.getDateTimeCreated()); + hasBuilder |= addStringToJson(mixBuilder, "mix:imageProducer", niso.getImageProducer()); + hasBuilder |= addStringToJson(mixBuilder, "mix:captureDevice", niso.getDeviceSource()); + hasBuilder |= addStringToJson(mixBuilder, "mix:scannerManufacturer", niso.getScannerManufacturer()); + + String model = niso.getScannerModelName(); + String modelNum = niso.getScannerModelNumber(); + String serNum = niso.getScannerModelSerialNo(); + if (model != null || modelNum != null || serNum != null) { + hasBuilder = true; + JsonObjectBuilder smBuilder = Json.createObjectBuilder(); + addStringToJson(smBuilder, "mix:scannerModelName", model); + addStringToJson(smBuilder, "mix:scannerModelNumber", modelNum); + addStringToJson(smBuilder, "mix:scannerModelSerialNo", serNum); + mixBuilder.add("mix:ScannerModel", smBuilder); + } + double xres = niso.getXPhysScanResolution(); + double yres = niso.getYPhysScanResolution(); + if (xres != NisoImageMetadata.NULL && yres != NisoImageMetadata.NULL) { + double res = (xres > yres ? xres : yres); + if (bMix10) { + mixBuilder.add("mix:maximumOpticalResolution", res); + } else { + mixBuilder.add( + "mix:MaximumOpticalResolution", + Json.createObjectBuilder() + .add("mix:xOpticalResolution", xres) + .add("mix:yOpticalResolution", yres) + .add("mix:resolutionUnit", ".in")); + } + hasBuilder = true; + } + if (addStringToJson(mixBuilder, "mix:scanningSoftwareName", niso.getScanningSoftware())) { + hasBuilder = true; + addStringToJson(mixBuilder, "mix:scanningSoftwareVersionNo", niso.getScanningSoftwareVersionNo()); + } + + // Now we'll hear from the digital cameras. + hasBuilder |= addStringToJson(mixBuilder, "mix:digitalCameraManufacturer", niso.getDigitalCameraManufacturer()); + String dcmodel = niso.getDigitalCameraModelName(); + String dcmodelNum = niso.getDigitalCameraModelNumber(); + String dcserNum = niso.getDigitalCameraModelSerialNo(); + if (dcmodel != null || dcmodelNum != null || dcserNum != null) { + hasBuilder = true; + JsonObjectBuilder smBuilder = Json.createObjectBuilder(); + addStringToJson(smBuilder, "mix:digitalCameraModelName", dcmodel); + addStringToJson(smBuilder, "mix:digitalCameraModelNumber", dcmodelNum); + addStringToJson(smBuilder, "mix:mix:digitalCameraModelSerialNo", dcserNum); + mixBuilder.add("mix:DigitalCameraModel", smBuilder); + } + + // Nest a buffer for CameraCaptureSettings + JsonObjectBuilder ccsBuilder = Json.createObjectBuilder(); + boolean useCcSetBuf = false; + useCcSetBuf |= addNisoDoubleToJson(ccsBuilder, "mix:fNumber", niso.getFNumber()); + useCcSetBuf |= addNisoDoubleToJson(ccsBuilder, "mix:exposureTime", niso.getExposureTime()); + n = niso.getExposureProgram(); + if (n != NisoImageMetadata.NULL) { + if (bMix10) { + ccsBuilder.add("mix:exposureProgram", n); + } else { + if (n > 8 || n < 0) { + n = 0; // force "Not defined" for bad value + } + ccsBuilder.add("mix:exposureProgram", + NisoImageMetadata.EXPOSURE_PROGRAM[n]); + } + useCcSetBuf = true; + } + useCcSetBuf |= addStringToJson(ccsBuilder, "mix:exifVersion", niso.getExifVersion()); + useCcSetBuf |= addRationalToJson(ccsBuilder, "mix:brightnessValue", niso.getBrightness()); + useCcSetBuf |= addRationalToJson(ccsBuilder, "mix:exposureBiasValue", niso.getExposureBias()); + useCcSetBuf |= addRationalToJson(ccsBuilder, "mix:maxApertureValue", niso.getMaxApertureValue()); + double[] darray = niso.getSubjectDistance(); + if (darray != null) { + ccsBuilder.add("mix:subjectDistance", showArray(darray)); + useCcSetBuf = true; + } + n = niso.getMeteringMode(); + if (n != NisoImageMetadata.NULL) { + if (bMix10) { + ccsBuilder.add("mix:meteringMode", n); + } else { + String s = meteringModeToString(n); + if (s.startsWith("Center weighted")) { + s = "Center weighted Average"; + } + ccsBuilder.add("mix:MeteringMode", s); + } + useCcSetBuf = true; + } + n = niso.getFlash(); + if (n != NisoImageMetadata.NULL) { + // First bit (0 = Flash did not fire, 1 = Flash fired) + int firstBit = n & 1; + ccsBuilder.add("mix:flash", NisoImageMetadata.FLASH_20[firstBit]); + useCcSetBuf = true; + } + useCcSetBuf |= addNisoDoubleToJson(ccsBuilder, "mix:focalLength", niso.getFocalLength()); + useCcSetBuf |= addRationalToJson(ccsBuilder, "mix:flashEnergy", niso.getFlashEnergy()); + useCcSetBuf |= addNisoIntToJson(ccsBuilder, "mix:backLight", niso.getBackLight()); + useCcSetBuf |= addNisoDoubleToJson(ccsBuilder, "mix:exposureIndex", niso.getExposureIndex()); + useCcSetBuf |= addNisoIntToJson(ccsBuilder, "mix:autoFocus", niso.getAutoFocus()); + useCcSetBuf |= addNisoDoubleToJson(ccsBuilder, "mix:xPrintAspectRatio", niso.getXPrintAspectRatio()); + useCcSetBuf |= addNisoDoubleToJson(ccsBuilder, "mix:yPrintAspectRatio", niso.getYPrintAspectRatio()); + if (useCcSetBuf) { + mixBuilder.add("mix:CameraCaptureSettings", ccsBuilder); + hasBuilder = true; + } + + n = niso.getOrientation(); + if (n != NisoImageMetadata.NULL) { + if (n > 9 || n < 1) { + n = 9; // force "unknown" for reserved value + } + if (bMix10) { + mixBuilder.add("mix:orientation", n); + } else { + final String[] orient = { "", "normal*", + "normal, image flipped", "normal, rotated 180\u00B0", + "normal, image flipped, rotated 180\u00B0", + "normal, image flipped, rotated cw 90\u00B0", + "normal, rotated ccw 90\u00B0", + "normal, image flipped, rotated ccw 90\u00B0", + "normal, rotated cw 90\u00B0", "unknown" }; + mixBuilder.add("mix:orientation", orient[n]); + } + hasBuilder = true; + } + hasBuilder |= addStringToJson(mixBuilder, "mix:methodology", niso.getMethodology()); + return hasBuilder ? mixBuilder : null; + } + + /* 1.0, Top level element 4 of 5: ImageAssessmentMetadata */ + protected JsonObjectBuilder showNisoImageAssessmentMetadata( + NisoImageMetadata niso, boolean bMix10) { + JsonObjectBuilder mixBuilder = Json.createObjectBuilder(); + boolean hasBuilder = false; + + JsonObjectBuilder smBuilder = Json.createObjectBuilder(); + boolean useMetricsBuf = false; + useMetricsBuf |= addNisoIntToJson(smBuilder, "mix:samplingFrequencyPlane", niso.getSamplingFrequencyPlane()); + int n = niso.getSamplingFrequencyUnit(); + if (n != NisoImageMetadata.NULL) { + if (bMix10) { + smBuilder.add("mix:samplingFrequencyUnit", n); + } else { + final String sfu[] = { null, "no absolute unit of measurement", + "in.", "cm" }; + if (n < 1 || n > 3) { + n = 1; + } + smBuilder.add("mix:samplingFrequencyUnit", sfu[n]); + } + useMetricsBuf = true; + } + useMetricsBuf |= addRationalToJson(smBuilder, "mix:xSamplingFrequency", niso.getXSamplingFrequency()); + useMetricsBuf |= addRationalToJson(smBuilder, "mix:ySamplingFrequency", niso.getYSamplingFrequency()); + if (useMetricsBuf) { + mixBuilder.add("mix:SpatialMetrics", smBuilder); + hasBuilder = true; + } + + JsonObjectBuilder imeBuilder = Json.createObjectBuilder(); + boolean useColorEncBuf = false; + + int[] iarray = niso.getBitsPerSample(); + if (iarray != null) { + imeBuilder.add("mix:bitsPerSample", showArray(iarray)); + imeBuilder.add("mix:bitsPerSampleUnit", "integer"); + // bitsPerSampleUnit can also be floating point. Don't ask me why. + useColorEncBuf = true; + } + useColorEncBuf |= addNisoIntToJson(imeBuilder, "mix:samplesPerPixel", niso.getSamplesPerPixel()); + iarray = niso.getExtraSamples(); + if (iarray != null) { + // extraSamples must be limited to + // 0, 1, 2, or 3. + n = iarray[0]; + if (n >= 0 && n <= 3) { + if (bMix10) { + imeBuilder.add(MIX_EXTRA_SAMPLES, showArray(iarray)); + } else { + String[] sarray = new String[iarray.length]; + for (int ii = 0; ii < iarray.length; ii++) { + sarray[ii] = NisoImageMetadata.EXTRA_SAMPLE_20[iarray[ii]]; + imeBuilder.add(MIX_EXTRA_SAMPLES, showArray(sarray)); + } + + } + useColorEncBuf = true; + } + } + + useColorEncBuf |= addStringToJson(imeBuilder, "mix:colormapReference", niso.getColormapReference()); + + // This is complete nonsense, but it's what the spec says + iarray = niso.getGrayResponseCurve(); + if (iarray != null) { + imeBuilder.add("mix:grayResponseCurve", showArray(iarray)); + useColorEncBuf = true; + } + + n = niso.getGrayResponseUnit(); + if (n != NisoImageMetadata.NULL) { + if (bMix10) { + imeBuilder.add(MIX_GRAY_RESPONSE_UNIT, n); + } else if (n > 0 && n <= 5) { + // Convert integer to text value; only values 1-5 are legal + imeBuilder.add(MIX_GRAY_RESPONSE_UNIT, + NisoImageMetadata.GRAY_RESPONSE_UNIT_20[n - 1]); + } + useColorEncBuf = true; + } + + Rational r = niso.getWhitePointXValue(); + Rational r2 = niso.getWhitePointYValue(); + if (r != null && r2 != null) { + imeBuilder.add( + "mix:WhitePoint", + Json.createObjectBuilder() + .add("mix:whitePointXValue", showRational(r)) + .add("mix:whitePointYValue", showRational(r2))); + useColorEncBuf = true; + } + + // A chromaticities buffer to go in the color encoding buffer. + JsonObjectBuilder pcBuilder = Json.createObjectBuilder(); + boolean useChromaBuf = false; + useChromaBuf |= addRationalToJson(pcBuilder, "mix:primaryChromaticitiesRedX", + niso.getPrimaryChromaticitiesRedX()); + useChromaBuf |= addRationalToJson(pcBuilder, "mix:primaryChromaticitiesRedY", + niso.getPrimaryChromaticitiesRedY()); + useChromaBuf |= addRationalToJson(pcBuilder, "mix:primaryChromaticitiesGreenX", + niso.getPrimaryChromaticitiesGreenX()); + useChromaBuf |= addRationalToJson(pcBuilder, "mix:primaryChromaticitiesGreenY", + niso.getPrimaryChromaticitiesGreenY()); + useChromaBuf |= addRationalToJson(pcBuilder, "mix:primaryChromaticitiesBlueX", + niso.getPrimaryChromaticitiesBlueX()); + useChromaBuf |= addRationalToJson(pcBuilder, "mix:primaryChromaticitiesBlueY", + niso.getPrimaryChromaticitiesBlueY()); + if (useChromaBuf) { + imeBuilder.add("mix:PrimaryChromaticities", pcBuilder); + useColorEncBuf = true; + } + + if (useColorEncBuf) { + mixBuilder.add("mix:ImageColorEncoding", imeBuilder); + hasBuilder = true; + } + + JsonObjectBuilder tdBuilder = Json.createObjectBuilder(); + boolean useTargetBuf = false; + useTargetBuf |= addNisoIntToJson(tdBuilder, "mix:targetType", niso.getTargetType()); + useTargetBuf |= addStringToJson(tdBuilder, "mix:targetManufacturer", niso.getTargetIDManufacturer()); + useTargetBuf |= addStringToJson(tdBuilder, "mix:targetName", niso.getTargetIDName()); + useTargetBuf |= addStringToJson(tdBuilder, "mix:targetNo", niso.getTargetIDNo()); + useTargetBuf |= addStringToJson(tdBuilder, "mix:targetMedia", niso.getTargetIDMedia()); + useTargetBuf |= addStringToJson(tdBuilder, "mix:externalTarget", niso.getImageData()); + useTargetBuf |= addStringToJson(tdBuilder, "mix:performanceData", niso.getPerformanceData()); + if (useTargetBuf) { + mixBuilder.add("mix:TargetData", tdBuilder); + hasBuilder = true; + } + return hasBuilder ? mixBuilder : null; + } + + /* 1.0, Top level element 5 of 5: ChangeHistory (without time travel) */ + protected JsonObjectBuilder showChangeHistory(NisoImageMetadata niso, + boolean bMix10) { + JsonObjectBuilder mixBuilder = Json.createObjectBuilder(); + boolean hasBuilder = false; + + hasBuilder |= addStringToJson(mixBuilder, "mix:sourceData", niso.getSourceData()); + hasBuilder |= addStringToJson(mixBuilder, "mix:processingAgency", niso.getProcessingAgency()); + + JsonObjectBuilder psBuilder = Json.createObjectBuilder(); + boolean useSftwBuf = false; + useSftwBuf |= addStringToJson(psBuilder, "mix:processingSoftwareName", niso.getProcessingSoftwareName()); + useSftwBuf |= addStringToJson(psBuilder, "mix:processingSoftwareVersion", niso.getProcessingSoftwareVersion()); + useSftwBuf |= addStringToJson(psBuilder, "mix:processingOperatingSystemName", niso.getOS()); + useSftwBuf |= addStringToJson(psBuilder, "mix:processingOperatingSystemVersion", niso.getOSVersion()); + if (useSftwBuf) { + mixBuilder.add("mix:ProcessingSoftware", psBuilder); + hasBuilder = true; + } + + String[] sarray = niso.getProcessingActions(); + if (sarray != null) { + mixBuilder.add("mix:processingActions", showArray(sarray)); + hasBuilder = true; + } + return hasBuilder ? mixBuilder : null; + } + + /** + * Convert the metering mode value to one of the suggested values for MIX + * 2.0 + */ + private String meteringModeToString(int n) { + String s = NisoImageMetadata.METERING_MODE[1]; + if (n >= 1 && n <= 6) { + s = NisoImageMetadata.METERING_MODE[n]; + } + // Capitalize first letter + return s.substring(0, 1).toUpperCase(Locale.ROOT) + s.substring(1); + } + + /** + * Convert the color space value (which is based on the TIFF + * PhotometricInterpretation convention) to one of the suggested values for + * MIX 2.0 + */ + private String photometricInterpretationToString(int n) { + switch (n) { + case 0: + return "WhiteIsZero"; + case 1: + return "BlackIsZero"; + case 2: + return "RGB"; + case 3: + return "PaletteColor"; + case 4: + return "TransparencyMask"; + case 5: + return "CMYK"; + case 6: + return "YCbCr"; + case 8: + return "CIELab"; + case 9: + return "ICCLab"; + case 10: + return "ITULab"; + case 32803: + return "CFA"; + case 34892: + return "LinearRaw"; + default: + return "Unknown"; + } + } + + /** + * Convert compression scheme value (based on the TIFF compression + * convention) to a label + */ + private String compressionSchemeToString(int n) { + for (int i = 0; i < NisoImageMetadata.COMPRESSION_SCHEME_INDEX.length; i++) { + if (n == NisoImageMetadata.COMPRESSION_SCHEME_INDEX[i]) + return NisoImageMetadata.COMPRESSION_SCHEME[i]; + } + return Integer.toString(n); + } + + /** + * Display the audio metadata formatted according to the AES schema. + * + * @param aes AES audio metadata + * @return Json + */ + protected JsonObjectBuilder showAESAudioMetadata(AESAudioMetadata aes) { + JsonObjectBuilder aesBuilder = Json.createObjectBuilder(); + + _sampleRate = aes.getSampleRate(); + + addStringToJson(aesBuilder, "aes:analogDigitalFlag", aes.getAnalogDigitalFlag()); + addStringToJson(aesBuilder, "aes:schemaVersion", aes.getSchemaVersion()); + addStringToJson(aesBuilder, "aes:format", aes.getFormat()); + addStringToJson(aesBuilder, "aes:specificationVersion", aes.getSpecificationVersion()); + addStringToJson(aesBuilder, "aes:appSpecificData", aes.getAppSpecificData()); + addStringToJson(aesBuilder, "aes:audioDataEncoding", aes.getAudioDataEncoding()); + int in = aes.getByteOrder(); + if (in != AESAudioMetadata.NULL) { + aesBuilder.add("aes:byteOrder", + (in == AESAudioMetadata.BIG_ENDIAN ? "BIG_ENDIAN" + : "LITTLE_ENDIAN")); + } + long lin = aes.getFirstSampleOffset(); + if (lin != AESAudioMetadata.NULL) { + aesBuilder.add("aes:firstSampleOffset", lin); + } + String[] use = aes.getUse(); + if (use != null) { + aesBuilder.add( + "aes:use", + Json.createObjectBuilder().add("aes:useType", use[0]) + .add("aes:otherType", use[1])); + } + if (addStringToJson(aesBuilder, "aes:primaryIdentifier", aes.getPrimaryIdentifier())) { + addStringToJson(aesBuilder, "aes:primaryIdentifierType", aes.getPrimaryIdentifierType()); + } + List facelist = aes.getFaceList(); + if (facelist != null && !facelist.isEmpty()) { + // Add the face information, which is mostly filler. + AESAudioMetadata.Face f = facelist.get(0); + JsonObjectBuilder faceBuilder = Json.createObjectBuilder(); + + AESAudioMetadata.TimeDesc startTime = f.getStartTime(); + if (startTime != null) { + faceBuilder.add("aes:timeline", + writeAESTimeRange(startTime, f.getDuration())); + } + int nchan = aes.getNumChannels(); + if (nchan != AESAudioMetadata.NULL) { + faceBuilder.add("aes:numChannels", nchan); + } + JsonArrayBuilder streamsBuilder = Json.createArrayBuilder(); + for (int ch = 0; ch < nchan; ch++) { + // write a stream description for each channel + streamsBuilder.add(Json.createObjectBuilder() + .add("aes:channelNum", ch)); + } + faceBuilder.add("aes:streams", streamsBuilder); + aesBuilder.add("aes:face", faceBuilder); + } + + showAesFormatList(aes.getFormatList(), aesBuilder); + return aesBuilder; + } + + private void showAesFormatList(List flist, + JsonObjectBuilder aesBuilder) { + if (flist == null || flist.isEmpty()) { + return; + } + // In the general case, a FormatList can contain multiple + // FormatRegions. This doesn't happen with any of the current + // modules; if it's needed in the future, simply set up an + // iteration loop on formatList. + AESAudioMetadata.FormatRegion rgn = flist.get(0); + int bitDepth = rgn.getBitDepth(); + double sampleRate = rgn.getSampleRate(); + int wordSize = rgn.getWordSize(); + String[] bitRed = rgn.getBitrateReduction(); + // Build a FormatRegion subtree if at least one piece of data + // that goes into it is present. + JsonArrayBuilder formatListBuilder = Json.createArrayBuilder(); + JsonObjectBuilder formatRegionBuilder = Json.createObjectBuilder(); + if (bitDepth != AESAudioMetadata.NULL + || sampleRate != AESAudioMetadata.NILL + || wordSize != AESAudioMetadata.NULL) { + if (bitDepth != AESAudioMetadata.NULL) { + formatRegionBuilder.add("aes:bitDepth", bitDepth); + } + if (sampleRate != AESAudioMetadata.NILL) { + formatRegionBuilder.add("aes:sampleRate", sampleRate); + } + if (wordSize != AESAudioMetadata.NULL) { + formatRegionBuilder.add("aes:wordSize", wordSize); + } + if (bitRed != null) { + formatRegionBuilder.add( + "aes:bitrateReduction", + Json.createObjectBuilder() + .add("aes:codecName", bitRed[0]) + .add("aes:codecNameVersion", bitRed[1]) + .add("aes:codecCreatorApplication", + bitRed[2]) + .add("aes:codecCreatorApplicationVersion", + bitRed[3]) + .add("aes:codecQuality", bitRed[4]) + .add("aes:dataRate", bitRed[5]) + .add("aes:dataRateMode", bitRed[6])); + } + + formatListBuilder.add(formatRegionBuilder); + aesBuilder.add("aes:formatList", formatListBuilder); + } + } + + /* + * Break out the writing of a timeRangeType element. This always gives a + * start time of 0. This is all FAKE DATA for the moment. + */ + private JsonObjectBuilder writeAESTimeRange( + AESAudioMetadata.TimeDesc start, AESAudioMetadata.TimeDesc duration) { + JsonObjectBuilder timerangeBuilder = Json.createObjectBuilder(); this.writeAESTimeRangePart(timerangeBuilder, "aes:start", start); - if (duration != null) { + if (duration != null) { this.writeAESTimeRangePart(timerangeBuilder, "aes:duration", duration); - } - return timerangeBuilder; - } + } + return timerangeBuilder; + } private void writeAESTimeRangePart(final JsonObjectBuilder timerangeBuilder, final String name, - AESAudioMetadata.TimeDesc part) { - double sr = (part.getSampleRate() == 1.0) ? _sampleRate : part.getSampleRate(); - timerangeBuilder - .add(name, - Json.createObjectBuilder() - .add("aes:value", part.getSamples()) - .add("aes:editRate", (int) sr) - .add("aes:factorNumerator", "1") - .add("aes:factorDenominator", "1")); + AESAudioMetadata.TimeDesc part) { + double sr = (part.getSampleRate() == 1.0) ? _sampleRate : part.getSampleRate(); + timerangeBuilder + .add(name, + Json.createObjectBuilder() + .add("aes:value", part.getSamples()) + .add("aes:editRate", (int) sr) + .add("aes:factorNumerator", "1") + .add("aes:factorDenominator", "1")); + } + + protected JsonArrayBuilder showArray(int[] iarray) { + JsonArrayBuilder aBuilder = Json.createArrayBuilder(); + for (int i : iarray) { + aBuilder.add(i); + } + return aBuilder; + } + + protected JsonArrayBuilder showArray(double[] darray) { + JsonArrayBuilder dBuilder = Json.createArrayBuilder(); + for (double d : darray) { + dBuilder.add(d); + } + return dBuilder; + } + + protected JsonArrayBuilder showArray(String[] sarray) { + JsonArrayBuilder sBuilder = Json.createArrayBuilder(); + for (String s : sarray) { + if (s == null) { + sBuilder.addNull(); + } else { + sBuilder.add(s); + } + } + return sBuilder; + } + + protected JsonArrayBuilder showArray(Rational[] rarray) { + JsonArrayBuilder rBuilder = Json.createArrayBuilder(); + for (Rational r : rarray) { + if (r == null) { + rBuilder.addNull(); + } else { + rBuilder.add(showRational(r)); + } + } + return rBuilder; + } + + protected JsonArrayBuilder showRational(Rational r) { + JsonArrayBuilder rationalBuilder = Json.createArrayBuilder(); + long numer = r.getNumerator(); + long denom = r.getDenominator(); + rationalBuilder.add(numer); + rationalBuilder.add(denom); + return rationalBuilder; + } + + private boolean addStringToJson(JsonObjectBuilder objBuilder, String attr, String value) { + if (value == null) { + return false; + } + objBuilder.add(attr, value); + return true; + } + + private boolean addRationalToJson(JsonObjectBuilder objBuilder, String attr, Rational r) { + if (r == null) { + return false; + } + objBuilder.add(attr, showRational(r)); + return true; + } + + private boolean addNisoIntToJson(JsonObjectBuilder objBuilder, String attr, int n) { + if (n == NisoImageMetadata.NULL) { + return false; + } + objBuilder.add(attr, n); + return true; + } + + private boolean addNisoDoubleToJson(JsonObjectBuilder objBuilder, String attr, double d) { + if (d == NisoImageMetadata.NILL) { + return false; + } + objBuilder.add(attr, d); + return true; } - protected JsonArrayBuilder showArray(int[] iarray) { - JsonArrayBuilder aBuilder = Json.createArrayBuilder(); - for (int i : iarray) { - aBuilder.add(i); - } - return aBuilder; - } - - protected JsonArrayBuilder showArray(double[] darray) { - JsonArrayBuilder dBuilder = Json.createArrayBuilder(); - for (double d : darray) { - dBuilder.add(d); - } - return dBuilder; - } - - protected JsonArrayBuilder showArray(String[] sarray) { - JsonArrayBuilder sBuilder = Json.createArrayBuilder(); - for (String s : sarray) { - if (s == null) { - sBuilder.addNull(); - } else { - sBuilder.add(s); - } - } - return sBuilder; - } - - protected JsonArrayBuilder showArray(Rational[] rarray) { - JsonArrayBuilder rBuilder = Json.createArrayBuilder(); - for (Rational r : rarray) { - if (r == null) { - rBuilder.addNull(); - } else { - rBuilder.add(showRational(r)); - } - } - return rBuilder; - } - - protected JsonArrayBuilder showRational(Rational r) { - JsonArrayBuilder rationalBuilder = Json.createArrayBuilder(); - long numer = r.getNumerator(); - long denom = r.getDenominator(); - rationalBuilder.add(numer); - rationalBuilder.add(denom); - return rationalBuilder; - } - - private boolean addStringToJson(JsonObjectBuilder objBuilder, String attr, String value) { - if (value == null) { - return false; - } - objBuilder.add(attr, value); - return true; - } - - private boolean addRationalToJson(JsonObjectBuilder objBuilder, String attr, Rational r) { - if (r == null) { - return false; - } - objBuilder.add(attr, showRational(r)); - return true; - } - - private boolean addNisoIntToJson(JsonObjectBuilder objBuilder, String attr, int n) { - if (n == NisoImageMetadata.NULL) { - return false; - } - objBuilder.add(attr, n); - return true; - } - - private boolean addNisoDoubleToJson(JsonObjectBuilder objBuilder, String attr, double d) { - if (d == NisoImageMetadata.NILL) { - return false; - } - objBuilder.add(attr, d); - return true; - } } diff --git a/jhove-core/src/main/java/edu/harvard/hul/ois/jhove/handler/TextHandler.java b/jhove-core/src/main/java/edu/harvard/hul/ois/jhove/handler/TextHandler.java index 7e5c6030e..86e410015 100644 --- a/jhove-core/src/main/java/edu/harvard/hul/ois/jhove/handler/TextHandler.java +++ b/jhove-core/src/main/java/edu/harvard/hul/ois/jhove/handler/TextHandler.java @@ -54,1940 +54,1945 @@ * OutputHandler for plain text output. */ public class TextHandler extends HandlerBase { - /****************************************************************** - * PRIVATE CLASS FIELDS. - ******************************************************************/ - - private static final String NAME = "TEXT"; - private static final String RELEASE = "1.7"; - private static final int[] DATE = { 2022, 8, 22 }; - private static final String NOTE = "This is the default JHOVE output " - + "handler"; - private static final String RIGHTS = "Derived from software Copyright 2004-2011 " - + "by the President and Fellows of Harvard College. " - + "Version 1.6 release by Open Preservation Foundation. " - + "Released under the GNU Lesser General Public License."; - - private NumberFormat _format; - - /****************************************************************** - * PRIVATE INSTANCE FIELDS. - ******************************************************************/ - - /* Sample rate. */ - private double _sampleRate; - - /****************************************************************** - * CLASS CONSTRUCTOR. - ******************************************************************/ - - /** - * Creates a TextHandler. - */ - public TextHandler() { - super(NAME, RELEASE, DATE, NOTE, RIGHTS); - _vendor = Agent.harvardInstance(); - - _format = NumberFormat.getInstance(Locale.ROOT); - _format.setGroupingUsed(false); - _format.setMinimumFractionDigits(0); - } - - /****************************************************************** - * PUBLIC INSTANCE METHODS. - ******************************************************************/ - - /** - * Outputs minimal information about the application - */ - @Override - public void show() { - _level--; - } - - /** - * Outputs detailed information about the application, including - * configuration, available modules and handlers, etc. - */ - @Override - public void show(App app) { - String margin = getIndent(++_level); - - _writer.println(margin + "App:"); - _writer.println(margin + " API: " + app.getRelease() + ", " - + HandlerBase.date.format(_je.getDate())); - String configFile = _je.getConfigFile(); - if (configFile != null) { - _writer.println(margin + " Configuration: " + configFile); - } - String s = _je.getSaxClass(); - if (s != null) { - _writer.println(margin + " SAXparser: " + s); - } - s = _je.getJhoveHome(); - if (s != null) { - _writer.println(margin + " JhoveHome: " + s); - } - s = _je.getEncoding(); - if (s != null) { - _writer.println(margin + " Encoding: " + s); - } - s = _je.getTempDirectory(); - if (s != null) { - _writer.println(margin + " TempDirectory: " + s); - } - _writer.println(margin + " BufferSize: " + _je.getBufferSize()); - Iterator iter = _je.getModuleMap().keySet().iterator(); - while (iter.hasNext()) { - Module module = _je.getModule(iter.next()); - _writer.println(margin + " Module: " + module.getName() + " " - + module.getRelease()); - } - iter = _je.getHandlerMap().keySet().iterator(); - while (iter.hasNext()) { - OutputHandler handler = _je.getHandler(iter.next()); - _writer.println(margin + " OutputHandler: " + handler.getName() - + " " + handler.getRelease()); - } - - _writer.println(margin + " Usage: " + app.getUsage()); - _writer.println(margin + " Rights: " + app.getRights()); - - _level--; - } - - /** - * Outputs information about the OutputHandler specified in the parameter - */ - @Override - public void show(OutputHandler handler) { - String margin = getIndent(++_level); - - _writer.println(margin + "Handler: " + handler.getName()); - _writer.println(margin + " Release: " + handler.getRelease()); - _writer.println(margin + " Date: " - + HandlerBase.date.format(handler.getDate())); - List list = handler.getSpecification(); - int n = list.size(); - for (int i = 0; i < n; i++) { - showDocument(list.get(i), "Specification"); - } - Agent vendor = handler.getVendor(); - if (vendor != null) { - showAgent(vendor, "Vendor"); - } - String s; - if ((s = handler.getNote()) != null) { - _writer.println(margin + " Note: " + s); - } - if ((s = handler.getRights()) != null) { - _writer.println(margin + " Rights: " + s); - } - } - - /** - * Outputs information about a Module - */ - @Override - public void show(Module module) { - String margin = getIndent(++_level); - - _writer.println(margin + "Module: " + module.getName()); - _writer.println(margin + " Release: " + module.getRelease()); - _writer.println(margin + " Date: " - + HandlerBase.date.format(module.getDate())); - String[] ss = module.getFormat(); - if (ss.length > 0) { - _writer.print(margin + " Format: " + ss[0]); - for (int i = 1; i < ss.length; i++) { - _writer.print(", " + ss[i]); - } - _writer.println(); - } - String s = module.getCoverage(); - if (s != null) { - _writer.println(margin + " Coverage: " + s); - } - ss = module.getMimeType(); - if (ss.length > 0) { - _writer.print(margin + " MIMEtype: " + ss[0]); - for (int i = 1; i < ss.length; i++) { - _writer.print(", " + ss[i]); - } - ; - _writer.println(); - } - for (Signature sig : module.getSignature()) { - showSignature(sig); - } - for (Document spec : module.getSpecification()) { - showDocument(spec, "Specification"); - } - for (String feature : module.getFeatures()) { - _writer.println(margin + " Feature: " + feature); - } - - _writer.println(margin + " Methodology:"); - if ((s = module.getWellFormedNote()) != null) { - _writer.println(margin + " Well-formed: " + s); - } - if ((s = module.getValidityNote()) != null) { - _writer.println(margin + " Validity: " + s); - } - if ((s = module.getRepInfoNote()) != null) { - _writer.println(margin + " RepresentationInformation: " + s); - } - Agent vendor = module.getVendor(); - if (vendor != null) { - showAgent(vendor, "Vendor"); - } - if ((s = module.getNote()) != null) { - _writer.println(margin + " Note: " + s); - } - if ((s = module.getRights()) != null) { - _writer.println(margin + " Rights: " + s); - } - - _level--; - } - - /** - * Outputs the information contained in a RepInfo object - */ - @Override - public void show(RepInfo info) { - String margin = getIndent(++_level); - - Module module = info.getModule(); - _writer.println(margin + "RepresentationInformation: " + info.getUri()); - if (module != null) { - _writer.println(margin + " ReportingModule: " + module.getName() - + ", Rel. " + module.getRelease() + " (" - + date.format(module.getDate()) + ")"); - } - - Date date = info.getCreated(); - if (date != null) { - _writer.println(margin + " Created: " + dateTime.format(date)); - } - date = info.getLastModified(); - if (date != null) { - _writer.println(margin + " LastModified: " + dateTime.format(date)); - } - long size = info.getSize(); - if (size > -1) { - _writer.println(margin + " Size: " + size); - } - String s = info.getFormat(); - if (s != null) { - _writer.println(margin + " Format: " + s); - } - s = info.getVersion(); - if (s != null) { - _writer.println(margin + " Version: " + s); - } - if (!_je.getSignatureFlag()) { - _writer.print(margin + " Status: "); - switch (info.getWellFormed()) { - case RepInfo.TRUE: - s = "Well-Formed"; - break; - - case RepInfo.FALSE: - s = "Not well-formed"; - break; - - default: - s = "Unknown"; - break; - } - if (info.getWellFormed() == RepInfo.TRUE) { - switch (info.getValid()) { - - case RepInfo.TRUE: - s += " and valid"; - break; - - case RepInfo.FALSE: - s += ", but not valid"; - break; - - // case UNDETERMINED: add nothing - } - } - _writer.println(s); - } else { - // If we aren't checking signatures, we still need to say something. - _writer.print(margin + " Status: "); - switch (info.getWellFormed()) { - case RepInfo.TRUE: - s = "Well-Formed"; - break; - - default: - s = "Not well-formed"; - break; - } - _writer.println(s); - } - List list1 = info.getSigMatch(); - int n = list1.size(); - if (n > 0) { - _writer.println(margin + " SignatureMatches:"); - for (int i = 0; i < n; i++) { - _writer.println(margin + " " + list1.get(i)); - } - } - - List list2 = info.getMessage(); - n = list2.size(); - for (int i = 0; i < n; i++) { - showMessage(list2.get(i)); - } - s = info.getMimeType(); - if (s != null) { - _writer.println(margin + " MIMEtype: " + s); - } - - List list3 = info.getProfile(); - n = list3.size(); - if (n > 0) { - _writer.print(margin + " Profile: " + list3.get(0)); - for (int i = 1; i < n; i++) { - _writer.print(", " + list3.get(i)); - } - _writer.println(); - } - - Map map = info.getProperty(); - if (map != null) { - Iterator iter = map.keySet().iterator(); - while (iter.hasNext()) { - String key = iter.next(); - showProperty(info.getProperty(key), key, margin); - } - } - - List list4 = info.getChecksum(); - n = list4.size(); - for (int i = 0; i < n; i++) { - showChecksum((Checksum) list4.get(i)); - } - - _level--; - } - - /****************************************************************** - * PRIVATE INSTANCE METHODS. - ******************************************************************/ - - private void showAgent(Agent agent, String label) { - String margin = getIndent(++_level); - - _writer.println(margin + label + ": " + agent.getName()); - _writer.println(margin + " Type: " + agent.getType().toString()); - String s = agent.getAddress(); - if (s != null) { - _writer.println(margin + " Address: " + s); - } - if ((s = agent.getTelephone()) != null) { - _writer.println(margin + " Telephone: " + s); - } - if ((s = agent.getFax()) != null) { - _writer.println(margin + " Fax: " + s); - } - if ((s = agent.getEmail()) != null) { - _writer.println(margin + " Email: " + s); - } - if ((s = agent.getWeb()) != null) { - _writer.println(margin + " Web: " + s); - } - _level--; - } - - private void showChecksum(Checksum checksum) { - String margin = getIndent(++_level); - - _writer.println(margin + "Checksum: " + checksum.getValue()); - _writer.println(margin + " Type: " + checksum.getType().toString()); - - _level--; - } - - private void showDocument(Document document, String label) { - String margin = getIndent(++_level); - - _writer.println(margin + label + ": " + document.getTitle()); - _writer.println(margin + " Type: " + document.getType()); - List list1 = document.getAuthor(); - int n = list1.size(); - for (int i = 0; i < n; i++) { - showAgent(list1.get(i), "Author"); - } - List list2 = document.getPublisher(); - n = list2.size(); - for (int i = 0; i < n; i++) { - showAgent(list2.get(i), "Publisher"); - } - String s = document.getEdition(); - if (s != null) { - _writer.println(margin + " Edition: " + s); - } - if ((s = document.getDate()) != null) { - _writer.println(margin + " Date: " + s); - } - if ((s = document.getEnumeration()) != null) { - _writer.println(margin + " Enumeration: " + s); - } - if ((s = document.getPages()) != null) { - _writer.println(margin + " Pages: " + s); - } - List list3 = document.getIdentifier(); - n = list3.size(); - for (int i = 0; i < n; i++) { - showIdentifier(list3.get(i)); - } - if ((s = document.getNote()) != null) { - _writer.println(margin + " Note: " + s); - } - _level--; - } - - /** - * Do the final output. This should be in a suitable format for including - * multiple files between the header and the footer. - */ - @Override - public void showFooter() { - _level--; - - _writer.flush(); - } - - /** - * Do the initial output. This should be in a suitable format for including - * multiple files between the header and the footer. - */ - @Override - public void showHeader() { - String margin = getIndent(++_level); - - _writer.println(margin + _app.getName() + " (Rel. " + _app.getRelease() - + ", " + HandlerBase.date.format(_app.getDate()) + ")"); - _writer.println(margin + " Date: " - + HandlerBase.dateTime.format(new Date())); - } - - private void showIdentifier(Identifier identifier) { - String margin = getIndent(++_level); - - _writer.println(margin + "Identifier: " + identifier.getValue()); - _writer.println(margin + " Type: " + identifier.getType().toString()); - String note = identifier.getNote(); - if (note != null) { - _writer.println(margin + " Note: " + note); - } - _level--; - } - - private void showMessage(Message message) { - String margin = getIndent(++_level); - String prefix = message.getPrefix() + "Message: "; - String str = message.getMessage(); - // Append submessage, if any, after a colon. - String submsg = message.getSubMessage(); - if (submsg != null) { - str += ": " + submsg; - } - _writer.println(margin + prefix + str); - String id = message.getId(); - if (!(id == null || id.isEmpty() || id.equals(JhoveMessages.NO_ID))) { - _writer.println(margin + " ID: " + id); - } - long offset = message.getOffset(); - if (offset > -1) { - _writer.println(margin + " Offset: " + offset); - } - _level--; - } - - private void showSignature(Signature signature) { - String margin = getIndent(++_level); - - String sigValue; - if (signature.isStringValue()) { - sigValue = signature.getValueString(); - } else { - sigValue = signature.getValueHexString(); - } - _writer.println(margin + signature.getType().toString() + ": " - + sigValue); - if ((signature.getType().equals(SignatureType.MAGIC)) - && (((InternalSignature) signature).hasFixedOffset())) { - _writer.println(margin + " Offset: " - + ((InternalSignature) signature).getOffset()); - } - String note = signature.getNote(); - if (note != null) { - _writer.println(margin + " Note: " + note); - } - String use = signature.getUse().toString(); - if (use != null) { - _writer.println(margin + " Use: " + use); - } - _level--; - } - - /* showProperty may be called recursively. */ - private void showProperty(Property property, String key, String margin) { - PropertyArity arity = property.getArity(); - - if (key == null) { - _writer.print(margin + " "); - } else { - _writer.print(margin + " " + key + ": "); - } - if (arity.equals(PropertyArity.SCALAR)) { - showScalarProperty(property, margin); - } else if (arity.equals(PropertyArity.LIST)) { - showListProperty(property, margin); - } else if (arity.equals(PropertyArity.MAP)) { - showMapProperty(property, margin); - } else if (arity.equals(PropertyArity.SET)) { - showSetProperty(property, margin); - } else if (arity.equals(PropertyArity.ARRAY)) { - showArrayProperty(property, margin); - } else { - _writer.println(); - } - } - - private void showScalarProperty(Property property, String margin) { - PropertyType type = property.getType(); - if (PropertyType.PROPERTY.equals(type)) { - _writer.println(); - Property prop = (Property) property.getValue(); - showProperty(prop, prop.getName(), margin + " "); - // _writer.println (); // Does this improve things? - } else if (PropertyType.NISOIMAGEMETADATA.equals(type)) { - showNisoImageMetadata((NisoImageMetadata) property.getValue(), - margin + " ", _je.getShowRawFlag()); - } else if (PropertyType.AESAUDIOMETADATA.equals(type)) { - showAESAudioMetadata((AESAudioMetadata) property.getValue(), margin - + " ", _je.getShowRawFlag()); - } else if (PropertyType.TEXTMDMETADATA.equals(type)) { - showTextMDMetadata((TextMDMetadata) property.getValue(), margin - + " ", _je.getShowRawFlag()); - } else { - _writer.println(property.getValue().toString()); - } - } - - private void showListProperty(Property property, String margin) { - PropertyType type = property.getType(); - boolean valueIsProperty = PropertyType.PROPERTY.equals(type); - boolean valueIsNiso = PropertyType.NISOIMAGEMETADATA.equals(type); - boolean valueIsTextMD = PropertyType.TEXTMDMETADATA.equals(type); - - List list = (List) property.getValue(); - - int n = list.size(); - int i; - if (n > 0) { - // Put a blank line after the name of the property list. - if (valueIsProperty) { - _writer.println(); - } - for (i = 0; i < n; i++) { - if (valueIsProperty) { - Property pval = (Property) list.get(i); - showProperty(pval, pval.getName(), margin + " "); - } else if (valueIsNiso) { - showNisoImageMetadata((NisoImageMetadata) list.get(i), - margin + " ", _je.getShowRawFlag()); - } else if (valueIsTextMD) { - showTextMDMetadata((TextMDMetadata) list.get(i), margin - + " ", _je.getShowRawFlag()); - } else { - Object val = list.get(i); - if (i == 0) { - _writer.print(val); - } else { - _writer.print(", " + val); - } - } - } - } - if (!valueIsProperty || n == 0) { - _writer.println(); - } - } - - private void showMapProperty(Property property, String margin) { - /* - * Map output looks like key : mapkey1 / mapval1, mapkey2 / mapval2, ... - */ - PropertyType type = property.getType(); - boolean valueIsProperty = PropertyType.PROPERTY.equals(type); - boolean valueIsNiso = PropertyType.NISOIMAGEMETADATA.equals(type); - boolean valueIsTextMD = PropertyType.TEXTMDMETADATA.equals(type); - - Map propmap = (Map) property.getValue(); - Set keys = propmap.keySet(); - Iterator propiter = keys.iterator(); - while (propiter.hasNext()) { - Object propkey = propiter.next(); - Object val = propmap.get(propkey); - if (valueIsProperty) { - Property pval = (Property) val; - showProperty(pval, pval.getName(), margin + " "); - String propkeyStr = propkey.toString(); - if (!(pval.getName().equals(propkeyStr))) { - _writer.println(" Key: " + propkeyStr); - } - } else if (valueIsNiso) { - showNisoImageMetadata((NisoImageMetadata) val, margin + " ", - _je.getShowRawFlag()); - } else if (valueIsTextMD) { - showTextMDMetadata((TextMDMetadata) val, margin + " ", - _je.getShowRawFlag()); - } else { - _writer.println(" " + val.toString()); - _writer.println(" Key: " + propkey.toString()); - } - } - } - - private void showSetProperty(Property property, String margin) { - PropertyType type = property.getType(); - boolean valueIsProperty = PropertyType.PROPERTY.equals(type); - boolean valueIsNiso = PropertyType.NISOIMAGEMETADATA.equals(type); - boolean valueIsTextMD = PropertyType.TEXTMDMETADATA.equals(type); - - Set propset = (Set) property.getValue(); - Iterator propiter = propset.iterator(); - boolean first = true; - while (propiter.hasNext()) { - Object val = propiter.next(); - if (valueIsProperty) { - Property pval = (Property) val; - showProperty(pval, pval.getName(), margin + " "); - } else if (valueIsNiso) { - showNisoImageMetadata((NisoImageMetadata) val, margin + " ", - _je.getShowRawFlag()); - } else if (valueIsTextMD) { - showTextMDMetadata((TextMDMetadata) val, margin + " ", - _je.getShowRawFlag()); - } else { - if (first) { - _writer.print(val.toString()); - first = false; - } else { - _writer.print(", " + val.toString()); - } - } - } - _writer.println(); - } - - private void showArrayProperty(Property property, String margin) { - boolean[] boolArray = null; - byte[] byteArray = null; - char[] charArray = null; - java.util.Date[] dateArray = null; - double[] doubleArray = null; - float[] floatArray = null; - int[] intArray = null; - long[] longArray = null; - Object[] objArray = null; - Property[] propArray = null; - short[] shortArray = null; - String[] stringArray = null; - Rational[] rationalArray = null; - NisoImageMetadata[] nisoArray = null; - TextMDMetadata[] textMDArray = null; - int n = 0; - - PropertyType propType = property.getType(); - if (PropertyType.BOOLEAN.equals(propType)) { - boolArray = (boolean[]) property.getValue(); - n = boolArray.length; - } else if (PropertyType.BYTE.equals(propType)) { - byteArray = (byte[]) property.getValue(); - n = byteArray.length; - } else if (PropertyType.CHARACTER.equals(propType)) { - charArray = (char[]) property.getValue(); - n = charArray.length; - } else if (PropertyType.DATE.equals(propType)) { - dateArray = (java.util.Date[]) property.getValue(); - n = dateArray.length; - } else if (PropertyType.DOUBLE.equals(propType)) { - doubleArray = (double[]) property.getValue(); - n = doubleArray.length; - } else if (PropertyType.FLOAT.equals(propType)) { - floatArray = (float[]) property.getValue(); - n = floatArray.length; - } else if (PropertyType.INTEGER.equals(propType)) { - intArray = (int[]) property.getValue(); - n = intArray.length; - } else if (PropertyType.LONG.equals(propType)) { - longArray = (long[]) property.getValue(); - n = longArray.length; - } else if (PropertyType.OBJECT.equals(propType)) { - objArray = (Object[]) property.getValue(); - n = objArray.length; - } else if (PropertyType.SHORT.equals(propType)) { - shortArray = (short[]) property.getValue(); - n = shortArray.length; - } else if (PropertyType.STRING.equals(propType)) { - stringArray = (String[]) property.getValue(); - n = stringArray.length; - } else if (PropertyType.RATIONAL.equals(propType)) { - rationalArray = (Rational[]) property.getValue(); - n = rationalArray.length; - } else if (PropertyType.PROPERTY.equals(propType)) { - propArray = (Property[]) property.getValue(); - n = propArray.length; - } else if (PropertyType.NISOIMAGEMETADATA.equals(propType)) { - nisoArray = (NisoImageMetadata[]) property.getValue(); - n = nisoArray.length; - } else if (PropertyType.TEXTMDMETADATA.equals(propType)) { - textMDArray = (TextMDMetadata[]) property.getValue(); - n = textMDArray.length; - } - - for (int i = 0; i < n; i++) { - String elem; - if (PropertyType.BOOLEAN.equals(propType)) { - elem = String.valueOf(boolArray[i]); - } else if (PropertyType.BYTE.equals(propType)) { - elem = String.valueOf(byteArray[i]); - } else if (PropertyType.CHARACTER.equals(propType)) { - elem = String.valueOf(charArray[i]); - } else if (PropertyType.DATE.equals(propType)) { - elem = dateArray[i].toString(); - } else if (PropertyType.DOUBLE.equals(propType)) { - elem = String.valueOf(doubleArray[i]); - } else if (PropertyType.FLOAT.equals(propType)) { - elem = String.valueOf(floatArray[i]); - } else if (PropertyType.INTEGER.equals(propType)) { - elem = String.valueOf(intArray[i]); - } else if (PropertyType.LONG.equals(propType)) { - elem = String.valueOf(longArray[i]); - } else if (PropertyType.OBJECT.equals(propType)) { - elem = objArray[i].toString(); - } else if (PropertyType.SHORT.equals(propType)) { - elem = String.valueOf(shortArray[i]); - } else if (PropertyType.STRING.equals(propType)) { - elem = stringArray[i]; - } else if (PropertyType.RATIONAL.equals(propType)) { - elem = rationalArray[i].toString(); - } else if (PropertyType.NISOIMAGEMETADATA.equals(propType)) { - if (i == 0) { - _writer.println(); - } - NisoImageMetadata niso = nisoArray[i]; - showNisoImageMetadata(niso, margin + " ", _je.getShowRawFlag()); - continue; - } else if (PropertyType.TEXTMDMETADATA.equals(propType)) { - if (i == 0) { - _writer.println(); - } - showTextMDMetadata(textMDArray[i], margin + " ", - _je.getShowRawFlag()); - continue; - } else if (PropertyType.PROPERTY.equals(propType)) { - if (i == 0) { - _writer.println(); - } - Property pval = propArray[i]; - showProperty(pval, pval.getName(), margin + " "); - continue; - } else - elem = ""; - if (i == 0) { - _writer.print(elem); - } else { - _writer.print(", " + elem); - } - } - if (propType != PropertyType.PROPERTY - && propType != PropertyType.NISOIMAGEMETADATA) { - _writer.println(); - } - } - - /* - * Output the textMD metadata, which is its own special kind of property. - */ - private void showTextMDMetadata(TextMDMetadata textMD, String margin, - boolean rawOutput) { - String margn2 = margin + " "; - String margn3 = margn2 + " "; - - _writer.println(); - _writer.println(margn2 + "Character_info:"); - String s = textMD.getCharset(); - if (s != null) { - _writer.println(margn3 + "Charset: " + s); - } - if ((s = textMD.getByte_orderString()) != null) { - _writer.println(margn3 + "Byte_order: " + s); - } - if ((s = textMD.getByte_size()) != null) { - _writer.println(margn3 + "Byte_size: " + s); - } - if ((s = textMD.getCharacter_size()) != null) { - _writer.println(margn3 + "Character_size: " + s); - } - if ((s = textMD.getLinebreakString()) != null) { - _writer.println(margn3 + "Linebreak: " + s); - } - - if ((s = textMD.getLanguage()) != null) { - _writer.println(margn2 + "Language: " + s); - } - if ((s = textMD.getMarkup_basis()) != null) { - _writer.println(margn2 + "Markup_basis: " + s); - } - if ((s = textMD.getMarkup_basis_version()) != null) { - _writer.println(margn2 + "Markup_basis_version: " + s); - } - if ((s = textMD.getMarkup_language()) != null) { - _writer.println(margn2 + "Markup_language: " + s); - } - if ((s = textMD.getMarkup_language_version()) != null) { - _writer.println(margn2 + "Markup_language_version: " + s); - } - } - - /* - * Output the AES audio metadata, which is its own special kind of property. - */ - private void showAESAudioMetadata(AESAudioMetadata aes, String margin, - boolean rawOutput) { - String margn2 = margin + " "; - String margn3 = margn2 + " "; - String margn4 = margn3 + " "; - String margn5 = margn4 + " "; - - _sampleRate = aes.getSampleRate(); - - _writer.println(); - String s = aes.getAnalogDigitalFlag(); - if (s != null) { - _writer.println(margn2 + "AnalogDigitalFlag: " + s); - } - s = aes.getSchemaVersion(); - if (s != null) { - _writer.println(margn2 + "SchemaVersion: " + s); - } - s = aes.getFormat(); - if (s != null) { - _writer.println(margn2 + "Format: " + s); - } - s = aes.getSpecificationVersion(); - if (s != null) { - _writer.println(margn2 + "SpecificationVersion: " + s); - } - s = aes.getAppSpecificData(); - if (s != null) { - _writer.println(margn2 + "AppSpecificData: " + s); - } - s = aes.getAudioDataEncoding(); - if (s != null) { - _writer.println(margn2 + "AudioDataEncoding: " + s); - } - int in = aes.getByteOrder(); - if (in != AESAudioMetadata.NULL) { - _writer.println(margn2 - + "ByteOrder: " - + (in == AESAudioMetadata.BIG_ENDIAN ? "BIG_ENDIAN" - : "LITTLE_ENDIAN")); - } - long lin = aes.getFirstSampleOffset(); - if (lin != AESAudioMetadata.NULL) { - _writer.println(margn2 + "FirstSampleOffset: " + Long.toString(lin)); - } - String[] use = aes.getUse(); - if (use != null) { - _writer.println(margn2 + "Use:"); - _writer.println(margn3 + "UseType: " + use[0]); - _writer.println(margn3 + "OtherType: " + use[1]); - } - s = aes.getPrimaryIdentifier(); - if (s != null) { - String t = aes.getPrimaryIdentifierType(); - _writer.println(margn2 + "PrimaryIdentifier: " + s); - if (t != null) { - _writer.println(margn3 + "IdentifierType: " + t); - } - } - List facelist = aes.getFaceList(); - if (!facelist.isEmpty()) { - // Add the face information, which is mostly filler. - AESAudioMetadata.Face f = (AESAudioMetadata.Face) facelist.get(0); - _writer.println(margn2 + "Face: "); - _writer.println(margn3 + "TimeLine: "); - AESAudioMetadata.TimeDesc startTime = f.getStartTime(); - if (startTime != null) { - writeAESTimeRange(margn3, startTime, f.getDuration()); - } + /****************************************************************** + * PRIVATE CLASS FIELDS. + ******************************************************************/ + + private static final String NAME = "TEXT"; + private static final String RELEASE = "1.8"; + private static final int[] DATE = { 2024, 11, 19 }; + private static final String NOTE = "This is the default JHOVE output " + + "handler"; + private static final String RIGHTS = "Derived from software Copyright 2004-2011 " + + "by the President and Fellows of Harvard College. " + + "Version 1.6 release by Open Preservation Foundation. " + + "Released under the GNU Lesser General Public License."; + + private NumberFormat _format; + + /****************************************************************** + * PRIVATE INSTANCE FIELDS. + ******************************************************************/ + + /* Sample rate. */ + private double _sampleRate; + /** Reporting module */ + private String reportingModule = ""; + + /****************************************************************** + * CLASS CONSTRUCTOR. + ******************************************************************/ + + /** + * Creates a TextHandler. + */ + public TextHandler() { + super(NAME, RELEASE, DATE, NOTE, RIGHTS); + _vendor = Agent.harvardInstance(); + + _format = NumberFormat.getInstance(Locale.ROOT); + _format.setGroupingUsed(false); + _format.setMinimumFractionDigits(0); + } + + /****************************************************************** + * PUBLIC INSTANCE METHODS. + ******************************************************************/ + + /** + * Outputs minimal information about the application + */ + @Override + public void show() { + _level--; + } + + /** + * Outputs detailed information about the application, including + * configuration, available modules and handlers, etc. + */ + @Override + public void show(App app) { + String margin = getIndent(++_level); + + _writer.println(margin + "App:"); + _writer.println(margin + " API: " + app.getRelease() + ", " + + HandlerBase.date.format(_je.getDate())); + String configFile = _je.getConfigFile(); + if (configFile != null) { + _writer.println(margin + " Configuration: " + configFile); + } + String s = _je.getSaxClass(); + if (s != null) { + _writer.println(margin + " SAXparser: " + s); + } + s = _je.getJhoveHome(); + if (s != null) { + _writer.println(margin + " JhoveHome: " + s); + } + s = _je.getEncoding(); + if (s != null) { + _writer.println(margin + " Encoding: " + s); + } + s = _je.getTempDirectory(); + if (s != null) { + _writer.println(margin + " TempDirectory: " + s); + } + _writer.println(margin + " BufferSize: " + _je.getBufferSize()); + Iterator iter = _je.getModuleMap().keySet().iterator(); + while (iter.hasNext()) { + Module module = _je.getModule(iter.next()); + _writer.println(margin + " Module: " + module.getName() + " " + + module.getRelease()); + } + iter = _je.getHandlerMap().keySet().iterator(); + while (iter.hasNext()) { + OutputHandler handler = _je.getHandler(iter.next()); + _writer.println(margin + " OutputHandler: " + handler.getName() + + " " + handler.getRelease()); + } + + _writer.println(margin + " Usage: " + app.getUsage()); + _writer.println(margin + " Rights: " + app.getRights()); + + _level--; + } + + /** + * Outputs information about the OutputHandler specified in the parameter + */ + @Override + public void show(OutputHandler handler) { + String margin = getIndent(++_level); + + _writer.println(margin + "Handler: " + handler.getName()); + _writer.println(margin + " Release: " + handler.getRelease()); + _writer.println(margin + " Date: " + + HandlerBase.date.format(handler.getDate())); + List list = handler.getSpecification(); + int n = list.size(); + for (int i = 0; i < n; i++) { + showDocument(list.get(i), "Specification"); + } + Agent vendor = handler.getVendor(); + if (vendor != null) { + showAgent(vendor, "Vendor"); + } + String s; + if ((s = handler.getNote()) != null) { + _writer.println(margin + " Note: " + s); + } + if ((s = handler.getRights()) != null) { + _writer.println(margin + " Rights: " + s); + } + } + + /** + * Outputs information about a Module + */ + @Override + public void show(Module module) { + String margin = getIndent(++_level); + + _writer.println(margin + "Module: " + module.getName()); + _writer.println(margin + " Release: " + module.getRelease()); + _writer.println(margin + " Date: " + + HandlerBase.date.format(module.getDate())); + String[] ss = module.getFormat(); + if (ss.length > 0) { + _writer.print(margin + " Format: " + ss[0]); + for (int i = 1; i < ss.length; i++) { + _writer.print(", " + ss[i]); + } + _writer.println(); + } + String s = module.getCoverage(); + if (s != null) { + _writer.println(margin + " Coverage: " + s); + } + ss = module.getMimeType(); + if (ss.length > 0) { + _writer.print(margin + " MIMEtype: " + ss[0]); + for (int i = 1; i < ss.length; i++) { + _writer.print(", " + ss[i]); + } + ; + _writer.println(); + } + for (Signature sig : module.getSignature()) { + showSignature(sig); + } + for (Document spec : module.getSpecification()) { + showDocument(spec, "Specification"); + } + for (String feature : module.getFeatures()) { + _writer.println(margin + " Feature: " + feature); + } + + _writer.println(margin + " Methodology:"); + if ((s = module.getWellFormedNote()) != null) { + _writer.println(margin + " Well-formed: " + s); + } + if ((s = module.getValidityNote()) != null) { + _writer.println(margin + " Validity: " + s); + } + if ((s = module.getRepInfoNote()) != null) { + _writer.println(margin + " RepresentationInformation: " + s); + } + Agent vendor = module.getVendor(); + if (vendor != null) { + showAgent(vendor, "Vendor"); + } + if ((s = module.getNote()) != null) { + _writer.println(margin + " Note: " + s); + } + if ((s = module.getRights()) != null) { + _writer.println(margin + " Rights: " + s); + } + + _level--; + } + + /** + * Outputs the information contained in a RepInfo object + */ + @Override + public void show(RepInfo info) { + String margin = getIndent(++_level); + + Module module = info.getModule(); + _writer.println(margin + "RepresentationInformation: " + info.getUri()); + if (module != null) { + this.reportingModule = module.getName(); + _writer.println(margin + " ReportingModule: " + this.reportingModule + + ", Rel. " + module.getRelease() + " (" + + date.format(module.getDate()) + ")"); + } + + Date date = info.getCreated(); + if (date != null) { + _writer.println(margin + " Created: " + dateTime.format(date)); + } + date = info.getLastModified(); + if (date != null) { + _writer.println(margin + " LastModified: " + dateTime.format(date)); + } + long size = info.getSize(); + if (size > -1) { + _writer.println(margin + " Size: " + size); + } + String s = info.getFormat(); + if (s != null) { + _writer.println(margin + " Format: " + s); + } + s = info.getVersion(); + if (s != null) { + _writer.println(margin + " Version: " + s); + } + if (!_je.getSignatureFlag()) { + _writer.print(margin + " Status: "); + switch (info.getWellFormed()) { + case RepInfo.TRUE: + s = "Well-Formed"; + break; + + case RepInfo.FALSE: + s = "Not well-formed"; + break; + + default: + s = "Unknown"; + break; + } + if (info.getWellFormed() == RepInfo.TRUE) { + switch (info.getValid()) { + + case RepInfo.TRUE: + s += " and valid"; + break; + + case RepInfo.FALSE: + s += ", but not valid"; + break; + + // case UNDETERMINED: add nothing + } + } + _writer.println(s); + } else { + // If we aren't checking signatures, we still need to say something. + _writer.print(margin + " Status: "); + switch (info.getWellFormed()) { + case RepInfo.TRUE: + s = "Well-Formed"; + break; + + default: + s = "Not well-formed"; + break; + } + _writer.println(s); + } + List list1 = info.getSigMatch(); + int n = list1.size(); + if (n > 0) { + _writer.println(margin + " SignatureMatches:"); + for (int i = 0; i < n; i++) { + _writer.println(margin + " " + list1.get(i)); + } + } + + List list2 = info.getMessage(); + n = list2.size(); + for (int i = 0; i < n; i++) { + showMessage(list2.get(i)); + } + s = info.getMimeType(); + if (s != null) { + _writer.println(margin + " MIMEtype: " + s); + } + + List list3 = info.getProfile(); + n = list3.size(); + if (n > 0) { + _writer.print(margin + " Profile: " + list3.get(0)); + for (int i = 1; i < n; i++) { + _writer.print(", " + list3.get(i)); + } + _writer.println(); + } + + Map map = info.getProperty(); + if (map != null) { + Iterator iter = map.keySet().iterator(); + while (iter.hasNext()) { + String key = iter.next(); + showProperty(info.getProperty(key), key, margin); + } + } + + List list4 = info.getChecksum(); + n = list4.size(); + for (int i = 0; i < n; i++) { + showChecksum((Checksum) list4.get(i)); + } + + _level--; + } + + /****************************************************************** + * PRIVATE INSTANCE METHODS. + ******************************************************************/ + + private void showAgent(Agent agent, String label) { + String margin = getIndent(++_level); + + _writer.println(margin + label + ": " + agent.getName()); + _writer.println(margin + " Type: " + agent.getType().toString()); + String s = agent.getAddress(); + if (s != null) { + _writer.println(margin + " Address: " + s); + } + if ((s = agent.getTelephone()) != null) { + _writer.println(margin + " Telephone: " + s); + } + if ((s = agent.getFax()) != null) { + _writer.println(margin + " Fax: " + s); + } + if ((s = agent.getEmail()) != null) { + _writer.println(margin + " Email: " + s); + } + if ((s = agent.getWeb()) != null) { + _writer.println(margin + " Web: " + s); + } + _level--; + } + + private void showChecksum(Checksum checksum) { + String margin = getIndent(++_level); + + _writer.println(margin + "Checksum: " + checksum.getValue()); + _writer.println(margin + " Type: " + checksum.getType().toString()); + + _level--; + } + + private void showDocument(Document document, String label) { + String margin = getIndent(++_level); + + _writer.println(margin + label + ": " + document.getTitle()); + _writer.println(margin + " Type: " + document.getType()); + List list1 = document.getAuthor(); + int n = list1.size(); + for (int i = 0; i < n; i++) { + showAgent(list1.get(i), "Author"); + } + List list2 = document.getPublisher(); + n = list2.size(); + for (int i = 0; i < n; i++) { + showAgent(list2.get(i), "Publisher"); + } + String s = document.getEdition(); + if (s != null) { + _writer.println(margin + " Edition: " + s); + } + if ((s = document.getDate()) != null) { + _writer.println(margin + " Date: " + s); + } + if ((s = document.getEnumeration()) != null) { + _writer.println(margin + " Enumeration: " + s); + } + if ((s = document.getPages()) != null) { + _writer.println(margin + " Pages: " + s); + } + List list3 = document.getIdentifier(); + n = list3.size(); + for (int i = 0; i < n; i++) { + showIdentifier(list3.get(i)); + } + if ((s = document.getNote()) != null) { + _writer.println(margin + " Note: " + s); + } + _level--; + } + + /** + * Do the final output. This should be in a suitable format for including + * multiple files between the header and the footer. + */ + @Override + public void showFooter() { + _level--; + + _writer.flush(); + } + + /** + * Do the initial output. This should be in a suitable format for including + * multiple files between the header and the footer. + */ + @Override + public void showHeader() { + String margin = getIndent(++_level); + + _writer.println(margin + _app.getName() + " (Rel. " + _app.getRelease() + + ", " + HandlerBase.date.format(_app.getDate()) + ")"); + _writer.println(margin + " Date: " + + HandlerBase.dateTime.format(new Date())); + } + + private void showIdentifier(Identifier identifier) { + String margin = getIndent(++_level); + + _writer.println(margin + "Identifier: " + identifier.getValue()); + _writer.println(margin + " Type: " + identifier.getType().toString()); + String note = identifier.getNote(); + if (note != null) { + _writer.println(margin + " Note: " + note); + } + _level--; + } + + private void showMessage(Message message) { + String margin = getIndent(++_level); + String prefix = message.getPrefix() + "Message: "; + String str = message.getMessage(); + // Append submessage, if any, after a colon. + String submsg = message.getSubMessage(); + if (submsg != null) { + str += ": " + submsg; + } + _writer.println(margin + prefix + str); + String id = message.getId(); + if (!(id == null || id.isEmpty() || id.equals(JhoveMessages.NO_ID))) { + _writer.println(margin + " ID: " + id); + _writer.println(margin + " InfoLink: " + Handlers.makeInfoLink(this.reportingModule, id)); + } + long offset = message.getOffset(); + if (offset > -1) { + _writer.println(margin + " Offset: " + offset); + } + _level--; + } + + private void showSignature(Signature signature) { + String margin = getIndent(++_level); + + String sigValue; + if (signature.isStringValue()) { + sigValue = signature.getValueString(); + } else { + sigValue = signature.getValueHexString(); + } + _writer.println(margin + signature.getType().toString() + ": " + + sigValue); + if ((signature.getType().equals(SignatureType.MAGIC)) + && (((InternalSignature) signature).hasFixedOffset())) { + _writer.println(margin + " Offset: " + + ((InternalSignature) signature).getOffset()); + } + String note = signature.getNote(); + if (note != null) { + _writer.println(margin + " Note: " + note); + } + String use = signature.getUse().toString(); + if (use != null) { + _writer.println(margin + " Use: " + use); + } + _level--; + } + + /* showProperty may be called recursively. */ + private void showProperty(Property property, String key, String margin) { + PropertyArity arity = property.getArity(); + + if (key == null) { + _writer.print(margin + " "); + } else { + _writer.print(margin + " " + key + ": "); + } + if (arity.equals(PropertyArity.SCALAR)) { + showScalarProperty(property, margin); + } else if (arity.equals(PropertyArity.LIST)) { + showListProperty(property, margin); + } else if (arity.equals(PropertyArity.MAP)) { + showMapProperty(property, margin); + } else if (arity.equals(PropertyArity.SET)) { + showSetProperty(property, margin); + } else if (arity.equals(PropertyArity.ARRAY)) { + showArrayProperty(property, margin); + } else { + _writer.println(); + } + } + + private void showScalarProperty(Property property, String margin) { + PropertyType type = property.getType(); + if (PropertyType.PROPERTY.equals(type)) { + _writer.println(); + Property prop = (Property) property.getValue(); + showProperty(prop, prop.getName(), margin + " "); + // _writer.println (); // Does this improve things? + } else if (PropertyType.NISOIMAGEMETADATA.equals(type)) { + showNisoImageMetadata((NisoImageMetadata) property.getValue(), + margin + " ", _je.getShowRawFlag()); + } else if (PropertyType.AESAUDIOMETADATA.equals(type)) { + showAESAudioMetadata((AESAudioMetadata) property.getValue(), margin + + " ", _je.getShowRawFlag()); + } else if (PropertyType.TEXTMDMETADATA.equals(type)) { + showTextMDMetadata((TextMDMetadata) property.getValue(), margin + + " ", _je.getShowRawFlag()); + } else { + _writer.println(property.getValue().toString()); + } + } + + private void showListProperty(Property property, String margin) { + PropertyType type = property.getType(); + boolean valueIsProperty = PropertyType.PROPERTY.equals(type); + boolean valueIsNiso = PropertyType.NISOIMAGEMETADATA.equals(type); + boolean valueIsTextMD = PropertyType.TEXTMDMETADATA.equals(type); + + List list = (List) property.getValue(); + + int n = list.size(); + int i; + if (n > 0) { + // Put a blank line after the name of the property list. + if (valueIsProperty) { + _writer.println(); + } + for (i = 0; i < n; i++) { + if (valueIsProperty) { + Property pval = (Property) list.get(i); + showProperty(pval, pval.getName(), margin + " "); + } else if (valueIsNiso) { + showNisoImageMetadata((NisoImageMetadata) list.get(i), + margin + " ", _je.getShowRawFlag()); + } else if (valueIsTextMD) { + showTextMDMetadata((TextMDMetadata) list.get(i), margin + + " ", _je.getShowRawFlag()); + } else { + Object val = list.get(i); + if (i == 0) { + _writer.print(val); + } else { + _writer.print(", " + val); + } + } + } + } + if (!valueIsProperty || n == 0) { + _writer.println(); + } + } + + private void showMapProperty(Property property, String margin) { + /* + * Map output looks like key : mapkey1 / mapval1, mapkey2 / mapval2, ... + */ + PropertyType type = property.getType(); + boolean valueIsProperty = PropertyType.PROPERTY.equals(type); + boolean valueIsNiso = PropertyType.NISOIMAGEMETADATA.equals(type); + boolean valueIsTextMD = PropertyType.TEXTMDMETADATA.equals(type); + + Map propmap = (Map) property.getValue(); + Set keys = propmap.keySet(); + Iterator propiter = keys.iterator(); + while (propiter.hasNext()) { + Object propkey = propiter.next(); + Object val = propmap.get(propkey); + if (valueIsProperty) { + Property pval = (Property) val; + showProperty(pval, pval.getName(), margin + " "); + String propkeyStr = propkey.toString(); + if (!(pval.getName().equals(propkeyStr))) { + _writer.println(" Key: " + propkeyStr); + } + } else if (valueIsNiso) { + showNisoImageMetadata((NisoImageMetadata) val, margin + " ", + _je.getShowRawFlag()); + } else if (valueIsTextMD) { + showTextMDMetadata((TextMDMetadata) val, margin + " ", + _je.getShowRawFlag()); + } else { + _writer.println(" " + val.toString()); + _writer.println(" Key: " + propkey.toString()); + } + } + } + + private void showSetProperty(Property property, String margin) { + PropertyType type = property.getType(); + boolean valueIsProperty = PropertyType.PROPERTY.equals(type); + boolean valueIsNiso = PropertyType.NISOIMAGEMETADATA.equals(type); + boolean valueIsTextMD = PropertyType.TEXTMDMETADATA.equals(type); + + Set propset = (Set) property.getValue(); + Iterator propiter = propset.iterator(); + boolean first = true; + while (propiter.hasNext()) { + Object val = propiter.next(); + if (valueIsProperty) { + Property pval = (Property) val; + showProperty(pval, pval.getName(), margin + " "); + } else if (valueIsNiso) { + showNisoImageMetadata((NisoImageMetadata) val, margin + " ", + _je.getShowRawFlag()); + } else if (valueIsTextMD) { + showTextMDMetadata((TextMDMetadata) val, margin + " ", + _je.getShowRawFlag()); + } else { + if (first) { + _writer.print(val.toString()); + first = false; + } else { + _writer.print(", " + val.toString()); + } + } + } + _writer.println(); + } + + private void showArrayProperty(Property property, String margin) { + boolean[] boolArray = null; + byte[] byteArray = null; + char[] charArray = null; + java.util.Date[] dateArray = null; + double[] doubleArray = null; + float[] floatArray = null; + int[] intArray = null; + long[] longArray = null; + Object[] objArray = null; + Property[] propArray = null; + short[] shortArray = null; + String[] stringArray = null; + Rational[] rationalArray = null; + NisoImageMetadata[] nisoArray = null; + TextMDMetadata[] textMDArray = null; + int n = 0; + + PropertyType propType = property.getType(); + if (PropertyType.BOOLEAN.equals(propType)) { + boolArray = (boolean[]) property.getValue(); + n = boolArray.length; + } else if (PropertyType.BYTE.equals(propType)) { + byteArray = (byte[]) property.getValue(); + n = byteArray.length; + } else if (PropertyType.CHARACTER.equals(propType)) { + charArray = (char[]) property.getValue(); + n = charArray.length; + } else if (PropertyType.DATE.equals(propType)) { + dateArray = (java.util.Date[]) property.getValue(); + n = dateArray.length; + } else if (PropertyType.DOUBLE.equals(propType)) { + doubleArray = (double[]) property.getValue(); + n = doubleArray.length; + } else if (PropertyType.FLOAT.equals(propType)) { + floatArray = (float[]) property.getValue(); + n = floatArray.length; + } else if (PropertyType.INTEGER.equals(propType)) { + intArray = (int[]) property.getValue(); + n = intArray.length; + } else if (PropertyType.LONG.equals(propType)) { + longArray = (long[]) property.getValue(); + n = longArray.length; + } else if (PropertyType.OBJECT.equals(propType)) { + objArray = (Object[]) property.getValue(); + n = objArray.length; + } else if (PropertyType.SHORT.equals(propType)) { + shortArray = (short[]) property.getValue(); + n = shortArray.length; + } else if (PropertyType.STRING.equals(propType)) { + stringArray = (String[]) property.getValue(); + n = stringArray.length; + } else if (PropertyType.RATIONAL.equals(propType)) { + rationalArray = (Rational[]) property.getValue(); + n = rationalArray.length; + } else if (PropertyType.PROPERTY.equals(propType)) { + propArray = (Property[]) property.getValue(); + n = propArray.length; + } else if (PropertyType.NISOIMAGEMETADATA.equals(propType)) { + nisoArray = (NisoImageMetadata[]) property.getValue(); + n = nisoArray.length; + } else if (PropertyType.TEXTMDMETADATA.equals(propType)) { + textMDArray = (TextMDMetadata[]) property.getValue(); + n = textMDArray.length; + } + + for (int i = 0; i < n; i++) { + String elem; + if (PropertyType.BOOLEAN.equals(propType)) { + elem = String.valueOf(boolArray[i]); + } else if (PropertyType.BYTE.equals(propType)) { + elem = String.valueOf(byteArray[i]); + } else if (PropertyType.CHARACTER.equals(propType)) { + elem = String.valueOf(charArray[i]); + } else if (PropertyType.DATE.equals(propType)) { + elem = dateArray[i].toString(); + } else if (PropertyType.DOUBLE.equals(propType)) { + elem = String.valueOf(doubleArray[i]); + } else if (PropertyType.FLOAT.equals(propType)) { + elem = String.valueOf(floatArray[i]); + } else if (PropertyType.INTEGER.equals(propType)) { + elem = String.valueOf(intArray[i]); + } else if (PropertyType.LONG.equals(propType)) { + elem = String.valueOf(longArray[i]); + } else if (PropertyType.OBJECT.equals(propType)) { + elem = objArray[i].toString(); + } else if (PropertyType.SHORT.equals(propType)) { + elem = String.valueOf(shortArray[i]); + } else if (PropertyType.STRING.equals(propType)) { + elem = stringArray[i]; + } else if (PropertyType.RATIONAL.equals(propType)) { + elem = rationalArray[i].toString(); + } else if (PropertyType.NISOIMAGEMETADATA.equals(propType)) { + if (i == 0) { + _writer.println(); + } + NisoImageMetadata niso = nisoArray[i]; + showNisoImageMetadata(niso, margin + " ", _je.getShowRawFlag()); + continue; + } else if (PropertyType.TEXTMDMETADATA.equals(propType)) { + if (i == 0) { + _writer.println(); + } + showTextMDMetadata(textMDArray[i], margin + " ", + _je.getShowRawFlag()); + continue; + } else if (PropertyType.PROPERTY.equals(propType)) { + if (i == 0) { + _writer.println(); + } + Property pval = propArray[i]; + showProperty(pval, pval.getName(), margin + " "); + continue; + } else + elem = ""; + if (i == 0) { + _writer.print(elem); + } else { + _writer.print(", " + elem); + } + } + if (propType != PropertyType.PROPERTY + && propType != PropertyType.NISOIMAGEMETADATA) { + _writer.println(); + } + } + + /* + * Output the textMD metadata, which is its own special kind of property. + */ + private void showTextMDMetadata(TextMDMetadata textMD, String margin, + boolean rawOutput) { + String margn2 = margin + " "; + String margn3 = margn2 + " "; + + _writer.println(); + _writer.println(margn2 + "Character_info:"); + String s = textMD.getCharset(); + if (s != null) { + _writer.println(margn3 + "Charset: " + s); + } + if ((s = textMD.getByte_orderString()) != null) { + _writer.println(margn3 + "Byte_order: " + s); + } + if ((s = textMD.getByte_size()) != null) { + _writer.println(margn3 + "Byte_size: " + s); + } + if ((s = textMD.getCharacter_size()) != null) { + _writer.println(margn3 + "Character_size: " + s); + } + if ((s = textMD.getLinebreakString()) != null) { + _writer.println(margn3 + "Linebreak: " + s); + } + + if ((s = textMD.getLanguage()) != null) { + _writer.println(margn2 + "Language: " + s); + } + if ((s = textMD.getMarkup_basis()) != null) { + _writer.println(margn2 + "Markup_basis: " + s); + } + if ((s = textMD.getMarkup_basis_version()) != null) { + _writer.println(margn2 + "Markup_basis_version: " + s); + } + if ((s = textMD.getMarkup_language()) != null) { + _writer.println(margn2 + "Markup_language: " + s); + } + if ((s = textMD.getMarkup_language_version()) != null) { + _writer.println(margn2 + "Markup_language_version: " + s); + } + } + + /* + * Output the AES audio metadata, which is its own special kind of property. + */ + private void showAESAudioMetadata(AESAudioMetadata aes, String margin, + boolean rawOutput) { + String margn2 = margin + " "; + String margn3 = margn2 + " "; + String margn4 = margn3 + " "; + String margn5 = margn4 + " "; + + _sampleRate = aes.getSampleRate(); + + _writer.println(); + String s = aes.getAnalogDigitalFlag(); + if (s != null) { + _writer.println(margn2 + "AnalogDigitalFlag: " + s); + } + s = aes.getSchemaVersion(); + if (s != null) { + _writer.println(margn2 + "SchemaVersion: " + s); + } + s = aes.getFormat(); + if (s != null) { + _writer.println(margn2 + "Format: " + s); + } + s = aes.getSpecificationVersion(); + if (s != null) { + _writer.println(margn2 + "SpecificationVersion: " + s); + } + s = aes.getAppSpecificData(); + if (s != null) { + _writer.println(margn2 + "AppSpecificData: " + s); + } + s = aes.getAudioDataEncoding(); + if (s != null) { + _writer.println(margn2 + "AudioDataEncoding: " + s); + } + int in = aes.getByteOrder(); + if (in != AESAudioMetadata.NULL) { + _writer.println(margn2 + + "ByteOrder: " + + (in == AESAudioMetadata.BIG_ENDIAN ? "BIG_ENDIAN" + : "LITTLE_ENDIAN")); + } + long lin = aes.getFirstSampleOffset(); + if (lin != AESAudioMetadata.NULL) { + _writer.println(margn2 + "FirstSampleOffset: " + Long.toString(lin)); + } + String[] use = aes.getUse(); + if (use != null) { + _writer.println(margn2 + "Use:"); + _writer.println(margn3 + "UseType: " + use[0]); + _writer.println(margn3 + "OtherType: " + use[1]); + } + s = aes.getPrimaryIdentifier(); + if (s != null) { + String t = aes.getPrimaryIdentifierType(); + _writer.println(margn2 + "PrimaryIdentifier: " + s); + if (t != null) { + _writer.println(margn3 + "IdentifierType: " + t); + } + } + List facelist = aes.getFaceList(); + if (!facelist.isEmpty()) { + // Add the face information, which is mostly filler. + AESAudioMetadata.Face f = (AESAudioMetadata.Face) facelist.get(0); + _writer.println(margn2 + "Face: "); + _writer.println(margn3 + "TimeLine: "); + AESAudioMetadata.TimeDesc startTime = f.getStartTime(); + if (startTime != null) { + writeAESTimeRange(margn3, startTime, f.getDuration()); + } // For the present, assume just one face region AESAudioMetadata.FaceRegion facergn = f.getFaceRegion(0); _writer.println(margn3 + "Region: "); - _writer.println (margn4 + "TimeRange: "); + _writer.println(margn4 + "TimeRange: "); writeAESTimeRange(margn4, facergn.getStartTime(), facergn.getDuration()); - int nchan = aes.getNumChannels(); - if (nchan != AESAudioMetadata.NULL) { - _writer.println(margn4 + "NumChannels: " - + Integer.toString(nchan)); - } + int nchan = aes.getNumChannels(); + if (nchan != AESAudioMetadata.NULL) { + _writer.println(margn4 + "NumChannels: " + + Integer.toString(nchan)); + } for (int ch = 0; ch < nchan; ch++) { - // write a stream description for each channel - _writer.println(margn4 + "Stream:"); - _writer.println(margn5 + "ChannelNum: " + Integer.toString(ch)); - } - } - - // In the general case, a FormatList can contain multiple - // FormatRegions. This doesn't happen with any of the current - // modules; if it's needed in the future, simply set up an - // iteration loop on formatList. - List flist = aes.getFormatList(); - if (!flist.isEmpty()) { - AESAudioMetadata.FormatRegion rgn = (AESAudioMetadata.FormatRegion) flist - .get(0); - int bitDepth = rgn.getBitDepth(); - double sampleRate = rgn.getSampleRate(); - int wordSize = rgn.getWordSize(); - String[] bitRed = rgn.getBitrateReduction(); - // Build a FormatRegion subtree if at least one piece of data - // that goes into it is present. - if (bitDepth != AESAudioMetadata.NULL - || sampleRate != AESAudioMetadata.NILL - || wordSize != AESAudioMetadata.NULL) { - _writer.println(margn2 + "FormatList:"); - _writer.println(margn3 + "FormatRegion:"); - if (bitDepth != AESAudioMetadata.NULL) { - _writer.println(margn4 + "BitDepth: " - + Integer.toString(bitDepth)); - } - if (sampleRate != AESAudioMetadata.NILL) { - _writer.println(margn4 + "SampleRate: " - + Double.toString(sampleRate)); - } - if (wordSize != AESAudioMetadata.NULL) { - _writer.println(margn4 + "WordSize: " - + Integer.toString(wordSize)); - } - if (bitRed != null) { - _writer.println(margn4 + "BitrateReduction"); - _writer.println(margn5 + "CodecName: " + bitRed[0]); - _writer.println(margn5 + "codecNameVersion: " + bitRed[1]); - _writer.println(margn5 + "codecCreatorApplication: " - + bitRed[2]); - _writer.println(margn5 + "codecCreatorApplicationVersion: " - + bitRed[3]); - _writer.println(margn5 + "codecQuality: " + bitRed[4]); - _writer.println(margn5 + "dataRate: " + bitRed[5]); - _writer.println(margn5 + "dataRateMode: " + bitRed[6]); - } - } - } - } - - /* start must be non-null, but duration may be null */ - private void writeAESTimeRange(String baseIndent, - AESAudioMetadata.TimeDesc start, AESAudioMetadata.TimeDesc duration) { + // write a stream description for each channel + _writer.println(margn4 + "Stream:"); + _writer.println(margn5 + "ChannelNum: " + Integer.toString(ch)); + } + } + + // In the general case, a FormatList can contain multiple + // FormatRegions. This doesn't happen with any of the current + // modules; if it's needed in the future, simply set up an + // iteration loop on formatList. + List flist = aes.getFormatList(); + if (!flist.isEmpty()) { + AESAudioMetadata.FormatRegion rgn = (AESAudioMetadata.FormatRegion) flist + .get(0); + int bitDepth = rgn.getBitDepth(); + double sampleRate = rgn.getSampleRate(); + int wordSize = rgn.getWordSize(); + String[] bitRed = rgn.getBitrateReduction(); + // Build a FormatRegion subtree if at least one piece of data + // that goes into it is present. + if (bitDepth != AESAudioMetadata.NULL + || sampleRate != AESAudioMetadata.NILL + || wordSize != AESAudioMetadata.NULL) { + _writer.println(margn2 + "FormatList:"); + _writer.println(margn3 + "FormatRegion:"); + if (bitDepth != AESAudioMetadata.NULL) { + _writer.println(margn4 + "BitDepth: " + + Integer.toString(bitDepth)); + } + if (sampleRate != AESAudioMetadata.NILL) { + _writer.println(margn4 + "SampleRate: " + + Double.toString(sampleRate)); + } + if (wordSize != AESAudioMetadata.NULL) { + _writer.println(margn4 + "WordSize: " + + Integer.toString(wordSize)); + } + if (bitRed != null) { + _writer.println(margn4 + "BitrateReduction"); + _writer.println(margn5 + "CodecName: " + bitRed[0]); + _writer.println(margn5 + "codecNameVersion: " + bitRed[1]); + _writer.println(margn5 + "codecCreatorApplication: " + + bitRed[2]); + _writer.println(margn5 + "codecCreatorApplicationVersion: " + + bitRed[3]); + _writer.println(margn5 + "codecQuality: " + bitRed[4]); + _writer.println(margn5 + "dataRate: " + bitRed[5]); + _writer.println(margn5 + "dataRateMode: " + bitRed[6]); + } + } + } + } + + /* start must be non-null, but duration may be null */ + private void writeAESTimeRange(String baseIndent, + AESAudioMetadata.TimeDesc start, AESAudioMetadata.TimeDesc duration) { writeAESTimeRangePart(baseIndent, "StartTime", start); - if (duration != null) { + if (duration != null) { writeAESTimeRangePart(baseIndent, "Duration", duration); - } - } + } + } + private void writeAESTimeRangePart(String baseIndent, String name, AESAudioMetadata.TimeDesc timeDesc) { String margn1 = baseIndent + " "; String margn2 = margn1 + " "; - _writer.println (margn1 + name + ": "); + _writer.println(margn1 + name + ": "); double sampleRate = timeDesc.getSampleRate(); if (sampleRate == 1.0) { sampleRate = _sampleRate; } - _writer.println (margn2 + "Value: " + String.valueOf(timeDesc.getSamples())); - _writer.println (margn2 + "EditRate: " + Integer.toString ((int) sampleRate)); - _writer.println (margn2 + "FactorNumerator: 1"); - _writer.println (margn2 + "FactorDenominator: 1"); + _writer.println(margn2 + "Value: " + String.valueOf(timeDesc.getSamples())); + _writer.println(margn2 + "EditRate: " + Integer.toString((int) sampleRate)); + _writer.println(margn2 + "FactorNumerator: 1"); + _writer.println(margn2 + "FactorDenominator: 1"); + } + + /** + * Display the NISO image metadata formatted according to the MIX schema. + * The schema which is used may be 0.2 or 1.0, depending on the module + * parameters. + * + * @param niso + * NISO image metadata + */ + protected void showNisoImageMetadata(NisoImageMetadata niso, String margin, + boolean rawOutput) { + if ("0.2".equals(_je.getMixVersion())) { + showNisoImageMetadata02(niso, margin, rawOutput); + } else { + showNisoImageMetadata10(niso, margin, rawOutput); + } } - /** - * Display the NISO image metadata formatted according to the MIX schema. - * The schema which is used may be 0.2 or 1.0, depending on the module - * parameters. - * - * @param niso - * NISO image metadata - */ - protected void showNisoImageMetadata(NisoImageMetadata niso, String margin, - boolean rawOutput) { - if ("0.2".equals(_je.getMixVersion())) { - showNisoImageMetadata02(niso, margin, rawOutput); - } else { - showNisoImageMetadata10(niso, margin, rawOutput); - } - } - - /* - * Output the Niso image metadata, which is its own special kind of - * property. This provides a text approximation to MIX 0.2. - */ - private void showNisoImageMetadata02(NisoImageMetadata niso, String margin, - boolean rawOutput) { - String margn2 = margin + " "; - - _writer.println(); - String s = niso.getMimeType(); - if (s != null) { - _writer.println(margn2 + "MIMEType: " + s); - } - if ((s = niso.getByteOrder()) != null) { - _writer.println(margn2 + "ByteOrder: " + s); - } - int n = niso.getCompressionScheme(); - if (n != NisoImageMetadata.NULL) { - _writer.println(margn2 - + "CompressionScheme: " - + addIntegerValue(n, NisoImageMetadata.COMPRESSION_SCHEME, - NisoImageMetadata.COMPRESSION_SCHEME_INDEX, - rawOutput)); - } - if ((n = niso.getCompressionLevel()) != NisoImageMetadata.NULL) { - _writer.println(margn2 + "CompressionLevel: " + n); - } - if ((n = niso.getColorSpace()) != NisoImageMetadata.NULL) { - _writer.println(margn2 - + "ColorSpace: " - + addIntegerValue(n, NisoImageMetadata.COLORSPACE, - NisoImageMetadata.COLORSPACE_INDEX, rawOutput)); - } - if ((s = niso.getProfileName()) != null) { - _writer.println(margn2 + "ProfileName: " + s); - } - if ((s = niso.getProfileURL()) != null) { - _writer.println(margn2 + "ProfileURL: " + s); - } - int[] iarray = niso.getYCbCrSubSampling(); - if (iarray != null) { - _writer.print(margn2 + "YCbCrSubSampling: " + iarray[0]); - for (int i = 1; i < iarray.length; i++) { - _writer.print(", " + iarray[i]); - } - _writer.println(); - } - if ((n = niso.getYCbCrPositioning()) != NisoImageMetadata.NULL) { - _writer.println(margn2 - + "YCbCrPositioning: " - + addIntegerValue(n, NisoImageMetadata.YCBCR_POSITIONING, - rawOutput)); - } - Rational[] rarray = niso.getYCbCrCoefficients(); - if (rarray != null) { - _writer.print(margn2 + "YCbCrCoefficients: " - + addRationalValue(rarray[0], rawOutput)); - for (int i = 1; i < rarray.length; i++) { - _writer.print(", " + addRationalValue(rarray[i], rawOutput)); - } - _writer.println(); - } - rarray = niso.getReferenceBlackWhite(); - if (rarray != null) { - _writer.print(margn2 + "ReferenceBlackWhite: " - + addRationalValue(rarray[0], rawOutput)); - for (int i = 1; i < rarray.length; i++) { - _writer.print(", " + addRationalValue(rarray[i], rawOutput)); - } - _writer.println(); - } - if ((n = niso.getSegmentType()) != NisoImageMetadata.NULL) { - _writer.println(margn2 - + "SegmentType: " - + addIntegerValue(n, NisoImageMetadata.SEGMENT_TYPE, - rawOutput)); - } - long[] larray = niso.getStripOffsets(); - if (larray != null) { - _writer.print(margn2 + "StripOffsets: " + larray[0]); - for (int i = 1; i < larray.length; i++) { - _writer.print(", " + larray[i]); - } - _writer.println(); - } - long ln = niso.getRowsPerStrip(); - if (ln != NisoImageMetadata.NULL) { - _writer.println(margn2 + "RowsPerStrip: " + ln); - } - if ((larray = niso.getStripByteCounts()) != null) { - _writer.print(margn2 + "StripByteCounts: " + larray[0]); - for (int i = 1; i < larray.length; i++) { - _writer.print(", " + larray[i]); - } - _writer.println(); - } - if ((ln = niso.getTileWidth()) != NisoImageMetadata.NULL) { - _writer.println(margn2 + "TileWidth: " + ln); - } - if ((ln = niso.getTileLength()) != NisoImageMetadata.NULL) { - _writer.println(margn2 + "TileLength: " + ln); - } - if ((larray = niso.getTileOffsets()) != null) { - _writer.print(margn2 + "TileOffsets: " + larray[0]); - for (int i = 1; i < larray.length; i++) { - _writer.print(", " + larray[i]); - } - _writer.println(); - } - if ((larray = niso.getTileByteCounts()) != null) { - _writer.print(margn2 + "TileByteCounts: " + larray[0]); - for (int i = 1; i < larray.length; i++) { - _writer.print(", " + larray[i]); - } - _writer.println(); - } - if ((n = niso.getPlanarConfiguration()) != NisoImageMetadata.NULL) { - _writer.println(margn2 - + "PlanarConfiguration: " - + addIntegerValue(n, - NisoImageMetadata.PLANAR_CONFIGURATION, rawOutput)); - } - if ((s = niso.getImageIdentifier()) != null) { - _writer.println(margn2 + "ImageIdentifier: " + s); - } - if ((s = niso.getImageIdentifierLocation()) != null) { - _writer.println(margn2 + "ImageIdentifierLocation: " + s); - } - if ((ln = niso.getFileSize()) != NisoImageMetadata.NULL) { - _writer.println(margn2 + "FileSize: " + ln); - } - if ((n = niso.getChecksumMethod()) != NisoImageMetadata.NULL) { - _writer.println(margn2 - + "ChecksumMethod: " - + addIntegerValue(n, NisoImageMetadata.CHECKSUM_METHOD, - rawOutput)); - } - if ((s = niso.getChecksumValue()) != null) { - _writer.println(margn2 + "ChecksumValue: " + s); - } - if ((n = niso.getOrientation()) != NisoImageMetadata.NULL) { - _writer.println(margn2 - + "Orientation: " - + addIntegerValue(n, NisoImageMetadata.ORIENTATION, - rawOutput)); - } - if ((n = niso.getDisplayOrientation()) != NisoImageMetadata.NULL) { - _writer.println(margn2 - + "DisplayOrientation: " - + addIntegerValue(n, NisoImageMetadata.DISPLAY_ORIENTATION, - rawOutput)); - } - if ((ln = niso.getXTargetedDisplayAR()) != NisoImageMetadata.NULL) { - _writer.println(margn2 + "XTargetedDisplayAR: " + ln); - } - if ((ln = niso.getYTargetedDisplayAR()) != NisoImageMetadata.NULL) { - _writer.println(margn2 + "YTargetedDisplayAR: " + ln); - } - if ((s = niso.getPreferredPresentation()) != null) { - _writer.println(margn2 + "PreferredPresentation: " + s); - } - if ((s = niso.getSourceType()) != null) { - _writer.println(margn2 + "SourceType: " + s); - } - if ((s = niso.getImageProducer()) != null) { - _writer.println(margn2 + "ImageProducer: " + s); - } - if ((s = niso.getHostComputer()) != null) { - _writer.println(margn2 + "HostComputer: " + s); - } - if ((s = niso.getOS()) != null) { - _writer.println(margn2 + "OperatingSystem: " + s); - } - if ((s = niso.getOSVersion()) != null) { - _writer.println(margn2 + "OSVersion: " + s); - } - if ((s = niso.getDeviceSource()) != null) { - _writer.println(margn2 + "DeviceSource: " + s); - } - if ((s = niso.getScannerManufacturer()) != null) { - _writer.println(margn2 + "ScannerManufacturer: " + s); - } - if ((s = niso.getScannerModelName()) != null) { - _writer.println(margn2 + "ScannerModelName: " + s); - } - if ((s = niso.getScannerModelNumber()) != null) { - _writer.println(margn2 + "ScannerModelNumber: " + s); - } - if ((s = niso.getScannerModelSerialNo()) != null) { - _writer.println(margn2 + "ScannerModelSerialNo: " + s); - } - if ((s = niso.getScanningSoftware()) != null) { - _writer.println(margn2 + "ScanningSoftware: " + s); - } - if ((s = niso.getScanningSoftwareVersionNo()) != null) { - _writer.println(margn2 + "ScanningSoftwareVersionNo: " + s); - } - double d = niso.getPixelSize(); - if (d != NisoImageMetadata.NILL) { - _writer.println(margn2 + "PixelSize: " + d); - } - if ((d = niso.getXPhysScanResolution()) != NisoImageMetadata.NILL) { - _writer.println(margn2 + "XPhysScanResolution: " + d); - } - if ((d = niso.getYPhysScanResolution()) != NisoImageMetadata.NILL) { - _writer.println(margn2 + "YPhysScanResolution: " + d); - } - - if ((s = niso.getDigitalCameraManufacturer()) != null) { - _writer.println(margn2 + "DigitalCameraManufacturer: " + s); - } - if ((s = niso.getDigitalCameraModelName()) != null) { - _writer.println(margn2 + "DigitalCameraModelName: " + s); - } - if ((s = niso.getDigitalCameraModelNumber()) != null) { - _writer.println(margn2 + "DigitalCameraModelNumber: " + s); - } - if ((s = niso.getDigitalCameraModelSerialNo()) != null) { - _writer.println(margn2 + "DigitalCameraModelSerialNo: " + s); - } - if ((d = niso.getFNumber()) != NisoImageMetadata.NILL) { - _writer.println(margn2 + "FNumber: " + d); - } - if ((d = niso.getExposureTime()) != NisoImageMetadata.NILL) { - _writer.println(margn2 + "ExposureTime: " + d); - } - Rational r; - if ((r = niso.getBrightness()) != null) { - d = r.toDouble(); - _writer.println(margn2 + "Brightness: " + d); - } - if ((r = niso.getExposureBias()) != null) { - d = r.toDouble(); - _writer.println(margn2 + "ExposureBias: " + d); - } - - double[] darray = niso.getSubjectDistance(); - if (darray != null) { - _writer.print(margn2 + "SubjectDistance: " + darray[0]); - for (int i = 1; i < darray.length; i++) { - _writer.print(", " + darray[i]); - } - _writer.println(); - } - if ((n = niso.getMeteringMode()) != NisoImageMetadata.NULL) { - _writer.println(margn2 - + "MeteringMode: " - + addIntegerValue(n, NisoImageMetadata.METERING_MODE, - rawOutput)); - } - if ((n = niso.getSceneIlluminant()) != NisoImageMetadata.NULL) { - _writer.println(margn2 - + "SceneIlluminant: " - + addIntegerValue(n, NisoImageMetadata.METERING_MODE, - rawOutput)); - } - if ((d = niso.getColorTemp()) != NisoImageMetadata.NILL) { - _writer.println(margn2 + "ColorTemp: " + d); - } - if ((d = niso.getFocalLength()) != NisoImageMetadata.NILL) { - _writer.println(margn2 + "FocalLength: " + d); - } - if ((n = niso.getFlash()) != NisoImageMetadata.NULL) { - _writer.println(margn2 + "Flash: " - + addIntegerValue(n, NisoImageMetadata.FLASH, rawOutput)); - } - if ((r = niso.getFlashEnergy()) != null) { - d = r.toDouble(); - _writer.println(margn2 + "FlashEnergy: " + d); - } - if ((n = niso.getFlashReturn()) != NisoImageMetadata.NULL) { - _writer.println(margn2 - + "FlashReturn: " - + addIntegerValue(n, NisoImageMetadata.FLASH_RETURN, - rawOutput)); - } - if ((n = niso.getBackLight()) != NisoImageMetadata.NULL) { - _writer.println(margn2 - + "BackLight: " - + addIntegerValue(n, NisoImageMetadata.BACKLIGHT, rawOutput)); - } - if ((d = niso.getExposureIndex()) != NisoImageMetadata.NILL) { - _writer.println(margn2 + "ExposureIndex: " + d); - } - if ((n = niso.getAutoFocus()) != NisoImageMetadata.NULL) { - _writer.println(margn2 - + "AutoFocus: " - + addIntegerValue(n, NisoImageMetadata.AUTOFOCUS, rawOutput)); - } - if ((d = niso.getXPrintAspectRatio()) != NisoImageMetadata.NILL) { - _writer.println(margn2 + "XPrintAspectRatio: " + d); - } - if ((d = niso.getYPrintAspectRatio()) != NisoImageMetadata.NILL) { - _writer.println(margn2 + "YPrintAspectRatio: " + d); - } - - if ((n = niso.getSensor()) != NisoImageMetadata.NULL) { - _writer.println(margn2 + "Sensor: " - + addIntegerValue(n, NisoImageMetadata.SENSOR, rawOutput)); - } - if ((s = niso.getDateTimeCreated()) != null) { - _writer.println(margn2 + "DateTimeCreated: " + s); - } - if ((s = niso.getMethodology()) != null) { - _writer.println(margn2 + "Methodology: " + s); - } - if ((n = niso.getSamplingFrequencyPlane()) != NisoImageMetadata.NULL) { - _writer.println(margn2 - + "SamplingFrequencyPlane: " - + addIntegerValue(n, - NisoImageMetadata.SAMPLING_FREQUENCY_PLANE, - rawOutput)); - } - if ((n = niso.getSamplingFrequencyUnit()) != NisoImageMetadata.NULL) { - _writer.println(margn2 - + "SamplingFrequencyUnit: " - + addIntegerValue(n, - NisoImageMetadata.SAMPLING_FREQUENCY_UNIT, - rawOutput)); - } - r = niso.getXSamplingFrequency(); - if (r != null) { - _writer.println(margn2 + "XSamplingFrequency: " - + addRationalValue(r, rawOutput)); - - } - r = niso.getYSamplingFrequency(); - if (r != null) { - _writer.println(margn2 + "YSamplingFrequency: " - + addRationalValue(r, rawOutput)); - } - if ((ln = niso.getImageWidth()) != NisoImageMetadata.NULL) { - _writer.println(margn2 + "ImageWidth: " + ln); - } - if ((ln = niso.getImageLength()) != NisoImageMetadata.NULL) { - _writer.println(margn2 + "ImageLength: " + ln); - } - if ((d = niso.getSourceXDimension()) != NisoImageMetadata.NILL) { - _writer.println(margn2 + "SourceXDimension: " + d); - } - if ((n = niso.getSourceXDimensionUnit()) != NisoImageMetadata.NULL) { - _writer.println(margn2 - + "SourceXDimensionUnit: " - + addIntegerValue(n, - NisoImageMetadata.SOURCE_DIMENSION_UNIT, rawOutput)); - } - if ((d = niso.getSourceYDimension()) != NisoImageMetadata.NILL) { - _writer.println(margn2 + "SourceYDimension: " + ln); - } - if ((n = niso.getSourceYDimensionUnit()) != NisoImageMetadata.NULL) { - _writer.println(margn2 - + "SourceYDimensionUnit: " - + addIntegerValue(n, - NisoImageMetadata.SOURCE_DIMENSION_UNIT, rawOutput)); - } - if ((iarray = niso.getBitsPerSample()) != null) { - _writer.print(margn2 + "BitsPerSample: " + iarray[0]); - for (int i = 1; i < iarray.length; i++) { - _writer.print(", " + iarray[i]); - } - _writer.println(); - } - if ((n = niso.getSamplesPerPixel()) != NisoImageMetadata.NULL) { - _writer.println(margn2 + "SamplesPerPixel: " + n); - } - if ((iarray = niso.getExtraSamples()) != null) { - _writer.print(margn2 - + "ExtraSamples: " - + addIntegerValue(iarray[0], - NisoImageMetadata.EXTRA_SAMPLES, rawOutput)); - for (int i = 1; i < iarray.length; i++) { - _writer.print(", " - + addIntegerValue(iarray[i], - NisoImageMetadata.EXTRA_SAMPLES, rawOutput)); - } - _writer.println(); - } - if ((s = niso.getColormapReference()) != null) { - _writer.println(margn2 + "ColormapReference: " + s); - } - if ((iarray = niso.getColormapBitCodeValue()) != null) { - _writer.print(margn2 + "ColormapBitCodeValue: " + iarray[0]); - for (int i = 1; i < iarray.length; i++) { - _writer.print(", " + iarray[i]); - } - _writer.println(); - } - if ((iarray = niso.getColormapRedValue()) != null) { - _writer.print(margn2 + "ColormapRedValue: " + iarray[0]); - for (int i = 1; i < iarray.length; i++) { - _writer.print(", " + iarray[i]); - } - _writer.println(); - } - if ((iarray = niso.getColormapGreenValue()) != null) { - _writer.print(margn2 + "ColormapGreenValue: " + iarray[0]); - for (int i = 1; i < iarray.length; i++) { - _writer.print(", " + iarray[i]); - } - _writer.println(); - } - if ((iarray = niso.getColormapBlueValue()) != null) { - _writer.print(margn2 + "ColormapBlueValue: " + iarray[0]); - for (int i = 1; i < iarray.length; i++) { - _writer.print(", " + iarray[i]); - } - _writer.println(); - } - if ((iarray = niso.getGrayResponseCurve()) != null) { - _writer.print(margn2 + "GrayResponseCurve: " + iarray[0]); - for (int i = 1; i < iarray.length; i++) { - _writer.print(", " + iarray[i]); - } - _writer.println(); - } - if ((n = niso.getGrayResponseUnit()) != NisoImageMetadata.NULL) { - _writer.println(margn2 - + "GrayResponseUnit: " - + addIntegerValue(n, - NisoImageMetadata.GRAY_RESPONSE_UNIT_02, rawOutput)); - } - r = niso.getWhitePointXValue(); - if (r != null) { - _writer.println(margn2 + "WhitePointXValue: " - + addRationalValue(r, rawOutput)); - } - if ((r = niso.getWhitePointYValue()) != null) { - _writer.println(margn2 + "WhitePointXValue: " - + addRationalValue(r, rawOutput)); - } - if ((r = niso.getPrimaryChromaticitiesRedX()) != null) { - _writer.println(margn2 + "PrimaryChromaticitiesRedX: " - + addRationalValue(r, rawOutput)); - } - if ((r = niso.getPrimaryChromaticitiesRedY()) != null) { - _writer.println(margn2 + "PrimaryChromaticitiesRedY: " - + addRationalValue(r, rawOutput)); - } - if ((r = niso.getPrimaryChromaticitiesGreenX()) != null) { - _writer.println(margn2 + "PrimaryChromaticitiesGreenX: " - + addRationalValue(r, rawOutput)); - } - if ((r = niso.getPrimaryChromaticitiesGreenY()) != null) { - _writer.println(margn2 + "PrimaryChromaticitiesGreenY: " - + addRationalValue(r, rawOutput)); - } - if ((r = niso.getPrimaryChromaticitiesBlueX()) != null) { - _writer.println(margn2 + "PrimaryChromaticitiesBlueX: " - + addRationalValue(r, rawOutput)); - } - if ((r = niso.getPrimaryChromaticitiesBlueY()) != null) { - _writer.println(margn2 + "PrimaryChromaticitiesBlueY: " - + addRationalValue(r, rawOutput)); - } - if ((n = niso.getTargetType()) != NisoImageMetadata.NULL) { - _writer.println(margn2 - + "TargetType: " - + addIntegerValue(n, NisoImageMetadata.TARGET_TYPE, - rawOutput)); - } - if ((s = niso.getTargetIDManufacturer()) != null) { - _writer.println(margn2 + "TargetIDManufacturer: " + s); - } - if ((s = niso.getTargetIDName()) != null) { - _writer.println(margn2 + "TargetIDName: " + s); - } - if ((s = niso.getTargetIDNo()) != null) { - _writer.println(margn2 + "TargetIDNo: " + s); - } - if ((s = niso.getTargetIDMedia()) != null) { - _writer.println(margn2 + "TargetIDMedia: " + s); - } - if ((s = niso.getImageData()) != null) { - _writer.println(margn2 + "ImageData: " + s); - } - if ((s = niso.getPerformanceData()) != null) { - _writer.println(margn2 + "PerformanceData: " + s); - } - if ((s = niso.getProfiles()) != null) { - _writer.println(margn2 + "Profiles: " + s); - } - if ((s = niso.getDateTimeProcessed()) != null) { - _writer.println(margn2 + "DateTimeProcessed: " + s); - } - if ((s = niso.getSourceData()) != null) { - _writer.println(margn2 + "SourceData: " + s); - } - if ((s = niso.getProcessingAgency()) != null) { - _writer.println(margn2 + "ProcessingAgency: " + s); - } - if ((s = niso.getProcessingSoftwareName()) != null) { - _writer.println(margn2 + "ProcessingSoftwareName: " + s); - } - if ((s = niso.getProcessingSoftwareVersion()) != null) { - _writer.println(margn2 + "ProcessingSoftwareVersion: " + s); - } - String[] sarray = niso.getProcessingActions(); - if (sarray != null) { - _writer.print(margn2 + "ProcessingActions: " + sarray[0]); - for (int i = 1; i < sarray.length; i++) { - _writer.print(", " + sarray[i]); - } - _writer.println(); - } - - } - - private void showNisoImageMetadata10(NisoImageMetadata niso, String margin, - boolean rawOutput) { - String margn2 = margin + " "; - String s; - long ln; - _writer.println(); - if ((s = niso.getImageIdentifier()) != null) { - _writer.println(margn2 + "ImageIdentifier: " + s); - } - if ((ln = niso.getFileSize()) != NisoImageMetadata.NULL) { - _writer.println(margn2 + "FileSize: " + ln); - } - if ((s = niso.getMimeType()) != null) { - _writer.println(margn2 + "FormatName: " + s); - } - if ((s = niso.getByteOrder()) != null) { - // Convert strings to MIX 1.0 form - if (s.startsWith("big")) { - s = "big_endian"; - } else if (s.startsWith("little")) { - s = "little_endian"; - } - _writer.println(margn2 + "ByteOrder: " + s); - } - int n = niso.getCompressionScheme(); - if (n != NisoImageMetadata.NULL) { - _writer.println(margn2 - + "CompressionScheme: " - + addIntegerValue(n, NisoImageMetadata.COMPRESSION_SCHEME, - NisoImageMetadata.COMPRESSION_SCHEME_INDEX, - rawOutput)); - } - if ((n = niso.getCompressionLevel()) != NisoImageMetadata.NULL) { - _writer.println(margn2 + "CompressionLevel: " + n); - } - if ((n = niso.getChecksumMethod()) != NisoImageMetadata.NULL) { - _writer.println(margn2 - + "ChecksumMethod: " - + addIntegerValue(n, NisoImageMetadata.CHECKSUM_METHOD, - rawOutput)); - } - if ((s = niso.getChecksumValue()) != null) { - _writer.println(margn2 + "ChecksumValue: " + s); - } - if ((ln = niso.getImageWidth()) != NisoImageMetadata.NULL) { - _writer.println(margn2 + "ImageWidth: " + ln); - } - if ((ln = niso.getImageLength()) != NisoImageMetadata.NULL) { - _writer.println(margn2 + "ImageHeight: " + ln); - } - if ((n = niso.getColorSpace()) != NisoImageMetadata.NULL) { - _writer.println(margn2 - + "ColorSpace: " - + addIntegerValue(n, NisoImageMetadata.COLORSPACE, - NisoImageMetadata.COLORSPACE_INDEX, rawOutput)); - } - if ((s = niso.getProfileName()) != null) { - _writer.println(margn2 + "ICCProfileName: " + s); - } - if ((s = niso.getProfileURL()) != null) { - _writer.println(margn2 + "ICCProfileURL: " + s); - } - int[] iarray = niso.getYCbCrSubSampling(); - if (iarray != null) { - _writer.print(margn2 + "YCbCrSubSampling: " + iarray[0]); - for (int i = 1; i < iarray.length; i++) { - _writer.print(", " + iarray[i]); - } - _writer.println(); - } - Rational[] rarray = niso.getYCbCrCoefficients(); - if (rarray != null) { - _writer.print(margn2 + "YCbCrCoefficients: " - + addRationalValue(rarray[0], rawOutput)); - for (int i = 1; i < rarray.length; i++) { - _writer.print(", " + addRationalValue(rarray[i], rawOutput)); - } - _writer.println(); - } - rarray = niso.getReferenceBlackWhite(); - if (rarray != null) { - _writer.print(margn2 + "ReferenceBlackWhite: " - + addRationalValue(rarray[0], rawOutput)); - for (int i = 1; i < rarray.length; i++) { - _writer.print(", " + addRationalValue(rarray[i], rawOutput)); - } - _writer.println(); - } - if ((s = niso.getSourceType()) != null) { - _writer.println(margn2 + "SourceType: " + s); - } - s = niso.getSourceID(); - if (s != null) { - _writer.println(margn2 + "SourceID" + s); - } - double d; - if ((d = niso.getSourceXDimension()) != NisoImageMetadata.NILL) { - _writer.println(margn2 + "SourceXDimension: " + d); - } - if ((n = niso.getSourceXDimensionUnit()) != NisoImageMetadata.NULL) { - _writer.println(margn2 - + "SourceXDimensionUnit: " - + addIntegerValue(n, - NisoImageMetadata.SOURCE_DIMENSION_UNIT, rawOutput)); - } - if ((d = niso.getSourceYDimension()) != NisoImageMetadata.NILL) { - _writer.println(margn2 + "SourceYDimension: " + ln); - } - if ((n = niso.getSourceYDimensionUnit()) != NisoImageMetadata.NULL) { - _writer.println(margn2 - + "SourceYDimensionUnit: " - + addIntegerValue(n, - NisoImageMetadata.SOURCE_DIMENSION_UNIT, rawOutput)); - } - if ((s = niso.getDateTimeCreated()) != null) { - _writer.println(margn2 + "DateTimeCreated: " + s); - } - if ((s = niso.getImageProducer()) != null) { - _writer.println(margn2 + "ImageProducer: " + s); - } - if ((s = niso.getDeviceSource()) != null) { - _writer.println(margn2 + "CaptureDevice: " + s); - } - if ((s = niso.getScannerManufacturer()) != null) { - _writer.println(margn2 + "ScannerManufacturer: " + s); - } - if ((s = niso.getScannerModelName()) != null) { - _writer.println(margn2 + "ScannerModelName: " + s); - } - if ((s = niso.getScannerModelNumber()) != null) { - _writer.println(margn2 + "ScannerModelNumber: " + s); - } - if ((s = niso.getScannerModelSerialNo()) != null) { - _writer.println(margn2 + "ScannerModelSerialNo: " + s); - } - double xres = niso.getXPhysScanResolution(); - double yres = niso.getYPhysScanResolution(); - if (xres != NisoImageMetadata.NULL && yres != NisoImageMetadata.NULL) { - double res = (xres > yres ? xres : yres); - _writer.println(margn2 + "MaximumOpticalResolution: " - + Double.toString(res)); - } - if ((s = niso.getScanningSoftware()) != null) { - _writer.println(margn2 + "ScanningSoftware: " + s); - } - if ((s = niso.getScanningSoftwareVersionNo()) != null) { - _writer.println(margn2 + "ScanningSoftwareVersionNo: " + s); - } - if ((s = niso.getDigitalCameraManufacturer()) != null) { - _writer.println(margn2 + "DigitalCameraManufacturer: " + s); - } - if ((s = niso.getDigitalCameraModelName()) != null) { - _writer.println(margn2 + "DigitalCameraModelName: " + s); - } - if ((s = niso.getDigitalCameraModelNumber()) != null) { - _writer.println(margn2 + "DigitalCameraModelNumber: " + s); - } - if ((s = niso.getDigitalCameraModelSerialNo()) != null) { - _writer.println(margn2 + "DigitalCameraModelSerialNo: " + s); - } - if ((d = niso.getFNumber()) != NisoImageMetadata.NILL) { - _writer.println(margn2 + "FNumber: " + _format.format(d)); - } - if ((s = niso.getExifVersion()) != null) { - _writer.println(margn2 + "ExifVersion: " + s); - } - Rational r; - if ((r = niso.getMaxApertureValue()) != null) { - _writer.println(margn2 + "MaxApertureValue: " - + addRationalValue(r, rawOutput)); - } - if ((d = niso.getExposureTime()) != NisoImageMetadata.NILL) { - _writer.println(margn2 + "ExposureTime: " + _format.format(d)); - } - if ((n = niso.getExposureProgram()) != NisoImageMetadata.NULL) { - _writer.println(margn2 - + "ExposureProgram: " - + addIntegerValue(n, NisoImageMetadata.EXPOSURE_PROGRAM, - rawOutput)); - } - if ((r = niso.getBrightness()) != null) { - _writer.println(margn2 + "BrightnessValue: " - + addRationalValue(r, rawOutput)); - } - if ((r = niso.getExposureBias()) != null) { - _writer.println(margn2 + "ExposureBiasValue: " - + addRationalValue(r, rawOutput)); - } - double[] darray = niso.getSubjectDistance(); - if (darray != null) { - _writer.print(margn2 + "SubjectDistance: " + darray[0]); - for (int i = 1; i < darray.length; i++) { - _writer.print(", " + darray[i]); - } - _writer.println(); - } - if ((n = niso.getMeteringMode()) != NisoImageMetadata.NULL) { - _writer.println(margn2 - + "MeteringMode: " - + addIntegerValue(n, NisoImageMetadata.METERING_MODE, - rawOutput)); - } - if ((n = niso.getFlash()) != NisoImageMetadata.NULL) { - _writer.println(margn2 + "Flash: " - + addIntegerValue(n, NisoImageMetadata.FLASH, rawOutput)); - } - if ((d = niso.getFocalLength()) != NisoImageMetadata.NILL) { - _writer.println(margn2 + "FocalLength: " + d); - } - if ((r = niso.getFlashEnergy()) != null) { - _writer.println(margn2 + "FlashEnergy: " - + addRationalValue(r, rawOutput)); - } - if ((n = niso.getBackLight()) != NisoImageMetadata.NULL) { - _writer.println(margn2 - + "BackLight: " - + addIntegerValue(n, NisoImageMetadata.BACKLIGHT, rawOutput)); - } - if ((d = niso.getExposureIndex()) != NisoImageMetadata.NILL) { - _writer.println(margn2 + "ExposureIndex: " + d); - } - if ((n = niso.getAutoFocus()) != NisoImageMetadata.NULL) { - _writer.println(margn2 - + "AutoFocus: " - + addIntegerValue(n, NisoImageMetadata.AUTOFOCUS, rawOutput)); - } - if ((d = niso.getXPrintAspectRatio()) != NisoImageMetadata.NILL) { - _writer.println(margn2 + "XPrintAspectRatio: " + d); - } - if ((d = niso.getYPrintAspectRatio()) != NisoImageMetadata.NILL) { - _writer.println(margn2 + "YPrintAspectRatio: " + d); - } - if ((n = niso.getOrientation()) != NisoImageMetadata.NULL) { - _writer.println(margn2 - + "Orientation: " - + addIntegerValue(n, NisoImageMetadata.ORIENTATION, - rawOutput)); - } - if ((s = niso.getMethodology()) != null) { - _writer.println(margn2 + "Methodology: " + s); - } - if ((n = niso.getSamplingFrequencyPlane()) != NisoImageMetadata.NULL) { - _writer.println(margn2 - + "SamplingFrequencyPlane: " - + addIntegerValue(n, - NisoImageMetadata.SAMPLING_FREQUENCY_PLANE, - rawOutput)); - } - if ((n = niso.getSamplingFrequencyUnit()) != NisoImageMetadata.NULL) { - _writer.println(margn2 - + "SamplingFrequencyUnit: " - + addIntegerValue(n, - NisoImageMetadata.SAMPLING_FREQUENCY_UNIT, - rawOutput)); - } - r = niso.getXSamplingFrequency(); - if (r != null) { - _writer.println(margn2 + "XSamplingFrequency: " - + addRationalValue(r, rawOutput)); - - } - r = niso.getYSamplingFrequency(); - if (r != null) { - _writer.println(margn2 + "YSamplingFrequency: " - + addRationalValue(r, rawOutput)); - } - if ((iarray = niso.getBitsPerSample()) != null) { - _writer.print(margn2 + "BitsPerSample: " + iarray[0]); - for (int i = 1; i < iarray.length; i++) { - _writer.print(", " + iarray[i]); - } - _writer.println(); - _writer.println(margn2 + "BitsPerSampleUnit: integer"); - } - if ((n = niso.getSamplesPerPixel()) != NisoImageMetadata.NULL) { - _writer.println(margn2 + "SamplesPerPixel: " + n); - } - if ((iarray = niso.getExtraSamples()) != null) { - _writer.print(margn2 - + "ExtraSamples: " - + addIntegerValue(iarray[0], - NisoImageMetadata.EXTRA_SAMPLES, rawOutput)); - for (int i = 1; i < iarray.length; i++) { - _writer.print(", " - + addIntegerValue(iarray[i], - NisoImageMetadata.EXTRA_SAMPLES, rawOutput)); - } - _writer.println(); - } - if ((s = niso.getColormapReference()) != null) { - _writer.println(margn2 + "ColormapReference: " + s); - } - // The MIX 1.0 schema requires the letter "N" as the value of the - // gray response curve, which is clearly a bug. We deviate from - // the bug here. - if ((iarray = niso.getGrayResponseCurve()) != null) { - _writer.print(margn2 + "GrayResponseCurve: " + iarray[0]); - for (int i = 1; i < iarray.length; i++) { - _writer.print(", " + iarray[i]); - } - _writer.println(); - } - if ((n = niso.getGrayResponseUnit()) != NisoImageMetadata.NULL) { - _writer.println(margn2 - + "GrayResponseUnit: " - + addIntegerValue(n, - NisoImageMetadata.GRAY_RESPONSE_UNIT_02, rawOutput)); - } - r = niso.getWhitePointXValue(); - if (r != null) { - _writer.println(margn2 + "WhitePointXValue: " - + addRationalValue(r, rawOutput)); - } - if ((r = niso.getWhitePointYValue()) != null) { - _writer.println(margn2 + "WhitePointXValue: " - + addRationalValue(r, rawOutput)); - } - if ((r = niso.getPrimaryChromaticitiesRedX()) != null) { - _writer.println(margn2 + "PrimaryChromaticitiesRedX: " - + addRationalValue(r, rawOutput)); - } - if ((r = niso.getPrimaryChromaticitiesRedY()) != null) { - _writer.println(margn2 + "PrimaryChromaticitiesRedY: " - + addRationalValue(r, rawOutput)); - } - if ((r = niso.getPrimaryChromaticitiesGreenX()) != null) { - _writer.println(margn2 + "PrimaryChromaticitiesGreenX: " - + addRationalValue(r, rawOutput)); - } - if ((r = niso.getPrimaryChromaticitiesGreenY()) != null) { - _writer.println(margn2 + "PrimaryChromaticitiesGreenY: " - + addRationalValue(r, rawOutput)); - } - if ((r = niso.getPrimaryChromaticitiesBlueX()) != null) { - _writer.println(margn2 + "PrimaryChromaticitiesBlueX: " - + addRationalValue(r, rawOutput)); - } - if ((r = niso.getPrimaryChromaticitiesBlueY()) != null) { - _writer.println(margn2 + "PrimaryChromaticitiesBlueY: " - + addRationalValue(r, rawOutput)); - } - if ((n = niso.getTargetType()) != NisoImageMetadata.NULL) { - _writer.println(margn2 - + "TargetType: " - + addIntegerValue(n, NisoImageMetadata.TARGET_TYPE, - rawOutput)); - } - if ((s = niso.getTargetIDManufacturer()) != null) { - _writer.println(margn2 + "TargetIDManufacturer: " + s); - } - if ((s = niso.getTargetIDName()) != null) { - _writer.println(margn2 + "TargetIDName: " + s); - } - if ((s = niso.getTargetIDNo()) != null) { - _writer.println(margn2 + "TargetIDNo: " + s); - } - if ((s = niso.getTargetIDMedia()) != null) { - _writer.println(margn2 + "TargetIDMedia: " + s); - } - if ((s = niso.getImageData()) != null) { - _writer.println(margn2 + "ExternalTarget: " + s); - } - if ((s = niso.getPerformanceData()) != null) { - _writer.println(margn2 + "PerformanceData: " + s); - } - if ((s = niso.getSourceData()) != null) { - _writer.println(margn2 + "SourceData: " + s); - } - if ((s = niso.getProcessingAgency()) != null) { - _writer.println(margn2 + "ProcessingAgency: " + s); - } - if ((s = niso.getProcessingSoftwareName()) != null) { - _writer.println(margn2 + "ProcessingSoftwareName: " + s); - } - if ((s = niso.getProcessingSoftwareVersion()) != null) { - _writer.println(margn2 + "ProcessingSoftwareVersion: " + s); - } - if ((s = niso.getOS()) != null) { - _writer.println(margn2 + "OperatingSystem: " + s); - } - if ((s = niso.getOSVersion()) != null) { - _writer.println(margn2 + "OSVersion: " + s); - } - String[] sarray = niso.getProcessingActions(); - if (sarray != null) { - _writer.print(margn2 + "ProcessingActions: " + sarray[0]); - for (int i = 1; i < sarray.length; i++) { - _writer.print(", " + sarray[i]); - } - _writer.println(); - } - - } - - private String addIntegerValue(int value, String[] labels, boolean rawOutput) { - String s = null; - if (!rawOutput && 0 <= value && value < labels.length) { - s = labels[value]; - } else { - s = Integer.toString(value); - } - - return s; - } - - private String addIntegerValue(int value, String[] labels, int[] index, - boolean rawOutput) { - String s = null; - boolean outOfRange = false; - if (!rawOutput) { - int n = -1; - for (int i = 0; i < index.length; i++) { - if (value == index[i]) { - n = i; - break; - } - } - if (n > -1) { - s = labels[n]; - } else { - outOfRange = true; - } - } - if (rawOutput || outOfRange) { - s = Integer.toString(value); - } - - return s; - } - - private String addRationalValue(Rational r, boolean rawOutput) { - String s = null; - if (!rawOutput) { - s = _format.format(r.toDouble()); - } else { - s = r.toString(); - } - - return s; - } + /* + * Output the Niso image metadata, which is its own special kind of + * property. This provides a text approximation to MIX 0.2. + */ + private void showNisoImageMetadata02(NisoImageMetadata niso, String margin, + boolean rawOutput) { + String margn2 = margin + " "; + + _writer.println(); + String s = niso.getMimeType(); + if (s != null) { + _writer.println(margn2 + "MIMEType: " + s); + } + if ((s = niso.getByteOrder()) != null) { + _writer.println(margn2 + "ByteOrder: " + s); + } + int n = niso.getCompressionScheme(); + if (n != NisoImageMetadata.NULL) { + _writer.println(margn2 + + "CompressionScheme: " + + addIntegerValue(n, NisoImageMetadata.COMPRESSION_SCHEME, + NisoImageMetadata.COMPRESSION_SCHEME_INDEX, + rawOutput)); + } + if ((n = niso.getCompressionLevel()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + "CompressionLevel: " + n); + } + if ((n = niso.getColorSpace()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + + "ColorSpace: " + + addIntegerValue(n, NisoImageMetadata.COLORSPACE, + NisoImageMetadata.COLORSPACE_INDEX, rawOutput)); + } + if ((s = niso.getProfileName()) != null) { + _writer.println(margn2 + "ProfileName: " + s); + } + if ((s = niso.getProfileURL()) != null) { + _writer.println(margn2 + "ProfileURL: " + s); + } + int[] iarray = niso.getYCbCrSubSampling(); + if (iarray != null) { + _writer.print(margn2 + "YCbCrSubSampling: " + iarray[0]); + for (int i = 1; i < iarray.length; i++) { + _writer.print(", " + iarray[i]); + } + _writer.println(); + } + if ((n = niso.getYCbCrPositioning()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + + "YCbCrPositioning: " + + addIntegerValue(n, NisoImageMetadata.YCBCR_POSITIONING, + rawOutput)); + } + Rational[] rarray = niso.getYCbCrCoefficients(); + if (rarray != null) { + _writer.print(margn2 + "YCbCrCoefficients: " + + addRationalValue(rarray[0], rawOutput)); + for (int i = 1; i < rarray.length; i++) { + _writer.print(", " + addRationalValue(rarray[i], rawOutput)); + } + _writer.println(); + } + rarray = niso.getReferenceBlackWhite(); + if (rarray != null) { + _writer.print(margn2 + "ReferenceBlackWhite: " + + addRationalValue(rarray[0], rawOutput)); + for (int i = 1; i < rarray.length; i++) { + _writer.print(", " + addRationalValue(rarray[i], rawOutput)); + } + _writer.println(); + } + if ((n = niso.getSegmentType()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + + "SegmentType: " + + addIntegerValue(n, NisoImageMetadata.SEGMENT_TYPE, + rawOutput)); + } + long[] larray = niso.getStripOffsets(); + if (larray != null) { + _writer.print(margn2 + "StripOffsets: " + larray[0]); + for (int i = 1; i < larray.length; i++) { + _writer.print(", " + larray[i]); + } + _writer.println(); + } + long ln = niso.getRowsPerStrip(); + if (ln != NisoImageMetadata.NULL) { + _writer.println(margn2 + "RowsPerStrip: " + ln); + } + if ((larray = niso.getStripByteCounts()) != null) { + _writer.print(margn2 + "StripByteCounts: " + larray[0]); + for (int i = 1; i < larray.length; i++) { + _writer.print(", " + larray[i]); + } + _writer.println(); + } + if ((ln = niso.getTileWidth()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + "TileWidth: " + ln); + } + if ((ln = niso.getTileLength()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + "TileLength: " + ln); + } + if ((larray = niso.getTileOffsets()) != null) { + _writer.print(margn2 + "TileOffsets: " + larray[0]); + for (int i = 1; i < larray.length; i++) { + _writer.print(", " + larray[i]); + } + _writer.println(); + } + if ((larray = niso.getTileByteCounts()) != null) { + _writer.print(margn2 + "TileByteCounts: " + larray[0]); + for (int i = 1; i < larray.length; i++) { + _writer.print(", " + larray[i]); + } + _writer.println(); + } + if ((n = niso.getPlanarConfiguration()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + + "PlanarConfiguration: " + + addIntegerValue(n, + NisoImageMetadata.PLANAR_CONFIGURATION, rawOutput)); + } + if ((s = niso.getImageIdentifier()) != null) { + _writer.println(margn2 + "ImageIdentifier: " + s); + } + if ((s = niso.getImageIdentifierLocation()) != null) { + _writer.println(margn2 + "ImageIdentifierLocation: " + s); + } + if ((ln = niso.getFileSize()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + "FileSize: " + ln); + } + if ((n = niso.getChecksumMethod()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + + "ChecksumMethod: " + + addIntegerValue(n, NisoImageMetadata.CHECKSUM_METHOD, + rawOutput)); + } + if ((s = niso.getChecksumValue()) != null) { + _writer.println(margn2 + "ChecksumValue: " + s); + } + if ((n = niso.getOrientation()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + + "Orientation: " + + addIntegerValue(n, NisoImageMetadata.ORIENTATION, + rawOutput)); + } + if ((n = niso.getDisplayOrientation()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + + "DisplayOrientation: " + + addIntegerValue(n, NisoImageMetadata.DISPLAY_ORIENTATION, + rawOutput)); + } + if ((ln = niso.getXTargetedDisplayAR()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + "XTargetedDisplayAR: " + ln); + } + if ((ln = niso.getYTargetedDisplayAR()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + "YTargetedDisplayAR: " + ln); + } + if ((s = niso.getPreferredPresentation()) != null) { + _writer.println(margn2 + "PreferredPresentation: " + s); + } + if ((s = niso.getSourceType()) != null) { + _writer.println(margn2 + "SourceType: " + s); + } + if ((s = niso.getImageProducer()) != null) { + _writer.println(margn2 + "ImageProducer: " + s); + } + if ((s = niso.getHostComputer()) != null) { + _writer.println(margn2 + "HostComputer: " + s); + } + if ((s = niso.getOS()) != null) { + _writer.println(margn2 + "OperatingSystem: " + s); + } + if ((s = niso.getOSVersion()) != null) { + _writer.println(margn2 + "OSVersion: " + s); + } + if ((s = niso.getDeviceSource()) != null) { + _writer.println(margn2 + "DeviceSource: " + s); + } + if ((s = niso.getScannerManufacturer()) != null) { + _writer.println(margn2 + "ScannerManufacturer: " + s); + } + if ((s = niso.getScannerModelName()) != null) { + _writer.println(margn2 + "ScannerModelName: " + s); + } + if ((s = niso.getScannerModelNumber()) != null) { + _writer.println(margn2 + "ScannerModelNumber: " + s); + } + if ((s = niso.getScannerModelSerialNo()) != null) { + _writer.println(margn2 + "ScannerModelSerialNo: " + s); + } + if ((s = niso.getScanningSoftware()) != null) { + _writer.println(margn2 + "ScanningSoftware: " + s); + } + if ((s = niso.getScanningSoftwareVersionNo()) != null) { + _writer.println(margn2 + "ScanningSoftwareVersionNo: " + s); + } + double d = niso.getPixelSize(); + if (d != NisoImageMetadata.NILL) { + _writer.println(margn2 + "PixelSize: " + d); + } + if ((d = niso.getXPhysScanResolution()) != NisoImageMetadata.NILL) { + _writer.println(margn2 + "XPhysScanResolution: " + d); + } + if ((d = niso.getYPhysScanResolution()) != NisoImageMetadata.NILL) { + _writer.println(margn2 + "YPhysScanResolution: " + d); + } + + if ((s = niso.getDigitalCameraManufacturer()) != null) { + _writer.println(margn2 + "DigitalCameraManufacturer: " + s); + } + if ((s = niso.getDigitalCameraModelName()) != null) { + _writer.println(margn2 + "DigitalCameraModelName: " + s); + } + if ((s = niso.getDigitalCameraModelNumber()) != null) { + _writer.println(margn2 + "DigitalCameraModelNumber: " + s); + } + if ((s = niso.getDigitalCameraModelSerialNo()) != null) { + _writer.println(margn2 + "DigitalCameraModelSerialNo: " + s); + } + if ((d = niso.getFNumber()) != NisoImageMetadata.NILL) { + _writer.println(margn2 + "FNumber: " + d); + } + if ((d = niso.getExposureTime()) != NisoImageMetadata.NILL) { + _writer.println(margn2 + "ExposureTime: " + d); + } + Rational r; + if ((r = niso.getBrightness()) != null) { + d = r.toDouble(); + _writer.println(margn2 + "Brightness: " + d); + } + if ((r = niso.getExposureBias()) != null) { + d = r.toDouble(); + _writer.println(margn2 + "ExposureBias: " + d); + } + + double[] darray = niso.getSubjectDistance(); + if (darray != null) { + _writer.print(margn2 + "SubjectDistance: " + darray[0]); + for (int i = 1; i < darray.length; i++) { + _writer.print(", " + darray[i]); + } + _writer.println(); + } + if ((n = niso.getMeteringMode()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + + "MeteringMode: " + + addIntegerValue(n, NisoImageMetadata.METERING_MODE, + rawOutput)); + } + if ((n = niso.getSceneIlluminant()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + + "SceneIlluminant: " + + addIntegerValue(n, NisoImageMetadata.METERING_MODE, + rawOutput)); + } + if ((d = niso.getColorTemp()) != NisoImageMetadata.NILL) { + _writer.println(margn2 + "ColorTemp: " + d); + } + if ((d = niso.getFocalLength()) != NisoImageMetadata.NILL) { + _writer.println(margn2 + "FocalLength: " + d); + } + if ((n = niso.getFlash()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + "Flash: " + + addIntegerValue(n, NisoImageMetadata.FLASH, rawOutput)); + } + if ((r = niso.getFlashEnergy()) != null) { + d = r.toDouble(); + _writer.println(margn2 + "FlashEnergy: " + d); + } + if ((n = niso.getFlashReturn()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + + "FlashReturn: " + + addIntegerValue(n, NisoImageMetadata.FLASH_RETURN, + rawOutput)); + } + if ((n = niso.getBackLight()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + + "BackLight: " + + addIntegerValue(n, NisoImageMetadata.BACKLIGHT, rawOutput)); + } + if ((d = niso.getExposureIndex()) != NisoImageMetadata.NILL) { + _writer.println(margn2 + "ExposureIndex: " + d); + } + if ((n = niso.getAutoFocus()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + + "AutoFocus: " + + addIntegerValue(n, NisoImageMetadata.AUTOFOCUS, rawOutput)); + } + if ((d = niso.getXPrintAspectRatio()) != NisoImageMetadata.NILL) { + _writer.println(margn2 + "XPrintAspectRatio: " + d); + } + if ((d = niso.getYPrintAspectRatio()) != NisoImageMetadata.NILL) { + _writer.println(margn2 + "YPrintAspectRatio: " + d); + } + + if ((n = niso.getSensor()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + "Sensor: " + + addIntegerValue(n, NisoImageMetadata.SENSOR, rawOutput)); + } + if ((s = niso.getDateTimeCreated()) != null) { + _writer.println(margn2 + "DateTimeCreated: " + s); + } + if ((s = niso.getMethodology()) != null) { + _writer.println(margn2 + "Methodology: " + s); + } + if ((n = niso.getSamplingFrequencyPlane()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + + "SamplingFrequencyPlane: " + + addIntegerValue(n, + NisoImageMetadata.SAMPLING_FREQUENCY_PLANE, + rawOutput)); + } + if ((n = niso.getSamplingFrequencyUnit()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + + "SamplingFrequencyUnit: " + + addIntegerValue(n, + NisoImageMetadata.SAMPLING_FREQUENCY_UNIT, + rawOutput)); + } + r = niso.getXSamplingFrequency(); + if (r != null) { + _writer.println(margn2 + "XSamplingFrequency: " + + addRationalValue(r, rawOutput)); + + } + r = niso.getYSamplingFrequency(); + if (r != null) { + _writer.println(margn2 + "YSamplingFrequency: " + + addRationalValue(r, rawOutput)); + } + if ((ln = niso.getImageWidth()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + "ImageWidth: " + ln); + } + if ((ln = niso.getImageLength()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + "ImageLength: " + ln); + } + if ((d = niso.getSourceXDimension()) != NisoImageMetadata.NILL) { + _writer.println(margn2 + "SourceXDimension: " + d); + } + if ((n = niso.getSourceXDimensionUnit()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + + "SourceXDimensionUnit: " + + addIntegerValue(n, + NisoImageMetadata.SOURCE_DIMENSION_UNIT, rawOutput)); + } + if ((d = niso.getSourceYDimension()) != NisoImageMetadata.NILL) { + _writer.println(margn2 + "SourceYDimension: " + ln); + } + if ((n = niso.getSourceYDimensionUnit()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + + "SourceYDimensionUnit: " + + addIntegerValue(n, + NisoImageMetadata.SOURCE_DIMENSION_UNIT, rawOutput)); + } + if ((iarray = niso.getBitsPerSample()) != null) { + _writer.print(margn2 + "BitsPerSample: " + iarray[0]); + for (int i = 1; i < iarray.length; i++) { + _writer.print(", " + iarray[i]); + } + _writer.println(); + } + if ((n = niso.getSamplesPerPixel()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + "SamplesPerPixel: " + n); + } + if ((iarray = niso.getExtraSamples()) != null) { + _writer.print(margn2 + + "ExtraSamples: " + + addIntegerValue(iarray[0], + NisoImageMetadata.EXTRA_SAMPLES, rawOutput)); + for (int i = 1; i < iarray.length; i++) { + _writer.print(", " + + addIntegerValue(iarray[i], + NisoImageMetadata.EXTRA_SAMPLES, rawOutput)); + } + _writer.println(); + } + if ((s = niso.getColormapReference()) != null) { + _writer.println(margn2 + "ColormapReference: " + s); + } + if ((iarray = niso.getColormapBitCodeValue()) != null) { + _writer.print(margn2 + "ColormapBitCodeValue: " + iarray[0]); + for (int i = 1; i < iarray.length; i++) { + _writer.print(", " + iarray[i]); + } + _writer.println(); + } + if ((iarray = niso.getColormapRedValue()) != null) { + _writer.print(margn2 + "ColormapRedValue: " + iarray[0]); + for (int i = 1; i < iarray.length; i++) { + _writer.print(", " + iarray[i]); + } + _writer.println(); + } + if ((iarray = niso.getColormapGreenValue()) != null) { + _writer.print(margn2 + "ColormapGreenValue: " + iarray[0]); + for (int i = 1; i < iarray.length; i++) { + _writer.print(", " + iarray[i]); + } + _writer.println(); + } + if ((iarray = niso.getColormapBlueValue()) != null) { + _writer.print(margn2 + "ColormapBlueValue: " + iarray[0]); + for (int i = 1; i < iarray.length; i++) { + _writer.print(", " + iarray[i]); + } + _writer.println(); + } + if ((iarray = niso.getGrayResponseCurve()) != null) { + _writer.print(margn2 + "GrayResponseCurve: " + iarray[0]); + for (int i = 1; i < iarray.length; i++) { + _writer.print(", " + iarray[i]); + } + _writer.println(); + } + if ((n = niso.getGrayResponseUnit()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + + "GrayResponseUnit: " + + addIntegerValue(n, + NisoImageMetadata.GRAY_RESPONSE_UNIT_02, rawOutput)); + } + r = niso.getWhitePointXValue(); + if (r != null) { + _writer.println(margn2 + "WhitePointXValue: " + + addRationalValue(r, rawOutput)); + } + if ((r = niso.getWhitePointYValue()) != null) { + _writer.println(margn2 + "WhitePointXValue: " + + addRationalValue(r, rawOutput)); + } + if ((r = niso.getPrimaryChromaticitiesRedX()) != null) { + _writer.println(margn2 + "PrimaryChromaticitiesRedX: " + + addRationalValue(r, rawOutput)); + } + if ((r = niso.getPrimaryChromaticitiesRedY()) != null) { + _writer.println(margn2 + "PrimaryChromaticitiesRedY: " + + addRationalValue(r, rawOutput)); + } + if ((r = niso.getPrimaryChromaticitiesGreenX()) != null) { + _writer.println(margn2 + "PrimaryChromaticitiesGreenX: " + + addRationalValue(r, rawOutput)); + } + if ((r = niso.getPrimaryChromaticitiesGreenY()) != null) { + _writer.println(margn2 + "PrimaryChromaticitiesGreenY: " + + addRationalValue(r, rawOutput)); + } + if ((r = niso.getPrimaryChromaticitiesBlueX()) != null) { + _writer.println(margn2 + "PrimaryChromaticitiesBlueX: " + + addRationalValue(r, rawOutput)); + } + if ((r = niso.getPrimaryChromaticitiesBlueY()) != null) { + _writer.println(margn2 + "PrimaryChromaticitiesBlueY: " + + addRationalValue(r, rawOutput)); + } + if ((n = niso.getTargetType()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + + "TargetType: " + + addIntegerValue(n, NisoImageMetadata.TARGET_TYPE, + rawOutput)); + } + if ((s = niso.getTargetIDManufacturer()) != null) { + _writer.println(margn2 + "TargetIDManufacturer: " + s); + } + if ((s = niso.getTargetIDName()) != null) { + _writer.println(margn2 + "TargetIDName: " + s); + } + if ((s = niso.getTargetIDNo()) != null) { + _writer.println(margn2 + "TargetIDNo: " + s); + } + if ((s = niso.getTargetIDMedia()) != null) { + _writer.println(margn2 + "TargetIDMedia: " + s); + } + if ((s = niso.getImageData()) != null) { + _writer.println(margn2 + "ImageData: " + s); + } + if ((s = niso.getPerformanceData()) != null) { + _writer.println(margn2 + "PerformanceData: " + s); + } + if ((s = niso.getProfiles()) != null) { + _writer.println(margn2 + "Profiles: " + s); + } + if ((s = niso.getDateTimeProcessed()) != null) { + _writer.println(margn2 + "DateTimeProcessed: " + s); + } + if ((s = niso.getSourceData()) != null) { + _writer.println(margn2 + "SourceData: " + s); + } + if ((s = niso.getProcessingAgency()) != null) { + _writer.println(margn2 + "ProcessingAgency: " + s); + } + if ((s = niso.getProcessingSoftwareName()) != null) { + _writer.println(margn2 + "ProcessingSoftwareName: " + s); + } + if ((s = niso.getProcessingSoftwareVersion()) != null) { + _writer.println(margn2 + "ProcessingSoftwareVersion: " + s); + } + String[] sarray = niso.getProcessingActions(); + if (sarray != null) { + _writer.print(margn2 + "ProcessingActions: " + sarray[0]); + for (int i = 1; i < sarray.length; i++) { + _writer.print(", " + sarray[i]); + } + _writer.println(); + } + + } + + private void showNisoImageMetadata10(NisoImageMetadata niso, String margin, + boolean rawOutput) { + String margn2 = margin + " "; + String s; + long ln; + _writer.println(); + if ((s = niso.getImageIdentifier()) != null) { + _writer.println(margn2 + "ImageIdentifier: " + s); + } + if ((ln = niso.getFileSize()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + "FileSize: " + ln); + } + if ((s = niso.getMimeType()) != null) { + _writer.println(margn2 + "FormatName: " + s); + } + if ((s = niso.getByteOrder()) != null) { + // Convert strings to MIX 1.0 form + if (s.startsWith("big")) { + s = "big_endian"; + } else if (s.startsWith("little")) { + s = "little_endian"; + } + _writer.println(margn2 + "ByteOrder: " + s); + } + int n = niso.getCompressionScheme(); + if (n != NisoImageMetadata.NULL) { + _writer.println(margn2 + + "CompressionScheme: " + + addIntegerValue(n, NisoImageMetadata.COMPRESSION_SCHEME, + NisoImageMetadata.COMPRESSION_SCHEME_INDEX, + rawOutput)); + } + if ((n = niso.getCompressionLevel()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + "CompressionLevel: " + n); + } + if ((n = niso.getChecksumMethod()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + + "ChecksumMethod: " + + addIntegerValue(n, NisoImageMetadata.CHECKSUM_METHOD, + rawOutput)); + } + if ((s = niso.getChecksumValue()) != null) { + _writer.println(margn2 + "ChecksumValue: " + s); + } + if ((ln = niso.getImageWidth()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + "ImageWidth: " + ln); + } + if ((ln = niso.getImageLength()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + "ImageHeight: " + ln); + } + if ((n = niso.getColorSpace()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + + "ColorSpace: " + + addIntegerValue(n, NisoImageMetadata.COLORSPACE, + NisoImageMetadata.COLORSPACE_INDEX, rawOutput)); + } + if ((s = niso.getProfileName()) != null) { + _writer.println(margn2 + "ICCProfileName: " + s); + } + if ((s = niso.getProfileURL()) != null) { + _writer.println(margn2 + "ICCProfileURL: " + s); + } + int[] iarray = niso.getYCbCrSubSampling(); + if (iarray != null) { + _writer.print(margn2 + "YCbCrSubSampling: " + iarray[0]); + for (int i = 1; i < iarray.length; i++) { + _writer.print(", " + iarray[i]); + } + _writer.println(); + } + Rational[] rarray = niso.getYCbCrCoefficients(); + if (rarray != null) { + _writer.print(margn2 + "YCbCrCoefficients: " + + addRationalValue(rarray[0], rawOutput)); + for (int i = 1; i < rarray.length; i++) { + _writer.print(", " + addRationalValue(rarray[i], rawOutput)); + } + _writer.println(); + } + rarray = niso.getReferenceBlackWhite(); + if (rarray != null) { + _writer.print(margn2 + "ReferenceBlackWhite: " + + addRationalValue(rarray[0], rawOutput)); + for (int i = 1; i < rarray.length; i++) { + _writer.print(", " + addRationalValue(rarray[i], rawOutput)); + } + _writer.println(); + } + if ((s = niso.getSourceType()) != null) { + _writer.println(margn2 + "SourceType: " + s); + } + s = niso.getSourceID(); + if (s != null) { + _writer.println(margn2 + "SourceID" + s); + } + double d; + if ((d = niso.getSourceXDimension()) != NisoImageMetadata.NILL) { + _writer.println(margn2 + "SourceXDimension: " + d); + } + if ((n = niso.getSourceXDimensionUnit()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + + "SourceXDimensionUnit: " + + addIntegerValue(n, + NisoImageMetadata.SOURCE_DIMENSION_UNIT, rawOutput)); + } + if ((d = niso.getSourceYDimension()) != NisoImageMetadata.NILL) { + _writer.println(margn2 + "SourceYDimension: " + ln); + } + if ((n = niso.getSourceYDimensionUnit()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + + "SourceYDimensionUnit: " + + addIntegerValue(n, + NisoImageMetadata.SOURCE_DIMENSION_UNIT, rawOutput)); + } + if ((s = niso.getDateTimeCreated()) != null) { + _writer.println(margn2 + "DateTimeCreated: " + s); + } + if ((s = niso.getImageProducer()) != null) { + _writer.println(margn2 + "ImageProducer: " + s); + } + if ((s = niso.getDeviceSource()) != null) { + _writer.println(margn2 + "CaptureDevice: " + s); + } + if ((s = niso.getScannerManufacturer()) != null) { + _writer.println(margn2 + "ScannerManufacturer: " + s); + } + if ((s = niso.getScannerModelName()) != null) { + _writer.println(margn2 + "ScannerModelName: " + s); + } + if ((s = niso.getScannerModelNumber()) != null) { + _writer.println(margn2 + "ScannerModelNumber: " + s); + } + if ((s = niso.getScannerModelSerialNo()) != null) { + _writer.println(margn2 + "ScannerModelSerialNo: " + s); + } + double xres = niso.getXPhysScanResolution(); + double yres = niso.getYPhysScanResolution(); + if (xres != NisoImageMetadata.NULL && yres != NisoImageMetadata.NULL) { + double res = (xres > yres ? xres : yres); + _writer.println(margn2 + "MaximumOpticalResolution: " + + Double.toString(res)); + } + if ((s = niso.getScanningSoftware()) != null) { + _writer.println(margn2 + "ScanningSoftware: " + s); + } + if ((s = niso.getScanningSoftwareVersionNo()) != null) { + _writer.println(margn2 + "ScanningSoftwareVersionNo: " + s); + } + if ((s = niso.getDigitalCameraManufacturer()) != null) { + _writer.println(margn2 + "DigitalCameraManufacturer: " + s); + } + if ((s = niso.getDigitalCameraModelName()) != null) { + _writer.println(margn2 + "DigitalCameraModelName: " + s); + } + if ((s = niso.getDigitalCameraModelNumber()) != null) { + _writer.println(margn2 + "DigitalCameraModelNumber: " + s); + } + if ((s = niso.getDigitalCameraModelSerialNo()) != null) { + _writer.println(margn2 + "DigitalCameraModelSerialNo: " + s); + } + if ((d = niso.getFNumber()) != NisoImageMetadata.NILL) { + _writer.println(margn2 + "FNumber: " + _format.format(d)); + } + if ((s = niso.getExifVersion()) != null) { + _writer.println(margn2 + "ExifVersion: " + s); + } + Rational r; + if ((r = niso.getMaxApertureValue()) != null) { + _writer.println(margn2 + "MaxApertureValue: " + + addRationalValue(r, rawOutput)); + } + if ((d = niso.getExposureTime()) != NisoImageMetadata.NILL) { + _writer.println(margn2 + "ExposureTime: " + _format.format(d)); + } + if ((n = niso.getExposureProgram()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + + "ExposureProgram: " + + addIntegerValue(n, NisoImageMetadata.EXPOSURE_PROGRAM, + rawOutput)); + } + if ((r = niso.getBrightness()) != null) { + _writer.println(margn2 + "BrightnessValue: " + + addRationalValue(r, rawOutput)); + } + if ((r = niso.getExposureBias()) != null) { + _writer.println(margn2 + "ExposureBiasValue: " + + addRationalValue(r, rawOutput)); + } + double[] darray = niso.getSubjectDistance(); + if (darray != null) { + _writer.print(margn2 + "SubjectDistance: " + darray[0]); + for (int i = 1; i < darray.length; i++) { + _writer.print(", " + darray[i]); + } + _writer.println(); + } + if ((n = niso.getMeteringMode()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + + "MeteringMode: " + + addIntegerValue(n, NisoImageMetadata.METERING_MODE, + rawOutput)); + } + if ((n = niso.getFlash()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + "Flash: " + + addIntegerValue(n, NisoImageMetadata.FLASH, rawOutput)); + } + if ((d = niso.getFocalLength()) != NisoImageMetadata.NILL) { + _writer.println(margn2 + "FocalLength: " + d); + } + if ((r = niso.getFlashEnergy()) != null) { + _writer.println(margn2 + "FlashEnergy: " + + addRationalValue(r, rawOutput)); + } + if ((n = niso.getBackLight()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + + "BackLight: " + + addIntegerValue(n, NisoImageMetadata.BACKLIGHT, rawOutput)); + } + if ((d = niso.getExposureIndex()) != NisoImageMetadata.NILL) { + _writer.println(margn2 + "ExposureIndex: " + d); + } + if ((n = niso.getAutoFocus()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + + "AutoFocus: " + + addIntegerValue(n, NisoImageMetadata.AUTOFOCUS, rawOutput)); + } + if ((d = niso.getXPrintAspectRatio()) != NisoImageMetadata.NILL) { + _writer.println(margn2 + "XPrintAspectRatio: " + d); + } + if ((d = niso.getYPrintAspectRatio()) != NisoImageMetadata.NILL) { + _writer.println(margn2 + "YPrintAspectRatio: " + d); + } + if ((n = niso.getOrientation()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + + "Orientation: " + + addIntegerValue(n, NisoImageMetadata.ORIENTATION, + rawOutput)); + } + if ((s = niso.getMethodology()) != null) { + _writer.println(margn2 + "Methodology: " + s); + } + if ((n = niso.getSamplingFrequencyPlane()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + + "SamplingFrequencyPlane: " + + addIntegerValue(n, + NisoImageMetadata.SAMPLING_FREQUENCY_PLANE, + rawOutput)); + } + if ((n = niso.getSamplingFrequencyUnit()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + + "SamplingFrequencyUnit: " + + addIntegerValue(n, + NisoImageMetadata.SAMPLING_FREQUENCY_UNIT, + rawOutput)); + } + r = niso.getXSamplingFrequency(); + if (r != null) { + _writer.println(margn2 + "XSamplingFrequency: " + + addRationalValue(r, rawOutput)); + + } + r = niso.getYSamplingFrequency(); + if (r != null) { + _writer.println(margn2 + "YSamplingFrequency: " + + addRationalValue(r, rawOutput)); + } + if ((iarray = niso.getBitsPerSample()) != null) { + _writer.print(margn2 + "BitsPerSample: " + iarray[0]); + for (int i = 1; i < iarray.length; i++) { + _writer.print(", " + iarray[i]); + } + _writer.println(); + _writer.println(margn2 + "BitsPerSampleUnit: integer"); + } + if ((n = niso.getSamplesPerPixel()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + "SamplesPerPixel: " + n); + } + if ((iarray = niso.getExtraSamples()) != null) { + _writer.print(margn2 + + "ExtraSamples: " + + addIntegerValue(iarray[0], + NisoImageMetadata.EXTRA_SAMPLES, rawOutput)); + for (int i = 1; i < iarray.length; i++) { + _writer.print(", " + + addIntegerValue(iarray[i], + NisoImageMetadata.EXTRA_SAMPLES, rawOutput)); + } + _writer.println(); + } + if ((s = niso.getColormapReference()) != null) { + _writer.println(margn2 + "ColormapReference: " + s); + } + // The MIX 1.0 schema requires the letter "N" as the value of the + // gray response curve, which is clearly a bug. We deviate from + // the bug here. + if ((iarray = niso.getGrayResponseCurve()) != null) { + _writer.print(margn2 + "GrayResponseCurve: " + iarray[0]); + for (int i = 1; i < iarray.length; i++) { + _writer.print(", " + iarray[i]); + } + _writer.println(); + } + if ((n = niso.getGrayResponseUnit()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + + "GrayResponseUnit: " + + addIntegerValue(n, + NisoImageMetadata.GRAY_RESPONSE_UNIT_02, rawOutput)); + } + r = niso.getWhitePointXValue(); + if (r != null) { + _writer.println(margn2 + "WhitePointXValue: " + + addRationalValue(r, rawOutput)); + } + if ((r = niso.getWhitePointYValue()) != null) { + _writer.println(margn2 + "WhitePointXValue: " + + addRationalValue(r, rawOutput)); + } + if ((r = niso.getPrimaryChromaticitiesRedX()) != null) { + _writer.println(margn2 + "PrimaryChromaticitiesRedX: " + + addRationalValue(r, rawOutput)); + } + if ((r = niso.getPrimaryChromaticitiesRedY()) != null) { + _writer.println(margn2 + "PrimaryChromaticitiesRedY: " + + addRationalValue(r, rawOutput)); + } + if ((r = niso.getPrimaryChromaticitiesGreenX()) != null) { + _writer.println(margn2 + "PrimaryChromaticitiesGreenX: " + + addRationalValue(r, rawOutput)); + } + if ((r = niso.getPrimaryChromaticitiesGreenY()) != null) { + _writer.println(margn2 + "PrimaryChromaticitiesGreenY: " + + addRationalValue(r, rawOutput)); + } + if ((r = niso.getPrimaryChromaticitiesBlueX()) != null) { + _writer.println(margn2 + "PrimaryChromaticitiesBlueX: " + + addRationalValue(r, rawOutput)); + } + if ((r = niso.getPrimaryChromaticitiesBlueY()) != null) { + _writer.println(margn2 + "PrimaryChromaticitiesBlueY: " + + addRationalValue(r, rawOutput)); + } + if ((n = niso.getTargetType()) != NisoImageMetadata.NULL) { + _writer.println(margn2 + + "TargetType: " + + addIntegerValue(n, NisoImageMetadata.TARGET_TYPE, + rawOutput)); + } + if ((s = niso.getTargetIDManufacturer()) != null) { + _writer.println(margn2 + "TargetIDManufacturer: " + s); + } + if ((s = niso.getTargetIDName()) != null) { + _writer.println(margn2 + "TargetIDName: " + s); + } + if ((s = niso.getTargetIDNo()) != null) { + _writer.println(margn2 + "TargetIDNo: " + s); + } + if ((s = niso.getTargetIDMedia()) != null) { + _writer.println(margn2 + "TargetIDMedia: " + s); + } + if ((s = niso.getImageData()) != null) { + _writer.println(margn2 + "ExternalTarget: " + s); + } + if ((s = niso.getPerformanceData()) != null) { + _writer.println(margn2 + "PerformanceData: " + s); + } + if ((s = niso.getSourceData()) != null) { + _writer.println(margn2 + "SourceData: " + s); + } + if ((s = niso.getProcessingAgency()) != null) { + _writer.println(margn2 + "ProcessingAgency: " + s); + } + if ((s = niso.getProcessingSoftwareName()) != null) { + _writer.println(margn2 + "ProcessingSoftwareName: " + s); + } + if ((s = niso.getProcessingSoftwareVersion()) != null) { + _writer.println(margn2 + "ProcessingSoftwareVersion: " + s); + } + if ((s = niso.getOS()) != null) { + _writer.println(margn2 + "OperatingSystem: " + s); + } + if ((s = niso.getOSVersion()) != null) { + _writer.println(margn2 + "OSVersion: " + s); + } + String[] sarray = niso.getProcessingActions(); + if (sarray != null) { + _writer.print(margn2 + "ProcessingActions: " + sarray[0]); + for (int i = 1; i < sarray.length; i++) { + _writer.print(", " + sarray[i]); + } + _writer.println(); + } + + } + + private String addIntegerValue(int value, String[] labels, boolean rawOutput) { + String s = null; + if (!rawOutput && 0 <= value && value < labels.length) { + s = labels[value]; + } else { + s = Integer.toString(value); + } + + return s; + } + + private String addIntegerValue(int value, String[] labels, int[] index, + boolean rawOutput) { + String s = null; + boolean outOfRange = false; + if (!rawOutput) { + int n = -1; + for (int i = 0; i < index.length; i++) { + if (value == index[i]) { + n = i; + break; + } + } + if (n > -1) { + s = labels[n]; + } else { + outOfRange = true; + } + } + if (rawOutput || outOfRange) { + s = Integer.toString(value); + } + + return s; + } + + private String addRationalValue(Rational r, boolean rawOutput) { + String s = null; + if (!rawOutput) { + s = _format.format(r.toDouble()); + } else { + s = r.toString(); + } + + return s; + } } diff --git a/jhove-core/src/main/java/edu/harvard/hul/ois/jhove/handler/XmlHandler.java b/jhove-core/src/main/java/edu/harvard/hul/ois/jhove/handler/XmlHandler.java index e84b4fee3..0bd0be1bf 100644 --- a/jhove-core/src/main/java/edu/harvard/hul/ois/jhove/handler/XmlHandler.java +++ b/jhove-core/src/main/java/edu/harvard/hul/ois/jhove/handler/XmlHandler.java @@ -27,6 +27,7 @@ import java.util.ListIterator; import java.util.Locale; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import edu.harvard.hul.ois.jhove.AESAudioMetadata; @@ -83,10 +84,10 @@ protected NumberFormat initialValue() { private static final String NAME = "XML"; /** Handler release identifier. */ - private static final String RELEASE = "1.12"; + private static final String RELEASE = "1.13"; /** Handler release date. */ - private static final int[] DATE = { 2024, 8, 22 }; + private static final int[] DATE = { 2024, 11, 19 }; /** Handler informative note. */ private static final String NOTE = "This output handler is defined by the XML Schema " @@ -110,6 +111,8 @@ protected NumberFormat initialValue() { /* Sample rate. */ private double _sampleRate; + /** Reporting module */ + private String reportingModule = ""; /****************************************************************** * CLASS CONSTRUCTOR. @@ -273,35 +276,31 @@ public void show(Module module) { ; _writer.println(margn2 + elementEnd("mimeTypes")); } - List list1 = module.getSignature(); - int n = list1.size(); - if (n > 0) { + List sigList = module.getSignature(); + if (!sigList.isEmpty()) { _writer.println(margn2 + elementStart("signatures")); ++_level; - for (int i = 0; i < n; i++) { - showSignature(list1.get(i)); + for (Signature sig : sigList) { + showSignature(sig); } _level--; _writer.println(margn2 + elementEnd("signatures")); } - List list2 = module.getSpecification(); - n = list2.size(); - if (n > 0) { + List docList = module.getSpecification(); + if (!docList.isEmpty()) { _writer.println(margn2 + elementStart("specifications")); ++_level; - for (int i = 0; i < n; i++) { - showDocument(list2.get(i)); + for (Document doc : docList) { + showDocument(doc); } --_level; _writer.println(margn2 + elementEnd("specifications")); } - List ftr = module.getFeatures(); - if (ftr != null && !ftr.isEmpty()) { + List featList = module.getFeatures(); + if (featList != null && !featList.isEmpty()) { _writer.println(margn2 + elementStart("features")); - Iterator iter = ftr.iterator(); - while (iter.hasNext()) { - s = iter.next(); - _writer.println(margn3 + element("feature", s)); + for (String feat : featList) { + _writer.println(margn3 + element("feature", feat)); } _writer.println(margn2 + elementEnd("features")); } @@ -349,8 +348,9 @@ public void show(RepInfo info) { if (module != null) { String[][] attr2 = { { "release", module.getRelease() }, { "date", date.format(module.getDate()) } }; + this.reportingModule = module.getName(); _writer.println(margn2 - + element("reportingModule", attr2, module.getName())); + + element("reportingModule", attr2, this.reportingModule)); } /* * else { String [][] attr2 = { {"severity", "error"} }; _writer.println @@ -422,26 +422,24 @@ public void show(RepInfo info) { _writer.println(margn2 + element("status", wfStr)); } - List list1 = info.getSigMatch(); - int n = list1.size(); - if (n > 0) { + List sigMatches = info.getSigMatch(); + if (!sigMatches.isEmpty()) { _writer.println(margn2 + elementStart("sigMatch")); _level++; - for (int i = 0; i < n; i++) { + for (String sigMatch : sigMatches) { _writer.println(margn2 - + element("module", list1.get(i))); + + element("module", sigMatch)); } _level--; _writer.println(margn2 + elementEnd("sigMatch")); } - List list2 = info.getMessage(); - n = list2.size(); - if (n > 0) { + List messages = info.getMessage(); + if (!messages.isEmpty()) { _writer.println(margn2 + elementStart("messages")); _level++; - for (int i = 0; i < n; i++) { - showMessage(list2.get(i)); + for (Message message : messages) { + showMessage(message); } _level--; _writer.println(margn2 + elementEnd("messages")); @@ -451,38 +449,31 @@ public void show(RepInfo info) { _writer.println(margn2 + element("mimeType", s)); } - List list3 = info.getProfile(); - n = list3.size(); - if (n > 0) { + List profiles = info.getProfile(); + if (!profiles.isEmpty()) { _writer.println(margn2 + elementStart("profiles")); - for (int i = 0; i < n; i++) { + for (String profile : profiles) { _writer.println(margn3 - + element("profile", list3.get(i))); + + element("profile", profile)); } _writer.println(margn2 + elementEnd("profiles")); } Map map = info.getProperty(); - if (map != null) { - if (map.size() > 0) { - _writer.println(margn2 + elementStart("properties")); - Iterator iter = map.keySet().iterator(); - while (iter.hasNext()) { - String key = iter.next(); - Property property = info.getProperty(key); - showProperty(property); - } - _writer.println(margn2 + elementEnd("properties")); + if (map != null && !map.isEmpty()) { + _writer.println(margn2 + elementStart("properties")); + for (Entry entry : map.entrySet()) { + showProperty(entry.getValue()); } + _writer.println(margn2 + elementEnd("properties")); } - List list4 = info.getChecksum(); - n = list4.size(); - if (n > 0) { + List checksums = info.getChecksum(); + if (!checksums.isEmpty()) { _writer.println(margn2 + elementStart("checksums")); _level++; - for (int i = 0; i < n; i++) { - showChecksum(list4.get(i)); + for (Checksum checksum : checksums) { + showChecksum(checksum); } _level--; _writer.println(margn2 + elementEnd("checksums")); @@ -662,12 +653,13 @@ protected void showIdentifier(Identifier identifier) { protected void showMessage(Message message) { String margin = getIndent(++_level); - String[][] attrs = new String[4][]; + String[][] attrs = new String[5][]; boolean hasAttr = false; attrs[0] = new String[] { "subMessage", null }; attrs[1] = new String[] { "offset", null }; attrs[2] = new String[] { "severity", null }; attrs[3] = new String[] { "id", null }; + attrs[4] = new String[] { "infoLink", null }; String submsg = message.getSubMessage(); if (submsg != null) { @@ -686,8 +678,10 @@ protected void showMessage(Message message) { String id = message.getJhoveMessage().getId(); if (!(id == null || id.isEmpty() || id.equals(JhoveMessages.NO_ID))) { attrs[3][1] = message.getId(); + attrs[4][1] = Handlers.makeInfoLink(this.reportingModule, id); hasAttr = true; } + if (hasAttr) { _writer.println(margin + element("message", attrs, message.getMessage())); diff --git a/jhove-core/src/main/resources/schema.openpreservation.org/ois/xml/xsd/jhove/1.10/jhove.xsd b/jhove-core/src/main/resources/schema.openpreservation.org/ois/xml/xsd/jhove/1.10/jhove.xsd new file mode 100644 index 000000000..80f53e203 --- /dev/null +++ b/jhove-core/src/main/resources/schema.openpreservation.org/ois/xml/xsd/jhove/1.10/jhove.xsd @@ -0,0 +1,848 @@ + + + + + + + + + This is the XML Schema for the output produced by the JHOVE XML output handler. + + + + + + + The date/time at which JHOVE was invoked. + + + + + + Descriptive information about JHOVE itself. Requested by the "jhove -h xml" command. + + + + + Results of a file audit, i.e., per-file pathname, MIME type, and status information. + + + + + Descriptive information about a JHOVE output handler. Requested by the "jhove -h xml -H handler" command. + + + + + Descriptive information about a JHOVE module. Requested by the "jhove -h xml -m module" command. + + + + + Unbounded sequence of representation information elements. + + + + + + + JHOVE application name. + + + + + JHOVE release identifier: "major.minor". + + + + + JHOVE release date: "yyyy-mm-dd" + + + + + + + Descriptive information about JHOVE itself. Requested by the "jhove -h xml" command. + + + + + Optional JHOVE API information. + + + + + + + The release date for the API: "yyyy-mm-dd". + + + + + + + + + Optional configuration file pathname. + + + + + SAX parser fully-qualified class name. + + + + + JHOVE home directory pathname. + + + + + Output handler encoding. + + + + + Temporary directory pathname. + + + + + Buffer size for buffered I/O. + + + + + List of modules configured for this invocation. + + + + + + Module name, generally of the form "FORMAT-vendor". + + + + + + + The release identifier for the module. + + + + + + + + + + + + List of output handlers configued for this invocation. + + + + + + Output handler name. + + + + + + + The release identifier for the module. + + + + + + + + + + + + Command line invocation syntax. + + + + + Rights statement. + + + + + + + Results of a file audit, i.e., per-file pathname, MIME type, and status information. + + + + + Per-file informatino: pathname, MIME type, and status information. + + + + + + + The file MIME type. + + + + + The file validation status. + + + + + + + + + + + + + MD5 checksum for the file. + + + + + + + + + + Home directory from which the Audit handler was invoked. + + + + + + Descriptive information about a JHOVE output handler. Requested by the "jhove -h xml -H handler" command. + + + + + Output handler name. + + + + + Handler release identifier: "major.minor". + + + + + Handler release date: "yyyy-mm-dd". + + + + + Optional list of specification documents for the handler. + + + + + The output handler vendor. + + + + + Optional informative note about the handler. + + + + + Optional rights statement about the handler. Typically this would niclude a copyright statement of the vendor and a summary of the licesnse agreement under which the handler is release. + + + + + + + Descriptive information about a JHOVE module. Requested by the "jhove -h xml -m module" command. + + + + + Module name. + + + + + Module release identifier: "major.minor". + + + + + Module release date: "yyyy-mm-dd". + + + + + Optional list of modules formats. + + + + + + Module format + + + + + + + + Optional statement of format coverage. + + + + + Optional list of format MIME types. + + + + + + Format MIME type + + + + + + + + Optional list of signatures. + + + + + + + + + + + + + + + + + + Signature value. + + + + + Fixed byte offset of the signature + + + + + Informative note about the signature. + + + + + Use flag for the signature. + + + + + + + + + + + Optional list of specification documents. + + + + + + Format specification. + + + + + + + + List of module features: canValidate, canCharacterize, etc. + + + + + + Module feature + + + + + + + + List of methodology statements + + + + + + Statement of well-formedness criteria.. + + + + + Statement of validty criteria. + + + + + Statement of representation information properties. + + + + + + + + Optional vendor agent. + + + + + Optional informative note. + + + + + Optional rights statement. Generally this includes a copyright statement of the vendor and a summary of the license agreement under which the module is released. + + + + + + + Descriptive information about a digital object. + + + + + The module producing the representation information. + + + + + + + Release identifier for the module. + + + + + Release date for the module. + + + + + + + + + Object creation date timestamp. + + + + + Object last modified data timestemp. + + + + + Object size in bytes. + + + + + Object format. + + + + + Object version. + + + + + Object validation status. + + + + + + + + Modules with matching internal signatures. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Object MIME type. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Personal or corporate agent type. + + + + + Agent name. + + + + + Agent type. + + + + + + + + + + + + + + + Optional agent postal address. + + + + + Optional agent telephone number. + + + + + Optional agent FAX number. + + + + + Optional agent email address. + + + + + Optional agent web site URI. + + + + + + Agent role. + + + + + + + + + + + + + + + + + + + + Allow recursive structure of property types + + + + + The value element can contain a scalar actual value or additional markup from known namespaces + + + + + + + + Attribute contains the key name for key-value pairs in a Map property + + + + + + + + The arity of the property. The non-scalar arities have the semantics associated with the Java collection types of the same name. + + + + + + + + + + + + + + The type of the property. Most types have the semantics of the Java types of the same name. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Description information about a specification document. + + + + + Document title. + + + + + Document type. + + + + + + + + + + + + + + + + Optional list of authors. + + + + + + Author agent. + + + + + + + + Optional list of publishers. + + + + + + Publisher agent. + + + + + + + + Optional document edition. + + + + + Optional document edition: "yyyy[-mm[-dd]]". + + + + + + + + Optional document enumeration. + + + + + Optional document pages. + + + + + Optional list of identifiers. + + + + + + Document identifier. + + + + + + Identifier value. + + + + + Identifier type. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Optional informative note. + + + + + + + + + + + Optional informative note. + + + + + diff --git a/jhove-core/src/main/resources/schema.openpreservation.org/ois/xml/xsd/jhove/1.6/jhove.xsd b/jhove-core/src/main/resources/schema.openpreservation.org/ois/xml/xsd/jhove/1.6/jhove.xsd new file mode 100644 index 000000000..f459f5137 --- /dev/null +++ b/jhove-core/src/main/resources/schema.openpreservation.org/ois/xml/xsd/jhove/1.6/jhove.xsd @@ -0,0 +1,839 @@ + + + + + + + + + This is the XML Schema for the output produced by the JHOVE XML output handler. + + + + + + + The date/time at which JHOVE was invoked. + + + + + + Descriptive information about JHOVE itself. Requested by the "jhove -h xml" command. + + + + + Results of a file audit, i.e., per-file pathname, MIME type, and status information. + + + + + Descriptive information about a JHOVE output handler. Requested by the "jhove -h xml -H handler" command. + + + + + Descriptive information about a JHOVE module. Requested by the "jhove -h xml -m module" command. + + + + + Unbounded sequence of representation information elements. + + + + + + + JHOVE application name. + + + + + JHOVE release identifier: "major.minor". + + + + + JHOVE release date: "yyyy-mm-dd" + + + + + + + Descriptive information about JHOVE itself. Requested by the "jhove -h xml" command. + + + + + Optional JHOVE API information. + + + + + + + The release date for the API: "yyyy-mm-dd". + + + + + + + + + Optional configuration file pathname. + + + + + SAX parser fully-qualified class name. + + + + + JHOVE home directory pathname. + + + + + Output handler encoding. + + + + + Temporary directory pathname. + + + + + Buffer size for buffered I/O. + + + + + List of modules configured for this invocation. + + + + + + Module name, generally of the form "FORMAT-vendor". + + + + + + + The release identifier for the module. + + + + + + + + + + + + List of output handlers configued for this invocation. + + + + + + Output handler name. + + + + + + + The release identifier for the module. + + + + + + + + + + + + Command line invocation syntax. + + + + + Rights statement. + + + + + + + Results of a file audit, i.e., per-file pathname, MIME type, and status information. + + + + + Per-file informatino: pathname, MIME type, and status information. + + + + + + + The file MIME type. + + + + + The file validation status. + + + + + + + + + + + + + MD5 checksum for the file. + + + + + + + + + + Home directory from which the Audit handler was invoked. + + + + + + Descriptive information about a JHOVE output handler. Requested by the "jhove -h xml -H handler" command. + + + + + Output handler name. + + + + + Handler release identifier: "major.minor". + + + + + Handler release date: "yyyy-mm-dd". + + + + + Optional list of specification documents for the handler. + + + + + The output handler vendor. + + + + + Optional informative note about the handler. + + + + + Optional rights statement about the handler. Typically this would niclude a copyright statement of the vendor and a summary of the licesnse agreement under which the handler is release. + + + + + + + Descriptive information about a JHOVE module. Requested by the "jhove -h xml -m module" command. + + + + + Module name. + + + + + Module release identifier: "major.minor". + + + + + Module release date: "yyyy-mm-dd". + + + + + Optional list of modules formats. + + + + + + Module format + + + + + + + + Optional statement of format coverage. + + + + + Optional list of format MIME types. + + + + + + Format MIME type + + + + + + + + Optional list of signatures. + + + + + + + + + + + + + + + + + + Signature value. + + + + + Fixed byte offset of the signature + + + + + Informative note about the signature. + + + + + Use flag for the signature. + + + + + + + + + + + Optional list of specification documents. + + + + + + Format specification. + + + + + + + + List of module features: canValidate, canCharacterize, etc. + + + + + + Module feature + + + + + + + + List of methodology statements + + + + + + Statement of well-formedness criteria.. + + + + + Statement of validty criteria. + + + + + Statement of representation information properties. + + + + + + + + Optional vendor agent. + + + + + Optional informative note. + + + + + Optional rights statement. Generally this includes a copyright statement of the vendor and a summary of the license agreement under which the module is released. + + + + + + + Descriptive information about a digital object. + + + + + The module producing the representation information. + + + + + + + Release identifier for the module. + + + + + Release date for the module. + + + + + + + + + Object creation date timestamp. + + + + + Object last modified data timestemp. + + + + + Object size in bytes. + + + + + Object format. + + + + + Object version. + + + + + Object validation status. + + + + + + + + Modules with matching internal signatures. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Object MIME type. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Personal or corporate agent type. + + + + + Agent name. + + + + + Agent type. + + + + + + + + + + + + + + + Optional agent postal address. + + + + + Optional agent telephone number. + + + + + Optional agent FAX number. + + + + + Optional agent email address. + + + + + Optional agent web site URI. + + + + + + Agent role. + + + + + + + + + + + + + + + + + + + + Allow recursive structure of property types + + + + + The value element can contain a scalar actual value or additional markup from known namespaces + + + + + + + + + + + The arity of the property. The non-scalar arities have the semantics associated with the Java collection types of the same name. + + + + + + + + + + + + + + The type of the property. Most types have the semantics of the Java types of the same name. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Description information about a specification document. + + + + + Document title. + + + + + Document type. + + + + + + + + + + + + + + + + Optional list of authors. + + + + + + Author agent. + + + + + + + + Optional list of publishers. + + + + + + Publisher agent. + + + + + + + + Optional document edition. + + + + + Optional document edition: "yyyy[-mm[-dd]]". + + + + + + + + Optional document enumeration. + + + + + Optional document pages. + + + + + Optional list of identifiers. + + + + + + Document identifier. + + + + + + Identifier value. + + + + + Identifier type. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Optional informative note. + + + + + + + + + + + Optional informative note. + + + + + diff --git a/jhove-core/src/main/resources/schema.openpreservation.org/ois/xml/xsd/jhove/1.8/jhove.xsd b/jhove-core/src/main/resources/schema.openpreservation.org/ois/xml/xsd/jhove/1.8/jhove.xsd new file mode 100644 index 000000000..c343be1d7 --- /dev/null +++ b/jhove-core/src/main/resources/schema.openpreservation.org/ois/xml/xsd/jhove/1.8/jhove.xsd @@ -0,0 +1,841 @@ + + + + + + + + + This is the XML Schema for the output produced by the JHOVE XML output handler. + + + + + + + The date/time at which JHOVE was invoked. + + + + + + Descriptive information about JHOVE itself. Requested by the "jhove -h xml" command. + + + + + Results of a file audit, i.e., per-file pathname, MIME type, and status information. + + + + + Descriptive information about a JHOVE output handler. Requested by the "jhove -h xml -H handler" command. + + + + + Descriptive information about a JHOVE module. Requested by the "jhove -h xml -m module" command. + + + + + Unbounded sequence of representation information elements. + + + + + + + JHOVE application name. + + + + + JHOVE release identifier: "major.minor". + + + + + JHOVE release date: "yyyy-mm-dd" + + + + + + + Descriptive information about JHOVE itself. Requested by the "jhove -h xml" command. + + + + + Optional JHOVE API information. + + + + + + + The release date for the API: "yyyy-mm-dd". + + + + + + + + + Optional configuration file pathname. + + + + + SAX parser fully-qualified class name. + + + + + JHOVE home directory pathname. + + + + + Output handler encoding. + + + + + Temporary directory pathname. + + + + + Buffer size for buffered I/O. + + + + + List of modules configured for this invocation. + + + + + + Module name, generally of the form "FORMAT-vendor". + + + + + + + The release identifier for the module. + + + + + + + + + + + + List of output handlers configued for this invocation. + + + + + + Output handler name. + + + + + + + The release identifier for the module. + + + + + + + + + + + + Command line invocation syntax. + + + + + Rights statement. + + + + + + + Results of a file audit, i.e., per-file pathname, MIME type, and status information. + + + + + Per-file informatino: pathname, MIME type, and status information. + + + + + + + The file MIME type. + + + + + The file validation status. + + + + + + + + + + + + + MD5 checksum for the file. + + + + + + + + + + Home directory from which the Audit handler was invoked. + + + + + + Descriptive information about a JHOVE output handler. Requested by the "jhove -h xml -H handler" command. + + + + + Output handler name. + + + + + Handler release identifier: "major.minor". + + + + + Handler release date: "yyyy-mm-dd". + + + + + Optional list of specification documents for the handler. + + + + + The output handler vendor. + + + + + Optional informative note about the handler. + + + + + Optional rights statement about the handler. Typically this would niclude a copyright statement of the vendor and a summary of the licesnse agreement under which the handler is release. + + + + + + + Descriptive information about a JHOVE module. Requested by the "jhove -h xml -m module" command. + + + + + Module name. + + + + + Module release identifier: "major.minor". + + + + + Module release date: "yyyy-mm-dd". + + + + + Optional list of modules formats. + + + + + + Module format + + + + + + + + Optional statement of format coverage. + + + + + Optional list of format MIME types. + + + + + + Format MIME type + + + + + + + + Optional list of signatures. + + + + + + + + + + + + + + + + + + Signature value. + + + + + Fixed byte offset of the signature + + + + + Informative note about the signature. + + + + + Use flag for the signature. + + + + + + + + + + + Optional list of specification documents. + + + + + + Format specification. + + + + + + + + List of module features: canValidate, canCharacterize, etc. + + + + + + Module feature + + + + + + + + List of methodology statements + + + + + + Statement of well-formedness criteria.. + + + + + Statement of validty criteria. + + + + + Statement of representation information properties. + + + + + + + + Optional vendor agent. + + + + + Optional informative note. + + + + + Optional rights statement. Generally this includes a copyright statement of the vendor and a summary of the license agreement under which the module is released. + + + + + + + Descriptive information about a digital object. + + + + + The module producing the representation information. + + + + + + + Release identifier for the module. + + + + + Release date for the module. + + + + + + + + + Object creation date timestamp. + + + + + Object last modified data timestemp. + + + + + Object size in bytes. + + + + + Object format. + + + + + Object version. + + + + + Object validation status. + + + + + + + + Modules with matching internal signatures. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Object MIME type. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Personal or corporate agent type. + + + + + Agent name. + + + + + Agent type. + + + + + + + + + + + + + + + Optional agent postal address. + + + + + Optional agent telephone number. + + + + + Optional agent FAX number. + + + + + Optional agent email address. + + + + + Optional agent web site URI. + + + + + + Agent role. + + + + + + + + + + + + + + + + + + + + Allow recursive structure of property types + + + + + The value element can contain a scalar actual value or additional markup from known namespaces + + + + + + + + + + + The arity of the property. The non-scalar arities have the semantics associated with the Java collection types of the same name. + + + + + + + + + + + + + + The type of the property. Most types have the semantics of the Java types of the same name. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Description information about a specification document. + + + + + Document title. + + + + + Document type. + + + + + + + + + + + + + + + + Optional list of authors. + + + + + + Author agent. + + + + + + + + Optional list of publishers. + + + + + + Publisher agent. + + + + + + + + Optional document edition. + + + + + Optional document edition: "yyyy[-mm[-dd]]". + + + + + + + + Optional document enumeration. + + + + + Optional document pages. + + + + + Optional list of identifiers. + + + + + + Document identifier. + + + + + + Identifier value. + + + + + Identifier type. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Optional informative note. + + + + + + + + + + + Optional informative note. + + + + + diff --git a/jhove-core/src/main/resources/schema.openpreservation.org/ois/xml/xsd/jhove/1.9/jhove.xsd b/jhove-core/src/main/resources/schema.openpreservation.org/ois/xml/xsd/jhove/1.9/jhove.xsd new file mode 100644 index 000000000..7dcca1125 --- /dev/null +++ b/jhove-core/src/main/resources/schema.openpreservation.org/ois/xml/xsd/jhove/1.9/jhove.xsd @@ -0,0 +1,846 @@ + + + + + + + + + This is the XML Schema for the output produced by the JHOVE XML output handler. + + + + + + + The date/time at which JHOVE was invoked. + + + + + + Descriptive information about JHOVE itself. Requested by the "jhove -h xml" command. + + + + + Results of a file audit, i.e., per-file pathname, MIME type, and status information. + + + + + Descriptive information about a JHOVE output handler. Requested by the "jhove -h xml -H handler" command. + + + + + Descriptive information about a JHOVE module. Requested by the "jhove -h xml -m module" command. + + + + + Unbounded sequence of representation information elements. + + + + + + + JHOVE application name. + + + + + JHOVE release identifier: "major.minor". + + + + + JHOVE release date: "yyyy-mm-dd" + + + + + + + Descriptive information about JHOVE itself. Requested by the "jhove -h xml" command. + + + + + Optional JHOVE API information. + + + + + + + The release date for the API: "yyyy-mm-dd". + + + + + + + + + Optional configuration file pathname. + + + + + SAX parser fully-qualified class name. + + + + + JHOVE home directory pathname. + + + + + Output handler encoding. + + + + + Temporary directory pathname. + + + + + Buffer size for buffered I/O. + + + + + List of modules configured for this invocation. + + + + + + Module name, generally of the form "FORMAT-vendor". + + + + + + + The release identifier for the module. + + + + + + + + + + + + List of output handlers configued for this invocation. + + + + + + Output handler name. + + + + + + + The release identifier for the module. + + + + + + + + + + + + Command line invocation syntax. + + + + + Rights statement. + + + + + + + Results of a file audit, i.e., per-file pathname, MIME type, and status information. + + + + + Per-file informatino: pathname, MIME type, and status information. + + + + + + + The file MIME type. + + + + + The file validation status. + + + + + + + + + + + + + MD5 checksum for the file. + + + + + + + + + + Home directory from which the Audit handler was invoked. + + + + + + Descriptive information about a JHOVE output handler. Requested by the "jhove -h xml -H handler" command. + + + + + Output handler name. + + + + + Handler release identifier: "major.minor". + + + + + Handler release date: "yyyy-mm-dd". + + + + + Optional list of specification documents for the handler. + + + + + The output handler vendor. + + + + + Optional informative note about the handler. + + + + + Optional rights statement about the handler. Typically this would niclude a copyright statement of the vendor and a summary of the licesnse agreement under which the handler is release. + + + + + + + Descriptive information about a JHOVE module. Requested by the "jhove -h xml -m module" command. + + + + + Module name. + + + + + Module release identifier: "major.minor". + + + + + Module release date: "yyyy-mm-dd". + + + + + Optional list of modules formats. + + + + + + Module format + + + + + + + + Optional statement of format coverage. + + + + + Optional list of format MIME types. + + + + + + Format MIME type + + + + + + + + Optional list of signatures. + + + + + + + + + + + + + + + + + + Signature value. + + + + + Fixed byte offset of the signature + + + + + Informative note about the signature. + + + + + Use flag for the signature. + + + + + + + + + + + Optional list of specification documents. + + + + + + Format specification. + + + + + + + + List of module features: canValidate, canCharacterize, etc. + + + + + + Module feature + + + + + + + + List of methodology statements + + + + + + Statement of well-formedness criteria.. + + + + + Statement of validty criteria. + + + + + Statement of representation information properties. + + + + + + + + Optional vendor agent. + + + + + Optional informative note. + + + + + Optional rights statement. Generally this includes a copyright statement of the vendor and a summary of the license agreement under which the module is released. + + + + + + + Descriptive information about a digital object. + + + + + The module producing the representation information. + + + + + + + Release identifier for the module. + + + + + Release date for the module. + + + + + + + + + Object creation date timestamp. + + + + + Object last modified data timestemp. + + + + + Object size in bytes. + + + + + Object format. + + + + + Object version. + + + + + Object validation status. + + + + + + + + Modules with matching internal signatures. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Object MIME type. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Personal or corporate agent type. + + + + + Agent name. + + + + + Agent type. + + + + + + + + + + + + + + + Optional agent postal address. + + + + + Optional agent telephone number. + + + + + Optional agent FAX number. + + + + + Optional agent email address. + + + + + Optional agent web site URI. + + + + + + Agent role. + + + + + + + + + + + + + + + + + + + + Allow recursive structure of property types + + + + + The value element can contain a scalar actual value or additional markup from known namespaces + + + + + + + + Attribute contains the key name for key-value pairs in a Map property + + + + + + + + The arity of the property. The non-scalar arities have the semantics associated with the Java collection types of the same name. + + + + + + + + + + + + + + The type of the property. Most types have the semantics of the Java types of the same name. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Description information about a specification document. + + + + + Document title. + + + + + Document type. + + + + + + + + + + + + + + + + Optional list of authors. + + + + + + Author agent. + + + + + + + + Optional list of publishers. + + + + + + Publisher agent. + + + + + + + + Optional document edition. + + + + + Optional document edition: "yyyy[-mm[-dd]]". + + + + + + + + Optional document enumeration. + + + + + Optional document pages. + + + + + Optional list of identifiers. + + + + + + Document identifier. + + + + + + Identifier value. + + + + + Identifier type. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Optional informative note. + + + + + + + + + + + Optional informative note. + + + + + diff --git a/jhove-core/src/main/resources/schema.openpreservation.org/ois/xml/xsd/jhove/jhove.xsd b/jhove-core/src/main/resources/schema.openpreservation.org/ois/xml/xsd/jhove/jhove.xsd new file mode 100644 index 000000000..80f53e203 --- /dev/null +++ b/jhove-core/src/main/resources/schema.openpreservation.org/ois/xml/xsd/jhove/jhove.xsd @@ -0,0 +1,848 @@ + + + + + + + + + This is the XML Schema for the output produced by the JHOVE XML output handler. + + + + + + + The date/time at which JHOVE was invoked. + + + + + + Descriptive information about JHOVE itself. Requested by the "jhove -h xml" command. + + + + + Results of a file audit, i.e., per-file pathname, MIME type, and status information. + + + + + Descriptive information about a JHOVE output handler. Requested by the "jhove -h xml -H handler" command. + + + + + Descriptive information about a JHOVE module. Requested by the "jhove -h xml -m module" command. + + + + + Unbounded sequence of representation information elements. + + + + + + + JHOVE application name. + + + + + JHOVE release identifier: "major.minor". + + + + + JHOVE release date: "yyyy-mm-dd" + + + + + + + Descriptive information about JHOVE itself. Requested by the "jhove -h xml" command. + + + + + Optional JHOVE API information. + + + + + + + The release date for the API: "yyyy-mm-dd". + + + + + + + + + Optional configuration file pathname. + + + + + SAX parser fully-qualified class name. + + + + + JHOVE home directory pathname. + + + + + Output handler encoding. + + + + + Temporary directory pathname. + + + + + Buffer size for buffered I/O. + + + + + List of modules configured for this invocation. + + + + + + Module name, generally of the form "FORMAT-vendor". + + + + + + + The release identifier for the module. + + + + + + + + + + + + List of output handlers configued for this invocation. + + + + + + Output handler name. + + + + + + + The release identifier for the module. + + + + + + + + + + + + Command line invocation syntax. + + + + + Rights statement. + + + + + + + Results of a file audit, i.e., per-file pathname, MIME type, and status information. + + + + + Per-file informatino: pathname, MIME type, and status information. + + + + + + + The file MIME type. + + + + + The file validation status. + + + + + + + + + + + + + MD5 checksum for the file. + + + + + + + + + + Home directory from which the Audit handler was invoked. + + + + + + Descriptive information about a JHOVE output handler. Requested by the "jhove -h xml -H handler" command. + + + + + Output handler name. + + + + + Handler release identifier: "major.minor". + + + + + Handler release date: "yyyy-mm-dd". + + + + + Optional list of specification documents for the handler. + + + + + The output handler vendor. + + + + + Optional informative note about the handler. + + + + + Optional rights statement about the handler. Typically this would niclude a copyright statement of the vendor and a summary of the licesnse agreement under which the handler is release. + + + + + + + Descriptive information about a JHOVE module. Requested by the "jhove -h xml -m module" command. + + + + + Module name. + + + + + Module release identifier: "major.minor". + + + + + Module release date: "yyyy-mm-dd". + + + + + Optional list of modules formats. + + + + + + Module format + + + + + + + + Optional statement of format coverage. + + + + + Optional list of format MIME types. + + + + + + Format MIME type + + + + + + + + Optional list of signatures. + + + + + + + + + + + + + + + + + + Signature value. + + + + + Fixed byte offset of the signature + + + + + Informative note about the signature. + + + + + Use flag for the signature. + + + + + + + + + + + Optional list of specification documents. + + + + + + Format specification. + + + + + + + + List of module features: canValidate, canCharacterize, etc. + + + + + + Module feature + + + + + + + + List of methodology statements + + + + + + Statement of well-formedness criteria.. + + + + + Statement of validty criteria. + + + + + Statement of representation information properties. + + + + + + + + Optional vendor agent. + + + + + Optional informative note. + + + + + Optional rights statement. Generally this includes a copyright statement of the vendor and a summary of the license agreement under which the module is released. + + + + + + + Descriptive information about a digital object. + + + + + The module producing the representation information. + + + + + + + Release identifier for the module. + + + + + Release date for the module. + + + + + + + + + Object creation date timestamp. + + + + + Object last modified data timestemp. + + + + + Object size in bytes. + + + + + Object format. + + + + + Object version. + + + + + Object validation status. + + + + + + + + Modules with matching internal signatures. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Object MIME type. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Personal or corporate agent type. + + + + + Agent name. + + + + + Agent type. + + + + + + + + + + + + + + + Optional agent postal address. + + + + + Optional agent telephone number. + + + + + Optional agent FAX number. + + + + + Optional agent email address. + + + + + Optional agent web site URI. + + + + + + Agent role. + + + + + + + + + + + + + + + + + + + + Allow recursive structure of property types + + + + + The value element can contain a scalar actual value or additional markup from known namespaces + + + + + + + + Attribute contains the key name for key-value pairs in a Map property + + + + + + + + The arity of the property. The non-scalar arities have the semantics associated with the Java collection types of the same name. + + + + + + + + + + + + + + The type of the property. Most types have the semantics of the Java types of the same name. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Description information about a specification document. + + + + + Document title. + + + + + Document type. + + + + + + + + + + + + + + + + Optional list of authors. + + + + + + Author agent. + + + + + + + + Optional list of publishers. + + + + + + Publisher agent. + + + + + + + + Optional document edition. + + + + + Optional document edition: "yyyy[-mm[-dd]]". + + + + + + + + Optional document enumeration. + + + + + Optional document pages. + + + + + Optional list of identifiers. + + + + + + Document identifier. + + + + + + Identifier value. + + + + + Identifier type. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Optional informative note. + + + + + + + + + + + Optional informative note. + + + + +