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

com.google.web.bindery.requestfactory.server.ServiceLayerDecorator 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.web.bindery.requestfactory.server;

import com.google.web.bindery.requestfactory.shared.BaseProxy;
import com.google.web.bindery.requestfactory.shared.Locator;
import com.google.web.bindery.requestfactory.shared.RequestContext;
import com.google.web.bindery.requestfactory.shared.RequestFactory;
import com.google.web.bindery.requestfactory.shared.ServiceLocator;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.validation.ConstraintViolation;

/**
 * Users that intend to alter how RequestFactory interacts with the domain
 * environment can extend this type and provide it to
 * {@link ServiceLayer#create(ServiceLayerDecorator...)}. The methods defined in
 * this type will automatically delegate to the next decorator or the root
 * service object after being processed by{@code create()}.
 */
public class ServiceLayerDecorator extends ServiceLayer {
  private static final Logger log = Logger.getLogger(ServiceLayer.class.getName());

  /**
   * A pointer to the next deepest layer.
   */
  ServiceLayer next;

  @Override
  public  T createDomainObject(Class clazz) {
    return getNext().createDomainObject(clazz);
  }

  @Override
  public > T createLocator(Class clazz) {
    return getNext().createLocator(clazz);
  }

  @Override
  public Object createServiceInstance(Class requestContext) {
    return getNext().createServiceInstance(requestContext);
  }

  @Override
  public  T createServiceLocator(Class clazz) {
    return getNext().createServiceLocator(clazz);
  }

  @Override
  public ClassLoader getDomainClassLoader() {
    return getNext().getDomainClassLoader();
  }

  @Override
  public Method getGetter(Class domainType, String property) {
    return getNext().getGetter(domainType, property);
  }

  @Override
  public Object getId(Object domainObject) {
    return getNext().getId(domainObject);
  }

  @Override
  public Class getIdType(Class domainType) {
    return getNext().getIdType(domainType);
  }

  @Override
  public Object getProperty(Object domainObject, String property) {
    return getNext().getProperty(domainObject, property);
  }

  @Override
  public Type getRequestReturnType(Method contextMethod) {
    return getNext().getRequestReturnType(contextMethod);
  }

  @Override
  public Method getSetter(Class domainType, String property) {
    return getNext().getSetter(domainType, property);
  }

  @Override
  public Object getVersion(Object domainObject) {
    return getNext().getVersion(domainObject);
  }

  @Override
  public Object invoke(Method domainMethod, Object... args) {
    return getNext().invoke(domainMethod, args);
  }

  @Override
  public boolean isLive(Object domainObject) {
    return getNext().isLive(domainObject);
  }

  @Override
  public  T loadDomainObject(Class clazz, Object domainId) {
    return getNext().loadDomainObject(clazz, domainId);
  }

  @Override
  public List loadDomainObjects(List> classes, List domainIds) {
    return getNext().loadDomainObjects(classes, domainIds);
  }

  @Override
  public boolean requiresServiceLocator(Method contextMethod, Method domainMethod) {
    return getNext().requiresServiceLocator(contextMethod, domainMethod);
  }

  @Override
  public Class resolveClass(String typeToken) {
    return getNext().resolveClass(typeToken);
  }

  @Override
  public  Class resolveClientType(Class domainClass, Class clientType,
      boolean required) {
    return getNext().resolveClientType(domainClass, clientType, required);
  }

  @Override
  public Class resolveDomainClass(Class clazz) {
    return getNext().resolveDomainClass(clazz);
  }

  @Override
  public Method resolveDomainMethod(String operation) {
    return getNext().resolveDomainMethod(operation);
  }

  @Override
  public Class> resolveLocator(Class domainType) {
    return getNext().resolveLocator(domainType);
  }

  @Override
  public Class resolveRequestContext(String operation) {
    return getNext().resolveRequestContext(operation);
  }

  @Override
  public Method resolveRequestContextMethod(String operation) {
    return getNext().resolveRequestContextMethod(operation);
  }

  @Override
  public Class resolveRequestFactory(String binaryName) {
    return getNext().resolveRequestFactory(binaryName);
  }

  @Override
  public Class resolveServiceClass(Class requestContextClass) {
    return getNext().resolveServiceClass(requestContextClass);
  }

  @Override
  public Class resolveServiceLocator(
      Class requestContext) {
    return getNext().resolveServiceLocator(requestContext);
  }

  @Override
  public String resolveTypeToken(Class proxyType) {
    return getNext().resolveTypeToken(proxyType);
  }

  @Override
  public void setProperty(Object domainObject, String property, Class expectedType, Object value) {
    getNext().setProperty(domainObject, property, expectedType, value);
  }

  @Override
  public  Set> validate(T domainObject) {
    return getNext().validate(domainObject);
  }

  /**
   * Throw a fatal error up into the top-level processing code. This method
   * 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 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);
  }

  /**
   * Returns the top-most service layer. General-purpose ServiceLayer decorators
   * 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 final ServiceLayer getTop() {
    return top;
  }

  /**
   * Report an exception thrown by code that is under the control of the
   * end-developer.
   * 
   * @param userGeneratedException an {@link InvocationTargetException} thrown
   *          by an invocation of user-provided code
   * @throws ReportableException this method never returns normally
   */
  protected final  T report(InvocationTargetException userGeneratedException)
      throws ReportableException {
    throw new ReportableException(userGeneratedException.getCause());
  }

  /**
   * 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
   * @see #die(Throwable, String, Object...)
   */
  protected final  T report(String msg, Object... args) throws ReportableException {
    throw new ReportableException(String.format(msg, args));
  }

  /**
   * Retrieves the next service layer. Used only by the server-package code and
   * accessed by used code via {@code super.doSomething()}.
   */
  final ServiceLayer getNext() {
    if (next == null) {
      // Unexpected, all methods should be implemented by some layer
      throw new UnsupportedOperationException();
    }
    return next;
  }
}