/* * ExpressionHandler.java * * Created by: seth proctor (stp) * Created on: Wed Dec 29, 2004 8:24:30 PM * Desc: * */ package com.sun.xacml.cond; import com.sun.xacml.ParsingException; import com.sun.xacml.PolicyMetaData; import com.sun.xacml.UnknownIdentifierException; import com.sun.xacml.attr.AttributeDesignator; import com.sun.xacml.attr.AttributeFactory; import com.sun.xacml.attr.AttributeSelector; import com.sun.xacml.debug.RuntimeInfo; import com.sun.xacml.debug.RuntimeInfo.ELEMENT_TYPE; import org.w3c.dom.Node; /** * This is a package-private utility class that handles parsing all the * possible expression types. It was added becuase in 2.0 multiple classes * needed this. Note that this could also be added to Expression and * that interface could be made an abstract class, but that would require * substantial change. * * @since 2.0 * @author Seth Proctor * @author Ludwig Seitz */ class ExpressionHandler { /** * Parses an expression, recursively handling any sub-elements. This is * provided as a utility class, but in practice is used only by * <code>Apply</code>, <code>Condition</code>, and * <code>VariableDefinition</code>. * * @param root the DOM root of an ExpressionType XML type * @param metaData the meta-data associated with the containing policy * @param manager <code>VariableManager</code> used to connect references * and definitions while parsing * * @return an <code>Expression</code> or null if the root node cannot be * parsed as a valid Expression * * @throws ParsingException */ public static Expression parseExpression(Node root, PolicyMetaData metaData, VariableManager manager ) throws ParsingException { if (root.getNodeType() != Node.ELEMENT_NODE) { return null; } String name = root.getLocalName(); if (name.equals("Apply")) { return Apply.getInstance(root, metaData, manager); } else if (name.equals("AttributeValue")) { try { return AttributeFactory.getInstance().createValue(root); } catch (UnknownIdentifierException uie) { RuntimeInfo src = RuntimeInfo.getRuntimeInfo(root, ELEMENT_TYPE.ATTRIBUTE_VALUE); throw new ParsingException("Unknown DataType" + (src != null ? src.getLocationMsgForError() : ""), uie); } } else if (name.endsWith("AttributeDesignator")) { return AttributeDesignator.getInstance(root, metaData); } else if (name.equals("AttributeSelector")) { return AttributeSelector.getInstance(root, metaData); } else if (name.equals("Function")) { return getFunction(root, metaData, FunctionFactory.getGeneralInstance()); } else if (name.equals("VariableReference")) { return VariableReference.getInstance(root, metaData, manager); } // return null if it was none of these return null; } /** * Helper method that tries to get a function instance * * @param root the root node of the XML defining this expression. * @param metaData the policy meta data for this expression. * @param factory the function factory for this expression. * * @return The function of this expression. * * @throws ParsingException */ public static Function getFunction(Node root, PolicyMetaData metaData, FunctionFactory factory) throws ParsingException { RuntimeInfo src = RuntimeInfo.getRuntimeInfo(root, ELEMENT_TYPE.FUNCTION); if (root.getNodeType() != Node.ELEMENT_NODE || root.getAttributes().getNamedItem("FunctionId") == null) { throw new ParsingException("Error: tried to parse Function from" + " non Element type node or with missing FunctionId (ELEMENT_NODE: " + (root.getNodeType() == Node.ELEMENT_NODE) + ", Node: " + root.getLocalName() + ", FunctionId: " + root.getAttributes().getNamedItem("FunctionId") + ")" + (src != null ? src.getLocationMsgForError() : "")); } Node functionNode = root.getAttributes().getNamedItem("FunctionId"); String functionName = functionNode.getNodeValue(); try { // try to get an instance of the given function return factory.createFunction(functionName); } catch (UnknownIdentifierException uie) { throw new ParsingException("Unknown FunctionId: " + uie.getMessage() + (src != null ? src.getLocationMsgForError() : ""), uie); } catch (FunctionTypeException fte) { // try creating as an abstract function try { FunctionFactory ff = FunctionFactory.getGeneralInstance(); return ff.createAbstractFunction(functionName, root, metaData. getXPathIdentifier()); } catch (Exception e) { // any exception at this point is a failure throw new ParsingException("failed to create abstract function" + " " + functionName + (src != null ? src.getLocationMsgForError() : ""), e); } } } }