Listing of Source cgi/DirectoryListingCGI.javapackage se.entra.phantom.server.http;
import se.entra.phantom.common.LocaleInfo;
import se.entra.phantom.server.FileListContent;
import se.entra.phantom.server.BinaryTrace;
import se.entra.phantom.server.http.HttpSession;
import se.entra.phantom.server.http.HttpResource;
import se.entra.phantom.server.http.IncludeCgiPrintInterface;
import java.io.File;
import java.io.PrintWriter;
import java.io.IOException;
import java.util.Date;
import java.util.Enumeration;
import java.util.Vector;
import org.w3c.dom.Element;
/**
* The <code>DirectoryListingCGI</code> class lists a directory of files
* as specified by the tag element <code>DIR</code> relative the server
* directory (not <code>htdocs</code>).
*
* <p>It also contains a static method that other CGI's may call to produce
* this directory listing depending e.g. of a client certificate that
* implies a private directory on the server for the particular client.
*
* <p>A typical document would look like:
*
* <pre>
* (html)
* (head)
* (meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1")
* (title)Directory listing(/title)
* (style)
* (!--
* td { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 60%; }
* --)
* (/style)
* (body)
* (h2)Directory (%@include cgi="DIRLIST" dirname=1)(/h2)
*
* (table border cellspacing=1 cellpadding=1)
*
* (tr)
* (td bgcolor="#C0C0C0")(b)Name(/b)(/td)
* (td bgcolor="#C0C0C0" align="center")(b)Size(/b)(/td)
* (td bgcolor="#C0C0C0" align="center")(b)Date(/b)(/td)
* (/tr)
*
* (%@include cgi="DIRLIST"
* dir ="."
* fileref ="/download.cgi"
* tr ="(tr)"
* tdparent="(td)(pdir) "
* tddir ="(td)(dir) "
* tdfile ="(td)(file) "
* tdsize ="(td align='right')"
* tddate ="(td)")
*
* (/table)
*
* (/body)
* (/html)
* </pre>
*
* @see se.entra.phantom.server.http.FileDownloadCGI
*/
public class DirectoryListingCGI implements IncludeCgiPrintInterface
{
/**
* Prints the directory listing from the base directory as specified
* by the <b>DIR</b> element. If the current document contains additional
* directory information specified after the "?" of the URL, this will
* be appended to the directory specified by <b>DIR</b>.
*
* <p>If the element <b>DIRNAME=1</b> is specified, the subdirectory name
* specified in the URL as parameter is returned, e.g.
* <code>(h2)Directory (%@include cgi="DIRLIST" dirname=1)(/h2)</code>
*
* <p>The following elements are used to build the table:
*
* <ul>
* <li><b>dir</b> - the root directory for the listing relative the server
* directory.
*
* <li><b>fileref</b> - the base hyperlink for downloading files, e.g.
* /download.cgi will produce
* (a href="/download.cgi?%2Fselectedfile.doc")selectedfile.doc(/a).
*
* <li><b>tr</b> - the tag for each line in the listing, e.g. (tr).
*
* <li><b>tdParent</b> - the tag for parent directory, e.g.
* (td)(img src="images/updir.gif" width=6 height=6
* alt="Parent directory").
* This text will preceed the name of the parent directory.
*
* <li><b>tdDir</b> - the tag for directories, e.g.
* (td)(img src="images/dir.gif" width=6 height=6 alt="Directory").
* This text will preceed the name of the directory.
*
* <li><b>tdFile</b> - the tag for file names, e.g.
* (td)(img src="images/file.gif" width=6 height=6 alt="File").
* This text will preceed the name of the file.
*
* <li><b>tdSize</b> - the tag for size following the file name, e.g. (td align="right").
*
* <li><b>tdDate</b> - the tag for date following the file size, e.g.(td).
* </ul>
*
* @throws IOException for IO errors.
*/
@Override
public void performAction(HttpSession session,
HttpResource resource,
Element element,
PrintWriter out) throws IOException
{
// Perform the listing.
listDirectory(session,element,element.getAttribute("dir"),out);
}
/**
* Prints the directory listing to the print writer. If the
* parameter <code>fileRef</code> is null or empty, no hyperlinks
* for the files will be created.
*/
@SuppressWarnings("deprecation")
public static void listDirectory(HttpSession session,
Element element,
String dir,
PrintWriter out)
{
// Get the HTML variables.
String fileRef=element.getAttribute("fileRef");
String tr =element.getAttribute("tr" );
String tdDir =element.getAttribute("tdDir" );
String tdFile =element.getAttribute("tdFile" );
String tdSize =element.getAttribute("tdSize" );
String tdDate =element.getAttribute("tdDate" );
String dirDown=element.getAttribute("dirDown");
// Get the document base reference for the links.
String baseRef=session.resourceName;
// Get the sub-directory name.
String subDir="";
String params=session.uriParams;
if ( params!=null && params.length()>0 )
{
// Convert to string and make sure it's not trying to
// access something above the root directory.
params=InternetCharacterConversion.urlDecode(params).replace('\\','/');
if ( params.indexOf("/..")<0 )
subDir=params;
}
// Check for special decode of the directory name.
if ( element.getAttribute("dirname").length()>0 )
{
out.println(subDir.length()==0? "/": subDir);
return;
}
// Add the parent directory to table.
if ( subDir.length()>1 )
{
int d=subDir.lastIndexOf('/');
String parent=(d==-1)? "/": subDir.substring(0,d);
if ( parent.length()==0 )
parent="/";
out.println(element.getAttribute("tdParent")
+"<a href=\""+baseRef+"?"+java.net.URLEncoder.encode(parent)+"\">..</a>"
+"</td>"+tdSize+"-</td>"+tdDate+"-</td></tr>");
}
// Build complete directory name.
if ( subDir.length()>0 && !subDir.equals("/") )
{
if ( subDir.charAt(0)!='/' )
dir+="/";
dir+=subDir;
}
// Check that directory spec is OK.
File f=new File(dir);
if ( !f.exists() )
{
out.println(tr+"<td>Directory \""+dir+"\" not found</td></tr>");
return;
}
if ( !f.isDirectory() )
{
out.println(tr+"<td>\""+dir+"\" is not a directory</td></tr>");
return;
}
String [] list=f.list();
if ( list==null )
{
out.println(tr+"<td>\""+dir+"\" is empty</td></tr>");
return;
}
Vector<String> dirs =new Vector<String>();
Vector<String> files=new Vector<String>();
for ( int ii=0, cc=list.length; ii<cc; ++ii )
{
String fn=list[ii];
f=new File(dir+"/"+fn);
if ( !f.exists() )
continue;
if ( f.isDirectory() )
dirs.addElement(fn);
else
files.addElement(fn);
}
// Output the sorted directories.
dirs=FileListContent.sortList(dirs);
for ( Enumeration<String> e=dirs.elements(); e.hasMoreElements(); )
{
// Build the hyperlink.
String fn=e.nextElement();
String sdir=subDir.equals("/")? "/"+fn: subDir+"/"+fn;
String ref=baseRef+"?"+java.net.URLEncoder.encode(sdir);
// Get the date.
f=new File(dir+"/"+fn);
String date="-";
long l=f.lastModified();
if ( l>0 )
{
Date d=new Date(l);
date=InternetCharacterConversion.stringConvertToHTMLString(LocaleInfo.getDate(d)+" "+LocaleInfo.getTimeHourMinute(d));
}
out.println(tr+tdDir+"<a href=\""+ref+"\">"+InternetCharacterConversion.stringConvertToHTMLString(fn)+"</a></td>"+tdSize+"-</td>"+tdDate+date+"</td></tr>");
}
// Output the sorted files.
files=FileListContent.sortList(files);
for ( Enumeration<String> e=files.elements(); e.hasMoreElements(); )
{
// Set the file name and possible hyperlink.
String fn=e.nextElement();
f=new File(dir+"/"+fn);
if ( fileRef!=null && fileRef.length()>0 )
{
if ( dirDown.length()>0 )
{
String fndir=dirDown;
if ( !fndir.endsWith("/") ) fndir+="/";
String sdir=subDir;
if ( sdir.startsWith("/") ) sdir=sdir.substring(1);
if ( !sdir.endsWith ("/") ) sdir+="/";
if ( sdir.equals ("/") ) sdir="";
fn=InternetCharacterConversion.urlDecode(fn).replace('\\','/');
fn="<a href=\""+fndir+sdir+fn+"\">"
+InternetCharacterConversion.stringConvertToHTMLString(fn)+"</a>";
}
else
{
String fndir=subDir.startsWith("/")? subDir: "/"+subDir;
fndir=fndir.equals("/")? "/"+fn: fndir+"/"+fn;
fn="<a href=\""+fileRef+"?"+java.net.URLEncoder.encode(fndir)+"\">"
+InternetCharacterConversion.stringConvertToHTMLString(fn)+"</a>";
}
}
else
fn=InternetCharacterConversion.stringConvertToHTMLString(fn);
// Get the date.
String date="-";
long l=f.lastModified();
if ( l>0 )
{
Date d=new Date(l);
date=InternetCharacterConversion.stringConvertToHTMLString(LocaleInfo.getDate(d)+" "+LocaleInfo.getTimeHourMinute(d));
}
// Get the length.
String length="-";
l=f.length();
if ( l>=0 )
length=BinaryTrace.getThousandFormattedNumber(l);
out.println(tr+tdFile+fn+"</td>"+tdSize+length+"</td>"+tdDate+date+"</td></tr>");
}
}
}