[VIVO-1316] moving base lookup architecture for vocabulary services to Vitro (#55)
This commit is contained in:
parent
ed2b570d37
commit
1bc1f68548
10 changed files with 1019 additions and 0 deletions
|
@ -0,0 +1,25 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
package edu.cornell.mannlib.semservices.bo;
|
||||
|
||||
public class BaseObject {
|
||||
/**
|
||||
* Simple JavaBean domain object with an id property.
|
||||
* Used as a base class for objects needing this property.
|
||||
*/
|
||||
private Integer id;
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public boolean isNew() {
|
||||
return (this.id == null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,163 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.semservices.bo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Concept {
|
||||
|
||||
private String definedBy;
|
||||
private String conceptId;
|
||||
private String bestMatch;
|
||||
private String label;
|
||||
private String type;
|
||||
private String definition;
|
||||
private String uri;
|
||||
private String schemeURI;
|
||||
private List<String> broaderURIList;
|
||||
private List<String> narrowerURIList;
|
||||
private List<String> exactMatchURIList;
|
||||
private List<String> closeMatchURIList;
|
||||
private List<String> altLabelList;
|
||||
|
||||
/**
|
||||
* default constructor
|
||||
*/
|
||||
public Concept() {
|
||||
this.broaderURIList = new ArrayList<String>();
|
||||
this.narrowerURIList = new ArrayList<String>();
|
||||
this.exactMatchURIList = new ArrayList<String>();
|
||||
this.closeMatchURIList = new ArrayList<String>();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the conceptId
|
||||
*/
|
||||
public String getConceptId() {
|
||||
return conceptId;
|
||||
}
|
||||
/**
|
||||
* @param conceptId the conceptId to set
|
||||
*/
|
||||
public void setConceptId(String conceptId) {
|
||||
this.conceptId = conceptId;
|
||||
}
|
||||
/**
|
||||
* @return the label
|
||||
*/
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
/**
|
||||
* @param label the label to set
|
||||
*/
|
||||
public void setLabel(String label) {
|
||||
this.label = label;
|
||||
}
|
||||
/**
|
||||
* @return the type
|
||||
*/
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
/**
|
||||
* @param type the type to set
|
||||
*/
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
/**
|
||||
* @return the definition
|
||||
*/
|
||||
public String getDefinition() {
|
||||
return definition;
|
||||
}
|
||||
/**
|
||||
* @param definition the definition to set
|
||||
*/
|
||||
public void setDefinition(String definition) {
|
||||
this.definition = definition;
|
||||
}
|
||||
/**
|
||||
* @return the uri
|
||||
*/
|
||||
public String getUri() {
|
||||
return uri;
|
||||
}
|
||||
/**
|
||||
* @param uri the uri to set
|
||||
*/
|
||||
public void setUri(String uri) {
|
||||
this.uri = uri;
|
||||
}
|
||||
/**
|
||||
* @return the definedBy
|
||||
*/
|
||||
public String getDefinedBy() {
|
||||
return definedBy;
|
||||
}
|
||||
/**
|
||||
* @param definedBy the definedBy to set
|
||||
*/
|
||||
public void setDefinedBy(String definedBy) {
|
||||
this.definedBy = definedBy;
|
||||
}
|
||||
/**
|
||||
* @return the schemeURI
|
||||
*/
|
||||
public String getSchemeURI() {
|
||||
return schemeURI;
|
||||
}
|
||||
/**
|
||||
* @param schemeURI the schemeURI to set
|
||||
*/
|
||||
public void setSchemeURI(String schemeURI) {
|
||||
this.schemeURI = schemeURI;
|
||||
}
|
||||
/**
|
||||
* @return the bestMatch
|
||||
*/
|
||||
public String getBestMatch() {
|
||||
return bestMatch;
|
||||
}
|
||||
/**
|
||||
* @param bestMatch the bestMatch to set
|
||||
*/
|
||||
public void setBestMatch(String bestMatch) {
|
||||
this.bestMatch = bestMatch;
|
||||
}
|
||||
public List<String> getBroaderURIList() {
|
||||
return broaderURIList;
|
||||
}
|
||||
public void setBroaderURIList(List<String> broaderURIList) {
|
||||
this.broaderURIList = broaderURIList;
|
||||
}
|
||||
public List<String> getNarrowerURIList() {
|
||||
return narrowerURIList;
|
||||
}
|
||||
public void setNarrowerURIList(List<String> narrowerURIList) {
|
||||
this.narrowerURIList = narrowerURIList;
|
||||
}
|
||||
public List<String> getExactMatchURIList() {
|
||||
return exactMatchURIList;
|
||||
}
|
||||
public void setExactMatchURIList(List<String> exactMatchURIList) {
|
||||
this.exactMatchURIList = exactMatchURIList;
|
||||
}
|
||||
public List<String> getCloseMatchURIList() {
|
||||
return closeMatchURIList;
|
||||
}
|
||||
public void setCloseMatchURIList(List<String> closeMatchURIList) {
|
||||
this.closeMatchURIList = closeMatchURIList;
|
||||
}
|
||||
|
||||
public List<String> getAltLabelList() {
|
||||
return altLabelList;
|
||||
}
|
||||
|
||||
public void setAltLabelList(List<String> altLabelList) {
|
||||
this.altLabelList = altLabelList;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.semservices.bo;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class ConceptInfo extends SemanticServicesInfoBase {
|
||||
|
||||
private List<?> conceptList;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public ConceptInfo() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the conceptList
|
||||
*/
|
||||
public List<?> getConceptList() {
|
||||
return conceptList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param conceptList the conceptList to set
|
||||
*/
|
||||
public void setConceptList(List<?> conceptList) {
|
||||
this.conceptList = conceptList;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.semservices.bo;
|
||||
|
||||
public class SemanticServicesError {
|
||||
private String message;
|
||||
private String exception;
|
||||
private String severity;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public SemanticServicesError() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param exception Exception description
|
||||
* @param message Error message
|
||||
* @param severity Severity
|
||||
*/
|
||||
public SemanticServicesError(String exception, String message, String severity) {
|
||||
super();
|
||||
this.exception = exception;
|
||||
this.message = message;
|
||||
this.severity = severity;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return the message
|
||||
*/
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param message the message to set
|
||||
*/
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the exception
|
||||
*/
|
||||
public String getException() {
|
||||
return exception;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param exception the exception to set
|
||||
*/
|
||||
public void setException(String exception) {
|
||||
this.exception = exception;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the severity
|
||||
*/
|
||||
public String getSeverity() {
|
||||
return severity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param severity the severity to set
|
||||
*/
|
||||
public void setSeverity(String severity) {
|
||||
this.severity = severity;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.semservices.bo;
|
||||
|
||||
public class SemanticServicesInfoBase {
|
||||
|
||||
private SemanticServicesError semanticServicesError;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public SemanticServicesInfoBase() {
|
||||
super();
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the semanticServicesError
|
||||
*/
|
||||
public SemanticServicesError getSemanticServicesError() {
|
||||
return semanticServicesError;
|
||||
}
|
||||
/**
|
||||
* @param semanticServicesError the semanticServicesError to set
|
||||
*/
|
||||
public void setSemanticServicesError(SemanticServicesError semanticServicesError) {
|
||||
this.semanticServicesError = semanticServicesError;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.semservices.exceptions;
|
||||
|
||||
public class ConceptsNotFoundException extends Exception {
|
||||
/**
|
||||
* An exception that indicates a service could not find a Concept
|
||||
*/
|
||||
private static final long serialVersionUID = -4729465393290022840L;
|
||||
public ConceptsNotFoundException() { }
|
||||
public ConceptsNotFoundException(String message) { super(message); }
|
||||
public ConceptsNotFoundException(Throwable cause) { super(cause); }
|
||||
public ConceptsNotFoundException(String message, Throwable cause) { super(message, cause); }
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.semservices.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import edu.cornell.mannlib.semservices.bo.Concept;
|
||||
|
||||
public interface ExternalConceptService {
|
||||
|
||||
/**
|
||||
* @param term Term
|
||||
*/
|
||||
List<Concept> processResults(String term) throws Exception;
|
||||
|
||||
/**
|
||||
* @param term Term
|
||||
* @throws Exception
|
||||
*/
|
||||
List<Concept> getConcepts(String term) throws Exception;
|
||||
|
||||
/**
|
||||
* @param uri URI
|
||||
*/
|
||||
List<Concept> getConceptsByURIWithSparql(String uri) throws Exception;
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.semservices.util;
|
||||
import java.util.Iterator;
|
||||
import javax.xml.XMLConstants;
|
||||
import javax.xml.namespace.NamespaceContext;
|
||||
|
||||
public class MetadataNamespaceContext implements NamespaceContext {
|
||||
public String getNamespaceURI(String prefix) {
|
||||
if (prefix == null) throw new NullPointerException("Null prefix");
|
||||
else if ("mix".equals(prefix)) return "http://www.loc.gov/mix/";
|
||||
else if ("xml".equals(prefix)) return XMLConstants.XML_NS_URI;
|
||||
return XMLConstants.NULL_NS_URI;
|
||||
}
|
||||
|
||||
// This method isn't necessary for XPath processing.
|
||||
public String getPrefix(String uri) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
// This method isn't necessary for XPath processing either.
|
||||
public Iterator getPrefixes(String uri) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,266 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
/* We are no longer using the SKOS API since Vitro has moved to V 4.0 of OWL API which does not appear to be compatible.
|
||||
This file will contain methods used for reading SKOS as XML and parsing it for the properties
|
||||
we want to extract*/
|
||||
|
||||
package edu.cornell.mannlib.semservices.util;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.apache.jena.rdf.model.Model;
|
||||
import org.apache.jena.rdf.model.ModelFactory;
|
||||
import org.apache.jena.rdf.model.NodeIterator;
|
||||
import org.apache.jena.rdf.model.RDFNode;
|
||||
import org.apache.jena.rdf.model.ResourceFactory;
|
||||
import org.apache.jena.rdf.model.Statement;
|
||||
import org.apache.jena.rdf.model.StmtIterator;
|
||||
|
||||
import edu.cornell.mannlib.semservices.bo.Concept;
|
||||
|
||||
public class SKOSUtils {
|
||||
protected final static Log log = LogFactory.getLog(SKOSUtils.class);
|
||||
|
||||
public static String getConceptXML(String conceptUriString) {
|
||||
URL conceptURL = null;
|
||||
try {
|
||||
conceptURL = new URL(conceptUriString);
|
||||
} catch (Exception e) {
|
||||
log.error("Exception occurred in instantiating URL for "
|
||||
+ conceptUriString, e);
|
||||
// If the url is having trouble, just return null for the concept
|
||||
return null;
|
||||
}
|
||||
log.debug("loading concept uri " + conceptUriString);
|
||||
|
||||
String results = null;
|
||||
try {
|
||||
|
||||
StringWriter sw = new StringWriter();
|
||||
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(
|
||||
conceptURL.openStream()));
|
||||
String inputLine;
|
||||
while ((inputLine = in.readLine()) != null) {
|
||||
sw.write(inputLine);
|
||||
}
|
||||
in.close();
|
||||
|
||||
results = sw.toString();
|
||||
log.debug(results);
|
||||
} catch (Exception ex) {
|
||||
log.error("Error occurred in getting concept from the URL "
|
||||
+ conceptUriString, ex);
|
||||
return null;
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
// Downloading the XML from the URI itself
|
||||
// No language tag support here but can be specified if need be at this
|
||||
// level as well
|
||||
public static Concept createConceptUsingXMLFromURL(Concept concept,
|
||||
String conceptURLString, String langTagValue, boolean addNotes) {
|
||||
String results = getConceptXML(conceptURLString);
|
||||
if (StringUtils.isEmpty(results)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// return createConceptUsingXML(concept, results, langTagValue);
|
||||
return createConceptUsingXMLModel(concept, results, langTagValue,
|
||||
addNotes);
|
||||
|
||||
}
|
||||
|
||||
// Because of the fact the xml returns matches by tag name, and the XML may
|
||||
// look like <skos:narrower><skos:Concept ..><skos:broader
|
||||
// rdf:resource:"conceptURI">
|
||||
// where conceptURI is the concept that is the subject of skos:narrower, we
|
||||
// need to ensure we are not returning the same uri as that of the main
|
||||
// concept
|
||||
public static List<String> removeConceptURIFromList(List<String> uris,
|
||||
String conceptURI) {
|
||||
// remove will return a boolean if the value exists in the list and is
|
||||
// removed
|
||||
// if/when it returns false, the URI is not in the list
|
||||
while (uris.remove(conceptURI)) {
|
||||
}
|
||||
;
|
||||
return uris;
|
||||
}
|
||||
|
||||
/**
|
||||
* The above code, although functional, does not take advantage of the fact
|
||||
* that we can actually read and query the RDF in precisely the manner we
|
||||
* wish.
|
||||
*/
|
||||
|
||||
public static Concept createConceptUsingXMLModel(Concept concept,
|
||||
String results, String langTagValue, boolean addNotes) {
|
||||
|
||||
try {
|
||||
String conceptURI = concept.getUri();
|
||||
|
||||
// Load Model from RDF
|
||||
StringReader reader = new StringReader(results);
|
||||
Model model = ModelFactory.createDefaultModel();
|
||||
model.read(reader, null, "RDF/XML");
|
||||
|
||||
// Execute the following query to get the information we want for
|
||||
// this resource
|
||||
|
||||
// Preferred label
|
||||
List<String> labelLiterals = getPrefLabelsFromModel(conceptURI,
|
||||
model, langTagValue);
|
||||
if (labelLiterals.size() > 0) {
|
||||
concept.setLabel(labelLiterals.get(0));
|
||||
} else {
|
||||
// This is an error because there should be at least one label
|
||||
// returned
|
||||
log.debug("The number of preferred labels is not greater than zero");
|
||||
}
|
||||
|
||||
// Alternate label
|
||||
|
||||
List<String> altLabelList = getAltLabelsFromModel(conceptURI,
|
||||
model, langTagValue);
|
||||
concept.setAltLabelList(altLabelList);
|
||||
|
||||
// Broder, narrower, exact match, and close match properties
|
||||
|
||||
List<String> broaderURIList = getBroaderURIsFromModel(conceptURI,
|
||||
model);
|
||||
// broaderURIList = removeConceptURIFromList(broaderURIList,
|
||||
// conceptURI);
|
||||
concept.setBroaderURIList(broaderURIList);
|
||||
List<String> narrowerURIList = getNarrowerURIsFromModel(conceptURI,
|
||||
model);
|
||||
// narrowerURIList = removeConceptURIFromList(narrowerURIList,
|
||||
// conceptURI);
|
||||
concept.setNarrowerURIList(narrowerURIList);
|
||||
|
||||
List<String> exactMatchURIList = getExactMatchURIsFromModel(
|
||||
conceptURI, model);
|
||||
// exactMatchURIList = removeConceptURIFromList(exactMatchURIList,
|
||||
// conceptURI);
|
||||
concept.setExactMatchURIList(exactMatchURIList);
|
||||
List<String> closeMatchURIList = getCloseMatchURIsFromModel(
|
||||
conceptURI, model);
|
||||
// closeMatchURIList = removeConceptURIFromList(closeMatchURIList,
|
||||
// conceptURI);
|
||||
concept.setCloseMatchURIList(closeMatchURIList);
|
||||
|
||||
// Notes may exist, in which case they should be employed
|
||||
if (addNotes) {
|
||||
List<String> notes = getNotesFromModel(conceptURI, model,
|
||||
langTagValue);
|
||||
if (notes.size() > 0) {
|
||||
concept.setDefinition(notes.get(0));
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("error occurred in parsing " + results, e);
|
||||
}
|
||||
|
||||
return concept;
|
||||
|
||||
}
|
||||
|
||||
private static List<String> getPrefLabelsFromModel(String conceptURI,
|
||||
Model model, String langTagValue) {
|
||||
String propertyURI = "http://www.w3.org/2004/02/skos/core#prefLabel";
|
||||
return getLabelsFromModel(conceptURI, propertyURI, model, langTagValue);
|
||||
}
|
||||
|
||||
private static List<String> getAltLabelsFromModel(String conceptURI,
|
||||
Model model, String langTagValue) {
|
||||
String propertyURI = "http://www.w3.org/2004/02/skos/core#altLabel";
|
||||
return getLabelsFromModel(conceptURI, propertyURI, model, langTagValue);
|
||||
}
|
||||
|
||||
private static List<String> getLabelsFromModel(String conceptURI,
|
||||
String propertyURI, Model model, String langTagValue) {
|
||||
List<String> labels = new ArrayList<String>();
|
||||
StmtIterator statements = model.listStatements(
|
||||
ResourceFactory.createResource(conceptURI),
|
||||
ResourceFactory.createProperty(propertyURI), (RDFNode) null);
|
||||
while (statements.hasNext()) {
|
||||
Statement statement = statements.nextStatement();
|
||||
RDFNode node = statement.getObject();
|
||||
if (node != null && node.isLiteral()) {
|
||||
String label = node.asLiteral().getString();
|
||||
if (StringUtils.isNotEmpty(langTagValue)) {
|
||||
String language = node.asLiteral().getLanguage();
|
||||
if (language != null && language.equals(langTagValue)) {
|
||||
labels.add(label);
|
||||
}
|
||||
} else {
|
||||
labels.add(label);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return labels;
|
||||
}
|
||||
|
||||
private static List<String> getNotesFromModel(String conceptURI,
|
||||
Model model, String langTagValue) {
|
||||
String propertyURI = "http://www.w3.org/2004/02/skos/core#note";
|
||||
return getLabelsFromModel(conceptURI, propertyURI, model, langTagValue);
|
||||
}
|
||||
|
||||
private static List<String> getCloseMatchURIsFromModel(String conceptURI,
|
||||
Model model) {
|
||||
String propertyURI = "http://www.w3.org/2004/02/skos/core#closeMatch";
|
||||
return getRelatedURIsFromModel(conceptURI, propertyURI, model);
|
||||
|
||||
}
|
||||
|
||||
private static List<String> getExactMatchURIsFromModel(String conceptURI,
|
||||
Model model) {
|
||||
String propertyURI = "http://www.w3.org/2004/02/skos/core#exactMatch";
|
||||
return getRelatedURIsFromModel(conceptURI, propertyURI, model);
|
||||
}
|
||||
|
||||
private static List<String> getNarrowerURIsFromModel(String conceptURI,
|
||||
Model model) {
|
||||
String propertyURI = "http://www.w3.org/2004/02/skos/core#narrower";
|
||||
return getRelatedURIsFromModel(conceptURI, propertyURI, model);
|
||||
}
|
||||
|
||||
private static List<String> getBroaderURIsFromModel(String conceptURI,
|
||||
Model model) {
|
||||
String propertyURI = "http://www.w3.org/2004/02/skos/core#broader";
|
||||
return getRelatedURIsFromModel(conceptURI, propertyURI, model);
|
||||
}
|
||||
|
||||
private static List<String> getRelatedURIsFromModel(String conceptURI,
|
||||
String propertyURI, Model model) {
|
||||
List<String> URIs = new ArrayList<String>();
|
||||
NodeIterator nodeIterator = model.listObjectsOfProperty(
|
||||
ResourceFactory.createResource(conceptURI),
|
||||
ResourceFactory.createProperty(propertyURI));
|
||||
|
||||
while (nodeIterator.hasNext()) {
|
||||
RDFNode node = nodeIterator.nextNode();
|
||||
if (node.isResource() && node.asResource().getURI() != null) {
|
||||
String URI = node.asResource().getURI();
|
||||
URIs.add(URI);
|
||||
}
|
||||
}
|
||||
|
||||
return URIs;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,361 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.semservices.util;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.OutputKeys;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerConfigurationException;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.TransformerFactoryConfigurationError;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
import javax.xml.xpath.XPath;
|
||||
import javax.xml.xpath.XPathConstants;
|
||||
import javax.xml.xpath.XPathExpressionException;
|
||||
import javax.xml.xpath.XPathFactory;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.DocumentType;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
* Convenience Class to parse XML strings to DOM Document for XML contents
|
||||
* retrieval.
|
||||
*/
|
||||
public class XMLUtils {
|
||||
private static DocumentBuilder parser;
|
||||
public static Writer writer;
|
||||
static private String indent = "";
|
||||
protected static final Log logger = LogFactory.getLog(XMLUtils.class);
|
||||
|
||||
|
||||
/**
|
||||
* @throws ParserConfigurationException
|
||||
*/
|
||||
public static DocumentBuilder getDocumentBuilder()
|
||||
throws ParserConfigurationException {
|
||||
if (parser == null) {
|
||||
// JPT: Remove xerces use
|
||||
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory
|
||||
.newInstance();
|
||||
documentBuilderFactory.setNamespaceAware(true);
|
||||
documentBuilderFactory.setValidating(false);
|
||||
parser = documentBuilderFactory.newDocumentBuilder();
|
||||
}
|
||||
|
||||
return parser;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param xmlString XML String
|
||||
* @throws IOException
|
||||
* @throws SAXException
|
||||
* @throws ParserConfigurationException
|
||||
*/
|
||||
public synchronized static Document parse(String xmlString)
|
||||
throws IOException, SAXException, ParserConfigurationException {
|
||||
StringReader reader = new StringReader(xmlString);
|
||||
InputSource inputSource = new InputSource(reader);
|
||||
return getDocumentBuilder().parse(inputSource);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param stream Input stream
|
||||
* @throws IOException
|
||||
* @throws SAXException
|
||||
* @throws ParserConfigurationException
|
||||
*/
|
||||
public synchronized static Document parse(InputStream stream)
|
||||
throws IOException, SAXException, ParserConfigurationException {
|
||||
return getDocumentBuilder().parse(stream);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param document DOM Document
|
||||
* @param name Name
|
||||
*/
|
||||
public static String getElementByName(Document document, String name) {
|
||||
NodeList nodes = document.getElementsByTagName(name);
|
||||
String s = null;
|
||||
for (int i=0; i < nodes.getLength() ; i++) {
|
||||
Node node = nodes.item(i);
|
||||
s = node.getTextContent().trim();
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param doc DOM Document
|
||||
* @throws IOException
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void serializeDoc(Document doc) throws IOException {
|
||||
org.apache.xml.serialize.XMLSerializer serializer = new org.apache.xml.serialize.XMLSerializer();
|
||||
serializer.setOutputByteStream(System.out);
|
||||
serializer.serialize(doc);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static String serializeDoctoString(Document doc) throws IOException {
|
||||
org.apache.xml.serialize.XMLSerializer serializer = new org.apache.xml.serialize.XMLSerializer();
|
||||
ByteArrayOutputStream bout = new ByteArrayOutputStream();
|
||||
|
||||
serializer.setOutputByteStream(bout);
|
||||
serializer.serialize(doc);
|
||||
return bout.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param xml XML String
|
||||
*/
|
||||
public static void prettyPrint(String xml) {
|
||||
Source xmlInput = new StreamSource(new StringReader(xml));
|
||||
StreamResult xmlOutput = new StreamResult(new StringWriter());
|
||||
Transformer transformer = null;
|
||||
try {
|
||||
transformer = TransformerFactory.newInstance().newTransformer();
|
||||
} catch (TransformerConfigurationException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (TransformerFactoryConfigurationError e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
//transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "testing.dtd");
|
||||
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
|
||||
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
|
||||
try {
|
||||
transformer.transform(xmlInput, xmlOutput);
|
||||
} catch (TransformerException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
String formattedxml=xmlOutput.getWriter().toString();
|
||||
System.out.println(formattedxml);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param xml XML String
|
||||
*/
|
||||
public static String prettyPrintToString(String xml) {
|
||||
Source xmlInput = new StreamSource(new StringReader(xml));
|
||||
StreamResult xmlOutput = new StreamResult(new StringWriter());
|
||||
Transformer transformer = null;
|
||||
try {
|
||||
transformer = TransformerFactory.newInstance().newTransformer();
|
||||
} catch (TransformerConfigurationException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (TransformerFactoryConfigurationError e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
//transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "testing.dtd");
|
||||
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
|
||||
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
|
||||
try {
|
||||
transformer.transform(xmlInput, xmlOutput);
|
||||
} catch (TransformerException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
String formattedxml=xmlOutput.getWriter().toString();
|
||||
return formattedxml;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param node DOM Node
|
||||
*/
|
||||
public static void displayNodeInfo(Node node) {
|
||||
switch (node.getNodeType()) {
|
||||
case Node.DOCUMENT_NODE:
|
||||
System.out.println("Document Node ");
|
||||
break;
|
||||
case Node.ELEMENT_NODE:
|
||||
System.out.println("Element Node: "+ node.getNodeName());
|
||||
break;
|
||||
case Node.TEXT_NODE:
|
||||
System.out.println("Text Node: "+ node.getNodeName());
|
||||
break;
|
||||
case Node.CDATA_SECTION_NODE:
|
||||
System.out.println("CDATA Section Node: ");
|
||||
break;
|
||||
case Node.COMMENT_NODE:
|
||||
System.out.println("Comment Node ");
|
||||
break;
|
||||
case Node.PROCESSING_INSTRUCTION_NODE:
|
||||
System.out.println("Processing Instruction Node ");
|
||||
break;
|
||||
case Node.ENTITY_REFERENCE_NODE:
|
||||
System.out.println("Entity Reference Node ");
|
||||
break;
|
||||
case Node.DOCUMENT_TYPE_NODE:
|
||||
System.out.println("Document Type Node ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param node DOM Node
|
||||
* @throws IOException
|
||||
*/
|
||||
public static void serializeNode(Node node) throws IOException {
|
||||
if (writer == null) writer = new BufferedWriter(new OutputStreamWriter(System.out));
|
||||
|
||||
switch (node.getNodeType()) {
|
||||
case Node.DOCUMENT_NODE:
|
||||
Document doc = (Document) node;
|
||||
writer.write("<?xml version=\"");
|
||||
writer.write(doc.getXmlVersion());
|
||||
writer.write("\" encoding=\"UTF-8\" standalone=\"");
|
||||
if (doc.getXmlStandalone())
|
||||
writer.write("yes");
|
||||
else
|
||||
writer.write("no");
|
||||
writer.write("\"?>\n");
|
||||
|
||||
NodeList nodes = node.getChildNodes();
|
||||
if (nodes != null)
|
||||
for (int i = 0; i < nodes.getLength(); i++)
|
||||
serializeNode(nodes.item(i));
|
||||
break;
|
||||
case Node.ELEMENT_NODE:
|
||||
String name = node.getNodeName();
|
||||
writer.write("<" + name);
|
||||
NamedNodeMap attributes = node.getAttributes();
|
||||
for (int i = 0; i < attributes.getLength(); i++) {
|
||||
Node current = attributes.item(i);
|
||||
writer.write(" " + current.getNodeName() + "=\"");
|
||||
print(current.getNodeValue());
|
||||
writer.write("\"");
|
||||
}
|
||||
writer.write(">");
|
||||
|
||||
NodeList children = node.getChildNodes();
|
||||
if (children != null) {
|
||||
//if ((children.item(0) != null) && (children.item(0).getNodeType() == Node.ELEMENT_NODE))
|
||||
// writer.write("\n");
|
||||
|
||||
for (int i = 0; i < children.getLength(); i++)
|
||||
serializeNode(children.item(i));
|
||||
if ((children.item(0) != null)
|
||||
&& (children.item(children.getLength() - 1).getNodeType() == Node.ELEMENT_NODE))
|
||||
writer.write("");
|
||||
}
|
||||
|
||||
writer.write("</" + name + ">");
|
||||
break;
|
||||
case Node.TEXT_NODE:
|
||||
print(node.getNodeValue());
|
||||
break;
|
||||
case Node.CDATA_SECTION_NODE:
|
||||
writer.write("CDATA");
|
||||
print(node.getNodeValue());
|
||||
writer.write("");
|
||||
break;
|
||||
case Node.COMMENT_NODE:
|
||||
writer.write("<!-- " + node.getNodeValue() + " -->\n");
|
||||
break;
|
||||
case Node.PROCESSING_INSTRUCTION_NODE:
|
||||
writer.write("<?" + node.getNodeName() + " " + node.getNodeValue() + "?>\n");
|
||||
break;
|
||||
case Node.ENTITY_REFERENCE_NODE:
|
||||
writer.write("&" + node.getNodeName() + ";");
|
||||
break;
|
||||
case Node.DOCUMENT_TYPE_NODE:
|
||||
DocumentType docType = (DocumentType) node;
|
||||
String publicId = docType.getPublicId();
|
||||
String systemId = docType.getSystemId();
|
||||
String internalSubset = docType.getInternalSubset();
|
||||
writer.write("<!DOCTYPE " + docType.getName());
|
||||
if (publicId != null)
|
||||
writer.write(" PUBLIC \"" + publicId + "\" ");
|
||||
else
|
||||
writer.write(" SYSTEM ");
|
||||
writer.write("\"" + systemId + "\"");
|
||||
if (internalSubset != null)
|
||||
writer.write(" [" + internalSubset + "]");
|
||||
writer.write(">\n");
|
||||
break;
|
||||
}
|
||||
writer.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param s String
|
||||
* @throws IOException
|
||||
*/
|
||||
private static void print(String s) throws IOException {
|
||||
if (s == null)
|
||||
return;
|
||||
for (int i = 0, len = s.length(); i < len; i++) {
|
||||
char c = s.charAt(i);
|
||||
switch (c) {
|
||||
case '<':
|
||||
writer.write("<");
|
||||
break;
|
||||
case '>':
|
||||
writer.write(">");
|
||||
break;
|
||||
case '&':
|
||||
writer.write("&");
|
||||
break;
|
||||
case '\r':
|
||||
writer.write("
");
|
||||
break;
|
||||
default:
|
||||
writer.write(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param obj (either a Document or a Node)
|
||||
* @param expression Expression
|
||||
* @return string contents
|
||||
*/
|
||||
public static Node getNodeWithXpath(Object obj, String expression) {
|
||||
Object root = null;
|
||||
if (obj instanceof Document) {
|
||||
Document doc = (Document) obj;
|
||||
root = doc.getDocumentElement();
|
||||
} else {
|
||||
root = (Node) obj;
|
||||
}
|
||||
|
||||
XPath xpath = XPathFactory.newInstance().newXPath();
|
||||
xpath.setNamespaceContext(new MetadataNamespaceContext());
|
||||
Node result = null;
|
||||
|
||||
try {
|
||||
result = ((Node) xpath.evaluate(expression, root, XPathConstants.NODE));
|
||||
return result;
|
||||
} catch (XPathExpressionException e) {
|
||||
logger.error("XPathExpressionException ", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Reference in a new issue