Package juzu.impl.bridge.spi.web

Source Code of juzu.impl.bridge.spi.web.WebRequestBridge

/*
* 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.bridge.spi.web;

import juzu.PropertyMap;
import juzu.PropertyType;
import juzu.Response;
import juzu.Scope;
import juzu.asset.AssetLocation;
import juzu.impl.bridge.Bridge;
import juzu.impl.common.Logger;
import juzu.impl.common.RunMode;
import juzu.impl.common.UriBuilder;
import juzu.impl.inject.spi.InjectorProvider;
import juzu.impl.request.ContextualParameter;
import juzu.impl.request.ControllerHandler;
import juzu.request.ClientContext;
import juzu.request.RequestParameter;
import juzu.request.ResponseParameter;
import juzu.impl.bridge.spi.DispatchBridge;
import juzu.impl.common.MimeType;
import juzu.impl.common.MethodHandle;
import juzu.impl.plugin.controller.ControllerService;
import juzu.impl.bridge.spi.ScopedContext;
import juzu.impl.request.Request;
import juzu.impl.bridge.spi.RequestBridge;
import juzu.impl.common.Tools;
import juzu.impl.router.PathParam;
import juzu.impl.router.Route;
import juzu.impl.router.RouteMatch;
import juzu.request.ApplicationContext;
import juzu.request.HttpContext;
import juzu.request.Phase;
import juzu.request.SecurityContext;
import juzu.request.UserContext;
import juzu.request.WindowContext;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.RejectedExecutionException;

/** @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a> */
public abstract class WebRequestBridge implements RequestBridge, WindowContext {

  /** . */
  final Bridge bridge;

  /** . */
  final juzu.impl.bridge.spi.web.Handler handler;

  /** . */
  final WebBridge http;

  /** . */
  final Phase phase;

  /** . */
  final ControllerHandler<?> target;

  /** . */
  protected Request request;

  /** . */
  protected Map<String, RequestParameter> requestParameters;

  /** . */
  protected Response response;

  WebRequestBridge(
      Bridge bridge,
      juzu.impl.bridge.spi.web.Handler handler,
      WebBridge http,
      Phase phase,
      ControllerHandler<?> target,
      Map<String, RequestParameter> requestParameters) {
    this.requestParameters = requestParameters;
    this.bridge = bridge;
    this.target = target;
    this.handler = handler;
    this.http = http;
    this.request = null;
    this.phase = phase;
  }

  //

  @Override
  public Charset getDefaultRequestEncoding() {
    return bridge.getConfig().requestEncoding;
  }

  @Override
  public Map<ContextualParameter, Object> getContextualArguments(Set<ContextualParameter> parameters) {
    return Collections.emptyMap();
  }

  public RunMode getRunMode() {
    return bridge.getRunMode();
  }

  public Phase getPhase() {
    return phase;
  }

  public Logger getLogger(String name) {
    return http.getLogger(name);
  }

  public Map<String, RequestParameter> getRequestArguments() {
    return requestParameters;
  }

  public MethodHandle getTarget() {
    return target.getHandle();
  }

  public <T> T getProperty(PropertyType<T> propertyType) {
    if (RunMode.PROPERTY.equals(propertyType)) {
      return propertyType.cast(bridge.getRunMode());
    } else if (InjectorProvider.PROPERTY.equals(propertyType)) {
      return propertyType.cast(bridge.getConfig().injectorProvider);
    } else if (PropertyType.PATH.equals(propertyType)) {
      return propertyType.cast(http.getRequestContext().getRequestURI());
    }
    return null;
  }

  //

  public final String getNamespace() {
    return "window_ns";
  }

  public final String getId() {
    return "window_id";
  }
  //

  public ClientContext getClientContext() {
    return phase == Phase.ACTION || phase == Phase.RESOURCE ? http.getClientContext() : null;
  }

  public final HttpContext getHttpContext() {
    return http.getHttpContext();
  }

  public final WindowContext getWindowContext() {
    return this;
  }

  public final SecurityContext getSecurityContext() {
    return http.getSecurityContext();
  }

  public UserContext getUserContext() {
    return http.getUserContext();
  }

  public ApplicationContext getApplicationContext() {
    return http.getApplicationContext();
  }

  public final ScopedContext getScopedContext(Scope scope, boolean create) {
    ScopedContext context;
    switch (scope) {
      case REQUEST:
        context = http.getRequestScope(create);
        break;
      case FLASH:
        context = http.getFlashScope(create);
        break;
      case SESSION:
        context = http.getSessionScope(create);
        break;
      default:
        throw new UnsupportedOperationException("Unsupported scope " + scope);
    }
    return context;
  }

