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

com.google.web.bindery.requestfactory.server.LocatorServiceLayer 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.ProxyFor;
import com.google.web.bindery.requestfactory.shared.ProxyForName;
import com.google.web.bindery.requestfactory.shared.Request;
import com.google.web.bindery.requestfactory.shared.RequestContext;
import com.google.web.bindery.requestfactory.shared.Service;
import com.google.web.bindery.requestfactory.shared.ServiceLocator;
import com.google.web.bindery.requestfactory.shared.ServiceName;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
 * Adds support to the ServiceLayer chain for using {@link Locator} and
 * {@link ServiceLocator} helper objects.
 */
final class LocatorServiceLayer extends ServiceLayerDecorator {

  @Override
  public  T createDomainObject(Class clazz) {
    Locator l = getLocator(clazz);
    if (l == null) {
      return super.createDomainObject(clazz);
    }
    return l.create(clazz);
  }

  @Override
  public > T createLocator(Class clazz) {
    return newInstance(clazz, Locator.class);
  }

  @Override
  public Object createServiceInstance(Method contextMethod, Method domainMethod) {
    Class locatorType = getTop().resolveServiceLocator(
        contextMethod, domainMethod);
    ServiceLocator locator = getTop().createServiceLocator(locatorType);
    // Enclosing class may be a parent class, so invoke on service class
    Class declaringClass = contextMethod.getDeclaringClass();
    Class serviceClass = getTop().resolveServiceClass(
        declaringClass.asSubclass(RequestContext.class));
    return locator.getInstance(serviceClass);
  }

  @Override
  public  T createServiceLocator(
      Class serviceLocatorType) {
    return newInstance(serviceLocatorType, ServiceLocator.class);
  }

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

  @Override
  public Class getIdType(Class domainType) {
    Locator l = getLocator(domainType);
    if (l == null) {
      return super.getIdType(domainType);
    }
    return l.getIdType();
  }

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

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

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

  /**
   * Returns true if the context method returns a {@link Request} and the domain
   * method is non-static.
   */
  @Override
  public boolean requiresServiceLocator(Method contextMethod,
      Method domainMethod) {
    return Request.class.isAssignableFrom(contextMethod.getReturnType())
        && !Modifier.isStatic(domainMethod.getModifiers());
  }

  @Override
  public Class> resolveLocator(Class domainType) {
    // Find the matching BaseProxy
    Class proxyType = getTop().resolveClientType(domainType,
        BaseProxy.class, false);
    if (proxyType == null) {
      return null;
    }

    // Check it for annotations
    Class> locatorType;
    ProxyFor l = proxyType.getAnnotation(ProxyFor.class);
    ProxyForName ln = proxyType.getAnnotation(ProxyForName.class);
    if (l != null && !Locator.class.equals(l.locator())) {
      @SuppressWarnings("unchecked")
      Class> found = (Class>) l.locator();
      locatorType = found;
    } else if (ln != null && ln.locator().length() > 0) {
      try {
        @SuppressWarnings("unchecked")
        Class> found = (Class>) 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",
            ProxyForName.class.getCanonicalName(), ln.value());
      }
    } else {
      // No locator annotation
      locatorType = null;
    }
    return locatorType;
  }

  @Override
  public Class resolveServiceLocator(
      Method contextMethod, Method domainMethod) {
    Class locatorType;

    // Look at the RequestContext
    Class requestContextClass = contextMethod.getDeclaringClass();
    Service l = requestContextClass.getAnnotation(Service.class);
    ServiceName ln = requestContextClass.getAnnotation(ServiceName.class);
    if (l != null && !ServiceLocator.class.equals(l.locator())) {
      locatorType = l.locator();
    } else if (ln != null && ln.locator().length() > 0) {
      try {
        locatorType = 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",
            ServiceName.class.getCanonicalName(), ln.value());
      }
    } else {
      locatorType = null;
    }
    return locatorType;
  }

  private  Object doGetId(T domainObject) {
    @SuppressWarnings("unchecked")
    Class clazz = (Class) domainObject.getClass();
    Locator l = getLocator(clazz);
    if (l == null) {
      return super.getId(domainObject);
    }
    return l.getId(domainObject);
  }

  private  Object doGetVersion(T domainObject) {
    @SuppressWarnings("unchecked")
    Class clazz = (Class) domainObject.getClass();
    Locator l = getLocator(clazz);
    if (l == null) {
      return super.getVersion(domainObject);
    }
    return l.getVersion(domainObject);
  }

  private  boolean doIsLive(T domainObject) {
    @SuppressWarnings("unchecked")
    Class clazz = (Class) domainObject.getClass();
    Locator l = getLocator(clazz);
    if (l == null) {
      return super.isLive(domainObject);
    }
    return l.isLive(domainObject);
  }

  private  T doLoadDomainObject(Class clazz, Object domainId) {
    @SuppressWarnings("unchecked")
    Locator l = (Locator) getLocator(clazz);
    if (l == null) {
      return super.loadDomainObject(clazz, domainId);
    }
    I id = l.getIdType().cast(domainId);
    return l.find(clazz, id);
  }

  @SuppressWarnings("unchecked")
  private  Locator getLocator(Class domainType) {
    Class> locatorType = getTop().resolveLocator(
        domainType);
    if (locatorType == null) {
      return null;
    }
    return (Locator) getTop().createLocator(locatorType);
  }

  private  T newInstance(Class clazz, Class base) {
    Throwable ex;
    try {
      return clazz.newInstance();
    } catch (InstantiationException e) {
      ex = e;
    } catch (IllegalAccessException e) {
      ex = e;
    }
    return this. die(ex,
        "Could not instantiate %s %s. Is it default-instantiable?",
        base.getSimpleName(), clazz.getCanonicalName());
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy