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

com.google.gwt.requestfactory.server.ServiceLayerCache Maven / Gradle / Ivy

There is a newer version: 2.10.0
Show newest version
/*
 * Copyright 2010 Google Inc.
 *
 * 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 com.google.gwt.requestfactory.server;

import com.google.gwt.requestfactory.shared.BaseProxy;
import com.google.gwt.requestfactory.shared.Locator;
import com.google.gwt.requestfactory.shared.ServiceLocator;
import com.google.gwt.rpc.server.Pair;

import java.lang.ref.SoftReference;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * A cache for idempotent methods in {@link ServiceLayer}. The caching is
 * separate from {@link ReflectiveServiceLayer} so that the cache can be applied
 * to any decorators injected by the user.
 *
 * 

RequestFactory has moved to * com.google.web.bindery.requestfactory. This package will be * removed in a future version of GWT.

*/ @Deprecated class ServiceLayerCache extends ServiceLayerDecorator { /** * ConcurrentHashMaps don't allow null keys or values, but sometimes we want * to cache a null value. */ private static final Object NULL_MARKER = new Object(); private static SoftReference>> methodCache; private static final Method createLocator; private static final Method createServiceInstance; private static final Method getDomainClassLoader; private static final Method getGetter; private static final Method getIdType; private static final Method getRequestReturnType; private static final Method getSetter; private static final Method requiresServiceLocator; private static final Method resolveClass; private static final Method resolveClientType; private static final Method resolveDomainClass; private static final Method resolveDomainMethod; private static final Method resolveLocator; private static final Method resolveRequestContextMethod; private static final Method resolveServiceLocator; private static final Method resolveTypeToken; static { createLocator = getMethod("createLocator", Class.class); createServiceInstance = getMethod("createServiceInstance", Method.class, Method.class); getDomainClassLoader = getMethod("getDomainClassLoader"); getGetter = getMethod("getGetter", Class.class, String.class); getIdType = getMethod("getIdType", Class.class); getRequestReturnType = getMethod("getRequestReturnType", Method.class); getSetter = getMethod("getSetter", Class.class, String.class); requiresServiceLocator = getMethod("requiresServiceLocator", Method.class, Method.class); resolveClass = getMethod("resolveClass", String.class); resolveClientType = getMethod("resolveClientType", Class.class, Class.class, boolean.class); resolveDomainClass = getMethod("resolveDomainClass", Class.class); resolveDomainMethod = getMethod("resolveDomainMethod", Method.class); resolveLocator = getMethod("resolveLocator", Class.class); resolveRequestContextMethod = getMethod("resolveRequestContextMethod", String.class, String.class); resolveServiceLocator = getMethod("resolveServiceLocator", Method.class, Method.class); resolveTypeToken = getMethod("resolveTypeToken", Class.class); } private static Map> getCache() { Map> toReturn = methodCache == null ? null : methodCache.get(); if (toReturn == null) { toReturn = new ConcurrentHashMap>(); methodCache = new SoftReference>>(toReturn); } return toReturn; } private static Method getMethod(String name, Class... argTypes) { try { return ServiceLayer.class.getMethod(name, argTypes); } catch (SecurityException e) { throw new RuntimeException("Could not set up ServiceLayerCache Methods", e); } catch (NoSuchMethodException e) { throw new RuntimeException("Could not set up ServiceLayerCache Methods", e); } } private final Map> methodMap = getCache(); @Override public > T createLocator(Class clazz) { return getOrCache(createLocator, clazz, clazz, clazz); } @Override public Object createServiceInstance(Method contextMethod, Method domainMethod) { return getOrCache(createServiceInstance, new Pair(contextMethod, domainMethod), Object.class, contextMethod, domainMethod); } @Override public ClassLoader getDomainClassLoader() { return getOrCache(getDomainClassLoader, NULL_MARKER, ClassLoader.class); } @Override public Method getGetter(Class domainType, String property) { return getOrCache(getGetter, new Pair, String>(domainType, property), Method.class, domainType, property); } @Override public Class getIdType(Class domainType) { return getOrCache(getIdType, domainType, Class.class, domainType); } @Override public Type getRequestReturnType(Method contextMethod) { return getOrCache(getRequestReturnType, contextMethod, Type.class, contextMethod); } @Override public Method getSetter(Class domainType, String property) { return getOrCache(getSetter, new Pair, String>(domainType, property), Method.class, domainType, property); } @Override public boolean requiresServiceLocator(Method contextMethod, Method domainMethod) { return getOrCache(requiresServiceLocator, new Pair(contextMethod, domainMethod), Boolean.class, contextMethod, domainMethod); } @Override public Class resolveClass(String typeToken) { Class found = getOrCache(resolveClass, typeToken, Class.class, typeToken); return found.asSubclass(BaseProxy.class); } @Override public Class resolveClientType(Class domainClass, Class clientType, boolean required) { Class clazz = getOrCache(resolveClientType, new Pair, Class>(domainClass, clientType), Class.class, domainClass, clientType, required); return clazz == null ? null : clazz.asSubclass(clientType); } @Override public Class resolveDomainClass(Class clazz) { return getOrCache(resolveDomainClass, clazz, Class.class, clazz); } @Override public Method resolveDomainMethod(Method requestContextMethod) { return getOrCache(resolveDomainMethod, requestContextMethod, Method.class, requestContextMethod); } @Override @SuppressWarnings("unchecked") public Class> resolveLocator(Class domainType) { return getOrCache(resolveLocator, domainType, Class.class, domainType); } @Override public Method resolveRequestContextMethod(String requestContextClass, String methodName) { return getOrCache(resolveRequestContextMethod, new Pair(requestContextClass, methodName), Method.class, requestContextClass, methodName); } @Override public Class resolveServiceLocator(Method contextMethod, Method domainMethod) { Class clazz = getOrCache(resolveServiceLocator, new Pair(contextMethod, domainMethod), Class.class, contextMethod, domainMethod); return clazz == null ? null : clazz.asSubclass(ServiceLocator.class); } @Override public String resolveTypeToken(Class domainClass) { return getOrCache(resolveTypeToken, domainClass, String.class, domainClass); } private T getOrCache(Method method, K key, Class valueType, Object... args) { Map map = methodMap.get(method); if (map == null) { map = new ConcurrentHashMap(); methodMap.put(method, map); } Object raw = map.get(key); if (raw == NULL_MARKER) { return null; } T toReturn = valueType.cast(raw); if (toReturn == null) { Throwable ex = null; try { toReturn = valueType.cast(method.invoke(getNext(), args)); map.put(key, toReturn == null ? NULL_MARKER : toReturn); } catch (InvocationTargetException e) { // The next layer threw an exception Throwable cause = e.getCause(); if (cause instanceof RuntimeException) { // Re-throw RuntimeExceptions, which likely originate from die() throw ((RuntimeException) cause); } die(cause, "Unexpected checked exception"); } catch (IllegalArgumentException e) { ex = e; } catch (IllegalAccessException e) { ex = e; } if (ex != null) { die(ex, "Bad method invocation"); } } return toReturn; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy