001/*
002 * Copyright (c) 2002-2010 The Regents of the University of California.
003 * All rights reserved.
004 *
005 * '$Author: welker $'
006 * '$Date: 2010-05-06 05:21:26 +0000 (Thu, 06 May 2010) $' 
007 * '$Revision: 24234 $'
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.geon;
031
032import java.awt.Point;
033import java.io.BufferedReader;
034import java.io.BufferedWriter;
035import java.io.ByteArrayInputStream;
036import java.io.File;
037import java.io.FileReader;
038import java.io.FileWriter;
039import java.io.IOException;
040import java.io.InputStream;
041
042import javax.xml.parsers.DocumentBuilder;
043import javax.xml.parsers.DocumentBuilderFactory;
044
045import org.w3c.dom.Document;
046import org.w3c.dom.Element;
047import org.w3c.dom.Node;
048import org.w3c.dom.NodeList;
049
050import ptolemy.actor.TypedAtomicActor;
051import ptolemy.actor.TypedIOPort;
052import ptolemy.data.IntToken;
053import ptolemy.data.ObjectToken;
054import ptolemy.data.StringToken;
055import ptolemy.data.type.BaseType;
056import ptolemy.gui.MessageHandler;
057import ptolemy.kernel.CompositeEntity;
058import ptolemy.kernel.util.IllegalActionException;
059import ptolemy.kernel.util.NameDuplicationException;
060
061//////////////////////////////////////////////////////////////////////////
062//// GetPoint
063/**
064 * This is a domain specific actor used within the GEON mineral classifier for
065 * calculating a calssification point given mineral composition and coordinate
066 * names.
067 * 
068 * @author Efrat Jaeger
069 * @version $Id: GetPoint.java 24234 2010-05-06 05:21:26Z welker $
070 * @since Ptolemy II 3.0.2
071 */
072public class GetPoint extends TypedAtomicActor {
073
074        /**
075         * Construct an actor with the given container and name.
076         * 
077         * @param container
078         *            The container.
079         * @param name
080         *            The name of this actor.
081         * @exception IllegalActionException
082         *                If the actor cannot be contained by the proposed
083         *                container.
084         * @exception NameDuplicationException
085         *                If the container already has an actor with this name.
086         */
087        public GetPoint(CompositeEntity container, String name)
088                        throws NameDuplicationException, IllegalActionException {
089
090                super(container, name);
091
092                // Set the type constraint.
093                rowInfo = new TypedIOPort(this, "rowInfo", true, false);
094                // rowInfo.setTypeEquals(BaseType.GENERAL);
095                rowInfo.setTypeEquals(BaseType.STRING);
096                coordinateNames = new TypedIOPort(this, "coordinateNames", true, false);
097                coordinateNames.setTypeEquals(BaseType.INT); // FIX ME! for demo
098                                                                                                                // purposes!!!
099                point = new TypedIOPort(this, "point", false, true);
100                point.setTypeEquals(BaseType.GENERAL);
101        }
102
103        // /////////////////////////////////////////////////////////////////
104        // // ports and parameters ////
105
106        /**
107         * Hold the mineral composition info.
108         */
109        public TypedIOPort rowInfo;
110
111        /**
112         * The coordinates/minerals of the classification diagram.
113         */
114        public TypedIOPort coordinateNames;
115
116        /**
117         * The classification point.
118         */
119        public TypedIOPort point;
120
121        /**
122         * Retrieve the mineral composition for the coordinate names and calculate
123         * the classification point.
124         */
125        public void fire() throws IllegalActionException {
126
127                // get the working directory.
128                String _keplerPath = System.getProperty("user.dir");
129                System.out.println("kepler abs path ==> " + _keplerPath);
130
131                // FIX ME: for demo purposes. needs to be generalized.
132                // ObjectToken obj1 = (ObjectToken) rowInfo.get(0);
133                // RockSample Rock = (RockSample) obj1.getValue();
134
135                RockSample Rock = new RockSample();
136
137                String xmlStr = ((StringToken) rowInfo.get(0)).stringValue();
138                try {
139                        DocumentBuilderFactory factory = DocumentBuilderFactory
140                                        .newInstance();
141                        factory.setValidating(false);
142                        DocumentBuilder builder = factory.newDocumentBuilder();
143                        byte[] xmlBytes = xmlStr.getBytes();
144                        InputStream is = new ByteArrayInputStream(xmlBytes);
145                        Document doc = builder.parse(is);
146
147                        NodeList nodes = doc.getElementsByTagName("row");
148                        for (int i = 0; i < nodes.getLength(); i++) {
149                                NodeList childs = nodes.item(i).getChildNodes();
150                                for (int j = 0; j < childs.getLength(); j++) {
151                                        Node child = childs.item(j);
152                                        if (child instanceof Element) {
153                                                Element elem = (Element) child;
154                                                String tag = elem.getTagName();
155                                                String val = "";
156                                                if (elem.getChildNodes().getLength() > 0) {
157                                                        val = elem.getFirstChild().getNodeValue().trim();
158                                                }
159                                                Rock.add(tag, val);
160                                        }
161                                }
162                        }
163                } catch (Exception ex) {
164                        throw new IllegalActionException(this, ex
165                                        + " xml processing exception.");
166                }
167
168                while (true) {
169                        int layer = ((IntToken) coordinateNames.get(0)).intValue();
170                        if (layer == 1) {
171                                _point = Rock.getPointForGabbroOlivine(35, 32, 340, 294, layer);
172                                // FIX ME: Change according to diagram coordinates.
173                                _addPointToSVG(_keplerPath + "/lib/testdata/geon/QAPF.svg",
174                                                _keplerPath + "/lib/testdata/geon/layer1.svg"); // FIX
175                                                                                                                                                // ME!!!
176                                                                                                                                                // relative
177                                                                                                                                                // files
178                        } else if (layer == 2) {
179                                _point = Rock.getPointForGabbroOlivine(40, 32, 420, 345, layer);
180                                // FIX ME: Change according to diagram coordinates.
181                                _addPointToSVG(_keplerPath + "/lib/testdata/geon/PlagPxOl.svg",
182                                                _keplerPath + "/lib/testdata/geon/layer2.svg"); // FIX
183                                                                                                                                                // ME!!!
184                                                                                                                                                // relative
185                                                                                                                                                // files
186                        }
187                        // System.out.println("point: Px = " + _point.getX() + " , Py = " +
188                        // _point.getY());
189                        point.broadcast(new ObjectToken(_point));
190                }
191        }
192
193        /**
194         * Post fire the actor. Return false to indicate that the process has
195         * finished. If it returns true, the process will continue indefinitely.
196         */
197        public boolean postfire() {
198                return true;
199        }
200
201        /**
202         * Add the classification point to the SVG file for display purposes.
203         */
204        private void _addPointToSVG(String inpFile, String outFile) {
205                try {
206                        System.out.println("input : " + inpFile + " , output : " + outFile);
207                        File input = new File(inpFile);
208                        BufferedReader br = new BufferedReader(new FileReader(input));
209                        String line;
210                        File output = new File(outFile);
211                        // System.out.println("File name" + file.getName());
212                        BufferedWriter out = new BufferedWriter(new FileWriter(output));
213                        // System.out.println("path" + file.getPath());
214                        String extraLine = "<circle cx='" + _point.getX() + "' cy='"
215                                        + _point.getY() + "' r='3' fill='red' stroke='red'/>";
216                        // System.out.println("Extra line" + extraLine);
217                        while ((line = br.readLine()) != null) {
218                                int ind = line.toLowerCase().indexOf("</svg>");
219                                if (ind != -1) {
220                                        // System.out.println("Inside extra line");
221                                        out.write(line.substring(0, ind) + "\n");
222                                        out.write(extraLine + "\n");
223                                        out.write(line.substring(ind) + "\n");
224                                } else
225                                        out.write(line + "\n");
226                        }
227                        out.close();
228                        br.close();
229                } catch (IOException e) {
230                        MessageHandler.error("Error opening file", e);
231                }
232        }
233
234        /**
235         * The classification point.
236         */
237        private Point _point;
238}