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

com.google.web.bindery.requestfactory.server.LocatorServiceLayer Maven / Gradle / Ivy

The 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(Class requestContext) {
    Class locatorType = getTop().resolveServiceLocator(requestContext);
    ServiceLocator locator = getTop().createServiceLocator(locatorType);
    Class serviceClass = getTop().resolveServiceClass(requestContext);
    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(
      Class requestContext) {
    Class locatorType;

    Service l = requestContext.getAnnotation(Service.class);
    ServiceName ln = requestContext.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