blob: 63e5a6a962a2929497ffb2225dc8d9db337192ba [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.pushpull.filerestrictions.parsers;
//OODT imports
import org.apache.oodt.cas.metadata.Metadata;
import org.apache.oodt.cas.metadata.util.PathUtils;
import org.apache.oodt.cas.pushpull.filerestrictions.Parser;
import org.apache.oodt.cas.pushpull.filerestrictions.VirtualFile;
import org.apache.oodt.cas.pushpull.filerestrictions.VirtualFileStructure;
import org.apache.oodt.cas.pushpull.exceptions.ParserException;
import org.apache.oodt.cas.pushpull.expressions.GlobalVariables;
import org.apache.oodt.cas.pushpull.expressions.Method;
import org.apache.oodt.cas.pushpull.expressions.Variable;
import org.apache.oodt.commons.xml.XMLUtils;
//JDK imports
import java.io.FileInputStream;
import java.util.HashMap;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.DOMException;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
/**
*
* @author bfoster
* @version $Revision$
*
* <p>
* Describe your class here
* </p>.
*/
public class DirStructXmlParser implements Parser {
private static final Logger LOG = Logger.getLogger(DirStructXmlParser.class
.getName());
private static final HashMap<String, Method> methodRepo = new HashMap<String, Method>();
public DirStructXmlParser() {}
public VirtualFileStructure parse(FileInputStream xmlFile, Metadata metadata)
throws ParserException {
try {
String initialCdDir = "/";
VirtualFile root = null;
NodeList list = (DocumentBuilderFactory.newInstance()
.newDocumentBuilder().parse(new InputSource(xmlFile)))
.getDocumentElement().getChildNodes();
VirtualFile currentFile = null;
for (int i = 0; i < list.getLength(); i++) {
Node node = list.item(i);
if (node.getNodeName().equals("dirstruct")) {
// parse out starting path
String startingPath = ((Element) node)
.getAttribute("starting_path");
if (startingPath != null) {
root = (currentFile = new VirtualFile(
initialCdDir = startingPath, true))
.getRootDir();
VirtualFile temp = currentFile.getParentFile();
while (temp != null) {
temp.setNoDirs(true);
temp.setNoFiles(true);
temp = temp.getParentFile();
}
} else {
currentFile = root = VirtualFile.createRootDir();
}
// parse the directory structure
parseDirstructXML(node.getChildNodes(), currentFile);
} else if (node.getNodeName().equals("variables")) {
parseVariablesXML(node.getChildNodes());
} else if (node.getNodeName().equals("methods")) {
parseMethodsXML(node.getChildNodes());
}
}
return new VirtualFileStructure(initialCdDir, root);
} catch (Exception e) {
e.printStackTrace();
throw new ParserException("Failed to parse XML file : "
+ e.getMessage());
}
}
private void parseDirstructXML(NodeList list, VirtualFile currentLoadFile) {
for (int i = 0; i < list.getLength(); i++) {
Node dir = list.item(i);
if (dir.getNodeName().equals("dir")) {
String dirName = replaceVariablesAndMethods(((Element) dir)
.getAttribute("name"));
currentLoadFile.addChild(new VirtualFile(dirName, true));
NodeList children;
if ((children = dir.getChildNodes()).getLength() > 0) {
parseDirstructXML(children, currentLoadFile.getChild(
dirName, true));
}
} else if (dir.getNodeName().equals("nodirs")) {
currentLoadFile.setNoDirs(true);
} else if (dir.getNodeName().equals("nofiles")) {
currentLoadFile.setNoFiles(true);
} else if (dir.getNodeName().equals("file")) {
VirtualFile vf = new VirtualFile(
replaceVariablesAndMethods(((Element) dir)
.getAttribute("name")), false);
vf.setNoDirs(true);
currentLoadFile.addChild(vf);
}
}
}
private String replaceVariablesAndMethods(String input) {
for (int i = 0; i < input.length(); i++) {
char c = input.charAt(i);
switch (c) {
case '$':
try {
if (input.charAt(i + 1) == '{') {
StringBuffer variable = new StringBuffer("");
for (int j = i + 2; j < input.length(); j++) {
char ch = input.charAt(j);
if ((ch <= 'Z' && ch >= 'A')
|| (ch <= 'z' && ch >= 'a')
|| (ch <= '9' && ch >= '0')
|| ch == '_')
variable.append(ch);
else
break;
}
Variable v = GlobalVariables.hashMap.get(variable
.toString());
if (v == null)
throw new Exception("No variable defined with name '" + variable.toString() + "'");
input = input.replaceFirst("\\$\\{" + variable + "\\}", v.toString());
i = i + v.toString().length();
}
} catch (Exception e) {
LOG.log(Level.WARNING, "Failed to replace variable in '" + input + " for i = '" + i + "' : " + e.getMessage(), e);
}
break;
case '%':
try {
StringBuffer method = new StringBuffer("");
int j = i + 1;
for (; j < input.length(); j++) {
char ch = input.substring(j, j + 1).charAt(0);
if ((ch <= 'Z' && ch >= 'A')
|| (ch <= 'z' && ch >= 'a')
|| (ch <= '9' && ch >= '0') || ch == '_')
method.append(ch);
else
break;
}
if (input.substring(j, j + 1).charAt(0) == '(') {
Method m = methodRepo.get(method.toString());
StringTokenizer st = new StringTokenizer(input
.substring(j, input.substring(j).indexOf(")")
+ j), "#\", ()");
while (st.hasMoreTokens()) {
String arg = st.nextToken();
m.addArg(null, arg);
}
String returnValue = m.execute().toString();
input = input.substring(0, i)
+ returnValue
+ input.substring(input.substring(i).indexOf(
")")
+ 1 + i);
i = i + returnValue.length();
} else {
LOG.log(Level.SEVERE, "Invalid method signature in "
+ input + " near " + method);
break;
}
} catch (Exception e) {
}
break;
}
}
return input;
}
private void parseVariablesXML(NodeList list) throws DOMException, Exception {
// loop through all variable elements
for (int i = 0; i < list.getLength(); i++) {
Node node = list.item(i);
// parse variable element
if (node.getNodeName().equals("variable")) {
NodeList children = node.getChildNodes();
// create Variable Object
String variableName = ((Element) node).getAttribute("name");
Variable variable = new Variable(variableName);
// loop through to fill Variable
String type = null, value = null;
for (int j = 0; j < children.getLength(); j++) {
Node child = children.item(j);
// get the Variable's name
if (child.getNodeName().equals("type")) {
type = XMLUtils.getSimpleElementText((Element) child,
true).toLowerCase();
// get the Variable's value
} else if (child.getNodeName().equals("value")) {
value = PathUtils.doDynamicReplacement(XMLUtils
.getSimpleElementText((Element) child, false));
// get the Variable's value's precision infomation
} else if (child.getNodeName().equals("precision")) {
NodeList grandChildren = child.getChildNodes();
for (int k = 0; k < grandChildren.getLength(); k++) {
Node grandChild = grandChildren.item(k);
// get the precision
if (grandChild.getNodeName().equals("locations")) {
variable.setPrecision(Integer.parseInt(XMLUtils
.getSimpleElementText((Element) grandChild, true)));
// get the fill character to meet the precision
// [optional]
} else if (grandChild.getNodeName().equals("fill")) {
variable.setFillString(
XMLUtils.getSimpleElementText((Element) grandChild, false));
// get the side for which the fill character
// will be applied [optional]
} else if (grandChild.getNodeName().equals("side")) {
variable.setFillSide(
(XMLUtils.getSimpleElementText((Element) grandChild, true)
.toLowerCase().equals("front"))
? variable.FILL_FRONT
: variable.FILL_BACK);
}
}
}
}
// determine if variable is an Integer or a String
if (type.equals("int")) {
variable.setValue(new Integer(value));
} else
variable.setValue(value);
// store Variable in list of Variables
GlobalVariables.hashMap.put(variable.getName(), variable);
}
}
}
private void parseMethodsXML(NodeList list) {
// loop though all method elements
for (int i = 0; i < list.getLength(); i++) {
Node node = list.item(i);
// parse method element
if (node.getNodeName().equals("method")) {
NodeList children = node.getChildNodes();
// create Method Object
String methodName = ((Element) node).getAttribute("name");
Method method = new Method(methodName);
// loop through to fill Method Object
for (int j = 0; j < children.getLength(); j++) {
Node child = children.item(j);
// get the Method's behavoir
if (child.getNodeName().equals("action")) {
method.setBehavoir(XMLUtils.getSimpleElementText(
(Element) child, false));
// get the Method's arguments
} else if (child.getNodeName().equals("args")) {
String name, argType = null;
NodeList grandChildren = child.getChildNodes();
// loop for every arg element
for (int k = 0; k < grandChildren.getLength(); k++) {
Node grandChild = grandChildren.item(k);
// parse arg element
if (grandChild.getNodeName().equals("arg")) {
name = ((Element) grandChild)
.getAttribute("name");
// get arg element properties
NodeList greatGrandChildren = grandChild
.getChildNodes();
for (int l = 0; l < greatGrandChildren
.getLength(); l++) {
Node greatGrandChild = greatGrandChildren
.item(l);
if (greatGrandChild.getNodeName().equals(
"type")) {
argType = XMLUtils.getSimpleElementText(
(Element) greatGrandChild,
true);
}
}
// create argument signature in Method
method
.addArgSignature(
name,
((argType.toLowerCase()
.equals("int")) ? method.INT
: method.STRING));
}
}
}
}
// store Method in list of Methods
methodRepo.put(method.getName(), method);
}
}
}
}