package com.ghc.custom.functions; import com.ghc.ghTester.expressions.*; import java.util.Vector; import java.io.*; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.channels.FileChannel; import java.nio.channels.FileLock; import java.nio.charset.Charset; /** * The function takes two parameters. Param1: Result length (ie 6 would result * in 000001, 3 would result in 001). * <p/> * NumberGenerator( length ) * <p/> * Example: * <p/> * NumberGenerator( 6 ) returns: 000001 * <p/> * Param2: Optional path to a file to read and store the last used number. * <p/> * NumberGenerator( length[, path]) * <p/> * Example: * <p/> * NumberGenerator( 6, c:\\temp\\myFile.txt ) returns: 000001 then: 000002 and * increments on subsequent executions. * <p/> */ public class NumberGenerator extends Function { /** * This function will return the number that we wish to output. */ private Function m_fNumberGeneratorNumber = null; /** * This function will return the length that we wish to output. */ private Function m_fNumberGeneratorLength = null; private Function m_fFileName; private File file; /** * Constructor used to register this function. */ public NumberGenerator(Function f1, Function f2) { m_fFileName = null; m_fNumberGeneratorLength = null; m_fNumberGeneratorLength = f1; m_fFileName = f2; } public NumberGenerator(Function f1) { m_fFileName = null; m_fNumberGeneratorLength = null; m_fNumberGeneratorLength = f1; } public NumberGenerator() { m_fFileName = null; m_fNumberGeneratorLength = null; try { // Default if no path specified file = new File("c:\\\\numberGenerator.tmp"); if (!file.exists()) { file.createNewFile(); BufferedWriter out = new BufferedWriter(new FileWriter(file)); out.write("0"); out.flush(); out.close(); } } catch (Exception e) { e.printStackTrace(); } } /** * Evaluate method is used to do the meat of the work. This will always * return 'done' to the caller regardless of success or failure * * @param data * - this should be passed to all evaluate calls */ public synchronized Object evaluate(Object data) { // StringWriter responseString = new StringWriter(); String newNumber = ""; String filename; FileLock lock; newNumber = ""; filename = ""; lock = null; String len = m_fNumberGeneratorLength.evaluateAsString(data); try { filename = m_fFileName.evaluateAsString(data); } catch(Exception noFilename){ filename = ""; } try { if (filename.equals("")) filename = "c:\\\\numberGenerator.tmp"; System.out.println((new StringBuilder("Output to file: ")).append( filename).toString()); int length = (new Integer(len)).intValue(); file = new File(filename); if (!file.exists()) { file.createNewFile(); BufferedWriter out = new BufferedWriter(new FileWriter(file)); out.write("0"); out.flush(); out.close(); } FileChannel channel = (new RandomAccessFile(file, "rw")) .getChannel(); while (lock == null) try { lock = channel.tryLock(); } catch (Exception exception1) { } ByteBuffer buff = ByteBuffer.allocate(0x80000); buff.position(0); Charset cs = Charset.forName("ASCII"); channel.read(buff, 0L); buff.flip(); CharBuffer charbuff = cs.decode(buff); String previousNumber = charbuff.toString(); if (previousNumber.equals("")) previousNumber = "0"; int prev = (new Integer(previousNumber)).intValue(); prev++; for (newNumber = new String((new StringBuilder()).append(prev) .toString()); newNumber.length() < length; newNumber = "0" .concat(newNumber)) ; buff.clear(); buff.put(newNumber.getBytes()); buff.flip(); channel.write(buff, 0L); channel.close(); channel = null; } catch (Exception exception) { exception.printStackTrace(); } return newNumber; } /** * This function is called when an expression is being evaluated and a new * instance of this function needs to be created. * * @param size * number of params * @param params * a vector of Function objects, which are the parameters */ public Function create(int size, Vector params) { if (params.size() > 1) return new NumberGenerator((Function) params.get(0), (Function) params.get(1)); else return new NumberGenerator((Function) params.get(0)); } }