001/*
002 * Copyright (c) 2003-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.kepler.objectmanager.data.db;
031
032import java.util.Iterator;
033
034import ptolemy.actor.gui.Effigy;
035import ptolemy.actor.gui.PtolemyEffigy;
036import ptolemy.actor.gui.Tableau;
037import ptolemy.actor.gui.TableauFactory;
038import ptolemy.kernel.util.Attribute;
039import ptolemy.kernel.util.IllegalActionException;
040import ptolemy.kernel.util.NameDuplicationException;
041import ptolemy.kernel.util.NamedObj;
042import ptolemy.kernel.util.Settable;
043import ptolemy.kernel.util.StringAttribute;
044
045//////////////////////////////////////////////////////////////////////////
046//// QBTableauFactory
047/**
048 * This class is an attribute that creates a Query Builder to edit a specified
049 * string attribute in the container of this attribute.
050 */
051public class QBTableauFactory extends TableauFactory {
052
053        /**
054         * Create a factory with the given name and container.
055         * 
056         * @param container
057         *            The container.
058         * @param name
059         *            The name.
060         * @exception IllegalActionException
061         *                If the container is incompatible with this attribute.
062         * @exception NameDuplicationException
063         *                If the name coincides with an attribute already in the
064         *                container.
065         */
066        public QBTableauFactory(NamedObj container, String name)
067                        throws IllegalActionException, NameDuplicationException {
068                super(container, name);
069
070                _sqlAttrName = new StringAttribute(this, "sqlName");
071                ((Settable) _sqlAttrName).setExpression("sqlDef");
072                _schemaAttrName = new StringAttribute(this, "schemaName");
073                ((Settable) _schemaAttrName).setExpression("schemaDef");
074        }
075
076        // /////////////////////////////////////////////////////////////////
077        // // parameters ////
078
079        /** The name of the sql definition string attribute that is to be edited. */
080        public StringAttribute _sqlAttrName;
081
082        /** The name of the schema definition string attribute (not editted) */
083        public StringAttribute _schemaAttrName;
084
085        // /////////////////////////////////////////////////////////////////
086        // // public methods ////
087
088        /**
089         * Remove any editor that may have been associated with this object by a
090         * previous call to createEditor().
091         */
092        public void clear() {
093                _editor = null;
094        }
095
096        /**
097         * Create a tableau for the specified effigy. The tableau will be created
098         * with a new unique name with the specified effigy as its container. If
099         * this factory cannot create a tableau for the given effigy (it is not an
100         * instance of PtolemyEffigy), then return null.
101         * 
102         * @param effigy
103         *            The component effigy.
104         * @return A tableau for the effigy, or null if one cannot be created.
105         * @exception Exception
106         *                If the factory should be able to create a Tableau for the
107         *                effigy, but something goes wrong.
108         */
109        public Tableau createTableau(Effigy effigy) throws Exception {
110                if (!(effigy instanceof PtolemyEffigy)) {
111                        return null;
112                }
113                NamedObj object = ((PtolemyEffigy) effigy).getModel();
114                Attribute sqlAttrName = object.getAttribute(_sqlAttrName
115                                .getExpression());
116                if (!(sqlAttrName instanceof StringAttribute)) {
117                        throw new IllegalActionException(object, "Expected "
118                                        + object.getFullName()
119                                        + " to contain a StringAttribute named "
120                                        + _sqlAttrName.getExpression() + ", but it does not.");
121                }
122
123                Attribute schemaAttrName = object.getAttribute(_schemaAttrName
124                                .getExpression());
125                if (!(schemaAttrName instanceof StringAttribute)) {
126                        throw new IllegalActionException(object, "Expected "
127                                        + object.getFullName()
128                                        + " to contain a StringAttribute named "
129                                        + _schemaAttrName.getExpression() + ", but it does not.");
130                }
131
132                // effigy may already contain a texteffigy.
133                QBEffigy qbEffigy = null;
134                Iterator subEffigies = effigy.entityList(QBEffigy.class).iterator();
135                while (subEffigies.hasNext()) {
136                        qbEffigy = (QBEffigy) subEffigies.next();
137                }
138                if (qbEffigy == null) {
139                        qbEffigy = QBEffigy.newQBEffigy(effigy);
140                }
141
142                // qbEffigy may already have a tableau.
143                Iterator tableaux = qbEffigy.entityList(QBTableau.class).iterator();
144                if (tableaux.hasNext()) {
145                        return (QBTableau) tableaux.next();
146                }
147
148                // Need a new tableau, so create an editor for it.
149                if (_editor == null) {
150                        _editor = new QBEditor(this, (StringAttribute) sqlAttrName,
151                                        (StringAttribute) schemaAttrName, "Query Builder");
152                }
153
154                return new QBTableau(qbEffigy, "_tableau", _editor);
155        }
156
157        // /////////////////////////////////////////////////////////////////
158        // // private members ////
159
160        // Keep track of an open editor so that it isn't opened more than
161        // once.
162        private QBEditor _editor;
163}