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

juzu.impl.plugin.controller.ControllerService Maven / Gradle / Ivy

There is a newer version: 1.2.0
Show newest version
/*
 * Copyright 2013 eXo Platform SAS
 *
 * 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 juzu.impl.plugin.controller;

import juzu.Response;
import juzu.impl.common.Tools;
import juzu.impl.plugin.ServiceContext;
import juzu.impl.plugin.ServiceDescriptor;
import juzu.impl.plugin.application.Application;
import juzu.impl.request.ContextualParameter;
import juzu.impl.request.ControlParameter;
import juzu.impl.request.ControllerHandler;
import juzu.impl.request.RequestFilter;
import juzu.impl.value.ValueType;
import juzu.request.Phase;
import juzu.io.UndeclaredIOException;
import juzu.impl.bridge.spi.RequestBridge;
import juzu.impl.common.MethodHandle;
import juzu.impl.inject.spi.InjectionContext;
import juzu.impl.plugin.application.ApplicationService;
import juzu.impl.plugin.controller.descriptor.ControllersDescriptor;
import juzu.impl.request.Request;
import juzu.request.RequestParameter;

import javax.inject.Inject;

import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/** @author Julien Viet */
public class ControllerService extends ApplicationService {

  /** . */
  private ControllersDescriptor descriptor;

  /** . */
  final ArrayList> valueTypes = new ArrayList>();

  /** . */
  final List>                             filters = new ArrayList>();

  /** . */
  @Inject
  private Application application;

  public ControllerService() {
    super("controller");
  }

  public Application getApplication() {
    return application;
  }

  public ControllersDescriptor getDescriptor() {
    return descriptor;
  }

  public ControllerResolver getResolver() {
    return descriptor != null ? descriptor.getResolver() : null;
  }

  @Override
  public ServiceDescriptor init(ServiceContext context) throws Exception {
    valueTypes.addAll(ValueType.DEFAULT);
    for (ValueType valueType : Tools.loadService(ValueType.class, context.getClassLoader())) {
      valueTypes.add(valueType);
    }
    return descriptor = new ControllersDescriptor(context.getClassLoader(), context.getConfig());
  }

  public InjectionContext getInjectionContext() {
    return application.getInjectionContext();
  }
  
  public List> getFilters() {
    if (filters.isEmpty()) {
      synchronized (filters) {
        if (filters.isEmpty()) {
          // Build the filter list
          for (RequestFilter filter : getInjectionContext().resolveInstances(RequestFilter.class)) {
            filters.add(filter);
          }
        }
      }
    }
    return filters;
  }

  public  ValueType resolveValueType(Class type) {
    for (int i = 0;i < valueTypes.size();i++) {
      ValueType valueType = valueTypes.get(i);
      for (Class tmp : valueType.getTypes()) {
        if (tmp.equals(type)) {
          return (ValueType)valueType;
        }
      }
    }
    return null;
  }

  public void invoke(RequestBridge bridge) {

    //
    MethodHandle handle = bridge.getTarget();
    ControllerHandler handler = descriptor.getMethodByHandle(handle);
    if (handler == null) {
      StringBuilder sb = new StringBuilder("handle me gracefully : no method could be resolved for " +
          "phase=").append(bridge.getPhase()).append(" handle=").append(handle).append(" parameters={");
      int index = 0;
      for (RequestParameter parameter : bridge.getRequestArguments().values()) {
        if (index++ > 0) {
          sb.append(',');
        }
        sb.append(parameter.getName()).append("=[");
        for (int i = 0;i < parameter.size();i++) {
          if (i > 0) {
            sb.append(',');
          }
          sb.append(parameter.get(i));
        }
        sb.append(']');
      }
      sb.append("}");
      throw new UnsupportedOperationException(sb.toString());
    }

    //
    Request request = new Request(this, handler, bridge);

    //
    ClassLoader oldCL = Thread.currentThread().getContextClassLoader();
    try {
      ClassLoader classLoader = application.getClassLoader();
      Thread.currentThread().setContextClassLoader(classLoader);
      bridge.begin(request);

      //
      Response result = request.invoke();

      //
      if (result instanceof Response.Error && descriptor.getErrorController() != null) {
        Class> a = descriptor.getErrorController();
        Method m;
        try {
          m = a.getMethod("handle", Response.Error.class);
        }
        catch (NoSuchMethodException e) {
          throw new UndeclaredThrowableException(e);
        }

        //
        ContextualParameter argument = new ContextualParameter("argument", Response.Error.class);
        handler = new ControllerHandler(null, Phase.VIEW, a, m, Collections.singletonList(argument));
        request = new Request(this, handler, bridge);
        request.getContextualArguments().put(argument, result);
        result = request.invoke();
      }

      //
      if (result != null) {
        try {
          bridge.setResponse(result);
        }
        catch (IOException e) {
          throw new UndeclaredIOException(e);
        }
      }


    }
    finally {
      bridge.end();
      Thread.currentThread().setContextClassLoader(oldCL);
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy