blob: cb4c2b131eb90c96d138a386f7bf07ba2c938add [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.syncope.core.provisioning.java.data;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.commons.jexl3.JexlContext;
import org.apache.commons.jexl3.MapContext;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.common.lib.to.AnyTO;
import org.apache.syncope.common.lib.to.EntityTO;
import org.apache.syncope.common.lib.types.AttrSchemaType;
import org.apache.syncope.core.persistence.api.entity.Any;
import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
import org.apache.syncope.core.persistence.api.entity.resource.Item;
import org.apache.syncope.core.provisioning.api.DerAttrHandler;
import org.apache.syncope.core.provisioning.api.data.JEXLItemTransformer;
import org.apache.syncope.core.provisioning.api.jexl.JexlUtils;
import org.springframework.beans.factory.annotation.Autowired;
public class JEXLItemTransformerImpl implements JEXLItemTransformer {
@Autowired
private DerAttrHandler derAttrHandler;
@Autowired
private AnyUtilsFactory anyUtilsFactory;
private String propagationJEXL;
private String pullJEXL;
@Override
public void setPropagationJEXL(final String propagationJEXL) {
this.propagationJEXL = propagationJEXL;
}
@Override
public void setPullJEXL(final String pullJEXL) {
this.pullJEXL = pullJEXL;
}
protected AttrSchemaType beforePropagation(
final Any<?> any,
final AttrSchemaType schemaType,
final PlainAttrValue value) {
JexlContext jexlContext = new MapContext();
if (any != null) {
JexlUtils.addFieldsToContext(any, jexlContext);
JexlUtils.addPlainAttrsToContext(any.getPlainAttrs(), jexlContext);
JexlUtils.addDerAttrsToContext(any, derAttrHandler, jexlContext);
}
Object oValue;
switch (schemaType) {
case Binary:
case Encrypted:
oValue = value.getBinaryValue();
break;
case Boolean:
oValue = value.getBooleanValue();
break;
case Date:
oValue = value.getDateValue();
break;
case Double:
oValue = value.getDoubleValue();
break;
case Long:
oValue = value.getLongValue();
break;
case Enum:
case String:
default:
oValue = value.getStringValue();
}
jexlContext.set("value", oValue);
Object tValue = JexlUtils.evaluate(propagationJEXL, jexlContext);
value.setBinaryValue(null);
value.setBooleanValue(null);
value.setDateValue(null);
value.setDoubleValue(null);
value.setLongValue(null);
value.setStringValue(null);
if (tValue instanceof byte[]) {
value.setBinaryValue((byte[]) tValue);
return AttrSchemaType.Binary;
}
if (tValue instanceof Boolean) {
value.setBooleanValue((Boolean) tValue);
return AttrSchemaType.Boolean;
}
if (tValue instanceof OffsetDateTime) {
value.setDateValue((OffsetDateTime) tValue);
return AttrSchemaType.Date;
}
if (tValue instanceof Double) {
value.setDoubleValue((Double) tValue);
return AttrSchemaType.Double;
}
if (tValue instanceof Long) {
value.setLongValue((Long) tValue);
return AttrSchemaType.Long;
}
if (tValue != null) {
value.setStringValue(tValue.toString());
}
return AttrSchemaType.String;
}
@Override
public Pair<AttrSchemaType, List<PlainAttrValue>> beforePropagation(
final Item item,
final Any<?> any,
final AttrSchemaType schemaType,
final List<PlainAttrValue> values) {
if (StringUtils.isBlank(propagationJEXL)) {
return JEXLItemTransformer.super.beforePropagation(item, any, schemaType, values);
}
AtomicReference<AttrSchemaType> tType = new AtomicReference<>();
if (values.isEmpty()) {
PlainAttrValue value = anyUtilsFactory.getInstance(any).newPlainAttrValue();
tType.set(beforePropagation(any, schemaType, value));
values.add(value);
} else {
values.forEach(value -> tType.set(beforePropagation(any, schemaType, value)));
}
return Pair.of(tType.get(), values);
}
@Override
public List<Object> beforePull(
final Item item,
final EntityTO entityTO,
final List<Object> values) {
if (StringUtils.isNotBlank(pullJEXL) && values != null) {
List<Object> newValues = new ArrayList<>(values.size());
values.forEach(value -> {
JexlContext jexlContext = new MapContext();
jexlContext.set("value", value);
JexlUtils.addFieldsToContext(entityTO, jexlContext);
if (entityTO instanceof AnyTO) {
JexlUtils.addAttrsToContext(((AnyTO) entityTO).getPlainAttrs(), jexlContext);
JexlUtils.addAttrsToContext(((AnyTO) entityTO).getDerAttrs(), jexlContext);
JexlUtils.addAttrsToContext(((AnyTO) entityTO).getVirAttrs(), jexlContext);
}
newValues.add(JexlUtils.evaluate(pullJEXL, jexlContext));
});
return newValues;
}
return JEXLItemTransformer.super.beforePull(item, entityTO, values);
}
}