// IncludeCommand.java
// $Id: IncludeCommand.java,v 1.4 2000/08/16 21:37:47 ylafon Exp $
// (c) COPYRIGHT MIT and INRIA, 1996.
// Please first read the full copyright statement in file COPYRIGHT.html
package org.w3c.jigsaw.ssi.commands;
import java.util.Dictionary;
import java.net.MalformedURLException;
import java.net.URL;
import org.w3c.www.http.HTTP;
import org.w3c.www.http.HttpEntityMessage;
import org.w3c.www.http.HttpMessage;
import org.w3c.www.http.HttpReplyMessage;
import org.w3c.www.http.HttpRequestMessage;
import org.w3c.util.ArrayDictionary;
import org.w3c.jigsaw.http.Reply;
import org.w3c.jigsaw.http.Request;
import org.w3c.tools.resources.Resource;
import org.w3c.tools.resources.ServerInterface;
import org.w3c.jigsaw.ssi.SSIFrame;
/**
* Implementation of the SSI <code>include</code> command. (CGI
* scripts <em>can</em> be included, simply by providing a so-called
* virtual path to a CgiResource).
* @author Antonio Ramirez <anto@mit.edu>
*/
public class IncludeCommand extends BasicCommand {
private final static String NAME = "include" ;
public String getName() { return NAME; }
private static final String[] keys =
{
"virtual",
"file",
"ifheader",
"else"
} ;
public Reply execute(SSIFrame ssiframe,
Request request,
ArrayDictionary parameters,
Dictionary variables)
{
// Get the relevant parameters
Object[] values = parameters.getMany(keys) ;
String targetName = (String) values[0] ;
if(targetName == null)
targetName = (String) values[1] ;
String ifheader = (String) values[2] ;
String alt = (String) values[3] ;
if(targetName == null) return null ; // Nothing to include
if(ifheader != null &&
!request.getOriginal().hasHeader(ifheader)) {
if(alt == null) return null ;
else targetName = alt ;
}
// If we are at an illegal depth, don't include.
Integer depth = (Integer) variables.get("depth") ;
int maxDepth = ((Integer)variables.get("maxDepth")).intValue() ;
if(maxDepth != 0 && depth.intValue()>maxDepth) {
Reply reply = ssiframe
.createCommandReply(request,HTTP.OK) ;
reply.setContent("[recursion depth limit exceeded]") ;
handleSimpleIMS(request,reply) ;
return reply ;
}
Request subReq = null ;
Reply subRep = null ;
try {
// Prepare an internal request
subReq =
prepareRequest(request,
new URL(ssiframe.getURL(request)
, targetName)
.toString(),
variables,
depth) ;
// Obtain a reply for it
subRep =
(Reply) ssiframe.getFileResource().getServer().perform(subReq) ;
// If it has status NOT_MODIFIED, it means the included
// ssiframe was also SSI, and we don't calculate anything
// here.
// Otherwise, see if we can reply NOT_MODIFIED.
if(subRep.getStatus() != HTTP.NOT_MODIFIED) {
long ims = request.getIfModifiedSince() ;
if(ims==-1) {
Long IMS = (Long)
request.getState(STATE_IF_MODIFIED_SINCE) ;
if(IMS != null) ims = IMS.longValue() ;
}
long lmd = subRep.getLastModified() ;
lmd -= lmd % 1000 ; // this is annoying
if(ims != -1 && lmd != -1 && ims>=lmd) {
subRep.setStatus(HTTP.NOT_MODIFIED) ;
//close the stream
subRep.openStream().close();
}
}
return subRep ;
} catch(MalformedURLException ex) {
Reply reply = ssiframe
.createCommandReply(request,HTTP.OK) ;
reply.setContent("[malformed URL]") ;
handleSimpleIMS(request,reply) ;
return reply ;
} catch(Exception ex) {
Reply reply = ssiframe
.createCommandReply(request,HTTP.OK) ;
reply.setContent("[error including: "+targetName+"]") ;
handleSimpleIMS(request,reply) ;
return reply ;
}
}
private Request prepareRequest(Request request,
String url,
Dictionary variables,
Integer depth)
{
Request subReq = (Request) request.getClone() ;
subReq.setURLPath(url) ;
long ims = request.getIfModifiedSince() ;
if(ims != -1) {
subReq.setHeaderValue(Request.H_IF_MODIFIED_SINCE,null) ;
subReq.setState(STATE_IF_MODIFIED_SINCE,
new Long(ims)) ;
}
subReq.setState(SSIFrame.STATE_VARIABLES,
variables) ;
subReq.setState(SSIFrame.STATE_DEPTH,
new Integer(depth.intValue()+1)) ;
return subReq ;
}
public String getValue(Dictionary variables,
String variable,
Request request) {
return "null";
}
}