org.gradle.util.ConfigureUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gradle-api Show documentation
Show all versions of gradle-api Show documentation
Gradle 6.9.1 API redistribution.
/*
* Copyright 2010 the original author or authors.
*
* 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 org.gradle.util;
import groovy.lang.Closure;
import org.codehaus.groovy.runtime.GeneratedClosure;
import org.gradle.api.Action;
import org.gradle.api.Nullable;
import org.gradle.api.internal.ClosureBackedAction;
import org.gradle.api.internal.DynamicObjectUtil;
import org.gradle.internal.Actions;
import org.gradle.internal.metaobject.ConfigureDelegate;
import org.gradle.internal.metaobject.DynamicObject;
import org.gradle.internal.metaobject.InvokeMethodResult;
import org.gradle.internal.metaobject.SetPropertyResult;
import java.util.Collection;
import java.util.Map;
import static org.gradle.util.CollectionUtils.toStringList;
public class ConfigureUtil {
public static T configureByMap(Map, ?> properties, T delegate) {
DynamicObject dynamicObject = DynamicObjectUtil.asDynamicObject(delegate);
for (Map.Entry, ?> entry : properties.entrySet()) {
String name = entry.getKey().toString();
Object value = entry.getValue();
SetPropertyResult setterResult = new SetPropertyResult();
dynamicObject.setProperty(name, value, setterResult);
if (setterResult.isFound()) {
continue;
}
InvokeMethodResult invokeResult = new InvokeMethodResult();
dynamicObject.invokeMethod(name, invokeResult, value);
if (!invokeResult.isFound()) {
throw dynamicObject.setMissingProperty(name);
}
}
return delegate;
}
public static T configureByMap(Map, ?> properties, T delegate, Collection> mandatoryKeys) {
if (!mandatoryKeys.isEmpty()) {
Collection missingKeys = toStringList(mandatoryKeys);
missingKeys.removeAll(toStringList(properties.keySet()));
if (!missingKeys.isEmpty()) {
throw new IncompleteInputException("Input configuration map does not contain following mandatory keys: " + missingKeys, missingKeys);
}
}
return configureByMap(properties, delegate);
}
public static class IncompleteInputException extends RuntimeException {
private final Collection missingKeys;
public IncompleteInputException(String message, Collection missingKeys) {
super(message);
this.missingKeys = missingKeys;
}
public Collection getMissingKeys() {
return missingKeys;
}
}
/**
* Configures {@code target} with {@code configureClosure}, via the {@link Configurable} interface if necessary.
*
* If {@code target} does not implement {@link Configurable} interface, it is set as the delegate of a clone of
* {@code configureClosure} with a resolve strategy of {@code DELEGATE_FIRST}.
*
* If {@code target} does implement the {@link Configurable} interface, the {@code configureClosure} will be passed to
* {@code delegate}'s {@link Configurable#configure(Closure)} method.
*
* @param configureClosure The configuration closure
* @param target The object to be configured
* @return The delegate param
*/
public static T configure(@Nullable Closure configureClosure, T target) {
if (configureClosure == null) {
return target;
}
if (target instanceof Configurable) {
((Configurable) target).configure(configureClosure);
} else {
configureTarget(configureClosure, target, new ConfigureDelegate(configureClosure, target));
}
return target;
}
/**
* Creates an action that uses the given closure to configure objects of type T.
*/
public static Action configureUsing(@Nullable final Closure configureClosure) {
if (configureClosure == null) {
return Actions.doNothing();
}
return new Action() {
@Override
public void execute(T t) {
configure(configureClosure, t);
}
};
}
/**
* Called from an object's {@link Configurable#configure} method.
*/
public static T configureSelf(@Nullable Closure configureClosure, T target) {
if (configureClosure == null) {
return target;
}
configureTarget(configureClosure, target, new ConfigureDelegate(configureClosure, target));
return target;
}
/**
* Called from an object's {@link Configurable#configure} method.
*/
public static T configureSelf(@Nullable Closure configureClosure, T target, ConfigureDelegate closureDelegate) {
if (configureClosure == null) {
return target;
}
configureTarget(configureClosure, target, closureDelegate);
return target;
}
private static void configureTarget(Closure configureClosure, T target, ConfigureDelegate closureDelegate) {
if (!(configureClosure instanceof GeneratedClosure)) {
new ClosureBackedAction(configureClosure, Closure.DELEGATE_FIRST, false).execute(target);
return;
}
// Hackery to make closure execution faster, by short-circuiting the expensive property and method lookup on Closure
Closure withNewOwner = configureClosure.rehydrate(target, closureDelegate, configureClosure.getThisObject());
new ClosureBackedAction(withNewOwner, Closure.OWNER_ONLY, false).execute(target);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy