//
// Copyright (c)1998-2011 Pearson Education, Inc. or its affiliate(s).
// All rights reserved.
//
package openadk.library;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import openadk.library.impl.SIFPullParser;
/**
* Parses a SIF message or Data Object into a SIFElement object graph.<p>
*
* A single instance of SIFParser can be reused by a thread. However, the parse
* method is synchronized for serial access. If multiple threads wish to parse
* messages concurrently a unique SIFParser instance should be allocated to
* each.<p>
*
* @author Eric Petersen
* @version 1.0
*/
public abstract class SIFParser
{
/**
* Flag that indicates that SIFParser should expect a nested SIF_Message
*/
public static final int FLG_EXPECT_INNER_ENVELOPE = 0x00000001;
/**
* Factory method for creatin a new instance of a SIFParser
* @return A SIFParser that can be used for parsing SIF XML
* @throws ADKException If a SIFParser class cannot be instantiated
*/
public static SIFParser newInstance()
throws ADKException
{
String cls = System.getProperty("adkglobal.factory.SIFParser");
if( cls == null || cls.length() == 0 ){
return new SIFPullParser();
}
try
{
return (SIFParser)Class.forName(cls).newInstance();
}
catch( Throwable thr )
{
throw new ADKException("ADK could not create an instance of the class "+cls+": "+thr,null);
}
}
/**
* Parses Xml text into a SIFElement
* @param msg The content to parse
* @return A SIFElement object encapsulating the message payload (e.g.
* a openadk.library.student.StudentPersonal object)
* @throws ADKParsingException is thrown if unable to parse the message
* @throws SIFException is thrown if unable to parse the message
* @throws IOException is thrown if an error is reported while reading the message content
*/
public abstract SIFElement parse( String msg )
throws ADKParsingException,
SIFException,
IOException;
/**
* Parses a SIF data element into a <code>SIFElement</code>.
*
* @param msg The content to parse
* @param zone The Zone from which the message was received, or null if
* not applicable or not known
*
* @return A SIFElement object encapsulating the message payload (e.g.
* a openadk.library.student.StudentPersonal object)
*
* @throws ADKParsingException is thrown if unable to parse the message
* @throws SIFException is thrown if unable to parse the message
* @throws IOException is thrown if an error is reported while reading the message content
*/
public abstract SIFElement parse( String msg, Zone zone )
throws ADKParsingException,
SIFException,
IOException;
/**
* Parses a SIF data element into a <code>SIFElement</code>.
*
* @param msg The content to parse
* @param zone The Zone from which the message was received, or null if
* not applicable or not known
* @param flags One or more <code>FLG_</code> constants, or zero if no
* flags are applicable
* @return A SIFElement object encapsulating the message payload (e.g.
* a openadk.library.student.StudentPersonal object)
*
* @throws ADKParsingException is thrown if unable to parse the message
* @throws SIFException is thrown if unable to parse the message
* @throws IOException is thrown if an error is reported while reading the message content
*/
public abstract SIFElement parse( String msg, Zone zone, int flags )
throws ADKParsingException,
SIFException,
IOException;
/**
* Parses a SIF data element into a <code>SIFElement</code>.
*
* @param msg The content to parse
* @param zone The Zone from which the message was received, or null if
* not applicable or not known
* @param flags One or more <code>FLG_</code> constants, or zero if no
* flags are applicable
* @param version The version of SIF that will be associated with the
* returned object. By default, SIFParser uses the default version of
* SIF in effect for the agent when parsing messages that do not have
* a SIF_Message envelope. By specifying a value to this parameter, you
* can change the version of SIF associated with the returned object in
* the event there is no SIF_Message envelope present in the XML
* content. Note that when parsing XML content with a SIF_Message
* envelope, SIFParser ignores this parameter and instead uses the
* version indicated by the <i>Version</i> and <i>xmlns</i> attributes
*
* @return A SIFElement object encapsulating the message payload (e.g.
* a openadk.library.student.StudentPersonal object)
*
* @throws ADKParsingException is thrown if unable to parse the message
* @throws SIFException is thrown if unable to parse the message
* @throws IOException is thrown if an error is reported while reading the message content
*/
public abstract SIFElement parse( String msg, Zone zone, int flags, SIFVersion version )
throws ADKParsingException,
SIFException,
IOException;
/**
* Parses a SIF data element into a <code>SIFElement</code>.
*
* @param msg The content to parse
* @param zone The Zone from which the message was received, or null if
* not applicable or not known
* @return A SIFElement object encapsulating the message payload (e.g.
* a openadk.library.student.StudentPersonal object)
*
* @throws ADKParsingException is thrown if unable to parse the message
* @throws SIFException is thrown if unable to parse the message
* @throws IOException is thrown if an error is reported while reading the message content
*/
public abstract SIFElement parse( Reader msg, Zone zone )
throws ADKParsingException,
SIFException,
IOException;
/**
* Parses a SIF data element into a <code>SIFElement</code>.
*
* @param msg The content to parse
* @param zone The Zone from which the message was received, or null if
* not applicable or not known
* @param flags One or more <code>FLG_</code> constants, or zero if no
* flags are applicable
* @return A SIFElement object encapsulating the message payload (e.g.
* a openadk.library.student.StudentPersonal object)
*
* @throws ADKParsingException is thrown if unable to parse the message
* @throws SIFException is thrown if unable to parse the message
* @throws IOException is thrown if an error is reported while reading the message content
*/
public abstract SIFElement parse( Reader msg, Zone zone, int flags )
throws ADKParsingException,
SIFException,
IOException;
/**
* Parses a SIF data element into a <code>SIFElement</code>.
*
* @param msg The content to parse
* @param zone The Zone from which the message was received, or null if
* not applicable or not known
* @param flags One or more <code>FLG_</code> constants, or zero if no
* flags are applicable
* @param version The version of SIF that will be associated with the
* returned object. By default, SIFParser uses the default version of
* SIF in effect for the agent when parsing messages that do not have
* a SIF_Message envelope. By specifying a value to this parameter, you
* can change the version of SIF associated with the returned object in
* the event there is no SIF_Message envelope present in the XML
* content. Note that when parsing XML content with a SIF_Message
* envelope, SIFParser ignores this parameter and instead uses the
* version indicated by the <i>Version</i> and <i>xmlns</i> attributes
*
* @return A SIFElement object encapsulating the message payload (e.g.
* a openadk.library.student.StudentPersonal object)
*
* @throws ADKParsingException is thrown if unable to parse the message
* @throws SIFException is thrown if unable to parse the message
* @throws IOException is thrown if an error is reported while reading the message content
*/
public abstract SIFElement parse( Reader msg, Zone zone, int flags, SIFVersion version )
throws ADKParsingException,
SIFException,
IOException;
/**
* Gets the last SIFElement parsed
* @return A SIFElement object encapsulating the message payload (e.g.
* a openadk.library.student.StudentPersonal object). Note
* if the parse method was unsuccessful, the element may be incomplete.
*/
public abstract SIFElement getParsed();
/**
* Run SIFParser as a command-line program. This may be useful to Customer Support
* staff in determining if an arbitrary SIF XML document is invalid from the ADK's
* perspective.<p>
*
* Usage: SIFParser [/v n.n] file<p>
*
* Use the <code>/v</code> option to specify a version of SIF (e.g. "/v 1.5r1").
* Defaults to the latest version of SIF supported by the ADK.
* @param args Command-Line arguments ([/v n.n] file)
*/
public static void main( String[] args )
{
try
{
SIFVersion ver = SIFVersion.LATEST;
String file = null;
for( int i = 0; i < args.length; i++ ) {
if( args[i].charAt(0) == '-' && args[i].length() > 1 ) {
switch( Character.toLowerCase(args[i].charAt(1)) ) {
case 'v':
case 'V': {
if( i+1 != args.length ) {
ver = SIFVersion.parse(args[++i]);
}
}
break;
default: {
file = args[i];
}
}
} else {
file = args[i];
}
}
if( file == null ) {
System.out.println("Usage: SIFParser [/v n.n] file" );
System.out.println(" /v - The version of SIF to use to parse the file (defaults to " + SIFVersion.LATEST + ")" );
System.out.println(" file - The file to parse");
return;
}
ADK.initialize( ver, SIFDTD.SDO_ALL );
System.out.println("Using ADK: " + ADK.getADKVersion() );
System.out.println("Using SIF: " + ADK.getSIFVersion() );
System.out.println("Parsing: " + file + "\r\n" );
SIFParser p = SIFParser.newInstance();
BufferedReader in = new BufferedReader( new FileReader(file) );
p.parse(in,null);
in.close();
}
catch( Exception ex )
{
System.out.println(ex);
}
}
}