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.view.graph;
042:
043: import java.awt.GridBagConstraints;
044: import java.awt.GridBagLayout;
045: import java.awt.Insets;
046: import java.awt.event.ActionEvent;
047: import java.awt.event.ActionListener;
048: import java.sql.Types;
049: import java.util.ArrayList;
050: import java.util.Iterator;
051: import java.util.List;
052: import java.util.Vector;
053:
054: import javax.swing.DefaultCellEditor;
055: import javax.swing.JButton;
056: import javax.swing.JComboBox;
057: import javax.swing.JLabel;
058: import javax.swing.JPanel;
059: import javax.swing.JScrollPane;
060: import javax.swing.JTable;
061: import javax.swing.JTextField;
062: import javax.swing.ListSelectionModel;
063: import javax.swing.table.AbstractTableModel;
064: import javax.swing.table.TableColumn;
065:
066: import org.netbeans.modules.sql.framework.model.SQLDBColumn;
067: import org.netbeans.modules.sql.framework.model.SQLModelObjectFactory;
068: import org.netbeans.modules.sql.framework.model.SQLOperatorArg;
069: import org.netbeans.modules.sql.framework.model.SourceColumn;
070: import org.netbeans.modules.sql.framework.model.TargetColumn;
071:
072: import com.sun.sql.framework.jdbc.SQLUtils;
073: import net.java.hulp.i18n.Logger;
074: import org.netbeans.modules.etl.logger.Localizer;
075: import org.netbeans.modules.etl.logger.LogUtil;
076:
077: /**
078: * Configures type, precision and scale (as appropriate) of a cast as operator.
079: *
080: * @author Wei
081: * @version $Revision$
082: */
083: public class CustomOperatorPane extends JPanel {
084:
085: private static String[] headers = new String[] { "Argument Name",
086: "SQL Type" };
087: private List args;
088: private JTextField nameField = new JTextField(20);
089: private TableColumnModel tableModel = null;
090: private static transient final Logger mLogger = LogUtil
091: .getLogger(CustomOperatorPane.class.getName());
092: private static transient final Localizer mLoc = Localizer.get();
093:
094: public CustomOperatorPane() {
095: initArguments();
096: this .tableModel = new TableColumnModel(this .args);
097: this .initComponents();
098: }
099:
100: public CustomOperatorPane(List args) {
101: this .args = args;
102: if (args.isEmpty()) {
103: initArguments();
104: }
105: this .tableModel = new TableColumnModel(this .args);
106: this .initComponents();
107: }
108:
109: /**
110: * Overloaded constructor which takes input args and return type and
111: * generates the custom operator wizard
112: *
113: * @param inputArgs
114: * @param retType
115: */
116: public CustomOperatorPane(List inputArgs, SQLOperatorArg retType) {
117: this .args = new ArrayList();
118: this .setArgList(inputArgs);
119: this .setReturnType(retType);
120: this .tableModel = new TableColumnModel(this .args);
121: this .initComponents();
122: }
123:
124: /**
125: * Returns a list of arguments
126: *
127: * @return List
128: */
129: public List getArgList() {
130: ArrayList inputArgs = new ArrayList();
131: List list = this .tableModel.getColumns();
132: int num = list.size() - 1;
133: for (int i = 0; i < num; i++) {
134: ColumnWrapper wrapper = (ColumnWrapper) list.get(i);
135: SQLOperatorArg arg = new SQLOperatorArg(wrapper.getName(),
136: wrapper.getJdbcType());
137: inputArgs.add(arg);
138: }
139: return inputArgs;
140: }
141:
142: /**
143: * setter for argument list does the transformation of SQLOperatorArg to
144: * ColumnWrapper before populating the list of args.
145: *
146: * @param args
147: */
148: public void setArgList(List args) {
149: this .args.clear();
150: Iterator iter = args.iterator();
151: TargetColumn inputArg = null;
152: while (iter.hasNext()) {
153: SQLOperatorArg arg = (SQLOperatorArg) iter.next();
154: inputArg = SQLModelObjectFactory.getInstance()
155: .createTargetColumn(arg.getArgName(),
156: arg.getJdbcType(), 0, 0, true);
157: this .args.add(new ColumnWrapper(inputArg));
158: }
159: }
160:
161: /**
162: * Returns the SourceColumn as return type
163: */
164: public SQLOperatorArg getReturnType() {
165: int size = this .tableModel.getColumns().size();
166: ColumnWrapper wrapper = (ColumnWrapper) this .tableModel
167: .getColumns().get(size - 1);
168: return new SQLOperatorArg(wrapper.getName(), wrapper
169: .getJdbcType());
170: }
171:
172: /**
173: * sets the return type used for custom functions
174: * @param retType
175: */
176: public void setReturnType(SQLOperatorArg retType) {
177: SourceColumn retArg = SQLModelObjectFactory.getInstance()
178: .createSourceColumn(retType.getArgName(),
179: retType.getJdbcType(), 0, 0, true);
180: this .args.add(new ColumnWrapper(retArg));
181: }
182:
183: public String getFunctionName() {
184: String name = this .nameField.getText().trim();
185: return (name.length() == 0) ? "userFx" : name;
186: }
187:
188: /**
189: * populates the name value in the textfield
190: * @param name
191: */
192: public void setFunctionName(String name) {
193: this .nameField.setText(name);
194: }
195:
196: private void initArguments() {
197: TargetColumn arg1 = SQLModelObjectFactory.getInstance()
198: .createTargetColumn("arg1", Types.NUMERIC, 0, 0, true);
199: SourceColumn retArg = SQLModelObjectFactory
200: .getInstance()
201: .createSourceColumn("return", Types.NUMERIC, 0, 0, true);
202: this .args.add(new ColumnWrapper(arg1));
203: this .args.add(new ColumnWrapper(retArg));
204: }
205:
206: private void initComponents() {
207: this .setLayout(new GridBagLayout());
208: String nbBundle1 = mLoc.t("PRSR001: Function Name");
209: JLabel nameLabel = new JLabel(Localizer.parse(nbBundle1)); //NOI18N
210: nameLabel.getAccessibleContext().setAccessibleName(
211: Localizer.parse(nbBundle1));
212: this .add(nameLabel, new GridBagConstraints(0, 0, 1, 1, 0.0,
213: 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE,
214: new Insets(5, 5, 5, 5), 0, 0));
215: nameField.setText("userFx");
216: this .add(nameField, new GridBagConstraints(1, 0, 1, 1, 1.0,
217: 0.0, GridBagConstraints.WEST,
218: GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5),
219: 0, 0));
220: String nbBundle4 = mLoc.t("PRSR001: Add");
221: JButton addButton = new JButton(Localizer.parse(nbBundle4));
222: addButton.getAccessibleContext().setAccessibleName(
223: Localizer.parse(nbBundle4));
224: this .add(addButton, new GridBagConstraints(0, 1, 1, 1, 0.0,
225: 0.0, GridBagConstraints.WEST,
226: GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5),
227: 0, 0));
228:
229: String nbBundle2 = mLoc.t("PRSR001: Remove");
230: JButton removeButton = new JButton(Localizer.parse(nbBundle2));
231: removeButton.getAccessibleContext().setAccessibleName(
232: Localizer.parse(nbBundle2));
233: this .add(removeButton, new GridBagConstraints(1, 1, 1, 1, 0.0,
234: 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE,
235: new Insets(5, 5, 5, 5), 0, 0));
236: String nbBundle3 = mLoc.t("PRSR001: Arguments");
237: JLabel argLabel = new JLabel(Localizer.parse(nbBundle3));
238: argLabel.getAccessibleContext().setAccessibleName(
239: Localizer.parse(nbBundle3));
240:
241: this .add(argLabel, new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0,
242: GridBagConstraints.WEST, GridBagConstraints.NONE,
243: new Insets(5, 5, 5, 5), 0, 0));
244: final JTable table = new JTable();
245: table.setModel(this .tableModel);
246: table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
247: TableColumn typeColumn = table.getColumnModel().getColumn(1);
248: typeColumn.setCellEditor(new DefaultCellEditor(new JComboBox(
249: new Vector(SQLUtils.getSupportedLiteralTypes()))));
250: this .add(new JScrollPane(table), new GridBagConstraints(0, 3,
251: 2, 2, 0.0, 0.0, GridBagConstraints.WEST,
252: GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
253:
254: addButton.addActionListener(new ActionListener() {
255:
256: public void actionPerformed(ActionEvent ae) {
257: tableModel.addEmptyRow();
258: }
259: });
260:
261: removeButton.addActionListener(new ActionListener() {
262:
263: public void actionPerformed(ActionEvent ae) {
264: int index = table.getSelectedRow();
265: if (index >= 0) {
266: String argName = (String) tableModel.getValueAt(
267: index, 0);
268: tableModel.removeRow(index);
269: }
270: }
271: });
272: }
273:
274: private class TableColumnModel extends AbstractTableModel {
275: // local list for table column
276: private List columnList = new ArrayList();
277:
278: TableColumnModel(List columnList) {
279: if (columnList != null) {
280: this .columnList.addAll(columnList);
281: }
282: }
283:
284: public void addEmptyRow() {
285: String argName = "arg" + columnList.size();
286: TargetColumn arg1 = SQLModelObjectFactory.getInstance()
287: .createTargetColumn(argName, Types.NUMERIC, 0, 0,
288: true);
289: this .columnList.add(columnList.size() - 1,
290: new ColumnWrapper(arg1));
291: this .fireTableDataChanged();
292: }
293:
294: public void removeRow(int row) {
295: if (columnList.size() <= 2) {
296: return;
297: }
298: if (row == columnList.size() - 1) {
299: return;
300: }
301: columnList.remove(row);
302: this .fireTableRowsDeleted(row, row);
303: }
304:
305: /**
306: * Returns the number of columns in the model. A <code>JTable</code> uses this
307: * method to determine how many columns it should create and display by default.
308: *
309: * @return the number of columns in the model
310: * @see #getRowCount
311: */
312: public int getColumnCount() {
313: return headers.length;
314: }
315:
316: /**
317: * @see javax.swing.table.AbstractTableModel#getColumnName
318: */
319: public String getColumnName(int col) {
320: return headers[col];
321: }
322:
323: public List getColumns() {
324: return columnList;
325: }
326:
327: public ColumnWrapper getColumnWrapper(String columnName) {
328: Iterator it = columnList.iterator();
329:
330: while (it.hasNext()) {
331: ColumnWrapper colWrapper = (ColumnWrapper) it.next();
332: if (colWrapper.getColumnOldName().equals(columnName)) {
333: return colWrapper;
334: }
335: }
336: return null;
337: }
338:
339: /**
340: * Returns the number of rows in the model. A <code>JTable</code> uses this
341: * method to determine how many rows it should display. This method should be
342: * quick, as it is called frequently during rendering.
343: *
344: * @return the number of rows in the model
345: * @see #getColumnCount
346: */
347: public int getRowCount() {
348: return columnList.size();
349: }
350:
351: /**
352: * Returns the value for the cell at <code>columnIndex</code> and
353: * <code>rowIndex</code>.
354: *
355: * @param rowIndex the row whose value is to be queried
356: * @param columnIndex the column whose value is to be queried
357: * @return the value Object at the specified cell
358: */
359: public Object getValueAt(int rowIndex, int columnIndex) {
360: ColumnWrapper colWrapper = (ColumnWrapper) columnList
361: .get(rowIndex);
362: Object retValue = null;
363:
364: switch (columnIndex) {
365: case 0:
366: retValue = colWrapper.getName();
367: break;
368: case 1:
369: retValue = colWrapper.getJdbcTypeString();
370: break;
371: case 2:
372: retValue = new Integer(colWrapper.getPrecision());
373: break;
374: case 3:
375: retValue = new Integer(colWrapper.getScale());
376: break;
377: }
378:
379: return retValue;
380: }
381:
382: /**
383: * Indicates whether given cell is editable.
384: *
385: * @param row row number of cell
386: * @param col column number of cell
387: * @return true if all cells are editable, false otherwise
388: */
389: public boolean isCellEditable(int row, int col) {
390: return col != 0;
391: }
392:
393: /**
394: * Sets the specified cell to the desired value
395: *
396: * @param value desired value of the cell
397: * @param row row number
398: * @param col column number
399: */
400: public void setValueAt(Object value, int row, int col) {
401:
402: ColumnWrapper colWrapper = (ColumnWrapper) columnList
403: .get(row);
404:
405: int val = 0;
406: boolean set = false;
407:
408: switch (col) {
409: case 1:
410: colWrapper
411: .setJdbcType(com.sun.sql.framework.jdbc.SQLUtils
412: .getStdJdbcType((String) value));
413: set = true;
414: break;
415: case 2:
416: try {
417: val = Integer.parseInt((String) value);
418: } catch (NumberFormatException e) {
419: return;
420: }
421:
422: colWrapper.setPrecision(val);
423: set = true;
424: break;
425: case 3:
426: try {
427: val = Integer.parseInt((String) value);
428: } catch (NumberFormatException e) {
429: return;
430: }
431:
432: colWrapper.setScale(val);
433: set = true;
434: }
435:
436: if (set) {
437: fireTableCellUpdated(row, col);
438: }
439: }
440: }
441:
442: class ColumnWrapper {
443:
444: private SQLDBColumn column;
445: private String columnOldName;
446: private boolean isNew = false;
447:
448: ColumnWrapper(SQLDBColumn column) {
449: this .column = column;
450: this .columnOldName = column.getName();
451: }
452:
453: public SQLDBColumn getColumn() {
454: return column;
455: }
456:
457: public String getColumnOldName() {
458: return this .columnOldName;
459: }
460:
461: public String getDefaultValue() {
462: return column.getDefaultValue();
463: }
464:
465: public int getJdbcType() {
466: return column.getJdbcType();
467: }
468:
469: public String getJdbcTypeString() {
470: return column.getJdbcTypeString();
471: }
472:
473: public String getName() {
474: return column.getName();
475: }
476:
477: public int getPrecision() {
478: return column.getPrecision();
479: }
480:
481: public int getScale() {
482: return column.getScale();
483: }
484:
485: public boolean isNew() {
486: return isNew;
487: }
488:
489: public void setDefaultValue(String defaultVal) {
490: column.setDefaultValue(defaultVal);
491: }
492:
493: public void setJdbcType(int newType) {
494: column.setJdbcType(newType);
495: }
496:
497: public void setName(String name) {
498: column.setName(name);
499: column.setDisplayName(name);
500: }
501:
502: public void setNew(boolean isNew) {
503: this .isNew = isNew;
504: }
505:
506: public void setPrecision(int precision) {
507: column.setPrecision(precision);
508: }
509:
510: public void setScale(int scale) {
511: column.setScale(scale);
512: }
513: }
514: }
|