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.
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.olingo.ext.proxy.commons;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.Type;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.olingo.client.api.domain.ClientEntity;
import org.apache.olingo.client.api.domain.ClientInlineEntity;
import org.apache.olingo.client.api.domain.ClientInlineEntitySet;
import org.apache.olingo.client.api.domain.ClientLink;
import org.apache.olingo.client.api.domain.ClientLinked;
import org.apache.olingo.client.api.domain.ClientProperty;
import org.apache.olingo.client.api.domain.ClientValue;
import org.apache.olingo.client.api.uri.QueryOption;
import org.apache.olingo.client.api.uri.URIBuilder;
import org.apache.olingo.client.core.uri.URIUtils;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.ext.proxy.AbstractService;
import org.apache.olingo.ext.proxy.api.AbstractEntitySet;
import org.apache.olingo.ext.proxy.api.ComplexCollection;
import org.apache.olingo.ext.proxy.api.EdmStreamValue;
import org.apache.olingo.ext.proxy.api.EntityCollection;
import org.apache.olingo.ext.proxy.api.PrimitiveCollection;
import org.apache.olingo.ext.proxy.api.annotations.ComplexType;
import org.apache.olingo.ext.proxy.api.annotations.Namespace;
import org.apache.olingo.ext.proxy.api.annotations.NavigationProperty;
import org.apache.olingo.ext.proxy.api.annotations.Property;
import org.apache.olingo.ext.proxy.context.AttachedEntityStatus;
import org.apache.olingo.ext.proxy.context.EntityContext;
import org.apache.olingo.ext.proxy.context.EntityUUID;
import org.apache.olingo.ext.proxy.utils.ClassUtils;
import org.apache.olingo.ext.proxy.utils.CoreUtils;
import org.apache.olingo.ext.proxy.utils.ProxyUtils;
public abstract class AbstractStructuredInvocationHandler extends AbstractInvocationHandler {
protected URIBuilder uri;
protected URI baseURI;
protected final Class> typeRef;
protected EntityInvocationHandler entityHandler;
protected Object internal;
private final Map propAnnotatableHandlers =
new HashMap();
private final Map navPropAnnotatableHandlers =
new HashMap();
protected final Map propertyChanges = new HashMap();
protected final Map propertyCache = new HashMap();
protected final Map linkChanges = new HashMap();
protected final Map linkCache = new HashMap();
protected final Map streamedPropertyChanges = new HashMap();
protected final Map streamedPropertyCache = new HashMap();
protected AbstractStructuredInvocationHandler(
final Class> typeRef,
final AbstractService> service) {
super(service);
this.internal = null;
this.typeRef = typeRef;
this.entityHandler = null;
}
protected AbstractStructuredInvocationHandler(
final Class> typeRef,
final Object internal,
final AbstractService> service) {
super(service);
this.internal = internal;
this.typeRef = typeRef;
this.entityHandler = null;
}
protected AbstractStructuredInvocationHandler(
final Class> typeRef,
final Object internal,
final EntityInvocationHandler entityHandler) {
super(entityHandler == null ? null : entityHandler.service);
this.internal = internal;
this.typeRef = typeRef;
// prevent memory leak
this.entityHandler = entityHandler == this ? null : entityHandler;
}
public Object getInternal() {
return internal;
}
public EntityInvocationHandler getEntityHandler() {
return entityHandler == null
? this instanceof EntityInvocationHandler
? EntityInvocationHandler.class.cast(this)
: null
: entityHandler;
}
public void setEntityHandler(final EntityInvocationHandler entityHandler) {
// prevents memory leak
this.entityHandler = entityHandler == this ? null : entityHandler;
}
public Class> getTypeRef() {
return typeRef;
}
@Override
public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
if (method.getName().startsWith("get")) {
// Here need check "get"/"set" first for better get-/set- performance because
// the below if-statements are really time-consuming, even twice slower than "get" body.
// Assumption: for each getter will always exist a setter and viceversa.
// get method annotation and check if it exists as expected
final Object res;
final Method getter = typeRef.getMethod(method.getName());
final Property property = ClassUtils.getAnnotation(Property.class, getter);
if (property == null) {
final NavigationProperty navProp = ClassUtils.getAnnotation(NavigationProperty.class, getter);
if (navProp == null) {
throw new UnsupportedOperationException("Unsupported method " + method.getName());
} else {
// if the getter refers to a navigation property ... navigate and follow link if necessary
res = getNavigationPropertyValue(navProp, getter);
}
} else {
// if the getter refers to a property .... get property from wrapped entity
res = getPropertyValue(property.name(), getter.getGenericReturnType());
}
return res;
} else if (method.getName().startsWith("set")) {
// get the corresponding getter method (see assumption above)
final String getterName = method.getName().replaceFirst("set", "get");
final Method getter = typeRef.getMethod(getterName);
final Property property = ClassUtils.getAnnotation(Property.class, getter);
if (property == null) {
final NavigationProperty navProp = ClassUtils.getAnnotation(NavigationProperty.class, getter);
if (navProp == null) {
throw new UnsupportedOperationException("Unsupported method " + method.getName());
} else {
// if the getter refers to a navigation property ...
if (ArrayUtils.isEmpty(args) || args.length != 1) {
throw new IllegalArgumentException("Invalid argument");
}
setNavigationPropertyValue(navProp, args[0]);
}
} else {
setPropertyValue(property, args[0]);
}
return ClassUtils.returnVoid();
} else if ("expand".equals(method.getName())
|| "select".equals(method.getName())
|| "refs".equals(method.getName())) {
invokeSelfMethod(method, args);
return proxy;
} else if (isSelfMethod(method)) {
return invokeSelfMethod(method, args);
} else if ("load".equals(method.getName()) && ArrayUtils.isEmpty(args)) {
load();
return proxy;
} else if ("loadAsync".equals(method.getName()) && ArrayUtils.isEmpty(args)) {
return service.getClient().getConfiguration().getExecutor().submit(new Callable