incubator-wink-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ngalla...@apache.org
Subject svn commit: r787557 [2/12] - in /incubator/wink/contrib/ibm-jaxrs: ./ lib/ src/ src/com/ src/com/ibm/ src/com/ibm/ws/ src/com/ibm/ws/jaxrs/ src/com/ibm/ws/jaxrs/annotations/ src/com/ibm/ws/jaxrs/context/ src/com/ibm/ws/jaxrs/core/ src/com/ibm/ws/jaxrs/...
Date Tue, 23 Jun 2009 05:41:55 GMT
Added: incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/core/SecurityContextImpl.java
URL: http://svn.apache.org/viewvc/incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/core/SecurityContextImpl.java?rev=787557&view=auto
==============================================================================
--- incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/core/SecurityContextImpl.java (added)
+++ incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/core/SecurityContextImpl.java Tue Jun 23 05:41:49 2009
@@ -0,0 +1,99 @@
+/*
+ * 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 com.ibm.ws.jaxrs.core;
+
+import java.security.Principal;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.core.SecurityContext;
+
+import com.ibm.ws.jaxrs.context.ContextConstants;
+import com.ibm.ws.jaxrs.context.RESTContext;
+import com.ibm.ws.jaxrs.i18n.Messages;
+
+/**
+ * This class will be the injectable implementation of the SecurityContext
+ * interface. Instances of this class can be requested by applications to
+ * query security context information for a request.
+ *
+ */
+public class SecurityContextImpl implements SecurityContext {
+
+    RESTContext context;
+
+    public SecurityContextImpl(RESTContext context) {
+        this.context = context;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see javax.ws.rs.core.SecurityContext#getAuthenticationScheme()
+     */
+    public String getAuthenticationScheme() {
+        checkValidity();
+        return (String) context
+                .getProperty(ContextConstants.AUTHENTICATION_SCHEME);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see javax.ws.rs.core.SecurityContext#getUserPrincipal()
+     */
+    public Principal getUserPrincipal() {
+        checkValidity();
+        return (Principal) context.getProperty(ContextConstants.USER_PRINCIPAL);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see javax.ws.rs.core.SecurityContext#isSecure()
+     */
+    public boolean isSecure() {
+        checkValidity();
+        return ((Boolean) context.getProperty(ContextConstants.REQUEST_SECURE))
+                .booleanValue();
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see javax.ws.rs.core.SecurityContext#isUserInRole()
+     */
+    public boolean isUserInRole(String role) {
+        checkValidity();
+        HttpServletRequest request = (HttpServletRequest) context
+                .getProperty(ContextConstants.SERVLET_REQUEST);
+        if (request != null) {
+            return request.isUserInRole(role);
+        }
+        return false;
+    }
+
+    void checkValidity() {
+        if (context == null) {
+            throw new IllegalStateException(Messages
+                    .getMessage("contextInjectionFail"));
+        }
+    }
+
+}

Added: incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/core/UriInfoImpl.java
URL: http://svn.apache.org/viewvc/incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/core/UriInfoImpl.java?rev=787557&view=auto
==============================================================================
--- incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/core/UriInfoImpl.java (added)
+++ incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/core/UriInfoImpl.java Tue Jun 23 05:41:49 2009
@@ -0,0 +1,245 @@
+/*
+ * 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 com.ibm.ws.jaxrs.core;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.PathSegment;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.cxf.jaxrs.impl.MetadataMap;
+import org.apache.cxf.jaxrs.impl.UriBuilderImpl;
+import org.apache.cxf.jaxrs.model.URITemplate;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+
+import com.ibm.ws.jaxrs.context.ContextConstants;
+import com.ibm.ws.jaxrs.context.RESTContext;
+
+/**
+ * This class will be the implementation of the injectable UriInfo interface.
+ * A UriInfo instance will provide an application information about request
+ * and application URIs.
+ *
+ */
+public class UriInfoImpl implements UriInfo {
+
+    private RESTContext context;
+
+    private MultivaluedMap<String, String> templateParams;
+
+    private String charSet;
+
+    private String requestURL;
+
+    private String path;
+
+    @SuppressWarnings("unchecked")
+    public UriInfoImpl(RESTContext context) {
+        this.context = context;
+        if (context != null) {
+            templateParams = (MultivaluedMap<String, String>) context
+                    .getProperty(ContextConstants.TEMPLATE_VALUES);
+            charSet = (String) context
+                    .getProperty(ContextConstants.HTTP_REQUEST_ENCODING);
+            if (charSet == null) {
+                charSet = "UTF-8";
+            }
+            requestURL = (String) context
+                    .getProperty(ContextConstants.HTTP_REQUEST_URL);
+            path = (String) context
+                    .getProperty(ContextConstants.HTTP_PATH_INFO);
+        }
+    }
+
+    public URI getAbsolutePath() {
+        String absolutePath = requestURL.contains("?") ? requestURL.substring(
+                0, requestURL.indexOf("?")) : requestURL;
+        return URI.create(absolutePath);
+    }
+
+    public UriBuilder getAbsolutePathBuilder() {
+        return new UriBuilderImpl(getAbsolutePath());
+    }
+
+    public URI getBaseUri() {
+        String contextPath = (String) context
+                .getProperty(ContextConstants.HTTP_REQUEST_CONTEXT_PATH);
+        String uri = (String) context
+                .getProperty(ContextConstants.HTTP_REQUEST_URI);
+        String base = "";
+        if (contextPath == null || "".equals(contextPath)) {
+            base = requestURL.substring(0, requestURL.indexOf(uri));
+        } else {
+            if (!contextPath.endsWith("/")) {
+                contextPath += "/";
+            }
+            int endIndex = requestURL.indexOf(contextPath)
+                    + contextPath.length() - 1;
+            base = requestURL.substring(0, endIndex);
+        }
+
+        return URI.create(base);
+    }
+
+    public UriBuilder getBaseUriBuilder() {
+        return new UriBuilderImpl(getBaseUri());
+    }
+
+    public String getPath() {
+        return getPath(true);
+    }
+
+    public String getPath(boolean decode) {
+        try {
+            String pathInfo = path;
+            /*
+             * the request URL is not decoded at this point
+             */
+            int lastIndex = requestURL.lastIndexOf(pathInfo);
+            if (lastIndex == -1) {
+                String pathResource = (String) context
+                        .getProperty(ContextConstants.HTTP_PATH_RESOURCE);
+                lastIndex = requestURL.lastIndexOf(pathResource);
+            }
+            pathInfo = requestURL.substring(lastIndex);
+            if (decode) {
+                pathInfo = URLDecoder.decode(pathInfo, charSet);
+            }
+            return pathInfo;
+        } catch (Exception e) {
+            throw new WebApplicationException(e);
+        }
+    }
+
+    public MultivaluedMap<String, String> getPathParameters() {
+        return getPathParameters(true);
+    }
+
+    public MultivaluedMap<String, String> getPathParameters(boolean decode) {
+        MultivaluedMap<String, String> values = new MetadataMap<String, String>();
+        for (Map.Entry<String, List<String>> entry : templateParams.entrySet()) {
+            if (entry.getKey().equals(URITemplate.FINAL_MATCH_GROUP)) {
+                continue;
+            }
+            String valueToAdd = entry.getValue().get(0);
+
+            // if we shouldn't be decoding we will need to encode the value, the
+            // values have likely already been decoded
+            if (decode) {
+                try {
+                    valueToAdd = URLDecoder.decode(valueToAdd, charSet);
+                } catch (UnsupportedEncodingException e) {
+                    throw new WebApplicationException(e);
+                }
+            }
+            values.add(entry.getKey(), valueToAdd);
+        }
+        return values;
+    }
+
+    public List<PathSegment> getPathSegments() {
+        return getPathSegments(true);
+    }
+
+    public List<PathSegment> getPathSegments(boolean decode) {
+        return JAXRSUtils.getPathSegments(getPath(false), decode);
+    }
+
+    public MultivaluedMap<String, String> getQueryParameters() {
+        return getQueryParameters(true);
+    }
+
+    public MultivaluedMap<String, String> getQueryParameters(boolean decode) {
+        String queryString = (String) context
+                .getProperty(ContextConstants.HTTP_QUERY_STRING);
+        return JAXRSUtils.getStructuredParams(queryString, "&", decode);
+    }
+
+    public URI getRequestUri() {
+        String absPath = getAbsolutePath().toString();
+        String reqUri = "";
+        String queryString = (String) context
+                .getProperty(ContextConstants.HTTP_QUERY_STRING);
+        if (queryString != null) {
+            reqUri = absPath + "?" + queryString;
+        } else {
+            reqUri = absPath;
+        }
+        return URI.create(reqUri);
+    }
+
+    public UriBuilder getRequestUriBuilder() {
+        return new UriBuilderImpl(getRequestUri());
+    }
+
+    @SuppressWarnings("unchecked")
+    public List<Object> getMatchedResources() {
+        List<Object> matched = (List<Object>) context
+                .getProperty(ContextConstants.MATCHED_RESOURCES);
+        List<Object> newList = null;
+        if (matched != null) {
+            newList = new ArrayList<Object>(matched);
+            Collections.reverse(newList);
+            newList = Collections.unmodifiableList(newList);
+        }
+        return newList;
+    }
+
+    public List<String> getMatchedURIs() {
+        return getMatchedURIs(true);
+    }
+
+    @SuppressWarnings("unchecked")
+    public List<String> getMatchedURIs(boolean decode) {
+        List<String> matched = (List<String>) context
+                .getProperty(ContextConstants.MATCHED_URIS);
+        List<String> newList = null;
+        if (matched != null) {
+            newList = new ArrayList<String>(matched);
+            Collections.reverse(newList);
+
+            // make sure it is decoded
+            if (decode) {
+                for (int i = 0; i < newList.size(); i++) {
+                    String uriPart = newList.get(i);
+                    try {
+                        uriPart = URLDecoder.decode(uriPart, charSet);
+                        newList.remove(i);
+                        newList.add(i, uriPart);
+                    } catch (UnsupportedEncodingException e) {
+                        throw new WebApplicationException(e);
+                    }
+                }
+            }
+            newList = Collections.unmodifiableList(newList);
+        }
+        return newList;
+    }
+
+}

Added: incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/engine/RESTConfig.java
URL: http://svn.apache.org/viewvc/incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/engine/RESTConfig.java?rev=787557&view=auto
==============================================================================
--- incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/engine/RESTConfig.java (added)
+++ incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/engine/RESTConfig.java Tue Jun 23 05:41:49 2009
@@ -0,0 +1,65 @@
+/*
+ * 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 com.ibm.ws.jaxrs.engine;
+
+import javax.servlet.ServletConfig;
+
+import com.ibm.ws.jaxrs.context.ContextConstants;
+import com.ibm.ws.jaxrs.context.RESTContext;
+
+/**
+ * Contains all the configuration constants that change the runtime behavior.
+ */
+public final class RESTConfig {
+    /**
+     * If this configuration flag is set, then the runtime should use
+     * X-HTTP-Method-Override and X-Method-Override HTTP headers to determine
+     * the final HTTP method.
+     */
+    public final static String HTTP_METHOD_OVERRIDE_CONFIG = "com.ibm.ws.jaxrs.httpmethodoverride.enable";
+
+    private RESTConfig() {
+        /* do nothing */
+    }
+
+    public static String getPropertyValue(String propertyKey, RESTContext context) {
+        if (propertyKey == null) {
+            throw new IllegalArgumentException(
+                    "Tried accessing a property with a null property key");
+        }
+
+        if (context == null) {
+            throw new IllegalArgumentException(
+                    "Tried accessing a property with a null context");
+        }
+
+        /* try the servlet config property before the System JVM property */
+        ServletConfig servletConfig = (ServletConfig) context
+                .getProperty(ContextConstants.SERVLET_CONFIG);
+        if (servletConfig != null) {
+            String str = servletConfig.getInitParameter(propertyKey);
+            if (str != null) {
+                return str;
+            }
+        }
+
+        return System.getProperty(propertyKey);
+    }
+}

Added: incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/engine/RESTConstants.java
URL: http://svn.apache.org/viewvc/incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/engine/RESTConstants.java?rev=787557&view=auto
==============================================================================
--- incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/engine/RESTConstants.java (added)
+++ incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/engine/RESTConstants.java Tue Jun 23 05:41:49 2009
@@ -0,0 +1,32 @@
+/*
+ * 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 com.ibm.ws.jaxrs.engine;
+
+/**
+ * Class of constant values used throught the REST runtime.
+ *
+ */
+public class RESTConstants {
+
+    public static final String MESSAGE_FLOW_INBOUND = "com.ibm.ws.jaxrs.engine.MESSAGE_FLOW_INBOUND";
+
+    public static final String MESSAGE_FLOW_OUTBOUND = "com.ibm.ws.jaxrs.engine.MESSAGE_FLOW_OUTBOUND";
+
+}

Added: incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/engine/RESTEngine.java
URL: http://svn.apache.org/viewvc/incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/engine/RESTEngine.java?rev=787557&view=auto
==============================================================================
--- incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/engine/RESTEngine.java (added)
+++ incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/engine/RESTEngine.java Tue Jun 23 05:41:49 2009
@@ -0,0 +1,190 @@
+/*
+ * 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 com.ibm.ws.jaxrs.engine;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Iterator;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.cxf.jaxrs.model.ClassResourceInfo;
+
+import com.ibm.ws.jaxrs.context.ContextConstants;
+import com.ibm.ws.jaxrs.context.RESTContext;
+import com.ibm.ws.jaxrs.exception.ExceptionUtils;
+import com.ibm.ws.jaxrs.handler.HandlerFactory;
+import com.ibm.ws.jaxrs.handler.RESTSystemHandler;
+import com.ibm.ws.jaxrs.i18n.Messages;
+import com.ibm.ws.jaxrs.io.DelegatingOutputStream;
+import com.ibm.ws.jaxrs.io.LogInputStream;
+import com.ibm.ws.jaxrs.io.LogOutputStream;
+import com.ibm.ws.jaxrs.lifecycle.LifecycleManager;
+import com.ibm.ws.jaxrs.lifecycle.LifecycleManagerFactory;
+
+/**
+ * This class will be the entry/exit point for REST requests and
+ * responses in our runtime.
+ *
+ */
+public class RESTEngine {
+
+    private static final Log log = LogFactory.getLog(RESTEngine.class);
+
+    public static RESTContext invoke(RESTContext context) throws Throwable {
+        RESTContext response = receive(context);
+        handleResponse(response);
+        return response;
+    }
+
+    /**
+     * This method will be called when a request has been received by our
+     * REST runtime. It will be responsible for driving the invocation of
+     * the appropriate resource.
+     *
+     */
+    public static RESTContext receive(RESTContext context) throws Throwable {
+
+        initializeIO(context);
+
+        // set the message flow
+        context.setProperty(ContextConstants.MESSAGE_FLOW,
+                RESTConstants.MESSAGE_FLOW_INBOUND);
+
+        // run the RESTSystemHandlers
+        try {
+            Iterator<RESTSystemHandler> systemHandlers = HandlerFactory
+                    .getSystemInboundHandlers().iterator();
+            while (systemHandlers.hasNext()) {
+                RESTSystemHandler systemHandler = systemHandlers.next();
+                if (log.isDebugEnabled()) {
+                    log.debug("Calling system handler: "
+                            + systemHandler.getClass().getName());
+                }
+                systemHandler.invoke(context);
+            }
+
+            // get the root level resource from the RESTContext, if it is not
+            // there throw an exception
+            ClassResourceInfo resource = (ClassResourceInfo) context
+                    .getProperty(ContextConstants.ROOT_RESOURCE);
+            if (resource == null) {
+
+                // could have been an options request at the context root,
+                // if so, the response context should already be setup
+                RESTContext rspContext = (RESTContext) context
+                        .getProperty(ContextConstants.OPTIONS_RESPONSE_CONTEXT);
+                if (rspContext != null) {
+                    return rspContext;
+                }
+
+                // this can happen if none of the REST Handlers set this property
+                Response rsp = Response.status(Response.Status.NOT_FOUND)
+                        .build();
+                String msg = Messages.getMessage("resourceNotFound",
+                        (String) context
+                                .getProperty(ContextConstants.HTTP_PATH_INFO));
+                throw new WebApplicationException(new RuntimeException(msg),
+                        rsp);
+            }
+
+            LifecycleManager mgr = LifecycleManagerFactory
+                    .getLifeCycleManager(resource);
+            Object instance = mgr.createInstance(resource, context);
+            if (instance == null) {
+                throw new WebApplicationException(
+                        Response.Status.INTERNAL_SERVER_ERROR);
+            }
+            if (log.isDebugEnabled()) {
+                log.debug("Created resource instance: "
+                        + instance.getClass().getName());
+            }
+            return ResourceInvoker.invokeMethod(instance, context);
+
+        } catch (Throwable e) {
+            if (log.isErrorEnabled()) {
+                log.error(Messages.getMessage("resourceInvocationFail"), e);
+            }
+            RESTContext responseCtx = ExceptionUtils.processServerException(e,
+                    context);
+            if (responseCtx != null)
+                return responseCtx;
+
+            throw e;
+        }
+    }
+
+    /**
+     * This method will drive the call to the outbound handlers for the
+     * response RESTContext.
+     */
+    public static void handleResponse(RESTContext context) throws Exception {
+
+        // run the RESTSystemHandlers
+        context.setProperty(ContextConstants.MESSAGE_FLOW,
+                RESTConstants.MESSAGE_FLOW_OUTBOUND);
+        Iterator<RESTSystemHandler> systemHandlers = HandlerFactory
+                .getSystemOutboundHandlers().iterator();
+        while (systemHandlers.hasNext()) {
+            RESTSystemHandler systemHandler = systemHandlers.next();
+            if (log.isDebugEnabled()) {
+                log.debug("Calling system handler: "
+                        + systemHandler.getClass().getName());
+            }
+            systemHandler.invoke(context);
+        }
+
+    }
+
+    /**
+     * This method initializes the RESTContext with the appropriate InputStream
+     * and OutputStream instances. If logging is enabled, special streams will
+     * be used to avoid double serialization/deserialization of the message.
+     */
+    static void initializeIO(RESTContext context) {
+
+        // initialize the InputStream as necessary
+        InputStream is = (InputStream) context
+                .getProperty(ContextConstants.REQUEST_INPUT_STREAM);
+        if (log.isDebugEnabled() && is != null) {
+            is = new LogInputStream(is, 100000);
+            context.setProperty(ContextConstants.REQUEST_INPUT_STREAM, is);
+        }
+
+        // initialize the OutputStream as necessary
+        OutputStream os = (OutputStream) context
+                .getProperty(ContextConstants.RESPONSE_OUTPUT_STREAM);
+        DelegatingOutputStream dos = null;
+        LogOutputStream los = null;
+        if (log.isDebugEnabled() && os != null) {
+            los = new LogOutputStream(os, 100000);
+            dos = new DelegatingOutputStream(los);
+        } else {
+            dos = new DelegatingOutputStream(os);
+        }
+        context.setProperty(ContextConstants.RESPONSE_OUTPUT_STREAM, dos);
+        context.setProperty(ContextConstants.CONTENT_MONITOR, dos);
+        context.setProperty(ContextConstants.OUTPUT_LOGGER, los);
+    }
+
+}

Added: incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/engine/RESTEngineUtils.java
URL: http://svn.apache.org/viewvc/incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/engine/RESTEngineUtils.java?rev=787557&view=auto
==============================================================================
--- incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/engine/RESTEngineUtils.java (added)
+++ incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/engine/RESTEngineUtils.java Tue Jun 23 05:41:49 2009
@@ -0,0 +1,84 @@
+/*
+ * 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 com.ibm.ws.jaxrs.engine;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+
+import com.ibm.ws.jaxrs.context.ContextConstants;
+import com.ibm.ws.jaxrs.context.RESTContext;
+
+/**
+ * A collection of utility methods for our engine runtime.
+ *
+ */
+public class RESTEngineUtils {
+
+    /**
+     * This method will add a path that has been matched to a resource or subresource,
+     * to a list of Strings that are being kept on the RESTContext.
+     *
+     */
+    public static void addMatchedUri(String uri, RESTContext context) {
+        List<String> matchedUris = (List<String>) context
+                .getProperty(ContextConstants.MATCHED_URIS);
+        if (matchedUris == null) {
+            matchedUris = new ArrayList<String>();
+            context.setProperty(ContextConstants.MATCHED_URIS, matchedUris);
+        }
+
+        // nothing to do, just return
+        if (uri.equals("/")) {
+            return;
+        }
+
+        String cleanedUpURI = uri;
+        cleanedUpURI = JAXRSUtils.removePrecedingSlash(cleanedUpURI);
+        cleanedUpURI = JAXRSUtils.removeTrailingSlash(cleanedUpURI);
+
+        // only add if we don't have it in our list
+        if (!matchedUris.contains(cleanedUpURI)) {
+            matchedUris.add(cleanedUpURI);
+        }
+    }
+
+    /**
+     * This method will add an object to our matched resources list each time a resource
+     * class is targetted during request processing.
+     *
+     */
+    public static void addMatchedResource(Object resource, RESTContext context) {
+        List<Object> matchedResources = (List<Object>) context
+                .getProperty(ContextConstants.MATCHED_RESOURCES);
+        if (matchedResources == null) {
+            matchedResources = new ArrayList<Object>();
+            context.setProperty(ContextConstants.MATCHED_RESOURCES,
+                    matchedResources);
+        }
+
+        // only add if we don't already have it in our list
+        if (!matchedResources.contains(resource)) {
+            matchedResources.add(resource);
+        }
+    }
+
+}

Added: incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/engine/ResourceInvoker.java
URL: http://svn.apache.org/viewvc/incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/engine/ResourceInvoker.java?rev=787557&view=auto
==============================================================================
--- incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/engine/ResourceInvoker.java (added)
+++ incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/engine/ResourceInvoker.java Tue Jun 23 05:41:49 2009
@@ -0,0 +1,374 @@
+/*
+ * 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 com.ibm.ws.jaxrs.engine;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.List;
+
+import javax.ws.rs.HttpMethod;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.ExceptionMapper;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.cxf.jaxrs.model.ClassResourceInfo;
+import org.apache.cxf.jaxrs.model.OperationResourceInfo;
+import org.apache.cxf.jaxrs.model.URITemplate;
+import org.apache.cxf.jaxrs.provider.ProviderFactory;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+
+import com.ibm.ws.jaxrs.context.ContextConstants;
+import com.ibm.ws.jaxrs.context.RESTContext;
+import com.ibm.ws.jaxrs.exception.TargetValidationException;
+import com.ibm.ws.jaxrs.i18n.Messages;
+import com.ibm.ws.jaxrs.integration.OptionsResponseProvider;
+import com.ibm.ws.jaxrs.metadata.RESTMetaData;
+
+/**
+ * This class will be responsible for handling the invocation of a selected
+ * resource, subresource, or subresource locator method. The returned result
+ * will be a RESTContext with updated information.
+ *
+ */
+public class ResourceInvoker {
+
+    private static final Log log = LogFactory.getLog(ResourceInvoker.class);
+
+    /**
+     * This method will drive the invocation of a resource method based on
+     * the supplied resource class instances and the current RESTContext.
+     * The result of invoking this method will be a RESTContext that contains
+     * information for the runtime to build a response.
+     *
+     */
+    public static RESTContext invokeMethod(Object instance, RESTContext context)
+            throws Throwable {
+        OperationResourceInfo opInfo = (OperationResourceInfo) context
+                .getProperty(ContextConstants.OPERATION_RESOURCE);
+        String contentType = (String) context
+                .getProperty(ContextConstants.CONTENT_TYPE);
+        List<MediaType> acceptContentTypes = (List<MediaType>) context
+                .getProperty(ContextConstants.ACCEPT_CONTENT_TYPES);
+        String httpMethod = (String) context
+                .getProperty(ContextConstants.HTTP_METHOD);
+        String pathInfo = (String) context
+                .getProperty(ContextConstants.HTTP_PATH_INFO);
+
+        // handle the case that this is an OPTIONS request to the Resource
+        if (opInfo == null && httpMethod.equalsIgnoreCase("OPTIONS")) {
+            if (log.isDebugEnabled()) {
+                log.debug("Handling options request");
+            }
+            return handleOptionsRequest(context);
+        } else if (opInfo == null) {
+            throw new RuntimeException(Messages.getMessage("methodNotFound",
+                    pathInfo));
+        }
+        
+        List<Object> params = null;
+        try {
+            params = JAXRSUtils.processParameters(opInfo, context);
+        } catch (Throwable t) {
+            return handleReaderException(t, context);
+        }
+
+        Object[] paramArray = params.toArray();
+
+        Method method = opInfo.getMethodToInvoke();
+
+        // only go forward with invocations if this is a public method
+        try {
+            validateMethod(method);
+            if (log.isDebugEnabled()) {
+                log.debug("Invoking Java method: " + method.getName()
+                        + " for HTTP method: " + httpMethod);
+            }
+            // Invoke the resource method
+            Object obj = _invoke(method, instance, paramArray);
+
+            if (log.isDebugEnabled()) {
+                log.debug("Resource method return value: " + obj);
+            }
+
+            RESTMetaData metadata = (RESTMetaData) context
+                    .getProperty(ContextConstants.REST_METADATA);
+            List<ClassResourceInfo> resources = metadata.getClassInfoList();
+
+            // let's do recursion if the operation was a subresource locator
+            if (opInfo.isSubResourceLocator() && obj != null) {
+                ClassResourceInfo newResource = JAXRSUtils.getSubResourceInfo(
+                        obj.getClass().getName(), resources);
+                if (newResource == null) {
+                    throw new RuntimeException(Messages
+                            .getMessage("subResourceDataNotFound", obj
+                                    .getClass().getName()));
+                }
+
+                if (log.isDebugEnabled()) {
+                    log
+                            .debug("Subresource locator invocation returned subresource: "
+                                    + obj.getClass().getName());
+                }
+                // store the subresource
+                context.setProperty(ContextConstants.SUB_RESOURCE_INFO,
+                        newResource);
+                context
+                        .setProperty(ContextConstants.SUB_RESOURCE_INSTANCE,
+                                obj);
+                RESTContext responseContext = setupContext(context);
+
+                // a response context was created, which probably means an Options
+                // request was served, we'll just return it now
+                if (responseContext != null) {
+                    return responseContext;
+                }
+                return invokeMethod(obj, context);
+            }
+            RESTContext responseContext = new RESTContext(context, true);
+            // store the needed information on the RESTContext, this info will
+            // be used to build the response
+            responseContext
+                    .setProperty(ContextConstants.INVOCATION_RESULT, obj);
+            responseContext.setProperty(ContextConstants.OPERATION_RESOURCE,
+                    opInfo);
+            responseContext.setProperty(ContextConstants.ACCEPT_CONTENT_TYPES,
+                    acceptContentTypes);
+            responseContext.setProperty(ContextConstants.CONTENT_TYPE,
+                    contentType);
+            return responseContext;
+        } catch (TargetValidationException e) {
+            if (log.isErrorEnabled()) {
+                log.error(Messages.getMessage("methodNotValid", method
+                        .getName(), instance.getClass().getName()), e);
+            }
+            Response resp = Response.status(404).build();
+            RESTContext responseContext = new RESTContext(context, true);
+            responseContext.setProperty(ContextConstants.RESPONSE, resp);
+            return responseContext;
+        }
+    }
+
+    /**
+     * This method will be used to create a response RESTContext in the case
+     * that an error occurred while deserializing an incoming request.
+     */
+    static RESTContext handleReaderException(Throwable t, RESTContext context) throws Throwable {
+        
+        if (log.isErrorEnabled()) {
+            log.error(t.getMessage(), t);
+        }
+        
+        RESTContext responseContext = new RESTContext(context, true);
+        Response response = null;
+
+        ExceptionMapper mapper = ProviderFactory.getInstance(context)
+        .createExceptionMapper(t.getClass(), context);
+
+        // if we find the mapper, let it handle the exception
+        if (mapper != null) {
+            try {
+                response = mapper.toResponse(t);
+            } catch (Throwable th) {
+                if (log.isDebugEnabled()) {
+                    log.debug(mapper.getClass().getName() + ".toResponse(" + t.getClass() + ") threw throwable " + th.getClass().getName() + " with message \"" + th.getMessage() + "\"");
+                }
+                response = Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
+            }
+        } else {
+            if (log.isDebugEnabled()) {
+                log.debug("ExceptionMapper could not be found for the throwable class: " + t.getClass());
+            }
+            throw t;
+        }
+
+        responseContext.setProperty(ContextConstants.RESPONSE, response);
+        responseContext.setProperty(ContextConstants.MAPPED_EXCEPTION,
+                Boolean.TRUE);
+        return responseContext;
+    }
+
+    /**
+     * This method will setup the RESTContext for a recursive call into this
+     * class' 'invokeMethod' method. This will be in charge of updating the
+     * necessary values to reflect the new target of the request.
+     */
+    static RESTContext setupContext(RESTContext context) {
+
+        ClassResourceInfo resource = (ClassResourceInfo) context
+                .getProperty(ContextConstants.SUB_RESOURCE_INFO);
+        // add the resource and its path to our context
+        RESTEngineUtils.addMatchedResource(resource.getServiceClass(), context);
+        if (resource.getPath() != null) {
+            RESTEngineUtils.addMatchedUri(resource.getPath(), context);
+        }
+
+        MultivaluedMap<String, String> values = (MultivaluedMap<String, String>) context
+                .getProperty(ContextConstants.TEMPLATE_VALUES);
+        List<MediaType> acceptContentTypes = (List<MediaType>) context
+                .getProperty(ContextConstants.ACCEPT_CONTENT_TYPES);
+        String httpMethod = (String) context
+                .getProperty(ContextConstants.HTTP_METHOD);
+        String contentType = (String) context
+                .getProperty(ContextConstants.CONTENT_TYPE);
+        String pathInfo = (String) context
+                .getProperty(ContextConstants.HTTP_PATH_INFO);
+
+        OperationResourceInfo opInfo = JAXRSUtils.findTargetMethod(resource,
+                values.getFirst(URITemplate.FINAL_MATCH_GROUP), httpMethod,
+                values, contentType, acceptContentTypes);
+
+        if (opInfo == null && httpMethod.equalsIgnoreCase("OPTIONS")) {
+            if (log.isDebugEnabled()) {
+                log.debug("Handling options request");
+            }
+            return handleOptionsRequest(context);
+        } else if (opInfo == null) {
+            throw new RuntimeException(Messages.getMessage("methodNotFound",
+                    pathInfo));
+        }
+
+        context.setProperty(ContextConstants.OPERATION_RESOURCE, opInfo);
+        RESTEngineUtils.addMatchedUri(JAXRSUtils.getPathForOperation(values
+                .getFirst(URITemplate.FINAL_MATCH_GROUP), pathInfo), context);
+        return null;
+    }
+
+    /**
+     * This method will handle an OPTIONS request when the resource class does not
+     * have a method with an OPTIONS request designator. In this case, we will build
+     * up a response with the appropriate header information based on the resource.
+     *
+     */
+    public static RESTContext handleOptionsRequest(RESTContext context) {
+        if (log.isDebugEnabled()) {
+            log.debug("Handling OPTIONS request");
+        }
+        RESTContext responseContext = new RESTContext(context, true);
+        OptionsResponseProvider respProvider = JAXRSUtils
+                .getOptionsResponseProvider(context);
+        if (respProvider != null) {
+            if (log.isDebugEnabled()) {
+                log.debug("The OptionsResponseProvider "
+                        + respProvider.getClass().getName()
+                        + " is creating a response to the OPTIONS request");
+            }
+            responseContext.setProperty(ContextConstants.INVOCATION_RESULT,
+                    respProvider.createOptionsResponse(context));
+        }
+        return responseContext;
+    }
+
+    /*
+     * Invoke the provided Java method.
+     */
+    private static Object _invoke(Method m, Object inst, Object[] params)
+            throws Throwable {
+        Object obj = null;
+        try {
+            if (log.isDebugEnabled()) {
+                log.debug("Invoking method: " + m.getName() + " on instance: "
+                        + inst);
+                log.debug("Method params: ");
+                for (Class<?> param : m.getParameterTypes()) {
+                    log.debug("paramType: " + param.getName());
+                }
+                if (params != null) {
+                    log.debug("Supplied params: ");
+                    for (Object param : params) {
+                        log.debug("paramType: "
+                                + (param != null ? param.getClass().getName()
+                                        : "<null>"));
+                    }
+                }
+            }
+            if (m.getName().contains("getValueOfHeaderParam")) {
+            System.out.println("MIKE: invoking method: " + m.getDeclaringClass().getName() + "." + m.getName());
+            System.out.println("MIKE: " + params.length);
+            for (int i = 0; i < params.length; i++) {
+                System.out.println("MIKE: " + params[i]);
+            }
+            }
+            obj = m.invoke(inst, params);
+        } catch (Throwable t) {
+            // Check to see if an unchecked Exception was thrown
+            t = getCause(t);
+            throw t;
+        }
+
+        return obj;
+    }
+
+    /**
+     * Helper method to ensure the validity of a method we have targetted for
+     * a particular RESTful request.
+     *
+     */
+    static void validateMethod(Method method) throws Exception {
+
+        // method must be public
+        if (!Modifier.isPublic(method.getModifiers())) {
+            throw new TargetValidationException(Messages.getMessage(
+                    "methodNotPublic", method.getName(), method
+                            .getDeclaringClass().getName()));
+        }
+
+        // now make sure only one @HttpMethod annotation type was found
+        int httpMethodAnnotCount = 0;
+        Annotation[] annotations = method.getAnnotations();
+        for (Annotation annotation : annotations) {
+            HttpMethod httpMethodAnnot = annotation.annotationType()
+                    .getAnnotation(HttpMethod.class);
+            if (httpMethodAnnot != null) {
+                httpMethodAnnotCount++;
+            }
+        }
+        if (httpMethodAnnotCount > 1) {
+            throw new TargetValidationException(Messages.getMessage(
+                    "methodInvalidAnnot00", method.getName(), method
+                            .getDeclaringClass().getName()));
+        }
+    }
+
+    /*
+     * Returns the root cause Exception that should flow
+     * back to the client.
+     */
+    private static Throwable getCause(Throwable t) {
+        Throwable cause = null;
+
+        // Look for a specific cause for this kind of exception
+        if (t instanceof InvocationTargetException) {
+            cause = ((InvocationTargetException) t).getTargetException();
+        }
+
+        // If no specific cause, fall back to the general cause.
+        //if (cause == null) {
+        //    cause = t.getCause();
+        //}
+        return cause != null ? cause : t;
+    }
+
+}

Added: incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/exception/ExceptionUtils.java
URL: http://svn.apache.org/viewvc/incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/exception/ExceptionUtils.java?rev=787557&view=auto
==============================================================================
--- incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/exception/ExceptionUtils.java (added)
+++ incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/exception/ExceptionUtils.java Tue Jun 23 05:41:49 2009
@@ -0,0 +1,62 @@
+/*
+ * 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 com.ibm.ws.jaxrs.exception;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.ExceptionMapper;
+
+import org.apache.cxf.jaxrs.provider.ProviderFactory;
+
+import com.ibm.ws.jaxrs.context.RESTContext;
+import com.ibm.ws.jaxrs.context.RESTContextFactory;
+
+public class ExceptionUtils {
+
+    public static RESTContext processServerException(Throwable t, RESTContext requestCtx) {
+        ExceptionMapper mapper = ProviderFactory.getInstance(requestCtx)
+                .createExceptionMapper(t.getClass(), requestCtx);
+
+        if (mapper != null) {
+            Response response = null;
+            try {
+                response = mapper.toResponse(t);
+            } catch (RuntimeException e) {
+                // TODO: determine in spec if need to catch errors as well
+                // TODO: should log that the mapper threw an exception
+                response = Response.serverError().build();
+            }
+            RESTContext responseCtx = RESTContextFactory.createResponseContext(
+                    requestCtx, response);
+            return responseCtx;
+        } else if (WebApplicationException.class.isAssignableFrom(t.getClass())) {
+            // If we have a WebApplicationException, let's get the necessary
+            // content and get back on the response path.
+            WebApplicationException wae = (WebApplicationException) t;
+            RESTContext responseCtx = RESTContextFactory
+                    .createFaultResponseContext(wae, requestCtx);
+            return responseCtx;
+        } else {
+            //TODO: There should be a better way to handle this scenario.
+            return null;
+        }
+    }
+
+}

Added: incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/exception/TargetValidationException.java
URL: http://svn.apache.org/viewvc/incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/exception/TargetValidationException.java?rev=787557&view=auto
==============================================================================
--- incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/exception/TargetValidationException.java (added)
+++ incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/exception/TargetValidationException.java Tue Jun 23 05:41:49 2009
@@ -0,0 +1,47 @@
+/*
+ * 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 com.ibm.ws.jaxrs.exception;
+
+/**
+ * Custom exception class used during validation of a targetted method
+ * for a RESTful request.
+ *
+ */
+public class TargetValidationException extends Exception {
+
+    private static final long serialVersionUID = -198116800601836710L;
+
+    public TargetValidationException() {
+        super();
+    }
+
+    public TargetValidationException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public TargetValidationException(String message) {
+        super(message);
+    }
+
+    public TargetValidationException(Throwable cause) {
+        super(cause);
+    }
+
+}

Added: incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/ext/ProvidersImpl.java
URL: http://svn.apache.org/viewvc/incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/ext/ProvidersImpl.java?rev=787557&view=auto
==============================================================================
--- incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/ext/ProvidersImpl.java (added)
+++ incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/ext/ProvidersImpl.java Tue Jun 23 05:41:49 2009
@@ -0,0 +1,94 @@
+/*
+ * 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 com.ibm.ws.jaxrs.ext;
+
+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.apache.cxf.jaxrs.provider.ProviderFactory;
+
+import com.ibm.ws.jaxrs.context.RESTContext;
+
+/**
+ * This class will be our implementation of the Providers interface.
+ * It will provide information about the registered Providers to callers.
+ *
+ */
+public class ProvidersImpl implements Providers {
+
+    private ProviderFactory factory;
+
+    private RESTContext context;
+
+    public ProvidersImpl(RESTContext context) {
+        this.context = context;
+        factory = ProviderFactory.getInstance(context);
+    }
+
+    ProviderFactory getProviderFactory() {
+        return factory;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see javax.ws.rs.ext.Providers#getContextResolver(Class<T>, MediaType)
+     */
+    public <T> ContextResolver<T> getContextResolver(Class<T> contextClass, MediaType mediaType) {
+        return factory.createContextResolver(contextClass, mediaType, context);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see javax.ws.rs.ext.Providers#getExceptionMapper(Class<T>)
+     */
+    public <T extends Throwable> ExceptionMapper<T> getExceptionMapper(Class<T> exceptionClass) {
+        return factory.createExceptionMapper(exceptionClass, context);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see javax.ws.rs.ext.Providers#getMessageBodyReader(Class<T>, Type, Annotation[], MediaType)
+     */
+    public <T> MessageBodyReader<T> getMessageBodyReader(Class<T> bodyType, Type parameterType, Annotation[] parameterAnnotations, MediaType mediaType) {
+        return factory.createMessageBodyReader(bodyType, parameterType,
+                parameterAnnotations, mediaType, context);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see javax.ws.rs.ext.Providers#getMessageBodyWriter(Class<T>, Type, Annotation[], MediaType)
+     */
+    public <T> MessageBodyWriter<T> getMessageBodyWriter(Class<T> bodyType, Type parameterType, Annotation[] parameterAnnotations, MediaType mediaType) {
+        return factory.createMessageBodyWriter(bodyType, parameterType,
+                parameterAnnotations, mediaType, context);
+    }
+
+}

Added: incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/ext/RuntimeDelegateImpl.java
URL: http://svn.apache.org/viewvc/incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/ext/RuntimeDelegateImpl.java?rev=787557&view=auto
==============================================================================
--- incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/ext/RuntimeDelegateImpl.java (added)
+++ incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/ext/RuntimeDelegateImpl.java Tue Jun 23 05:41:49 2009
@@ -0,0 +1,84 @@
+/*
+ * 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 com.ibm.ws.jaxrs.ext;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.CacheControl;
+import javax.ws.rs.core.Cookie;
+import javax.ws.rs.core.EntityTag;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.NewCookie;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.Response.ResponseBuilder;
+import javax.ws.rs.core.Variant.VariantListBuilder;
+import javax.ws.rs.ext.RuntimeDelegate;
+
+import org.apache.cxf.jaxrs.impl.CacheControlHeaderProvider;
+import org.apache.cxf.jaxrs.impl.CookieHeaderProvider;
+import org.apache.cxf.jaxrs.impl.EntityTagHeaderProvider;
+import org.apache.cxf.jaxrs.impl.MediaTypeHeaderProvider;
+import org.apache.cxf.jaxrs.impl.NewCookieHeaderProvider;
+import org.apache.cxf.jaxrs.impl.ResponseBuilderImpl;
+import org.apache.cxf.jaxrs.impl.UriBuilderImpl;
+import org.apache.cxf.jaxrs.impl.VariantListBuilderImpl;
+
+public class RuntimeDelegateImpl extends RuntimeDelegate {
+
+    protected Map<Class, HeaderDelegate> headerProviders = new HashMap<Class, HeaderDelegate>();
+
+    public RuntimeDelegateImpl() {
+        headerProviders.put(MediaType.class, new MediaTypeHeaderProvider());
+        headerProviders.put(CacheControl.class,
+                new CacheControlHeaderProvider());
+        headerProviders.put(EntityTag.class, new EntityTagHeaderProvider());
+        headerProviders.put(Cookie.class, new CookieHeaderProvider());
+        headerProviders.put(NewCookie.class, new NewCookieHeaderProvider());
+    }
+
+    @Override
+    public <T> T createEndpoint(Application arg0, Class<T> arg1)
+            throws IllegalArgumentException, UnsupportedOperationException {
+        return null;
+    }
+
+    @Override
+    public <T> HeaderDelegate<T> createHeaderDelegate(Class<T> type) {
+        return headerProviders.get(type);
+    }
+
+    @Override
+    public ResponseBuilder createResponseBuilder() {
+        return new ResponseBuilderImpl();
+    }
+
+    @Override
+    public UriBuilder createUriBuilder() {
+        return new UriBuilderImpl();
+    }
+
+    @Override
+    public VariantListBuilder createVariantListBuilder() {
+        return new VariantListBuilderImpl();
+    }
+
+}

Added: incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/handler/HandlerFactory.java
URL: http://svn.apache.org/viewvc/incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/handler/HandlerFactory.java?rev=787557&view=auto
==============================================================================
--- incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/handler/HandlerFactory.java (added)
+++ incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/handler/HandlerFactory.java Tue Jun 23 05:41:49 2009
@@ -0,0 +1,124 @@
+/*
+ * 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 com.ibm.ws.jaxrs.handler;
+
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.ibm.ws.jaxrs.handler.internal.ContextValidator;
+import com.ibm.ws.jaxrs.handler.internal.HTTPMethodOverrideHandler;
+import com.ibm.ws.jaxrs.handler.internal.MetadataLocator;
+import com.ibm.ws.jaxrs.handler.internal.ResourceSelector;
+import com.ibm.ws.jaxrs.handler.internal.ResponseHandler;
+
+/**
+ * This is a factory to register RESTHandler instances that will be used
+ * by the engine on incoming and outgoing messages.
+ *
+ */
+public class HandlerFactory {
+
+    private static Log log = LogFactory.getLog(HandlerFactory.class);
+
+    private static final SortedSet<RESTSystemHandler> systemInboundHandlers = new TreeSet<RESTSystemHandler>(
+            new SystemHandlerComparator(true));
+
+    private static final SortedSet<RESTSystemHandler> systemOutboundHandlers = new TreeSet<RESTSystemHandler>(
+            new SystemHandlerComparator(false));
+
+    private static final Map<String, RESTHandler> handlerMap = new HashMap<String, RESTHandler>();
+
+    static {
+        systemInboundHandlers.add(new ContextValidator());
+        systemInboundHandlers.add(new MetadataLocator());
+        systemInboundHandlers.add(new ResourceSelector());
+        systemInboundHandlers.add(new HTTPMethodOverrideHandler());
+        systemOutboundHandlers.add(new ResponseHandler());
+    }
+
+    public static SortedSet<RESTSystemHandler> getSystemInboundHandlers() {
+        return systemInboundHandlers;
+    }
+
+    public static SortedSet<RESTSystemHandler> getSystemOutboundHandlers() {
+        return systemOutboundHandlers;
+    }
+
+    public static Iterator<RESTHandler> getHandlers() {
+        return handlerMap.values().iterator();
+    }
+
+    /**
+     * This method will add a RESTHandler implementation to the list of handlers known to the runtime.
+     */
+    public static void addHandler(RESTHandler handler) {
+        if (handler instanceof RESTSystemHandler) {
+            if (log.isDebugEnabled()) {
+                log.debug("Adding RESTSystemHandler implementation: "
+                        + handler.getClass().getName());
+            }
+            systemInboundHandlers.add((RESTSystemHandler) handler);
+            systemOutboundHandlers.add((RESTSystemHandler) handler);
+        } else {
+            if (log.isDebugEnabled()) {
+                log.debug("Adding RESTHandler implementation: "
+                        + handler.getClass().getName());
+            }
+            handlerMap.put(handler.getClass().getName(), handler);
+        }
+    }
+
+    static class SystemHandlerComparator implements Comparator<RESTSystemHandler> {
+
+        private boolean isInbound;
+
+        public SystemHandlerComparator(boolean isInbound) {
+            this.isInbound = isInbound;
+        }
+
+        /**
+         * This compares two RESTSystemHandler instances by using the getPriority() method.
+         */
+        public int compare(RESTSystemHandler object1, RESTSystemHandler object2) {
+            int o1priority = isInbound ? object1.getInboundPriority() : object1
+                    .getOutboundPriority();
+            int o2priority = isInbound ? object2.getInboundPriority() : object2
+                    .getOutboundPriority();
+
+            if (o1priority < o2priority) {
+                return -1;
+            } else if (o1priority > o2priority) {
+                return 1;
+            }
+
+            // default to the > case
+            return 1;
+        }
+
+    }
+
+}

Added: incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/handler/RESTHandler.java
URL: http://svn.apache.org/viewvc/incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/handler/RESTHandler.java?rev=787557&view=auto
==============================================================================
--- incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/handler/RESTHandler.java (added)
+++ incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/handler/RESTHandler.java Tue Jun 23 05:41:49 2009
@@ -0,0 +1,33 @@
+/*
+ * 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 com.ibm.ws.jaxrs.handler;
+
+import com.ibm.ws.jaxrs.context.RESTContext;
+
+/**
+ * This interface describes handlers that will be invoked by the
+ * RESTEngine for an incoming request and outgoing response.
+ *
+ */
+public interface RESTHandler {
+
+    public void invoke(RESTContext context) throws Exception;
+
+}

Added: incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/handler/RESTSystemHandler.java
URL: http://svn.apache.org/viewvc/incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/handler/RESTSystemHandler.java?rev=787557&view=auto
==============================================================================
--- incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/handler/RESTSystemHandler.java (added)
+++ incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/handler/RESTSystemHandler.java Tue Jun 23 05:41:49 2009
@@ -0,0 +1,33 @@
+/*
+ * 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 com.ibm.ws.jaxrs.handler;
+
+/**
+ * This describes a handler that will be internally implemented by
+ * our JAX-RS runtime.
+ *
+ */
+public interface RESTSystemHandler extends RESTHandler {
+
+    public int getInboundPriority();
+
+    public int getOutboundPriority();
+
+}

Added: incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/handler/internal/ContextValidator.java
URL: http://svn.apache.org/viewvc/incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/handler/internal/ContextValidator.java?rev=787557&view=auto
==============================================================================
--- incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/handler/internal/ContextValidator.java (added)
+++ incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/handler/internal/ContextValidator.java Tue Jun 23 05:41:49 2009
@@ -0,0 +1,172 @@
+/*
+ * 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 com.ibm.ws.jaxrs.handler.internal;
+
+import java.io.OutputStream;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.ibm.ws.jaxrs.context.ContextConstants;
+import com.ibm.ws.jaxrs.context.RESTContext;
+import com.ibm.ws.jaxrs.engine.RESTConstants;
+import com.ibm.ws.jaxrs.handler.RESTSystemHandler;
+import com.ibm.ws.jaxrs.i18n.Messages;
+
+/**
+ * This is a system handler that will validate a RESTContext for an
+ * incoming request.
+ *
+ */
+public class ContextValidator implements RESTSystemHandler {
+
+    private static final Log log = LogFactory.getLog(ContextValidator.class);
+
+    /**
+     * Indicate that this should be at the front of the line by giving
+     * the priority of '0'.
+     */
+    public int getInboundPriority() {
+        return 0;
+    }
+
+    /**
+     * This handler will not run on the outbound flow.
+     */
+    public int getOutboundPriority() {
+        return Integer.MAX_VALUE;
+    }
+
+    /**
+     * This method will validate an incoming RESTContext to ensure all the
+     * needed information is available to the runtime. If essential information
+     * is missing, an IllegalArgumentException will be thrown.
+     */
+    public void invoke(RESTContext context) throws Exception {
+        if (log.isDebugEnabled()) {
+            log.debug("ContextValidator.invoke(): entry");
+        }
+
+        String flow = (String) context
+                .getProperty(ContextConstants.MESSAGE_FLOW);
+
+        // only proceed if this is the inbound flow
+        if (RESTConstants.MESSAGE_FLOW_INBOUND.equals(flow)) {
+            // obviously if we don't have properites we will want to throw an exception
+            if (context.getProperties() == null
+                    || context.getProperties().isEmpty()) {
+                throw new IllegalArgumentException(Messages
+                        .getMessage("inboundContextFail00"));
+            }
+
+            // let's make sure the path was supplied, or we can determine it
+            String pathInfo = (String) context
+                    .getProperty(ContextConstants.HTTP_PATH_INFO);
+
+            // if the path info is not supplied, let's try to derive it by using the full
+            // request URL and the context path
+            if (pathInfo == null || "".equals(pathInfo)) {
+                String requestURL = (String) context
+                        .getProperty(ContextConstants.HTTP_REQUEST_URL);
+                String contextPath = (String) context
+                        .getProperty(ContextConstants.HTTP_REQUEST_CONTEXT_PATH);
+                if (requestURL == null || "".equals(requestURL)
+                        || contextPath == null) {
+                    throw new IllegalArgumentException(Messages
+                            .getMessage("inboundContextFail01"));
+                }
+
+                if (requestURL.indexOf(contextPath) == -1) {
+                    throw new IllegalArgumentException(Messages
+                            .getMessage("inboundContextFail01"));
+                }
+
+                if (requestURL.endsWith(contextPath)) {
+                    pathInfo = "";
+                } else {
+                    pathInfo = requestURL.substring(requestURL
+                            .indexOf(contextPath)
+                            + contextPath.length() + 1);
+                }
+
+                if (pathInfo != null && !pathInfo.startsWith("/")) {
+                    pathInfo = "/" + pathInfo;
+                }
+                if (log.isDebugEnabled()) {
+                    log.debug("Path information for request set to " + pathInfo
+                            + " by using the " + "request URL: " + requestURL
+                            + " and context path: " + contextPath);
+                }
+                context.setProperty(ContextConstants.HTTP_PATH_INFO, pathInfo);
+
+            }
+
+            // make sure the HTTP method is set
+            String httpMethod = (String) context
+                    .getProperty(ContextConstants.HTTP_METHOD);
+            if (httpMethod == null) {
+                throw new IllegalArgumentException(Messages
+                        .getMessage("inboundContextFail02"));
+            }
+
+            // make sure an OutputStream is available for the response
+            OutputStream os = (OutputStream) context
+                    .getProperty(ContextConstants.RESPONSE_OUTPUT_STREAM);
+            if (os == null) {
+                throw new IllegalArgumentException(Messages
+                        .getMessage("inboundContextFail03"));
+            }
+
+            // make sure request URL is set
+            String requestURL = (String) context
+                    .getProperty(ContextConstants.HTTP_REQUEST_URL);
+            if (requestURL == null) {
+                throw new IllegalArgumentException(Messages
+                        .getMessage("inboundContextFail04"));
+            }
+
+            // if the context classloader was not set, set it now to the thread's classloader
+            if (context.getProperty(ContextConstants.CONTEXT_CLASSLOADER) == null) {
+                if (log.isDebugEnabled()) {
+                    log
+                            .debug("Classloader not set on RESTContext, initializing to the "
+                                    + "thread's context classloader");
+                }
+                context.setProperty(ContextConstants.CONTEXT_CLASSLOADER,
+                        Thread.currentThread().getContextClassLoader());
+            }
+
+            if (context
+                    .getProperty(ContextConstants.INTEGRATION_REGISTRATION_KEY) == null) {
+                if (log.isDebugEnabled()) {
+                    log
+                            .debug("Integration registration key is not set on RESTContext");
+                }
+                throw new IllegalArgumentException(Messages
+                        .getMessage("inboundContextFail05"));
+            }
+        }
+
+        if (log.isDebugEnabled()) {
+            log.debug("ContextValidator.invoke(): exit");
+        }
+    }
+
+}

Added: incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/handler/internal/HTTPMethodOverrideHandler.java
URL: http://svn.apache.org/viewvc/incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/handler/internal/HTTPMethodOverrideHandler.java?rev=787557&view=auto
==============================================================================
--- incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/handler/internal/HTTPMethodOverrideHandler.java (added)
+++ incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/handler/internal/HTTPMethodOverrideHandler.java Tue Jun 23 05:41:49 2009
@@ -0,0 +1,108 @@
+/*
+ * 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 com.ibm.ws.jaxrs.handler.internal;
+
+import javax.ws.rs.core.MultivaluedMap;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.ibm.ws.jaxrs.context.ContextConstants;
+import com.ibm.ws.jaxrs.context.RESTContext;
+import com.ibm.ws.jaxrs.engine.RESTConfig;
+import com.ibm.ws.jaxrs.engine.RESTConstants;
+import com.ibm.ws.jaxrs.handler.RESTSystemHandler;
+
+public class HTTPMethodOverrideHandler implements RESTSystemHandler {
+
+    private static final Log log = LogFactory
+            .getLog(HTTPMethodOverrideHandler.class);
+
+    public int getInboundPriority() {
+        return 2;
+    }
+
+    public int getOutboundPriority() {
+        return Integer.MAX_VALUE;
+    }
+
+    public void invoke(RESTContext context) throws Exception {
+        if (log.isDebugEnabled()) {
+            log.debug("HTTPMethodOverrideHandler.invoke(): entry");
+        }
+
+        String flow = (String) context
+                .getProperty(ContextConstants.MESSAGE_FLOW);
+
+        // only operate on inbound messages
+        if (RESTConstants.MESSAGE_FLOW_INBOUND.equals(flow)) {
+            boolean isEnabled = Boolean.valueOf(
+                    RESTConfig.getPropertyValue(
+                            RESTConfig.HTTP_METHOD_OVERRIDE_CONFIG, context))
+                    .booleanValue();
+
+            if (log.isDebugEnabled()) {
+                log.debug("HTTPMethodOverrideHandler is enabled:" + isEnabled);
+            }
+            if (isEnabled) {
+                MultivaluedMap<String, String> headers = (MultivaluedMap<String, String>) context
+                        .getProperty(ContextConstants.HTTP_HEADER_VALUES);
+                if (headers != null) {
+                    String httpMethodOverride = headers
+                            .getFirst("x-http-method-override");
+
+                    if (log.isDebugEnabled()) {
+                        log
+                                .debug("X-HTTP-Method-Override Request Header Value: "
+                                        + httpMethodOverride);
+                    }
+                    if (httpMethodOverride != null) {
+                        context.setProperty(ContextConstants.HTTP_METHOD,
+                                httpMethodOverride.toUpperCase());
+                    } else {
+                        httpMethodOverride = headers
+                                .getFirst("x-method-override");
+
+                        if (log.isDebugEnabled()) {
+                            log
+                                    .debug("X-Method-Override Request Header Value: "
+                                            + httpMethodOverride);
+                        }
+                        if (httpMethodOverride != null) {
+                            context.setProperty(ContextConstants.HTTP_METHOD,
+                                    httpMethodOverride.toUpperCase());
+                        }
+                    }
+                }
+
+                if (log.isDebugEnabled()) {
+                    log
+                            .debug("HTTP Method is now: "
+                                    + context
+                                            .getProperty(ContextConstants.HTTP_METHOD));
+                }
+            }
+        }
+
+        if (log.isDebugEnabled()) {
+            log.debug("HTTPMethodOverrideHandler.invoke(): exit");
+        }
+    }
+}

Added: incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/handler/internal/MetadataLocator.java
URL: http://svn.apache.org/viewvc/incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/handler/internal/MetadataLocator.java?rev=787557&view=auto
==============================================================================
--- incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/handler/internal/MetadataLocator.java (added)
+++ incubator/wink/contrib/ibm-jaxrs/src/com/ibm/ws/jaxrs/handler/internal/MetadataLocator.java Tue Jun 23 05:41:49 2009
@@ -0,0 +1,199 @@
+/*
+ * 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 com.ibm.ws.jaxrs.handler.internal;
+
+import java.net.URL;
+import java.util.List;
+
+import javax.ws.rs.core.Application;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.ibm.ws.jaxrs.context.ContextConstants;
+import com.ibm.ws.jaxrs.context.RESTContext;
+import com.ibm.ws.jaxrs.engine.RESTConstants;
+import com.ibm.ws.jaxrs.handler.RESTSystemHandler;
+import com.ibm.ws.jaxrs.i18n.Messages;
+import com.ibm.ws.jaxrs.integration.ApplicationProvider;
+import com.ibm.ws.jaxrs.integration.IntegrationRegistry;
+import com.ibm.ws.jaxrs.integration.MetaDataProvider;
+import com.ibm.ws.jaxrs.metadata.RESTMetaData;
+import com.ibm.ws.jaxrs.model.ApplicationProcessor;
+import com.ibm.ws.jaxrs.model.JAXRSInfoOutput;
+
+/**
+ * This is a system handler that will be responsible for retrieving and building the metadata.
+ *
+ */
+public class MetadataLocator implements RESTSystemHandler {
+
+    private static final Log log = LogFactory.getLog(MetadataLocator.class);
+
+    public int getInboundPriority() {
+        return 1;
+    }
+
+    /**
+     * This handler will not run on the outbound flow.
+     */
+    public int getOutboundPriority() {
+        return Integer.MAX_VALUE;
+    }
+
+    /**
+     * This method will build or retrieve the metadata for the current request.
+     * If a key is supplied on the RESTContext, and metadata is found by that
+     * key, we will use that metadata. Otherwise, metadata will be built and
+     * stored on the RESTContext.
+     *
+     */
+    public void invoke(RESTContext context) throws Exception {
+        if (log.isDebugEnabled()) {
+            log.debug("MetadataLocator.invoke(): entry");
+        }
+
+        String flow = (String) context
+                .getProperty(ContextConstants.MESSAGE_FLOW);
+
+        // only operate on inbound messages
+        if (RESTConstants.MESSAGE_FLOW_INBOUND.equals(flow)) {
+            RESTMetaData metaData = null;
+
+            // first retrieve the cache key and provider
+            String metadataKey = (String) context
+                    .getProperty(ContextConstants.METADATA_KEY);
+            MetaDataProvider cacheProvider = (MetaDataProvider) IntegrationRegistry
+                    .getIntegrationProvider(
+                            context
+                                    .getProperty(ContextConstants.INTEGRATION_REGISTRATION_KEY),
+                            MetaDataProvider.class);
+
+            if (cacheProvider != null && metadataKey != null) {
+                if (log.isDebugEnabled()) {
+                    log
+                            .debug("Calling the "
+                                    + cacheProvider.getClass().getName()
+                                    + " MetadataCacheProvider with key: "
+                                    + metadataKey);
+                }
+
+                metaData = cacheProvider.getRESTMetaData(metadataKey);
+                if (metaData == null) {
+                    if (log.isDebugEnabled()) {
+                        log
+                                .debug("RESTMetaData not found in cache by the key: "
+                                        + metadataKey);
+                    }
+                    metaData = cacheProvider.buildRESTMetaData(metadataKey,
+                            context);
+                } else {
+                    if (log.isDebugEnabled()) {
+                        log.debug("RESTMetaData found in cache by the key: "
+                                + metadataKey);
+                    }
+                }
+            } else {
+                // if thre is no cache provider, we'll always build the metadata
+                // XXX: this isn't what you want to do.  if the metadata isn't cached, there is no guarantee
+                // of singletons being instantiated only once
+                metaData = buildMetaData(context);
+            }
+
+            if (metaData == null) {
+                throw new RuntimeException(Messages.getMessage(
+                        "invalidMetaData00", (String) context
+                                .getProperty(ContextConstants.HTTP_PATH_INFO)));
+            }
+
+            context.setProperty(ContextConstants.REST_METADATA, metaData);
+        }
+
+        if (log.isDebugEnabled()) {
+            log.debug("MetadataLocator.invoke(): exit");
+        }
+    }
+
+    /**
+     * This method will be responsible for driving the calls to build up an instance
+     * of RESTMetaData for the current request.
+     *
+     */
+    RESTMetaData buildMetaData(RESTContext context) throws Exception {
+        RESTMetaData metaData = new RESTMetaData();
+
+        // we need to get an ApplicationProvider so we know the source of the metadata
+        ApplicationProvider appProvider = (ApplicationProvider) IntegrationRegistry
+                .getIntegrationProvider(
+                        context
+                                .getProperty(ContextConstants.INTEGRATION_REGISTRATION_KEY),
+                        ApplicationProvider.class);
+        if (appProvider == null) {
+            throw new RuntimeException(Messages.getMessage("invalidMetaData00",
+                    (String) context
+                            .getProperty(ContextConstants.HTTP_PATH_INFO)));
+        }
+
+        List<Application> applications = appProvider
+                .getApplicationClasses(context);
+
+        URL configURL = (URL) context
+                .getProperty(ContextConstants.CONFIG_FILE_URL);
+
+        ClassLoader classLoader = (ClassLoader) context
+                .getProperty(ContextConstants.CONTEXT_CLASSLOADER);
+
+        // list must be non-null and non-empty
+        if ((applications == null || applications.isEmpty())
+                && configURL == null) {
+            throw new IllegalArgumentException(Messages.getMessage(
+                    "invalidMetaData01", appProvider.getClass().getName()));
+        }
+
+        if (applications != null && !applications.isEmpty()) {
+            for (Application application : applications) {
+                createMetadata(application, configURL, classLoader, metaData);
+            }
+        } else {
+            createMetadata(null, configURL, classLoader, metaData);
+        }
+
+        return metaData;
+    }
+
+    /**
+     * Method to drive the building and storing of metadata for the runtime.
+     */
+    void createMetadata(Application application, URL configURL, ClassLoader classLoader, RESTMetaData metaData)
+            throws Exception {
+        ApplicationProcessor processor = new ApplicationProcessor(configURL,
+                classLoader);
+        JAXRSInfoOutput output = processor.processApplication(application);
+
+        // now add both the resource and provider information
+        if (output.getClassInfoList() != null) {
+            metaData.getClassInfoList().addAll(output.getClassInfoList());
+        }
+        if (output.getProviderInfoList() != null) {
+            metaData.getProviderInfoList().addAll(output.getProviderInfoList());
+        }
+    }
+
+}



Mime
View raw message