001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.modules.sql.framework.model.impl;
042:
043: import java.awt.datatransfer.DataFlavor;
044: import java.awt.datatransfer.Transferable;
045: import java.awt.datatransfer.UnsupportedFlavorException;
046: import java.beans.PropertyChangeEvent;
047: import java.beans.PropertyChangeListener;
048: import java.io.IOException;
049: import java.util.ArrayList;
050: import java.util.Collections;
051: import java.util.Iterator;
052: import java.util.List;
053:
054: import org.w3c.dom.Element;
055: import org.w3c.dom.Node;
056: import org.w3c.dom.NodeList;
057:
058: import com.sun.sql.framework.exception.BaseException;
059: import com.sun.sql.framework.utils.StringUtil;
060:
061: /**
062: *
063: */
064: public class OperatorNodeX extends CommonNodeX implements
065: org.netbeans.modules.sql.framework.ui.graph.IOperatorXmlInfo,
066: Transferable {
067:
068: private static final String KEY_CHECKED = "Checked"; // NOI18N
069:
070: private static final String KEY_DISPLAYNAME = "DisplayName"; // NOI18N
071:
072: private static final String KEY_CLASSNAME = "className"; // NOI18N
073:
074: private static final String KEY_INPUTCOUNT = "InputNum"; // NOI18N
075:
076: private static final String KEY_OUTPUTCOUNT = "OutputNum"; // NOI18N
077:
078: private static final String KEY_TOOLTIP = "Tooltip"; // NOI18N
079:
080: private static final String KEY_TOOLBARCATEGORY = "ToolbarCategory"; // NOI18N
081:
082: private static final String KEY_SHOWPARENTHESIS = "ShowParenthesis"; // NOI18N
083:
084: private static final String KEY_JAVAOPERATOR = "JavaOperator"; // NOI18N
085:
086: private static final String KEY_OUTPUTPARAM = "OutputParam"; // NOI18N
087:
088: private static final String SUFFIX_DISPLAYNAME = KEY_DISPLAYNAME; // NOI18N
089:
090: private static final String SUFFIX_DISPLAYVALUES = "DisplayValues"; // NOI18N
091:
092: private static final String SUFFIX_CHOICES = "Choices"; // NOI18N
093:
094: private static final String SUFFIX_DEFAULT = "Default"; // NOI18N
095:
096: private static final String SUFFIX_EDITABLE = "Editable"; // NOI18N
097:
098: private static final String SUFFIX_STATIC = "Static"; // NOI18N
099:
100: private static final String KEY_OUTPUTPARAMEDITABLE = KEY_OUTPUTPARAM
101: + SUFFIX_EDITABLE; // NOI18N
102:
103: private static final String KEY_OUTPUTTOOLTIP = "OutputTooltip"; // NOI18N
104:
105: private static final String KEY_INPUTTOOLTIP = "InputTooltip"; // NOI18N
106:
107: private static final String KEY_INPUTPARAM = "InputParam"; // NOI18N
108:
109: private static final String KEY_INPUTPARAMEDITABLE = KEY_INPUTPARAM
110: + SUFFIX_EDITABLE; // NOI18N
111:
112: private static final String KEY_INPUTPARAMSTATIC = KEY_INPUTPARAM
113: + SUFFIX_STATIC; // NOI18N
114:
115: private static final String KEY_INPUTPARAMSTATICCHOICES = KEY_INPUTPARAMSTATIC
116: + SUFFIX_CHOICES; // NOI18N
117:
118: private static final String KEY_INPUTPARAMSTATICDEFAULT = KEY_INPUTPARAMSTATIC
119: + SUFFIX_DEFAULT; // NOI18N
120:
121: private static final String KEY_LISTDELIMITER = "attrListDelimiter"; // NOI18N
122:
123: private static DataFlavor[] mDataFlavorArray = new DataFlavor[1];
124: private ArrayList inputList = new ArrayList();
125: private ArrayList outputList = new ArrayList();
126: private List propChangeListners = new ArrayList();
127:
128: static {
129: try {
130: mDataFlavorArray[0] = new DataFlavor(
131: DataFlavor.javaJVMLocalObjectMimeType);
132: } catch (ClassNotFoundException ex) {
133: ex.printStackTrace();
134: }
135: }
136:
137: private void populateAttributes(Element opElem) {
138: NodeList children = opElem.getChildNodes();
139: Node node = null;
140: Element element = null;
141: String tName = null;
142: Object value = null;
143: for (int i = 0; i < children.getLength(); i++) {
144: node = children.item(i);
145: if (node.getNodeName().equals(TAG_ATTRIBUTE)) {
146: element = (Element) node;
147: tName = element.getAttribute(ATTR_NAME);
148: value = this .getAttributeValue(element);
149: this .attributes.put(tName, value);
150: }
151: }
152: }
153:
154: /**
155: * Creates a new instance of OperatorNodeX using the given DataObject.
156: *
157: * @param operatorObj DatabaObject used to create this operator node
158: */
159: public OperatorNodeX(Element opElement) throws BaseException {
160: super (opElement);
161: populateAttributes(opElement);
162:
163: String listDelimiter = (String) getAttributeValue(KEY_LISTDELIMITER);
164: if (listDelimiter == null) {
165: listDelimiter = ",";
166: }
167:
168: // add input graph field
169: for (int i = 0; i < getInputCount(); i++) {
170: int cnt = i + 1;
171:
172: String fieldName = (String) getAttributeValue(KEY_INPUTPARAM
173: + cnt);
174: OperatorFieldNodeX fieldNode = new OperatorFieldNodeX(
175: fieldName, getLocalizedAttributeValue(fieldName));
176:
177: String displayKey = (String) getAttributeValue(KEY_INPUTPARAM
178: + cnt + "_" + SUFFIX_DISPLAYNAME);
179: if (displayKey == null || displayKey.trim().length() == 0) {
180: fieldNode.setDisplayName(fieldName);
181: } else {
182: fieldNode
183: .setDisplayName(getLocalizedAttributeValue(displayKey));
184: }
185:
186: String toolTip = (String) getAttributeValue(KEY_INPUTTOOLTIP
187: + cnt);
188: fieldNode.setToolTip(getLocalizedAttributeValue(toolTip));
189: Boolean editFlag = (Boolean) getAttributeValue(KEY_INPUTPARAMEDITABLE
190: + cnt);
191: boolean editable = false;
192: if (editFlag != null && editFlag.booleanValue()) {
193: editable = true;
194: }
195: fieldNode.setEditable(editable);
196:
197: Boolean staticFlag = (Boolean) getAttributeValue(KEY_INPUTPARAMSTATIC
198: + cnt);
199: boolean isStatic = false;
200: if (staticFlag != null && staticFlag.booleanValue()) {
201: isStatic = true;
202: }
203: fieldNode.setStatic(isStatic);
204:
205: if (isStatic) {
206: String acceptableValStr = (String) getAttributeValue(KEY_INPUTPARAMSTATICCHOICES
207: + cnt);
208: List acceptableValues = Collections.EMPTY_LIST;
209: if (acceptableValStr != null
210: && acceptableValStr.trim().length() != 0) {
211: acceptableValues = StringUtil.createStringListFrom(
212: acceptableValStr, listDelimiter.charAt(0));
213: fieldNode.setAcceptableValues(acceptableValues);
214:
215: String displayValKey = (String) getAttributeValue(KEY_INPUTPARAMSTATICCHOICES
216: + cnt + "_" + SUFFIX_DISPLAYVALUES);
217: String displayValStr = getLocalizedAttributeValue(displayValKey);
218:
219: if (displayValStr != null
220: && displayValStr.trim().length() != 0) {
221: List displayValues = StringUtil
222: .createStringListFrom(displayValStr,
223: listDelimiter.charAt(0));
224: if (displayValues.size() == acceptableValues
225: .size()) {
226: fieldNode
227: .setAcceptableDisplayValues(displayValues);
228: }
229: }
230:
231: String defaultValue = (String) getAttributeValue(KEY_INPUTPARAMSTATICDEFAULT
232: + cnt);
233: if (StringUtil.isNullString(defaultValue)) {
234: throw new BaseException(
235: "Must have a valid default value for a static parameter");
236: }
237:
238: fieldNode.setDefaultValue(defaultValue);
239: }
240: }
241:
242: inputList.add(fieldNode);
243: }
244:
245: // add output graph field
246: for (int i = 0; i < getOutputCount(); i++) {
247: int cnt = i + 1;
248:
249: String fieldName = (String) getAttributeValue(KEY_OUTPUTPARAM
250: + cnt);
251: OperatorFieldNodeX fieldNode = new OperatorFieldNodeX(
252: fieldName, getLocalizedAttributeValue(fieldName));
253:
254: String displayKey = (String) getAttributeValue(KEY_OUTPUTPARAM
255: + cnt + "_" + SUFFIX_DISPLAYNAME);
256: if (displayKey == null || displayKey.trim().length() == 0) {
257: fieldNode.setDisplayName(fieldName);
258: } else {
259: fieldNode
260: .setDisplayName(getLocalizedAttributeValue(displayKey));
261: }
262:
263: String toolTip = (String) getAttributeValue(KEY_OUTPUTTOOLTIP
264: + cnt);
265: fieldNode.setToolTip(getLocalizedAttributeValue(toolTip));
266:
267: Boolean edit = (Boolean) getAttributeValue(KEY_OUTPUTPARAMEDITABLE
268: + cnt);
269: boolean editable = false;
270: if (edit != null && edit.booleanValue()) {
271: editable = true;
272: }
273: fieldNode.setEditable(editable);
274:
275: outputList.add(fieldNode);
276: }
277: }
278:
279: /**
280: * Gets the value of the attribute with the given name
281: *
282: * @param name name of attribute whose value is to be retrieved
283: * @return value of the attribute
284: */
285: public Object getAttributeValue(String tName) {
286: return this .attributes.get(tName);
287: }
288:
289: private String getLocalizedAttributeValue(String attrVal) {
290: return getLocalizedValue(attrVal);
291: }
292:
293: /**
294: * Gets number of inputs for thie operator
295: *
296: * @return number of inputs
297: */
298: public int getInputCount() {
299: Integer cnt = (Integer) this .attributes.get(KEY_INPUTCOUNT);
300: return cnt.intValue();
301: }
302:
303: /**
304: * Gets the (non-localized) name of this operator
305: *
306: * @return name
307: */
308: public String getName() {
309: String tname = super .getName();
310:
311: if (tname != null) {
312: return tname;
313: }
314: return "op";
315: }
316:
317: /**
318: * Gets class name of SQLBuilder object associated with this operator
319: *
320: * @return object type
321: */
322: public String getObjectClassName() {
323: return (String) this .attributes.get(KEY_CLASSNAME);
324: }
325:
326: /**
327: * Gets number of outputs for this operator
328: *
329: * @return number of outputs
330: */
331: public int getOutputCount() {
332: Integer cnt = (Integer) this .attributes.get(KEY_OUTPUTCOUNT);
333: if (cnt != null) {
334: return cnt.intValue();
335: } else {
336: return 0;
337: }
338: }
339:
340: /**
341: * Gets tool tip for the operator
342: *
343: * @return tool tip
344: */
345: public String getToolTip() {
346: String toolTip = (String) this .attributes.get(KEY_TOOLTIP);
347: return getLocalizedValue(toolTip);
348: }
349:
350: /**
351: * Indicates whether to display this operator in the toolbar
352: *
353: * @return true if displayable, false otherwise
354: */
355: public boolean isChecked() {
356: Boolean checked = (Boolean) this .attributes.get(KEY_CHECKED);
357: if (checked != null) {
358: return checked.booleanValue();
359: }
360: return false;
361: }
362:
363: public int getToolbarType() {
364: Integer toolbarType = (Integer) this .attributes
365: .get(KEY_TOOLBARCATEGORY);
366: int ret = org.netbeans.modules.sql.framework.ui.graph.IOperatorXmlInfoModel.CATEGORY_ALL;
367: if (toolbarType != null) {
368: ret = toolbarType.intValue();
369: }
370:
371: return ret;
372: }
373:
374: /**
375: * Returns an object which represents the data to be transferred. The class of the
376: * object returned is defined by the representation class of the flavor.
377: *
378: * @param flavor the requested flavor for the data
379: * @return data to be transferred
380: * @throws IOException if the data is no longer available in the requested flavor.
381: * @throws UnsupportedFlavorException if the requested data flavor is not supported.
382: * @see DataFlavor#getRepresentationClass
383: */
384: public Object getTransferData(DataFlavor flavor)
385: throws UnsupportedFlavorException, IOException {
386: return (isDataFlavorSupported(flavor)) ? this : null;
387: }
388:
389: /**
390: * Returns an array of DataFlavor objects indicating the flavors the data can be
391: * provided in. The array should be ordered according to preference for providing the
392: * data (from most richly descriptive to least descriptive).
393: *
394: * @return an array of data flavors in which this data can be transferred
395: */
396: public DataFlavor[] getTransferDataFlavors() {
397: return mDataFlavorArray;
398: }
399:
400: /**
401: * Returns whether or not the specified data flavor is supported for this object.
402: *
403: * @param flavor the requested flavor for the data
404: * @return boolean indicating whether or not the data flavor is supported
405: */
406: public boolean isDataFlavorSupported(DataFlavor flavor) {
407: for (int i = 0; i < mDataFlavorArray.length; i++) {
408: if (flavor.equals(mDataFlavorArray[i])) {
409: return true;
410: }
411: }
412:
413: return false;
414: }
415:
416: /**
417: * override canRename to return false
418: *
419: * @return false
420: */
421: public boolean canRename() {
422: return false;
423: }
424:
425: /**
426: * Indicates whether this instance can be copied.
427: *
428: * @return true if copiable, false otherwise
429: */
430: public boolean canCopy() {
431: return true;
432: }
433:
434: /**
435: * Called when a drag is started with this node
436: *
437: * @return this
438: */
439: public Transferable drag() {
440: return clipboardCopy();
441: }
442:
443: /**
444: * Gets Transferable instance of this object
445: *
446: * @return Transferable reference to this
447: */
448: public Transferable clipboardCopy() {
449: return this ;
450: }
451:
452: /**
453: * Sets whether to display this operator in the toolbar
454: *
455: * @param checked true if this operator should be displayed
456: */
457: public void setChecked(boolean checked) {
458: Boolean oldSel = (Boolean) this .attributes.get(KEY_CHECKED);
459: this .attributes.put(KEY_CHECKED, Boolean.valueOf(checked));
460: firePropertyChange(OPERATOR_CHECKED, oldSel, Boolean
461: .valueOf(checked));
462: }
463:
464: /**
465: * Gets the transferable object
466: *
467: * @return transferable
468: */
469: public Transferable getTransferable() {
470: return this ;
471: }
472:
473: /**
474: * Sets an attribute's value
475: *
476: * @param attrName attribute name
477: * @param val attribute value
478: */
479: public void setAttributeValue(String attrName, Object val) {
480:
481: }
482:
483: /**
484: * Gets the input list of IOperatorFields
485: *
486: * @return list of input list
487: */
488: public List getInputFields() {
489: return inputList;
490: }
491:
492: /**
493: * Gets the output list of IOperatorFields
494: *
495: * @return list of output list
496: */
497: public List getOutputFields() {
498: return outputList;
499: }
500:
501: /**
502: * Signals that an instance of this operator should be 'dropped' onto the current
503: * collaboration canvas.
504: *
505: * @param dropped true if a new instance should be dropped.
506: */
507: public void setDropInstance(boolean dropped) {
508: firePropertyChange(OPERATOR_DROPPED, Boolean.FALSE, Boolean
509: .valueOf(dropped));
510: }
511:
512: /**
513: * check if open and close parenthesis should be used
514: *
515: * @return bool
516: */
517: public boolean isShowParenthesis() {
518: Boolean showParenthesis = (Boolean) this .attributes
519: .get(KEY_SHOWPARENTHESIS);
520: if (showParenthesis != null) {
521: return showParenthesis.booleanValue();
522: }
523:
524: return false;
525: }
526:
527: public org.netbeans.modules.sql.framework.ui.graph.IOperatorField getInputField(
528: String tName) {
529: Iterator it = this .inputList.iterator();
530: while (it.hasNext()) {
531: org.netbeans.modules.sql.framework.ui.graph.IOperatorField field = (org.netbeans.modules.sql.framework.ui.graph.IOperatorField) it
532: .next();
533: if (field.getName().equals(tName)) {
534: return field;
535: }
536: }
537:
538: return null;
539: }
540:
541: /**
542: * Is this a java operator.
543: *
544: * @return true if this operator is implemented and should be invoked in java.
545: */
546: public boolean isJavaOperator() {
547: Boolean javaOperator = (Boolean) this .attributes
548: .get(KEY_JAVAOPERATOR);
549: if (javaOperator != null) {
550: return javaOperator.booleanValue();
551: }
552: return false;
553: }
554:
555: public void addPropertyChangeListener(PropertyChangeListener l) {
556: this .propChangeListners.add(l);
557: }
558:
559: public void removePropertyChangeListener(PropertyChangeListener l) {
560: this .propChangeListners.remove(l);
561: }
562:
563: private void firePropertyChange(String propName, Object oldValue,
564: Object newValue) {
565: PropertyChangeEvent pce = new PropertyChangeEvent(this ,
566: propName, oldValue, newValue);
567: Iterator itr = this .propChangeListners.iterator();
568: PropertyChangeListener pcl = null;
569: while (itr.hasNext()) {
570: pcl = (PropertyChangeListener) itr.next();
571:
572: try {
573: pcl.propertyChange(pce);
574: } catch (Exception ex) {
575: // Log
576: }
577: }
578: }
579: }
|