001/*
002 * Copyright (c) 2004-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.cipres.kepler;
031
032// Ptolemy package
033import org.cipres.CipresIDL.api1.Tree;
034import org.cipres.CipresIDL.api1.TreeMerge;
035import org.cipres.CipresIDL.api1.TreeScore;
036import org.cipres.helpers.CipresRegistry;
037import org.cipres.helpers.RegistryEntryWrapper;
038
039import ptolemy.actor.TypedAtomicActor;
040import ptolemy.actor.TypedIOPort;
041import ptolemy.data.ObjectToken;
042import ptolemy.data.type.BaseType;
043import ptolemy.kernel.CompositeEntity;
044import ptolemy.kernel.util.IllegalActionException;
045import ptolemy.kernel.util.NameDuplicationException;
046
047//////////////////////////////////////////////////////////////////////////
048//// TreeMerger
049/**
050 * The TreeMerger actor merges a set of trees got from the input port and sends
051 * the whole tree to the output port.This actor uses the "tree merge" services
052 * provided by the CIPRes CORBA registry.
053 * 
054 * @author Zhijie Guan
055 * @version $Id: TreeMerger.java 24234 2010-05-06 05:21:26Z welker $
056 */
057
058public class TreeMerger extends TypedAtomicActor {
059
060        /**
061         * Construct a TreeMerger actor with the given container and name.
062         * 
063         * @param container
064         *            The container.
065         * @param name
066         *            The name of this actor.
067         * @exception IllegalActionException
068         *                If the entity cannot be contained by the proposed
069         *                container.
070         * @exception NameDuplicationException
071         *                If the container already has an actor with this name.
072         */
073
074        public TreeMerger(CompositeEntity container, String name)
075                        throws NameDuplicationException, IllegalActionException {
076                super(container, name);
077
078                // construct the input port inputTrees
079                inputTrees = new TypedIOPort(this, "inputTrees", true, false);
080                inputTrees.setDisplayName("Trees");
081                inputTrees.setTypeEquals(BaseType.GENERAL);
082
083                // construct the output port outputTree
084                outputTree = new TypedIOPort(this, "outputTree", false, true);
085                outputTree.setDisplayName("Merged Tree");
086                // Set the type constraint.
087                outputTree.setTypeEquals(BaseType.GENERAL);
088
089                _attachText("_iconDescription", "<svg>\n" + "<rect x=\"0\" y=\"0\" "
090                                + "width=\"60\" height=\"20\" " + "style=\"fill:white\"/>\n"
091                                + "</svg>\n");
092
093        }
094
095        // /////////////////////////////////////////////////////////////////
096        // // ports and parameters ////
097        /**
098         * A set of trees in CIPRes tree data structure is passed to the TreeMerger
099         * actor through this input port. This port is an input port of type
100         * GENERAL.
101         */
102        public TypedIOPort inputTrees = null;
103
104        /**
105         * The merged whole tree is sent through this output port. This port is an
106         * output port of type GENERAL.
107         */
108        public TypedIOPort outputTree = null;
109
110        // /////////////////////////////////////////////////////////////////
111        // // functional variables ////
112        private org.cipres.CipresIDL.api1.Tree _finalTree = null;
113
114        // /////////////////////////////////////////////////////////////////
115        // // public methods ////
116
117        /**
118         * Merge a set of trees and send the whole tree to the output port.
119         * 
120         * @exception IllegalActionException
121         *                If it is thrown by the send() method sending out the
122         *                token.
123         */
124        public void fire() throws IllegalActionException {
125                super.fire();
126                if (inputTrees.hasToken(0)) {
127
128                        RegistryEntryWrapper treeMergerWrapper = null;
129                        try {
130                                // get the TreeMerge CORBA service from CIPRes registry
131                                treeMergerWrapper = CipresRegistry.getCipresServiceWrapper(
132                                                TreeMerge.class, null, null);
133                                TreeMerge service = (TreeMerge) treeMergerWrapper.getService();
134
135                                // merge trees using TreeMerge service
136                                _finalTree = service
137                                                .mergeTrees((Tree[]) (((ObjectToken) inputTrees.get(0))
138                                                                .getValue()));
139
140                                // fix _finalTree. This section should be replaced once the
141                                // fix_tree is open to public access
142                                _finalTree.m_newick = _finalTree.m_newick.trim();
143                                if (_finalTree.m_newick.lastIndexOf(';') == -1) {
144                                        _finalTree.m_newick += ";";
145                                }
146                                if (_finalTree.m_score == null) {
147                                        _finalTree.m_score = new TreeScore();
148                                        _finalTree.m_score.noScore(0);
149                                }
150
151                                // This is the code to fix the whole tree with the fix_tree
152                                // service.
153                                // Unfortunately this fix_tree service is not available for
154                                // public access yet.
155                                // finalTree = RecIDcm3Impl.fix_tree( service.mergeTrees(
156                                // (Tree[])((ObjectToken)inputTrees.get(0)).getValue() ) );
157
158                        } catch (Exception e) {
159                                e.printStackTrace();
160                        } finally {
161                                if (treeMergerWrapper != null) {
162                                        // release the TreeMerge service
163                                        treeMergerWrapper.releaseService();
164                                }
165                        }
166
167                        // send out the whole tree to the ouput tree port
168                        outputTree.send(0, new ObjectToken(_finalTree));
169                }
170        }
171}