  public final DispatchBridge createDispatch(Phase phase, final MethodHandle target, final Map<String, ResponseParameter> parameters) {
    ControllerHandler handler = bridge.getApplication().resolveBean(ControllerService.class).getDescriptor().getMethodByHandle(target);

    //
    Route route = this.handler.getRoute(handler.getHandle());
    if (route == null) {
      if (bridge.getApplication().resolveBean(ControllerService.class).getResolver().isIndex(handler)) {
        route = this.handler.getRoot();
      }
    }

    //
    if (route != null) {
      Map<String, String> params;
      if (parameters.isEmpty()) {
        params = Collections.emptyMap();
      } else {
        params = new HashMap<String, String>(parameters.size());
        for (ResponseParameter parameter : parameters.values()) {
          params.put(parameter.getName(), parameter.get(0));
        }
      }

      //
      final RouteMatch match = route.matches(params);
      if (match != null) {
        return new DispatchBridge() {

          public MethodHandle getTarget() {
            return target;
          }

          public Map<String, ResponseParameter> getParameters() {
            return parameters;
          }

          public <T> String checkPropertyValidity(PropertyType<T> propertyType, T propertyValue) {
            // For now we don't validate anything
            return null;
          }

          public void renderURL(PropertyMap properties, MimeType mimeType, Appendable appendable) throws IOException {

            // Render base URL
            http.renderRequestURL(appendable);

            // Render path
            UriBuilder writer = new UriBuilder(appendable, mimeType);
            match.render(writer);

            // Retain matched parameters for filtering later
            Set<String> matched = match.getMatched().isEmpty() ? Collections.<String>emptySet() : new HashSet<String>(match.getMatched().size());
            for (PathParam param : match.getMatched().keySet()) {
              matched.add(param.getName());
            }

            // Render remaining parameters which have not been rendered yet
            for (ResponseParameter parameter : parameters.values()) {
              if (!matched.contains(parameter.getName())) {
                for (int i = 0;i < parameter.size();i++) {
                  writer.appendQueryParameter(parameter.getEncoding(), parameter.getName(), parameter.get(i));
                }
              }
            }
          }
        };
      } else {
        throw new IllegalArgumentException("The parameters " + parameters + " are not valid");
      }
    } else {
      throw new UnsupportedOperationException("handle me gracefully method not mapped " + handler.getHandle());
    }
  }

  public void setResponse(Response response) throws IllegalArgumentException, IOException {
    this.response = response;
  }

  public final void begin(Request request) {
    this.request = request;
  }

  public void end() {
    this.request = null;
  }

  public void execute(Runnable runnable) throws RejectedExecutionException {
    http.execute(runnable);
  }

  public void close() {
  }

  void invoke() throws Exception {
    try {
      bridge.getApplication().resolveBean(ControllerService.class).invoke(this);
    } finally {
      Tools.safeClose(this);
    }
  }

  /**
   * Send the response to the client.
   */
  boolean send() throws Exception {
    if (response instanceof Response.Error) {
      Response.Error error = (Response.Error)response;
      http.getRequestContext().send(error, bridge.getRunMode().getPrettyFail());
      return true;
    } else if (response instanceof Response.View) {
      Response.View view = (Response.View)response;
      Phase.View.Dispatch update = (Phase.View.Dispatch)view;
      Boolean redirect = view.getProperties().getValue(PropertyType.REDIRECT_AFTER_ACTION);
      if (redirect != null && !redirect) {
        ControllerHandler<?> desc = this.bridge.getApplication().resolveBean(ControllerService.class).getDescriptor().getMethodByHandle(update.getTarget());
        Map<String, RequestParameter> rp = Collections.emptyMap();
        for (ResponseParameter parameter : update.getParameters().values()) {
          if (rp.isEmpty()) {
            rp = new HashMap<String, RequestParameter>();
          }
          RequestParameter requestParameter = RequestParameter.create(parameter.getName(), parameter.toArray());
          rp.put(requestParameter.getName(), requestParameter);
        }
        WebViewBridge requestBridge = new WebViewBridge(bridge, handler, http, desc, rp);
        requestBridge.invoke();
        return requestBridge.send();
      } else {
        String url = update.with(MimeType.PLAIN).with(update.getProperties()).toString();
        Iterable<Map.Entry<String, String[]>> headers = view.getProperties().getValues(PropertyType.HEADER);
        if (headers == null) {
          headers = Tools.emptyIterable();
        }
        http.getRequestContext().setHeaders(headers);
        http.getRequestContext().sendRedirect(url);
        return true;
      }
    }
    else if (response instanceof Response.Redirect) {
      Response.Redirect redirect = (Response.Redirect)response;
      String url = redirect.getLocation();
      http.getRequestContext().sendRedirect(url);
      return true;
    } else {
      return false;
    }
  }

  public void renderAssetURL(AssetLocation location, String uri, Appendable appendable) throws NullPointerException, UnsupportedOperationException, IOException {
    http.getRequestContext().renderAssetURL(location, uri, appendable);
  }
}
TOP

Related Classes of juzu.impl.bridge.spi.web.WebRequestBridge

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.