/* * Copyright (c) 2010-2017 Evolveum * * Licensed 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 com.evolveum.midpoint.model.common.expression.evaluator; import java.util.UUID; import org.apache.commons.lang.StringUtils; import com.evolveum.midpoint.model.common.expression.ExpressionEvaluationContext; import com.evolveum.midpoint.model.common.expression.ExpressionEvaluator; import com.evolveum.midpoint.model.common.expression.ExpressionUtil; import com.evolveum.midpoint.model.common.expression.ExpressionVariables; import com.evolveum.midpoint.model.common.expression.StringPolicyResolver; import com.evolveum.midpoint.model.common.stringpolicy.ValuePolicyProcessor; import com.evolveum.midpoint.prism.Item; import com.evolveum.midpoint.prism.ItemDefinition; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.PrismProperty; import com.evolveum.midpoint.prism.PrismValue; import com.evolveum.midpoint.prism.PrismPropertyValue; import com.evolveum.midpoint.prism.crypto.Protector; import com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple; import com.evolveum.midpoint.prism.delta.ItemDelta; import com.evolveum.midpoint.schema.constants.ExpressionConstants; import com.evolveum.midpoint.schema.util.ObjectResolver; import com.evolveum.midpoint.util.RandomString; import com.evolveum.midpoint.util.exception.ExpressionEvaluationException; import com.evolveum.midpoint.util.exception.ObjectNotFoundException; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.xml.ns._public.common.common_3.GenerateExpressionEvaluatorModeType; import com.evolveum.midpoint.xml.ns._public.common.common_3.GenerateExpressionEvaluatorType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; import com.evolveum.midpoint.xml.ns._public.common.common_3.StringPolicyType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ValuePolicyType; /** * @author semancik * */ public class GenerateExpressionEvaluator<V extends PrismValue, D extends ItemDefinition> implements ExpressionEvaluator<V, D> { public static final int DEFAULT_LENGTH = 8; private GenerateExpressionEvaluatorType generateEvaluatorType; private D outputDefinition; private Protector protector; private PrismContext prismContext; private ObjectResolver objectResolver; private ValuePolicyProcessor valuePolicyGenerator; private StringPolicyType elementStringPolicy; GenerateExpressionEvaluator(GenerateExpressionEvaluatorType generateEvaluatorType, D outputDefinition, Protector protector, ObjectResolver objectResolver, ValuePolicyProcessor valuePolicyGenerator, PrismContext prismContext) { this.generateEvaluatorType = generateEvaluatorType; this.outputDefinition = outputDefinition; this.protector = protector; this.objectResolver = objectResolver; this.valuePolicyGenerator = valuePolicyGenerator; this.prismContext = prismContext; } private boolean isNotEmptyMinLength(StringPolicyType policy) { Integer minLength = policy.getLimitations().getMinLength(); if (minLength != null) { if (minLength.intValue() == 0) { return false; } return true; } return false; } /* * (non-Javadoc) * * @see * com.evolveum.midpoint.common.expression.ExpressionEvaluator#evaluate(java * .util.Collection, java.util.Map, boolean, java.lang.String, * com.evolveum.midpoint.schema.result.OperationResult) */ @Override public PrismValueDeltaSetTriple<V> evaluate(ExpressionEvaluationContext context) throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException { StringPolicyType stringPolicyType = null; ObjectReferenceType generateEvaluatorValuePolicyRef = generateEvaluatorType.getValuePolicyRef(); if (generateEvaluatorValuePolicyRef != null) { if (generateEvaluatorType.getValuePolicyRef() != null) { ValuePolicyType valuePolicyType = objectResolver.resolve(generateEvaluatorValuePolicyRef, ValuePolicyType.class, null, "resolving value policy reference in generateExpressionEvaluator", context.getTask(), context.getResult()); stringPolicyType = valuePolicyType.getStringPolicy(); } } // if (elementStringPolicy == null) { // if the policy was changed, the most fresh copy is needed, therefore // it must be resolved all time the value is generated..if it was not // resolved each time, the cached policy would be used and so bad values // would be generated if (stringPolicyType == null) { StringPolicyResolver stringPolicyResolver = context.getStringPolicyResolver(); if (stringPolicyResolver != null) { stringPolicyType = stringPolicyResolver.resolve(); } } elementStringPolicy = stringPolicyType; // } else { // stringPolicyType = elementStringPolicy; // } // String stringValue = null; GenerateExpressionEvaluatorModeType mode = generateEvaluatorType.getMode(); Item<V, D> output = outputDefinition.instantiate(); if (mode == null || mode == GenerateExpressionEvaluatorModeType.POLICY) { PrismObject<? extends ObjectType> object = getObject(context); // TODO: generate value based on stringPolicyType (if not null) if (stringPolicyType != null) { if (isNotEmptyMinLength(stringPolicyType)) { stringValue = valuePolicyGenerator.generate(output.getPath(), stringPolicyType, DEFAULT_LENGTH, true, object, context.getContextDescription(), context.getTask(), context.getResult()); } else { stringValue = valuePolicyGenerator.generate(output.getPath(), stringPolicyType, DEFAULT_LENGTH, false, object, context.getContextDescription(), context.getTask(), context.getResult()); } context.getResult().computeStatus(); if (context.getResult().isError()) { throw new ExpressionEvaluationException("Failed to generate value according to policy: " + stringPolicyType.getDescription() + ". " + context.getResult().getMessage()); } } if (stringValue == null) { int length = DEFAULT_LENGTH; RandomString randomString = new RandomString(length); stringValue = randomString.nextString(); } } else if (mode == GenerateExpressionEvaluatorModeType.UUID) { UUID randomUUID = UUID.randomUUID(); stringValue = randomUUID.toString(); } else { throw new ExpressionEvaluationException("Unknown mode for generate expression: " + mode); } Object value = ExpressionUtil.convertToOutputValue(stringValue, outputDefinition, protector); if (output instanceof PrismProperty) { PrismPropertyValue<Object> pValue = new PrismPropertyValue<Object>(value); ((PrismProperty<Object>) output).add(pValue); } else { throw new UnsupportedOperationException( "Can only generate values of property, not " + output.getClass()); } return ItemDelta.toDeltaSetTriple(output, null); } // determine object from the variables @SuppressWarnings("unchecked") private <O extends ObjectType> PrismObject<O> getObject(ExpressionEvaluationContext params) throws SchemaException { ExpressionVariables variables = params.getVariables(); if (variables == null) { return null; } PrismObject<O> object = variables.getObjectNew(ExpressionConstants.VAR_PROJECTION); if (object != null) { return object; } object = variables.getObjectNew(ExpressionConstants.VAR_FOCUS); return object; } /* * (non-Javadoc) * * @see com.evolveum.midpoint.common.expression.ExpressionEvaluator# * shortDebugDump() */ @Override public String shortDebugDump() { if (elementStringPolicy != null) { return "generate: " + toHumanReadableString(elementStringPolicy); } return "generate"; } private String toHumanReadableString(StringPolicyType stringPolicy) { if (stringPolicy.getDescription() != null) { return "StringPolicy: " + StringUtils.abbreviate(stringPolicy.getDescription(), 60); } return "StringPolicy"; } }