/*
* Copyright 2000 Draagon Software, Inc. All Rights Reserved.
*
* This software is the proprietary information of Draagon Software, Inc.
* Use is subject to license terms.
*
*/
package com.draagon.wii.streams;
import com.draagon.timers.MethodTimer;
import com.draagon.wii.*;
import java.io.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
// import com.ibm.xml.parser.TXDocument;
// import com.ibm.xml.parser.Parser;
import org.w3c.dom.*;
//import org.xml.sax.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class WIITagStream implements WIIStream
{
private WIIRequest mRequest = null;
// private InputStream mOs = null;
protected boolean mNoParse = false;
private static Log log = LogFactory.getLog( WIITagStream.class );
/**
* Input buffer for decompression.
*/
// protected byte[] buf;
// protected String outbuf = "";
/**
* Length of input buffer.
*/
protected int len = 0;
protected int mark = 0;
// this flag is set to true after EOF has reached
//private boolean reachEOF = false;
public WIITagStream()
{
// buf = new byte[ size ];
}
public void setRequest( WIIRequest req )
{
mRequest = req;
// mOs = req.getExternalInputStream();
}
public WIIRequest getRequest()
{
return mRequest;
}
public String getContentType()
{
return mRequest.getExternalContentType();
}
public void process( WIIResponse res )
throws IOException, WIIException
{
int rc = 0;
if ( getContentType() != null && getContentType().toLowerCase().startsWith( "text" ))
{
if ( log.isDebugEnabled() )
log.debug( "(process) Processing text data: [" + getContentType() + "]: " + mRequest.getPathInfo() );
InputStream is = mRequest.getExternalInputStream();
BufferedReader br = new BufferedReader( new InputStreamReader( is ));
filter( res, br );
}
else
{
if ( log.isDebugEnabled() )
log.debug( "(process) Processing binary data [" + getContentType() + "]: " + mRequest.getPathInfo() );
byte buf[] = new byte[ 4096 ];
OutputStream out = res.getOutputStream();
InputStream is = mRequest.getExternalInputStream();
while(( rc = is.read( buf, 0, 4096 )) >= 0 )
{
if ( rc >= 0 ) out.write( buf, 0, rc );
}
}
}
protected void filter2( WIIResponse res, BufferedReader br )
throws IOException
{
PrintWriter pw = res.getWriter();
String line = br.readLine();
while( line != null )
{
line += "\n";
pw.print( line );
line = br.readLine();
}
}
protected void filter( WIIResponse res, BufferedReader br )
throws IOException
{
PrintWriter pw = res.getWriter();
// int i = 0;
if ( log.isDebugEnabled() )
log.debug( "(filter) Filtering the text body" );
String line = br.readLine();
while( line != null )
{
if ( log.isDebugEnabled() )
log.debug( "(filter) Processing the line" );
line += "\n";
// The no parse variable is used to enhance performance
if ( mNoParse )
{
pw.print( line );
line = br.readLine();
continue;
}
String endtag = null;
String check = null;
boolean start = false;
while( true )
{
if ( !start )
{
int j = line.indexOf( "<wii>" );
if ( j >= 0 )
{
if ( log.isDebugEnabled() )
log.debug( "(filter) <wii> tag found" );
// Send the valid data to the print writer
pw.print( line.substring( 0, j ));
// Tack the rest of the line onto the check string
check = line.substring( j );
endtag = "</wii>";
start = true;
}
else
{
j = line.indexOf( "<wii:" );
if ( j >= 0 )
{
if ( log.isDebugEnabled() )
log.debug( "(filter) <wii: tag start found" );
// Send the valid data to the print writer
pw.print( line.substring( 0, j ));
int jj = line.indexOf( ">", j );
// System.out.println( "1: " + line );
while ( jj < 0 )
{
String tmp = br.readLine();
if ( tmp == null ) return;
line += tmp + "\n";
jj = line.indexOf( ">", j );
}
// System.out.println( "2: " + line );
if ( line.charAt( jj - 1 ) == '/' )
{
if ( log.isDebugEnabled() )
log.debug( "(filter) end of <wii: tag found" );
// Get the rest of the string to be parse
String tmp = line.substring( jj + 1 );
// System.out.println( "3: " + tmp );
// Get the WII XML data
check = line.substring( j, jj + 1 );
// System.out.println( "4: " + check );
// Parse the WII XML data
service( res, check );
// Set line to the remainder
line = tmp;
// System.out.println( "5: " + line );
}
else
{
// Get the XML tag
String tag = line.substring( j, jj + 1 );
// System.out.println( "6: " + tag );
int ws = tag.length() - 1;
// Check for white space
int x = tag.indexOf( ' ' );
if ( x >= 0 && x < ws ) ws = x;
x = tag.indexOf( '\n' );
if ( x >= 0 && x < ws ) ws = x;
x = tag.indexOf( '\r' );
if ( x >= 0 && x < ws ) ws = x;
x = tag.indexOf( '\t' );
if ( x >= 0 && x < ws ) ws = x;
tag = tag.substring( 5, ws );
// System.out.println( "7: " + tag );
// Tack the rest of the line onto the check string
check = line.substring( j );
// System.out.println( "8: " + check );
endtag = "</wii:" + tag + ">";
// System.out.println( "9: " + endtag );
if ( log.isDebugEnabled() )
log.debug( "(filter) Looking for tag: " + endtag );
start = true;
}
}
else
{
// If the start wasn't found, then return the line
pw.print( line );
/*if ( log.isDebugEnabled() )*/ log.debug( ">>> " + line );
break;
}
}
}
if ( start )
{
int j = check.indexOf( endtag );
if ( j >= 0 )
{
if ( log.isDebugEnabled() )
log.debug( "(filter) End tag found: " + endtag );
int len = endtag.length();
// Get the rest of the string to be parse
String tmp = check.substring( j + len );
// System.out.println( "10: " + tmp );
// Get the WII XML data
check = check.substring( 0, j + len );
// System.out.println( "11: " + check );
// Parse the WII XML data
service( res, check );
// Set line to the remainder
line = tmp;
// System.out.println( "12: " + line );
// Now we need to check the rest of the line for new tags
start = false;
}
else
{
line = br.readLine();
if ( line == null ) return;
check += line + "\n";
}
}
}
if ( log.isDebugEnabled() )
log.debug( "(filter) Reading a new line" );
line = br.readLine();
}
}
protected void service( WIIResponse res, String in )
throws IOException
{
PrintWriter pw = res.getWriter();
MethodTimer mt = new MethodTimer( this, "service" );
try {
// fis = new FileInputStream( xmlin);
in = "<?xml version=\"1.0\"?>\n" + in;
//org.apache.xerces.parsers.DOMParser parser = new org.apache.xerces.parsers.DOMParser();
DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
// Parser parser = new Parser( "wii" );
// parser.setDTDHandler( null );
Document doc = null;
try
{
InputStream is = new ByteArrayInputStream( in.getBytes("UTF-8"));
doc = parser.parse( is );
}
catch( Exception e )
{
String msg = "Parsing errors [" + in + "]";
getRequest().logError( "(parse) " + msg, e );
mRequest.getDevice().writeError( mRequest, pw, "SERVICE ERROR", msg );
}
if ( doc == null )
{
String msg = "Document is null [" + in + "]";
// System.err.println("(parse) " + msg );
getRequest().logError( "(parse) " + msg, null );
mRequest.getDevice().writeError( mRequest, pw, "SERVICE ERROR", msg );
}
else
{
if ( doc.getDocumentElement().getNodeName().equals( "wii" ))
{
for( Node kvchild = doc.getDocumentElement().getFirstChild();
kvchild != null;
kvchild = kvchild.getNextSibling())
{
String service = kvchild.getNodeName();
if ( service.equals( "noparse" ))
mNoParse = true;
else if ( kvchild instanceof Element )
callService( service, in, kvchild, res );
}
}
else if ( doc.getDocumentElement().getNodeName().startsWith( "wii:" ))
{
String name = doc.getDocumentElement().getNodeName();
String service = name.substring( 4, name.length() );
// System.out.println( "service: " + service );
if ( service.equals( "noparse" ))
mNoParse = true;
else
callService( service, in, doc.getDocumentElement(), res );
}
else
{
String msg = "Service Parse Error [" + in + "], unknown node [" + doc.getNodeName() + "]";
getRequest().logError( "(WIIServiceStream.parse) " + msg, null );
mt.done();
mRequest.getDevice().writeError( mRequest, pw, "SERVICE ERROR", msg );
}
}
}
catch( Exception e )
{
String msg = "Service Parse Error [" + in + "]";
getRequest().logError( "(WIIServiceStream.parse) " + msg, e );
mt.done();
mRequest.getDevice().writeError( mRequest, pw, "SERVICE ERROR", msg );
}
mt.done();
}
protected void callService( String name, String xml, Node node, WIIResponse res )
throws IOException, WIIException
{
PrintWriter pw = res.getWriter();
WIIService osf = getRequest().getWIIService( name );
// System.out.println( "Service [" + service + "]: " + osf );
if ( osf == null )
{
String msg = "Specified service [" + name + "] was not found";
getRequest().logError( "(callService) " + msg, null );
mRequest.getDevice().writeError( mRequest, pw, "SERVICE ERROR", msg );
}
else
{
try
{
MethodTimer mt = new MethodTimer( osf, "process" );
osf.process( node, res );
mt.done();
}
catch( Exception e )
{
String msg = "Service Parse Error [" + xml + "]";
getRequest().logError( "(callService) " + msg, e );
mRequest.getDevice().writeError( mRequest, pw, "SERVICE ERROR", msg );
}
}
}
}