Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* 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.tooling.internal.adapter;
import com.google.common.base.Optional;
import org.gradle.api.Nullable;
import org.gradle.internal.UncheckedException;
import org.gradle.internal.reflect.DirectInstantiator;
import org.gradle.internal.time.CountdownTimer;
import org.gradle.internal.time.Timers;
import org.gradle.internal.typeconversion.EnumFromCharSequenceNotationParser;
import org.gradle.internal.typeconversion.NotationConverterToNotationParserAdapter;
import org.gradle.internal.typeconversion.NotationParser;
import org.gradle.internal.typeconversion.TypeConversionException;
import org.gradle.tooling.model.DomainObjectSet;
import org.gradle.tooling.model.internal.Exceptions;
import org.gradle.tooling.model.internal.ImmutableDomainObjectSet;
import java.io.IOException;
import java.io.Serializable;
import java.lang.ref.SoftReference;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Proxy;
import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* Adapts some source object to some target view type.
*/
public class ProtocolToModelAdapter implements ObjectGraphAdapter {
private static final ViewDecoration NO_OP_MAPPER = new NoOpDecoration();
private static final TargetTypeProvider IDENTITY_TYPE_PROVIDER = new TargetTypeProvider() {
public Class extends T> getTargetType(Class initialTargetType, Object protocolObject) {
return initialTargetType;
}
};
private static final ReflectionMethodInvoker REFLECTION_METHOD_INVOKER = new ReflectionMethodInvoker();
private static final TypeInspector TYPE_INSPECTOR = new TypeInspector();
private static final CollectionMapper COLLECTION_MAPPER = new CollectionMapper();
private static final Object[] EMPTY = new Object[0];
private static final Class[] EMPTY_CLASS_ARRAY = new Class[0];
private static final Method EQUALS_METHOD;
private static final Method HASHCODE_METHOD;
private final TargetTypeProvider targetTypeProvider;
static {
Method equalsMethod;
Method hashCodeMethod;
try {
equalsMethod = Object.class.getMethod("equals", Object.class);
hashCodeMethod = Object.class.getMethod("hashCode");
} catch (NoSuchMethodException e) {
throw UncheckedException.throwAsUncheckedException(e);
}
EQUALS_METHOD = equalsMethod;
HASHCODE_METHOD = hashCodeMethod;
}
public ProtocolToModelAdapter() {
this(IDENTITY_TYPE_PROVIDER);
}
public ProtocolToModelAdapter(TargetTypeProvider targetTypeProvider) {
this.targetTypeProvider = targetTypeProvider;
}
/**
* Creates an adapter for a single object graph. Each object adapted by the returned adapter is treated as part of the same object graph, for the purposes of caching etc.
*/
public ObjectGraphAdapter newGraph() {
final ViewGraphDetails graphDetails = new ViewGraphDetails(targetTypeProvider);
return new ObjectGraphAdapter() {
@Override
public T adapt(Class targetType, Object sourceObject) {
return createView(targetType, sourceObject, NO_OP_MAPPER, graphDetails);
}
@Override
public ViewBuilder builder(Class viewType) {
return new DefaultViewBuilder(viewType, graphDetails);
}
};
}
/**
* Adapts the source object to a view object.
*/
@Override
public T adapt(Class targetType, Object sourceObject) {
if (sourceObject == null) {
return null;
}
return createView(targetType, sourceObject, NO_OP_MAPPER, new ViewGraphDetails(targetTypeProvider));
}
/**
* Creates a builder for views of the given type.
*/
@Override
public ViewBuilder builder(final Class viewType) {
return new DefaultViewBuilder(viewType);
}
private static T createView(Class targetType, Object sourceObject, ViewDecoration decoration, ViewGraphDetails graphDetails) {
if (sourceObject == null) {
return null;
}
// Calculate the actual type
Class extends T> viewType = graphDetails.typeProvider.getTargetType(targetType, sourceObject);
if (viewType.isInstance(sourceObject)) {
return viewType.cast(sourceObject);
}
if (targetType.isEnum()) {
return adaptToEnum(targetType, sourceObject);
}
// Restrict the decorations to those required to decorate all views reachable from this type
ViewDecoration decorationsForThisType = decoration.isNoOp() ? decoration : decoration.restrictTo(TYPE_INSPECTOR.getReachableTypes(targetType));
ViewKey viewKey = new ViewKey(viewType, sourceObject, decorationsForThisType);
Object view = graphDetails.views.get(viewKey);
if (view != null) {
return targetType.cast(view);
}
// Create a proxy
InvocationHandlerImpl handler = new InvocationHandlerImpl(targetType, sourceObject, decorationsForThisType, graphDetails);
Object proxy = Proxy.newProxyInstance(viewType.getClassLoader(), new Class>[]{viewType}, handler);
handler.attachProxy(proxy);
return viewType.cast(proxy);
}
private static T adaptToEnum(Class targetType, S sourceObject) {
try {
String literal;
if (sourceObject instanceof Enum) {
literal = ((Enum>) sourceObject).name();
} else if (sourceObject instanceof String) {
literal = (String) sourceObject;
} else {
literal = sourceObject.toString();
}
NotationParser parser = new NotationConverterToNotationParserAdapter(new EnumFromCharSequenceNotationParser(targetType));
T parsedLiteral = parser.parseNotation(literal);
return targetType.cast(parsedLiteral);
} catch (TypeConversionException e) {
throw new IllegalArgumentException(String.format("Can't convert '%s' to enum type '%s'", sourceObject, targetType.getSimpleName()), e);
}
}
private static Object convert(Type targetType, Object sourceObject, ViewDecoration decoration, ViewGraphDetails graphDetails) {
if (targetType instanceof ParameterizedType) {
ParameterizedType parameterizedTargetType = (ParameterizedType) targetType;
if (parameterizedTargetType.getRawType() instanceof Class) {
Class> rawClass = (Class>) parameterizedTargetType.getRawType();
if (Iterable.class.isAssignableFrom(rawClass)) {
Type targetElementType = getElementType(parameterizedTargetType, 0);
return convertCollectionInternal(rawClass, targetElementType, (Iterable>) sourceObject, decoration, graphDetails);
}
if (Map.class.isAssignableFrom(rawClass)) {
Type targetKeyType = getElementType(parameterizedTargetType, 0);
Type targetValueType = getElementType(parameterizedTargetType, 1);
return convertMap(rawClass, targetKeyType, targetValueType, (Map, ?>) sourceObject, decoration, graphDetails);
}
}
}
if (targetType instanceof Class) {
if (((Class) targetType).isPrimitive()) {
return sourceObject;
}
return createView((Class) targetType, sourceObject, decoration, graphDetails);
}
throw new UnsupportedOperationException(String.format("Cannot convert object of %s to %s.", sourceObject.getClass(), targetType));
}
private static Map