package com.ice.jcvsweb.action;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.Globals;
import org.apache.struts.action.RequestProcessor;
import org.apache.struts.config.ActionConfig;
import org.apache.struts.config.ExceptionConfig;
import org.apache.struts.config.ForwardConfig;
import org.apache.struts.config.ModuleConfig;
import org.apache.struts.taglib.html.Constants;
import org.apache.struts.upload.MultipartRequestWrapper;
import org.apache.struts.util.MessageResources;
import org.apache.struts.util.RequestUtils;
public
class JCVSRequestProcessor
extends org.apache.struts.tiles.TilesRequestProcessor
{
private static final boolean DEBUG = false;
private static final int IDX_KEY = 0;
private static final int IDX_VIEW = 1;
private static final int IDX_CMD = 2;
private static final int IDX_REQ = IDX_CMD + 1;
private HashMap cmdMap = null;
public
JCVSRequestProcessor()
{
this.cmdMap = new HashMap( 32 );
// NOTE
// These only apply to "/project/view/command" actions.
//
this.cmdMap.put( "delusergrant", new Integer( 1 ) );
this.cmdMap.put( "delmimetype", new Integer( 1 ) );
this.cmdMap.put( "list", new Integer( 0 ) );
this.cmdMap.put( "diff", new Integer( 2 ) );
this.cmdMap.put( "pdiff", new Integer( 2 ) );
this.cmdMap.put( "view", new Integer( 1 ) );
}
/**
* Identify and return the path component (from the request URI) that
* we will use to select an ActionMapping to dispatch with. If no such
* path can be identified, create an error response and return
* <code>null</code>.
*
* @param request The servlet request we are processing
* @param response The servlet response we are creating
*
* @exception IOException if an input/output error occurs
*/
protected String
processPath( HttpServletRequest request, HttpServletResponse response )
throws IOException
{
String path = request.getServletPath();
String prefix = moduleConfig.getPrefix();
String result = path;
if ( false ) log( "[JCVSReqProc] path '" + path + "'" );
if ( false ) log( "[JCVSReqProc] prefix '" + prefix + "'" );
if ( prefix.length() > 0 && path.startsWith( prefix ) )
{
path = path.substring( prefix.length() );
}
/*
**
//
// JSP Wrapper
//
if ( path.toLowerCase().endsWith( ".jsp" ) )
{
result = "/jsp";
}
**
*/
String[] pathElems = this.splitPathElements( path );
if ( DEBUG )
{
log( "[JCVSReqProc] ServletPath has " + pathElems.length + " elements." );
for ( int i = 0 ; i < pathElems.length ; ++i )
{
log( "[JCVSReqProc] pathElem["+i+"] = '" + pathElems[i] + "'" );
}
}
request.setAttribute( "jcvsPathElems", pathElems );
// NOTE
//
// Commands belong to two general categories, those that
// operate on the CVS working directory, and all the rest.
// We delineate these two categories of commands with the
// number of elements in the path. Those that operate on
// the working directory require at least three elements:
// the key, view, and command. Thus, all paths that have
// at least three elements in them are implicitly CVS
// working directory commands, and all others are not.
//
if ( pathElems.length == 0 )
{
result = "/home";
}
else if ( pathElems.length < IDX_REQ )
{
// NOT CVS working directory commands.
// Some commands must be handled specially, like
// "/img" setting the "imgname" attribute, and "/logo"
// overloading the "/img" command while also setting the
// "imgcat" attribute.
result = "/" + pathElems[0];
if ( "img".equals( pathElems[0] ) )
{
request.setAttribute( "jcvsImgCategory", "" );
}
else if ( "logo".equals( pathElems[0] ) )
{
request.setAttribute( "jcvsImgCategory", "logos" );
}
// NOTE
// Because every "two argument" project command, the project
// key is always located in the second argument. Ergo, if there
// are two arguments, we will just put that key in the proper
// location...
//
String[] cmdArgs = new String[ pathElems.length - 1 ];
if ( pathElems.length > 1 )
{
cmdArgs[0] = pathElems[1];
request.setAttribute( "urlProjectKey", pathElems[1] );
}
request.setAttribute( "jcvsArgs", cmdArgs );
}
else
{
//
// These are "cvs project view commands". They are of the
// form "/key/view/cmd/path/args". The key is the project
// key, the view is the project view (cvs tag), the cmd is
// the CVS command to be performed, the path is the path of
// the command, and args are arguments to the CVS command.
// Set the result to the command. This will select the action.
//
result = "/" + pathElems[ IDX_CMD ]; // UNDONE Inefficient...
request.setAttribute( "urlProjectKey", pathElems[ IDX_KEY ] );
request.setAttribute( "urlProjectView", pathElems[ IDX_VIEW ] );
if ( DEBUG ) log( "[JCVSReqProc] KEY = '"
+ request.getAttribute( "urlProjectKey" ) + "'" );
if ( DEBUG ) log( "[JCVSReqProc] VIEW = '"
+ request.getAttribute( "urlProjectView" ) + "'" );
int numArgs = 0;
Integer argCnt = (Integer) this.cmdMap.get( pathElems[2] );
if ( argCnt != null )
{
numArgs = argCnt.intValue();
}
if ( DEBUG ) log( "[JCVSReqProc] NUMARGS = " + numArgs );
StringBuffer pBuf = new StringBuffer( 128 );
if ( pathElems.length > (numArgs + 3) )
{
for ( int ai = 3 ; ai < (pathElems.length - numArgs) ; ++ai )
{
if ( ai > 3 ) pBuf.append( "/" );
pBuf.append( pathElems[ ai ] );
}
}
if ( DEBUG ) log( "[JCVSReqProc] PATH = '" + pBuf.toString() + "'" );
request.setAttribute( "urlEntryPath", pBuf.toString() );
String[] cmdArgs = new String[ numArgs ];
for ( int ci = 0 ; ci < numArgs ; ++ci )
{
cmdArgs[ ci ] = pathElems[ (pathElems.length - numArgs) + ci ];
if ( DEBUG ) log
( "[JCVSReqProc] ARG["+ci+"] = '" + cmdArgs[ ci ] + "'" );
}
request.setAttribute( "jcvsArgs", cmdArgs );
}
if ( DEBUG ) log( "[JCVSReqProc] result = '" + result + "'" );
return result;
}
protected String[]
splitPathElements( String path )
throws IOException
{
int idx = 0;
int sIdx = 0;
ArrayList elems = new ArrayList();
if ( path.startsWith( "/" ) )
sIdx = 1;
int pLen = path.length();
for ( ; sIdx < pLen ; )
{
idx = path.indexOf( "/", sIdx );
if ( idx == -1 )
break;
if ( idx > sIdx )
{
elems.add( path.substring( sIdx, idx ) );
}
else
{
// Double slashes implies an empty string...
elems.add( "" );
}
sIdx = idx + 1;
}
if ( sIdx < pLen )
{
elems.add( path.substring( sIdx ) );
}
String[] result = new String[ elems.size() ];
elems.toArray( result );
return result;
}
}
|