Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into feature/menu
Browse files Browse the repository at this point in the history
  • Loading branch information
1azyman committed Sep 29, 2015
2 parents d2994bf + e758779 commit c9bf742
Show file tree
Hide file tree
Showing 11 changed files with 314 additions and 46 deletions.
22 changes: 22 additions & 0 deletions infra/schema/src/main/resources/xml/ns/public/common/common-3.xsd
Expand Up @@ -5690,6 +5690,28 @@
<xsd:element name="target" type="tns:MappingTargetDeclarationType"/>
</xsd:sequence>
</xsd:complexType>

<xsd:complexType name="SequentialValueExpressionEvaluatorType">
<xsd:annotation>
<xsd:documentation>
Get a sequential value from a named sequence.
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="sequenceRef" type="tns:ObjectReferenceType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Reference to the sequence from which the value is taken.
</xsd:documentation>
<xsd:appinfo>
<a:objectReferenceTargetType>tns:SequenceType</a:objectReferenceTargetType>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
</xsd:complexType>

<xsd:element name="sequentialValue" type="tns:SequentialValueExpressionEvaluatorType" substitutionGroup="tns:expressionEvaluator"/>

<xsd:element name="synchronization" type="tns:SynchronizationType"/>

Expand Down
Expand Up @@ -29,7 +29,6 @@
import com.evolveum.midpoint.util.exception.SecurityViolationException;
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;
import com.evolveum.prism.xml.ns._public.types_3.ProtectedStringType;

import com.evolveum.midpoint.model.common.expression.functions.BasicExpressionFunctions;
import com.evolveum.midpoint.model.common.expression.functions.BasicExpressionFunctionsXPath;
import com.evolveum.midpoint.model.common.expression.functions.FunctionLibrary;
Expand Down Expand Up @@ -66,6 +65,7 @@
import com.evolveum.midpoint.prism.query.ValueFilter;
import com.evolveum.midpoint.prism.util.JavaTypeConverter;
import com.evolveum.midpoint.prism.util.PrismUtil;
import com.evolveum.midpoint.prism.xml.XmlTypeConverter;
import com.evolveum.midpoint.prism.xml.XsdTypeMapper;
import com.evolveum.midpoint.schema.constants.ExpressionConstants;
import com.evolveum.midpoint.schema.constants.MidPointConstants;
Expand Down Expand Up @@ -669,5 +669,46 @@ public static void addActorVariable(ExpressionVariables scriptVariables, Securit
}
scriptVariables.addVariableDefinition(ExpressionConstants.VAR_ACTOR, actor);
}

public static <D extends ItemDefinition> Object convertToOutputValue(Long longValue, D outputDefinition, Protector protector) throws ExpressionEvaluationException, SchemaException {
if (longValue == null) {
return null;
}
QName outputType = outputDefinition.getTypeName();
if (outputType.equals(DOMUtil.XSD_INT)) {
return longValue.intValue();
} else if (outputType.equals(DOMUtil.XSD_LONG)) {
return longValue;
} else {
return convertToOutputValue(longValue.toString(), outputDefinition, protector);
}
}

public static <D extends ItemDefinition> Object convertToOutputValue(String stringValue, D outputDefinition, Protector protector) throws ExpressionEvaluationException, SchemaException {
if (stringValue == null) {
return null;
}
QName outputType = outputDefinition.getTypeName();
if (outputType.equals(DOMUtil.XSD_STRING)) {
return stringValue;
} else if (outputType.equals(ProtectedStringType.COMPLEX_TYPE)) {
try {
return protector.encryptString(stringValue);
} catch (EncryptionException e) {
throw new ExpressionEvaluationException("Crypto error: "+e.getMessage(),e);
}
} else if (XmlTypeConverter.canConvert(outputType)) {
Class<?> outputJavaType = XsdTypeMapper.toJavaType(outputType);
try {
return XmlTypeConverter.toJavaValue(stringValue, outputJavaType, true);
} catch (NumberFormatException e) {
throw new SchemaException("Cannot convert string '"+stringValue+"' to data type "+outputType+": invalid number format", e);
} catch (IllegalArgumentException e) {
throw new SchemaException("Cannot convert string '"+stringValue+"' to data type "+outputType+": "+e.getMessage(), e);
}
} else {
throw new IllegalArgumentException("Expression cannot generate values for properties of type " + outputType);
}
}

}
Expand Up @@ -29,6 +29,7 @@
import com.evolveum.midpoint.common.policy.ValuePolicyGenerator;
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.Source;
import com.evolveum.midpoint.model.common.expression.StringPolicyResolver;
import com.evolveum.midpoint.prism.Item;
Expand Down Expand Up @@ -82,10 +83,6 @@ public class GenerateExpressionEvaluator<V extends PrismValue, D extends ItemDef
this.elementStringPolicy = elementStringPolicy;
this.prismContext = prismContext;
}

/* (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)
*/

