Using a Parser in your Connector

If your connector extends the base implementation of the IBM® Security Directory Integrator connector (com.ibm.di.connectors.Connector), you can invoke the initParser() method to initialize the associated parser.

  /**
   * Initialize the connector's parser with input and output streams. If the parser
   * has not been loaded then an attempt is made to load it. The input and output objects
   * may be Stream objects (InputStream,OutputStream), java.io.Reader object, String object,
   * java.net.Socket, byte and character array objects.
   * 
   * @param  is  The input object.
   * @param  os  the output object.
   * @exception  Any exception thrown by the parser
   * @see    #getParser
   */
  public void initParser (Object is, Object os) throws Exception;
You have to provide the input and/or output streams the parser will use for its read/write operations. The mode of your connector typically determines which way the flow goes (note that your initialize(Object obj) connector method will have the connector mode in the "obj" object). You are not required to initialize the parser at the time of connector initialization, but you should do so unless there is a good reason to initialize it elsewhere. In any case you should invoke the initParser() method to properly initialize the parser with logging objects, debug flags and other standard IBM Security Directory Integrator objects/behaviors.
The parser can be chosen either by the user or you can hide the parser selection and either provide the configuration in your "tdi.xml" file or programmatically configure the parser in your connector (or both).
  1. Let the user choose the parser.
    In this case you must set the parameter "parserOption" in your connector's "tdi.xml" file to the value "true". Once this field is defined the selection of the parser is delegated to the user through a standard user interface (note that you can prefill the parserConfig section of your tdi.xml file with a default parser). Here is a snippet from the FileSystem connector's "tdi.xml" file showing "parserOption" as "Required", which means the connector requires a parser (that is, an error is thrown if none is defined in the configuration):
    <Connector name="ibmdi.FileSystem">
    	<Configuration>
    	...
    		<parameter name="parserOption">Required</parameter>
    	</Configuration>
    </Connector>
    The value for the "parserOption" parameter can be "Required", "Useless" (no parser allowed) or "Optional".
  2. Use a predefined parser using the "tdi.xml" file.
    You can include the parserConfig section in your "tdi.xml" file if you always use the same parser, for example if you inherit from the CSV Parser:
    <Connector name="myconnector">
    	<Configuration>
    		<parameter name="parserOption">Required</parameter>
    	</Configuration>
    	<Parser>
    		<InheritFrom>system:/Parsers/ibmdi.CSV</InheritFrom>
    		... Optional parameter values to make the parser functional
    	</Parser>
    </Connector>
  3. Configure the parser at run time.
    Your connector has access to the ConnectorConfig object via the Connector.getConfiguration() method. Through the ConnectorConfig object you can obtain the ParserConfig interface object for the connector. Use that object to configure the parser before you invoke the initParser() method:
    import com.ibm.di.config.interfaces.ConnectorConfig;
    
    	public void initialize(Object obj) throws Exception {
    
    		// Check mode
    		String mode = "" + obj;
    		boolean isIterator = mode.equals(ConnectorConfig.ITERATOR_MODE);
    
    		ConnectorConfig cc = (ConnectorConfig)getConfiguration();
    
    		// Get the parser config object
    		ParserConfig parser = cc.getParserConfig();
    
    		// -- use the csv parser and set the column separator parameter
    		parser.setParameter("parserType", "com.ibm.di.parser.CSVParser");
    		parser.setParameter("csvColumnSeparator", "\t");
    
    		if(isIterator)
    			initParser(inputStream, null);
    		else
    			initParser(null, outputStream);
    Once the parser has been initialized you can invoke the readEntry() and writeEntry() methods to translate com.ibm.di.entry.Entry objects to and from the stream format defined by the parser. You typically invoke the readEntry() method in your getNextEntry() method and the writeEntry method from your putEntry method. You obtain the parser interface handle through the getParser() method.
  4. Optional parser and dynamic reinitialization
    If your connector can function with or without a parser you can invoke the hasParser() method to determine whether a parser is configured or not:
    if(hasParser())
    			doSomething();
    If you use multiple instances of the parser during the life time of your connector you should close the parser interface to ensure data is written to the outputstream and that system resources are released. The methods used to re-initialize a parser can differ based on which parser you use but the following method calls should be sufficient for most parsers:
    		// Close parser to release system resources
    		if(getParser() != null)
    			getParser().closeParser();
    
    		// assuming you just got a new input stream ... reinitialize the parser
    		initParser(inputStream, null);
    When your connector is terminated it will automatically invoke the closeParser() method if one is in use by the connector.