| /* |
| * 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.profile; |
| |
| import com.hp.hpl.jena.rdf.model.Model; |
| import com.hp.hpl.jena.rdf.model.ModelFactory; |
| import com.hp.hpl.jena.rdf.model.Property; |
| import com.hp.hpl.jena.rdf.model.Resource; |
| import java.io.IOException; |
| import java.io.Serializable; |
| import java.net.URI; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import org.apache.oodt.commons.Configuration; |
| import org.apache.oodt.commons.util.Documentable; |
| import org.apache.oodt.commons.util.XML; |
| import org.w3c.dom.DOMException; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.DocumentType; |
| import org.w3c.dom.Element; |
| import org.w3c.dom.Node; |
| import org.w3c.dom.NodeList; |
| import org.xml.sax.SAXException; |
| import org.xml.sax.SAXParseException; |
| import java.io.BufferedReader; |
| import java.io.FileReader; |
| import java.io.OutputStreamWriter; |
| |
| /** |
| * A profile. |
| * |
| * Objects of this class are profiles. Profiles are metadata descriptions of resources. |
| * |
| * @author Kelly |
| */ |
| public class Profile implements Serializable, Cloneable, Comparable, Documentable { |
| /** Serial version unique ID. */ |
| static final long serialVersionUID = -3936851809184360591L; |
| |
| /** The formal public identifier of the profiles DTD. */ |
| public static final String PROFILES_DTD_FPI = "-//JPL//DTD Profile 1.1//EN"; |
| |
| /** The system identifier of the profiles DTD. */ |
| public static String PROFILES_DTD_URL = "http://oodt.jpl.nasa.gov/grid-profile/dtd/prof.dtd"; |
| |
| /** |
| * Create a list of profiles by deserializing data from the given XML element. |
| * |
| * @param root Either a <profiles> or a <profile> element. |
| * @param factory Factory for creation of profile-related objects. |
| * @return A list of profiles. |
| */ |
| public static List createProfiles(Element root, ObjectFactory factory) { |
| List profiles = new ArrayList(); |
| if ("profile".equals(root.getNodeName())) |
| // The root is a <profile>, so add the single profile to the list. |
| profiles.add(factory.createProfile((Element) root)); |
| else if ("profiles".equals(root.getNodeName())) { |
| // The root is a <profiles>, so add each <profile> to the list. |
| NodeList children = root.getChildNodes(); |
| for (int i = 0; i < children.getLength(); ++i) { |
| Node node = children.item(i); |
| if ("profile".equals(node.getNodeName())) |
| profiles.add(factory.createProfile((Element) node)); |
| } |
| } else throw new IllegalArgumentException("Expected a <profiles> or <profile> top level element but got " |
| + root.getNodeName()); |
| return profiles; |
| } |
| |
| |
| /** |
| * Create a list of profiles by deserializing data from the given XML element. |
| * |
| * This method uses the default factory that yields objects of this package, |
| * namely {@link Profile}, {@link ProfileAttributes}, {@link ResourceAttributes}, |
| * and {@link ProfileElement} and its subclasses. |
| * |
| * @param root Either a <profiles> or a <profile> element. |
| * @return A list of profiles. |
| */ |
| public static List createProfiles(Element root) { |
| return createProfiles(root, new DefaultFactory()); |
| } |
| |
| /** |
| * Create a blank profile. |
| */ |
| public Profile() { |
| profAttr = new ProfileAttributes(); |
| resAttr = new ResourceAttributes(this); |
| } |
| |
| /** |
| * Create a profile from an XML document. |
| * |
| * @param string The XML document (as a string). |
| * @throws SAXException If the <var>string</var> can't be parsed. |
| */ |
| public Profile(String string) throws SAXException { |
| this(XML.parse(string).getDocumentElement(), new DefaultFactory()); |
| } |
| |
| /** |
| * Create a profile from an XML document. |
| * |
| * @param string The XML document (as a string). |
| * @param factory Object factory to use. |
| * @throws SAXException If the <var>string</var> can't be parsed. |
| */ |
| public Profile(String string, ObjectFactory factory) throws SAXException { |
| this(XML.parse(string).getDocumentElement(), factory); |
| } |
| |
| /** |
| * Creates a new <code>Profile</code> instance. |
| * |
| * @param root a <code>Node</code> value. |
| */ |
| public Profile(Node root) { |
| this(root, new DefaultFactory()); |
| } |
| |
| /** |
| * Create a profile from an XML document. |
| * |
| * @param root The <profile> element. |
| */ |
| public Profile(Node root, ObjectFactory factory) { |
| if (!root.getNodeName().equals("profile")) |
| throw new IllegalArgumentException("Construct a Profile from a <profile> element, not a <" |
| + root.getNodeName() + ">"); |
| NodeList children = root.getChildNodes(); |
| for (int i = 0; i < children.getLength(); ++i) { |
| Node node = children.item(i); |
| if ("profAttributes".equals(node.getNodeName())) |
| profAttr = factory.createProfileAttributes((Element) node); |
| else if ("resAttributes".equals(node.getNodeName())) |
| resAttr = factory.createResourceAttributes(this, (Element) node); |
| else if ("profElement".equals(node.getNodeName())) { |
| ProfileElement element = ProfileElement.createProfileElement((Element) node, this, factory); |
| elements.put(element.getName(), element); |
| } |
| } |
| } |
| |
| /** |
| * Create a profile from its attributes. |
| * |
| * @param profAttr Profile attributes. |
| * @param resAttr Resource attributes. |
| */ |
| public Profile(ProfileAttributes profAttr, ResourceAttributes resAttr) { |
| this.profAttr = profAttr; |
| this.resAttr = resAttr; |
| if (this.resAttr != null) this.resAttr.profile = this; |
| } |
| |
| public int hashCode() { |
| return profAttr.hashCode(); |
| } |
| |
| public boolean equals(Object rhs) { |
| if (rhs == this) return true; |
| if (rhs == null || !(rhs instanceof Profile)) return false; |
| Profile obj = (Profile) rhs; |
| return profAttr.equals(obj.profAttr); |
| } |
| |
| public int compareTo(Object rhs) { |
| Profile obj = (Profile) rhs; |
| return profAttr.compareTo(obj.profAttr); |
| } |
| |
| public String toString() { |
| Document doc = createProfileDocument(); |
| doc.removeChild(doc.getDocumentElement()); |
| doc.appendChild(toXML(doc)); |
| return XML.serialize(doc); |
| } |
| |
| public Object clone() { |
| Object clone = null; |
| try { |
| clone = super.clone(); |
| } catch (CloneNotSupportedException cantHappen) {} |
| return clone; |
| } |
| |
| /** |
| * Get the profile attributes. |
| * |
| * @return The profile attributes. |
| */ |
| public ProfileAttributes getProfileAttributes() { |
| return profAttr; |
| } |
| |
| /** |
| * Get the resource attributes. |
| * |
| * @return The resource attributes. |
| */ |
| public ResourceAttributes getResourceAttributes() { |
| return resAttr; |
| } |
| |
| /** |
| * Set this profile's profile attributes. |
| * |
| * @param profAttr a <code>ProfileAttributes</code> value. |
| */ |
| public void setProfileAttributes(ProfileAttributes profAttr) { |
| this.profAttr = profAttr; |
| } |
| |
| /** |
| * Set this profile's resource attributes. |
| * |
| * @param resAttr a <code>ResourceAttributes</code> value. |
| */ |
| public void setResourceAttributes(ResourceAttributes resAttr) { |
| this.resAttr = resAttr; |
| } |
| |
| /** |
| * Get the profile elements. |
| * |
| * The profile elements are a mapping from the element name ({@link |
| * java.lang.String}) to {@link ProfileElement}. |
| * |
| * @return The profile elements. |
| */ |
| public Map getProfileElements() { |
| return elements; |
| } |
| |
| public URI getURI() { |
| return resAttr.getURI(); |
| } |
| |
| /** |
| * Add this profile as an RDF resource description to an RDF model. |
| * |
| * This creates a description of the resource that this profile describes, as well |
| * as additional resources for the reified statements about the profile itself, |
| * and adds them all to the given model. |
| * |
| * @param model Model to which to add the profile and its related descriptions. |
| */ |
| public void addToModel(Model model) { |
| Resource resource = model.createResource(getURI().toString()); |
| resAttr.addToModel(model, resource, profAttr); |
| for (Iterator i = elements.values().iterator(); i.hasNext();) { |
| ProfileElement e = (ProfileElement) i.next(); |
| e.addToModel(model, resource, profAttr); |
| } |
| } |
| |
| /** |
| * Serialize this profile as an XML node. |
| * |
| * @param doc The document that will own this node. |
| * @return The XML element <profile> representing these attributes. |
| * @throws DOMException If an error occurs creating the XML nodes. |
| */ |
| public Node toXML(Document doc) throws DOMException { |
| return toXML(doc, /*withElements*/true); |
| } |
| |
| /** |
| * Serialize this profile as an XML node but without any elements. |
| * |
| * @param doc The document that will own this node. |
| * @return The XML element <profile> representing these attributes. |
| * @throws DOMException If an error occurs creating the XML nodes. |
| */ |
| public Node toXMLWithoutElements(Document doc) throws DOMException { |
| return toXML(doc, /*withElements*/false); |
| } |
| |
| /** |
| * Serialize this profile as an XML node. |
| * |
| * @param doc The document that will own this node. |
| * @param withElements Include the profile elements? |
| * @return The XML element <profile> representing these attributes. |
| * @throws DOMException If an error occurs creating the XML nodes. |
| */ |
| private Node toXML(Document doc, boolean withElements) throws DOMException { |
| Element profile = doc.createElement("profile"); |
| profile.appendChild(profAttr.toXML(doc)); |
| profile.appendChild(resAttr.toXML(doc)); |
| if (withElements) for (Iterator i = elements.values().iterator(); i.hasNext();) |
| profile.appendChild(((ProfileElement) i.next()).toXML(doc)); |
| return profile; |
| } |
| |
| /** |
| * Create a <profiles> document using the profiles DTD. |
| * |
| * @return A <profiles> document with the profiles DTD. |
| */ |
| public static Document createProfilesDocument() { |
| return createDocument("profiles"); |
| } |
| |
| /** |
| * Create a <profile> document using the profiles DTD. |
| * |
| * @return A <profile> document with the profiles DTD. |
| */ |
| public static Document createProfileDocument() { |
| return createDocument("profile"); |
| } |
| |
| /** |
| * Create a document using the profiles DTD with the given root element. |
| * |
| * @param root Name of the root element. |
| * @return The document with the appropriate document type declaration. |
| */ |
| static Document createDocument(String root) { |
| DocumentType docType = XML.getDOMImplementation().createDocumentType(root, PROFILES_DTD_FPI, PROFILES_DTD_URL); |
| Document doc = XML.getDOMImplementation().createDocument(/*namespaceURI*/null, root, docType); |
| return doc; |
| } |
| |
| /** My profile attributes. */ |
| protected ProfileAttributes profAttr; |
| |
| /** My resource attributes. */ |
| protected ResourceAttributes resAttr; |
| |
| /** My elements. |
| * |
| * This mapping is from element name (a {@link String}) to {@link ProfileElement}. |
| */ |
| protected Map elements = new HashMap(); |
| |
| /** |
| * Try to parse an XML profile in a file in its XML vocabulary. If successful, |
| * you get the profile as RDF document (in XML format) to the standard output |
| * after it's been digested by the profile class. If not, then you get an |
| * exception. |
| * |
| * @param argv Command-line arguments, of which there should be one, the name of XML file containing the profile to parse |
| * @throws Throwable if an error occurs. |
| */ |
| public static void main(String[] argv) throws Throwable { |
| if (argv.length != 1) { |
| System.err.println("Usage: <profile.xml>"); |
| System.exit(1); |
| } |
| StringBuffer b = new StringBuffer(); |
| BufferedReader reader = new BufferedReader(new FileReader(argv[0])); |
| char[] buf = new char[512]; |
| int num; |
| while ((num = reader.read(buf)) != -1) |
| b.append(buf, 0, num); |
| reader.close(); |
| Profile p = new Profile(b.toString()); |
| |
| Model model = ModelFactory.createDefaultModel(); |
| p.addToModel(model); |
| OutputStreamWriter writer = new OutputStreamWriter(System.out); |
| model.write(writer); |
| writer.close(); |
| System.exit(0); |
| } |
| } |