gov.nasa.pds.objectAccess.ObjectAccess Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of pds4-jparser Show documentation
Show all versions of pds4-jparser Show documentation
This is the parser library for the PDS4 planetary data standard.
// Copyright 2019, California Institute of Technology ("Caltech").
// U.S. Government sponsorship acknowledged.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
// * Neither the name of Caltech nor its operating division, the Jet Propulsion
// Laboratory, nor the names of its contributors may be used to endorse or
// promote products derived from this software without specific prior written
// permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package gov.nasa.pds.objectAccess;
import gov.nasa.arc.pds.xml.generated.Array;
import gov.nasa.arc.pds.xml.generated.Array2DImage;
import gov.nasa.arc.pds.xml.generated.Array3DImage;
import gov.nasa.arc.pds.xml.generated.Array3DSpectrum;
import gov.nasa.arc.pds.xml.generated.FieldBinary;
import gov.nasa.arc.pds.xml.generated.FieldCharacter;
import gov.nasa.arc.pds.xml.generated.FieldDelimited;
import gov.nasa.arc.pds.xml.generated.FileArea;
import gov.nasa.arc.pds.xml.generated.FileAreaAncillary;
import gov.nasa.arc.pds.xml.generated.FileAreaBrowse;
import gov.nasa.arc.pds.xml.generated.FileAreaInventory;
import gov.nasa.arc.pds.xml.generated.FileAreaObservational;
import gov.nasa.arc.pds.xml.generated.FileAreaObservationalSupplemental;
import gov.nasa.arc.pds.xml.generated.FileAreaSIPDeepArchive;
import gov.nasa.arc.pds.xml.generated.FileAreaTransferManifest;
import gov.nasa.arc.pds.xml.generated.GroupFieldDelimited;
import gov.nasa.arc.pds.xml.generated.Header;
import gov.nasa.arc.pds.xml.generated.ProductObservational;
import gov.nasa.arc.pds.xml.generated.TableBinary;
import gov.nasa.arc.pds.xml.generated.TableCharacter;
import gov.nasa.arc.pds.xml.generated.TableDelimited;
import gov.nasa.pds.label.jaxb.PDSXMLEventReader;
import gov.nasa.pds.label.jaxb.XMLLabelContext;
import gov.nasa.pds.objectAccess.utility.Utility;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.NoSuchElementException;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.ValidationEvent;
import javax.xml.bind.ValidationEventHandler;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The ObjectAccess
class is a point of entry into parsed PDS (including PDS 4/XML-schema-labeled) objects.
*
* @author dcberrio
*/
public class ObjectAccess implements ObjectProvider {
private static final Logger LOGGER = LoggerFactory.getLogger(ObjectAccess.class);
private String archiveRoot;
private URL root;
private final XMLInputFactory xif = XMLInputFactory.newInstance();
private XMLLabelContext labelContext;
/**
* Creates a new instance with the current local directory as the archive root
* path.
* @throws URISyntaxException
* @throws MalformedURLException
*/
public ObjectAccess() throws MalformedURLException, URISyntaxException {
this(new File("."));
}
/**
* Constructs an ObjectAccess
object and sets the archive root path.
*
* @param archiveRoot the archive root path
* @throws URISyntaxException
* @throws MalformedURLException
*/
public ObjectAccess(String archiveRoot) throws MalformedURLException, URISyntaxException {
URL url = null;
try {
url = new URL(archiveRoot);
} catch (MalformedURLException mu) {
url = new File(archiveRoot).toURI().toURL();
}
this.root = url.toURI().normalize().toURL();
this.archiveRoot = this.root.toString();
this.labelContext = new XMLLabelContext();
}
/**
* Constructs an ObjectAccess
object and sets the archive root path.
*
* @param archiveRoot the archive root path
* @throws URISyntaxException
* @throws MalformedURLException
*/
public ObjectAccess(File archiveRoot) throws MalformedURLException, URISyntaxException {
this(archiveRoot.toURI().toURL());
}
/**
* Constructs an ObjectAccess
object and sets the archive root path.
*
* @param archiveRoot the archive root path
* @throws URISyntaxException
* @throws MalformedURLException
*/
public ObjectAccess(URL archiveRoot) throws URISyntaxException, MalformedURLException {
this.root = archiveRoot.toURI().normalize().toURL();
this.archiveRoot = this.root.toString();
this.labelContext = new XMLLabelContext();
}
private JAXBContext getJAXBContext(String pkgName) throws JAXBException {
ClassLoader currentLoader = Thread.currentThread().getContextClassLoader();
if (!(currentLoader instanceof WorkaroundClassLoader)) {
ClassLoader loader = new WorkaroundClassLoader(
currentLoader!=null ? currentLoader : getClass().getClassLoader()
);
Thread.currentThread().setContextClassLoader(loader);
}
return JAXBContext.newInstance(pkgName);
}
@Override
public T getProduct(File labelFile, Class productClass) throws ParseException {
try {
return getProduct(labelFile.toURI().toURL(), productClass);
} catch (MalformedURLException e) {
LOGGER.error("Failed to load the product from the label.", e);
throw new ParseException("Unable to parse the product label", e);
}
}
@Override
public T getProduct(URL label, Class productClass) throws ParseException {
try {
JAXBContext context = getJAXBContext("gov.nasa.arc.pds.xml.generated");
Unmarshaller u = context.createUnmarshaller();
u.setEventHandler(new LenientEventHandler());
return productClass.cast(u.unmarshal(Utility.openConnection(label)));
} catch (JAXBException je) {
LOGGER.error("Failed to load the product from the label.", je);
throw new ParseException("Unable to parse the product label", je);
} catch (IOException io) {
LOGGER.error("Failed to load the product from the label.", io);
throw new ParseException("Unable to parse the product label", io);
} catch (Exception e) {
throw new ParseException("Error while parsing the product label", e);
}
}
@Override
public ProductObservational getObservationalProduct(String relativeXmlFilePath) {
InputStream in = null;
try {
JAXBContext context = getJAXBContext("gov.nasa.arc.pds.xml.generated");
Unmarshaller u = context.createUnmarshaller();
u.setEventHandler(new LenientEventHandler());
URL url = new URL(getRoot(), relativeXmlFilePath);
in = url.openStream();
XmlRootElement a = ProductObservational.class.getAnnotation(XmlRootElement.class);
String root = a.name();
PDSXMLEventReader xsr = new PDSXMLEventReader(
xif.createXMLEventReader(in), root);
ProductObservational po = (ProductObservational) u.unmarshal(xsr);
labelContext = xsr.getLabelContext();
return po;
} catch (JAXBException e) {
LOGGER.error("Failed to get the product observational.", e);
e.printStackTrace();
return null;
} catch (MalformedURLException e) {
LOGGER.error("Failed to get the product observational.", e);
e.printStackTrace();
return null;
} catch (XMLStreamException e) {
LOGGER.error("Failed to get the product observational: ", e);
e.printStackTrace();
return null;
} catch (IOException e) {
LOGGER.error("Failed to get the product observational.", e);
e.printStackTrace();
return null;
} finally {
IOUtils.closeQuietly(in);
}
}
public void setObservationalProduct(String relativeXmlFilePath, ProductObservational product)
throws Exception {
setObservationalProduct(relativeXmlFilePath, product, null);
}
/**
* Writes a label given the product XML file. This method assumes that the
* label will be written to the local file system. Therefore, the protocol
* of the ObjectAccess archive root must be a 'file'.
*
* @param relativeXmlFilePath the XML file path and name of the product to set, relative
* to the ObjectAccess archive root
*
* @param product The Product_Observational object to serialize into an XML file.
*
* @param labelContext A context to use when creating the XML file. Can be set to null.
*
* @throws Exception If there was an error creating the XML file.
*/
@Override
public void setObservationalProduct(String relativeXmlFilePath, ProductObservational product,
XMLLabelContext labelContext) throws Exception {
try {
JAXBContext context = getJAXBContext("gov.nasa.arc.pds.xml.generated");
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
if (labelContext != null) {
m.setProperty("com.sun.xml.bind.namespacePrefixMapper", labelContext.getNamespaces());
m.setProperty("com.sun.xml.bind.xmlHeaders", labelContext.getXmlModelPIs());
m.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, labelContext.getSchemaLocation());
}
if ("file".equalsIgnoreCase(getRoot().getProtocol())) {
File parent = FileUtils.toFile(getRoot());
File f = new File(parent, relativeXmlFilePath);
m.marshal(product, f);
} else {
OutputStream os = null;
try {
URL u = new URL(getRoot(), relativeXmlFilePath);
URLConnection conn = u.openConnection();
conn.setDoOutput(true);
os = conn.getOutputStream();
m.marshal(product, os);
} catch (Exception e) {
LOGGER.error("Failed to set the product observational.", e);
e.printStackTrace();
throw e;
} finally {
IOUtils.closeQuietly(os);
}
}
} catch (JAXBException e) {
LOGGER.error("Failed to set the product observational.", e);
e.printStackTrace();
throw e;
}
}
@Override
public List getArrays(FileArea fileArea) {
List list = new ArrayList();
if (fileArea instanceof FileAreaObservational) {
list.addAll(getArrays((FileAreaObservational) fileArea));
} else if (fileArea instanceof FileAreaBrowse) {
list.addAll(getArrays((FileAreaBrowse) fileArea));
}
return list;
}
@Override
public List getArrays(FileAreaObservational fileArea) {
List list = new ArrayList();
for (Object obj : fileArea.getDataObjects()) {
if (obj instanceof Array) {
list.add(Array.class.cast(obj));
}
}
return list;
}
@Override
public List getArrays(FileAreaBrowse fileArea) {
List list = new ArrayList();
for (Object obj : fileArea.getDataObjects()) {
if (obj instanceof Array) {
list.add(Array.class.cast(obj));
}
}
return list;
}
@Override
public List getArray2DImages(FileAreaObservational observationalFileArea) {
ArrayList list = new ArrayList();
for (Object obj : observationalFileArea.getDataObjects()) {
if (obj.getClass().equals(Array2DImage.class)) {
list.add(Array2DImage.class.cast(obj));
}
}
return list;
}
public List getArray3DImages(FileAreaObservational observationalFileArea) {
ArrayList list = new ArrayList();
for (Object obj : observationalFileArea.getDataObjects()) {
if (obj.getClass().equals(Array3DImage.class)) {
list.add(Array3DImage.class.cast(obj));
}
}
return list;
}
public List getArray3DSpectrums(FileAreaObservational observationalFileArea) {
ArrayList list = new ArrayList();
for (Object obj : observationalFileArea.getDataObjects()) {
if (obj.getClass().equals(Array3DSpectrum.class)) {
list.add(Array3DSpectrum.class.cast(obj));
}
}
return list;
}
public List