/**
* Copyright 2009 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.safehaus.penrose.interpreter;
import org.safehaus.penrose.directory.EntryAttributeConfig;
import org.safehaus.penrose.directory.EntryFieldConfig;
import org.safehaus.penrose.directory.EntryField;
import org.safehaus.penrose.ldap.Attribute;
import org.safehaus.penrose.ldap.Attributes;
import org.safehaus.penrose.ldap.RDN;
import org.safehaus.penrose.ldap.SourceAttributes;
import org.safehaus.penrose.mapping.Expression;
import org.safehaus.penrose.mapping.MappingRule;
import org.safehaus.penrose.source.Field;
import org.safehaus.penrose.Penrose;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
/**
* @author Endi S. Dewata
*/
public abstract class Interpreter {
public Logger log = LoggerFactory.getLogger(getClass());
protected Collection rows;
protected ClassLoader classLoader;
public void set(RDN rdn) throws Exception {
set(null, rdn);
}
public void set(String prefix, RDN rdn) throws Exception {
if (rdn == null) return;
for (String name : rdn.getNames()) {
Object value = rdn.get(name);
set(prefix == null ? name : prefix+"."+name, value);
}
}
public void set(SourceAttributes sv) throws Exception {
for (String sourceName : sv.getNames()) {
Attributes attributes = sv.get(sourceName);
for (String fieldName : attributes.getNames()) {
Attribute attribute = attributes.get(fieldName);
if (attribute.getSize() == 1) {
set(sourceName+"."+fieldName, attribute.getValue());
} else {
set(sourceName+"."+fieldName, attribute.getValues());
}
}
}
}
public void set(Attributes attributes) throws Exception {
set(null, attributes);
}
public void set(String prefix, Attributes attributes) throws Exception {
for (String name : attributes.getNames()) {
Collection list = attributes.getValues(name);
Object value;
if (list.size() == 1) {
value = list.iterator().next();
} else {
value = list;
}
set(prefix == null ? name : prefix+"."+name, value);
}
}
public abstract Collection<String> parseVariables(String script) throws Exception;
public abstract void set(String name, Object value) throws Exception;
public abstract Object get(String name) throws Exception;
public abstract Object eval(String script) throws Exception;
public abstract void clear() throws Exception;
public Object eval(EntryAttributeConfig attributeMapping) throws Exception {
try {
Object constant = attributeMapping.getConstant();
if (constant != null) {
//log.debug("Constant: "+constant);
return constant;
}
String variable = attributeMapping.getVariable();
if (variable != null) {
//log.debug("Variable: "+variable);
return get(variable);
}
Expression expression = attributeMapping.getExpression();
if (expression != null) {
//log.debug("Expression: "+expression);
return eval(expression);
}
//log.debug("Variable: "+attributeMapping.getName());
return get(attributeMapping.getName());
} catch (Exception e) {
Penrose.errorLog.error("Error evaluating attribute "+attributeMapping.getName()+": "+e.getMessage());
throw e;
}
}
public Object eval(Field field) throws Exception {
try {
Object constant = field.getConstant();
if (constant != null) {
//log.debug("Constant: "+constant);
return constant;
}
String variable = field.getVariable();
if (variable != null) {
Object value = get(variable);
if (value == null && variable.startsWith("rdn.")) {
value = get(variable.substring(4));
}
//log.debug("Variable: "+variable+" = "+value);
return value;
}
Expression expression = field.getExpression();
if (expression != null) {
Object value = eval(expression);
//log.debug("Expression: "+expression+" = "+value);
return value;
}
//log.debug("Undefined field.");
return null;
} catch (Exception e) {
throw new Exception("Error evaluating field "+field.getName(), e);
}
}
public Object eval(EntryField fieldRef) throws Exception {
try {
if (fieldRef.getConstant() != null) {
return fieldRef.getConstant();
} else if (fieldRef.getVariable() != null) {
String name = fieldRef.getVariable();
Object value = get(name);
if (value == null && name.startsWith("rdn.")) {
value = get(name.substring(4));
}
return value;
} else if (fieldRef.getExpression() != null) {
return eval(fieldRef.getExpression());
} else {
return null;
}
} catch (Exception e) {
throw new Exception("Error evaluating field "+fieldRef.getName(), e);
}
}
public Object eval(EntryFieldConfig fieldMapping) throws Exception {
try {
if (fieldMapping.getConstant() != null) {
return fieldMapping.getConstant();
} else if (fieldMapping.getVariable() != null) {
String name = fieldMapping.getVariable();
Object value = get(name);
if (value == null && name.startsWith("rdn.")) {
value = get(name.substring(4));
}
return value;
} else if (fieldMapping.getExpression() != null) {
return eval(fieldMapping.getExpression());
} else {
return null;
}
} catch (Exception e) {
throw new Exception("Error evaluating field "+fieldMapping.getName(), e);
}
}
public Object eval(MappingRule rule) throws Exception {
try {
if (rule.getConstant() != null) {
return rule.getConstant();
} else if (rule.getVariable() != null) {
String name = rule.getVariable();
return get(name);
} else if (rule.getExpression() != null) {
return eval(rule.getExpression());
} else {
return null;
}
} catch (Exception e) {
throw new Exception("Error evaluating field "+rule.getName(), e);
}
}
public Object eval(Expression expression) throws Exception {
String foreach = expression.getForeach();
String var = expression.getVar();
String script = expression.getScript();
Object value = null;
if (foreach == null) {
//log.debug("Evaluating expression: "+expression);
value = eval(script);
} else {
//log.debug("Foreach: "+foreach);
Object v = get(foreach);
//log.debug("Values: "+v);
Collection<Object> newValues = new HashSet<Object>();
if (v != null) {
Collection<Object> values;
if (v instanceof Collection) {
values = (Collection<Object>)v;
} else {
values = new ArrayList<Object>();
values.add(v);
}
for (Object o : values) {
set(var, o);
value = eval(script);
if (value == null) continue;
//log.debug(" - "+value);
newValues.add(value);
}
}
if (newValues.size() == 1) {
value = newValues.iterator().next();
} else if (newValues.size() > 1) {
value = newValues;
}
}
return value;
}
public ClassLoader getClassLoader() {
return classLoader;
}
public void setClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
}
}