001/*
002 * Copyright (c) 2003-2010 The Regents of the University of California.
003 * All rights reserved.
004 *
005 * '$Author: crawl $'
006 * '$Date: 2012-09-20 22:41:53 +0000 (Thu, 20 Sep 2012) $' 
007 * '$Revision: 30725 $'
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.io.ByteArrayInputStream;
033import java.io.InputStream;
034import java.net.URL;
035import java.util.Iterator;
036import java.util.Vector;
037
038import javax.xml.parsers.DocumentBuilder;
039import javax.xml.parsers.DocumentBuilderFactory;
040
041import org.w3c.dom.Document;
042import org.w3c.dom.Element;
043import org.w3c.dom.Node;
044import org.w3c.dom.NodeList;
045
046import ptolemy.actor.CompositeActor;
047import ptolemy.actor.Manager;
048import ptolemy.actor.lib.Const;
049import ptolemy.data.ArrayToken;
050import ptolemy.data.BooleanMatrixToken;
051import ptolemy.data.DoubleMatrixToken;
052import ptolemy.data.DoubleToken;
053import ptolemy.data.IntMatrixToken;
054import ptolemy.data.IntToken;
055import ptolemy.data.LongMatrixToken;
056import ptolemy.data.LongToken;
057import ptolemy.data.RecordToken;
058import ptolemy.data.StringToken;
059import ptolemy.data.Token;
060import ptolemy.data.UnsignedByteToken;
061import ptolemy.data.expr.Variable;
062import ptolemy.data.type.BaseType;
063import ptolemy.kernel.ComponentEntity;
064import ptolemy.kernel.util.Attribute;
065import ptolemy.kernel.util.IllegalActionException;
066import ptolemy.kernel.util.NamedObj;
067import ptolemy.moml.MoMLParser;
068
069//////////////////////////////////////////////////////////////////////////
070////PTModelService
071/**
072 * Invoke a model when the service method is called.
073 * 
074 * @author Efrat Jaeger, Yang Zhao
075 * @deprecated This class is mostly duplicated by org.geon.LidarWorkflowExecute.
076 * Use org.geon.LidarWorkflowExecute instead since it provides more functionality.
077 */
078public class ModelService {
079        public ModelService() {
080
081        }
082
083        /**
084         * This method takes a url specifying the model to be execute. The
085         * <i>args<i> argument is a record token that will be used to set
086         * corresponding attributes of the spedified model by naming match, (see
087         * _setAttribute() method). The results of executing the model is returned
088         * back by setting the value of some Attributes. In particular, only
089         * Attributes that have name matches the <i>resultLabels<i> are returned.
090         * The return result is a RecordToken which has the resultLabels as its
091         * feild.
092         * 
093         * @param url
094         *            The Model url.
095         * @param args
096         *            A set of attributes of the specified model.
097         * @param resultLabels
098         *            Labels of the returned result.
099         * @return The execution result.
100         * @exception IllegalActionException
101         *                If can not parse the url or failed to execute the model.
102         */
103        public String execute(String modelURL, String xmlParams) throws Exception {
104                URL url = new URL(modelURL);
105                if (url != null) {
106                        MoMLParser parser = new MoMLParser();
107                        NamedObj model;
108                        try {
109                                model = parser.parse(null, url);
110                                setInputs(model, xmlParams);
111
112                        } catch (Exception ex) {
113                                throw new IllegalActionException(ex
114                                                + "Failed to pass the model URL." + url.toString());
115                        }
116                        if (model instanceof CompositeActor) {
117                                return executeModel((CompositeActor) model);
118                        } else {
119                                return null;
120                        }
121                } else {
122                        return null;
123                }
124        }
125
126        /**
127         * This method takes model argument which is type of CompositeActor. The
128         * <i>args<i> argument is a record token that will be used to set
129         * corresponding attributes of the spedified model by naming match, (see
130         * _setAttribute() method). The results of executing the model is returned
131         * back by setting the value of some Attributes. In particular, only
132         * Attributes that have name matches the <i>resultLabels<i> are returned.
133         * The return result is a RecordToken which has the resultLabels as its
134         * feild.
135         * 
136         * @param model
137         *            The Model.
138         * @param args
139         *            A set of attributes of the specified model.
140         * @param resultLabels
141         *            Labels of the returned result.
142         * @return The execution result.
143         * @exception IllegalActionException
144         *                If failed to execute the model.
145         */
146        public String executeModel(CompositeActor model) throws Exception {
147                Manager manager = model.getManager();
148                if (manager == null) {
149                        // System.out.println("create manager for the model");
150                        manager = new Manager(model.workspace(), "Manager");
151                        model.setManager(manager);
152                }
153                // _setAttribute(model, args);
154
155                manager.execute();
156
157                return _getResult(model);
158        }
159
160        // /////////////////////////////////////////////////////////////////
161        // // private methods ////
162
163        /**
164         * Iterate over the resultLabels and check whether the specified model has
165         * Attribute with the same name of a label. If so, get the value of the
166         * attribute and return a record token with labels equal to resultLabels and
167         * values equal to the corresponding attribute value.
168         * 
169         * @param model
170         *            The model executed.
171         * @param resultLabels
172         *            Labels of the returned result.
173         * @return The execution result.
174         * @exception IllegalActionException
175         *                If reading the ports or setting the parameters causes it.
176         */
177        private String _getResult(CompositeActor model)
178                        throws IllegalActionException {
179
180                xml = "<variables>\n";
181
182                Iterator atts = model.attributeList().iterator();
183                while (atts.hasNext()) {
184                        Attribute att = (Attribute) atts.next();
185                        if (att instanceof Variable) {
186                                String attName = att.getName();
187                                if (attName.trim().toLowerCase().startsWith("out")) {
188                                        Variable var = (Variable) att;
189                                        System.out.println(var.getType().toString());
190                                        if (var.getType().equals(BaseType.UNKNOWN)) {
191                                                var.setTypeEquals(BaseType.GENERAL);
192                                        }
193
194                                        xml += "<output>\n";
195                                        xml += "<name>" + attName + "</name>\n";
196                                        processToken(var.getToken());
197                                        xml += "</output>\n";
198                                }
199                        }
200                }
201                xml += "</variables>";
202                return xml;
203        }
204
205        private void setInputs(NamedObj model, String xml) {
206                try {
207                        // TODO:: If an input is left empty remove the connected const
208                        // actor.
209                        ComponentEntity CE = (ComponentEntity) model;
210                        DocumentBuilderFactory factory = DocumentBuilderFactory
211                                        .newInstance();
212                        factory.setValidating(false);
213                        DocumentBuilder builder = factory.newDocumentBuilder();
214                        byte[] xmlBytes = xml.getBytes();
215                        InputStream is = new ByteArrayInputStream(xmlBytes);
216                        Document doc = builder.parse(is);
217
218                        NodeList inputs = doc.getElementsByTagName("input");
219                        for (int i = 0; i < inputs.getLength(); i++) {
220                                NodeList nameNode = ((Element) inputs.item(i))
221                                                .getElementsByTagName("name");
222                                String name = "";
223                                if (nameNode != null) {
224                                        // get the name of the input and process it.
225                                        name = nameNode.item(0).getFirstChild().getNodeValue()
226                                                        .trim();
227                                        name = name.replace('_', '.');
228                                        // find the const actor with this name.
229
230                                        NodeList channels = ((Element) inputs.item(i))
231                                                        .getElementsByTagName("channel");
232                                        for (int j = 0; j < channels.getLength(); j++) {
233                                                Element data = (Element) channels.item(j);
234                                                NodeList childs = data.getChildNodes();
235                                                for (int k = 0; k < childs.getLength(); k++) {
236                                                        Node node = childs.item(k);
237                                                        if (node instanceof Element) {
238                                                                // get the token for element nodes.
239                                                                Token dataToken = process((Element) node);
240                                                                // instantiate the desired variable with the
241                                                                // token value.
242                                                                // get the tag name const actor.
243                                                                ComponentEntity actor = getEntity(CE, name);
244                                                                if (actor instanceof Const) {
245                                                                        ((Const) actor).value
246                                                                                        .setExpression(dataToken.toString());
247                                                                        System.out.println("lalala");
248                                                                }
249                                                        }
250                                                }
251                                        }
252                                }
253                        }
254                } catch (Exception e) {
255                        e.printStackTrace();
256                }
257        }
258
259        private ComponentEntity getEntity(ComponentEntity CE, String inputName) {
260                int ind = inputName.indexOf(".");
261                while (ind != -1) {
262                        String aName = inputName.substring(0, ind);
263                        inputName = inputName.substring(ind + 1);
264                        ind = inputName.indexOf(".");
265                        CE = ((CompositeActor) CE).getEntity(aName);
266                }
267                CE = ((CompositeActor) CE).getEntity(inputName);
268                return CE;
269        }
270
271        private Token process(Element tag) throws IllegalActionException { // elem =
272                                                                                                                                                // channel..
273                String tagName = tag.getTagName();
274
275                if (tagName.equals("unsignedbyte")) {
276                        String val = tag.getFirstChild().getNodeValue().trim();
277                        UnsignedByteToken t = new UnsignedByteToken(val);
278                        return t;
279                }
280
281                if (tagName.equals("int")) {
282                        String val = tag.getFirstChild().getNodeValue().trim();
283                        IntToken t = new IntToken(val);
284                        return t;
285                }
286
287                if (tagName.equals("double")) {
288                        String val = tag.getFirstChild().getNodeValue().trim();
289                        DoubleToken t = new DoubleToken(val);
290                        return t;
291                }
292
293                if (tagName.equals("long")) {
294                        String val = tag.getFirstChild().getNodeValue().trim();
295                        LongToken t = new LongToken(val);
296                        return t;
297                }
298
299                if (tagName.equals("intmatrix")) {
300                        NodeList rows = tag.getElementsByTagName("row");
301                        int rowNum = rows.getLength();
302                        if (rowNum > 0) {
303                                NodeList tempCols = ((Element) rows.item(0))
304                                                .getElementsByTagName("value");
305                                int colNum = tempCols.getLength();
306                                int[][] Mat = new int[rowNum][colNum];
307                                for (int j = 0; j < rowNum; j++) {
308                                        NodeList Cols = ((Element) rows.item(j))
309                                                        .getElementsByTagName("value");
310                                        for (int k = 0; k < colNum; k++) {
311                                                String val = Cols.item(k).getFirstChild()
312                                                                .getNodeValue().trim();
313                                                Mat[j][k] = Integer.parseInt(val);
314                                        }
315                                }
316                                IntMatrixToken t = new IntMatrixToken(Mat);
317                                return t;
318                        } else
319                                return new IntMatrixToken();
320                }
321
322                if (tagName.equals("doublematrix")) {
323                        NodeList rows = tag.getElementsByTagName("row");
324                        int rowNum = rows.getLength();
325                        if (rowNum > 0) {
326                                NodeList tempCols = ((Element) rows.item(0))
327                                                .getElementsByTagName("value");
328                                int colNum = tempCols.getLength();
329                                double[][] Mat = new double[rowNum][colNum];
330                                for (int j = 0; j < rowNum; j++) {
331                                        NodeList Cols = ((Element) rows.item(j))
332                                                        .getElementsByTagName("value");
333                                        for (int k = 0; k < colNum; k++) {
334                                                String val = Cols.item(k).getFirstChild()
335                                                                .getNodeValue().trim();
336                                                Mat[j][k] = Double.parseDouble(val);
337                                        }
338                                }
339                                DoubleMatrixToken t = new DoubleMatrixToken(Mat);
340                                return t;
341                        } else
342                                return new DoubleMatrixToken();
343                }
344
345                if (tagName.equals("longmatrix")) {
346                        NodeList rows = tag.getElementsByTagName("row");
347                        int rowNum = rows.getLength();
348                        if (rowNum > 0) {
349                                NodeList tempCols = ((Element) rows.item(0))
350                                                .getElementsByTagName("value");
351                                int colNum = tempCols.getLength();
352                                long[][] Mat = new long[rowNum][colNum];
353                                for (int j = 0; j < rowNum; j++) {
354                                        NodeList Cols = ((Element) rows.item(j))
355                                                        .getElementsByTagName("value");
356                                        for (int k = 0; k < colNum; k++) {
357                                                String val = Cols.item(k).getFirstChild()
358                                                                .getNodeValue().trim();
359                                                Mat[j][k] = Long.parseLong(val);
360                                        }
361                                }
362                                LongMatrixToken t = new LongMatrixToken(Mat);
363                                return t;
364                        } else
365                                return new LongMatrixToken();
366                }
367
368                if (tagName.equals("booleanmatrix")) {
369                        NodeList rows = tag.getElementsByTagName("row");
370                        int rowNum = rows.getLength();
371                        if (rowNum > 0) {
372                                NodeList tempCols = ((Element) rows.item(0))
373                                                .getElementsByTagName("value");
374                                int colNum = tempCols.getLength();
375                                boolean[][] Mat = new boolean[rowNum][colNum];
376                                for (int j = 0; j < rowNum; j++) {
377                                        NodeList Cols = ((Element) rows.item(j))
378                                                        .getElementsByTagName("value");
379                                        for (int k = 0; k < colNum; k++) {
380                                                String val = Cols.item(k).getFirstChild()
381                                                                .getNodeValue().trim();
382                                                Mat[j][k] = Boolean.getBoolean(val);
383                                        }
384                                }
385                                BooleanMatrixToken t = new BooleanMatrixToken(Mat);
386                                return t;
387                        } else
388                                return new BooleanMatrixToken();
389                }
390
391                if (tagName.equals("string")) {
392                        String val = tag.getFirstChild().getNodeValue().trim();
393                        StringToken t = new StringToken(val);
394                        return t;
395                }
396
397                if (tagName.equals("array")) {
398                        Vector tVec = new Vector();
399                        NodeList arrChilds = tag.getChildNodes();
400
401                        // find only the element children
402                        for (int j = 0; j < arrChilds.getLength(); j++) {
403                                if (arrChilds.item(j) instanceof Element) {
404
405                                        Token token = process((Element) arrChilds.item(j));
406                                        tVec.add(token);
407                                }
408                        }
409                        Token tArr[] = new Token[tVec.size()];
410                        tVec.toArray(tArr);
411                        ArrayToken t = new ArrayToken(tArr);
412                        return t;
413                }
414
415                if (tagName.equals("record")) {
416                        NodeList labelNodes = tag.getElementsByTagName("label");
417                        NodeList valueNodes = tag.getElementsByTagName("value");
418                        int recLen = labelNodes.getLength();
419                        String[] labels = new String[recLen];
420                        Token[] tokens = new Token[recLen];
421                        for (int j = 0; j < recLen; j++) {
422                                labels[j] = labelNodes.item(j).getFirstChild().getNodeValue()
423                                                .trim();
424                        }
425                        int k = 0;
426                        for (int j = 0; j < valueNodes.getLength(); j++) {
427                                Element value = (Element) valueNodes.item(j);
428                                NodeList childs = value.getChildNodes();
429                                for (int l = 0; l < childs.getLength(); l++) {
430                                        Node node = childs.item(l);
431                                        if (node instanceof Element) {
432                                                tokens[k++] = process((Element) node);
433                                        }
434                                }
435                        }
436                        RecordToken t = new RecordToken(labels, tokens);
437                        return t;
438                }
439
440                Token t = new Token();
441                return t;
442        }
443
444        private void processToken(Token token) {
445
446                if (token instanceof UnsignedByteToken) {
447                        xml += "<unsignedbyte>";
448                        String val = ((UnsignedByteToken) token).unitsString();
449                        xml += val + "</unsignedbyte>\n";
450
451                } else if (token instanceof IntToken) {
452                        xml += "<int>";
453                        String val = ((IntToken) token).toString();
454                        xml += val + "</int>\n";
455
456                } else if (token instanceof DoubleToken) {
457                        xml += "<double>";
458                        String val = ((DoubleToken) token).toString();
459                        xml += val + "</double>\n";
460
461                } else if (token instanceof LongToken) {
462                        xml += "<long>";
463                        String val = ((LongToken) token).toString();
464                        xml += val + "</long>\n";
465
466                } else if (token instanceof IntMatrixToken) {
467                        xml += "<intmatrix>\n";
468                        int[][] Mat = ((IntMatrixToken) token).intMatrix();
469                        for (int i = 0; i < Mat.length; i++) {
470                                xml += "<row>\n";
471                                for (int j = 0; j < Mat[0].length; j++) {
472                                        xml += "<value>" + Mat[i][j] + "</value>\n";
473                                }
474                                xml += "</row>\n";
475                        }
476                        xml += "</intmatrix>\n";
477
478                } else if (token instanceof DoubleMatrixToken) {
479                        xml += "<doublematrix>\n";
480                        double[][] Mat = ((DoubleMatrixToken) token).doubleMatrix();
481                        for (int i = 0; i < Mat.length; i++) {
482                                xml += "<row>\n";
483                                for (int j = 0; j < Mat[0].length; j++) {
484                                        xml += "<value>" + Mat[i][j] + "</value>\n";
485                                }
486                                xml += "</row>\n";
487                        }
488                        xml += "</doublematrix>\n";
489
490                } else if (token instanceof LongMatrixToken) {
491                        xml += "<longmatrix>\n";
492                        long[][] Mat = ((LongMatrixToken) token).longMatrix();
493                        for (int i = 0; i < Mat.length; i++) {
494                                xml += "<row>\n";
495                                for (int j = 0; j < Mat[0].length; j++) {
496                                        xml += "<value>" + Mat[i][j] + "</value>\n";
497                                }
498                                xml += "</row>\n";
499                        }
500                        xml += "</longmatrix>\n";
501
502                } else if (token instanceof BooleanMatrixToken) {
503                        xml += "<booleanmatrix>\n";
504                        boolean Mat[][] = ((BooleanMatrixToken) token).booleanMatrix();
505                        for (int i = 0; i < Mat.length; i++) {
506                                xml += "<row>\n";
507                                for (int j = 0; j < Mat[0].length; j++) {
508                                        xml += "<value>" + Mat[i][j] + "</value>\n";
509                                }
510                                xml += "</row>\n";
511                        }
512                        xml += "</booleanmatrix>\n";
513
514                } else if (token instanceof StringToken) {
515                        xml += "<string>";
516                        String val = ((StringToken) token).stringValue();
517                        xml += val + "</string>\n";
518
519                } else if (token instanceof ArrayToken) {
520                        xml += "<array>\n";
521                        ArrayToken at = (ArrayToken) token;
522                        Token[] tArr = at.arrayValue();
523                        for (int i = 0; i < tArr.length; i++) {
524                                processToken(tArr[i]);
525                        }
526                        xml += "</array>\n";
527
528                } else if (token instanceof RecordToken) {
529                        xml += "<record>\n";
530                        RecordToken rt = (RecordToken) token;
531                        Object[] labelObjects = rt.labelSet().toArray();
532                        for (int i = 0; i < labelObjects.length; i++) {
533                                String label = (String) labelObjects[i];
534                                xml += "<label>" + label + "</label>\n";
535                                Token value = rt.get(label);
536                                xml += "<value>\n";
537                                processToken(value);
538                                xml += "</value>\n";
539                        }
540                        xml += "</record>\n";
541                }
542
543        }
544
545        private String xml = "";
546
547}