/**
* Copyright (c) 2013-2016, The SeedStack authors <http://seedstack.org>
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.seedstack.seed.core.internal.el;
import com.google.common.base.Strings;
import org.seedstack.seed.SeedException;
import org.seedstack.seed.el.ELContextBuilder;
import javax.el.ELContext;
import javax.el.ExpressionFactory;
import javax.inject.Inject;
import java.lang.reflect.Method;
import static com.google.common.base.Preconditions.checkArgument;
/**
* Implementation of ELContextBuilder.
*
* *
*/
class ELContextBuilderImpl implements ELContextBuilder {
@Inject
private ExpressionFactory expressionFactory;
static ELContext createDefaultELContext(ExpressionFactory expressionFactory) {
if (ELPlugin.EL3_OPTIONAL.isPresent()) {
try {
return ELPlugin.EL3_OPTIONAL.get().getConstructor(ExpressionFactory.class).newInstance(expressionFactory);
} catch (Exception e) {
throw new RuntimeException("Unable to instantiate StandardELContext");
}
} else if (ELPlugin.JUEL_OPTIONAL.isPresent()) {
try {
return ELPlugin.JUEL_OPTIONAL.get().newInstance();
} catch (Exception e) {
throw new RuntimeException("Unable to instantiate JUEL SimpleContext");
}
} else {
throw new UnsupportedOperationException("StandardELContext is not supported in this environment (EL level 3+ required)");
}
}
@Override
public ELPropertyProvider defaultContext() {
return new SubContextBuilderImpl(createDefaultELContext(expressionFactory));
}
@Override
public ELPropertyProvider context(ELContext elContext) {
return new SubContextBuilderImpl(elContext);
}
private static class SubContextBuilderImpl implements ELContextBuilder.ELPropertyProvider {
private final ELContext elContext;
SubContextBuilderImpl(ELContext elContext) {
this.elContext = elContext;
}
@Override
public ELPropertyProvider withProperty(String name, Object object) {
checkArgument(!Strings.isNullOrEmpty(name), "A property name is required");
elContext.getELResolver().setValue(elContext, null, name, object);
return this;
}
@Override
public ELPropertyProvider withFunction(String prefix, String localName, Method method) {
checkArgument(!Strings.isNullOrEmpty(localName), "A function local name is required");
if (ELPlugin.EL3_OPTIONAL.isPresent()) {
elContext.getFunctionMapper().mapFunction(prefix, localName, method);
} else if (ELPlugin.JUEL_OPTIONAL.isPresent()) {
if (ELPlugin.JUEL_OPTIONAL.get().isAssignableFrom(elContext.getClass())) {
try {
ELPlugin.JUEL_OPTIONAL.get().getMethod("setFunction", String.class, String.class, Method.class).invoke(elContext, prefix, localName, method);
} catch (Exception e) {
throw SeedException.wrap(e, ExpressionLanguageErrorCode.UNEXPECTED_EXCEPTION);
}
} else {
throw new UnsupportedOperationException("At EL level 2, function mapping is only supported by JUEL SimpleContext");
}
} else {
throw new UnsupportedOperationException("Function mapping is not supported in this environment (EL level 3+ required)");
}
return this;
}
@Override
public ELContext build() {
return elContext;
}
}
}