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
015package org.apache.tapestry.engine.encoders;
016
017import org.apache.tapestry.INamespace;
018import org.apache.tapestry.Tapestry;
019import org.apache.tapestry.engine.ServiceEncoder;
020import org.apache.tapestry.engine.ServiceEncoding;
021import org.apache.tapestry.services.ServiceConstants;
022
023/**
024 * A specialized encoder for the {@link org.apache.tapestry.engine.DirectService direct service}
025 *  that encodes the page name and component id path into the servlet path, and encodes the
026 * stateful flag by choosing one of two extensions.
027 * 
028 * @author Howard M. Lewis Ship
029 * @since 4.0
030 */
031public class DirectServiceEncoder implements ServiceEncoder
032{
033    private String _statelessExtension;
034
035    private String _statefulExtension;
036
037    public void encode(ServiceEncoding encoding)
038    {
039        String service = encoding.getParameterValue(ServiceConstants.SERVICE);
040        if (!service.equals(Tapestry.DIRECT_SERVICE))
041            return;
042
043        String pageName = encoding.getParameterValue(ServiceConstants.PAGE);
044
045        // Only handle pages in the application namespace (not from a library).
046
047        if (pageName.indexOf(INamespace.SEPARATOR) >= 0)
048            return;
049
050        String stateful = encoding.getParameterValue(ServiceConstants.SESSION);
051        String componentIdPath = encoding.getParameterValue(ServiceConstants.COMPONENT);
052
053        StringBuffer buffer = new StringBuffer("/");
054        buffer.append(pageName);
055
056        buffer.append(",");
057        buffer.append(componentIdPath);
058
059        buffer.append(".");
060        buffer.append(stateful != null ? _statefulExtension : _statelessExtension);
061
062        encoding.setServletPath(buffer.toString());
063
064        encoding.setParameterValue(ServiceConstants.SERVICE, null);
065        encoding.setParameterValue(ServiceConstants.PAGE, null);
066        encoding.setParameterValue(ServiceConstants.SESSION, null);
067        encoding.setParameterValue(ServiceConstants.COMPONENT, null);
068    }
069
070    public void decode(ServiceEncoding encoding)
071    {
072        String servletPath = encoding.getServletPath();
073
074        int dotx = servletPath.lastIndexOf('.');
075        if (dotx < 0)
076            return;
077
078        String extension = servletPath.substring(dotx + 1);
079
080        if (!(extension.equals(_statefulExtension) || extension.equals(_statelessExtension)))
081            return;
082
083        int commax = servletPath.lastIndexOf(',');
084
085        String pageName = servletPath.substring(1, commax);
086        String componentIdPath = servletPath.substring(commax + 1, dotx);
087
088        encoding.setParameterValue(ServiceConstants.SERVICE, Tapestry.DIRECT_SERVICE);
089        encoding.setParameterValue(ServiceConstants.PAGE, pageName);
090        encoding.setParameterValue(
091                ServiceConstants.SESSION,
092                extension.equals(_statefulExtension) ? "T" : null);
093        encoding.setParameterValue(ServiceConstants.COMPONENT, componentIdPath);
094    }
095
096    public void setStatefulExtension(String statefulExtension)
097    {
098        _statefulExtension = statefulExtension;
099    }
100
101    public void setStatelessExtension(String statelessExtension)
102    {
103        _statelessExtension = statelessExtension;
104    }
105}