/** * Licensed to Apereo under one or more contributor license agreements. See the NOTICE file * distributed with this work for additional information regarding copyright ownership. Apereo * 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 the * following location: * * <p>http://www.apache.org/licenses/LICENSE-2.0 * * <p>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.apereo.portal.layout.dlm.providers; import org.apereo.portal.layout.dlm.Evaluator; import org.apereo.portal.layout.dlm.EvaluatorFactory; import org.apereo.portal.xml.XmlUtilitiesImpl; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * Implementation of the Evaluator Factory interface that creates evaluators of string attributes in * implementations of IPerson to determine if a user gets a layout fragment. * * @since 2.5 */ public class PersonEvaluatorFactory implements EvaluatorFactory { private static final int OR = 0; private static final int AND = 1; private static final int NOT = 2; @Override public Evaluator getEvaluator(Node audience) { return getGroupEvaluator(OR, audience); } private Evaluator getGroupEvaluator(int type, Node node) { NodeList nodes = node.getChildNodes(); Evaluator container = null; if (nodes == null || nodes.getLength() == 0 || (container = createGroupEvaluator(type, nodes)) == null) { throw new RuntimeException( "Invalid content. Expected one to many " + "<paren>, <NOT>, or <attribute> in '" + XmlUtilitiesImpl.toString(node) + "'"); } return container; } private Evaluator createGroupEvaluator(int type, NodeList nodes) { // if only one child skip wrapping in container for AND and OR if (nodes.getLength() == 1 && (type == OR || type == AND)) return createEvaluator(nodes.item(0)); Paren container = null; if (type == NOT) container = new Paren(Paren.Type.NOT); else if (type == OR) container = new Paren(Paren.Type.OR); else if (type == AND) container = new Paren(Paren.Type.AND); boolean validContentAdded = false; for (int i = 0; i < nodes.getLength(); i++) { if (nodes.item(i).getNodeType() == Node.ELEMENT_NODE) { Evaluator e = createEvaluator(nodes.item(i)); if (e != null) { validContentAdded = true; container.addEvaluator(e); } } } if (validContentAdded) return container; return null; } private Evaluator createEvaluator(Node node) { String nodeName = node.getNodeName(); if (nodeName.equals("paren")) return createParen(node); else if (nodeName.equals("attribute")) return createAttributeEvaluator(node); throw new RuntimeException( "Unrecognized element '" + nodeName + "' in '" + XmlUtilitiesImpl.toString(node) + "'"); } private Evaluator createParen(Node n) { NamedNodeMap attribs = n.getAttributes(); Node opNode = attribs.getNamedItem("mode"); if (opNode == null) throw new RuntimeException( "Invalid mode. Expected 'AND','OR', or 'NOT'" + " in '" + XmlUtilitiesImpl.toString(n) + "'"); else if (opNode.getNodeValue().equals("OR")) return getGroupEvaluator(OR, n); else if (opNode.getNodeValue().equals("NOT")) return getGroupEvaluator(NOT, n); else if (opNode.getNodeValue().equals("AND")) return getGroupEvaluator(AND, n); else throw new RuntimeException( "Invalid mode. Expected 'AND','OR', or 'NOT'" + " in '" + XmlUtilitiesImpl.toString(n) + "'"); } private Evaluator createAttributeEvaluator(Node n) { NamedNodeMap attribs = n.getAttributes(); Node attribNode = attribs.getNamedItem("name"); if (attribNode == null || attribNode.getNodeValue().equals("")) throw new RuntimeException( "Missing or empty name attribute in '" + XmlUtilitiesImpl.toString(n) + "'"); String name = attribNode.getNodeValue(); String value = null; attribNode = attribs.getNamedItem("value"); if (attribNode != null) value = attribNode.getNodeValue(); attribNode = attribs.getNamedItem("mode"); if (attribNode == null || attribNode.getNodeValue().equals("")) throw new RuntimeException( "Missing or empty mode attribute in '" + XmlUtilitiesImpl.toString(n) + "'"); String mode = attribNode.getNodeValue(); Evaluator eval = null; try { eval = getAttributeEvaluator(name, mode, value); } catch (Exception e) { throw new RuntimeException(e.getMessage() + " in '" + XmlUtilitiesImpl.toString(n), e); } return eval; } /** * returns an Evaluator unique to the type of attribute being evaluated. subclasses can override * this method to return the Evaluator that's appropriate to their implementation. * * @param name the attribute's name. * @param mode the attribute's mode. (i.e. 'equals') * @param value the attribute's value. * @return an Evaluator for evaluating attributes */ public Evaluator getAttributeEvaluator(String name, String mode, String value) throws Exception { return new AttributeEvaluator(name, mode, value); } }