This example creates an adapter for use as an interface to a message store. It uses the standard Java™ i/o classes to manipulate files in the store.
This example is not meant as a replacement for the adapters that are supplied with MQe, but rather as a simple introduction to creating a message store adapter.
A new class file is constructed, inheriting from MQeAdapter. Some variables are defined to hold this adapter's instance information, such as the name of the file/message and the location of the message store.
public class MyMsgStoreAdapter extends MQeAdapter implements FilenameFilter { protected String filter = ""; /* file type filter */ protected String fileName = ""; /* disk file name */ protected String filePath = ""; /* drive and directory */ protected boolean reading = false; /* opened for reading */ protected boolean writing = false;
public boolean accept( File dir, String name ) { return( name.endsWith( filter )); }
Next the activate method is coded. This is the method that extracts, from the file descriptor, the name of the directory to be used to hold all the messages.
The Object parameter on the method call may be an attribute object. If it is, this is the attribute that is used to encode or decode the messages in the message store.
public void activate( String fileDesc, Object param, Object options, int value1, int value2 ) throws Exception { super.activate( fileDesc, param, options, lrecl, noRec ); filePath = fileId.substring( fileId.indexOf( ':' ) + 1 ); String Temp = filePath; /* copy the path data */ if ( filePath.endsWith( File.separator ) ) /* ending separator ? */ Temp = Temp.substring( 0, Temp.length( ) - File.separator.length( ) ); else filePath = filePath + File.separator; /* add separator */ File diskFile = new File( Temp ); if ( ! diskFile.isDirectory( ) ) /* directory ? */ if ( ! diskFile.mkdirs( ) ) /* does mkDirs work ? */ throw new MQeException( MQe.Except_NotAllowed, "mkdirs '" + filePath + "' failed" ); filePath = diskFile.getAbsolutePath( ) + File.separator; this.open( null ); }
public void close( Object opt ) throws Exception { reading = false; /* not open for reading*/ writing = false; /* not open for writing*/ }
public Object control( Object opt, Object ctrlObj ) throws Exception { if ( checkOption( opt, MQe.MQe_Adapter_LIST ) ) return( new File( filePath ).list( this ) ); else if ( checkOption( opt, MQe.MQe_Adapter_FILTER ) ) { filter = (String) ctrlObj; /* set the filter */ return( null ); /* nothing to return */ } else return( super.control( opt, ctrlObj ) ); /* try ancestor */ }
public void erase( Object opt ) throws Exception { if ( opt instanceof String ) /* select file ? */ { String FN = (String) opt; /* re-type the option */ if ( FN.indexOf( File.separator ) > -1 ) /* directory ? */ throw new MQeException( MQe.Except_Syntax, "Not allowed" ); if ( ! new File( filePath + FN ).delete( ) ) throw new MQeException( MQe.Except_NotAllowed, "Erase failed" ); } else throw new MQeException( MQe.Except_NotSupported, "Not supported" ); }
public void open( Object opt ) throws Exception { this.close( null ); /* close any open file */ fileName = null; /* clear the filename */ if ( opt instanceof String ) /* select new file ? */ fileName = (String) opt; /* retype the name */ reading = checkOption( opt, MQe.MQe_Adapter_READ ) || checkOption( opt, MQe.MQe_Adapter_UPDATE ); writing = checkOption( opt, MQe.MQe_Adapter_WRITE ) || checkOption( opt, MQe.MQe_Adapter_UPDATE ); }
public Object readObject( Object opt ) throws Exception { if ( reading ) { if ( opt instanceof MQeFields ) { /* 1. list all files in the directory */ /* 2. read each file in turn and restore as a Fields object */ /* 3. try an equality check - if equal then return that object */ String List[] = new File( filePath ).list( this ); MQeFields Fields = null; for ( int i = 0; i < List.length; i = i + 1 ) try { fileName = List[i]; /* remember the name */ open( fileName ); /* try this file */ Fields = (MQeFields) readObject( null ); if ( Fields.equals( (MQeFields) opt ) ) /* match ? */ return( Fields ); } catch ( Exception e ) /* error occured */ { } /* ignore error */ throw new MQeException( Except_NotFound, "No match" ); } /* read the bytes from disk */ File diskFile = new File( filePath + fileName ); byte data[] = new byte[(int) diskFile.length()]; FileInputStream InputFile = new FileInputStream( diskFile ); InputFile.read( data ); /* read the file data */ InputFile.close( ); /* finish with file */ /* possible Attribute decode of the data */ if ( parameter instanceof MQeAttribute ) /* Attribute encoding ?*/ data = ((MQeAttribute) parameter).decodeData( null, data, 0, data.length ); MQeFields FieldsObject = MQeFields.reMake( data, null ); return( FieldsObject ); } else throw new MQeException( MQe.Except_NotSupported, "Not supported" ); }
public String status( Object opt ) throws Exception { if ( checkOption( opt, MQe.MQe_Adapter_FILTER ) ) return( filter ); if ( checkOption( opt, MQe.MQe_Adapter_FILENAME ) ) return( fileName ); return( super.status( opt ) ); }
public void writeObject( Object opt, Object data ) throws Exception { if ( writing && (data instanceof MQeFields) ) { byte dump[] = ((MQeFields) data).dump( ); /* dump object */ /* possible Attribute encode of the data */ if ( parameter instanceof MQeAttribute ) dump = ((MQeAttribute) parameter).encodeData( null, dump, 0, dump.length ); /* write out the object bytes */ File diskFile = new File( filePath + fileName ); FileOutputStream OutputFile = new FileOutputStream( diskFile ); OutputFile.write( dump ); /* write the data */ OutputFile.getFD().sync( ); /* synchronize disk */ OutputFile.close(); /* finish with file */ } else throw new MQeException( MQe.Except_NotSupported, "Not supported" ); }
This is now a complete (though very simple) message store adapter that reads and writes message objects to a message store.
Variations of this adapter could be coded for example to store messages in a database or in nonvolatile memory.