blob: 76ee160b5e11e33d44d90e6f06a578c01c17d6e7 [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.netbeans.modules.xml.axi.util;
import java.io.FileReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.netbeans.modules.xml.axi.AXIComponent;
import org.netbeans.modules.xml.axi.AXIDocument;
import org.netbeans.modules.xml.axi.AnyAttribute;
import org.netbeans.modules.xml.axi.Attribute;
import org.netbeans.modules.xml.axi.Element;
import org.netbeans.modules.xml.axi.visitor.PrintAXITreeVisitor;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
/**
* Test visitor to visit all children in the AXI tree.
* @author Samaresh
*/
public class ModelValidator extends PrintAXITreeVisitor {
private String errorMessage;
private boolean success;
private URL expectedFileURL;
private FileReader expectedFileReader;
/**
* Creates a new instance of AXITreeVisitor
*/
public ModelValidator(URL url) {
this.success = true;
this.expectedFileURL = url;
}
public boolean visitAndCompareAgainstDOMElement(Element element) {
this.visit(element);
return success;
}
public void visit(Attribute attr) {
//do nothing
}
public void visit(AnyAttribute attr) {
//do nothing
}
protected void visitChildren(AXIComponent component) {
if(canCompare()) {
if(!compare(component))
return;
}
super.visitChildren(component);
}
public String getErrorMessage() {
return errorMessage;
}
private boolean canCompare() {
if(expectedFileURL == null)
return false;
return true;
}
/**
* Compares AXI component against corresponding DOM element.
*/
private boolean compare(AXIComponent axiNode) {
FileUtil util = FileUtil.getInstance();
try {
InputSource inputSource = util.openFile(expectedFileURL);
if(inputSource == null) {
success = false;
return false;
}
String expression = getExpression(axiNode);
XPath xpath = XPathFactory.newInstance().newXPath();
Node domNode = (Node) xpath.evaluate(expression, inputSource, XPathConstants.NODE);
if(!axiNode.toString().equals(domNode.getNodeName())) {
success = false;
errorMessage = "Expected AXI node " + axiNode + ", but found DOM node " + domNode.getNodeName();
return false;
}
if(!compareChildren(axiNode, domNode)) {
return false;
}
} catch(Exception ex) {
ex.printStackTrace();
success = false;
errorMessage = "Exception: " + ex.getMessage();
return false;
} finally {
util.closeFile();
}
return true;
}
/**
* Compares each child of an AXI component against
* corresponding DOM element's child.
*/
private boolean compareChildren(AXIComponent axiNode, Node domNode) {
//compare sizes
Collection<AXIComponent> axiChildren = getChildren(axiNode);
Collection<Node> domChildren = getChildren(domNode);
if( axiChildren.size() != domChildren.size() ) {
success = false;
errorMessage = "For AXI node " + axiNode +
", expected child count is " + axiChildren.size() +
" where as, actual count is " + domChildren.size();
return success;
}
Collection<Attribute> attrs = axiNode.getChildren(Attribute.class);
if( attrs.size() != domNode.getAttributes().getLength() ) {
success = false;
errorMessage = "For AXI node " + axiNode +
", expected attribute count is " + attrs.size() +
" where as, actual count is " + domNode.getAttributes().getLength();
return success;
}
Iterator<AXIComponent> axiIterator = axiChildren.iterator();
Iterator<Node> domIterator = domChildren.iterator();
while(axiIterator.hasNext() && domIterator.hasNext()) {
AXIComponent axiChild = axiIterator.next();
Node domChild = domIterator.next();
if(!axiChild.toString().equals(domChild.getNodeName())) {
success = false;
errorMessage = "For AXI node " + axiNode +
", expecting child " + axiChild +
" where as, found child " + domChild.getNodeName();
return success;
}
}
return true;
}
private String getExpression(AXIComponent component) {
if(component.getParent() instanceof AXIDocument)
return "/" + component;
return getExpression(component.getParent()) + "/" + component;
}
private Collection<Node> getChildren(Node node) {
Collection<Node> nodes = new ArrayList<Node>();
NodeList children = node.getChildNodes();
for(int i=0; i<children.getLength(); i++) {
Node child = children.item(i);
if(child.getNodeType() != Node.ELEMENT_NODE)
continue;
nodes.add(child);
}
return nodes;
}
private Collection<AXIComponent> getChildren(AXIComponent component) {
Collection<AXIComponent> children = new ArrayList<AXIComponent>();
for(AXIComponent child : component.getChildren()) {
if(child instanceof Attribute)
continue;
children.add(child);
}
return children;
}
}