001/*
002 * Copyright (c) 2002-2010 The Regents of the University of California.
003 * All rights reserved.
004 *
005 * '$Author: crawl $'
006 * '$Date: 2015-08-24 22:48:48 +0000 (Mon, 24 Aug 2015) $' 
007 * '$Revision: 33634 $'
008 * 
009 * Permission is hereby granted, without written agreement and without
010 * license or royalty fees, to use, copy, modify, and distribute this
011 * software and its documentation for any purpose, provided that the above
012 * copyright notice and the following two paragraphs appear in all copies
013 * of this software.
014 *
015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
019 * SUCH DAMAGE.
020 *
021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
026 * ENHANCEMENTS, OR MODIFICATIONS.
027 *
028 */
029
030package org.ROADnet;
031
032//ptolemy classes
033import java.io.BufferedReader;
034import java.io.BufferedWriter;
035import java.io.File;
036import java.io.FileReader;
037import java.io.FileWriter;
038import java.util.Iterator;
039import java.util.List;
040import java.util.StringTokenizer;
041import java.util.Vector;
042import java.util.regex.Matcher;
043import java.util.regex.Pattern;
044
045import com.brtt.antelope.Orb;
046import com.brtt.antelope.OrbSource;
047
048import ptolemy.actor.IOPort;
049import ptolemy.actor.TypedAtomicActor;
050import ptolemy.actor.TypedIOPort;
051import ptolemy.data.BooleanToken;
052import ptolemy.data.StringToken;
053import ptolemy.data.Token;
054import ptolemy.data.expr.Parameter;
055import ptolemy.data.expr.Variable;
056import ptolemy.data.type.BaseType;
057import ptolemy.kernel.CompositeEntity;
058import ptolemy.kernel.util.Attribute;
059import ptolemy.kernel.util.IllegalActionException;
060import ptolemy.kernel.util.NameDuplicationException;
061import ptolemy.kernel.util.NamedObj;
062
063/**
064 * This actor connects to an Antelope ORB and collects element values for
065 * weather elements such as temperature,pressure,humidity,wind.
066 * 
067 * @see OrbWaveformSource, OrbWaveformSink, OrbPacketSource,
068 * @author Nandita Mangal, University of California
069 * @version $Id: OrbLogger.java 33634 2015-08-24 22:48:48Z crawl $
070 * @UserLevelDocumentation This actor connects to the Antelope ORB and logs the
071 *                         required sensor data values.
072 */
073
074public class OrbLogger extends TypedAtomicActor {
075        /**
076         * @param container
077         *            The container.
078         * @param name
079         *            The name of this actor.
080         * @exception IllegalActionException
081         *                If the actor cannot be contained by the proposed
082         *                container.
083         * @exception NameDuplicationException
084         *                If the container already has an actor with this name.
085         */
086        public OrbLogger(CompositeEntity container, String name)
087                        throws NameDuplicationException, IllegalActionException {
088                super(container, name);
089
090                // The orb source to connect to, (Samples: mercali.ucsd.edu:6770 or
091                // rt.sdsc.edu:6770)
092                orbname = new Parameter(this, "orbname");
093                orbname.setTypeEquals(BaseType.STRING);
094
095                // Sensor Locations File
096                sitesFile = new TypedIOPort(this, "sitesFile", true, false);
097                sitesFile.setTypeEquals(BaseType.STRING);
098
099                // A File containing the weather elements to be recorded as well a
100                // regular expression of
101                // the keywords matching the sourcnames for the above weather elements.
102                // e.g Pressure ((pres|Bar|BaroPr).*) [0-1500] specifies Pressure
103                // element,with keywords
104                // such as pres,Bar,BaroPr (like HPWREN_SDSC_Bar/GENC) and range of
105                // values should be 0-1500.
106                elementsExpressionFile = new TypedIOPort(this,
107                                "elementsExpressionFile", true, false);
108                elementsExpressionFile.setTypeEquals(BaseType.STRING);
109
110                // The path to save the recorded data files
111                filePath = new TypedIOPort(this, "filePath", true, false);
112                filePath.setTypeEquals(BaseType.STRING);
113
114                // If the user wants to output the existing workflow Parameters
115                paramsOutput = new Parameter(this, "paramsOutput", new BooleanToken(
116                                false));
117                paramsOutput.setTypeEquals(BaseType.BOOLEAN);
118                paramsOutput.setDisplayName("Output the Workflow Parameters");
119
120                // If the user wants to output an End/Finished Signal from the current
121                // actor
122                // check this box in parameters dialog
123                triggerOutput = new Parameter(this, "triggerOutput", new BooleanToken(
124                                false));
125                triggerOutput.setTypeEquals(BaseType.BOOLEAN);
126                triggerOutput.setDisplayName("Output Finished/End Signal ");
127
128                // If the user wants to output an Error Log of the Exceptions/Errors
129                // encountered
130                // check this box in parameters dialog
131                ErrorOutput = new Parameter(this, "ErrorOutput",
132                                new BooleanToken(false));
133                ErrorOutput.setTypeEquals(BaseType.BOOLEAN);
134                ErrorOutput.setDisplayName("Output ErrorsFile Handle ");
135
136                _attachText(
137                                "_iconDescription",
138                                "<svg>"
139                                                + "  <rect x=\"-30\" y=\"-20\" width=\"60\" height=\"40\" "
140                                                + "        style=\"fill:white\"/> "
141                                                + "  <circle cx=\"0\" cy=\"0\" r=\"15\" style=\"stroke:black\"/> "
142                                                + "  <text x=\"-10\" y=\"-5\">Orb</text>" + "</svg>");
143        }
144
145        // /////////////////////////////////////////////////////////////////
146        // // public methods ////
147
148        /**
149         * If the specified attribute is triggerOutput then create a "triggerReady"
150         * output port If the specified attribute is paramOutput then create ports
151         * for all the workflow String Parameters If the specified attribute is
152         * ErrorOutput then create a "ErrorFile" output port The newly created ports
153         * are removed if attribute is unchecked.
154         * 
155         * @param attribute
156         *            The attribute that has changed.
157         * @exception IllegalActionException
158         */
159        public void attributeChanged(Attribute at) throws IllegalActionException {
160
161                try {
162
163                        if (at == triggerOutput) {
164                                _triggerFlag = ((BooleanToken) triggerOutput.getToken())
165                                                .booleanValue();
166
167                                // If true create a "triggerReady" port which will output an
168                                // End/Finished Signal.
169                                if (_triggerFlag) {
170                                        // check if trigger exists already?
171                                        IOPort deleteTriggerCheck = getPort("triggerReady", 2);
172                                        if (deleteTriggerCheck == null) {
173                                                TypedIOPort p1 = new TypedIOPort(this, "triggerReady",
174                                                                false, true);
175                                                new Attribute(p1, "_showName");
176                                                p1.setTypeEquals(BaseType.BOOLEAN);
177
178                                        }
179
180                                }
181                                // remove trigger port
182                                else {
183                                        // iterate through each port till we get to triggerReady
184                                        // port.
185                                        List outPortList = this.outputPortList();
186                                        Iterator ports = outPortList.iterator();
187                                        while (ports.hasNext()) {
188                                                IOPort p = (IOPort) ports.next();
189                                                if (p.isOutput()) {
190                                                        try {
191                                                                if (p.getName().equals("triggerReady")) {
192                                                                        p.setContainer(null);
193
194                                                                }
195                                                        } catch (Exception e) {
196                                                                System.err
197                                                                                .println("Could not delete the trigger port--'"
198                                                                                                + e.getMessage() + "'.");
199                                                                writeErrorLog("Couldn't delete port:trigger"
200                                                                                + e.getMessage());
201
202                                                        }// catch
203                                                }// if
204                                        }// while
205                                }// if triggerFlag
206                        }
207                        // Workflow Parameters (if they exist) can have their values send
208                        // out as
209                        // param ports with this actor
210                        // (Useful for scenarios when workflow is being executed as a web
211                        // application & parameters are set as inputs to a workflow from
212                        // WorkflowExecute)
213                        else if (at == paramsOutput) {
214                                _paramsFlag = ((BooleanToken) paramsOutput.getToken())
215                                                .booleanValue();
216                                if (_paramsFlag)
217                                        addParamsPorts();
218                                else
219                                        removeParamsPorts();
220                        }
221                        // a log of all errors/exceptions can be output as a port
222                        else if (at == ErrorOutput) {
223                                _ErrorsFlag = ((BooleanToken) ErrorOutput.getToken())
224                                                .booleanValue();
225                                if (_ErrorsFlag)
226                                        addErrorHandle();
227                                else
228                                        removeErrorHandle();
229                        }
230
231                } catch (Exception e) {
232                        System.err.println(e.toString());
233                        writeErrorLog(e.toString());
234                }
235
236        }
237
238        /**
239         * This method initializes the component and connects to the specified orb
240         * source.It also obtains all source names in the current orb and puts them
241         * in array _values.
242         * 
243         */
244        public void initialize() throws IllegalActionException {
245
246                super.initialize();
247                try {
248
249                        // The Orb Source to connect to.
250                        _orb = new Orb(StringToken.convert(orbname.getToken())
251                                        .stringValue(), "r");
252
253                        // Sources will contain all the current sourcenames in the above orb
254                        OrbSource sources[], srcs[];
255                        int r, c;
256
257                        // get all source names.
258                        sources = _orb.sources();
259                        _nSources = sources.length;
260                        srcs = new OrbSource[_nSources];
261                        java.lang.System.arraycopy(sources, 0, srcs, 0, _nSources);
262                        java.util.Arrays.sort(srcs);
263                        _values = new String[_nSources];
264                        _selectedValues = new Vector();
265
266                        // _values is the array holding all the source names in the current
267                        // orb.
268                        for (r = 0; r < _nSources; r++) {
269                                _values[r] = srcs[r].srcname;
270                        }
271
272                } catch (Exception e) {
273
274                        writeErrorLog("Couldn't connect to Orb and/or get the required element Sources."
275                                        + e.toString());
276
277                }
278
279        }
280
281        /**
282         * This method first determines how many threads are currently running in
283         * the workflow.For each of the weather elements such as
284         * (Temp,Press,Wind,Humidity) we get the appropriate filter (regular
285         * expression pattern) and narrow down the source names to unstuff for
286         * values. Once these sources have been determined for the current element,
287         * a separate process is started to unstuff each waveform packet. Reaping
288         * each packet's value in a separate process makes sure (a read time out for
289         * one packet/other exceptions) doesn't slow down unstuffing for all the
290         * other sourcenames as well. More of a concurrently reaping way of
291         * unstuffing the packets, due to high number of sensors. (about 1500 in
292         * total)
293         */
294
295        public void fire() throws IllegalActionException {
296                super.fire();
297
298                // read all the regular Expression/keywords to be used for source names
299                // search
300                calculateElementSources();
301
302                // read the path of sensor sites file
303                _sitesFileRoot = ((StringToken) (sitesFile.get(0))).stringValue();
304
305                // read the path where to save all the result files produced
306                _filePath = ((StringToken) (filePath.get(0))).stringValue();
307
308                // delete pre-existing files
309                deleteOldLogFiles();
310
311                // first determine how many threads are running
312                determineThreadsFinished();
313                int preWorkflowThreads = threadCounter;
314
315                try {
316                        Vector currentSources = new Vector();
317                        boolean found = false;
318
319                        int j = 0;
320                        int i = 0;
321
322                        // loop for each of the elements
323                        // elementsCounter is the number of weather elements such as
324                        // Temperature,Pressure,Humidity,Wind
325                        for (i = 0; i < elementsCounter; i++) {
326                                // re-initialize current sources to include all the source names
327                                // in the ORB
328                                currentSources.removeAllElements();
329                                for (j = 0; j < _values.length; j++) {
330                                        if (_values[j] != null)
331                                                currentSources.add(_values[j]);
332                                }
333
334                                // for each filter get a bunch of refined sourcenames
335                                String filter = (String) regularExpVector.elementAt(i);
336                                System.err.println(filter);
337                                for (j = 0; j < currentSources.size(); j++) {
338
339                                        pattern = Pattern.compile(filter);
340                                        matcher = pattern.matcher((String) currentSources
341                                                        .elementAt(j));
342                                        while (matcher.find()) {
343
344                                                found = true;
345                                        }
346                                        if (!found) { // if filter couldn't find match for htat
347                                                                        // source name
348                                                // delete it from list of sources for hte element.
349                                                currentSources.removeElementAt(j);
350                                                j--; // update the counter of for loop accordingly
351                                        }
352                                        found = false; // reset boolean false
353
354                                }
355                                // get the narrowed down version of currentSources for the
356                                // current Element
357                                // after filter has filtered out some of the source names.
358
359                                j = 0;
360                                // iterate through the filtered sources
361                                for (j = 0; j < currentSources.size(); j++) {
362                                        if (excludeVector.contains((String) currentSources
363                                                        .elementAt(j))) {
364                                                // do nothing: dont add that source.
365                                        } else {
366
367                                                // add that source
368                                                // Get the source packet value in a separate process
369
370                                                // Get the required orbsource
371                                                String orbName = StringToken
372                                                                .convert(orbname.getToken()).stringValue();
373
374                                                // Get the current packet name
375                                                String packetName = (String) currentSources
376                                                                .elementAt(j);
377
378                                                // Get the current element being logged
379                                                String elementName = (String) elementsVector
380                                                                .elementAt(i);
381
382                                                // Get the sites file
383                                                String sitesFile = _sitesFileRoot;
384
385                                                // Get the range for the element
386                                                String ranges = (String) rangeVector.elementAt(i);
387
388                                                // Reap the Packet (unstuff the packet for the value)
389                                                ReapPacketThread p = new ReapPacketThread(orbName,
390                                                                packetName, elementName, sitesFile, ranges,
391                                                                _filePath);
392                                                // start the process
393                                                p.start();
394
395                                        }
396                                }
397
398                        }
399
400                } catch (Exception e) {
401                        System.err.println(e.toString() + " in Fire");
402                        writeErrorLog("In Main Fire method:" + e.toString());
403
404                }
405
406                // here we check if all the started threads have finished or not
407                // compare with starting number of threads
408                boolean continueCheck = true;
409                while (continueCheck) {
410                        determineThreadsFinished();
411                        if (threadCounter <= preWorkflowThreads) {
412                                // if all the threads have finished output the ready signal &
413                                // errorsFile
414                                // if the user has checked the boxes for them in
415                                // ParametersDialog.
416
417                                IOPort p = getPort("triggerReady", 2);
418                                if (p != null)
419                                        p.broadcast(new BooleanToken(true));
420                                calculateParams();
421
422                                IOPort p2 = getPort("ErrorsFile", 2);
423                                if (p2 != null)
424                                        p2.broadcast(new StringToken(_filePath + "/ErrorsLogFile"));
425                                continueCheck = false;
426
427                        }
428                }
429
430        }
431
432        // /////////////////////////////////////////////////////////////////
433        // // private methods ////
434
435        /**
436         * This method updates threadCounter variable to indicate the number of
437         * current threads.A thread exists in a thread group and a thread group can
438         * contain other thread groups. This method visits all threads in all thread
439         * groups.
440         * 
441         * @author Java Developers Almanac,Addison-Wesley.
442         */
443
444        private void determineThreadsFinished() {
445
446                // Find the root thread group
447                ThreadGroup root = Thread.currentThread().getThreadGroup().getParent();
448                while (root.getParent() != null) {
449                        root = root.getParent();
450                }
451                threadCounter = 0;
452                // Visit each thread group
453                visit(root, 0);
454        }
455
456        // This method recursively visits all thread groups under `group'.
457        public void visit(ThreadGroup group, int level) {
458                // Get threads in `group'
459                int numThreads = group.activeCount();
460                Thread[] threads = new Thread[numThreads * 2];
461                numThreads = group.enumerate(threads, false);
462
463                // Enumerate each thread in `group'
464                for (int i = 0; i < numThreads; i++) {
465                        // Get thread
466                        Thread thread = threads[i];
467
468                        threadCounter++;
469
470                }
471
472                // Get thread subgroups of `group'
473                int numGroups = group.activeGroupCount();
474                ThreadGroup[] groups = new ThreadGroup[numGroups * 2];
475                numGroups = group.enumerate(groups, false);
476
477                // Recursively visit each subgroup
478                for (int i = 0; i < numGroups; i++) {
479                        visit(groups[i], level + 1);
480                }
481        }
482
483        /**
484         * This method first retrieves all the workflow parameters and creates
485         * appropriate output ports. NOTE: All workflow parameter are currently
486         * expected to be string type
487         */
488        private void addParamsPorts() {
489                try {
490                        NamedObj model = getContainer();
491                        String val = "";
492                        Iterator atts = model.attributeList().iterator();
493                        boolean continueLoop = true;
494                        while (atts.hasNext() && continueLoop == true) {
495                                Attribute att = (Attribute) atts.next();
496                                if (att instanceof Variable) {
497                                        String attName = att.getName();
498
499                                        if (getPort(attName, 2) == null) {
500
501                                                TypedIOPort p = new TypedIOPort(this, attName, false,
502                                                                true);
503                                                new Attribute(p, "_showName");
504                                                Variable var = (Variable) att;
505                                                p.setTypeEquals(var.getToken().getType());
506                                                _paramsPorts.add(attName);
507                                        }
508
509                                }
510                        }
511
512                } catch (Exception e) {
513                        writeErrorLog("Adding Workflow Parameter Ports" + e.toString());
514                }
515        }
516
517        /**
518         * This method removes all the workflow ports created.
519         */
520
521        private void removeParamsPorts() {
522
523                List outPortList = this.outputPortList();
524                Iterator ports = outPortList.iterator();
525                while (ports.hasNext()) {
526                        IOPort p = (IOPort) ports.next();
527                        if (p.isOutput()) {
528                                try {
529                                        if (_paramsPorts.contains(p.getName())) {
530                                                p.setContainer(null);
531                                        }
532                                } catch (Exception e) {
533                                        writeErrorLog("Removing Workflow Parameter Ports"
534                                                        + e.toString());
535                                }
536
537                        }
538                }
539
540                _paramsPorts.removeAllElements();
541
542        }
543
544        /**
545         * This method adds a Error log File port
546         */
547        private void addErrorHandle() {
548                try {
549                        TypedIOPort p = new TypedIOPort(this, "ErrorsFile", false, true);
550                        new Attribute(p, "_showName");
551                        p.setTypeEquals(BaseType.STRING);
552                } catch (Exception e) {
553                        writeErrorLog("Adding ErrorsLogFile port" + e.toString());
554                }
555        }
556
557        /**
558         * This method removes the Error log File port
559         */
560        private void removeErrorHandle() {
561                List outPortList = this.outputPortList();
562                Iterator ports = outPortList.iterator();
563                while (ports.hasNext()) {
564                        IOPort p = (IOPort) ports.next();
565                        if (p.isOutput()) {
566                                try {
567                                        if (p.getName().equals("ErrorsFile")) {
568                                                p.setContainer(null);
569                                        }
570                                } catch (Exception e) {
571                                        writeErrorLog("Deleting ErrorsLogFile port" + e.toString());
572                                }
573                        }
574                }
575
576        }
577
578        /**
579         * This method retrieves the port for the specified name. Mode=1 is input
580         * port & Mode=2 is output port.
581         */
582
583        private IOPort getPort(String portName, int mode) {
584                if (mode == 1) {
585                        List inPortList = this.inputPortList();
586                        Iterator ports = inPortList.iterator();
587                        while (ports.hasNext()) {
588                                IOPort p = (IOPort) ports.next();
589                                if (p.isInput()) {
590                                        try {
591                                                if (p.getName().equals(portName)) {
592                                                        return p;
593                                                }
594                                        } catch (Exception e) {
595                                                writeErrorLog("Couldn't retrieve port" + portName
596                                                                + e.toString());
597                                        }
598                                }
599                        }
600
601                } else if (mode == 2) {
602
603                        List outPortList = this.outputPortList();
604                        Iterator ports = outPortList.iterator();
605                        while (ports.hasNext()) {
606                                IOPort p = (IOPort) ports.next();
607                                if (p.isOutput()) {
608                                        try {
609                                                if (p.getName().equals(portName)) {
610                                                        return p;
611                                                }
612                                        } catch (Exception e) {
613                                                writeErrorLog("Couldn't retrieve port" + portName
614                                                                + e.toString());
615
616                                        }
617                                }
618                        }
619
620                }
621                // null otherwise
622                return null;
623
624        }
625
626        /**
627         * This method broadcasts the workflow parameter values to the appropriate
628         * parameter ports
629         */
630        private void calculateParams() {
631
632                List outPortList = this.outputPortList();
633                Iterator ports = outPortList.iterator();
634                while (ports.hasNext()) {
635                        IOPort p = (IOPort) ports.next();
636                        if (p.isOutput() && !(p.getName().equals("triggerReady"))) {
637                                try {
638
639                                        // retrieve workflow value
640                                        Token t = getWorkflowParam(p.getName());
641                                        if (t != null)
642                                                p.broadcast(t);
643
644                                } catch (Exception e) {
645                                        writeErrorLog("Couldn't broadcast workflow parameter values to ports"
646                                                        + e.toString());
647
648                                }
649                        }
650                }
651
652        }
653
654        /**
655         * This method simply outputs the following 6 workflow parameters values to
656         * be used by other actors.
657         * colorTemp,colorPress,colorWind,colorHumid,contourWidth,contourLevel.
658         */
659        private Token getWorkflowParam(String portName) {
660
661                try {
662                        NamedObj model = getContainer();
663                        String val = "";
664                        Iterator atts = model.attributeList().iterator();
665                        boolean continueLoop = true;
666                        while (atts.hasNext() && continueLoop == true) {
667                                Attribute att = (Attribute) atts.next();
668                                if (att instanceof Variable) {
669                                        String attName = att.getName();
670                                        if (attName.trim().equals(portName)) {
671                                                Variable var = (Variable) att;
672                                                return var.getToken();
673                                        }
674
675                                }
676                        }
677
678                } catch (Exception e) {
679                        System.err.println(e.toString());
680                        writeErrorLog("Couldn't retrieve workflow Parameters"
681                                        + e.toString());
682
683                }
684
685                return null;
686        }
687
688        /**
689         * This method first reads the given regular expressions file containing
690         * sourcenames keywords,ranges as well as weather element names.Accordingly
691         * creates an elementsVector,regularExpVector,rangeVector and an
692         * excludeVector(sources not to be included) for further use later in the
693         * actor.
694         */
695        private void calculateElementSources() {
696
697                int tokenCounter = 0;
698                elementsCounter = 0;
699                String str = "";
700
701                try {
702
703                        _expressionsFileRoot = ((StringToken) (elementsExpressionFile
704                                        .get(0))).stringValue();
705
706                        BufferedReader in = new BufferedReader(new FileReader(
707                                        _expressionsFileRoot));
708
709                        while ((str = in.readLine()) != null && str != "\n") {
710                                // System.err.println(str);
711                                StringTokenizer st = new StringTokenizer(str);
712                                while (st.hasMoreTokens()) {
713
714                                        if (tokenCounter == 0) // currently at an element
715                                        {
716                                                elementsVector.add(st.nextToken());
717                                                // System.err.println("ELEMENTS " + elementsVector);
718                                        } else if (tokenCounter == 1) // currently at the regular
719                                                                                                        // expression
720                                        {
721                                                regularExpVector.add(st.nextToken());
722                                                // System.err.println("REGEXP" + regularExpVector);
723                                        } else if (tokenCounter == 2) // currently at the range
724                                        {
725                                                rangeVector.add(st.nextToken());
726
727                                                // System.err.println("RANGE" + rangeVector);
728                                        } else if (tokenCounter == 3) // EXCLUDE
729                                        {
730                                                String filter = st.nextToken();
731                                                // System.err.println(filter);
732                                                if (filter.indexOf("EXCLUDE") >= 0) {
733                                                        filter = filter.substring(8, filter.length() - 1);
734
735                                                        if (filter.indexOf(",") >= 0) {
736                                                                StringTokenizer st2 = new StringTokenizer(
737                                                                                filter, ",");
738                                                                while (st2.hasMoreTokens()) {
739                                                                        excludeVector.add(st2.nextToken());
740                                                                }// while
741                                                        }// if-","
742                                                        else
743                                                                excludeVector.add(filter);
744
745                                                }// if-exclude
746                                                // System.err.println("EXCLUDE" + excludeVector);
747                                        }// if-token==3
748                                        tokenCounter++;
749
750                                }
751                                tokenCounter = 0;
752                                elementsCounter++;
753
754                        }
755
756                } catch (Exception e) {
757                        System.err.println(e.toString());
758                        writeErrorLog(e.toString());
759                }
760
761        }
762
763        private void writeErrorLog(String message) {
764
765                try {
766                        BufferedWriter bw = new BufferedWriter(new FileWriter(_filePath
767                                        + "/ErrorsLogFile", true));
768                        bw.write("\n");
769                        bw.write(message);
770                        bw.close();
771
772                } catch (Exception e) {
773                        System.err.println(e.toString());
774                }
775
776        }
777
778        private void deleteOldLogFiles() {
779                boolean success = false;
780
781                for (int i = 0; i < elementsCounter; i++) {
782
783                        // Get the current element being logged
784                        String element = (String) elementsVector.elementAt(i);
785
786                        success = (new File(new String(_filePath + "/" + element
787                                        + "FileValues"))).delete();
788                        if (!success) {
789                                writeErrorLog("Failed to delete old log file: " + element
790                                                + "FileValues");
791                        }
792                        success = (new File(new String(_filePath + "/" + element
793                                        + "FileSensors"))).delete();
794                        if (!success) {
795                                writeErrorLog("Failed to delete old log file: " + element
796                                                + "FileSensors");
797                        }
798
799                }
800                success = (new File(new String(_filePath + "/ErrorsLogFile"))).delete();
801                if (!success) {
802                        writeErrorLog("Failed to delete old log file: " + "ErrorsLogFile");
803                }
804
805        }
806
807        // /////////////////////////////////////////////////////////////////
808        // // ports and parameters ////
809
810        /**
811         * The name of the orb to connect to, in the format "hostname:port". Note
812         * that orbnames.pf-style names are not supported -- you have to use a valid
813         * IP address or resolvable DNS name, and you have to use a numeric port
814         * number.
815         * 
816         * @UserLevelDocumentation The orbname refers to the specific ORB source
817         *                         that you want to connect to via Antelope software
818         *                         in Kepler.
819         */
820        public Parameter orbname;
821
822        // the path where to save all the log files,element values files
823        public TypedIOPort filePath;
824
825        // the file path containing regular expressions for elements & source names
826        // keywords
827        public TypedIOPort elementsExpressionFile;
828
829        // the file path containing sensor locations.
830        public TypedIOPort sitesFile;
831
832        // whether to include trigger port
833        public Parameter triggerOutput;
834
835        // whether to include workflow parameters ports
836        public Parameter paramsOutput;
837
838        // whether to include errorlog file port
839        public Parameter ErrorOutput;
840
841        // /////////////////////////////////////////////////////////////////
842        // // private variables ////
843
844        // contains all the source names for the specified orb.
845        private String _values[];
846        // the orb which we connected to.
847        private Orb _orb;
848        // number of sources in the orb
849        private int _nSources;
850        // current source counter, what index sourceName is currently being reaped.
851        private int _sourceCounter = 0;
852        // name of current source being reaped.
853        private String _currentSource = "";
854        // recording of all element values finished or not, indicates whether to
855        // continueStream is true/false.
856        private boolean _continueStream = true;
857        // a vector to hold all the sourcenames for the specific element currently
858        // being recorded.
859        private Vector _selectedValues;
860
861        // The string containing sensor locations file's path
862        private String _sitesFileRoot;
863        // The sensor locations File
864        private File _sitesFile;
865        // The regular expression File
866        private File _expressionFile;
867        // The path which contains all data files in the local server
868        private String _filePath = "";
869        // The path to file containing expressions.
870        private String _expressionsFileRoot = "";
871
872        private boolean _paramsFlag;
873        private boolean _triggerFlag;
874        private boolean _ErrorsFlag;
875
876        // a list of all workflow parameter ports created
877        private Vector _paramsPorts = new Vector();
878        // contains the weather elements being recorded
879        private Vector elementsVector = new Vector();
880
881        // contains the regular expresion filters for the above elements
882        private Vector regularExpVector = new Vector();
883        // contains the ranges for the above elements
884        private Vector rangeVector = new Vector();
885        // contains the sources not to be excluded
886        private Vector excludeVector = new Vector();
887        // number of weather elements recorded
888        private int elementsCounter = 0;
889
890        private static Pattern pattern;
891        private static Matcher matcher;
892
893        // count of threads currently in the application.
894        private int threadCounter = 0;
895}