private boolean isNotEmptyMinLength(StringPolicyType policy){
Integer minLength = policy.getLimitations().getMinLength();
Expand All @@ -97,10 +94,13 @@ private boolean isNotEmptyMinLength(StringPolicyType policy){
}
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 params) throws SchemaException,
ExpressionEvaluationException, ObjectNotFoundException {


StringPolicyType stringPolicyType = null;

Expand Down Expand Up @@ -149,28 +149,7 @@ public PrismValueDeltaSetTriple<V> evaluate(ExpressionEvaluationContext params)
throw new ExpressionEvaluationException("Unknown mode for generate expression: "+mode);
}

Object value;
QName outputType = outputDefinition.getTypeName();
if (outputType.equals(DOMUtil.XSD_STRING)) {
value = stringValue;
} else if (outputType.equals(ProtectedStringType.COMPLEX_TYPE)) {
try {
value = protector.encryptString(stringValue);
} catch (EncryptionException e) {
throw new ExpressionEvaluationException("Crypto error: "+e.getMessage(),e);
}
} else if (XmlTypeConverter.canConvert(outputType)) {
Class<?> outputJavaType = XsdTypeMapper.toJavaType(outputType);
try {
value = XmlTypeConverter.toJavaValue(stringValue, outputJavaType, true);
} catch (NumberFormatException e) {
throw new SchemaException("Cannot convert generated string '"+stringValue+"' to data type "+outputType+": invalid number format", e);
} catch (IllegalArgumentException e) {
throw new SchemaException("Cannot convert generated string '"+stringValue+"' to data type "+outputType+": "+e.getMessage(), e);
}
} else {
throw new IllegalArgumentException("Generate value constructor cannot generate values for properties of type " + outputType);
}
Object value = ExpressionUtil.convertToOutputValue(stringValue, outputDefinition, protector);

Item<V,D> output = outputDefinition.instantiate();
if (output instanceof PrismProperty) {
Expand Down
@@ -0,0 +1,84 @@
/*
* Copyright (c) 2015 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.impl.expr;

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.prism.Item;
import com.evolveum.midpoint.prism.ItemDefinition;
import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.PrismProperty;
import com.evolveum.midpoint.prism.PrismPropertyValue;
import com.evolveum.midpoint.prism.PrismValue;
import com.evolveum.midpoint.prism.crypto.Protector;
import com.evolveum.midpoint.prism.delta.ItemDelta;
import com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple;
import com.evolveum.midpoint.repo.api.RepositoryService;
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.SequentialValueExpressionEvaluatorType;

/**
* @author semancik
*
*/
public class SequentialValueExpressionEvaluator<V extends PrismValue, D extends ItemDefinition> implements ExpressionEvaluator<V,D> {

private SequentialValueExpressionEvaluatorType sequentialValueEvaluatorType;
private D outputDefinition;
private Protector protector;
RepositoryService repositoryService;
private PrismContext prismContext;

SequentialValueExpressionEvaluator(SequentialValueExpressionEvaluatorType sequentialValueEvaluatorType,
D outputDefinition, Protector protector, RepositoryService repositoryService, PrismContext prismContext) {
this.sequentialValueEvaluatorType = sequentialValueEvaluatorType;
this.outputDefinition = outputDefinition;
this.protector = protector;
this.repositoryService = repositoryService;
this.prismContext = prismContext;
}

@Override
public PrismValueDeltaSetTriple<V> evaluate(ExpressionEvaluationContext params) throws SchemaException,
ExpressionEvaluationException, ObjectNotFoundException {

long counter = repositoryService.advanceSequence(sequentialValueEvaluatorType.getSequenceRef().getOid(), params.getResult());

Object value = ExpressionUtil.convertToOutputValue(counter, outputDefinition, protector);

Item<V,D> output = outputDefinition.instantiate();
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);
}

/* (non-Javadoc)
* @see com.evolveum.midpoint.common.expression.ExpressionEvaluator#shortDebugDump()
*/
@Override
public String shortDebugDump() {
return "squentialValue: "+sequentialValueEvaluatorType.getSequenceRef().getOid();
}

}
@@ -0,0 +1,89 @@
/*
* Copyright (c) 2015 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.impl.expr;

import java.util.Collection;

import javax.xml.bind.JAXBElement;
import javax.xml.namespace.QName;

import com.evolveum.midpoint.model.common.expression.ExpressionEvaluator;
import com.evolveum.midpoint.model.common.expression.ExpressionEvaluatorFactory;
import com.evolveum.midpoint.prism.ItemDefinition;
import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.PrismValue;
import com.evolveum.midpoint.prism.crypto.Protector;
import com.evolveum.midpoint.repo.api.RepositoryService;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.util.exception.ObjectNotFoundException;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectFactory;
import com.evolveum.midpoint.xml.ns._public.common.common_3.SequentialValueExpressionEvaluatorType;

/**
* @author semancik
*
*/
public class SequentialValueExpressionEvaluatorFactory implements ExpressionEvaluatorFactory {

private Protector protector;
private PrismContext prismContext;
private RepositoryService repositoryService;

public SequentialValueExpressionEvaluatorFactory(Protector protector, RepositoryService repositoryService, PrismContext prismContext) {
super();
this.protector = protector;
this.prismContext = prismContext;
this.repositoryService = repositoryService;
}

@Override
public QName getElementName() {
return new ObjectFactory().createSequentialValue(new SequentialValueExpressionEvaluatorType()).getName();
}

/* (non-Javadoc)
* @see com.evolveum.midpoint.common.expression.ExpressionEvaluatorFactory#createEvaluator(javax.xml.bind.JAXBElement, com.evolveum.midpoint.prism.PrismContext)
*/
@Override
public <V extends PrismValue,D extends ItemDefinition> ExpressionEvaluator<V,D> createEvaluator(Collection<JAXBElement<?>> evaluatorElements,
D outputDefinition, String contextDescription, Task task, OperationResult result)
throws SchemaException, ObjectNotFoundException {

if (evaluatorElements.size() > 1) {
throw new SchemaException("More than one evaluator specified in "+contextDescription);
}
JAXBElement<?> evaluatorElement = evaluatorElements.iterator().next();

Object evaluatorTypeObject = null;
if (evaluatorElement != null) {
evaluatorTypeObject = evaluatorElement.getValue();
}
if (evaluatorTypeObject != null && !(evaluatorTypeObject instanceof SequentialValueExpressionEvaluatorType)) {
throw new SchemaException("SequentialValue expression evaluator cannot handle elements of type " + evaluatorTypeObject.getClass().getName()+" in "+contextDescription);
}

SequentialValueExpressionEvaluatorType seqEvaluatorType = (SequentialValueExpressionEvaluatorType)evaluatorTypeObject;

if (seqEvaluatorType.getSequenceRef() == null || seqEvaluatorType.getSequenceRef().getOid() == null) {
throw new SchemaException("Missing sequence reference in sequentialValue expression evaluator in "+contextDescription);
}

return new SequentialValueExpressionEvaluator<V,D>(seqEvaluatorType, outputDefinition, protector, repositoryService, prismContext);
}

}
8 changes: 8 additions & 0 deletions model/model-impl/src/main/resources/ctx-model.xml
Expand Up @@ -199,6 +199,13 @@
<constructor-arg ref="modelController"/>
</bean>

