Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
mederly committed Nov 13, 2017
2 parents 1f0c83a + 6b95f1d commit df8f26c
Show file tree
Hide file tree
Showing 38 changed files with 1,303 additions and 390 deletions.
Expand Up @@ -17,9 +17,9 @@
xmlns:wicket="http://wicket.apache.org">
<body>
<wicket:panel>
<div wicket:id="displayName"/>
<div wicket:id="basic" />
<div wicket:id="otherContainers" />
<div wicket:id="displayName"/>
<div wicket:id="specificContainers" />
<div wicket:id="basicAssignmentPanel" />
<div wicket:id="activationPanel" />

<!-- <div class="box-body" > -->
Expand Down
Expand Up @@ -55,7 +55,8 @@ public abstract class AbstractAssignmentDetailsPanel<F extends FocusType> extend

private final static String ID_DISPLAY_NAME = "displayName";
private final static String ID_ACTIVATION_PANEL = "activationPanel";
protected final static String ID_CONTAINERS = "otherContainers";
private final static String ID_BASIC_ASSIGNMENT_PANEL = "basicAssignmentPanel";
protected final static String ID_SPECIFIC_CONTAINERS = "specificContainers";

public AbstractAssignmentDetailsPanel(String id, Form<?> form, IModel<ContainerValueWrapper<AssignmentType>> assignmentModel){
super(id, assignmentModel);
Expand Down Expand Up @@ -123,7 +124,7 @@ protected QName getRelation() {
ContainerValueWrapper<AssignmentType> containerWrapper = getModelObject();
if (containerWrapper == null){}

ContainerValuePanel<AssignmentType> assignmentPanel = new ContainerValuePanel("basic", getModel(), true, form,
ContainerValuePanel<AssignmentType> assignmentPanel = new ContainerValuePanel(ID_BASIC_ASSIGNMENT_PANEL, getModel(), true, form,
itemWrapper -> getAssignmentBasicTabVisibity(itemWrapper, assignmentPath), pageBase);
add(assignmentPanel);

Expand All @@ -136,7 +137,7 @@ protected QName getRelation() {
}

protected void initContainersPanel(Form form, PageAdminObjectDetails<F> pageBase){
PrismPanel<AssignmentType> containers = new PrismPanel<>(ID_CONTAINERS, new ContainerWrapperListFromObjectWrapperModel<AssignmentType, F>(pageBase.getObjectModel(), collectContainersToShow()),
PrismPanel<AssignmentType> containers = new PrismPanel<>(ID_SPECIFIC_CONTAINERS, new ContainerWrapperListFromObjectWrapperModel<AssignmentType, F>(pageBase.getObjectModel(), collectContainersToShow()),
null, form, null, pageBase) ;
add(containers);
}
Expand Down
Expand Up @@ -433,10 +433,10 @@ protected void appendOriginDump(StringBuilder builder) {
}
}

public static <T> Set<T> getRealValuesOfCollection(Collection<PrismPropertyValue<T>> collection) {
public static <T> Set<T> getRealValuesOfCollection(Collection<? extends PrismValue> collection) {
Set<T> retval = new HashSet<T>(collection.size());
for (PrismPropertyValue<T> value : collection) {
retval.add(value.getValue());
for (PrismValue value : collection) {
retval.add(value.getRealValue());
}
return retval;
}
Expand Down
Expand Up @@ -46,6 +46,7 @@ public class ExpressionConstants {
public static final QName VAR_PRISM_CONTEXT = new QName(SchemaConstants.NS_C, "prismContext");
public static final QName VAR_CONFIGURATION = new QName(SchemaConstants.NS_C, "configuration");
public static final QName VAR_ENTITLEMENT = new QName(SchemaConstants.NS_C, "entitlement");
public static final QName VAR_FILE = new QName(SchemaConstants.NS_C, "file");

/**
* User that is currently executing the operation.
Expand Down
Expand Up @@ -6658,19 +6658,32 @@
<a:since>3.7</a:since>
</xsd:appinfo>
</xsd:annotation>
<xsd:sequence>
<!-- TODO: later
<xsd:sequence>
<xsd:element name="macro" type="tns:ProvisioningScriptArgumentType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
Command-line macro. Any occurence of the macro will be replaced in the command-line code.
The order of arguments is not significant.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<!-- TODO: later
<xsd:element name="argument" type="tns:ProvisioningScriptArgumentType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
Script arguments. The arguments will passed to the script
in any way suitable for the script. The argument name
is "local" to the script (script-specific). Script name
is "local" to the script (script-specific). Argument name
must be unique in the argument set.
The order of arguments is not significant.
</xsd:documentation>
</xsd:annotation>
</xsd:element> -->
</xsd:element>
<xsd:element name="environment" type="tns:ProvisioningScriptArgumentType" minOccurs="0" maxOccurs="unbounded">
</xsd:element>
-->
<xsd:element name="executionMethod" type="tns:CommandLineExecutionMethod">
</xsd:element>
<xsd:element name="code" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
Expand All @@ -6684,6 +6697,43 @@
</xsd:element>
</xsd:sequence>
</xsd:complexType>

<xsd:simpleType name="CommandLineExecutionMethod">
<xsd:annotation>
<xsd:documentation>
TODO
</xsd:documentation>
<xsd:appinfo>
<jaxb:typesafeEnumClass/>
</xsd:appinfo>
</xsd:annotation>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="exec">
<xsd:annotation>
<xsd:documentation>
<p>
Plain exececution using OS services (exec).
</p>
</xsd:documentation>
<xsd:appinfo>
<jaxb:typesafeEnumMember name="EXEC"/>
</xsd:appinfo>
</xsd:annotation>
</xsd:enumeration>
<xsd:enumeration value="shell">
<xsd:annotation>
<xsd:documentation>
<p>
Execution using UNIX-like shell (e.g. bash)
</p>
</xsd:documentation>
<xsd:appinfo>
<jaxb:typesafeEnumMember name="SHELL"/>
</xsd:appinfo>
</xsd:annotation>
</xsd:enumeration>
</xsd:restriction>
</xsd:simpleType>

<xsd:complexType name="ConnectorConfigurationType">
<xsd:annotation>
Expand Down
Expand Up @@ -7,6 +7,7 @@ public class MidPointTestConstants {
public static final String TEST_RESOURCES_PATH = "src/test/resources";
public static File TEST_RESOURCES_DIR = new File (TEST_RESOURCES_PATH);
public static File OBJECTS_DIR = new File(TEST_RESOURCES_DIR, "objects");
public static final String TARGET_DIR_PATH = "target";

// copied from TestProtector - unfortunately these values are needed both in prism and in other modules
public static final String KEYSTORE_PATH = "src/test/resources/keystore.jceks";
Expand Down
Expand Up @@ -15,6 +15,7 @@
*/
package com.evolveum.midpoint.model.common.expression.functions;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
Expand All @@ -25,10 +26,18 @@
import org.apache.commons.lang.Validate;

import com.evolveum.midpoint.prism.ItemDefinition;
import com.evolveum.midpoint.prism.PrismContainerValue;
import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.PrismPropertyDefinitionImpl;
import com.evolveum.midpoint.prism.PrismPropertyValue;
import com.evolveum.midpoint.prism.PrismValue;
import com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple;
import com.evolveum.midpoint.prism.polystring.PolyString;
import com.evolveum.midpoint.prism.util.JavaTypeConverter;
import com.evolveum.midpoint.prism.xml.XmlTypeConverter;
import com.evolveum.midpoint.prism.xml.XsdTypeMapper;
import com.evolveum.midpoint.repo.common.expression.Expression;
import com.evolveum.midpoint.repo.common.expression.ExpressionEvaluationContext;
import com.evolveum.midpoint.repo.common.expression.ExpressionFactory;
import com.evolveum.midpoint.repo.common.expression.ExpressionUtil;
import com.evolveum.midpoint.repo.common.expression.ExpressionVariables;
Expand Down Expand Up @@ -68,40 +77,70 @@ public CustomFunctions(FunctionLibraryType library, ExpressionFactory expression
this.task = task;
}

public Object execute(String functionName, Map<String, Object> params) throws ExpressionEvaluationException {
public <V extends PrismValue, D extends ItemDefinition> Object execute(String functionName, Map<String, Object> params) throws ExpressionEvaluationException {
Validate.notNull(functionName, "Function name must be specified");

List<ExpressionType> functions = library.getFunction().stream().filter(expression -> functionName.equals(expression.getName())).collect(Collectors.toList());

LOGGER.trace("functions {}", functions);
ExpressionType expression = functions.iterator().next();
ExpressionType expressionType = functions.iterator().next();

LOGGER.trace("function to execute {}", expression);
LOGGER.trace("function to execute {}", expressionType);

try {
ExpressionVariables variables = new ExpressionVariables();
if (MapUtils.isNotEmpty(params)) {
for (Map.Entry<String, Object> entry : params.entrySet()) {
variables.addVariableDefinition(new QName(entry.getKey()), convertInput(entry, expression));
variables.addVariableDefinition(new QName(entry.getKey()), convertInput(entry, expressionType));
};
}

QName returnType = expression.getReturnType();
QName returnType = expressionType.getReturnType();
if (returnType == null) {
returnType = DOMUtil.XSD_STRING;
}

ItemDefinition outputDefinition = prismContext.getSchemaRegistry().findItemDefinitionByType(returnType);
D outputDefinition = (D) prismContext.getSchemaRegistry().findItemDefinitionByType(returnType);
if (outputDefinition == null) {
outputDefinition = new PrismPropertyDefinitionImpl<>(SchemaConstantsGenerated.C_VALUE, returnType, prismContext);
outputDefinition = (D) new PrismPropertyDefinitionImpl(SchemaConstantsGenerated.C_VALUE, returnType, prismContext);
}
if (expression.getReturnMultiplicity() != null && expression.getReturnMultiplicity() == ExpressionReturnMultiplicityType.MULTI) {
if (expressionType.getReturnMultiplicity() != null && expressionType.getReturnMultiplicity() == ExpressionReturnMultiplicityType.MULTI) {
outputDefinition.setMaxOccurs(-1);
} else {
outputDefinition.setMaxOccurs(1);
}
String shortDesc = "custom function execute";
Expression<V, D> expression = expressionFactory.makeExpression(expressionType, outputDefinition,
shortDesc, task, result);

ExpressionEvaluationContext context = new ExpressionEvaluationContext(null, variables, shortDesc, task,
result);
PrismValueDeltaSetTriple<V> outputTriple = expression.evaluate(context);

LOGGER.trace("Result of the expression evaluation: {}", outputTriple);

if (outputTriple == null) {
return null;
}

Collection<V> nonNegativeValues = outputTriple.getNonNegativeValues();

if (nonNegativeValues == null || nonNegativeValues.isEmpty()) {
return null;
}

if (outputDefinition.isMultiValue()) {
return PrismValue.getRealValuesOfCollection(nonNegativeValues);
}


if (nonNegativeValues.size() > 1) {
throw new ExpressionEvaluationException("Expression returned more than one value ("
+ nonNegativeValues.size() + ") in " + shortDesc);
}

return nonNegativeValues.iterator().next().getRealValue();

return ExpressionUtil.evaluateExpression(variables, outputDefinition, expression, expressionFactory, "description", task, result);

} catch (SchemaException | ExpressionEvaluationException | ObjectNotFoundException | CommunicationException | ConfigurationException | SecurityViolationException e) {
throw new ExpressionEvaluationException(e.getMessage(), e);
Expand All @@ -112,19 +151,27 @@ public Object execute(String functionName, Map<String, Object> params) throws Ex
private Object convertInput(Map.Entry<String, Object> entry, ExpressionType expression) throws SchemaException {

ExpressionParameterType expressionParam = expression.getParameter().stream().filter(param -> param.getName().equals(entry.getKey())).findAny().orElseThrow(SchemaException :: new);
Class<?> expressioNParameterClass = XsdTypeMapper.toJavaTypeIfKnown(expressionParam.getType());

// FIXME: awful hack
if (String.class.equals(expressioNParameterClass) && entry.getValue() instanceof PolyString) {
return ((PolyString) entry.getValue()).getOrig();
QName paramType = expressionParam.getType();
Class<?> expressionParameterClass = prismContext.getSchemaRegistry().determineClassForType(paramType);

if (expressionParameterClass != null && !DOMUtil.XSD_ANYTYPE.equals(paramType) && XmlTypeConverter.canConvert(expressionParameterClass)) {
return ExpressionUtil.convertValue(expressionParameterClass, null, entry.getValue(), prismContext.getDefaultProtector(), prismContext);
}

return entry.getValue();

// FIXME: awful hack
// if (String.class.equals(expressioNParameterClass) && entry.getValue() instanceof PolyString) {
// return ((PolyString) entry.getValue()).getOrig();
// }

//if (expressioNParameterClass != null && !expressioNParameterClass.isAssignableFrom(entry.getValue().getClass())) {
// if (expressioNParameterClass != null && !expressioNParameterClass.equals(entry.getValue().getClass())){
// throw new SchemaException("Unexpected type of value, expecting " + expressioNParameterClass.getSimpleName() + " but the actual value is " + entry.getValue().getClass().getSimpleName());
// }

return entry.getValue();
// return entry.getValue();

}

Expand Down
Expand Up @@ -149,9 +149,10 @@
map.put("country", locality)
fixedDrink = myLib.execute("addCountry", map)
}

log.info("drink: "+fixedDrink)
return fixedDrink
return fixedDrink.toString()
</code>
</script>
</expression>
Expand Down
22 changes: 22 additions & 0 deletions model/report-impl/pom.xml
Expand Up @@ -227,6 +227,12 @@
<version>3.7-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.evolveum.midpoint.repo</groupId>
<artifactId>security-enforcer-impl</artifactId>
<version>3.7-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.evolveum.midpoint.model</groupId>
<artifactId>model-test</artifactId>
Expand Down Expand Up @@ -278,6 +284,22 @@
<version>3.7-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.evolveum.midpoint.repo</groupId>
<artifactId>repo-sql-impl-test</artifactId>
<version>3.7-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency> <!-- needed as runtime dependency otherwise spring won't start -->
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<scope>test</scope>
</dependency>
<dependency> <!-- needed as runtime dependency otherwise spring won't start -->
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
Expand Down

0 comments on commit df8f26c

Please sign in to comment.