Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2016 SimplifyOps, Inc. (http://simplifyops.com)
*
* Licensed 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.
*/
/*
* ResourceXMLParser.java
*
* User: Greg Schueler [email protected]
* Created: Apr 23, 2010 3:35:55 PM
* $Id$
*/
package com.dtolabs.shared.resources;
import static com.dtolabs.shared.resources.ResourceXMLConstants.*;
import org.dom4j.*;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import java.io.*;
import java.util.*;
/**
* ResourceXMLParser parses a resources.xml formatted file, and provides several interfaces for using the result data.
*
* The {@link #parse()} method parses the configured File as a sequence of {@link com.dtolabs.shared.resources.ResourceXMLParser.Entity}
* objects, one for each entry in the file. It passes these objects to any configured {@link com.dtolabs.shared.resources.ResourceXMLReceiver}
* object. One should be set using {@link
* #setReceiver(ResourceXMLReceiver)} to receive parsed entities or the entire entity set.
*
* The default entityXpath property value is set to match all entity types in the resource xml
* (node|setting|package|deployment), but this can be set to any Xpath to limit the entities that are
* parsed from the document. (e.g. "node|package" or "node[@name='mynode']").
*
*
* @author Greg Schueler [email protected]
* @version $Revision$
*/
public class ResourceXMLParser {
static Logger log4j = LoggerFactory.getLogger(ResourceXMLParser.class.getName());
private File file;
private InputStream input;
private Document doc;
private ResourceXMLReceiver receiver;
public static final String DEFAULT_ENTITY_XPATH = NODE_ENTITY_TAG ;
private String entityXpath = DEFAULT_ENTITY_XPATH;
/**
* Constructor for the ResourceXMLParser
*
* @param file source file
*/
public ResourceXMLParser(final File file) {
this.file = file;
}
/**
* Constructor for the ResourceXMLParser
*
* @param input source file
*/
public ResourceXMLParser(final InputStream input) {
this.input = input;
}
/**
* Constructor for the ResourceXMLParser
*
* @param doc source document
*/
public ResourceXMLParser(final Document doc) {
this.doc = doc;
}
/**
* Parse the document, applying the configured Receiver to the parsed entities
*
* @throws ResourceXMLParserException parse error
* @throws java.io.IOException io error
*/
public void parse() throws ResourceXMLParserException, IOException {
final EntityResolver resolver = createEntityResolver();
final SAXReader reader = new SAXReader(false);
reader.setEntityResolver(resolver);
try {
final Document doc;
if(null==this.doc){
final InputStream in;
if(null!=file){
in = new FileInputStream(file);
}else{
in = input;
}
try{
doc=reader.read(in);
}finally{
if(null!=file){
in.close();
}
}
}else{
doc=this.doc;
}
final EntitySet set = new EntitySet();
final Element root = doc.getRootElement();
final List list = root.selectNodes(entityXpath);
for (final Object n : list) {
final Node node = (Node) n;
final Entity ent = parseEnt(node, set);
if (null != receiver) {
if (!receiver.resourceParsed(ent)) {
break;
}
}
}
if (null != receiver) {
receiver.resourcesParsed(set);
}
} catch (DocumentException e) {
throw new ResourceXMLParserException(e);
}
}
public static EntityResolver createEntityResolver() {
return new EntityResolver() {
public InputSource resolveEntity(final String publicId, final String systemId) {
if (publicId.equals(DTD_PROJECT_DOCUMENT_1_0_EN)) {
final InputStream in = ResourceXMLParser.class.getClassLoader().getResourceAsStream(
PROJECT_DTD_RESOURCE_PATH);
if (null != in) {
return new InputSource(in);
} else {
System.err.println(
"couldn't load resource " + PROJECT_DTD_RESOURCE_PATH + ":" + ResourceXMLParser.class
.getClassLoader().getResource(PROJECT_DTD_RESOURCE_PATH));
final File file1 = new File("src/java/" + PROJECT_DTD_RESOURCE_PATH);
if (file1.exists()) {
try {
return new InputSource(new FileInputStream(file1));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
}
return null;
}
};
}
/**
* Given xml Node and EntitySet, parse the entity defined in the Node
*
* @param node DOM node
* @param set entity set holder
*
* @return parsed Entity object
*
* @throws ResourceXMLParserException if entity definition was previously found, or another error occurs
*/
private Entity parseEnt(final Node node, final EntitySet set) throws ResourceXMLParserException {
final Entity ent = parseResourceRef(set, node);
ent.setResourceType(node.getName());
parseEntProperties(ent, node);
parseEntSubAttributes(ent, node);
return ent;
}
/**
* Parse a simple resource/entity node for the type/name attributes, returning a new or existing Entity
*
* @param set entity set
* @param n entity DOM node
*
* @return new or existing Entity
*
* @throws ResourceXMLParserException if the ndoe is missing the required attributes
*/
private Entity parseResourceRef(final EntitySet set, final Node n) throws ResourceXMLParserException {
final Node node2 = n.selectSingleNode("@" + COMMON_NAME);
if (null == node2) {
throw new ResourceXMLParserException("@" + COMMON_NAME + " required: " + reportNodeErrorLocation(n));
}
final String rname = node2.getStringValue();
return set.getOrCreateEntity( rname);
}
private static final HashMap entityProperties = new HashMap();
static {
entityProperties.put(NODE_ENTITY_TAG, nodeProps);
}
/**
* Parse the DOM attributes as properties for the particular entity node type
*
* @param ent Entity object
* @param node entity DOM node
*
* @throws ResourceXMLParserException if the DOM node is an unexpected tag name
*/
private void parseEntProperties(final Entity ent, final Node node) throws ResourceXMLParserException {
if (null == entityProperties.get(node.getName())) {
throw new ResourceXMLParserException(
"Unexpected entity declaration: " + node.getName() + ": " + reportNodeErrorLocation(node));
}
final Element node1 = (Element) node;
//load all element attributes as properties
for (final Object o : node1.attributes()) {
final Attribute attr = (Attribute) o;
ent.properties.setProperty(attr.getName(), attr.getStringValue());
}
}
/**
* Parse the DOM attributes as properties for the particular entity node type
*
* @param ent Entity object
* @param node entity DOM node
*
* @throws ResourceXMLParserException if the DOM node is an unexpected tag name
*/
private void parseEntSubAttributes(final Entity ent, final Node node) throws ResourceXMLParserException {
final Element node1 = (Element) node;
//load all sub elements called "attribute" as properties
for (final Object attribute : node1.selectNodes(ATTRIBUTE_TAG)) {
Element attr=(Element) attribute;
if(null==attr.selectSingleNode("@" + ATTRIBUTE_NAME_ATTR)) {
throw new ResourceXMLParserException(
ATTRIBUTE_TAG + " element has no '" + ATTRIBUTE_NAME_ATTR + "' attribute: "
+ reportNodeErrorLocation(attr));
}
String attrname = attr.selectSingleNode("@" + ATTRIBUTE_NAME_ATTR).getStringValue();
String attrvalue;
//look for "value" attribute
if(null!=attr.selectSingleNode("@"+ATTRIBUTE_VALUE_ATTR)) {
attrvalue = attr.selectSingleNode("@" + ATTRIBUTE_VALUE_ATTR).getStringValue();
}else if(null!= attr.getText()) {
//look for text content
attrvalue = attr.getText();
}else {
throw new ResourceXMLParserException(
ATTRIBUTE_TAG + " element has no '" + ATTRIBUTE_VALUE_ATTR + "' attribute or text content: "
+ reportNodeErrorLocation(attr));
}
ent.properties.setProperty(attrname, attrvalue);
}
}
/**
* Return a String describing the DOM node's location and parent type name
*
* @param e the node
*
* @return string describing xpath location and parent "type" element name
*/
protected static String reportNodeErrorLocation(final Node e) {
return "at xpath " + e.getUniquePath();
}
/**
* Return the ResourceXMLReceiver
*
* @return the ResourceXMLReceiver
*/
public ResourceXMLReceiver getReceiver() {
return receiver;
}
/**
* Set the ResourceXMLReceiver to use. It will be invoked to receive the {@link
* com.dtolabs.shared.resources.ResourceXMLParser.Entity} objects created during the {@link #parse()} method,
* and will also receive the complete {@link com.dtolabs.shared.resources.ResourceXMLParser.EntitySet} at the
* end of the sequence. It can govern whether parsing should continue or not, see {@link
* com.dtolabs.shared.resources.ResourceXMLReceiver}
*
* @param receiver the new ResourceXMLReceiver
*/
public void setReceiver(final ResourceXMLReceiver receiver) {
this.receiver = receiver;
}
/**
* Contains the set of parsed entities from the document.
*/
public static class EntitySet {
private HashMap entcache = new HashMap();
void addEntity(final Entity ent) {
entcache.put(ent.getId(), ent);
}
boolean containsEntity(final String name) {
return entcache.containsKey(name);
}
Entity createEntity( final String name) {
final Entity ent = new Entity();
ent.setName(name);
ent.set = this;
addEntity(ent);
return ent;
}
Entity getOrCreateEntity(final String name) {
if (containsEntity(name)) {
return entcache.get(name);
}
return createEntity(name);
}
/**
* Return the collection of entities.
*
* @return the entities.
*/
public Collection getEntities() {
return entcache.values();
}
}
/**
* Represents a parsed resource entity in the xml, which consists of a name property, a type property, and a set of
* name/value properties. These property names correspond to the attribute names of the type of entity being
* parsed. See {@link com.dtolabs.shared.resources.ResourceXMLConstants} for property names.
*
* The specific entity declaration type (node,setting,package,deployment) can be found with the {@link
* #getResourceType()} method. This method will return null if the entity is a resource-reference with no
* corresponding entity definition in the XML.
*
* Two special properties, "resources.replace" and "referrers.replace" correspond to the values of the "replace"
* attribute on any embedded resource/referrer references for the entity.
*/
public static class Entity {
private EntitySet set;
Entity() {
this.properties = new Properties();
}
private Properties properties;
private String name;
private String resourceType;
public String getId() {
return name;
}
public String getName() {
return name;
}
void setName(final String name) {
this.name = name;
}
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final Entity entity = (Entity) o;
if (name != null ? !name.equals(entity.name) : entity.name != null) {
return false;
}
return true;
}
@Override
public int hashCode() {
int result = set != null ? set.hashCode() : 0;
result = 31 * result + (properties != null ? properties.hashCode() : 0);
result = 31 * result + (name != null ? name.hashCode() : 0);
return result;
}
public Properties getProperties() {
return properties;
}
public String getProperty(final String prop) {
return properties.getProperty(prop);
}
public void setProperty(final String prop, final String value) {
properties.setProperty(prop, value);
}
/**
* Return the name of the resource xml "tag" defining this entity, or null if it is a resource reference
*
* @return the name of the resource xml "tag" defining this entity, or null if it is a resource reference
*/
public String getResourceType() {
return resourceType;
}
void setResourceType(final String resourceType) {
this.resourceType = resourceType;
}
}
}