Skip to content

Commit

Permalink
Merge remote-tracking branch 'refs/remotes/origin/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
skublik committed Oct 7, 2019
2 parents 6192ac1 + 99122a4 commit 0657d48
Show file tree
Hide file tree
Showing 36 changed files with 1,690 additions and 88 deletions.
Expand Up @@ -89,7 +89,7 @@ public void onClick(AjaxRequestTarget ajaxRequestTarget) {
getDetailsPanelContainer().add(cancelButton);

CaseWorkItemActionsPanel actionsPanel = new CaseWorkItemActionsPanel(ID_CASE_WORK_ITEM_ACTIONS_PANEL,
new LoadableModel<>() {
new LoadableModel<CaseWorkItemType>() {
private static final long serialVersionUID = 1L;

@Override
Expand Down
Expand Up @@ -101,7 +101,7 @@ private XSSchemaSet parseSchema(Element schema) throws SchemaException {
// Make sure that the schema parser sees all the namespace declarations
DOMUtil.fixNamespaceDeclarations(schema);
try {
TransformerFactory transfac = TransformerFactory.newInstance();
TransformerFactory transfac = DOMUtil.setupTransformerFactory();
Transformer trans = transfac.newTransformer();
trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
trans.setOutputProperty(OutputKeys.INDENT, "yes");
Expand Down
34 changes: 13 additions & 21 deletions infra/util/src/main/java/com/evolveum/midpoint/util/DOMUtil.java
Expand Up @@ -171,27 +171,7 @@ public class DOMUtil {

transformerThreadLocal = ThreadLocal.withInitial(() -> {
try {
//setTransformerFactoryIfPresent("com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl"); // too many whitespaces in Java11
//setTransformerFactoryIfPresent("org.apache.xalan.xsltc.trax.TransformerFactoryImpl"); // too few whitespaces

String className = "org.apache.xalan.processor.TransformerFactoryImpl";
setTransformerFactoryIfPresent(className); // a bit slower

ClassLoader cl = null;
try {
Class clazz = Class.forName(className);
if (clazz != null) {
cl = clazz.getClassLoader();
}
} catch (Exception ex) {
}

TransformerFactory transformerFactory;
if (cl != null) {
transformerFactory = TransformerFactory.newInstance(className, cl);
} else {
transformerFactory = TransformerFactory.newInstance();
}
TransformerFactory transformerFactory = setupTransformerFactory();

//System.out.println("TF = " + transformerFactory.getClass().getName());
Transformer trans = transformerFactory.newTransformer();
Expand All @@ -205,7 +185,19 @@ public class DOMUtil {
});
}

public static TransformerFactory setupTransformerFactory() {
//setTransformerFactoryIfPresent("com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl"); // too many whitespaces in Java11
//setTransformerFactoryIfPresent("org.apache.xalan.xsltc.trax.TransformerFactoryImpl"); // too few whitespaces
setTransformerFactoryIfPresent("org.apache.xalan.processor.TransformerFactoryImpl"); // a bit slower

return TransformerFactory.newInstance();
}

private static void setTransformerFactoryIfPresent(String className) {
if (!DOMUtilSettings.isAddTransformerFactorySystemProperty()) {
return;
}

String propertyName = TransformerFactory.class.getName();
try {
Class.forName(className);
Expand Down
@@ -0,0 +1,39 @@
/*
* Copyright (c) 2010-2019 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.util;

/**
* Created by Viliam Repan (lazyman).
*/
public class DOMUtilSettings {

private static boolean addTransformerFactorySystemProperty = true;

public static boolean isAddTransformerFactorySystemProperty() {
return addTransformerFactorySystemProperty;
}

/**
* Method used by MidPoint Studio to disable setting system property during {@link DOMUtil} initialization.
* Not used within MidPoint as the default "true" value doesn't change the initialization behaviour.
*
* @param addTransformerFactorySystemProperty
*/
public static void setAddTransformerFactorySystemProperty(boolean addTransformerFactorySystemProperty) {
DOMUtilSettings.addTransformerFactorySystemProperty = addTransformerFactorySystemProperty;
}
}
Expand Up @@ -1193,4 +1193,7 @@ <O extends ObjectType> void addRecomputeTrigger(PrismObject<O> object, Long time
throws ObjectAlreadyExistsException, SchemaException, ObjectNotFoundException;

RepositoryService getRepositoryService();

@NotNull
OptimizingTriggerCreator getOptimizingTriggerCreator(long fireAfter, long safetyMargin);
}
@@ -0,0 +1,51 @@
/*
* Copyright (c) 2019 Evolveum and contributors
*
* This work is dual-licensed under the Apache License 2.0
* and European Union Public License. See LICENSE file for details.
*/

package com.evolveum.midpoint.model.api.expr;

import com.evolveum.midpoint.util.exception.ObjectAlreadyExistsException;
import com.evolveum.midpoint.util.exception.ObjectNotFoundException;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;
import org.jetbrains.annotations.NotNull;

/**
* Adds recompute triggers to objects in an optimized way:
* - The triggers are set to a given time in future (e.g. 1 minute from now).
* - If more requests to create triggers to the same object come before that time comes (minus some safety margin,
* e.g. 2 seconds), their creation is skipped.
*
* Currently we deal only with the recompute triggers. Other types can be added as necessary.
*
* The deduplication currently assumes the requests are of the same kind (i.e. either name-based or OID-based).
*/
public interface OptimizingTriggerCreator {

/**
* Creates a trigger for the user with the given name.
* @return true if the trigger was really added; false if it already existed or could not be added
*
* (Note that if the object cannot be found by the name, currently no exception is reported.)
*/
boolean createForNamedUser(@NotNull String name) throws SchemaException, ObjectAlreadyExistsException, ObjectNotFoundException;

/**
* Creates a trigger for the object with the given name.
* @return true if the trigger was really added; false if it already existed or could not be added
*
* (Note that if the object cannot be found by the name, currently no exception is reported.)
*/
boolean createForNamedObject(@NotNull Class<? extends ObjectType> type, @NotNull String name)
throws ObjectAlreadyExistsException, ObjectNotFoundException, SchemaException;

/**
* Creates a trigger to the user with the given OID.
* @return true if the trigger was really added; false if it already existed or could not be added
*/
boolean createForObject(@NotNull Class<? extends ObjectType> type, @NotNull String oid)
throws ObjectAlreadyExistsException, ObjectNotFoundException, SchemaException;
}
Expand Up @@ -13,6 +13,7 @@

import javax.xml.namespace.QName;

import com.evolveum.midpoint.model.common.expression.script.ScriptExpressionEvaluationContext;
import com.evolveum.midpoint.prism.*;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang.Validate;
Expand Down Expand Up @@ -46,23 +47,31 @@

public class CustomFunctions {

Trace LOGGER = TraceManager.getTrace(CustomFunctions.class);
private Trace LOGGER = TraceManager.getTrace(CustomFunctions.class);

private ExpressionFactory expressionFactory;
private FunctionLibraryType library;
private ExpressionProfile expressionProfile;
private OperationResult result;
private Task task;
private PrismContext prismContext;
/**
* Operation result existing at the initialization time. It is used only if we cannot obtain current operation
* result in any other way.
*/
private OperationResult initializationTimeResult;
/**
* Operation result existing at the initialization time. It is used only if we cannot obtain current operation
* result in any other way.
*/
private Task initializationTimeTask;


public CustomFunctions(FunctionLibraryType library, ExpressionFactory expressionFactory, ExpressionProfile expressionProfile, OperationResult result, Task task) {
public CustomFunctions(FunctionLibraryType library, ExpressionFactory expressionFactory, ExpressionProfile expressionProfile,
OperationResult result, Task task) {
this.library = library;
this.expressionFactory = expressionFactory;
this.expressionProfile = expressionProfile;
this.prismContext = expressionFactory.getPrismContext();
this.result = result;
this.task = task;
this.initializationTimeResult = result;
this.initializationTimeTask = task;
}

/**
Expand All @@ -71,6 +80,31 @@ public CustomFunctions(FunctionLibraryType library, ExpressionFactory expression
*/
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");

ScriptExpressionEvaluationContext ctx = ScriptExpressionEvaluationContext.getThreadLocal();
Task task;
OperationResult result;
if (ctx != null) {
if (ctx.getTask() != null) {
task = ctx.getTask();
} else {
LOGGER.warn("No task in ScriptExpressionEvaluationContext for the current thread found. Using "
+ "initialization-time task: {}", initializationTimeTask);
task = initializationTimeTask;
}
if (ctx.getResult() != null) {
result = ctx.getResult();
} else {
LOGGER.warn("No operation result in ScriptExpressionEvaluationContext for the current thread found. Using "
+ "initialization-time op. result");
result = initializationTimeResult;
}
} else {
LOGGER.warn("No ScriptExpressionEvaluationContext for current thread found. Using initialization-time task "
+ "and operation result: {}", initializationTimeTask);
task = initializationTimeTask;
result = initializationTimeResult;
}

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

Expand All @@ -84,16 +118,18 @@ public <V extends PrismValue, D extends ItemDefinition> Object execute(String fu
if (MapUtils.isNotEmpty(params)) {
for (Map.Entry<String, Object> entry : params.entrySet()) {
variables.put(entry.getKey(), convertInput(entry, expressionType));
};
}
}

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


//noinspection unchecked
D outputDefinition = (D) prismContext.getSchemaRegistry().findItemDefinitionByType(returnType);
if (outputDefinition == null) {
//noinspection unchecked
outputDefinition = (D) prismContext.definitionFactory().createPropertyDefinition(SchemaConstantsGenerated.C_VALUE, returnType);
}
if (expressionType.getReturnMultiplicity() != null && expressionType.getReturnMultiplicity() == ExpressionReturnMultiplicityType.MULTI) {
Expand All @@ -116,7 +152,7 @@ public <V extends PrismValue, D extends ItemDefinition> Object execute(String fu

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

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

Expand Down Expand Up @@ -160,7 +196,7 @@ private TypedValue convertInput(Map.Entry<String, Object> entry, ExpressionType

ItemDefinition def = ExpressionUtil.determineDefinitionFromValueClass(prismContext, entry.getKey(), valueClass, paramType);

return new TypedValue(value, def);
return new TypedValue<>(value, def);
}

}
Expand Up @@ -19,11 +19,14 @@
import com.evolveum.midpoint.model.api.context.ModelProjectionContext;
import com.evolveum.midpoint.model.api.context.SynchronizationPolicyDecision;
import com.evolveum.midpoint.model.api.expr.MidpointFunctions;
import com.evolveum.midpoint.model.api.expr.OptimizingTriggerCreator;
import com.evolveum.midpoint.model.common.ArchetypeManager;
import com.evolveum.midpoint.model.common.ConstantsManager;
import com.evolveum.midpoint.model.common.expression.script.ScriptExpressionEvaluationContext;
import com.evolveum.midpoint.model.common.mapping.MappingImpl;
import com.evolveum.midpoint.model.impl.ModelObjectResolver;
import com.evolveum.midpoint.model.impl.expr.triggerSetter.OptimizingTriggerCreatorImpl;
import com.evolveum.midpoint.model.impl.expr.triggerSetter.TriggerCreatorGlobalState;
import com.evolveum.midpoint.model.impl.lens.EvaluatedAssignmentImpl;
import com.evolveum.midpoint.model.impl.lens.LensContext;
import com.evolveum.midpoint.model.impl.lens.LensFocusContext;
Expand All @@ -48,10 +51,6 @@
import com.evolveum.midpoint.repo.common.expression.ExpressionFactory;
import com.evolveum.midpoint.schema.*;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition;
import com.evolveum.midpoint.schema.processor.ResourceAttribute;
import com.evolveum.midpoint.schema.processor.ResourceAttributeDefinition;
import com.evolveum.midpoint.schema.processor.ResourceSchema;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.schema.result.OperationResultStatus;
import com.evolveum.midpoint.schema.util.*;
Expand Down Expand Up @@ -128,6 +127,7 @@ public class MidpointFunctionsImpl implements MidpointFunctions {
@Autowired private ExpressionFactory expressionFactory;
@Autowired private SynchronizationExpressionsEvaluator correlationConfirmationEvaluator;
@Autowired private ArchetypeManager archetypeManager;
@Autowired private TriggerCreatorGlobalState triggerCreatorGlobalState;

@Autowired
@Qualifier("cacheRepositoryService")
Expand Down Expand Up @@ -1907,4 +1907,10 @@ public <O extends ObjectType> void addRecomputeTrigger(PrismObject<O> object, Lo
public RepositoryService getRepositoryService() {
return repositoryService;
}

@NotNull
@Override
public OptimizingTriggerCreator getOptimizingTriggerCreator(long fireAfter, long safetyMargin) {
return new OptimizingTriggerCreatorImpl(triggerCreatorGlobalState, this, fireAfter, safetyMargin);
}
}
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2019 Evolveum and contributors
*
* This work is dual-licensed under the Apache License 2.0
* and European Union Public License. See LICENSE file for details.
*/

package com.evolveum.midpoint.model.impl.expr.triggerSetter;

import org.jetbrains.annotations.NotNull;

/**
* Information on the trigger created for a given object.
*/
class CreatedTrigger {

/**
* OID of the holder. It is sometimes resolved only when the trigger is being created.
*/
@NotNull private final String holderOid;

/**
* This is the fire time of the trigger created. Of course there might exist other triggers as well: created on another node,
* or created by a mechanism other than OptimizingTriggerCreator. We don't care. We have just one goal: to avoid redundant
* triggers being added when they come in a series on a single node.
*/
private final long fireTime;

CreatedTrigger(@NotNull String holderOid, long fireTime) {
this.holderOid = holderOid;
this.fireTime = fireTime;
}

@NotNull
String getHolderOid() {
return holderOid;
}

long getFireTime() {
return fireTime;
}

@Override
public String toString() {
return "CreatedTrigger{" +
"holderOid='" + holderOid + '\'' +
", fireTime=" + fireTime +
'}';
}
}

0 comments on commit 0657d48

Please sign in to comment.