You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2017/11/21 10:59:01 UTC
syncope git commit: JEXL: various enhancements and cleanup,
especially for templates
Repository: syncope
Updated Branches:
refs/heads/2_0_X ff7e5af0f -> 48ae5566d
JEXL: various enhancements and cleanup, especially for templates
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/48ae5566
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/48ae5566
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/48ae5566
Branch: refs/heads/2_0_X
Commit: 48ae5566d10cc5678a0de6606c4693aeb7f32359
Parents: ff7e5af
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Tue Nov 21 11:58:53 2017 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Tue Nov 21 11:58:53 2017 +0100
----------------------------------------------------------------------
.../java/data/JEXLItemTransformerImpl.java | 11 +-
.../core/provisioning/java/jexl/JexlUtils.java | 147 +++++++++----------
.../provisioning/java/utils/MappingUtils.java | 6 +-
.../provisioning/java/utils/TemplateUtils.java | 36 ++++-
4 files changed, 109 insertions(+), 91 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/48ae5566/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/JEXLItemTransformerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/JEXLItemTransformerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/JEXLItemTransformerImpl.java
index ae31618..01f1b7e 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/JEXLItemTransformerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/JEXLItemTransformerImpl.java
@@ -25,6 +25,7 @@ import org.apache.commons.jexl3.MapContext;
import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.common.lib.to.AnyTO;
import org.apache.syncope.common.lib.to.EntityTO;
+import org.apache.syncope.common.lib.to.RealmTO;
import org.apache.syncope.core.persistence.api.entity.Any;
import org.apache.syncope.core.persistence.api.entity.Entity;
import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
@@ -87,10 +88,16 @@ public class JEXLItemTransformerImpl extends DefaultItemTransformer implements J
JexlContext jexlContext = new MapContext();
jexlContext.set("value", value);
if (entityTO instanceof AnyTO) {
- newValues.add(JexlUtils.evaluate(pullJEXL, (AnyTO) entityTO, jexlContext));
- } else {
+ JexlUtils.addFieldsToContext((AnyTO) entityTO, jexlContext);
+ JexlUtils.addAttrTOsToContext(((AnyTO) entityTO).getPlainAttrs(), jexlContext);
+ JexlUtils.addAttrTOsToContext(((AnyTO) entityTO).getDerAttrs(), jexlContext);
+ JexlUtils.addAttrTOsToContext(((AnyTO) entityTO).getVirAttrs(), jexlContext);
+ } else if (entityTO instanceof RealmTO) {
+ JexlUtils.addFieldsToContext((RealmTO) entityTO, jexlContext);
newValues.add(JexlUtils.evaluate(pullJEXL, jexlContext));
}
+
+ newValues.add(JexlUtils.evaluate(pullJEXL, jexlContext));
}
return newValues;
http://git-wip-us.apache.org/repos/asf/syncope/blob/48ae5566/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/JexlUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/JexlUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/JexlUtils.java
index f68ec60..ddb393f 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/JexlUtils.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/JexlUtils.java
@@ -25,8 +25,11 @@ import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.apache.commons.jexl3.JexlBuilder;
import org.apache.commons.jexl3.JexlContext;
import org.apache.commons.jexl3.JexlEngine;
@@ -38,6 +41,7 @@ import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.common.lib.to.AnyTO;
import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.RealmTO;
import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.provisioning.api.utils.FormatUtils;
import org.apache.syncope.core.persistence.api.entity.Any;
@@ -57,6 +61,10 @@ public final class JexlUtils {
private static final String[] IGNORE_FIELDS = { "password", "clearPassword", "serialVersionUID", "class" };
+ private static final Map<Class<?>, Set<PropertyDescriptor>> FIELD_CACHE =
+ Collections.<Class<?>, Set<PropertyDescriptor>>synchronizedMap(
+ new HashMap<Class<?>, Set<PropertyDescriptor>>());
+
private static JexlEngine JEXL_ENGINE;
private static JexlEngine getEngine() {
@@ -113,56 +121,77 @@ public final class JexlUtils {
return result;
}
- public static JexlContext addFieldsToContext(final Object object, final JexlContext jexlContext) {
- JexlContext context = jexlContext == null ? new MapContext() : jexlContext;
+ public static void addFieldsToContext(final Object object, final JexlContext jexlContext) {
+ Set<PropertyDescriptor> cached = FIELD_CACHE.get(object.getClass());
+ if (cached == null) {
+ cached = new HashSet<>();
+ FIELD_CACHE.put(object.getClass(), cached);
- try {
- for (PropertyDescriptor desc : Introspector.getBeanInfo(object.getClass()).getPropertyDescriptors()) {
- Class<?> type = desc.getPropertyType();
- String fieldName = desc.getName();
-
- if ((!fieldName.startsWith("pc"))
- && (!ArrayUtils.contains(IGNORE_FIELDS, fieldName))
- && (!Iterable.class.isAssignableFrom(type))
- && (!type.isArray())) {
-
- try {
- Object fieldValue;
- if (desc.getReadMethod() == null) {
- final Field field = object.getClass().getDeclaredField(fieldName);
- field.setAccessible(true);
- fieldValue = field.get(object);
- } else {
- fieldValue = desc.getReadMethod().invoke(object);
- }
-
- context.set(fieldName, fieldValue == null
- ? StringUtils.EMPTY
- : (type.equals(Date.class)
- ? FormatUtils.format((Date) fieldValue, false)
- : fieldValue));
-
- LOG.debug("Add field {} with value {}", fieldName, fieldValue);
- } catch (Exception iae) {
- LOG.error("Reading '{}' value error", fieldName, iae);
+ try {
+ for (PropertyDescriptor desc : Introspector.getBeanInfo(object.getClass()).getPropertyDescriptors()) {
+ if ((!desc.getName().startsWith("pc"))
+ && (!ArrayUtils.contains(IGNORE_FIELDS, desc.getName()))
+ && (!Iterable.class.isAssignableFrom(desc.getPropertyType()))
+ && (!desc.getPropertyType().isArray())) {
+
+ cached.add(desc);
}
}
+ } catch (IntrospectionException ie) {
+ LOG.error("Reading class attributes error", ie);
}
- } catch (IntrospectionException ie) {
- LOG.error("Reading class attributes error", ie);
}
- if (object instanceof Any) {
- Any<?> any = (Any<?>) object;
- if (any.getRealm() != null) {
- context.set("realm", any.getRealm().getFullPath());
+ for (PropertyDescriptor desc : cached) {
+ String fieldName = desc.getName();
+ Class<?> fieldType = desc.getPropertyType();
+
+ try {
+ Object fieldValue;
+ if (desc.getReadMethod() == null) {
+ final Field field = object.getClass().getDeclaredField(fieldName);
+ field.setAccessible(true);
+ fieldValue = field.get(object);
+ } else {
+ fieldValue = desc.getReadMethod().invoke(object);
+ }
+ fieldValue = fieldValue == null
+ ? StringUtils.EMPTY
+ : (fieldType.equals(Date.class)
+ ? FormatUtils.format((Date) fieldValue, false)
+ : fieldValue);
+
+ jexlContext.set(fieldName, fieldValue);
+
+ LOG.debug("Add field {} with value {}", fieldName, fieldValue);
+ } catch (Exception iae) {
+ LOG.error("Reading '{}' value error", fieldName, iae);
}
+ }
+
+ if (object instanceof Any && ((Any<?>) object).getRealm() != null) {
+ jexlContext.set("realm", ((Any<?>) object).getRealm().getFullPath());
+ } else if (object instanceof AnyTO && ((AnyTO) object).getRealm() != null) {
+ jexlContext.set("realm", ((AnyTO) object).getRealm());
} else if (object instanceof Realm) {
- Realm realm = (Realm) object;
- context.set("fullPath", realm.getFullPath());
+ jexlContext.set("fullPath", ((Realm) object).getFullPath());
+ } else if (object instanceof RealmTO) {
+ jexlContext.set("fullPath", ((RealmTO) object).getFullPath());
}
+ }
+
+ public static void addAttrTOsToContext(final Collection<AttrTO> attrs, final JexlContext jexlContext) {
+ for (AttrTO attr : attrs) {
+ if (attr.getSchema() != null) {
+ String expressionValue = attr.getValues().isEmpty()
+ ? StringUtils.EMPTY
+ : attr.getValues().get(0);
- return context;
+ LOG.debug("Add attribute {} with value {}", attr.getSchema(), expressionValue);
+
+ jexlContext.set(attr.getSchema(), expressionValue);
+ }
+ }
}
public static void addPlainAttrsToContext(
@@ -199,44 +228,6 @@ public final class JexlUtils {
return Boolean.parseBoolean(evaluate(mandatoryCondition, jexlContext));
}
- public static String evaluate(final String expression, final AnyTO anyTO, final JexlContext context) {
- addFieldsToContext(anyTO, context);
-
- for (AttrTO plainAttr : anyTO.getPlainAttrs()) {
- List<String> values = plainAttr.getValues();
- String expressionValue = values.isEmpty()
- ? StringUtils.EMPTY
- : values.get(0);
-
- LOG.debug("Add plain attribute {} with value {}", plainAttr.getSchema(), expressionValue);
-
- context.set(plainAttr.getSchema(), expressionValue);
- }
- for (AttrTO derAttr : anyTO.getDerAttrs()) {
- List<String> values = derAttr.getValues();
- String expressionValue = values.isEmpty()
- ? StringUtils.EMPTY
- : values.get(0);
-
- LOG.debug("Add derived attribute {} with value {}", derAttr.getSchema(), expressionValue);
-
- context.set(derAttr.getSchema(), expressionValue);
- }
- for (AttrTO virAttr : anyTO.getVirAttrs()) {
- List<String> values = virAttr.getValues();
- String expressionValue = values.isEmpty()
- ? StringUtils.EMPTY
- : values.get(0);
-
- LOG.debug("Add virtual attribute {} with value {}", virAttr.getSchema(), expressionValue);
-
- context.set(virAttr.getSchema(), expressionValue);
- }
-
- // Evaluate expression using the context prepared before
- return evaluate(expression, context);
- }
-
/**
* Private default constructor, for static-only classes.
*/
http://git-wip-us.apache.org/repos/asf/syncope/blob/48ae5566/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java
index ba2c7a4..67f2fe0 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java
@@ -87,7 +87,7 @@ public final class MappingUtils {
});
}
- private static Name evaluateNAME(final String evalConnObjectLink, final String connObjectKey) {
+ private static Name getName(final String evalConnObjectLink, final String connObjectKey) {
// If connObjectLink evaluates to an empty string, just use the provided connObjectKey as Name(),
// otherwise evaluated connObjectLink expression is taken as Name().
Name name;
@@ -135,7 +135,7 @@ public final class MappingUtils {
evalConnObjectLink = JexlUtils.evaluate(connObjectLink, jexlContext);
}
- return evaluateNAME(evalConnObjectLink, connObjectKey);
+ return getName(evalConnObjectLink, connObjectKey);
}
/**
@@ -165,7 +165,7 @@ public final class MappingUtils {
evalConnObjectLink = JexlUtils.evaluate(connObjectLink, jexlContext);
}
- return evaluateNAME(evalConnObjectLink, connObjectKey);
+ return getName(evalConnObjectLink, connObjectKey);
}
private static List<ItemTransformer> getItemTransformers(
http://git-wip-us.apache.org/repos/asf/syncope/blob/48ae5566/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/TemplateUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/TemplateUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/TemplateUtils.java
index 2b342af..5df7cce 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/TemplateUtils.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/TemplateUtils.java
@@ -51,13 +51,13 @@ public class TemplateUtils {
@Autowired
private GroupDAO groupDAO;
- private AttrTO evaluateAttr(final AnyTO anyTO, final AttrTO template) {
+ private AttrTO evaluateAttr(final AttrTO template, final MapContext jexlContext) {
AttrTO result = new AttrTO();
result.setSchema(template.getSchema());
if (template.getValues() != null && !template.getValues().isEmpty()) {
for (String value : template.getValues()) {
- String evaluated = JexlUtils.evaluate(value, anyTO, new MapContext());
+ String evaluated = JexlUtils.evaluate(value, jexlContext);
if (StringUtils.isNotBlank(evaluated)) {
result.getValues().add(evaluated);
}
@@ -68,8 +68,14 @@ public class TemplateUtils {
}
private void fill(final AnyTO anyTO, final AnyTO template) {
+ MapContext jexlContext = new MapContext();
+ JexlUtils.addFieldsToContext(anyTO, jexlContext);
+ JexlUtils.addAttrTOsToContext(anyTO.getPlainAttrs(), jexlContext);
+ JexlUtils.addAttrTOsToContext(anyTO.getDerAttrs(), jexlContext);
+ JexlUtils.addAttrTOsToContext(anyTO.getVirAttrs(), jexlContext);
+
if (template.getRealm() != null) {
- String evaluated = JexlUtils.evaluate(template.getRealm(), anyTO, new MapContext());
+ String evaluated = JexlUtils.evaluate(template.getRealm(), jexlContext);
if (StringUtils.isNotBlank(evaluated)) {
anyTO.setRealm(evaluated);
}
@@ -81,7 +87,11 @@ public class TemplateUtils {
&& (!currentAttrMap.containsKey(templatePlainAttr.getSchema())
|| currentAttrMap.get(templatePlainAttr.getSchema()).getValues().isEmpty())) {
- anyTO.getPlainAttrs().add(evaluateAttr(anyTO, templatePlainAttr));
+ AttrTO evaluated = evaluateAttr(templatePlainAttr, jexlContext);
+ if (!evaluated.getValues().isEmpty()) {
+ anyTO.getPlainAttrs().add(evaluated);
+ jexlContext.set(evaluated.getSchema(), evaluated.getValues().get(0));
+ }
}
}
@@ -98,7 +108,11 @@ public class TemplateUtils {
&& (!currentAttrMap.containsKey(templateVirAttr.getSchema())
|| currentAttrMap.get(templateVirAttr.getSchema()).getValues().isEmpty())) {
- anyTO.getVirAttrs().add(evaluateAttr(anyTO, templateVirAttr));
+ AttrTO evaluated = evaluateAttr(templateVirAttr, jexlContext);
+ if (!evaluated.getValues().isEmpty()) {
+ anyTO.getVirAttrs().add(evaluated);
+ jexlContext.set(evaluated.getSchema(), evaluated.getValues().get(0));
+ }
}
}
@@ -134,19 +148,25 @@ public class TemplateUtils {
public <T extends AnyTO> void apply(final T anyTO, final AnyTO template) {
fill(anyTO, template);
+ MapContext jexlContext = new MapContext();
+ JexlUtils.addFieldsToContext(anyTO, jexlContext);
+ JexlUtils.addAttrTOsToContext(anyTO.getPlainAttrs(), jexlContext);
+ JexlUtils.addAttrTOsToContext(anyTO.getDerAttrs(), jexlContext);
+ JexlUtils.addAttrTOsToContext(anyTO.getVirAttrs(), jexlContext);
+
if (template instanceof AnyObjectTO) {
fillRelationships((GroupableRelatableTO) anyTO, ((GroupableRelatableTO) template));
fillMemberships((GroupableRelatableTO) anyTO, ((GroupableRelatableTO) template));
} else if (template instanceof UserTO) {
if (StringUtils.isNotBlank(((UserTO) template).getUsername())) {
- String evaluated = JexlUtils.evaluate(((UserTO) template).getUsername(), anyTO, new MapContext());
+ String evaluated = JexlUtils.evaluate(((UserTO) template).getUsername(), jexlContext);
if (StringUtils.isNotBlank(evaluated)) {
((UserTO) anyTO).setUsername(evaluated);
}
}
if (StringUtils.isNotBlank(((UserTO) template).getPassword())) {
- String evaluated = JexlUtils.evaluate(((UserTO) template).getPassword(), anyTO, new MapContext());
+ String evaluated = JexlUtils.evaluate(((UserTO) template).getPassword(), jexlContext);
if (StringUtils.isNotBlank(evaluated)) {
((UserTO) anyTO).setPassword(evaluated);
}
@@ -156,7 +176,7 @@ public class TemplateUtils {
fillMemberships((GroupableRelatableTO) anyTO, ((GroupableRelatableTO) template));
} else if (template instanceof GroupTO) {
if (StringUtils.isNotBlank(((GroupTO) template).getName())) {
- String evaluated = JexlUtils.evaluate(((GroupTO) template).getName(), anyTO, new MapContext());
+ String evaluated = JexlUtils.evaluate(((GroupTO) template).getName(), jexlContext);
if (StringUtils.isNotBlank(evaluated)) {
((GroupTO) anyTO).setName(evaluated);
}