org.gradle.model.internal.manage.schema.extract.ScalarCollectionNodeInitializerExtractionStrategy 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 2015 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.model.internal.manage.schema.extract;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import org.gradle.internal.Cast;
import org.gradle.model.internal.core.ModelPath;
import org.gradle.model.internal.core.ModelViewState;
import org.gradle.model.internal.core.MutableModelNode;
import org.gradle.model.internal.core.NodeInitializer;
import org.gradle.model.internal.core.NodeInitializerContext;
import org.gradle.model.internal.core.TypeCompatibilityModelProjectionSupport;
import org.gradle.model.internal.core.rule.describe.ModelRuleDescriptor;
import org.gradle.model.internal.inspect.ModelElementProjection;
import org.gradle.model.internal.inspect.ProjectionOnlyNodeInitializer;
import org.gradle.model.internal.manage.schema.CollectionSchema;
import org.gradle.model.internal.manage.schema.ScalarValueSchema;
import org.gradle.model.internal.type.ModelType;
import org.gradle.model.internal.type.ModelTypes;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Set;
public class ScalarCollectionNodeInitializerExtractionStrategy extends CollectionNodeInitializerExtractionSupport {
public final static List> TYPES = ImmutableList.>of(
ModelType.of(List.class),
ModelType.of(Set.class)
);
@Override
protected NodeInitializer extractNodeInitializer(CollectionSchema schema, NodeInitializerContext context) {
ModelType type = schema.getType();
Class super T> rawClass = type.getRawClass();
ModelType super T> rawCollectionType = ModelType.of(rawClass);
if (TYPES.contains(rawCollectionType) && (schema.getElementTypeSchema() instanceof ScalarValueSchema)) {
Optional propertyContext = context.getPropertyContextOptional();
boolean writable = !propertyContext.isPresent() || propertyContext.get().isWritable();
if (schema.getType().getRawClass() == List.class) {
return new ProjectionOnlyNodeInitializer(
ScalarCollectionModelProjection.forList(schema.getElementType(), !writable),
new ModelElementProjection(schema.getType())
);
} else {
return new ProjectionOnlyNodeInitializer(
ScalarCollectionModelProjection.forSet(schema.getElementType(), !writable),
new ModelElementProjection(schema.getType())
);
}
}
return null;
}
@Override
public Iterable> supportedTypes() {
return ImmutableList.copyOf(TYPES);
}
private abstract static class ScalarCollectionModelProjection> extends TypeCompatibilityModelProjectionSupport {
public ScalarCollectionModelProjection(ModelType type) {
super(type);
}
@Override
public Optional getValueDescription(MutableModelNode modelNodeInternal) {
Collection> values = modelNodeInternal.asImmutable(getType(), null).getInstance();
if (values == null) {
return Optional.of("null");
}
return Optional.of(values.toString());
}
@Override
protected abstract ScalarCollectionModelView toView(MutableModelNode modelNode, ModelRuleDescriptor ruleDescriptor, boolean readOnly);
public static ScalarCollectionModelProjection> forList(final ModelType elementType, final boolean readOnly) {
return new ScalarCollectionModelProjection>(ModelTypes.list(elementType)) {
@Override
protected ScalarCollectionModelView> toView(MutableModelNode modelNode, ModelRuleDescriptor ruleDescriptor, boolean mutable) {
return new ListModelView(modelNode.getPath(), elementType, modelNode, ruleDescriptor, readOnly, mutable);
}
};
}
public static ScalarCollectionModelProjection> forSet(final ModelType elementType, final boolean readOnly) {
return new ScalarCollectionModelProjection>(ModelTypes.set(elementType)) {
@Override
protected ScalarCollectionModelView> toView(MutableModelNode modelNode, ModelRuleDescriptor ruleDescriptor, boolean mutable) {
return new SetModelView(modelNode.getPath(), elementType, modelNode, ruleDescriptor, readOnly, mutable);
}
};
}
}
private static class ListModelView extends ScalarCollectionModelView> {
public ListModelView(ModelPath path, ModelType elementType, MutableModelNode modelNode, ModelRuleDescriptor descriptor, boolean overwritable, boolean mutable) {
super(path, ModelTypes.list(elementType), elementType, modelNode, descriptor, overwritable, mutable);
}
@Override
protected List initialValue() {
return new LinkedList();
}
@Override
protected List toMutationSafe(Collection> backingCollection) {
return new ListBackedCollection(Cast.>uncheckedCast(backingCollection), state, elementType);
}
}
private static class SetModelView extends ScalarCollectionModelView> {
public SetModelView(ModelPath path, ModelType elementType, MutableModelNode modelNode, ModelRuleDescriptor descriptor, boolean overwritable, boolean mutable) {
super(path, ModelTypes.set(elementType), elementType, modelNode, descriptor, overwritable, mutable);
}
@Override
protected Set initialValue() {
return new LinkedHashSet();
}
@Override
protected Set toMutationSafe(Collection> backingCollection) {
return new SetBackedCollection(Cast.>uncheckedCast(backingCollection), state, elementType);
}
}
private abstract static class MutationSafeCollection implements Collection {
private final Collection delegate;
private final ModelViewState state;
private final ModelType elementType;
public MutationSafeCollection(Collection delegate, ModelViewState state, ModelType elementType) {
this.delegate = delegate;
this.state = state;
this.elementType = elementType;
}
public Collection getDelegate(boolean forMutation) {
if (forMutation) {
state.assertCanMutate();
}
return delegate;
}
protected void validateElementType(Object o) {
if (o != null) {
ModelType> obType = ModelType.of(o.getClass());
if (!obType.equals(elementType)) {
throw new IllegalArgumentException(String.format("Cannot add an element of type %s to a collection of %s", obType, elementType));
}
}
}
protected void validateCollection(Collection extends T> c) {
for (T element : c) {
validateElementType(element);
}
}
@Override
public boolean add(T t) {
validateElementType(t);
return getDelegate(true).add(t);
}
@Override
public boolean addAll(Collection extends T> c) {
validateCollection(c);
return getDelegate(true).addAll(c);
}
@Override
public void clear() {
getDelegate(true).clear();
}
@Override
public boolean contains(Object o) {
return getDelegate(false).contains(o);
}
@Override
public boolean containsAll(Collection> c) {
return getDelegate(false).containsAll(c);
}
@Override
public boolean equals(Object o) {
return getDelegate(false).equals(o);
}
@Override
public int hashCode() {
return getDelegate(false).hashCode();
}
@Override
public boolean isEmpty() {
return getDelegate(false).isEmpty();
}
@Override
public Iterator iterator() {
return new MutationSafeIterator(getDelegate(false).iterator());
}
@Override
public boolean remove(Object o) {
return getDelegate(true).remove(o);
}
@Override
public boolean removeAll(Collection> c) {
return getDelegate(true).removeAll(c);
}
@Override
public boolean retainAll(Collection> c) {
return getDelegate(true).retainAll(c);
}
@Override
public int size() {
return getDelegate(false).size();
}
@Override
public Object[] toArray() {
return getDelegate(false).toArray();
}
@Override
public T[] toArray(T[] a) {
return getDelegate(false).toArray(a);
}
private final class MutationSafeIterator implements Iterator {
private final Iterator delegate;
private MutationSafeIterator(Iterator delegate) {
this.delegate = delegate;
}
@Override
public boolean hasNext() {
return delegate.hasNext();
}
@Override
public T next() {
return delegate.next();
}
@Override
public void remove() {
state.assertCanMutate();
delegate.remove();
}
}
@Override
public String toString() {
return delegate.toString();
}
}
private static class ListBackedCollection extends MutationSafeCollection implements List {
public ListBackedCollection(List delegate, ModelViewState state, ModelType elementType) {
super(delegate, state, elementType);
}
@Override
public void add(int index, T element) {
validateElementType(element);
((List)getDelegate(true)).add(index, element);
}
@Override
public boolean addAll(int index, Collection extends T> c) {
validateCollection(c);
return ((List)getDelegate(true)).addAll(index, c);
}
@Override
public T get(int index) {
return ((List)getDelegate(false)).get(index);
}
@Override
public int indexOf(Object o) {
return ((List)getDelegate(false)).indexOf(o);
}
@Override
public int lastIndexOf(Object o) {
return ((List)getDelegate(false)).lastIndexOf(o);
}
@Override
public ListIterator listIterator() {
return ((List)getDelegate(false)).listIterator();
}
@Override
public ListIterator listIterator(int index) {
return ((List)getDelegate(false)).listIterator(index);
}
@Override
public T remove(int index) {
return ((List)getDelegate(true)).remove(index);
}
@Override
public List subList(int fromIndex, int toIndex) {
throw new UnsupportedOperationException();
}
@Override
public T set(int index, T element) {
validateElementType(element);
return ((List)getDelegate(true)).set(index, element);
}
}
private static class SetBackedCollection extends MutationSafeCollection implements Set {
public SetBackedCollection(Set delegate, ModelViewState state, ModelType elementType) {
super(delegate, state, elementType);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy