source: tmcsimulator/trunk/src/tmcsim/paramicscommunicator/ParamicsFileWriter.java @ 2

Revision 2, 8.2 KB checked in by jdalbey, 10 years ago (diff)

Initial Import of project files

Line 
1package tmcsim.paramicscommunicator;
2
3
4import java.io.File;
5import java.io.FileWriter;
6import java.io.IOException;
7import java.util.LinkedList;
8import java.util.Observable;
9import java.util.Timer;
10import java.util.TimerTask;
11import java.util.logging.Level;
12import java.util.logging.Logger;
13
14import org.apache.xml.serialize.OutputFormat;
15import org.apache.xml.serialize.XMLSerializer;
16import org.w3c.dom.Element;
17
18import tmcsim.paramicscommunicator.FileIOUpdate.IO_TYPE;
19
20/**
21 * The ParamicsFileWriter handles writing messages to a target file which
22 * is read by Paramics.  Messages are received through the writeMessage() method.
23 * This object handles queueing messages and writing as the file becomes
24 * available.  New data is written to the target file when it has been
25 * modified (cleared) by Paramics.  If this does not happen, messages
26 * are queued and a timer is used to periodically determine if the
27 * file has become available for writing.
28 *
29 * @author Matthew Cechini
30 * @version
31 */
32public class ParamicsFileWriter extends Observable {
33   
34    /**
35     * Duration (in  ms) that the TimerTask will be scheduled to
36     * retry writing to the target file. Default = 2000ms
37     */
38    private static long TIMER_DURATION = 2000;
39   
40    /** Error Logger. */
41    private Logger paramLogger = Logger.getLogger("tmcsim.paramicscommunicator");
42   
43    /** Linked List of messages that have been received */
44    private LinkedList<Element> queuedMessages = null;
45   
46    /**  */
47    private String writerID = null;
48
49    /** File name of the file where data is written */
50    private String outputFile = null;
51   
52    /** FileWriter used to write data to the output file. */
53    private FileWriter fileWriter = null;
54   
55    /** Value (seconds since 1/1/1970) of output file's last modifcation time */
56    private long lastModified = 0; 
57   
58    /** Timer used to schedule file writing tasks. */
59    private Timer writerTimer = null;
60   
61    /**
62     * A TimerTask to retry writing messages that have been queued within this
63     * ParamicsWriter.  If a message has been queued, see if the target file
64     * has been modified since last write.  If so, write the first queued message
65     * to the file and remove the message from the queue.  If writing is unsuccessful,
66     * do not remove the message from the queue.  If there are no more messages in
67     * the queue, cancel this timer.
68     */
69    private class WriterTimerTask extends TimerTask {
70        public void run() {
71
72            synchronized(lock) {
73           
74                //if we've queued something, continue.
75                if(queuedMessages.size() > 0) {         
76                   
77                    //if file has been modified, write to it
78                    if(lastModified < new File(outputFile).lastModified())
79                    {       
80                        try {
81                            writeToFile(queuedMessages.getFirst());
82                            queuedMessages.remove(0);
83                        }
84                        catch (IOException ioe) {
85                            paramLogger.logp(Level.SEVERE, "ParamicsFileWriter.WriterTimerTask", 
86                                    "run()", "Exception in writing to the target file: " + 
87                                    outputFile + ".  Queue size = " + queuedMessages.size(), ioe);
88                        }
89                       
90                        //all queued messages gone, cancel timer
91                        if(queuedMessages.size() == 0)
92                            this.cancel();
93                    }   
94                }
95            }               
96        }
97    }
98   
99    /** Synchronizing lock to protect File IO and message queuing. */
100    private Object lock = null;     
101   
102    /**
103     * Constructor.  Initialize data objects.  If the target file exists, delete
104     * it, and then create a new file. 
105     *
106     * @param workingDir Directory path where the output file is to be written
107     * @param mess The ParamicsCommMessage containing the outputFile filename.
108     */
109    public ParamicsFileWriter(String id, String workingDir, String targetFile) {
110
111        try {
112            writerID = id;
113   
114            queuedMessages  = new LinkedList<Element>();   
115            lock            = new Object();
116                       
117            outputFile      = workingDir + targetFile; 
118           
119            File tempFile = new File(outputFile);           
120            if(tempFile.exists()) {
121                tempFile.delete();
122            }
123
124            tempFile.createNewFile();           
125                                               
126            writerTimer     = new Timer();
127           
128        } catch (IOException ioe) {
129            paramLogger.logp(Level.SEVERE, "ParamicsFileWriter", "Constructor", 
130                    "Unable to create Paramics File Writer.", ioe);
131        }
132       
133    }
134   
135   
136    /**
137     * Method is called when a message has been received from the CAD Simulator.
138     * If the message queue is not empty, add the new message to the queue.
139     * If the output file has not been modified (read) since last write,
140     * add the message to the queue and set a timer to repeatedly check for
141     * modification to the output file.  Else, write the new message to the file. 
142     * If there is an error in writing the data, queue the message start a timer
143     * to retry the writing.
144     *
145     * @param newMessage The received message which is to be written to
146     * the output file.
147     */
148    public void writeMessage(Element messageElem) {
149       
150        synchronized(lock) {
151           
152            //messages already queued... get in line.           
153            if(queuedMessages.size() > 0) {
154                queuedMessages.add(messageElem);
155
156                paramLogger.log(Level.INFO, "Queueing message, new queue " +
157                        "size = " + queuedMessages.size());
158            }               
159            //No modification since last write. (first queue)               
160            else if (lastModified >= new File(outputFile).lastModified()) {
161                queuedMessages.add(messageElem);               
162                               
163                writerTimer.scheduleAtFixedRate(new WriterTimerTask(), 
164                        0L, TIMER_DURATION);
165
166                paramLogger.log(Level.INFO, "First message queued");
167            }           
168            //free and clear, write.
169            else {
170                try {
171                    writeToFile(messageElem);
172                }
173                catch(IOException ioe) {
174                    paramLogger.logp(Level.SEVERE, "ParamicsFileWriter", 
175                            "writeMessage()", "Exception in writing to the " +
176                            "target file: " + outputFile, ioe);
177                   
178                    queuedMessages.add(messageElem);
179                   
180                    writerTimer.scheduleAtFixedRate(new WriterTimerTask(), 
181                            0L, TIMER_DURATION);
182                }
183            }
184        }
185    }
186       
187    /**
188     * Method writes data to the output file.
189     *
190     * @param output Data to be written to the file.
191     */
192    private void writeToFile(Element output) throws IOException {       
193       
194        fileWriter = new FileWriter(outputFile);
195       
196        OutputFormat of = new OutputFormat("XML","ISO-8859-1",true);
197        of.setIndent(1);
198        of.setIndenting(true);
199       
200        XMLSerializer serializer = new XMLSerializer(fileWriter, of);
201        serializer.asDOMSerializer();
202        serializer.serialize(output);
203
204        /** Added by Nathaniel Lehrer */
205        try {
206            java.io.ByteArrayOutputStream outputStream = new java.io.ByteArrayOutputStream();
207            new XMLSerializer(outputStream, of).serialize(output);
208            tmcsim.paramicslog.ParamicsLog.getInstance().writeToLog(outputStream.toString());
209        } catch(Exception e) {
210            System.out.println(e);
211        }
212        /** End Add by Nathaniel Lehrer */
213       
214        fileWriter.flush();
215        fileWriter.close();
216       
217        lastModified = new File(outputFile).lastModified();     
218       
219        setChanged();
220        notifyObservers(new FileIOUpdate(IO_TYPE.WRITE, writerID, new File(outputFile).length()));
221                           
222    }               
223}
Note: See TracBrowser for help on using the repository browser.