1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.core.provisioning.java.data;
20
21 import java.time.OffsetDateTime;
22 import java.util.ArrayList;
23 import java.util.List;
24 import java.util.concurrent.atomic.AtomicReference;
25 import org.apache.commons.jexl3.JexlContext;
26 import org.apache.commons.jexl3.MapContext;
27 import org.apache.commons.lang3.StringUtils;
28 import org.apache.commons.lang3.tuple.Pair;
29 import org.apache.syncope.common.lib.to.AnyTO;
30 import org.apache.syncope.common.lib.to.EntityTO;
31 import org.apache.syncope.common.lib.to.Item;
32 import org.apache.syncope.common.lib.types.AttrSchemaType;
33 import org.apache.syncope.core.persistence.api.entity.Any;
34 import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
35 import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
36 import org.apache.syncope.core.provisioning.api.DerAttrHandler;
37 import org.apache.syncope.core.provisioning.api.data.JEXLItemTransformer;
38 import org.apache.syncope.core.provisioning.api.jexl.JexlUtils;
39 import org.springframework.beans.factory.annotation.Autowired;
40
41 public class JEXLItemTransformerImpl implements JEXLItemTransformer {
42
43 @Autowired
44 private DerAttrHandler derAttrHandler;
45
46 @Autowired
47 private AnyUtilsFactory anyUtilsFactory;
48
49 private String propagationJEXL;
50
51 private String pullJEXL;
52
53 @Override
54 public void setPropagationJEXL(final String propagationJEXL) {
55 this.propagationJEXL = propagationJEXL;
56 }
57
58 @Override
59 public void setPullJEXL(final String pullJEXL) {
60 this.pullJEXL = pullJEXL;
61 }
62
63 protected AttrSchemaType beforePropagation(
64 final Any<?> any,
65 final AttrSchemaType schemaType,
66 final PlainAttrValue value) {
67
68 JexlContext jexlContext = new MapContext();
69 if (any != null) {
70 JexlUtils.addFieldsToContext(any, jexlContext);
71 JexlUtils.addPlainAttrsToContext(any.getPlainAttrs(), jexlContext);
72 JexlUtils.addDerAttrsToContext(any, derAttrHandler, jexlContext);
73 }
74
75 Object oValue;
76 switch (schemaType) {
77 case Binary:
78 case Encrypted:
79 oValue = value.getBinaryValue();
80 break;
81
82 case Boolean:
83 oValue = value.getBooleanValue();
84 break;
85
86 case Date:
87 oValue = value.getDateValue();
88 break;
89
90 case Double:
91 oValue = value.getDoubleValue();
92 break;
93
94 case Long:
95 oValue = value.getLongValue();
96 break;
97
98 case Enum:
99 case String:
100 default:
101 oValue = value.getStringValue();
102 }
103 jexlContext.set("value", oValue);
104
105 Object tValue = JexlUtils.evaluate(propagationJEXL, jexlContext);
106
107 value.setBinaryValue(null);
108 value.setBooleanValue(null);
109 value.setDateValue(null);
110 value.setDoubleValue(null);
111 value.setLongValue(null);
112 value.setStringValue(null);
113
114 if (tValue instanceof byte[]) {
115 value.setBinaryValue((byte[]) tValue);
116 return AttrSchemaType.Binary;
117 }
118
119 if (tValue instanceof Boolean) {
120 value.setBooleanValue((Boolean) tValue);
121 return AttrSchemaType.Boolean;
122 }
123
124 if (tValue instanceof OffsetDateTime) {
125 value.setDateValue((OffsetDateTime) tValue);
126 return AttrSchemaType.Date;
127 }
128
129 if (tValue instanceof Double) {
130 value.setDoubleValue((Double) tValue);
131 return AttrSchemaType.Double;
132 }
133
134 if (tValue instanceof Long) {
135 value.setLongValue((Long) tValue);
136 return AttrSchemaType.Long;
137 }
138
139 if (tValue != null) {
140 value.setStringValue(tValue.toString());
141 }
142 return AttrSchemaType.String;
143 }
144
145 @Override
146 public Pair<AttrSchemaType, List<PlainAttrValue>> beforePropagation(
147 final Item item,
148 final Any<?> any,
149 final AttrSchemaType schemaType,
150 final List<PlainAttrValue> values) {
151
152 if (StringUtils.isBlank(propagationJEXL)) {
153 return JEXLItemTransformer.super.beforePropagation(item, any, schemaType, values);
154 }
155
156 AtomicReference<AttrSchemaType> tType = new AtomicReference<>();
157 if (values.isEmpty()) {
158 PlainAttrValue value = anyUtilsFactory.getInstance(any).newPlainAttrValue();
159 tType.set(beforePropagation(any, schemaType, value));
160 values.add(value);
161 } else {
162 values.forEach(value -> tType.set(beforePropagation(any, schemaType, value)));
163 }
164
165 return Pair.of(tType.get(), values);
166 }
167
168 @Override
169 public List<Object> beforePull(
170 final Item item,
171 final EntityTO entityTO,
172 final List<Object> values) {
173
174 if (StringUtils.isNotBlank(pullJEXL) && values != null) {
175 List<Object> newValues = new ArrayList<>(values.size());
176 values.forEach(value -> {
177 JexlContext jexlContext = new MapContext();
178 jexlContext.set("value", value);
179 JexlUtils.addFieldsToContext(entityTO, jexlContext);
180 if (entityTO instanceof AnyTO) {
181 JexlUtils.addAttrsToContext(((AnyTO) entityTO).getPlainAttrs(), jexlContext);
182 JexlUtils.addAttrsToContext(((AnyTO) entityTO).getDerAttrs(), jexlContext);
183 JexlUtils.addAttrsToContext(((AnyTO) entityTO).getVirAttrs(), jexlContext);
184 }
185
186 newValues.add(JexlUtils.evaluate(pullJEXL, jexlContext));
187 });
188
189 return newValues;
190 }
191
192 return JEXLItemTransformer.super.beforePull(item, entityTO, values);
193 }
194 }