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.ui.graph.impl;
042:
043: import java.awt.datatransfer.DataFlavor;
044: import java.awt.datatransfer.Transferable;
045: import java.awt.datatransfer.UnsupportedFlavorException;
046: import java.beans.BeanInfo;
047: import java.io.IOException;
048: import java.util.ArrayList;
049: import java.util.Collections;
050: import java.util.Iterator;
051: import java.util.List;
052:
053: import javax.swing.Icon;
054: import javax.swing.ImageIcon;
055:
056: import org.netbeans.modules.sql.framework.ui.graph.IOperatorField;
057: import org.netbeans.modules.sql.framework.ui.graph.IOperatorXmlInfo;
058: import org.netbeans.modules.sql.framework.ui.graph.IOperatorXmlInfoModel;
059: import org.openide.loaders.DataObject;
060: import org.openide.nodes.Children;
061:
062: import com.sun.sql.framework.exception.BaseException;
063: import com.sun.sql.framework.utils.StringUtil;
064:
065: /**
066: * @author Ritesh Adval
067: * @author Jonathan Giron
068: * @version $Revision$
069: */
070: public class OperatorNode extends CommonNode implements
071: IOperatorXmlInfo, Transferable {
072:
073: private static final String KEY_CHECKED = "Checked"; //NOI18N
074:
075: private static final String KEY_DISPLAYNAME = "DisplayName"; // NOI18N
076:
077: private static final String KEY_CLASSNAME = "className"; // NOI18N
078:
079: private static final String KEY_INPUTCOUNT = "InputNum"; // NOI18N
080:
081: private static final String KEY_OUTPUTCOUNT = "OutputNum"; // NOI18N
082:
083: private static final String KEY_TOOLTIP = "Tooltip"; // NOI18N
084:
085: private static final String KEY_TOOLBARCATEGORY = "ToolbarCategory"; // NOI18N
086:
087: private static final String KEY_SHOWPARENTHESIS = "ShowParenthesis"; // NOI18N
088:
089: private static final String KEY_JAVAOPERATOR = "JavaOperator"; // NOI18N
090:
091: private static final String KEY_OUTPUTPARAM = "OutputParam"; // NOI18N
092:
093: private static final String SUFFIX_DISPLAYNAME = KEY_DISPLAYNAME; //NOI18N
094:
095: private static final String SUFFIX_DISPLAYVALUES = "DisplayValues"; //NOI18N
096:
097: private static final String SUFFIX_CHOICES = "Choices"; //NOI18N
098:
099: private static final String SUFFIX_DEFAULT = "Default"; // NOI18N
100:
101: private static final String SUFFIX_EDITABLE = "Editable"; //NOI18N
102:
103: private static final String SUFFIX_STATIC = "Static"; //NOI18N
104:
105: private static final String KEY_OUTPUTPARAMEDITABLE = KEY_OUTPUTPARAM
106: + SUFFIX_EDITABLE; // NOI18N
107:
108: private static final String KEY_OUTPUTTOOLTIP = "OutputTooltip"; //NOI18N
109:
110: private static final String KEY_INPUTTOOLTIP = "InputTooltip"; //NOI18N
111:
112: private static final String KEY_INPUTPARAM = "InputParam"; //NOI18N
113:
114: private static final String KEY_INPUTPARAMEDITABLE = KEY_INPUTPARAM
115: + SUFFIX_EDITABLE; //NOI18N
116:
117: private static final String KEY_INPUTPARAMSTATIC = KEY_INPUTPARAM
118: + SUFFIX_STATIC; //NOI18N
119:
120: private static final String KEY_INPUTPARAMSTATICCHOICES = KEY_INPUTPARAMSTATIC
121: + SUFFIX_CHOICES; //NOI18N
122:
123: private static final String KEY_INPUTPARAMSTATICDEFAULT = KEY_INPUTPARAMSTATIC
124: + SUFFIX_DEFAULT; //NOI18N
125:
126: private static final String KEY_LISTDELIMITER = "attrListDelimiter"; //NOI18N
127:
128: private DataObject operatorObj;
129: private static DataFlavor[] mDataFlavorArray = new DataFlavor[1];
130: private ArrayList inputList = new ArrayList();
131: private ArrayList outputList = new ArrayList();
132:
133: static {
134: try {
135: mDataFlavorArray[0] = new DataFlavor(
136: DataFlavor.javaJVMLocalObjectMimeType);
137: } catch (ClassNotFoundException ex) {
138: ex.printStackTrace();
139: }
140: }
141:
142: /**
143: * Creates a new instance of OperatorNode using the given DataObject.
144: *
145: * @param operatorObj DatabaObject used to create this operator node
146: */
147: public OperatorNode(DataObject operatorObj) throws BaseException {
148: super (operatorObj, Children.LEAF);
149: this .operatorObj = operatorObj;
150:
151: String listDelimiter = (String) getAttributeValue(KEY_LISTDELIMITER);
152: if (listDelimiter == null) {
153: listDelimiter = ",";
154: }
155:
156: //add input graph field
157: for (int i = 0; i < getInputCount(); i++) {
158: int cnt = i + 1;
159:
160: String fieldName = (String) getAttributeValue(KEY_INPUTPARAM
161: + cnt);
162: OperatorFieldNode fieldNode = new OperatorFieldNode(
163: fieldName, getLocalizedAttributeValue(fieldName));
164:
165: String displayKey = (String) getAttributeValue(KEY_INPUTPARAM
166: + cnt + "_" + SUFFIX_DISPLAYNAME);
167: if (displayKey == null || displayKey.trim().length() == 0) {
168: fieldNode.setDisplayName(fieldName);
169: } else {
170: fieldNode
171: .setDisplayName(getLocalizedAttributeValue(displayKey));
172: }
173:
174: String toolTip = (String) getAttributeValue(KEY_INPUTTOOLTIP
175: + cnt);
176: fieldNode.setToolTip(getLocalizedAttributeValue(toolTip));
177: Boolean editFlag = (Boolean) getAttributeValue(KEY_INPUTPARAMEDITABLE
178: + cnt);
179: boolean editable = false;
180: if (editFlag != null && editFlag.booleanValue()) {
181: editable = true;
182: }
183: fieldNode.setEditable(editable);
184:
185: Boolean staticFlag = (Boolean) getAttributeValue(KEY_INPUTPARAMSTATIC
186: + cnt);
187: boolean isStatic = false;
188: if (staticFlag != null && staticFlag.booleanValue()) {
189: isStatic = true;
190: }
191: fieldNode.setStatic(isStatic);
192:
193: if (isStatic) {
194: String acceptableValStr = (String) getAttributeValue(KEY_INPUTPARAMSTATICCHOICES
195: + cnt);
196: List acceptableValues = Collections.EMPTY_LIST;
197: if (acceptableValStr != null
198: && acceptableValStr.trim().length() != 0) {
199: acceptableValues = StringUtil.createStringListFrom(
200: acceptableValStr, listDelimiter.charAt(0));
201: fieldNode.setAcceptableValues(acceptableValues);
202:
203: String displayValKey = (String) getAttributeValue(KEY_INPUTPARAMSTATICCHOICES
204: + cnt + "_" + SUFFIX_DISPLAYVALUES);
205: String displayValStr = getLocalizedAttributeValue(displayValKey);
206:
207: if (displayValStr != null
208: && displayValStr.trim().length() != 0) {
209: List displayValues = StringUtil
210: .createStringListFrom(displayValStr,
211: listDelimiter.charAt(0));
212: if (displayValues.size() == acceptableValues
213: .size()) {
214: fieldNode
215: .setAcceptableDisplayValues(displayValues);
216: }
217: }
218:
219: String defaultValue = (String) getAttributeValue(KEY_INPUTPARAMSTATICDEFAULT
220: + cnt);
221: if (StringUtil.isNullString(defaultValue)) {
222: throw new BaseException(
223: "Must have a valid default value for a static parameter");
224: }
225:
226: fieldNode.setDefaultValue(defaultValue);
227: }
228: }
229:
230: inputList.add(fieldNode);
231: }
232:
233: //add output graph field
234: for (int i = 0; i < getOutputCount(); i++) {
235: int cnt = i + 1;
236:
237: String fieldName = (String) getAttributeValue(KEY_OUTPUTPARAM
238: + cnt);
239: OperatorFieldNode fieldNode = new OperatorFieldNode(
240: fieldName, getLocalizedAttributeValue(fieldName));
241:
242: String displayKey = (String) getAttributeValue(KEY_OUTPUTPARAM
243: + cnt + "_" + SUFFIX_DISPLAYNAME);
244: if (displayKey == null || displayKey.trim().length() == 0) {
245: fieldNode.setDisplayName(fieldName);
246: } else {
247: fieldNode
248: .setDisplayName(getLocalizedAttributeValue(displayKey));
249: }
250:
251: String toolTip = (String) getAttributeValue(KEY_OUTPUTTOOLTIP
252: + cnt);
253: fieldNode.setToolTip(getLocalizedAttributeValue(toolTip));
254:
255: Boolean edit = (Boolean) getAttributeValue(KEY_OUTPUTPARAMEDITABLE
256: + cnt);
257: boolean editable = false;
258: if (edit != null && edit.booleanValue()) {
259: editable = true;
260: }
261: fieldNode.setEditable(editable);
262:
263: outputList.add(fieldNode);
264: }
265: }
266:
267: /**
268: * Gets the value of the attribute with the given name
269: *
270: * @param name name of attribute whose value is to be retrieved
271: * @return value of the attribute
272: */
273: public Object getAttributeValue(String name) {
274: Object attrVal = operatorObj.getPrimaryFile()
275: .getAttribute(name);
276: return attrVal;
277: }
278:
279: private String getLocalizedAttributeValue(String attrVal) {
280: return getLocalizedValue(attrVal);
281: }
282:
283: /**
284: * Gets the (localized) display name of this operator
285: *
286: * @return display name
287: */
288: public String getDisplayName() {
289: if (operatorObj != null) {
290: String displayName = (String) operatorObj.getPrimaryFile()
291: .getAttribute(KEY_DISPLAYNAME);
292: return getLocalizedValue(displayName);
293: }
294:
295: return "disop";
296: }
297:
298: /**
299: * Gets the icon for this operator
300: *
301: * @return operator icon
302: */
303: public Icon getIcon() {
304: return new ImageIcon(operatorObj.getNodeDelegate().getIcon(
305: BeanInfo.ICON_COLOR_16x16));
306: }
307:
308: /**
309: * Gets number of inputs for thie operator
310: *
311: * @return number of inputs
312: */
313: public int getInputCount() {
314: Integer cnt = (Integer) operatorObj.getPrimaryFile()
315: .getAttribute(KEY_INPUTCOUNT);
316: return cnt.intValue();
317: }
318:
319: /**
320: * Gets the (non-localized) name of this operator
321: *
322: * @return name
323: */
324: public String getName() {
325: if (operatorObj != null) {
326: return operatorObj.getName();
327: }
328: return "op";
329: }
330:
331: /**
332: * Gets class name of SQLBuilder object associated with this operator
333: *
334: * @return object type
335: */
336: public String getObjectClassName() {
337: if (operatorObj != null) {
338: String objectType = (String) operatorObj.getPrimaryFile()
339: .getAttribute(KEY_CLASSNAME);
340: return objectType;
341: }
342:
343: return null;
344: }
345:
346: /**
347: * Gets number of outputs for this operator
348: *
349: * @return number of outputs
350: */
351: public int getOutputCount() {
352: Integer cnt = (Integer) operatorObj.getPrimaryFile()
353: .getAttribute(KEY_OUTPUTCOUNT);
354: return cnt.intValue();
355: }
356:
357: /**
358: * Gets tool tip for the operator
359: *
360: * @return tool tip
361: */
362: public String getToolTip() {
363: String toolTip = (String) operatorObj.getPrimaryFile()
364: .getAttribute(KEY_TOOLTIP);
365: return getLocalizedValue(toolTip);
366: }
367:
368: /**
369: * Indicates whether to display this operator in the toolbar
370: *
371: * @return true if displayable, false otherwise
372: */
373: public boolean isChecked() {
374: Boolean checked = (Boolean) operatorObj.getPrimaryFile()
375: .getAttribute(KEY_CHECKED);
376: if (checked != null) {
377: return checked.booleanValue();
378: }
379: return false;
380: }
381:
382: public int getToolbarType() {
383: Integer toolbarType = (Integer) operatorObj.getPrimaryFile()
384: .getAttribute(KEY_TOOLBARCATEGORY);
385: int ret = IOperatorXmlInfoModel.CATEGORY_ALL;
386: if (toolbarType != null) {
387: ret = toolbarType.intValue();
388: }
389:
390: return ret;
391: }
392:
393: /**
394: * Returns an object which represents the data to be transferred. The class of the
395: * object returned is defined by the representation class of the flavor.
396: *
397: * @param flavor the requested flavor for the data
398: * @return data to be transferred
399: * @throws IOException if the data is no longer available in the requested flavor.
400: * @throws UnsupportedFlavorException if the requested data flavor is not supported.
401: * @see DataFlavor#getRepresentationClass
402: */
403: public Object getTransferData(DataFlavor flavor)
404: throws UnsupportedFlavorException, IOException {
405: return (isDataFlavorSupported(flavor)) ? this : null;
406: }
407:
408: /**
409: * Returns an array of DataFlavor objects indicating the flavors the data can be
410: * provided in. The array should be ordered according to preference for providing the
411: * data (from most richly descriptive to least descriptive).
412: *
413: * @return an array of data flavors in which this data can be transferred
414: */
415: public DataFlavor[] getTransferDataFlavors() {
416: return mDataFlavorArray;
417: }
418:
419: /**
420: * Returns whether or not the specified data flavor is supported for this object.
421: *
422: * @param flavor the requested flavor for the data
423: * @return boolean indicating whether or not the data flavor is supported
424: */
425: public boolean isDataFlavorSupported(DataFlavor flavor) {
426: for (int i = 0; i < mDataFlavorArray.length; i++) {
427: if (flavor.equals(mDataFlavorArray[i])) {
428: return true;
429: }
430: }
431:
432: return false;
433: }
434:
435: /**
436: * override canRename to return false
437: *
438: * @return false
439: */
440: public boolean canRename() {
441: return false;
442: }
443:
444: /**
445: * Indicates whether this instance can be copied.
446: *
447: * @return true if copiable, false otherwise
448: */
449: public boolean canCopy() {
450: return true;
451: }
452:
453: /**
454: * Called when a drag is started with this node
455: *
456: * @return this
457: */
458: public Transferable drag() {
459: return clipboardCopy();
460: }
461:
462: /**
463: * Gets Transferable instance of this object
464: *
465: * @return Transferable reference to this
466: */
467: public Transferable clipboardCopy() {
468: return this ;
469: }
470:
471: /**
472: * Sets whether to display this operator in the toolbar
473: *
474: * @param checked true if this operator should be displayed
475: */
476: public void setChecked(boolean checked) {
477: try {
478: Boolean oldSel = (Boolean) operatorObj.getPrimaryFile()
479: .getAttribute(KEY_CHECKED);
480: operatorObj.getPrimaryFile().setAttribute(KEY_CHECKED,
481: Boolean.valueOf(checked));
482: firePropertyChange(OPERATOR_CHECKED, oldSel, Boolean
483: .valueOf(checked));
484: } catch (IOException ex) {
485: ex.printStackTrace();
486: }
487: }
488:
489: /**
490: * Gets the transferable object
491: *
492: * @return transferable
493: */
494: public Transferable getTransferable() {
495: return this ;
496: }
497:
498: /**
499: * Sets an attribute's value
500: *
501: * @param attrName attribute name
502: * @param val attribute value
503: */
504: public void setAttributeValue(String attrName, Object val) {
505:
506: }
507:
508: /**
509: * Gets the input list of IOperatorFields
510: *
511: * @return list of input list
512: */
513: public List getInputFields() {
514: return inputList;
515: }
516:
517: /**
518: * Gets the output list of IOperatorFields
519: *
520: * @return list of output list
521: */
522: public List getOutputFields() {
523: return outputList;
524: }
525:
526: /**
527: * Signals that an instance of this operator should be 'dropped' onto the current
528: * collaboration canvas.
529: *
530: * @param dropped true if a new instance should be dropped.
531: */
532: public void setDropInstance(boolean dropped) {
533: firePropertyChange(OPERATOR_DROPPED, Boolean.FALSE, Boolean
534: .valueOf(dropped));
535: }
536:
537: /**
538: * check if open and close parenthesis should be used
539: *
540: * @return bool
541: */
542: public boolean isShowParenthesis() {
543: Boolean showParenthesis = (Boolean) operatorObj
544: .getPrimaryFile().getAttribute(KEY_SHOWPARENTHESIS);
545: if (showParenthesis != null) {
546: return showParenthesis.booleanValue();
547: }
548:
549: return false;
550: }
551:
552: public IOperatorField getInputField(String name) {
553: Iterator it = this .inputList.iterator();
554: while (it.hasNext()) {
555: IOperatorField field = (IOperatorField) it.next();
556: if (field.getName().equals(name)) {
557: return field;
558: }
559: }
560:
561: return null;
562: }
563:
564: /**
565: * Is this a java operator.
566: *
567: * @return true if this operator is implemented and should be invoked in java.
568: */
569: public boolean isJavaOperator() {
570: Boolean javaOperator = (Boolean) operatorObj.getPrimaryFile()
571: .getAttribute(KEY_JAVAOPERATOR);
572: if (javaOperator != null) {
573: return javaOperator.booleanValue();
574: }
575: return false;
576: }
577:
578: // /**
579: // * check if this operator returns a boolean value
580: // * @return
581: // */
582: // public boolean isBooleanOperator() {
583: // Boolean boolOperator = (Boolean)
584: // operatorObj.getPrimaryFile().getAttribute("BooleanOperator");
585: // if (boolOperator != null) {
586: // return boolOperator.booleanValue();
587: // }
588: // return false;
589: // }
590:
591: // /**
592: // * @see org.netbeans.modules.sql.framework.ui.graph.IOperatorXmlInfo#getConfigDialog()
593: // */
594: // public OperatorConfigDialog getConfigDialog() {
595: // String dlgClass = (String)
596: // operatorObj.getPrimaryFile().getAttribute("ConfigDialogName");
597: // if (!StringUtil.isNullString(dlgClass)) {
598: // try {
599: // Class klass = Class.forName(dlgClass, true, getClass()
600: // .getClassLoader());
601: // return (OperatorConfigDialog) klass.newInstance();
602: // } catch (ClassNotFoundException ignore) {
603: // // ignore
604: // } catch (InstantiationException ignore) {
605: // // ignore
606: // } catch (IllegalAccessException ignore) {
607: // // ignore
608: // }
609: // }
610: //
611: // return null;
612: // }
613: }
|