blob: 32e3156b51489c2828b27fb2408ac7a067a5b37d [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.oodt.cas.filemgr.structs;
//JDK imports
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
//OODT imports
import org.apache.oodt.cas.filemgr.catalog.Catalog; //for javadoc
import org.apache.oodt.commons.xml.XMLUtils;
/**
* @author mattmann
* @author bfoster
* @version $Revision$
*
* <p>
* A Product is a set of files, or a heirarchical, directory structure that
* should be ingested into the {@link Catalog}.
* </p>
*
*/
public class Product {
/* our product id */
private String productId = null;
/* our product name */
private String productName = null;
/* our product type */
private ProductType productType = null;
/* our product structure: can be Heirarchical, or Flat */
private String productStructure = null;
/* a set of {@link References} to the items that make up this product */
private List<Reference> references = null;
/*
* the transfer status of this product: is it TRANSFERING, has it been
* RECEIVED?
*/
private String transferStatus = null;
/*
* the root reference for this product: if it's a dir, it's the root of the
* dir tree if the product is flat, it's the first (and possibly) only ref.
*/
private Reference rootRef;
/* a couple of static final Strings to represent the TransferStatus */
public static final String STATUS_TRANSFER = "TRANSFERING";
public static final String STATUS_RECEIVED = "RECEIVED";
/* a couple of static final Strings to represent the productStructure */
public static final String STRUCTURE_FLAT = "Flat";
public static final String STRUCTURE_HIERARCHICAL = "Hierarchical";
public static final String STRUCTURE_STREAM = "Stream";
private static String[] VALID_STRUCTURES = new String[]{STRUCTURE_FLAT,STRUCTURE_HIERARCHICAL,STRUCTURE_STREAM};
/* our log stream */
private static final Logger LOG = Logger.getLogger(Product.class.getName());
/**
* <p>
* Default Constructor
* </p>
*
*/
public Product() {
references = new Vector<Reference>();
}
public Product(InputStream is) throws InstantiationException {
if (is == null) {
throw new InstantiationException(
"Unable to parse product stream: stream not set!");
}
try {
DocumentBuilderFactory factory = DocumentBuilderFactory
.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder parser = factory.newDocumentBuilder();
references = new Vector<Reference>();
parse(parser.parse(new InputSource(is)));
} catch (Exception e) {
throw new InstantiationException(
"Unable to parse metadata stream.[" + e.getMessage() + "]");
}
}
/**
* <p>
* Constructs a new Product with the specified parameters.
* </p>
*
* @param name
* The Product's name.
* @param pType
* The Product's {@link ProductType}.
* @param structure
* The structure of the product: either Hierarchical, or Flat.
* @param transferStatus
* The status of this product's transfer to the DataStore:
* TRANSFERING, or RECEIVED would work
* @param refs
* A {@link List} of {@link Reference}s pointing to the items
* that make up this product.
*/
public Product(String name, ProductType pType, String structure,
String transferStatus, List<Reference> refs) {
productName = name;
productType = pType;
productStructure = structure;
references = refs;
this.transferStatus = transferStatus;
}
/**
* @return Returns the productType.
*/
public ProductType getProductType() {
return productType;
}
/**
* @param productType
* The productType to set.
*/
public void setProductType(ProductType productType) {
this.productType = productType;
}
/**
* @return Returns the productStructure.
*/
public String getProductStructure() {
return productStructure;
}
/**
* @param productStructure
* The productStructure to set.
*/
public void setProductStructure(String productStructure) {
//Guard clause, according to a unit test null is a valid value
if (!java.util.Arrays.asList(VALID_STRUCTURES).contains(productStructure) && productStructure != null)
throw new IllegalArgumentException("Undefined product structure: "+productStructure);
this.productStructure = productStructure;
}
/**
* @return Returns the references.
*/
public List<Reference> getProductReferences() {
return references;
}
/**
* @param references
* The references to set.
*/
public void setProductReferences(List<Reference> references) {
this.references = references;
}
/**
* @return Returns the productName.
*/
public String getProductName() {
return productName;
}
/**
* @param productName
* The productName to set.
*/
public void setProductName(String productName) {
this.productName = productName;
}
/**
* @return Returns the productId.
*/
public String getProductId() {
return productId;
}
/**
* @param productId
* The productId to set.
*/
public void setProductId(String productId) {
this.productId = productId;
}
/**
* @return Returns the transferStatus.
*/
public String getTransferStatus() {
return transferStatus;
}
/**
* @param transferStatus
* The transferStatus to set.
*/
public void setTransferStatus(String transferStatus) {
this.transferStatus = transferStatus;
}
/**
* @return the rootRef
*/
public Reference getRootRef() {
return rootRef;
}
/**
* @param rootRef
* the rootRef to set
*/
public void setRootRef(Reference rootRef) {
this.rootRef = rootRef;
}
public static final Product getDefaultFlatProduct(String name,
String defaultProductTypeId) {
Product defaultProduct = new Product();
defaultProduct.setProductName(name);
defaultProduct.setProductReferences(new Vector<Reference>());
defaultProduct.setProductStructure(Product.STRUCTURE_FLAT);
ProductType pType = new ProductType();
pType.setProductTypeId(defaultProductTypeId);
defaultProduct.setProductType(pType);
defaultProduct.setTransferStatus(Product.STATUS_TRANSFER);
return defaultProduct;
}
public Document toXML() throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
Document doc = null;
try {
DocumentBuilder builder = factory.newDocumentBuilder();
doc = builder.newDocument();
Element root = (Element) doc.createElement("cas:product");
XMLUtils.addAttribute(doc, root, "xmlns:cas",
"http://oodt.jpl.nasa.gov/1.0/cas");
XMLUtils.addAttribute(doc, root, "id", this.productId);
XMLUtils.addAttribute(doc, root, "name", URLEncoder.encode(
this.productName, "UTF-8"));
doc.appendChild(root);
XMLUtils.addNode(doc, root, "structure", this.productStructure);
XMLUtils.addNode(doc, root, "transferStatus", this.transferStatus);
XMLUtils.addNode(doc, root, "type",
this.productType != null ? this.productType.getName() : "");
if (this.getProductReferences() != null
&& this.getProductReferences().size() > 0) {
Element refsElem = XMLUtils.addNode(doc, root, "references");
for (Iterator<Reference> i = this.getProductReferences().iterator(); i
.hasNext();) {
Reference r = i.next();
Element refElem = XMLUtils.addNode(doc, refsElem,
"reference");
XMLUtils.addAttribute(doc, refElem, "orig", r
.getOrigReference());
XMLUtils.addAttribute(doc, refElem, "dataStore", r
.getDataStoreReference());
XMLUtils.addAttribute(doc, refElem, "size", String
.valueOf(r.getFileSize()));
}
}
} catch (ParserConfigurationException pce) {
LOG.log(Level.WARNING, "Error generating product xml file!: "
+ pce.getMessage());
throw new Exception("Error generating product xml file!: "
+ pce.getMessage());
}
return doc;
}
private void parse(Document doc) {
Element root = doc.getDocumentElement();
this.productId = root.getAttribute("id");
try {
this.productName = URLDecoder.decode(root.getAttribute("name"),
"UTF-8");
} catch (UnsupportedEncodingException e) {
LOG.log(Level.WARNING,
"Unable to set product name: error decoding encoded string: Message: "
+ e.getMessage());
}
this.productStructure = XMLUtils.getElementText("structure", root);
this.productType = new ProductType();
this.productType.setName(XMLUtils.getElementText("type", root));
this.transferStatus = XMLUtils.getElementText("transferStatus", root);
Element refsElem = XMLUtils.getFirstElement("references", root);
if (refsElem != null) {
NodeList refNodeList = refsElem.getElementsByTagName("reference");
if (refNodeList != null && refNodeList.getLength() > 0) {
for (int i = 0; i < refNodeList.getLength(); i++) {
Element refElem = (Element) refNodeList.item(i);
Reference r = new Reference();
r.setOrigReference(refElem.getAttribute("orig"));
r.setDataStoreReference(refElem.getAttribute("dataStore"));
r.setFileSize(Long.valueOf(refElem.getAttribute("size"))
.longValue());
this.references.add(r);
}
}
}
}
}