Package org.apache.clerezza.triaxrs.providers

Source Code of org.apache.clerezza.triaxrs.providers.CascadingProviders

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you 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 org.apache.clerezza.triaxrs.providers;

import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Providers;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.clerezza.triaxrs.InjectionUtilities;
import org.apache.clerezza.triaxrs.JaxRsHandler;
import org.apache.clerezza.triaxrs.RootResources;
import org.apache.clerezza.triaxrs.WebRequest;
import org.apache.clerezza.triaxrs.WebRequestProxy;
import org.apache.clerezza.triaxrs.parameterinjectors.UnsupportedFieldType;
import org.wymiwyg.wrhapi.HandlerException;

/**
* CascadingProviders is an implementation of {@link Providers} and it
* contains a tree of {@link ProvidersImpl}s where each {@link ProvidersImpl}
* is assigned a certain path prefix
*
* @author hasan
*
* since version 0.5
*/
public class CascadingProviders implements Providers {

  private Logger logger = LoggerFactory.getLogger(CascadingProviders.class);

  CascadeNode root = new CascadeNode();

  public void addClass(Class<?> componentClass, String pathPrefix) {
    try {
      addInstance(componentClass.newInstance(), pathPrefix);
    } catch (InstantiationException ex) {
      logger.error("Exception {}", ex);
    } catch (IllegalAccessException ex) {
      logger.error("Exception {}", ex);
    }
  }

  public void addInstance(Object component, String pathPrefix) {
    injectContext(component);
    String[] pathSections = getPathSections(pathPrefix);
    CascadeNode current = root;
    for (String section : pathSections) {
      if (!section.equals("")) {
        current = current.createChild(section);
      }
    }
    current.getProviders().addInstance(component);
  }

  /**
   * Injects context object in the fields of the provider annotated with
   * @Context.
   *
   * @param provider
   */
  private void injectContext(Object provider) {
    WebRequest requestProxy = WebRequestProxy.createProxy();
    try {
      InjectionUtilities.injectFields(requestProxy, null, JaxRsHandler.providers, provider);
    } catch (HandlerException ex) {
      logger.debug("Exception {}", ex);
      throw new RuntimeException(ex);
    } catch (UnsupportedFieldType ex) {
      logger.debug("Exception {}", ex);
      throw new RuntimeException(ex);
    }
  }

  private String[] getPathSections(String pathPrefix) {
    if (pathPrefix.startsWith("/")) {
      return pathPrefix.substring(1).split("/");
    } else {
      return pathPrefix.split("/");
    }
  }

  public void removeInstance(Object component, String pathPrefix) {
    String[] pathSections = getPathSections(pathPrefix);
    CascadeNode current = root;
    CascadeNode prev = current;
    int pos = 0;
    for (String section : pathSections) {
      if (current == null) {
        break;
      }
      pos++;
      prev = current;
      if (!section.equals("")) {
        current = current.getChild(section);
      }
    }
    if (current != null) {
      ProvidersImpl providers = current.getProviders();
      providers.removeInstance(component);
      if (providers.isEmpty()) {
        if (!current.hasChild() && (pos > 0)) {
          prev.deleteChild(pathSections[pos - 1]);
        }
      }
    }
  }

  @Override
  public <T> MessageBodyReader<T> getMessageBodyReader(Class<T> c, Type t,
      Annotation[] as, MediaType mediaType) {

    return getMessageBodyReader(c, t, as, mediaType,
        getRequestUriWithoutStartingSlash());
  }

  private String getRequestUriWithoutStartingSlash() {
    String requestUri = RootResources.getCurrentRequestUri();
    if (requestUri.startsWith("/")) {
      return requestUri.substring(1);
    } else {
      return requestUri;
    }
  }

  /**
   * an intermediate method with package visibility against which the tests run
   */
  <T> MessageBodyReader<T> getMessageBodyReader(Class<T> c, Type t,
      Annotation[] as, MediaType mediaType, String currentRequestUri) {

    String[] pathSections = currentRequestUri.split("/");
    return getMessageBodyReader(c, t, as, mediaType, root, pathSections, 0);
  }

  private <T> MessageBodyReader<T> getMessageBodyReader(Class<T> c, Type t,
      Annotation[] as, MediaType mediaType, CascadeNode node,
      String[] pathSections, int pos) {

    MessageBodyReader<T> result = null;
    if (pos < pathSections.length) {
      CascadeNode child = node.getChild(pathSections[pos]);
      if (child != null) {
        result = getMessageBodyReader(c, t, as, mediaType, child,
            pathSections, pos + 1);
      }
    }
    if (result == null) {
      return node.getProviders().getMessageBodyReader(c, t, as, mediaType);
    } else {
      return result;
    }
  }

  @Override
  public <T> MessageBodyWriter<T> getMessageBodyWriter(Class<T> c,
      Type t, Annotation[] as, MediaType mediaType) {

    String currentRequestUri = getRequestUriWithoutStartingSlash();
    String[] pathSections = currentRequestUri.split("/");

    return getMessageBodyWriter(c, t, as, mediaType, root, pathSections, 0);
  }

  private <T> MessageBodyWriter<T> getMessageBodyWriter(Class<T> c, Type t,
      Annotation[] as, MediaType mediaType, CascadeNode node,
      String[] pathSections, int pos) {

    MessageBodyWriter<T> result = null;
    if (pos < pathSections.length) {
      CascadeNode child = node.getChild(pathSections[pos]);
      if (child != null) {
        result = getMessageBodyWriter(c, t, as, mediaType, child,
            pathSections, pos + 1);
      }
    }
    if (result == null) {
      return node.getProviders().getMessageBodyWriter(c, t, as, mediaType);
    } else {
      return result;
    }
  }

  @Override
  public <T> ContextResolver<T> getContextResolver(Class<T> contextType,
      MediaType mediaType) {
    throw new UnsupportedOperationException("Not supported yet.");
  }

  @Override
  public <T extends Throwable> ExceptionMapper<T> getExceptionMapper(
      final Class<T> c) {

    String currentRequestUri = getRequestUriWithoutStartingSlash();
    String[] pathSections = currentRequestUri.split("/");

    return getExceptionMapper(c, root, pathSections, 0);
  }

  private <T extends Throwable> ExceptionMapper<T> getExceptionMapper(
      final Class<T> c, CascadeNode node,  String[] pathSections, int pos) {

    ExceptionMapper<T> result = null;
    if (pos < pathSections.length) {
      CascadeNode child = node.getChild(pathSections[pos]);
      if (child != null) {
        result = getExceptionMapper(c, child, pathSections, pos + 1);
      }
    }
    if (result == null) {
      return node.getProviders().getExceptionMapper(c);
    } else {
      return result;
    }
  }
}
TOP

Related Classes of org.apache.clerezza.triaxrs.providers.CascadingProviders

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.