/**
* 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;
public class ProfileEvaluatorFactory 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("profile")) return createProfileEvaluator(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 createProfileEvaluator(Node n) {
NamedNodeMap attribs = n.getAttributes();
Node attribNode = attribs.getNamedItem("fname");
if (attribNode == null || attribNode.getNodeValue().equals(""))
throw new RuntimeException(
"Missing or empty value attribute in '" + XmlUtilitiesImpl.toString(n) + "'");
String value = attribNode.getNodeValue();
Evaluator eval = null;
try {
eval = getProfileEvaluator(value);
} catch (Exception e) {
throw new RuntimeException(e.getMessage() + " in '" + XmlUtilitiesImpl.toString(n), e);
}
return eval;
}
public Evaluator getProfileEvaluator(String value) throws Exception {
return new ProfileEvaluator(value);
}
}