Extract ServiceLayer.getDomainClassLoader() to ensure consistent use of ClassLoaders within the service layer. Issue 6092. Review at http://gwt-code-reviews.appspot.com/1374804 Patch by: bobv Review by: t.broyer Suggested by: t.broyer git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@9836 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/requestfactory/server/LocatorServiceLayer.java b/user/src/com/google/gwt/requestfactory/server/LocatorServiceLayer.java index 5539d29..dbf81ed 100644 --- a/user/src/com/google/gwt/requestfactory/server/LocatorServiceLayer.java +++ b/user/src/com/google/gwt/requestfactory/server/LocatorServiceLayer.java
@@ -1,12 +1,12 @@ /* * 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 @@ -113,8 +113,9 @@ } else if (ln != null && ln.locator().length() > 0) { try { @SuppressWarnings("unchecked") - Class<? extends Locator<?, ?>> found = (Class<? extends Locator<?, ?>>) Class.forName( - ln.locator(), false, domainType.getClassLoader()).asSubclass(Locator.class); + Class<? extends Locator<?, ?>> found = + (Class<? extends Locator<?, ?>>) Class.forName(ln.locator(), false, + getTop().getDomainClassLoader()).asSubclass(Locator.class); locatorType = found; } catch (ClassNotFoundException e) { return die(e, "Could not find the locator type specified in the @%s annotation %s", @@ -128,8 +129,8 @@ } @Override - public Class<? extends ServiceLocator> resolveServiceLocator( - Method contextMethod, Method domainMethod) { + public Class<? extends ServiceLocator> resolveServiceLocator(Method contextMethod, + Method domainMethod) { Class<? extends ServiceLocator> locatorType; // Look at the RequestContext @@ -141,7 +142,7 @@ } else if (ln != null && ln.locator().length() > 0) { try { locatorType = - Class.forName(ln.locator(), false, requestContextClass.getClassLoader()).asSubclass( + Class.forName(ln.locator(), false, getTop().getDomainClassLoader()).asSubclass( ServiceLocator.class); } catch (ClassNotFoundException e) { return die(e, "Could not find the locator type specified in the @%s annotation %s", @@ -211,7 +212,7 @@ } catch (IllegalAccessException e) { ex = e; } - return this.<T> die(ex, "Could not instantiate %s %s. Is it default-instantiable?", - base.getSimpleName(), clazz.getCanonicalName()); + return this.<T> die(ex, "Could not instantiate %s %s. Is it default-instantiable?", base + .getSimpleName(), clazz.getCanonicalName()); } }
diff --git a/user/src/com/google/gwt/requestfactory/server/ResolverServiceLayer.java b/user/src/com/google/gwt/requestfactory/server/ResolverServiceLayer.java index 12eb799..dc4fa06 100644 --- a/user/src/com/google/gwt/requestfactory/server/ResolverServiceLayer.java +++ b/user/src/com/google/gwt/requestfactory/server/ResolverServiceLayer.java
@@ -1,12 +1,12 @@ /* * 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 @@ -45,15 +45,20 @@ */ private static final RequestFactoryInterfaceValidator validator = new RequestFactoryInterfaceValidator(log, - new RequestFactoryInterfaceValidator.ClassLoaderLoader( - ServiceLayer.class.getClassLoader())); + new RequestFactoryInterfaceValidator.ClassLoaderLoader(ServiceLayer.class + .getClassLoader())); + + @Override + public ClassLoader getDomainClassLoader() { + return Thread.currentThread().getContextClassLoader(); + } @Override public Class<? extends BaseProxy> resolveClass(String typeToken) { Class<?> found = forName(typeToken); if (!EntityProxy.class.isAssignableFrom(found) && !ValueProxy.class.isAssignableFrom(found)) { - die(null, "The requested type %s is not assignable to %s or %s", typeToken, - EntityProxy.class.getCanonicalName(), ValueProxy.class.getCanonicalName()); + die(null, "The requested type %s is not assignable to %s or %s", typeToken, EntityProxy.class + .getCanonicalName(), ValueProxy.class.getCanonicalName()); } synchronized (validator) { validator.antidote(); @@ -66,8 +71,8 @@ } @Override - public <T> Class<? extends T> resolveClientType( - Class<?> domainClass, Class<T> clientClass, boolean required) { + public <T> Class<? extends T> resolveClientType(Class<?> domainClass, Class<T> clientClass, + boolean required) { String name; synchronized (validator) { name = validator.getEntityProxyTypeName(domainClass.getName(), clientClass.getName()); @@ -107,8 +112,7 @@ return toReturn; } } - return die( - null, "Could not resolve a domain type for client type %s", clazz.getCanonicalName()); + return die(null, "Could not resolve a domain type for client type %s", clazz.getCanonicalName()); } @Override @@ -125,8 +129,8 @@ searchIn = forName(sn.value()); } if (searchIn == null) { - die(null, "The %s type %s did not specify a service type", - RequestContext.class.getSimpleName(), enclosing.getCanonicalName()); + die(null, "The %s type %s did not specify a service type", RequestContext.class + .getSimpleName(), enclosing.getCanonicalName()); } Class<?>[] parameterTypes = requestContextMethod.getParameterTypes(); @@ -135,8 +139,9 @@ if (BaseProxy.class.isAssignableFrom(parameterTypes[i])) { domainArgs[i] = getTop().resolveDomainClass(parameterTypes[i].asSubclass(BaseProxy.class)); } else if (EntityProxyId.class.isAssignableFrom(parameterTypes[i])) { - domainArgs[i] = TypeUtils.ensureBaseType(TypeUtils.getSingleParameterization( - EntityProxyId.class, requestContextMethod.getGenericParameterTypes()[i])); + domainArgs[i] = + TypeUtils.ensureBaseType(TypeUtils.getSingleParameterization(EntityProxyId.class, + requestContextMethod.getGenericParameterTypes()[i])); } else { domainArgs[i] = parameterTypes[i]; } @@ -184,7 +189,7 @@ */ private Class<?> forName(String name) { try { - return Class.forName(name, false, Thread.currentThread().getContextClassLoader()); + return Class.forName(name, false, getTop().getDomainClassLoader()); } catch (ClassNotFoundException e) { return die(e, "Could not locate class %s", name); }
diff --git a/user/src/com/google/gwt/requestfactory/server/ServiceLayer.java b/user/src/com/google/gwt/requestfactory/server/ServiceLayer.java index d7535ca..7a58918 100644 --- a/user/src/com/google/gwt/requestfactory/server/ServiceLayer.java +++ b/user/src/com/google/gwt/requestfactory/server/ServiceLayer.java
@@ -1,12 +1,12 @@ /* * 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 @@ -46,13 +46,13 @@ /** * Provides a flag to disable the ServiceLayerCache for debugging purposes. */ - private static final boolean ENABLE_CACHE = - Boolean.valueOf(System.getProperty("gwt.rf.ServiceLayerCache", "true")); + private static final boolean ENABLE_CACHE = Boolean.valueOf(System.getProperty( + "gwt.rf.ServiceLayerCache", "true")); /** * Create a RequestFactory ServiceLayer that is optionally modified by the * given decorators. - * + * * @param decorators the decorators that will modify the behavior of the core * service layer implementation * @return a ServiceLayer instance @@ -100,7 +100,7 @@ /** * Create an instance of the requested domain type. - * + * * @param <T> the requested domain type * @param clazz the requested domain type * @return an instance of the requested domain type @@ -109,7 +109,7 @@ /** * Create an instance of the requested {@link Locator} type. - * + * * @param <T> the requested Locator type * @param clazz the requested Locator type * @return an instance of the requested Locator type @@ -119,7 +119,7 @@ /** * Create an instance of a service object that can be used as the target for * the given method invocation. - * + * * @param contextMethod a method defined in a RequestContext * @param domainMethod the method that the service object must implement * @return an instance of the requested service object @@ -127,8 +127,17 @@ public abstract Object createServiceInstance(Method contextMethod, Method domainMethod); /** + * Returns the ClassLoader that should be used when attempting to access + * domain classes or resources. + * <p> + * The default implementation returns + * {@code Thread.currentThread().getContextClassLoader()}. + */ + public abstract ClassLoader getDomainClassLoader(); + + /** * Determine the method to invoke when retrieving the given property. - * + * * @param domainType a domain entity type * @param property the name of the property to be retrieved * @return the Method that should be invoked to retrieve the property or @@ -144,7 +153,7 @@ * <p> * The values returned from this method may be passed to * {@link #loadDomainObject(Class, Object)} in the future. - * + * * @param domainObject a domain object * @return the persistent id of the domain object or {@code null} if the * object is not persistent @@ -155,7 +164,7 @@ * Returns the type of object the domain type's {@code findFoo()} or * {@link com.google.gwt.requestfactory.shared.Locator#getId(Object) * Locator.getId()} expects to receive. - * + * * @param domainType a domain entity type * @return the type of the persistent id value used to represent the domain * type @@ -164,7 +173,7 @@ /** * Retrieve the named property from the domain object. - * + * * @param domainObject the domain object being examined * @param property the property name * @return the value of the property @@ -179,11 +188,11 @@ /** * Determine the method to invoke when setting the given property. - * + * * @param domainType a domain entity type * @param property the name of the property to be set - * @return the Method that should be invoked to set the property or {@code - * null} if the method could not be located + * @return the Method that should be invoked to set the property or + * {@code null} if the method could not be located */ public abstract Method getSetter(Class<?> domainType, String property); @@ -192,7 +201,7 @@ * persisted. The value returned from this method must be a simple type (e.g. * Integer, String) or a domain type for which a mapping to an EntityProxy or * Value proxy exists. - * + * * @param domainObject a domain object * @return the version of the domain object or {@code null} if the object is * not persistent @@ -202,7 +211,7 @@ /** * Invoke a domain service method. The underlying eventually calls * {@link Method#invoke(Object, Object...)}. - * + * * @param domainMethod the method to invoke * @param args the arguments to pass to the method * @return the value returned from the method invocation @@ -212,7 +221,7 @@ /** * Returns {@code true} if the given domain object is still live (i.e. not * deleted) in the backing store. - * + * * @param domainObject a domain entity * @return {@code true} if {@code domainObject} could be retrieved at a later * point in time @@ -222,7 +231,7 @@ /** * Load an object from the backing store. This method may return {@code null} * to indicate that the requested object is no longer available. - * + * * @param <T> the type of object to load * @param clazz the type of object to load * @param domainId an id previously returned from {@link #getId(Object)} @@ -237,7 +246,7 @@ * <p> * The default implementation of this method will delegate to * {@link #loadDomainObject(Class, Object)}. - * + * * @param classes type type of each object to load * @param domainIds the ids previously returned from {@link #getId(Object)} * @return the requested objects, elements of which may be {@code null} if the @@ -249,7 +258,7 @@ * Determines if the invocation of a domain method requires a * {@link ServiceLocator} as the 0th parameter when passed into * {@link #invoke(Method, Object...)}. - * + * * @param contextMethod a method defined in a RequestContext * @param domainMethod a domain method * @return {@code true} if a ServiceLocator is required @@ -260,7 +269,7 @@ * Given a type token previously returned from * {@link #resolveTypeToken(Class)}, return the Class literal associated with * the token. - * + * * @param typeToken a string token * @return the type represented by the token */ @@ -270,7 +279,7 @@ * Determine the type used by the client code to represent a given domain * type. If multiple proxy types have been mapped to the same domain type, the * {@code clientType} parameter is used to ensure assignability. - * + * * @param domainClass the server-side type to be transported to the client * @param clientType the type to which the returned type must be assignable * @param required if {@code true} and no mapping is available, throw an @@ -279,13 +288,13 @@ * @return a class that represents {@code domainClass} on the client which is * assignable to {@code clientType} */ - public abstract <T> Class<? extends T> resolveClientType( - Class<?> domainClass, Class<T> clientType, boolean required); + public abstract <T> Class<? extends T> resolveClientType(Class<?> domainClass, + Class<T> clientType, boolean required); /** * Determine the domain (server-side) type that the given client type is * mapped to. - * + * * @param clientType a client-side type * @return the domain type that {@code clientType} represents */ @@ -295,7 +304,7 @@ * Return the domain service method associated with a RequestContext method * declaration. The {@code requestContextMethod} will have been previously * resolved by {@link #resolveRequestContextMethod(String, String)}. - * + * * @param requestContextMethod a RequestContext method declaration. * @return the domain service method that should be invoked */ @@ -304,7 +313,7 @@ /** * Return the type of {@link Locator} that should be used to access the given * domain type. - * + * * @param domainType a domain (server-side) type * @return the type of Locator to use, or {@code null} if the type conforms to * the RequestFactory entity protocol @@ -313,7 +322,7 @@ /** * Find a RequestContext method declaration by name. - * + * * @param requestContextClass the fully-qualified binary name of the * RequestContext * @param methodName the name of the service method declared within the @@ -328,17 +337,17 @@ * {@link ServiceLocator} that should be used when invoking the domain method. * This method will only be called if {@link #requiresServiceLocator(Method)} * returned {@code true} for the associated domain method. - * + * * @param contextMethod a RequestContext method declaration * @param domainMethod the domain method that will be invoked * @return the type of ServiceLocator to use */ - public abstract Class<? extends ServiceLocator> resolveServiceLocator( - Method contextMethod, Method domainMethod); + public abstract Class<? extends ServiceLocator> resolveServiceLocator(Method contextMethod, + Method domainMethod); /** * Return a string used to represent the given type in the wire protocol. - * + * * @param proxyType a client-side EntityProxy or ValueProxy type * @return the type token used to represent the proxy type */ @@ -346,19 +355,19 @@ /** * Sets a property on a domain object. - * + * * @param domainObject the domain object to operate on * @param property the name of the property to set * @param expectedType the type of the property * @param value the new value */ - public abstract void setProperty( - Object domainObject, String property, Class<?> expectedType, Object value); + public abstract void setProperty(Object domainObject, String property, Class<?> expectedType, + Object value); /** * Invoke a JSR 303 validator on the given domain object. If no validator is * available, this method is a no-op. - * + * * @param <T> the type of data being validated * @param domainObject the domain objcet to validate * @return the violations associated with the domain object
diff --git a/user/src/com/google/gwt/requestfactory/server/ServiceLayerCache.java b/user/src/com/google/gwt/requestfactory/server/ServiceLayerCache.java index 80102cc..201fc62 100644 --- a/user/src/com/google/gwt/requestfactory/server/ServiceLayerCache.java +++ b/user/src/com/google/gwt/requestfactory/server/ServiceLayerCache.java
@@ -44,6 +44,7 @@ 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; @@ -60,34 +61,29 @@ static { createLocator = getMethod("createLocator", Class.class); - createServiceInstance = getMethod("createServiceInstance", Method.class, - Method.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); + requiresServiceLocator = getMethod("requiresServiceLocator", Method.class, Method.class); resolveClass = getMethod("resolveClass", String.class); - resolveClientType = getMethod("resolveClientType", Class.class, - Class.class, boolean.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); + resolveRequestContextMethod = + getMethod("resolveRequestContextMethod", String.class, String.class); + resolveServiceLocator = getMethod("resolveServiceLocator", Method.class, Method.class); resolveTypeToken = getMethod("resolveTypeToken", Class.class); } private static Map<Method, Map<Object, Object>> getCache() { - Map<Method, Map<Object, Object>> toReturn = methodCache == null ? null - : methodCache.get(); + Map<Method, Map<Object, Object>> toReturn = methodCache == null ? null : methodCache.get(); if (toReturn == null) { toReturn = new ConcurrentHashMap<Method, Map<Object, Object>>(); - methodCache = new SoftReference<Map<Method, Map<Object, Object>>>( - toReturn); + methodCache = new SoftReference<Map<Method, Map<Object, Object>>>(toReturn); } return toReturn; } @@ -96,11 +92,9 @@ try { return ServiceLayer.class.getMethod(name, argTypes); } catch (SecurityException e) { - throw new RuntimeException("Could not set up ServiceLayerCache Methods", - e); + throw new RuntimeException("Could not set up ServiceLayerCache Methods", e); } catch (NoSuchMethodException e) { - throw new RuntimeException("Could not set up ServiceLayerCache Methods", - e); + throw new RuntimeException("Could not set up ServiceLayerCache Methods", e); } } @@ -113,14 +107,19 @@ @Override public Object createServiceInstance(Method contextMethod, Method domainMethod) { - return getOrCache(createServiceInstance, new Pair<Method, Method>( - contextMethod, domainMethod), Object.class, contextMethod, domainMethod); + return getOrCache(createServiceInstance, new Pair<Method, Method>(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<Class<?>, String>(domainType, - property), Method.class, domainType, property); + return getOrCache(getGetter, new Pair<Class<?>, String>(domainType, property), Method.class, + domainType, property); } @Override @@ -130,21 +129,19 @@ @Override public Type getRequestReturnType(Method contextMethod) { - return getOrCache(getRequestReturnType, contextMethod, Type.class, - contextMethod); + return getOrCache(getRequestReturnType, contextMethod, Type.class, contextMethod); } @Override public Method getSetter(Class<?> domainType, String property) { - return getOrCache(getSetter, new Pair<Class<?>, String>(domainType, - property), Method.class, domainType, property); + return getOrCache(getSetter, new Pair<Class<?>, String>(domainType, property), Method.class, + domainType, property); } @Override - public boolean requiresServiceLocator(Method contextMethod, - Method domainMethod) { - return getOrCache(requiresServiceLocator, new Pair<Method, Method>( - contextMethod, domainMethod), Boolean.class, contextMethod, + public boolean requiresServiceLocator(Method contextMethod, Method domainMethod) { + return getOrCache(requiresServiceLocator, + new Pair<Method, Method>(contextMethod, domainMethod), Boolean.class, contextMethod, domainMethod); } @@ -155,11 +152,11 @@ } @Override - public <T> Class<? extends T> resolveClientType(Class<?> domainClass, - Class<T> clientType, boolean required) { - Class<?> clazz = getOrCache(resolveClientType, - new Pair<Class<?>, Class<?>>(domainClass, clientType), Class.class, - domainClass, clientType, required); + public <T> Class<? extends T> resolveClientType(Class<?> domainClass, Class<T> clientType, + boolean required) { + Class<?> clazz = + getOrCache(resolveClientType, new Pair<Class<?>, Class<?>>(domainClass, clientType), + Class.class, domainClass, clientType, required); return clazz == null ? null : clazz.asSubclass(clientType); } @@ -170,8 +167,7 @@ @Override public Method resolveDomainMethod(Method requestContextMethod) { - return getOrCache(resolveDomainMethod, requestContextMethod, Method.class, - requestContextMethod); + return getOrCache(resolveDomainMethod, requestContextMethod, Method.class, requestContextMethod); } @Override @@ -181,19 +177,17 @@ } @Override - public Method resolveRequestContextMethod(String requestContextClass, - String methodName) { - return getOrCache(resolveRequestContextMethod, new Pair<String, String>( - requestContextClass, methodName), Method.class, requestContextClass, - methodName); + public Method resolveRequestContextMethod(String requestContextClass, String methodName) { + return getOrCache(resolveRequestContextMethod, new Pair<String, String>(requestContextClass, + methodName), Method.class, requestContextClass, methodName); } @Override - public Class<? extends ServiceLocator> resolveServiceLocator( - Method contextMethod, Method domainMethod) { - Class<?> clazz = getOrCache(resolveServiceLocator, - new Pair<Method, Method>(contextMethod, domainMethod), Class.class, - contextMethod, domainMethod); + public Class<? extends ServiceLocator> resolveServiceLocator(Method contextMethod, + Method domainMethod) { + Class<?> clazz = + getOrCache(resolveServiceLocator, new Pair<Method, Method>(contextMethod, domainMethod), + Class.class, contextMethod, domainMethod); return clazz == null ? null : clazz.asSubclass(ServiceLocator.class); } @@ -202,8 +196,7 @@ return getOrCache(resolveTypeToken, domainClass, String.class, domainClass); } - private <K, T> T getOrCache(Method method, K key, Class<T> valueType, - Object... args) { + private <K, T> T getOrCache(Method method, K key, Class<T> valueType, Object... args) { Map<Object, Object> map = methodMap.get(method); if (map == null) { map = new ConcurrentHashMap<Object, Object>();
diff --git a/user/src/com/google/gwt/requestfactory/server/ServiceLayerDecorator.java b/user/src/com/google/gwt/requestfactory/server/ServiceLayerDecorator.java index 568303e..27bcbf4 100644 --- a/user/src/com/google/gwt/requestfactory/server/ServiceLayerDecorator.java +++ b/user/src/com/google/gwt/requestfactory/server/ServiceLayerDecorator.java
@@ -1,12 +1,12 @@ /* * 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 @@ -60,6 +60,11 @@ } @Override + public ClassLoader getDomainClassLoader() { + return getNext().getDomainClassLoader(); + } + + @Override public Method getGetter(Class<?> domainType, String property) { return getNext().getGetter(domainType, property); } @@ -125,8 +130,8 @@ } @Override - public <T> Class<? extends T> resolveClientType( - Class<?> domainClass, Class<T> clientType, boolean required) { + public <T> Class<? extends T> resolveClientType(Class<?> domainClass, Class<T> clientType, + boolean required) { return getNext().resolveClientType(domainClass, clientType, required); } @@ -151,8 +156,8 @@ } @Override - public Class<? extends ServiceLocator> resolveServiceLocator( - Method contextMethod, Method domainMethod) { + public Class<? extends ServiceLocator> resolveServiceLocator(Method contextMethod, + Method domainMethod) { return getNext().resolveServiceLocator(contextMethod, domainMethod); } @@ -162,8 +167,7 @@ } @Override - public void setProperty( - Object domainObject, String property, Class<?> expectedType, Object value) { + public void setProperty(Object domainObject, String property, Class<?> expectedType, Object value) { getNext().setProperty(domainObject, property, expectedType, value); } @@ -177,15 +181,14 @@ * should be used to provide diagnostic information that will help the * end-developer track down problems when that data would expose * implementation details of the server to the client. - * + * * @param e a throwable with more data, may be {@code null} * @param message a printf-style format string * @param args arguments for the message * @throws UnexpectedException this method never returns normally * @see #report(String, Object...) */ - protected final <T> T die(Throwable e, String message, Object... args) - throws UnexpectedException { + protected final <T> T die(Throwable e, String message, Object... args) throws UnexpectedException { String msg = String.format(message, args); log.log(Level.SEVERE, msg, e); throw new UnexpectedException(msg, e); @@ -196,18 +199,18 @@ * should use the instance provided by {@code getTop()} when calling public * methods on the ServiceLayer API to allow higher-level decorators to * override behaviors built into lower-level decorators. - * + * * @return the ServiceLayer returned by * {@link #create(ServiceLayerDecorator...)} */ - protected ServiceLayer getTop() { + protected final ServiceLayer getTop() { return top; } /** * Report an exception thrown by code that is under the control of the * end-developer. - * + * * @param an {@link InvocationTargetException} thrown by an invocation of * user-provided code * @throws ReportableException this method never returns normally @@ -220,7 +223,7 @@ /** * Return a message to the client. This method should not include any data * that was not sent to the server by the client to avoid leaking data. - * + * * @param msg a printf-style format string * @param args arguments for the message * @throws ReportableException this method never returns normally