001    // Copyright 2005 The Apache Software Foundation
002    //
003    // Licensed under the Apache License, Version 2.0 (the "License");
004    // you may not use this file except in compliance with the License.
005    // You may obtain a copy of the License at
006    //
007    //     http://www.apache.org/licenses/LICENSE-2.0
008    //
009    // Unless required by applicable law or agreed to in writing, software
010    // distributed under the License is distributed on an "AS IS" BASIS,
011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012    // See the License for the specific language governing permissions and
013    // limitations under the License.
014    
015    package org.apache.tapestry.engine.encoders;
016    
017    import org.apache.tapestry.INamespace;
018    import org.apache.tapestry.Tapestry;
019    import org.apache.tapestry.engine.ServiceEncoder;
020    import org.apache.tapestry.engine.ServiceEncoding;
021    import org.apache.tapestry.services.ServiceConstants;
022    
023    /**
024     * A specialized encoder for the
025     * {@link org.apache.tapestry.engine.DirectService direct service}  that
026     * encodes the page name and component id path into the servlet path, and
027     * encodes the stateful flag by choosing one of two extensions.
028     * 
029     * @author Howard M. Lewis Ship
030     * @since 4.0
031     */
032    public class DirectServiceEncoder implements ServiceEncoder
033    {
034    
035        private String _statelessExtension;
036    
037        private String _statefulExtension;
038    
039        public void encode(ServiceEncoding encoding)
040        {
041            String service = encoding.getParameterValue(ServiceConstants.SERVICE);
042            if (!service.equals(Tapestry.DIRECT_SERVICE)) return;
043    
044            String pageName = encoding.getParameterValue(ServiceConstants.PAGE);
045    
046            // Only handle pages in the application namespace (not from a library).
047    
048            if (pageName.indexOf(INamespace.SEPARATOR) >= 0) return;
049    
050            String stateful = encoding.getParameterValue(ServiceConstants.SESSION);
051            String componentIdPath = encoding
052                    .getParameterValue(ServiceConstants.COMPONENT);
053    
054            StringBuffer buffer = new StringBuffer("/");
055            buffer.append(pageName);
056    
057            buffer.append(",");
058            buffer.append(componentIdPath);
059    
060            buffer.append(".");
061            buffer.append(stateful != null ? _statefulExtension
062                    : _statelessExtension);
063    
064            encoding.setServletPath(buffer.toString());
065    
066            encoding.setParameterValue(ServiceConstants.SERVICE, null);
067            encoding.setParameterValue(ServiceConstants.PAGE, null);
068            encoding.setParameterValue(ServiceConstants.SESSION, null);
069            encoding.setParameterValue(ServiceConstants.COMPONENT, null);
070        }
071    
072        public void decode(ServiceEncoding encoding)
073        {
074            String servletPath = encoding.getServletPath();
075    
076            int dotx = servletPath.lastIndexOf('.');
077            if (dotx < 0) return;
078    
079            String extension = servletPath.substring(dotx + 1);
080    
081            if (!(extension.equals(_statefulExtension) || extension
082                    .equals(_statelessExtension))) return;
083    
084            int commax = servletPath.lastIndexOf(',');
085    
086            String pageName = servletPath.substring(1, commax);
087            String componentIdPath = servletPath.substring(commax + 1, dotx);
088    
089            encoding.setParameterValue(ServiceConstants.SERVICE,
090                    Tapestry.DIRECT_SERVICE);
091            encoding.setParameterValue(ServiceConstants.PAGE, pageName);
092            encoding.setParameterValue(ServiceConstants.SESSION, extension
093                    .equals(_statefulExtension) ? "T" : null);
094            encoding.setParameterValue(ServiceConstants.COMPONENT, componentIdPath);
095        }
096    
097        public void setStatefulExtension(String statefulExtension)
098        {
099            _statefulExtension = statefulExtension;
100        }
101    
102        public void setStatelessExtension(String statelessExtension)
103        {
104            _statelessExtension = statelessExtension;
105        }
106    }