All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.gradle.internal.typeconversion.NotationParserBuilder Maven / Gradle / Ivy

There is a newer version: 8.6
Show newest version
/*
 * Copyright 2011 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.internal.typeconversion;

import org.gradle.api.Describable;

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

public class NotationParserBuilder {
    private final Class notationType;
    private final TypeInfo resultingType;
    private String invalidNotationMessage;
    private Object typeDisplayName;
    private boolean implicitConverters = true;
    private boolean allowNullInput;
    private final Collection> notationParsers = new LinkedList>();

    public static  NotationParserBuilder toType(Class resultingType) {
        return new NotationParserBuilder(Object.class, new TypeInfo(resultingType));
    }

    public static  NotationParserBuilder toType(TypeInfo resultingType) {
        return new NotationParserBuilder(Object.class, resultingType);
    }

    public static  NotationParserBuilder builder(Class notationType, Class resultingType) {
        return new NotationParserBuilder(notationType, new TypeInfo(resultingType));
    }

    private NotationParserBuilder(Class notationType, TypeInfo resultingType) {
        this.notationType = notationType;
        this.resultingType = resultingType;
    }

    /**
     * Specifies the display name for the target type, to use in error messages. By default the target type's simple name is used.
     */
    public NotationParserBuilder typeDisplayName(final String name) {
        this.typeDisplayName = name;
        return this;
    }

    /**
     * Use only those converters that are explicitly registered, and disable any implicit conversion that may normally be done.
     */
    public NotationParserBuilder noImplicitConverters() {
        implicitConverters = false;
        return this;
    }

    /**
     * Allow null as a valid input. The default is to disallow null.
     *
     * 

When this is enabled, all converters must be null safe. * * TODO - attach the null safety to each converter and infer whether null is a valid input or not. */ public NotationParserBuilder allowNullInput() { allowNullInput = true; return this; } /** * Adds a converter to use to parse notations. Converters are used in the order added. */ public NotationParserBuilder converter(NotationConverter converter) { this.notationParsers.add(converter); return this; } /** * Adds a converter that accepts only notations of the given type. */ public NotationParserBuilder fromType(Class notationType, NotationConverter converter) { this.notationParsers.add(new TypeFilteringNotationConverter(notationType, converter)); return this; } /** * Adds a converter that accepts any CharSequence notation. Can only be used the notation type is a supertype of String. */ public NotationParserBuilder fromCharSequence(NotationConverter converter) { if (!notationType.isAssignableFrom(String.class)) { throw new IllegalArgumentException(String.format("Cannot convert from String when notation is %s.", notationType.getSimpleName())); } this.notationParsers.add(new CharSequenceNotationConverter(converter)); return this; } /** * Adds a converter that accepts any CharSequence notation. Can only be used when the target type is String and the notation type is a supertype of String. */ public NotationParserBuilder fromCharSequence() { if (!resultingType.getTargetType().equals(String.class)) { throw new UnsupportedOperationException("Can only convert from CharSequence when the target type is String."); } if (!notationType.isAssignableFrom(String.class)) { throw new IllegalArgumentException(String.format("Cannot convert from String when notation is %s.", notationType.getSimpleName())); } NotationConverter notationParser = new CharSequenceNotationParser(); fromCharSequence(notationParser); return this; } public NotationParserBuilder invalidNotationMessage(String invalidNotationMessage) { this.invalidNotationMessage = invalidNotationMessage; return this; } public NotationParser> toFlatteningComposite() { return wrapInErrorHandling(new FlatteningNotationParser(create())); } public NotationParser toComposite() { return wrapInErrorHandling(create()); } private NotationParser wrapInErrorHandling(NotationParser parser) { if (typeDisplayName == null) { typeDisplayName = new LazyDisplayName(resultingType); } return new ErrorHandlingNotationParser(typeDisplayName, invalidNotationMessage, allowNullInput, parser); } private NotationParser create() { List> composites = new LinkedList>(); if (notationType.isAssignableFrom(resultingType.getTargetType()) && implicitConverters) { composites.add(new JustReturningConverter(resultingType.getTargetType())); } composites.addAll(this.notationParsers); NotationConverter notationConverter; if (composites.size() == 1) { notationConverter = composites.get(0); } else { notationConverter = new CompositeNotationConverter(composites); } return new NotationConverterToNotationParserAdapter(notationConverter); } private static class LazyDisplayName implements Describable { private final TypeInfo resultingType; private String displayName; public LazyDisplayName(TypeInfo resultingType) { this.resultingType = resultingType; } @Override public String toString() { return getDisplayName(); } @Override public String getDisplayName() { if (displayName == null) { displayName = resultingType.getTargetType().equals(String.class) ? "a String" : ("an object of type " + resultingType.getTargetType().getSimpleName()); } return displayName; } } }