001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.chain.web.jakarta.servlet;
018
019import org.apache.commons.chain.Catalog;
020import org.apache.commons.chain.Command;
021import org.apache.commons.chain.Context;
022import org.apache.commons.chain.generic.LookupCommand;
023
024import jakarta.servlet.http.HttpServletRequest;
025
026/**
027 * {@link Command} that uses a specified request parameter
028 * to select a {@link Command} from the appropriate {@link Catalog}, and
029 * execute it. To use this command, you would typically map an instance
030 * of {@link ChainProcessor} to a wildcard pattern like "*.execute" and
031 * then arrange that this is the default command to be executed. In such
032 * an environment, a request for the context-relative path
033 * "/foo.execute?command=bar" would cause the "/bar" command to be loaded
034 * and executed.
035 *
036 * @author Craig R. McClanahan
037 */
038public class RequestParameterMapper extends LookupCommand<ServletWebContext> {
039
040    // ------------------------------------------------------ Instance Variables
041
042    private String catalogKey = ChainProcessor.CATALOG_DEFAULT;
043    private String parameter = "command";
044
045    // ------------------------------------------------------------ Constructors
046
047    /**
048     * The Default-Constructor for this class.
049     */
050    public RequestParameterMapper() {
051    }
052
053    // -------------------------------------------------------------- Properties
054
055    /**
056     * Return the context key under which our {@link Catalog} has been
057     * stored.
058     *
059     * @return The context key for the Catalog.
060     */
061    public String getCatalogKey() {
062        return this.catalogKey;
063    }
064
065    /**
066     * Set the context key under which our {@link Catalog} has been
067     * stored.
068     *
069     * @param catalogKey The new catalog key
070     *
071     * @deprecated Use catalogName to specify the name of the catalog in the
072     *  catalog factory
073     */
074    @Deprecated
075    public void setCatalogKey(String catalogKey) {
076        this.catalogKey = catalogKey;
077    }
078
079    /**
080     * Return the name of the request parameter to use for
081     * selecting the {@link Command} to be executed.
082     *
083     * @return The name of the request parameter.
084     *
085     * @deprecated Use catalogName to specify the name of the catalog in the
086     *  catalog factory
087     */
088    @Deprecated
089    public String getParameter() {
090        return this.parameter;
091    }
092
093    /**
094     * Set the name of the request parameter to use for
095     * selecting the {@link Command} to be executed.
096     *
097     * @param parameter The new parameter name
098     */
099    public void setParameter(String parameter) {
100        this.parameter = parameter;
101    }
102
103    // --------------------------------------------------------- Command Methods
104
105    /**
106     * Look up the specified request parameter for this request, and use it
107     * to select an appropriate {@link Command} to be executed.
108     *
109     * @param context Context for the current request
110     *
111     * @return The name of the {@link Command} instance
112     *
113     * @since Chain 1.2
114     */
115    @Override
116    protected String getCommandName(ServletWebContext context) {
117        // Look up the specified request parameter for this request
118        HttpServletRequest request = context.getRequest();
119        String value = request.getParameter(getParameter());
120        return value;
121    }
122
123    /**
124     * Return the {@link Catalog} to look up the {@link Command} in.
125     *
126     * @param context {@link Context} for this request
127     *
128     * @return The catalog.
129     *
130     * @throws IllegalArgumentException if no {@link Catalog}
131     *         can be found
132     *
133     * @since Chain 1.2
134     */
135    @Override
136    protected Catalog<ServletWebContext> getCatalog(ServletWebContext context) {
137        /* If the object returned from the passed context is not a valid catalog
138         * then we use the super class's catalog extraction logic to pull it
139         * or to error gracefully.
140         */
141        Object testCatalog = context.get(getCatalogKey());
142
143        /* Assume that the underlying implementation is following convention and
144         * returning a catalog with the current context.
145         */
146        @SuppressWarnings("unchecked")
147        Catalog<ServletWebContext> catalog = testCatalog instanceof Catalog
148                    ? (Catalog<ServletWebContext>) testCatalog
149                    : super.getCatalog(context);
150
151        return catalog;
152    }
153}