Warning: Can't use blame annotator:
svn blame failed on trunk/src/tmcsim/paramicscommunicator/ParamicsFileWriter.java: ("Can't find a temporary directory: Internal error", 20014)

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

Revision 25, 8.7 KB checked in by jdalbey, 10 years ago (diff)

ParamicsCommunicator?: added some diagnostic logging messages.

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