<bean id="sequentialValueExpressionEvaluatorFactory" class="com.evolveum.midpoint.model.impl.expr.SequentialValueExpressionEvaluatorFactory"
scope="singleton">
<constructor-arg ref="protector"/>
<constructor-arg ref="cacheRepositoryService"/>
<constructor-arg name="prismContext" ref="prismContext"/>
</bean>

<bean id="expressionFactory" class="com.evolveum.midpoint.model.common.expression.ExpressionFactory"
scope="singleton">
<constructor-arg>
Expand All @@ -218,6 +225,7 @@
<ref bean="referenceSearchExpressionEvaluatorFactory"/>
<ref bean="associationTargetSearchExpressionEvaluatorFactory"/>
<ref bean="associationFromLinkExpressionEvaluatorFactory"/>
<ref bean="sequentialValueExpressionEvaluatorFactory"/>
</list>
</property>
<property name="defaultEvaluatorFactory">
Expand Down
Expand Up @@ -1710,7 +1710,7 @@ public void test320AddAccountPosix() throws Exception {
assertAttribute(provisioningShadowType, "cn", "Haggis McMutton");
assertAttribute(provisioningShadowType, "sn", "McMutton");
assertAttribute(provisioningShadowType, "homeDirectory", "/home/scotland");
assertAttribute(provisioningShadowType, "uidNumber", "1001");
assertAttribute(provisioningShadowType, "uidNumber", 1001);

String uid = ShadowUtil.getSingleStringAttributeValue(repoShadowType, getPrimaryIdentifierQName());
assertNotNull(uid);
Expand Down Expand Up @@ -1760,7 +1760,7 @@ public void test322ModifyAccountPosix() throws Exception {
assertAttribute(accountType, "cn", "Haggis McMutton");
assertAttribute(accountType, "homeDirectory", "/home/caribbean");
assertAttribute(accountType, "roomNumber", "Barber Shop");
assertAttribute(accountType, "uidNumber", "1001");
assertAttribute(accountType, "uidNumber", 1001);

// Check if object was modified in LDAP

Expand Down Expand Up @@ -1846,7 +1846,7 @@ public void test330SearchForPosixAccount() throws Exception {
PrismObject<ShadowType> provisioningShadow = objListType.get(0);
assertAttribute(provisioningShadow, "cn", "Edward Van Helgen");
assertAttribute(provisioningShadow, "homeDirectory", "/home/vanhelgen");
assertAttribute(provisioningShadow, "uidNumber", "1002");
assertAttribute(provisioningShadow, "uidNumber", 1002);

assertConnectorOperationIncrement(1);
assertConnectorSimulatedPagingSearchIncrement(0);
Expand Down

0 comments on commit c9bf742

Please sign in to comment.