blob: 283615450308b9928a2930dc2faec5bcb736d4ee [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.cocoon.components.expression.jexl;
import java.lang.reflect.Field;
import java.util.Iterator;
import java.util.Map;
import org.apache.cocoon.components.expression.AbstractExpression;
import org.apache.cocoon.components.expression.ExpressionContext;
import org.apache.cocoon.components.expression.ExpressionException;
import org.apache.commons.jexl.JexlContext;
import org.apache.commons.jexl.util.Introspector;
import org.apache.commons.jexl.util.introspection.Info;
/**
* @version $Id$
*/
public class JexlExpression extends AbstractExpression {
private final org.apache.commons.jexl.Expression compiledExpression;
public JexlExpression(String language, String expression) throws ExpressionException {
super(language, expression);
try {
this.compiledExpression = org.apache.commons.jexl.ExpressionFactory.createExpression(expression);
} catch (Exception e) {
throw new ExpressionException("Couldn't create expression " + expression, e);
}
}
public Object evaluate(ExpressionContext context) throws ExpressionException {
try {
return this.compiledExpression.evaluate(new ContextAdapter(context));
} catch (Exception e) {
throw new ExpressionException("Couldn't evaluate expression " + getExpression(), e);
}
}
public Iterator iterate(ExpressionContext context) throws ExpressionException {
Iterator iter = null;
Object result = evaluate(context);
if (result != null) {
/*
* The Info object is supposed to contain the script location where
* the expression is invoked and use that in a warning log message
* if no iterator can be generated. This info is not available in
* the expression object and might not be relevant either as it can
* be used from a non script situation.
*/
try {
iter = Introspector.getUberspect().getIterator(result, new Info("Unknown", 0, 0));
} catch (Exception e) {
throw new ExpressionException("Couldn't get an iterator from expression " + getExpression(), e);
}
}
if (iter == null) {
iter = EMPTY_ITER;
}
return iter;
}
public void assign(ExpressionContext context, Object value) throws ExpressionException {
throw new UnsupportedOperationException("Assign is not yet implemented for Jexl");
}
public Object getNode(ExpressionContext context) throws ExpressionException {
return evaluate(context);
}
private static class ContextAdapter implements JexlContext {
private final ExpressionContext context;
public ContextAdapter(ExpressionContext context) {
this.context = context;
}
public Map getVars() {
return this.context.getVars();
}
public void setVars(Map map) {
this.context.setVars(map);
}
}
static {
// Hack: there's no _nice_ way to add my introspector to Jexl right now
try {
Field field = Introspector.class.getDeclaredField("uberSpect");
field.setAccessible(true);
field.set(null, new JSIntrospector());
} catch (Exception e) {
e.printStackTrace();
}
}
}