001    /*
002    // $Id: //open/mondrian/src/main/mondrian/gui/SchemaExplorer.java#28 $
003    // This software is subject to the terms of the Common Public License
004    // Agreement, available at the following URL:
005    // http://www.opensource.org/licenses/cpl.html.
006    // Copyright (C) 2002-2008 Julian Hyde and others
007    // Copyright (C) 2006-2007 CINCOM SYSTEMS, INC.
008    // All Rights Reserved.
009    // You must accept the terms of that agreement to use this software.
010    //
011    // Created on October 2, 2002, 5:42 PM
012    // Modified on 15-Jun-2003 by ebengtso
013    */
014    package mondrian.gui;
015    
016    import java.awt.event.ItemEvent;
017    import java.awt.event.ItemListener;
018    import java.awt.event.InputEvent;
019    import java.awt.event.KeyAdapter;
020    import java.io.StringReader;
021    import java.io.StringWriter;
022    import java.util.ArrayList;
023    import java.util.EventObject;
024    
025    import javax.swing.*;
026    import javax.swing.border.EtchedBorder;
027    import javax.swing.event.CellEditorListener;
028    import javax.swing.event.ChangeEvent;
029    import javax.swing.event.TreeSelectionEvent;
030    import javax.swing.event.TreeSelectionListener;
031    import javax.swing.table.DefaultTableModel;
032    import javax.swing.table.TableCellRenderer;
033    import javax.swing.table.TableCellEditor;
034    import javax.swing.tree.TreePath;
035    import java.awt.*;
036    import java.awt.event.ActionEvent;
037    import java.awt.event.KeyEvent;
038    import java.awt.event.MouseAdapter;
039    import java.awt.event.MouseEvent;
040    import java.io.File;
041    import java.lang.reflect.Array;
042    import java.lang.reflect.Field;
043    import javax.swing.event.TreeExpansionEvent;
044    import javax.swing.tree.TreeCellEditor;
045    import javax.swing.plaf.basic.BasicArrowButton;
046    import javax.swing.tree.DefaultTreeSelectionModel;
047    
048    import org.apache.log4j.Logger;
049    import org.eigenbase.xom.XOMUtil;
050    import org.eigenbase.xom.Parser;
051    import org.eigenbase.xom.NodeDef;
052    import org.eigenbase.xom.XOMException;
053    
054    /**
055     *
056     * @author  sean
057     * @version $Id: //open/mondrian/src/main/mondrian/gui/SchemaExplorer.java#28 $
058     */
059    public class SchemaExplorer extends javax.swing.JPanel implements TreeSelectionListener, CellEditorListener {
060    
061        private static final Logger LOGGER = Logger.getLogger(SchemaExplorer.class);
062    
063        private Workbench workbench;
064        private MondrianGuiDef.Schema schema;
065        private SchemaTreeModel model;
066        private SchemaTreeCellRenderer renderer;
067        private SchemaTreeCellEditor editor;
068        private File schemaFile;
069        private JTreeUpdater updater;
070        private final ClassLoader myClassLoader;
071        private boolean newFile;
072        private boolean dirty = false;  //indicates file is without changes, dirty=true when some changes are made to the file
073        private boolean dirtyFlag = false;  // indicates dirty status shown on title
074        private JInternalFrame parentIFrame;
075        private JDBCMetaData jdbcMetaData;
076        private boolean editModeXML = false;
077        private String errMsg = null;
078    
079        /** Creates new form SchemaExplorer */
080        public SchemaExplorer(Workbench workbench) {
081            this.workbench = workbench;
082            myClassLoader = this.getClass().getClassLoader();
083            initComponents();
084        }
085    
086        public SchemaExplorer(Workbench workbench, File f, JDBCMetaData jdbcMetaData, boolean newFile, JInternalFrame parentIFrame) {
087            this(workbench);
088    
089            alert = getResourceConverter().getString("schemaExplorer.alert.title","Alert");
090    
091            //====XML editor
092            try {
093                jEditorPaneXML = new JEditorPane();
094            } catch (Exception ex) {
095                LOGGER.error("SchemaExplorer-JEditorPane", ex);
096            }
097    
098            jEditorPaneXML.setLayout(new java.awt.BorderLayout());
099            jEditorPaneXML.setEditable(false);
100            jScrollPaneXML = new JScrollPane(jEditorPaneXML);
101            jPanelXML.setLayout(new java.awt.BorderLayout());
102            jPanelXML.add(jScrollPaneXML, java.awt.BorderLayout.CENTER);
103            jPanelXML.add(targetLabel2, java.awt.BorderLayout.NORTH);
104            jPanelXML.add(validStatusLabel2, java.awt.BorderLayout.SOUTH);
105            jPanelXML.setMaximumSize(jPanel1.getMaximumSize());
106            jPanelXML.setPreferredSize(jPanel1.getPreferredSize());
107    
108            databaseLabel.setText(getResourceConverter().getFormattedString("schemaExplorer.database.text",
109                    "Database - {0} ({1})",
110                        new String[] { jdbcMetaData.getDbCatalogName(), jdbcMetaData.getDatabaseProductName() }));
111    
112            try {
113                Parser xmlParser = XOMUtil.createDefaultParser();
114                this.schemaFile = f;
115                this.setNewFile(newFile);
116                this.parentIFrame = parentIFrame;
117    
118                this.jdbcMetaData = jdbcMetaData;
119    
120                if (newFile) {
121                    schema = new MondrianGuiDef.Schema();
122                    schema.cubes = new MondrianGuiDef.Cube[0];
123                    schema.dimensions = new MondrianGuiDef.Dimension[0];
124                    schema.namedSets = new MondrianGuiDef.NamedSet[0];
125                    schema.roles = new MondrianGuiDef.Role[0];
126                    schema.userDefinedFunctions = new MondrianGuiDef.UserDefinedFunction[0];
127                    schema.virtualCubes = new MondrianGuiDef.VirtualCube[0];
128    
129                    String sname = schemaFile.getName();
130                    int ext = sname.indexOf(".");
131                    if (ext != -1) {
132                        schema.name = "New " + sname.substring(0, ext);
133                    }
134                } else {
135                    try {
136                        schema = new MondrianGuiDef.Schema(xmlParser.parse(schemaFile.toURL()));
137                    } catch (XOMException ex) {
138                        // parsing error of the schema file causes default tree of colors etc. to be displayed in schema explorer
139                        // initialize the schema to display an empty schema if you want to show schema explorer for file
140                        // where parsing failed.
141                        schema = new MondrianGuiDef.Schema();
142                        schema.cubes = new MondrianGuiDef.Cube[0];
143                        schema.dimensions = new MondrianGuiDef.Dimension[0];
144                        schema.namedSets = new MondrianGuiDef.NamedSet[0];
145                        schema.roles = new MondrianGuiDef.Role[0];
146                        schema.userDefinedFunctions = new MondrianGuiDef.UserDefinedFunction[0];
147                        schema.virtualCubes = new MondrianGuiDef.VirtualCube[0];
148    
149                        LOGGER.error("Exception  : Schema file parsing failed." + ex.getMessage(), ex);
150                        errMsg = getResourceConverter().getFormattedString("schemaExplorer.parsing.error",
151                                "Parsing Error: Could not open file {0}\n{1}",
152                                    new String[] { schemaFile.toString(), ex.getLocalizedMessage() });
153    
154                    }
155                }
156                setTitle(); // sets title of i frame with schema name and file name
157    
158                //renderer = new SchemaTreeCellRenderer();
159                renderer = new SchemaTreeCellRenderer(workbench, jdbcMetaData);
160                model = new SchemaTreeModel(schema);
161                tree.setModel(model);
162                tree.setCellRenderer(renderer);
163                tree.addTreeSelectionListener(this);
164    
165                //            getResourceConverter().getString("schemaExplorer.hierarchy.select.title","Select Join or Table Hierarchy");
166    
167                JComboBox listEditor = new JComboBox(new String[] {getResourceConverter().getString("schemaExplorer.hierarchy.select.join","Join"),
168                                                                    getResourceConverter().getString("schemaExplorer.hierarchy.select.table", "Table")});
169                listEditor.setToolTipText(getResourceConverter().getString("schemaExplorer.hierarchy.select.title","Select Join or Table Hierarchy"));
170                listEditor.setPreferredSize(new java.awt.Dimension(listEditor.getPreferredSize().width, 24)); //Do not remove this
171    
172                listEditor.addItemListener(new ItemListener() {
173                    public void itemStateChanged(ItemEvent e) {
174                        tree.stopEditing();
175                        TreePath tpath = tree.getSelectionPath(); //tree.getEditingPath();
176                        if (tpath != null) {
177                            TreePath parentpath = tpath.getParentPath();
178                            if (parentpath != null) {
179                                refreshTree(parentpath);
180                            }
181                        }
182                    }
183                });
184    
185                TreeCellEditor comboEditor = new DefaultCellEditor(listEditor);
186    
187                editor = new SchemaTreeCellEditor(workbench, tree, renderer, comboEditor);
188                tree.setCellEditor(editor);
189                tree.setEditable(true);
190    
191    
192                //SchemaPropertyCellEditor spce = new SchemaPropertyCellEditor();
193                SchemaPropertyCellEditor spce = new SchemaPropertyCellEditor(workbench, jdbcMetaData);
194                spce.addCellEditorListener(this);
195                propertyTable.setDefaultEditor(Object.class, spce);
196                SchemaPropertyCellRenderer.attributeBackground = jScrollPane2.getBackground();    // to set background color of attribute columns
197                SchemaPropertyCellRenderer spcr = new SchemaPropertyCellRenderer(workbench);
198                propertyTable.setDefaultRenderer(Object.class, spcr);
199    
200    
201                 /*  Focus lost on table was supposed to save the last edited value in table model object
202                    but tabel focus lost is not called when tree selection is changed
203                //propertyTable.addPropertyChangeListener("model", this);
204                propertyTable.addFocusListener(new FocusAdapter() {
205                    public void focusGained(FocusEvent e) {System.out.println("====Table GAINED focus");}
206    
207                    public void focusLost(FocusEvent e) {System.out.println("====Table LOST focus");
208                            Object value = propertyTable.getCellEditor().getCellEditorValue();
209                            propertyTable.setValueAt(value, propertyTable.getEditingRow(), propertyTable.getEditingColumn());
210                    }
211                });
212                  */
213    
214                /* This line is supposed to save cell edited values when a user clicks anywhere outside the table
215                    // propertyTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
216                 * But this does not save if a tree cell is selected , whereas it only saves if a click is done anywhere on let panel.
217                 */
218    
219            } catch (Exception ex) {
220                LOGGER.error("SchemaExplorer init error", ex);
221            }
222        }
223    
224        /** This method is called from within the constructor to
225         * initialize the form.
226         */
227        private void initComponents() {
228    
229            //ResourceBundle resources = ResourceBundle.getBundle("mondrian.gui.resources.gui");
230            jPanelXML = new JPanel();
231            jScrollPaneXML = new JScrollPane();
232    
233            footer = new JPanel();
234            databaseLabel = new javax.swing.JLabel();
235    
236            jSeparator1 = new JSeparator();
237            jSplitPane1 = new JSplitPane();
238            jPanel1 = new JPanel();
239            jScrollPane2 = new JScrollPane();
240            //=============================================================
241            // propertyTable includes changeSelection and processKeyEvent
242            // processing for keyboard navigation
243            //=============================================================
244            propertyTable = new JTable() {
245                public void changeSelection(int rowIndex, int columnIndex, boolean toggle, boolean extend) {
246                    if (columnIndex == 0) {
247                        AWTEvent currentEvent = EventQueue.getCurrentEvent();
248                        if (currentEvent instanceof KeyEvent) {
249                            KeyEvent ke = (KeyEvent)currentEvent;
250                            int kcode = ke.getKeyCode();
251                            if (kcode == KeyEvent.VK_TAB) {
252                                if ((ke.getModifiersEx() & InputEvent.SHIFT_DOWN_MASK) ==
253                                        InputEvent.SHIFT_DOWN_MASK) {
254                                    rowIndex -= 1;
255                                    if (rowIndex < 0) {
256                                        rowIndex = (propertyTable.getRowCount()) - 1;
257                                    }
258                                }
259                              setTableCellFocus(rowIndex);
260                              return;
261                            }
262                        }
263                    }
264                    super.changeSelection(rowIndex, columnIndex, toggle, extend);
265                }
266                public void processKeyEvent(KeyEvent e) {
267                    int kcode = e.getKeyCode();
268                    if (kcode == KeyEvent.VK_UP || kcode == KeyEvent.VK_DOWN) {
269                        int row = propertyTable.getSelectedRow();
270                        setTableCellFocus(row);
271                        return;
272                    }
273                    super.processKeyEvent(e);
274                }
275            };
276    
277            targetLabel = new javax.swing.JLabel();
278            validStatusLabel = new javax.swing.JLabel();
279            targetLabel2 = new javax.swing.JLabel();
280            validStatusLabel2 = new javax.swing.JLabel();
281            jPanel2 = new JPanel();
282            jScrollPane1 = new JScrollPane();
283    
284            tree = new JTree() {
285                public String getToolTipText(MouseEvent evt) {
286                    String toggleMsg = getResourceConverter().getString("schemaExplorer.hierarchy.toggle", "Double click to display Join/Table selection");
287                    if (getRowForLocation(evt.getX(), evt.getY()) == -1) {
288                        return null;
289                    }
290                    TreePath curPath = getPathForLocation(evt.getX(), evt.getY());
291                    Object o = curPath.getLastPathComponent();
292                    if (o instanceof MondrianGuiDef.Join) {
293                        return toggleMsg;
294                    }
295                    TreePath parentPath = curPath.getParentPath();
296                    if (parentPath != null) {
297                        Object po = parentPath.getLastPathComponent();
298                        if (o instanceof MondrianGuiDef.Table &&
299                            (po instanceof MondrianGuiDef.Hierarchy ||
300                                po instanceof MondrianGuiDef.Join)) {
301                                return toggleMsg;
302                        }
303                    }
304                    return null;
305                }
306            };
307            tree.getSelectionModel().setSelectionMode(DefaultTreeSelectionModel.SINGLE_TREE_SELECTION);
308    
309            ToolTipManager.sharedInstance().registerComponent(tree);
310    
311            jToolBar1 = new JToolBar();
312            addCubeButton = new JButton();
313            addDimensionButton = new JButton();
314            addDimensionUsageButton = new JButton();
315            addHierarchyButton = new JButton();
316            addNamedSetButton = new JButton();
317            addUserDefinedFunctionButton = new JButton();
318            addRoleButton = new JButton();
319    
320            addMeasureButton = new JButton();
321            addCalculatedMemberButton = new JButton();
322            addLevelButton = new JButton();
323            addPropertyButton = new JButton();
324    
325            addVirtualCubeButton = new JButton();
326            addVirtualCubeDimensionButton = new JButton();
327            addVirtualCubeMeasureButton = new JButton();
328    
329            cutButton = new JButton();
330            copyButton = new JButton();
331            pasteButton = new JButton();
332            deleteButton = new JButton();
333            editModeButton = new JToggleButton();
334    
335            setLayout(new BorderLayout());
336    
337            jSplitPane1.setDividerLocation(200);
338            jPanel1.setLayout(new BorderLayout());
339    
340            propertyTable.setModel(new DefaultTableModel(new Object[][] {
341            }, new String[] { getResourceConverter().getString("schemaExplorer.propertyTable.attribute","Attribute"),
342                                getResourceConverter().getString("schemaExplorer.propertyTable.value","Value") }) {
343                Class[] types = new Class[] { java.lang.String.class, java.lang.Object.class };
344                boolean[] canEdit = new boolean[] { false, true };
345    
346                public Class getColumnClass(int columnIndex) {
347                    return types[columnIndex];
348                }
349    
350                public boolean isCellEditable(int rowIndex, int columnIndex) {
351                    return canEdit[columnIndex];
352                }
353            });
354    
355            propertyTable.getTableHeader().setFont(new Font("Dialog", Font.BOLD, 12));  // setting property table column headers to bold
356    
357            jScrollPane2.setViewportView(propertyTable);
358    
359            jPanel1.add(jScrollPane2, java.awt.BorderLayout.CENTER);
360    
361            targetLabel.setFont(new Font("Dialog", 1, 14));
362            targetLabel.setForeground((Color) UIManager.getDefaults().get("CheckBoxMenuItem.acceleratorForeground"));
363            targetLabel.setHorizontalAlignment(SwingConstants.CENTER);
364            targetLabel.setText(getResourceConverter().getString("schemaExplorer.targetLabel.title","Schema"));
365            targetLabel.setBorder(new EtchedBorder());
366            // up arrow button for property table heading
367            jPanel3 = new JPanel();
368            jPanel3.setLayout(new BorderLayout());
369            BasicArrowButton arrowButtonUp = new BasicArrowButton(SwingConstants.NORTH);
370            BasicArrowButton arrowButtonDown = new BasicArrowButton(SwingConstants.SOUTH);
371            arrowButtonUp.setToolTipText(getResourceConverter().getString("schemaExplorer.arrowButtonUp.toolTip","move to parent element"));
372            arrowButtonDown.setToolTipText(getResourceConverter().getString("schemaExplorer.arrowButtonDown.toolTip","move to child element"));
373            arrowButtonUpAction = new AbstractAction(getResourceConverter().getString("schemaExplorer.arrowButtonUp.title","Arrow button up")) {
374                public void actionPerformed(ActionEvent e) {
375                    arrowButtonUpAction(e);
376                }
377            };
378            arrowButtonDownAction = new AbstractAction(getResourceConverter().getString("schemaExplorer.arrowButtonDown.title","Arrow button down")) {
379                public void actionPerformed(ActionEvent e) {
380                    arrowButtonDownAction(e);
381                }
382            };
383            arrowButtonUp.addActionListener(arrowButtonUpAction);
384            arrowButtonDown.addActionListener(arrowButtonDownAction);
385            jPanel3.add(arrowButtonDown, java.awt.BorderLayout.EAST);
386            jPanel3.add(arrowButtonUp, java.awt.BorderLayout.WEST);
387            jPanel3.add(targetLabel, java.awt.BorderLayout.CENTER);
388    
389            jPanel1.add(jPanel3, java.awt.BorderLayout.NORTH);
390            validStatusLabel.setFont(new Font("Dialog", Font.PLAIN, 12));
391            validStatusLabel.setForeground(Color.RED);
392            validStatusLabel.setHorizontalAlignment(SwingConstants.CENTER);
393    
394            jPanel1.add(validStatusLabel, java.awt.BorderLayout.SOUTH);
395    
396            // for XML viewing
397            targetLabel2.setFont(new Font("Dialog", 1, 14));
398            targetLabel2.setForeground((Color) UIManager.getDefaults().get("CheckBoxMenuItem.acceleratorForeground"));
399            targetLabel2.setHorizontalAlignment(SwingConstants.CENTER);
400            targetLabel2.setText(getResourceConverter().getString("schemaExplorer.targetLabel.title","Schema"));
401            targetLabel2.setBorder(new EtchedBorder());
402            validStatusLabel2.setFont(new Font("Dialog", Font.PLAIN, 12));
403            validStatusLabel2.setForeground(Color.RED);
404            validStatusLabel2.setHorizontalAlignment(SwingConstants.CENTER);
405    
406            jSplitPane1.setRightComponent(jPanel1);
407    
408            jPanel2.setLayout(new java.awt.BorderLayout());
409    
410            jScrollPane1.setViewportView(tree);
411    
412            jPanel2.add(jScrollPane1, java.awt.BorderLayout.CENTER);
413    
414            jSplitPane1.setLeftComponent(jPanel2);
415    
416    
417            //========================================================
418            // actions
419            //========================================================
420            addCube = new AbstractAction(getResourceConverter().getString("schemaExplorer.addCube.title","Add cube")) {
421                public void actionPerformed(ActionEvent e) {
422                    addCube(e);
423                }
424            };
425            addDimension = new AbstractAction(getResourceConverter().getString("schemaExplorer.addDimension.title","Add Dimension")) {
426                public void actionPerformed(ActionEvent e) {
427                    addDimension(e);
428                }
429            };
430            addDimensionUsage = new AbstractAction(getResourceConverter().getString("schemaExplorer.addDimensionUsage.title","Add Dimension Usage")) {
431                public void actionPerformed(ActionEvent e) {
432                    addDimensionUsage(e);
433                }
434            };
435            addHierarchy = new AbstractAction(getResourceConverter().getString("schemaExplorer.addHierarchy.title","Add Hierarchy")) {
436                public void actionPerformed(ActionEvent e) {
437                    addHierarchy(e);
438                }
439            };
440            addNamedSet = new AbstractAction(getResourceConverter().getString("schemaExplorer.addNamedSet.title","Add Named Set")) {
441                public void actionPerformed(ActionEvent e) {
442                    addNamedSet(e);
443                }
444            };
445            addMeasure = new AbstractAction(getResourceConverter().getString("schemaExplorer.addMeasure.title","Add Measure")) {
446                public void actionPerformed(ActionEvent e) {
447                    addMeasure(e);
448                }
449            };
450            addCalculatedMember = new AbstractAction(getResourceConverter().getString("schemaExplorer.addCalculatedMember.title","Add Calculated Member")) {
451                public void actionPerformed(ActionEvent e) {
452                    addCalculatedMember(e);
453                }
454            };
455            addUserDefinedFunction = new AbstractAction(getResourceConverter().getString("schemaExplorer.addUserDefinedFunction.title","Add User Defined Function")) {
456                public void actionPerformed(ActionEvent e) {
457                    addUserDefinedFunction(e);
458                }
459            };
460            addRole = new AbstractAction(getResourceConverter().getString("schemaExplorer.addRole.title","Add Role")) {
461                public void actionPerformed(ActionEvent e) {
462                    addRole(e);
463                }
464            };
465            addSchemaGrant = new AbstractAction(getResourceConverter().getString("schemaExplorer.addSchemaGrant.title","Add Schema Grant")) {
466                public void actionPerformed(ActionEvent e) {
467                    addSchemaGrant(e);
468                }
469            };
470            addCubeGrant = new AbstractAction(getResourceConverter().getString("schemaExplorer.addCubeGrant.title","Add Cube Grant")) {
471                public void actionPerformed(ActionEvent e) {
472                    addCubeGrant(e);
473                }
474            };
475            addDimensionGrant = new AbstractAction(getResourceConverter().getString("schemaExplorer.addDimensionGrant.title","Add Dimension Grant")) {
476                public void actionPerformed(ActionEvent e) {
477                    addDimensionGrant(e);
478                }
479            };
480            addHierarchyGrant = new AbstractAction(getResourceConverter().getString("schemaExplorer.addHierarchyGrant.title","Add Hierarchy Grant")) {
481                public void actionPerformed(ActionEvent e) {
482                    addHierarchyGrant(e);
483                }
484            };
485            addMemberGrant = new AbstractAction(getResourceConverter().getString("schemaExplorer.addMemberGrant.title","Add Member Grant")) {
486                public void actionPerformed(ActionEvent e) {
487                    addMemberGrant(e);
488                }
489            };
490    
491            addLevel = new AbstractAction(getResourceConverter().getString("schemaExplorer.addLevel.title","Add Level")) {
492                public void actionPerformed(ActionEvent e) {
493                    addLevel(e);
494                }
495            };
496            addClosure = new AbstractAction(getResourceConverter().getString("schemaExplorer.addClosure.title","Add Closure")) {
497                public void actionPerformed(ActionEvent e) {
498                    addClosure(e);
499                }
500            };
501            addKeyExp = new AbstractAction(getResourceConverter().getString("schemaExplorer.addKeyExpression.title","Add Key Expression")) {
502                public void actionPerformed(ActionEvent e) {
503                    addKeyExp(e);
504                }
505            };
506            addNameExp = new AbstractAction(getResourceConverter().getString("schemaExplorer.addNameExpression.title","Add Name Expression")) {
507                public void actionPerformed(ActionEvent e) {
508                    addNameExp(e);
509                }
510            };
511            addOrdinalExp = new AbstractAction(getResourceConverter().getString("schemaExplorer.addOrdinalExpression.title","Add Ordinal Expression")) {
512                public void actionPerformed(ActionEvent e) {
513                    addOrdinalExp(e);
514                }
515            };
516            addParentExp = new AbstractAction(getResourceConverter().getString("schemaExplorer.addParentExpression.title","Add Parent Expression")) {
517                public void actionPerformed(ActionEvent e) {
518                    addParentExp(e);
519                }
520            };
521            addMeasureExp = new AbstractAction(getResourceConverter().getString("schemaExplorer.addMeasureExpression.title","Add Measure Expression")) {
522                public void actionPerformed(ActionEvent e) {
523                    addMeasureExp(e);
524                }
525            };
526            addSQL = new AbstractAction(getResourceConverter().getString("schemaExplorer.addSQL.title","Add SQL")) {
527                public void actionPerformed(ActionEvent e) {
528                    addSQL(e);
529                }
530            };
531            addRelation = new AbstractAction(getResourceConverter().getString("schemaExplorer.addRelation.title","Add Relation")) {
532                public void actionPerformed(ActionEvent e) {
533                    addRelation(e);
534                }
535            };
536            addProperty = new AbstractAction(getResourceConverter().getString("schemaExplorer.addProperty.title","Add Property")) {
537                public void actionPerformed(ActionEvent e) {
538                    addProperty(e);
539                }
540            };
541    
542            addVirtualCube = new AbstractAction(getResourceConverter().getString("schemaExplorer.addVirtualCube.title","Add Virtual Cube")) {
543                public void actionPerformed(ActionEvent e) {
544                    addVirtualCube(e);
545                }
546            };
547            addVirtualCubeDimension = new AbstractAction(getResourceConverter().getString("schemaExplorer.addVirtualCubeDimension.title","Add Virtual Cube Dimension")) {
548                public void actionPerformed(ActionEvent e) {
549                    addVirtualCubeDimension(e);
550                }
551            };
552            addVirtualCubeMeasure = new AbstractAction(getResourceConverter().getString("schemaExplorer.addVirtualCubeMeasure.title","Add Virtual Cube Measure")) {
553                public void actionPerformed(ActionEvent e) {
554                    addVirtualCubeMeasure(e);
555                }
556            };
557    
558            addAggPattern = new AbstractAction(getResourceConverter().getString("schemaExplorer.addAggregatePattern.title","Add Aggregate Pattern")) {
559                public void actionPerformed(ActionEvent e) {
560                    addAggPattern(e);
561                }
562            };
563            addAggExclude = new AbstractAction(getResourceConverter().getString("schemaExplorer.addAggregateExcludeTable.title","Add Aggregate Exclude Table")) {
564                public void actionPerformed(ActionEvent e) {
565                    addAggExclude(e);
566                }
567            };
568            addAggName = new AbstractAction(getResourceConverter().getString("schemaExplorer.addAggregateName.title","Add Aggregate Name")) {
569                public void actionPerformed(ActionEvent e) {
570                    addAggName(e);
571                }
572            };
573            addAggIgnoreColumn = new AbstractAction(getResourceConverter().getString("schemaExplorer.addAggregateIgnoreColumn.title","Add Aggregate Ignore Column")) {
574                public void actionPerformed(ActionEvent e) {
575                    addAggIgnoreColumn(e);
576                }
577            };
578            addAggForeignKey = new AbstractAction(getResourceConverter().getString("schemaExplorer.addAggregateForeignKey.title","Add Aggregate Foreign Key")) {
579                public void actionPerformed(ActionEvent e) {
580                    addAggForeignKey(e);
581                }
582            };
583            addAggMeasure = new AbstractAction(getResourceConverter().getString("schemaExplorer.addAggregateMeasure.title","Add Aggregate Measure")) {
584                public void actionPerformed(ActionEvent e) {
585                    addAggMeasure(e);
586                }
587            };
588            addAggLevel = new AbstractAction(getResourceConverter().getString("schemaExplorer.addAggregateLevel.title","Add Aggregate Level")) {
589                public void actionPerformed(ActionEvent e) {
590                    addAggLevel(e);
591                }
592            };
593            addAggFactCount = new AbstractAction(getResourceConverter().getString("schemaExplorer.addAggregateFactCount.title","Add Aggregate Fact Count")) {
594                public void actionPerformed(ActionEvent e) {
595                    addAggFactCount(e);
596                }
597            };
598    
599            delete = new AbstractAction(getResourceConverter().getString("schemaExplorer.actionDelete.title","Delete")) {
600                public void actionPerformed(ActionEvent e) {
601                    delete(e);
602                }
603            };
604    
605            editMode = new AbstractAction(getResourceConverter().getString("schemaExplorer.actionEdit.title","EditMode")) {
606                public void actionPerformed(ActionEvent e) {
607                    editMode(e);
608                }
609            };
610    
611            //========================================================
612            // toolbar buttons
613            //========================================================
614            addCubeButton.setIcon(new ImageIcon(myClassLoader.getResource(getResourceConverter().getGUIReference("addCube"))));
615            addCubeButton.setToolTipText(getResourceConverter().getString("schemaExplorer.addCube.title","Add cube"));
616            addCubeButton.addActionListener(addCube);
617    
618            addDimensionButton.setIcon(new ImageIcon(myClassLoader.getResource(getResourceConverter().getGUIReference("addDimension"))));
619            addDimensionButton.setToolTipText(getResourceConverter().getString("schemaExplorer.addDimension.title","Add Dimension"));
620            addDimensionButton.addActionListener(addDimension);
621    
622            addDimensionUsageButton.setIcon(new ImageIcon(myClassLoader.getResource(getResourceConverter().getGUIReference("addDimensionUsage"))));
623            addDimensionUsageButton.setToolTipText(getResourceConverter().getString("schemaExplorer.addDimensionUsage.title","Add Dimension Usage"));
624            addDimensionUsageButton.addActionListener(addDimensionUsage);
625    
626            addHierarchyButton.setIcon(new ImageIcon(myClassLoader.getResource(getResourceConverter().getGUIReference("addHierarchy"))));
627            addHierarchyButton.setToolTipText(getResourceConverter().getString("schemaExplorer.addHierarchy.title","Add Hierarchy"));
628            addHierarchyButton.addActionListener(addHierarchy);
629    
630            addNamedSetButton.setIcon(new ImageIcon(myClassLoader.getResource(getResourceConverter().getGUIReference("addNamedSet"))));
631            addNamedSetButton.setToolTipText(getResourceConverter().getString("schemaExplorer.addNamedSet.title","Add Named Set"));
632            addNamedSetButton.addActionListener(addNamedSet);
633    
634            addUserDefinedFunctionButton.setIcon(new ImageIcon(myClassLoader.getResource(getResourceConverter().getGUIReference("addUserDefinedFunction"))));
635            addUserDefinedFunctionButton.setToolTipText(getResourceConverter().getString("schemaExplorer.addUserDefinedFunction.title","Add User defined Function"));
636            addUserDefinedFunctionButton.addActionListener(addUserDefinedFunction);
637    
638            addCalculatedMemberButton.setIcon(new ImageIcon(myClassLoader.getResource(getResourceConverter().getGUIReference("addCalculatedMember"))));
639            addCalculatedMemberButton.setToolTipText(getResourceConverter().getString("schemaExplorer.addCalculatedMember.title","Add Calculated Member"));
640            addCalculatedMemberButton.addActionListener(addCalculatedMember);
641    
642            addMeasureButton.setIcon(new ImageIcon(myClassLoader.getResource(getResourceConverter().getGUIReference("addMeasure"))));
643            addMeasureButton.setToolTipText(getResourceConverter().getString("schemaExplorer.addMeasure.title","Add Measure"));
644            addMeasureButton.addActionListener(addMeasure);
645    
646            addLevelButton.setIcon(new ImageIcon(myClassLoader.getResource(getResourceConverter().getGUIReference("addLevel"))));
647            addLevelButton.setToolTipText(getResourceConverter().getString("schemaExplorer.addLevel.title","Add Level"));
648            addLevelButton.addActionListener(addLevel);
649    
650            addPropertyButton.setIcon(new ImageIcon(myClassLoader.getResource(getResourceConverter().getGUIReference("addProperty"))));
651            addPropertyButton.setToolTipText(getResourceConverter().getString("schemaExplorer.addProperty.title","Add Property"));
652            addPropertyButton.addActionListener(addProperty);
653    
654            addVirtualCubeButton.setIcon(new ImageIcon(myClassLoader.getResource(getResourceConverter().getGUIReference("addVirtualCube"))));
655            addVirtualCubeButton.setToolTipText(getResourceConverter().getString("schemaExplorer.addVirtualCube.title","Add Virtual Cube"));
656            addVirtualCubeButton.addActionListener(addVirtualCube);
657    
658            addVirtualCubeDimensionButton.setIcon(new ImageIcon(myClassLoader.getResource(getResourceConverter().getGUIReference("addVirtualCubeDimension"))));
659            addVirtualCubeDimensionButton.setToolTipText(getResourceConverter().getString("schemaExplorer.addVirtualCubeDimension.title","Add Virtual Dimension"));
660            addVirtualCubeDimensionButton.addActionListener(addVirtualCubeDimension);
661    
662            addVirtualCubeMeasureButton.setIcon(new ImageIcon(myClassLoader.getResource(getResourceConverter().getGUIReference("addVirtualCubeMeasure"))));
663            addVirtualCubeMeasureButton.setToolTipText(getResourceConverter().getString("schemaExplorer.addVirtualCubeMeasure.title","Add Virtual Measure"));
664            addVirtualCubeMeasureButton.addActionListener(addVirtualCubeMeasure);
665    
666            addRoleButton.setIcon(new ImageIcon(myClassLoader.getResource(getResourceConverter().getGUIReference("addRole"))));
667            addRoleButton.setToolTipText(getResourceConverter().getString("schemaExplorer.addRole.title","Add Role"));
668            addRoleButton.addActionListener(addRole);
669    
670            cutButton.setIcon(new javax.swing.ImageIcon(getClass().getResource(getResourceConverter().getGUIReference("cut"))));
671            cutButton.setToolTipText(getResourceConverter().getString("schemaExplorer.actionCut.title","Cut"));
672    
673            copyButton.setIcon(new javax.swing.ImageIcon(getClass().getResource(getResourceConverter().getGUIReference("copy"))));
674            copyButton.setToolTipText(getResourceConverter().getString("schemaExplorer.actionCopy.title","Copy"));
675    
676            pasteButton.setIcon(new javax.swing.ImageIcon(getClass().getResource(getResourceConverter().getGUIReference("paste"))));
677            pasteButton.setToolTipText(getResourceConverter().getString("schemaExplorer.actionPaste.title","Paste"));
678    
679            deleteButton.setIcon(new javax.swing.ImageIcon(getClass().getResource(getResourceConverter().getGUIReference("delete"))));
680            deleteButton.setToolTipText(getResourceConverter().getString("schemaExplorer.actionDelete.title","Delete"));
681            deleteButton.addActionListener(delete);
682    
683            editModeButton.setIcon(new javax.swing.ImageIcon(getClass().getResource(getResourceConverter().getGUIReference("edit"))));
684            editModeButton.setToolTipText(getResourceConverter().getString("schemaExplorer.actionEdit.title","Edit Mode"));
685            editModeButton.addActionListener(editMode);
686    
687            databaseLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource(getResourceConverter().getGUIReference("database"))));
688    
689    
690            jToolBar1.add(addCubeButton);
691            jToolBar1.add(addDimensionButton);
692            jToolBar1.add(addDimensionUsageButton);
693            jToolBar1.add(addHierarchyButton);
694            jToolBar1.add(addNamedSetButton);
695            jToolBar1.add(addUserDefinedFunctionButton);
696            jToolBar1.add(addCalculatedMemberButton);
697            jToolBar1.add(addMeasureButton);
698            jToolBar1.add(addLevelButton);
699            jToolBar1.add(addPropertyButton);
700            jToolBar1.addSeparator();
701            jToolBar1.add(addVirtualCubeButton);
702            jToolBar1.add(addVirtualCubeDimensionButton);
703            jToolBar1.add(addVirtualCubeMeasureButton);
704            jToolBar1.addSeparator();
705            jToolBar1.add(addRoleButton);
706            jToolBar1.addSeparator();
707    
708            jToolBar1.add(cutButton);
709            jToolBar1.add(copyButton);
710            jToolBar1.add(pasteButton);
711            jToolBar1.addSeparator();
712            jToolBar1.add(deleteButton);
713            jToolBar1.addSeparator();
714            jToolBar1.add(editModeButton);
715    
716            //========================================================
717            // popup menu
718            //========================================================
719            jPopupMenu = new JPopupMenu();
720    
721            //========================================================
722            // tree mouse listener
723            //========================================================
724            tree.addMouseListener(new PopupTrigger());
725            tree.addKeyListener(new KeyAdapter() {
726                public void keyPressed(KeyEvent e) {
727                        /*
728                        keytext=Delete
729                        keycode=127
730                        keytext=NumPad .
731                        keycode=110
732                         */
733                    int kcode = e.getKeyCode();
734                    if (kcode == 127 || kcode == 110) {
735                        delete(e);
736                    }
737                }
738            });
739    
740    
741            // add footer for connected database
742            footer.setLayout(new java.awt.BorderLayout());
743            footer.add(databaseLabel, java.awt.BorderLayout.CENTER);
744    
745            //========================================================
746            // jpanel
747            //========================================================
748            this.add(jSplitPane1, java.awt.BorderLayout.CENTER);
749            this.add(jToolBar1, java.awt.BorderLayout.NORTH);
750            this.add(footer, java.awt.BorderLayout.SOUTH);
751    
752            updater = new JTreeUpdater(tree);
753    
754        }
755    
756        protected void arrowButtonUpAction(ActionEvent evt) {
757            TreePath tpath = tree.getSelectionPath();
758            if (tpath != null) {
759                TreePath parentpath = tpath.getParentPath();
760                if (parentpath != null) {
761                    tree.setSelectionPath(parentpath);
762                    refreshTree(parentpath);
763                }
764            }
765        }
766    
767        protected void arrowButtonDownAction(ActionEvent evt) {
768            TreePath tpath = tree.getSelectionPath();
769            if (tpath != null) {
770                Object current = tpath.getLastPathComponent();
771                Object child = tree.getModel().getChild(current, 0);
772                if (child != null) {
773                    Object[] treeObjs = new Object[30];
774                    treeObjs[0] = child;
775                    treeObjs[1] = current;
776                    // traverse upward through tree, saving parent nodes
777                    TreePath parentpath;
778                    parentpath = tpath.getParentPath();
779                    int objCnt = 2;
780                    while (parentpath != null) {
781                        Object po = parentpath.getLastPathComponent();
782                        treeObjs[objCnt] = po;
783                        objCnt += 1;
784                        parentpath = parentpath.getParentPath();
785                    }
786                    // reverse the array so that schema is first, then the children
787                    Object[] nodes = new Object[objCnt];
788                    int loopCnt = objCnt - 1;
789                    for (int j = 0; j < objCnt; j++) {
790                        nodes[j] = treeObjs[loopCnt];
791                        loopCnt --;
792                    }
793                    TreePath childPath = new TreePath(nodes);
794                    tree.setSelectionPath(childPath);
795                    refreshTree(childPath);
796                }
797            }
798        }
799    
800        /**
801         * Several methods are called, e.g. editCellAt,  to get the focus set in the
802         * value column of the specified row.  The attribute column has the parameter
803         * name and should not receive focus.
804         */
805        protected void setTableCellFocus(int row) {
806            propertyTable.editCellAt(row, 1);
807            TableCellEditor editor = propertyTable.getCellEditor(row, 1);
808            Component comp = editor.getTableCellEditorComponent(propertyTable,
809                    propertyTable.getValueAt(row, 1), true, row, 1);
810        }
811    
812        /**
813         * @param evt
814         */
815        protected void addCube(ActionEvent evt) {
816            MondrianGuiDef.Schema schema = (MondrianGuiDef.Schema) tree.getModel().getRoot();
817            MondrianGuiDef.Cube cube = new MondrianGuiDef.Cube();
818    
819            cube.name = "";
820    
821            cube.dimensions = new MondrianGuiDef.Dimension[0];
822            cube.measures = new MondrianGuiDef.Measure[0];
823            MondrianGuiDef.Table cfact = new MondrianGuiDef.Table("","Table","");
824            cfact.aggExcludes = new MondrianGuiDef.AggExclude[0];
825            cfact.aggTables = new MondrianGuiDef.AggTable[0];
826    
827            cube.fact = cfact;
828            cube.calculatedMembers = new MondrianGuiDef.CalculatedMember[0];
829            cube.namedSets = new MondrianGuiDef.NamedSet[0];
830    
831            //add cube to schema
832            cube.name = getNewName(getResourceConverter().getString("schemaExplorer.newCube.title","New Cube"), schema.cubes);
833            cube.cache = Boolean.TRUE;
834            cube.enabled = Boolean.TRUE;
835            NodeDef[] temp = schema.cubes;
836            schema.cubes = new MondrianGuiDef.Cube[temp.length + 1];
837            for (int _i = 0; _i < temp.length; _i++) {
838                schema.cubes[_i] = (MondrianGuiDef.Cube) temp[_i];
839            }
840            schema.cubes[schema.cubes.length - 1] = cube;
841    
842            tree.setSelectionPath((new TreePath(model.getRoot())).pathByAddingChild(cube));
843            refreshTree(tree.getSelectionPath());
844            setTableCellFocus(0);
845        }
846    
847        protected void addRole(ActionEvent evt) {
848            MondrianGuiDef.Schema schema = (MondrianGuiDef.Schema) tree.getModel().getRoot();
849            MondrianGuiDef.Role role = new MondrianGuiDef.Role();
850    
851            role.name = "";
852    
853            role.schemaGrants = new MondrianGuiDef.SchemaGrant[0];
854    
855            //add cube to schema
856            role.name = getNewName(getResourceConverter().getString("schemaExplorer.newRole.title","New Role"), schema.roles);
857            NodeDef[] temp = schema.roles;
858            schema.roles = new MondrianGuiDef.Role[temp.length + 1];
859            for (int _i = 0; _i < temp.length; _i++) {
860                schema.roles[_i] = (MondrianGuiDef.Role) temp[_i];
861            }
862            schema.roles[schema.roles.length - 1] = role;
863    
864            tree.setSelectionPath((new TreePath(model.getRoot())).pathByAddingChild(role));
865            refreshTree(tree.getSelectionPath());
866            setTableCellFocus(0);
867        }
868    
869        protected void addVirtualCube(ActionEvent evt) {
870            MondrianGuiDef.Schema schema = (MondrianGuiDef.Schema) tree.getModel().getRoot();
871            MondrianGuiDef.VirtualCube cube = new MondrianGuiDef.VirtualCube();
872    
873            cube.name = "";// get unique name //"New Cube " + schema.cubes.length;
874    
875            cube.dimensions = new MondrianGuiDef.VirtualCubeDimension[0];
876            cube.measures = new MondrianGuiDef.VirtualCubeMeasure[0];
877            cube.calculatedMembers = new MondrianGuiDef.CalculatedMember[0];
878            cube.enabled = Boolean.TRUE;
879    
880            //add cube to schema
881            cube.name = getNewName(getResourceConverter().getString("schemaExplorer.newVirtualCube.title","New Virtual Cube"), schema.virtualCubes);
882            NodeDef[] temp = schema.virtualCubes;
883            schema.virtualCubes = new MondrianGuiDef.VirtualCube[temp.length + 1];
884            for (int _i = 0; _i < temp.length; _i++) {
885                schema.virtualCubes[_i] = (MondrianGuiDef.VirtualCube) temp[_i];
886            }
887            schema.virtualCubes[schema.virtualCubes.length - 1] = cube;
888    
889            tree.setSelectionPath((new TreePath(model.getRoot())).pathByAddingChild(cube));
890            refreshTree(tree.getSelectionPath());
891            setTableCellFocus(0);
892        }
893    
894        protected void addUserDefinedFunction(ActionEvent evt) {
895            MondrianGuiDef.Schema schema = (MondrianGuiDef.Schema) tree.getModel().getRoot();
896            MondrianGuiDef.UserDefinedFunction udf = new MondrianGuiDef.UserDefinedFunction();
897            udf.name = "";// get unique name //"New Udf " + schema.userDefinedFunctions.length;
898    
899            //add cube to schema
900            udf.name = getNewName(getResourceConverter().getString("schemaExplorer.newUserDefinedFunction.title","New User defined Function"), schema.userDefinedFunctions);
901            NodeDef[] temp = schema.userDefinedFunctions;
902            schema.userDefinedFunctions = new MondrianGuiDef.UserDefinedFunction[temp.length + 1];
903            for (int _i = 0; _i < temp.length; _i++) {
904                schema.userDefinedFunctions[_i] = (MondrianGuiDef.UserDefinedFunction) temp[_i];
905            }
906            schema.userDefinedFunctions[schema.userDefinedFunctions.length - 1] = udf;
907            tree.setSelectionPath((new TreePath(model.getRoot())).pathByAddingChild(udf));
908            refreshTree(tree.getSelectionPath());
909            setTableCellFocus(0);
910        }
911    
912        /**
913         * Updates the tree display after an Add / Delete operation.
914         */
915        private void refreshTree(TreePath path) {
916            setDirty(true);
917            if (! dirtyFlag) {
918                setDirtyFlag(true);   // dirty indication shown on title
919                setTitle();
920            }
921            updater.update();
922            tree.scrollPathToVisible(path);
923        }
924    
925        /**
926         * @param evt
927         */
928        protected void addMeasure(ActionEvent evt) {
929            TreePath tpath = tree.getSelectionPath();
930            int parentIndex = -1;
931            Object path = null;
932            if (tpath != null) {
933                for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0; parentIndex--) {
934                    if (tpath.getPathComponent(parentIndex) instanceof MondrianGuiDef.Cube) {
935                        path = tpath.getPathComponent(parentIndex);
936                        break;
937                    }
938                }
939    
940            }
941            //Object path = tree.getSelectionPath().getLastPathComponent();
942            if (!(path instanceof MondrianGuiDef.Cube)) {
943                JOptionPane.showMessageDialog(this, getResourceConverter().getString("schemaExplorer.cubeNotSelected.alert","Cube not selected."),
944                        alert, JOptionPane.WARNING_MESSAGE);
945                return;
946            }
947    
948    
949            MondrianGuiDef.Cube cube = (MondrianGuiDef.Cube) path;
950    
951            MondrianGuiDef.Measure measure = new MondrianGuiDef.Measure();
952            measure.name = "";
953    
954            //add cube to schema
955            measure.name = getNewName(getResourceConverter().getString("schemaExplorer.newMeasure.title","New Measure"), cube.measures);
956            measure.visible = Boolean.TRUE;
957            NodeDef[] temp = cube.measures;
958            cube.measures = new MondrianGuiDef.Measure[temp.length + 1];
959            for (int i = 0; i < temp.length; i++) {
960                cube.measures[i] = (MondrianGuiDef.Measure) temp[i];}
961    
962            cube.measures[cube.measures.length - 1] = measure;
963    
964            Object [] parentPathObjs = new Object[parentIndex + 1];
965            for (int i = 0; i <= parentIndex; i++) {
966                parentPathObjs[i] = tpath.getPathComponent(i) ;
967            }
968            TreePath parentPath = new TreePath(parentPathObjs);
969            tree.setSelectionPath(parentPath.pathByAddingChild(measure));
970    
971            refreshTree(tree.getSelectionPath());
972            setTableCellFocus(0);
973        }
974    
975        protected void addAggPattern(ActionEvent evt) {
976            TreePath tpath = tree.getSelectionPath();
977            int parentIndex = -1;
978            Object path = null;
979            if (tpath != null) {
980                for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0; parentIndex--) {
981                    if (tpath.getPathComponent(parentIndex) instanceof MondrianGuiDef.Table) {
982                        if (((parentIndex - 1) >= 0) && (tpath.getPathComponent(parentIndex - 1) instanceof MondrianGuiDef.Cube)) {
983                            path = tpath.getPathComponent(parentIndex);
984                            break;
985                        }
986                    }
987                }
988    
989            }
990            //Object path = tree.getSelectionPath().getLastPathComponent();
991            if (!(path instanceof MondrianGuiDef.Table)) {
992                JOptionPane.showMessageDialog(this, getResourceConverter().getString("schemaExplorer.cubeFactTableNotSelected.alert","Cube Fact Table not selected."), alert, JOptionPane.WARNING_MESSAGE);
993                return;
994            }
995    
996    
997            MondrianGuiDef.Table factTable = (MondrianGuiDef.Table) path;
998    
999            MondrianGuiDef.AggPattern aggname = new MondrianGuiDef.AggPattern();
1000            aggname.pattern = "";
1001    
1002            //add cube to schema
1003            aggname.ignorecase = Boolean.TRUE;
1004            aggname.factcount = null;
1005            aggname.ignoreColumns = new MondrianGuiDef.AggIgnoreColumn[0];
1006            aggname.foreignKeys = new MondrianGuiDef.AggForeignKey[0];
1007            aggname.measures = new MondrianGuiDef.AggMeasure[0];
1008            aggname.levels = new MondrianGuiDef.AggLevel[0];
1009            aggname.excludes = new MondrianGuiDef.AggExclude[0];
1010    
1011            NodeDef[] temp = factTable.aggTables;
1012            factTable.aggTables = new MondrianGuiDef.AggTable[temp.length + 1];
1013            for (int i = 0; i < temp.length; i++) {
1014                factTable.aggTables[i] = (MondrianGuiDef.AggTable) temp[i];}
1015    
1016            factTable.aggTables[factTable.aggTables.length - 1] = aggname;
1017    
1018            Object [] parentPathObjs = new Object[parentIndex + 1];
1019            for (int i = 0; i <= parentIndex; i++) {
1020                parentPathObjs[i] = tpath.getPathComponent(i) ;
1021            }
1022            TreePath parentPath = new TreePath(parentPathObjs);
1023            tree.setSelectionPath(parentPath.pathByAddingChild(aggname));
1024    
1025            refreshTree(tree.getSelectionPath());
1026            setTableCellFocus(0);
1027        }
1028    
1029        protected void addAggName(ActionEvent evt) {
1030            TreePath tpath = tree.getSelectionPath();
1031            int parentIndex = -1;
1032            Object path = null;
1033            if (tpath != null) {
1034                for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0; parentIndex--) {
1035                    if (tpath.getPathComponent(parentIndex) instanceof MondrianGuiDef.Table) {
1036                        if (((parentIndex - 1) >= 0) && (tpath.getPathComponent(parentIndex - 1) instanceof MondrianGuiDef.Cube)) {
1037                            path = tpath.getPathComponent(parentIndex);
1038                            break;
1039                        }
1040                    }
1041                }
1042            }
1043            if (!(path instanceof MondrianGuiDef.Table)) {
1044                JOptionPane.showMessageDialog(this, getResourceConverter().getString("schemaExplorer.tableNotSelected.alert","Table not selected."), alert, JOptionPane.WARNING_MESSAGE);
1045                return;
1046            }
1047    
1048            MondrianGuiDef.Table factTable = (MondrianGuiDef.Table) path;
1049    
1050            MondrianGuiDef.AggName aggname = new MondrianGuiDef.AggName();
1051            aggname.name = "";
1052    
1053            //add cube to schema
1054            aggname.ignorecase = Boolean.TRUE;
1055            aggname.factcount = null;
1056            aggname.ignoreColumns = new MondrianGuiDef.AggIgnoreColumn[0];
1057            aggname.foreignKeys = new MondrianGuiDef.AggForeignKey[0];
1058            aggname.measures = new MondrianGuiDef.AggMeasure[0];
1059            aggname.levels = new MondrianGuiDef.AggLevel[0];
1060    
1061    
1062            NodeDef[] temp = factTable.aggTables;
1063            factTable.aggTables = new MondrianGuiDef.AggTable[temp.length + 1];
1064            for (int i = 0; i < temp.length; i++) {
1065                factTable.aggTables[i] = (MondrianGuiDef.AggTable) temp[i];}
1066    
1067            factTable.aggTables[factTable.aggTables.length - 1] = aggname;
1068    
1069            Object [] parentPathObjs = new Object[parentIndex + 1];
1070            for (int i = 0; i <= parentIndex; i++) {
1071                parentPathObjs[i] = tpath.getPathComponent(i) ;
1072            }
1073            TreePath parentPath = new TreePath(parentPathObjs);
1074            tree.setSelectionPath(parentPath.pathByAddingChild(aggname));
1075    
1076            refreshTree(tree.getSelectionPath());
1077            setTableCellFocus(0);
1078        }
1079    
1080        protected void addAggExclude(ActionEvent evt) {
1081            TreePath tpath = tree.getSelectionPath();
1082            int parentIndex = -1;
1083            Object path = null;
1084            if (tpath != null) {
1085                for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0; parentIndex--) {
1086                    // aggexcludes can be added to cube fact table or
1087                    if (tpath.getPathComponent(parentIndex) instanceof MondrianGuiDef.Table) {
1088                        if (((parentIndex - 1) >= 0) && (tpath.getPathComponent(parentIndex - 1) instanceof MondrianGuiDef.Cube)) {
1089                            path = tpath.getPathComponent(parentIndex);
1090                            break;
1091                        }
1092                    } else if (tpath.getPathComponent(parentIndex) instanceof MondrianGuiDef.AggPattern) {
1093                        // aggexcludes can also be added to aggregate patterns
1094                        path = tpath.getPathComponent(parentIndex);
1095                        break;
1096    
1097                    }
1098                }
1099    
1100            }
1101            //Object path = tree.getSelectionPath().getLastPathComponent();
1102            if (!(path instanceof MondrianGuiDef.Table || path instanceof MondrianGuiDef.AggPattern)) {
1103                JOptionPane.showMessageDialog(this, getResourceConverter().getString("schemaExplorer.cubeFactTableOrAggPatternNotSelected.alert","Cube Fact Table or Aggregate Pattern not selected."), alert, JOptionPane.WARNING_MESSAGE);
1104                return;
1105            }
1106    
1107            MondrianGuiDef.AggExclude aggexclude = new MondrianGuiDef.AggExclude();
1108            aggexclude.pattern = "";
1109    
1110            aggexclude.ignorecase = Boolean.TRUE;
1111    
1112            if (path instanceof MondrianGuiDef.Table) {
1113                MondrianGuiDef.Table parent = (MondrianGuiDef.Table) path;  // fact table
1114    
1115                NodeDef[] temp = parent.aggExcludes;
1116                parent.aggExcludes = new MondrianGuiDef.AggExclude[temp.length + 1];
1117                for (int i = 0; i < temp.length; i++) {
1118                    parent.aggExcludes[i] = (MondrianGuiDef.AggExclude) temp[i];}
1119    
1120                parent.aggExcludes[parent.aggExcludes.length - 1] = aggexclude;
1121            } else {
1122                MondrianGuiDef.AggPattern parent = (MondrianGuiDef.AggPattern) path;  // aggpattern
1123                NodeDef[] temp = parent.excludes;
1124                parent.excludes = new MondrianGuiDef.AggExclude[temp.length + 1];
1125                for (int i = 0; i < temp.length; i++) {
1126                    parent.excludes[i] = (MondrianGuiDef.AggExclude) temp[i];}
1127    
1128                parent.excludes[parent.excludes.length - 1] = aggexclude;
1129            }
1130    
1131            Object [] parentPathObjs = new Object[parentIndex + 1];
1132            for (int i = 0; i <= parentIndex; i++) {
1133                parentPathObjs[i] = tpath.getPathComponent(i) ;
1134            }
1135            TreePath parentPath = new TreePath(parentPathObjs);
1136            tree.setSelectionPath(parentPath.pathByAddingChild(aggexclude));
1137    
1138            refreshTree(tree.getSelectionPath());
1139            setTableCellFocus(0);
1140        }
1141    
1142        protected void addAggIgnoreColumn(ActionEvent evt) {
1143            TreePath tpath = tree.getSelectionPath();
1144            int parentIndex = -1;
1145            Object path = null;
1146            if (tpath != null) {
1147                for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0; parentIndex--) {
1148                    if (tpath.getPathComponent(parentIndex) instanceof MondrianGuiDef.AggTable) {
1149                        path = tpath.getPathComponent(parentIndex);
1150                        break;
1151                    }
1152                }
1153    
1154            }
1155            //Object path = tree.getSelectionPath().getLastPathComponent();
1156            if (!(path instanceof MondrianGuiDef.AggTable)) {
1157                JOptionPane.showMessageDialog(this, getResourceConverter().getString("schemaExplorer.aggregateTableNotSelected.alert","Aggregate Table not selected."), alert, JOptionPane.WARNING_MESSAGE);
1158                return;
1159            }
1160    
1161    
1162            MondrianGuiDef.AggTable aggTable = (MondrianGuiDef.AggTable) path;
1163    
1164            MondrianGuiDef.AggIgnoreColumn aggicol = new MondrianGuiDef.AggIgnoreColumn();
1165            aggicol.column = "";
1166    
1167            NodeDef[] temp = aggTable.ignoreColumns;
1168            aggTable.ignoreColumns = new MondrianGuiDef.AggIgnoreColumn[temp.length + 1];
1169            for (int i = 0; i < temp.length; i++) {
1170                aggTable.ignoreColumns[i] = (MondrianGuiDef.AggIgnoreColumn) temp[i];}
1171    
1172            aggTable.ignoreColumns[aggTable.ignoreColumns.length - 1] = aggicol;
1173    
1174            Object [] parentPathObjs = new Object[parentIndex + 1];
1175            for (int i = 0; i <= parentIndex; i++) {
1176                parentPathObjs[i] = tpath.getPathComponent(i);
1177            }
1178            TreePath parentPath = new TreePath(parentPathObjs);
1179            tree.setSelectionPath(parentPath.pathByAddingChild(aggicol));
1180    
1181            refreshTree(tree.getSelectionPath());
1182            setTableCellFocus(0);
1183        }
1184    
1185        protected void addAggForeignKey(ActionEvent evt) {
1186            TreePath tpath = tree.getSelectionPath();
1187            int parentIndex = -1;
1188            Object path = null;
1189            if (tpath != null) {
1190                for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0; parentIndex--) {
1191                    if (tpath.getPathComponent(parentIndex) instanceof MondrianGuiDef.AggTable) {
1192                        path = tpath.getPathComponent(parentIndex);
1193                        break;
1194                    }
1195                }
1196    
1197            }
1198            //Object path = tree.getSelectionPath().getLastPathComponent();
1199            if (!(path instanceof MondrianGuiDef.AggTable)) {
1200                JOptionPane.showMessageDialog(this, getResourceConverter().getString("schemaExplorer.aggregateTableNotSelected.alert","Aggregate Table not selected."), alert, JOptionPane.WARNING_MESSAGE);
1201                return;
1202            }
1203    
1204    
1205            MondrianGuiDef.AggTable aggTable = (MondrianGuiDef.AggTable) path;
1206    
1207            MondrianGuiDef.AggForeignKey aggfkey = new MondrianGuiDef.AggForeignKey();
1208    
1209            NodeDef[] temp = aggTable.foreignKeys;
1210            aggTable.foreignKeys = new MondrianGuiDef.AggForeignKey[temp.length + 1];
1211            for (int i = 0; i < temp.length; i++) {
1212                aggTable.foreignKeys[i] = (MondrianGuiDef.AggForeignKey) temp[i];}
1213    
1214            aggTable.foreignKeys[aggTable.foreignKeys.length - 1] = aggfkey;
1215    
1216            Object [] parentPathObjs = new Object[parentIndex + 1];
1217            for (int i = 0; i <= parentIndex; i++) {
1218                parentPathObjs[i] = tpath.getPathComponent(i) ;
1219            }
1220            TreePath parentPath = new TreePath(parentPathObjs);
1221            tree.setSelectionPath(parentPath.pathByAddingChild(aggfkey));
1222    
1223            refreshTree(tree.getSelectionPath());
1224            setTableCellFocus(0);
1225        }
1226    
1227        protected void addAggMeasure(ActionEvent evt) {
1228            TreePath tpath = tree.getSelectionPath();
1229            int parentIndex = -1;
1230            Object path = null;
1231            if (tpath != null) {
1232                for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0; parentIndex--) {
1233                    if (tpath.getPathComponent(parentIndex) instanceof MondrianGuiDef.AggTable) {
1234                        path = tpath.getPathComponent(parentIndex);
1235                        break;
1236                    }
1237                }
1238    
1239            }
1240            //Object path = tree.getSelectionPath().getLastPathComponent();
1241            if (!(path instanceof MondrianGuiDef.AggTable)) {
1242                JOptionPane.showMessageDialog(this, getResourceConverter().getString("schemaExplorer.aggregateTableNotSelected.alert","Aggregate Table not selected."), alert, JOptionPane.WARNING_MESSAGE);
1243                return;
1244            }
1245    
1246    
1247            MondrianGuiDef.AggTable aggTable = (MondrianGuiDef.AggTable) path;
1248    
1249            MondrianGuiDef.AggMeasure aggmeasure = new MondrianGuiDef.AggMeasure();
1250    
1251            NodeDef[] temp = aggTable.measures;
1252            aggTable.measures = new MondrianGuiDef.AggMeasure[temp.length + 1];
1253            for (int i = 0; i < temp.length; i++) {
1254                aggTable.measures[i] = (MondrianGuiDef.AggMeasure) temp[i];}
1255    
1256            aggTable.measures[aggTable.measures.length - 1] = aggmeasure;
1257    
1258            Object [] parentPathObjs = new Object[parentIndex + 1];
1259            for (int i = 0; i <= parentIndex; i++) {
1260                parentPathObjs[i] = tpath.getPathComponent(i) ;
1261            }
1262            TreePath parentPath = new TreePath(parentPathObjs);
1263            tree.setSelectionPath(parentPath.pathByAddingChild(aggmeasure));
1264    
1265            refreshTree(tree.getSelectionPath());
1266            setTableCellFocus(0);
1267        }
1268    
1269        protected void addAggLevel(ActionEvent evt) {
1270            TreePath tpath = tree.getSelectionPath();
1271            int parentIndex = -1;
1272            Object path = null;
1273            if (tpath != null) {
1274                for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0; parentIndex--) {
1275                    if (tpath.getPathComponent(parentIndex) instanceof MondrianGuiDef.AggTable) {
1276                        path = tpath.getPathComponent(parentIndex);
1277                        break;
1278                    }
1279                }
1280    
1281            }
1282            if (!(path instanceof MondrianGuiDef.AggTable)) {
1283                JOptionPane.showMessageDialog(this, getResourceConverter().getString("schemaExplorer.aggregateTableNotSelected.alert","Aggregate Table not selected."), alert, JOptionPane.WARNING_MESSAGE);
1284                return;
1285            }
1286    
1287    
1288            MondrianGuiDef.AggTable aggTable = (MondrianGuiDef.AggTable) path;
1289    
1290            MondrianGuiDef.AggLevel agglevel = new MondrianGuiDef.AggLevel();
1291    
1292            NodeDef[] temp = aggTable.levels;
1293            aggTable.levels = new MondrianGuiDef.AggLevel[temp.length + 1];
1294            for (int i = 0; i < temp.length; i++) {
1295                aggTable.levels[i] = (MondrianGuiDef.AggLevel) temp[i];}
1296    
1297            aggTable.levels[aggTable.levels.length - 1] = agglevel;
1298    
1299            Object [] parentPathObjs = new Object[parentIndex + 1];
1300            for (int i = 0; i <= parentIndex; i++) {
1301                parentPathObjs[i] = tpath.getPathComponent(i) ;
1302            }
1303            TreePath parentPath = new TreePath(parentPathObjs);
1304            tree.setSelectionPath(parentPath.pathByAddingChild(agglevel));
1305    
1306            refreshTree(tree.getSelectionPath());
1307            setTableCellFocus(0);
1308        }
1309    
1310        protected void addAggFactCount(ActionEvent evt) {
1311            TreePath tpath = tree.getSelectionPath();
1312            int parentIndex = -1;
1313            Object path = null;
1314            if (tpath != null) {
1315                for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0; parentIndex--) {
1316                    if (tpath.getPathComponent(parentIndex) instanceof MondrianGuiDef.AggTable) {
1317                        path = tpath.getPathComponent(parentIndex);
1318                        break;
1319                    }
1320                }
1321    
1322            }
1323            if (! ((path instanceof MondrianGuiDef.AggName) ||
1324                    (path instanceof MondrianGuiDef.AggPattern))) {
1325                JOptionPane.showMessageDialog(this, getResourceConverter().getString("schemaExplorer.aggregateTableOrAggPatternNotSelected.alert","Aggregate Table or Aggregate Pattern not selected."),
1326                        alert, JOptionPane.WARNING_MESSAGE);
1327                return;
1328            }
1329    
1330            MondrianGuiDef.AggFactCount aggFactCount = new MondrianGuiDef.AggFactCount();
1331            MondrianGuiDef.AggTable aggName = null;
1332            MondrianGuiDef.AggPattern aggPattern = null;
1333            if (path instanceof MondrianGuiDef.AggName) {
1334                aggName = (MondrianGuiDef.AggName) path;
1335                aggName.factcount = new MondrianGuiDef.AggFactCount();
1336            } else {
1337                aggPattern = (MondrianGuiDef.AggPattern) path;
1338                aggPattern.factcount = new MondrianGuiDef.AggFactCount();
1339            }
1340    
1341            Object [] parentPathObjs = new Object[parentIndex + 1];
1342            for (int i = 0; i <= parentIndex; i++) {
1343                parentPathObjs[i] = tpath.getPathComponent(i) ;
1344            }
1345            TreePath parentPath = new TreePath(parentPathObjs);
1346            tree.setSelectionPath(parentPath.pathByAddingChild(aggFactCount));
1347    
1348            refreshTree(tree.getSelectionPath());
1349            setTableCellFocus(0);
1350        }
1351    
1352        protected void addVirtualCubeMeasure(ActionEvent evt) {
1353            TreePath tpath = tree.getSelectionPath();
1354            int parentIndex = -1;
1355            Object path = null;
1356            if (tpath != null) {
1357                for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0; parentIndex--) {
1358                    if (tpath.getPathComponent(parentIndex) instanceof MondrianGuiDef.VirtualCube) {
1359                        //System.out.println("==== path element "+i+" ="+tpath.getPathComponent(i).getClass().toString());
1360                        path = tpath.getPathComponent(parentIndex);
1361                        //System.out.println("Cube name ="+((MondrianGuiDef.Cube) path).name);
1362                        break;
1363                    }
1364                }
1365    
1366            }
1367            //Object path = tree.getSelectionPath().getLastPathComponent();
1368            if (!(path instanceof MondrianGuiDef.VirtualCube)) {
1369                JOptionPane.showMessageDialog(this, getResourceConverter().getString("schemaExplorer.virtualCubeNotSelected.alert","Virtual Cube not selected."), alert, JOptionPane.WARNING_MESSAGE);
1370                return;
1371            }
1372    
1373    
1374            MondrianGuiDef.VirtualCube cube = (MondrianGuiDef.VirtualCube) path;
1375    
1376            MondrianGuiDef.VirtualCubeMeasure measure = new MondrianGuiDef.VirtualCubeMeasure();
1377            measure.name = ""; // get unique name //"New Measure " + cube.measures.length;
1378    
1379            //add cube to schema
1380            measure.name = getNewName(getResourceConverter().getString("schemaExplorer.newVirtualMeasure.title","New Virtual Measure"), cube.measures);
1381            measure.visible = Boolean.TRUE; // default true
1382    
1383            NodeDef[] temp = cube.measures;
1384            cube.measures = new MondrianGuiDef.VirtualCubeMeasure[temp.length + 1];
1385            for (int i = 0; i < temp.length; i++) {
1386                cube.measures[i] = (MondrianGuiDef.VirtualCubeMeasure) temp[i];}
1387    
1388            cube.measures[cube.measures.length - 1] = measure;
1389    
1390            Object [] parentPathObjs = new Object[parentIndex + 1];
1391            for (int i = 0; i <= parentIndex; i++) {
1392                parentPathObjs[i] = tpath.getPathComponent(i) ;
1393            }
1394            TreePath parentPath = new TreePath(parentPathObjs);
1395            tree.setSelectionPath(parentPath.pathByAddingChild(measure));
1396    
1397            refreshTree(tree.getSelectionPath());
1398            setTableCellFocus(0);
1399        }
1400    
1401        protected void addCalculatedMember(ActionEvent evt) {
1402            TreePath tpath = tree.getSelectionPath();
1403            Object path = null;
1404            int parentIndex = -1;
1405            if (tpath != null) {
1406                for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0; parentIndex--) {
1407                    if ((tpath.getPathComponent(parentIndex) instanceof MondrianGuiDef.Cube) ||
1408                            (tpath.getPathComponent(parentIndex) instanceof MondrianGuiDef.VirtualCube)) {
1409                        //System.out.println("==== path element "+i+" ="+tpath.getPathComponent(i).getClass().toString());
1410                        path = tpath.getPathComponent(parentIndex);
1411                        //System.out.println("Cube name ="+((MondrianGuiDef.Cube) path).name);
1412                        break;
1413                    }
1414                }
1415    
1416            }
1417            if (! ((path instanceof MondrianGuiDef.Cube) || (path instanceof MondrianGuiDef.VirtualCube))) {
1418                JOptionPane.showMessageDialog(this, getResourceConverter().getString("schemaExplorer.cubeOrVirtualCubeNotSelected.alert","Cube or Virtual Cube not selected."), alert, JOptionPane.WARNING_MESSAGE);
1419                return;
1420            }
1421    
1422            MondrianGuiDef.Cube cube = null;
1423            MondrianGuiDef.VirtualCube vcube = null;
1424    
1425            if (path instanceof MondrianGuiDef.Cube) {
1426                cube = (MondrianGuiDef.Cube) path;
1427            } else {
1428                vcube = (MondrianGuiDef.VirtualCube) path;
1429            }
1430    
1431            MondrianGuiDef.CalculatedMember calcmember = new MondrianGuiDef.CalculatedMember();
1432            calcmember.name = "";
1433            calcmember.dimension = "Measures";
1434            calcmember.visible = Boolean.TRUE;  // default value
1435            calcmember.formatString = "";
1436            calcmember.formula = "";
1437            calcmember.formulaElement = new MondrianGuiDef.Formula();
1438            calcmember.memberProperties = new MondrianGuiDef.CalculatedMemberProperty[0];
1439    
1440            //add cube to schema
1441            if (cube != null) {
1442                calcmember.name = getNewName(getResourceConverter().getString("schemaExplorer.newCalculatedMember.title","New Calculated Member"), cube.calculatedMembers);
1443                NodeDef[] temp = cube.calculatedMembers;
1444                cube.calculatedMembers = new MondrianGuiDef.CalculatedMember[temp.length + 1];
1445                for (int i = 0; i < temp.length; i++) {
1446                    cube.calculatedMembers[i] = (MondrianGuiDef.CalculatedMember) temp[i];}
1447    
1448                cube.calculatedMembers[cube.calculatedMembers.length - 1] = calcmember;
1449            } else {
1450                calcmember.name = getNewName(getResourceConverter().getString("schemaExplorer.newCalculatedMember.title","New Calculated Member"), vcube.calculatedMembers);
1451                NodeDef[] temp = vcube.calculatedMembers;
1452                vcube.calculatedMembers = new MondrianGuiDef.CalculatedMember[temp.length + 1];
1453                for (int i = 0; i < temp.length; i++) {
1454                    vcube.calculatedMembers[i] = (MondrianGuiDef.CalculatedMember) temp[i];}
1455    
1456                vcube.calculatedMembers[vcube.calculatedMembers.length - 1] = calcmember;
1457    
1458            }
1459    
1460            Object [] parentPathObjs = new Object[parentIndex + 1];
1461            for (int i = 0; i <= parentIndex; i++) {
1462                parentPathObjs[i] = tpath.getPathComponent(i) ;
1463            }
1464            TreePath parentPath = new TreePath(parentPathObjs);
1465            tree.setSelectionPath(parentPath.pathByAddingChild(calcmember));
1466    
1467            refreshTree(tree.getSelectionPath());
1468            setTableCellFocus(0);
1469    }
1470    
1471        protected boolean editMode(EventObject evt) {
1472            editModeXML = ! isEditModeXML();    // toggle edit mode between xml or properties table form
1473            editModeButton.setSelected(isEditModeXML());
1474            if (isEditModeXML()) {
1475                jSplitPane1.setRightComponent(jPanelXML);
1476            } else {
1477                jSplitPane1.setRightComponent(jPanel1);
1478            }
1479            // update the workbench view menu
1480            Component o = parentIFrame.getDesktopPane().getParent();
1481            while (o != null) {
1482                if (o.getClass() == Workbench.class) {
1483                    ((Workbench) o).getViewXMLMenuItem().setSelected(editModeXML);
1484                    break;
1485                }
1486                o = o.getParent();
1487            }
1488            return isEditModeXML();
1489        }
1490    
1491        protected void delete(EventObject evt) {
1492            // delete the selected  schema object
1493            TreePath tpath = tree.getSelectionPath();
1494            if (tpath == null) {
1495                JOptionPane.showMessageDialog(this, getResourceConverter().getString("schemaExplorer.objectToDeleteNotSelected.alert","Object to delete in Schema not selected."), alert, JOptionPane.WARNING_MESSAGE);
1496                return ;
1497            }
1498            Object child = tpath.getLastPathComponent(); // to be deleted
1499            Object nextSibling = null, prevSibling = null;
1500    
1501            Object parent = null;
1502            Object grandparent = null;
1503            boolean grandparentAsSibling = false;
1504    
1505            for (int i = tpath.getPathCount() - 1 - 1; i >= 0; i--) {
1506                parent = tpath.getPathComponent(i);   // get parent path
1507                if (tpath.getPathCount() - 3 > 0) {
1508                    grandparent = tpath.getPathComponent(i - 1);   // get parent path
1509                }
1510                break;
1511            }
1512            if (parent == null) {
1513                JOptionPane.showMessageDialog(this, getResourceConverter().getString("schemaExplorer.cantDeleteObject.alert","Schema object cannot be deleted."), alert, JOptionPane.WARNING_MESSAGE);
1514                return ;
1515            }
1516    
1517            boolean tofind = true;
1518    
1519            Field[] fs = parent.getClass().getFields();
1520            for (int i = 0; i < fs.length; i++) {
1521                if (fs[i].getType().isArray() && (fs[i].getType().getComponentType().isInstance(child))) {
1522                    try {
1523                        Object parentArr = fs[i].get(parent); // get the parent's array of child objects
1524                        int parentArrLen = Array.getLength(parentArr);
1525                        Object newArr = Array.newInstance(fs[i].getType().getComponentType(), parentArrLen - 1);
1526                        tofind = true;
1527                        for (int k = 0, m = 0; k < parentArrLen; k++) {
1528                            Object match = Array.get(parentArr, k);
1529    
1530                            if (tofind && match.equals(child)) {
1531                                if (child instanceof MondrianGuiDef.CubeDimension) {
1532                                    // check equality of parent class attributes for a special case when child is an object of CubeDimensions
1533                                    MondrianGuiDef.CubeDimension matchDim = (MondrianGuiDef.CubeDimension) match;
1534                                    MondrianGuiDef.CubeDimension childDim = (MondrianGuiDef.CubeDimension) child;
1535    
1536                                    if (((matchDim.name == null && childDim.name == null) || (matchDim.name != null && matchDim.name.equals(childDim.name))) &&
1537                                            ((matchDim.caption == null && childDim.caption == null) || (matchDim.caption != null && matchDim.caption.equals(childDim.caption))) &&
1538                                            ((matchDim.foreignKey == null && childDim.foreignKey == null) || (matchDim.foreignKey != null && matchDim.foreignKey.equals(childDim.foreignKey)))) {
1539                                        tofind = false;
1540                                        if (k + 1 < parentArrLen) {
1541                                            nextSibling = Array.get(parentArr, k + 1);
1542                                        }
1543                                        if (k - 1 >= 0) {
1544                                            prevSibling = Array.get(parentArr, k - 1);
1545                                        }
1546                                        continue;
1547                                    }
1548                                } else {
1549                                    // other cases require no such check
1550                                    tofind = false;
1551                                    if (k + 1 < parentArrLen) {
1552                                        nextSibling = Array.get(parentArr, k + 1);
1553                                    }
1554                                    if (k - 1 >= 0) {
1555                                        prevSibling = Array.get(parentArr, k - 1);
1556                                    }
1557                                    continue;
1558    
1559                                }
1560                            }
1561                            Array.set(newArr, m++, match);
1562                        }
1563                        // after deletion check before the saving the new array in parent
1564                        // check for min 1 SQL object(child)  in (parent) expression  for (grandparent) level
1565                        // if 1 or more, save the newarray in parent, otherwise delete parent from grandparent
1566                        if ((child instanceof MondrianGuiDef.SQL) &&
1567                                (parent instanceof MondrianGuiDef.ExpressionView) &&
1568                                (Array.getLength(newArr) < 1)) {
1569                            if (parent instanceof MondrianGuiDef.KeyExpression) {
1570                                ((MondrianGuiDef.Level)grandparent).keyExp = null;
1571                            } else if (parent instanceof MondrianGuiDef.NameExpression) {
1572                                ((MondrianGuiDef.Level)grandparent).nameExp = null;
1573                            } else if (parent instanceof MondrianGuiDef.OrdinalExpression) {
1574                                ((MondrianGuiDef.Level)grandparent).ordinalExp = null;
1575                            } else if (parent instanceof MondrianGuiDef.ParentExpression) {
1576                                ((MondrianGuiDef.Level)grandparent).parentExp = null;
1577                            } else if (parent instanceof MondrianGuiDef.MeasureExpression) {
1578                                ((MondrianGuiDef.Measure)grandparent).measureExp = null;
1579                            }
1580                            grandparentAsSibling = true;
1581                        } else {
1582                            fs[i].set(parent, newArr);
1583                        }
1584    
1585                    } catch (Exception ex) {
1586                        // field not found
1587                    }
1588                    break;
1589                } else if  (fs[i].getType().isInstance(child)) {  // parent's field is an instanceof child object'
1590                    try {
1591                        if (parent instanceof MondrianGuiDef.Join ||
1592                            (parent instanceof MondrianGuiDef.Cube && child instanceof MondrianGuiDef.RelationOrJoin) ||
1593                            (parent instanceof MondrianGuiDef.Closure && child instanceof MondrianGuiDef.RelationOrJoin)) {
1594                            // do not delete if deleting left or right table of a join
1595                            // do not delete table of cube or closure
1596                        } else {
1597                            if (fs[i].get(parent) == child) {
1598                                fs[i].set(parent, null);
1599                                break;
1600                            }
1601                        }
1602                    } catch (Exception ex) {
1603                        LOGGER.error("delete", ex);
1604                        // field not found
1605                    }
1606                }
1607            }
1608    
1609    
1610            // delete the node from set of expended nodes in JTreeUpdater also
1611            TreeExpansionEvent e = null;
1612            e = new TreeExpansionEvent(tree, tpath);
1613            updater.treeCollapsed(e);
1614    
1615            if (nextSibling != null) {
1616                tree.setSelectionPath(tpath.getParentPath().pathByAddingChild(nextSibling));
1617            } else if (prevSibling != null) {
1618                tree.setSelectionPath(tpath.getParentPath().pathByAddingChild(prevSibling));
1619            } else if (grandparentAsSibling) {
1620                tree.setSelectionPath(tpath.getParentPath().getParentPath());
1621            } else {
1622                tree.setSelectionPath(tpath.getParentPath());
1623            }
1624            refreshTree(tree.getSelectionPath());
1625        }
1626    
1627        /**
1628         * @param evt
1629         */
1630        protected void addDimension(ActionEvent evt) {
1631            TreePath tpath = tree.getSelectionPath();
1632            Object path = null;
1633            int parentIndex = -1;
1634            if (tpath != null) {
1635                for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0; parentIndex--) {
1636                    if ((tpath.getPathComponent(parentIndex) instanceof MondrianGuiDef.Cube) ||
1637                            (tpath.getPathComponent(parentIndex) instanceof MondrianGuiDef.Schema)) {
1638                        path =  tpath.getPathComponent(parentIndex);
1639                        break;
1640                    }
1641                }
1642            }
1643    
1644            //Object path = tree.getSelectionPath().getLastPathComponent();
1645            if (! ((path instanceof MondrianGuiDef.Cube) || (path instanceof MondrianGuiDef.Schema))) {
1646                JOptionPane.showMessageDialog(this, getResourceConverter().getString("schemaExplorer.cubeOrSchemaNotSelected.alert","Cube or Schema not selected."), alert, JOptionPane.WARNING_MESSAGE);
1647                return;
1648            }
1649    
1650            MondrianGuiDef.Cube cube = null;
1651            MondrianGuiDef.Schema schema = null;
1652    
1653            if (path instanceof MondrianGuiDef.Cube) {
1654                cube = (MondrianGuiDef.Cube) path;
1655            } else {
1656                schema = (MondrianGuiDef.Schema) path;
1657            }
1658    
1659            MondrianGuiDef.Dimension dimension = new MondrianGuiDef.Dimension();
1660            dimension.name = "";
1661            dimension.type = "StandardDimension";    // default dimension type
1662            dimension.hierarchies = new MondrianGuiDef.Hierarchy[1];
1663            dimension.hierarchies[0] = new MondrianGuiDef.Hierarchy();
1664            dimension.hierarchies[0].name = getResourceConverter().getString("schemaExplorer.newHierarchyInTree.title","New Hierarchy 0");
1665            dimension.hierarchies[0].hasAll = true;
1666            dimension.hierarchies[0].levels = new MondrianGuiDef.Level[0];
1667            dimension.hierarchies[0].memberReaderParameters = new MondrianGuiDef.MemberReaderParameter[0];
1668            dimension.hierarchies[0].relation = new MondrianGuiDef.Table("", "Table", "");
1669    
1670            //add cube to schema
1671            if (cube != null) {
1672                dimension.name = getNewName(getResourceConverter().getString("schemaExplorer.newDimension.title","New Dimension"), cube.dimensions);
1673                NodeDef[] temp = cube.dimensions;
1674                cube.dimensions = new MondrianGuiDef.CubeDimension[temp.length + 1];
1675                for (int i = 0; i < temp.length; i++) {
1676                    cube.dimensions[i] = (MondrianGuiDef.CubeDimension) temp[i];
1677                }
1678                cube.dimensions[cube.dimensions.length - 1] = dimension;
1679            } else {
1680                dimension.name = getNewName(getResourceConverter().getString("schemaExplorer.newDimension.title","New Dimension"), schema.dimensions);
1681                NodeDef[] temp = schema.dimensions;
1682                schema.dimensions = new MondrianGuiDef.Dimension[temp.length + 1];
1683                for (int i = 0; i < temp.length; i++) {
1684                    schema.dimensions[i] = (MondrianGuiDef.Dimension) temp[i];}
1685    
1686                schema.dimensions[schema.dimensions.length - 1] = dimension;
1687            }
1688    
1689            Object [] parentPathObjs = new Object[parentIndex + 1];
1690            for (int i = 0; i <= parentIndex; i++) {
1691                parentPathObjs[i] = tpath.getPathComponent(i) ;
1692            }
1693            TreePath parentPath = new TreePath(parentPathObjs);
1694            tree.setSelectionPath(parentPath.pathByAddingChild(dimension));
1695    
1696            refreshTree(tree.getSelectionPath());
1697            setTableCellFocus(0);
1698        }
1699    
1700    
1701        protected void addVirtualCubeDimension(ActionEvent evt) {
1702            TreePath tpath = tree.getSelectionPath();
1703            Object path = null;
1704            int parentIndex = -1;
1705            if (tpath != null) {
1706                for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0; parentIndex--) {
1707                    if (tpath.getPathComponent(parentIndex) instanceof MondrianGuiDef.VirtualCube) {
1708                        path =  tpath.getPathComponent(parentIndex);
1709                        break;
1710                    }
1711                }
1712            }
1713    
1714            //Object path = tree.getSelectionPath().getLastPathComponent();
1715            if (! (path instanceof MondrianGuiDef.VirtualCube)) {
1716                JOptionPane.showMessageDialog(this, getResourceConverter().getString("schemaExplorer.virtualCubeNotSelected.alert","Virtual Cube not selected."), alert, JOptionPane.WARNING_MESSAGE);
1717                return;
1718            }
1719    
1720            MondrianGuiDef.VirtualCube cube = (MondrianGuiDef.VirtualCube) path;;
1721    
1722            MondrianGuiDef.VirtualCubeDimension dimension = new MondrianGuiDef.VirtualCubeDimension();
1723            dimension.name = "";
1724    
1725            //add cube to schema
1726            dimension.name = getNewName(getResourceConverter().getString("schemaExplorer.newVirtualDimension.title","New Virtual Dimension"), cube.dimensions);
1727            NodeDef[] temp = cube.dimensions;
1728            cube.dimensions = new MondrianGuiDef.VirtualCubeDimension[temp.length + 1];
1729            for (int i = 0; i < temp.length; i++) {
1730                cube.dimensions[i] = (MondrianGuiDef.VirtualCubeDimension) temp[i];
1731            }
1732            cube.dimensions[cube.dimensions.length - 1] = dimension;
1733    
1734            Object [] parentPathObjs = new Object[parentIndex + 1];
1735            for (int i = 0; i <= parentIndex; i++) {
1736                parentPathObjs[i] = tpath.getPathComponent(i) ;
1737            }
1738            TreePath parentPath = new TreePath(parentPathObjs);
1739            tree.setSelectionPath(parentPath.pathByAddingChild(dimension));
1740            refreshTree(tree.getSelectionPath());
1741            setTableCellFocus(0);
1742        }
1743    
1744        private String getNewName(String preName, Object[] objs) {
1745            boolean exists = true;
1746    
1747            String newName = "", objName = "", workName = preName.trim() + " ";
1748    
1749            if (objs != null) {
1750                int objNo = objs.length;
1751                try {
1752                    Field f = objs.getClass().getComponentType().getField("name");
1753                    while (exists) {
1754                        newName = workName + objNo++;
1755                        exists = false;
1756                        for (int i = 0; i < objs.length; i++) {
1757                            objName  = (String) f.get(objs[i]);
1758                            if (newName.equals(objName)) {
1759                                exists = true;
1760                                break;
1761                            }
1762                        }
1763                    }
1764                } catch (Exception ex) {
1765                    LOGGER.error("getNewName", ex);
1766                }
1767            } else {
1768                newName = workName + 0;
1769            }
1770            return newName;
1771        }
1772        protected void addNamedSet(ActionEvent evt) {
1773            TreePath tpath = tree.getSelectionPath();
1774            int parentIndex = -1;
1775            Object path = null;
1776            if (tpath != null) {
1777                for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0; parentIndex--) {
1778                    if ((tpath.getPathComponent(parentIndex) instanceof MondrianGuiDef.Cube) ||
1779                            (tpath.getPathComponent(parentIndex) instanceof MondrianGuiDef.Schema)) {
1780                        path =  tpath.getPathComponent(parentIndex);
1781                        break;
1782                    }
1783                }
1784            }
1785    
1786            //Object path = tree.getSelectionPath().getLastPathComponent();
1787            if (! ((path instanceof MondrianGuiDef.Cube) || (path instanceof MondrianGuiDef.Schema))) {
1788                JOptionPane.showMessageDialog(this, getResourceConverter().getString("schemaExplorer.cubeOrSchemaNotSelected.alert","Cube or Schema not selected."), alert, JOptionPane.WARNING_MESSAGE);
1789                return;
1790            }
1791    
1792    
1793            MondrianGuiDef.Cube cube = null;
1794            MondrianGuiDef.Schema schema = null;
1795    
1796            if (path instanceof MondrianGuiDef.Cube) {
1797                cube = (MondrianGuiDef.Cube) path;
1798            } else {
1799                schema = (MondrianGuiDef.Schema) path;
1800            }
1801    
1802            MondrianGuiDef.NamedSet namedset = new MondrianGuiDef.NamedSet();
1803            namedset.name = "";
1804            namedset.formula = "";
1805            namedset.formulaElement = new MondrianGuiDef.Formula();
1806    
1807            //add cube to schema
1808            if (cube != null) {
1809                namedset.name = getNewName(getResourceConverter().getString("schemaExplorer.newNamedSet.title","New Named Set"), cube.namedSets);
1810    
1811                NodeDef[] temp = cube.namedSets;
1812                cube.namedSets = new MondrianGuiDef.NamedSet[temp.length + 1];
1813                for (int i = 0; i < temp.length; i++) {
1814                    cube.namedSets[i] = (MondrianGuiDef.NamedSet) temp[i];}
1815    
1816                cube.namedSets[cube.namedSets.length - 1] = namedset;
1817            } else {
1818                namedset.name = getNewName(getResourceConverter().getString("schemaExplorer.newNamedSet.title","New Named Set"), schema.namedSets);
1819                NodeDef[] temp = schema.namedSets;
1820                schema.namedSets = new MondrianGuiDef.NamedSet[temp.length + 1];
1821                for (int i = 0; i < temp.length; i++) {
1822                    schema.namedSets[i] = (MondrianGuiDef.NamedSet) temp[i];}
1823    
1824                schema.namedSets[schema.namedSets.length - 1] = namedset;
1825            }
1826    
1827            Object [] parentPathObjs = new Object[parentIndex + 1];
1828            for (int i = 0; i <= parentIndex; i++) {
1829                parentPathObjs[i] = tpath.getPathComponent(i) ;
1830            }
1831            TreePath parentPath = new TreePath(parentPathObjs);
1832            tree.setSelectionPath(parentPath.pathByAddingChild(namedset));
1833    
1834            refreshTree(tree.getSelectionPath());
1835            setTableCellFocus(0);
1836        }
1837    
1838        protected void addDimensionUsage(ActionEvent evt) {
1839            TreePath tpath = tree.getSelectionPath();
1840            int parentIndex = -1;
1841            Object path = null;
1842            if (tpath != null) {
1843                for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0; parentIndex--) {
1844                    if (tpath.getPathComponent(parentIndex) instanceof MondrianGuiDef.Cube) {
1845                        //System.out.println("==== path element "+i+" ="+tpath.getPathComponent(i).getClass().toString());
1846                        path = tpath.getPathComponent(parentIndex);
1847                        //System.out.println("Cube name ="+((MondrianGuiDef.Cube) path).name);
1848                        break;
1849                    }
1850                }
1851    
1852            }
1853            //Object path = tree.getSelectionPath().getLastPathComponent();
1854            if (!(path instanceof MondrianGuiDef.Cube)) {
1855                JOptionPane.showMessageDialog(this, getResourceConverter().getString("schemaExplorer.cubeNotSelected.alert","Cube not selected."), alert, JOptionPane.WARNING_MESSAGE);
1856                return;
1857            }
1858    
1859            MondrianGuiDef.Cube cube = (MondrianGuiDef.Cube) path;
1860    
1861            MondrianGuiDef.DimensionUsage dimension = new MondrianGuiDef.DimensionUsage();
1862            dimension.name = ""; //get unique name //"New Dimension Usage" + cube.dimensions.length;
1863    
1864            //add cube to schema
1865            dimension.name = getNewName(getResourceConverter().getString("schemaExplorer.newDimensionUsage.title","New Dimension Usage"), cube.dimensions);
1866            NodeDef[] temp = cube.dimensions;
1867            cube.dimensions = new MondrianGuiDef.CubeDimension[temp.length + 1];
1868            for (int i = 0; i < temp.length; i++) {
1869                cube.dimensions[i] = (MondrianGuiDef.CubeDimension) temp[i];}
1870    
1871            cube.dimensions[cube.dimensions.length - 1] = dimension;
1872    
1873            Object [] parentPathObjs = new Object[parentIndex + 1];
1874            for (int i = 0; i <= parentIndex; i++) {
1875                parentPathObjs[i] = tpath.getPathComponent(i) ;
1876            }
1877            TreePath parentPath = new TreePath(parentPathObjs);
1878            tree.setSelectionPath(parentPath.pathByAddingChild(dimension));
1879    
1880            refreshTree(tree.getSelectionPath());
1881            setTableCellFocus(0);
1882        }
1883    
1884        protected void addSchemaGrant(ActionEvent evt) {
1885            TreePath tpath = tree.getSelectionPath();
1886            int parentIndex = -1;
1887            Object path = null;
1888            if (tpath != null) {
1889                for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0; parentIndex--) {
1890                    if (tpath.getPathComponent(parentIndex) instanceof MondrianGuiDef.Role) {
1891                        path = tpath.getPathComponent(parentIndex);
1892                        break;
1893                    }
1894                }
1895    
1896            }
1897            //Object path = tree.getSelectionPath().getLastPathComponent();
1898            if (!(path instanceof MondrianGuiDef.Role)) {
1899                JOptionPane.showMessageDialog(this, getResourceConverter().getString("schemaExplorer.roleNotSelected.alert","Role not selected."), alert, JOptionPane.WARNING_MESSAGE);
1900                return;
1901            }
1902    
1903            MondrianGuiDef.Role role = (MondrianGuiDef.Role) path;
1904    
1905            MondrianGuiDef.SchemaGrant schemaGrant = new MondrianGuiDef.SchemaGrant();
1906            schemaGrant.access = ""; //get unique name //"New Dimension Usage" + cube.dimensions.length;
1907            schemaGrant.cubeGrants = new MondrianGuiDef.CubeGrant[0];
1908    
1909            //add cube to schema
1910            NodeDef[] temp = role.schemaGrants;
1911            role.schemaGrants = new MondrianGuiDef.SchemaGrant[temp.length + 1];
1912            for (int i = 0; i < temp.length; i++) {
1913                role.schemaGrants[i] = (MondrianGuiDef.SchemaGrant) temp[i];}
1914    
1915            role.schemaGrants[role.schemaGrants.length - 1] = schemaGrant;
1916    
1917            Object [] parentPathObjs = new Object[parentIndex + 1];
1918            for (int i = 0; i <= parentIndex; i++) {
1919                parentPathObjs[i] = tpath.getPathComponent(i) ;
1920            }
1921            TreePath parentPath = new TreePath(parentPathObjs);
1922            tree.setSelectionPath(parentPath.pathByAddingChild(schemaGrant));
1923    
1924            refreshTree(tree.getSelectionPath());
1925            setTableCellFocus(0);
1926        }
1927    
1928        protected void addCubeGrant(ActionEvent evt) {
1929            TreePath tpath = tree.getSelectionPath();
1930            int parentIndex = -1;
1931            Object path = null;
1932            if (tpath != null) {
1933                for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0; parentIndex--) {
1934                    if (tpath.getPathComponent(parentIndex) instanceof MondrianGuiDef.SchemaGrant) {
1935                        path = tpath.getPathComponent(parentIndex);
1936                        break;
1937                    }
1938                }
1939    
1940            }
1941    
1942            if (!(path instanceof MondrianGuiDef.SchemaGrant)) {
1943                JOptionPane.showMessageDialog(this, getResourceConverter().getString("schemaExplorer.schemaGrantNotSelected.alert","Schema Grant not selected."), alert, JOptionPane.WARNING_MESSAGE);
1944                return;
1945            }
1946    
1947            MondrianGuiDef.SchemaGrant schemaGrant = (MondrianGuiDef.SchemaGrant) path;
1948    
1949            MondrianGuiDef.CubeGrant cubeGrant = new MondrianGuiDef.CubeGrant();
1950            cubeGrant.access = ""; //get unique name //"New Dimension Usage" + cube.dimensions.length;
1951            cubeGrant.dimensionGrants = new MondrianGuiDef.DimensionGrant[0];
1952            cubeGrant.hierarchyGrants = new MondrianGuiDef.HierarchyGrant[0];
1953    
1954            //add cube to schema
1955            NodeDef[] temp = schemaGrant.cubeGrants;
1956            schemaGrant.cubeGrants = new MondrianGuiDef.CubeGrant[temp.length + 1];
1957            for (int i = 0; i < temp.length; i++) {
1958                schemaGrant.cubeGrants[i] = (MondrianGuiDef.CubeGrant) temp[i];}
1959    
1960            schemaGrant.cubeGrants[schemaGrant.cubeGrants.length - 1] = cubeGrant;
1961    
1962            Object [] parentPathObjs = new Object[parentIndex + 1];
1963            for (int i = 0; i <= parentIndex; i++) {
1964                parentPathObjs[i] = tpath.getPathComponent(i) ;
1965            }
1966            TreePath parentPath = new TreePath(parentPathObjs);
1967            tree.setSelectionPath(parentPath.pathByAddingChild(cubeGrant));
1968    
1969            refreshTree(tree.getSelectionPath());
1970            setTableCellFocus(0);
1971        }
1972    
1973        protected void addDimensionGrant(ActionEvent evt) {
1974            TreePath tpath = tree.getSelectionPath();
1975            int parentIndex = -1;
1976            Object path = null;
1977            if (tpath != null) {
1978                for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0; parentIndex--) {
1979                    if (tpath.getPathComponent(parentIndex) instanceof MondrianGuiDef.CubeGrant) {
1980                        //System.out.println("==== path element "+i+" ="+tpath.getPathComponent(i).getClass().toString());
1981                        path = tpath.getPathComponent(parentIndex);
1982                        //System.out.println("Cube name ="+((MondrianGuiDef.Cube) path).name);
1983                        break;
1984                    }
1985                }
1986    
1987            }
1988            //Object path = tree.getSelectionPath().getLastPathComponent();
1989            if (!(path instanceof MondrianGuiDef.CubeGrant)) {
1990                JOptionPane.showMessageDialog(this, getResourceConverter().getString("schemaExplorer.cubeGrantNotSelected.alert","Cube Grant not selected."), alert, JOptionPane.WARNING_MESSAGE);
1991                return;
1992            }
1993    
1994            MondrianGuiDef.CubeGrant cubeGrant = (MondrianGuiDef.CubeGrant) path;
1995    
1996            MondrianGuiDef.DimensionGrant dimeGrant = new MondrianGuiDef.DimensionGrant();
1997            dimeGrant.access = "";
1998    
1999            //add cube to schema
2000            NodeDef[] temp = cubeGrant.dimensionGrants;
2001            cubeGrant.dimensionGrants = new MondrianGuiDef.DimensionGrant[temp.length + 1];
2002            for (int i = 0; i < temp.length; i++) {
2003                cubeGrant.dimensionGrants[i] = (MondrianGuiDef.DimensionGrant) temp[i];}
2004    
2005            cubeGrant.dimensionGrants[cubeGrant.dimensionGrants.length - 1] = dimeGrant;
2006    
2007            Object [] parentPathObjs = new Object[parentIndex + 1];
2008            for (int i = 0; i <= parentIndex; i++) {
2009                parentPathObjs[i] = tpath.getPathComponent(i) ;
2010            }
2011            TreePath parentPath = new TreePath(parentPathObjs);
2012            tree.setSelectionPath(parentPath.pathByAddingChild(dimeGrant));
2013    
2014            refreshTree(tree.getSelectionPath());
2015            setTableCellFocus(0);
2016        }
2017    
2018        protected void addHierarchyGrant(ActionEvent evt) {
2019            TreePath tpath = tree.getSelectionPath();
2020            int parentIndex = -1;
2021            Object path = null;
2022            if (tpath != null) {
2023                for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0; parentIndex--) {
2024                    if (tpath.getPathComponent(parentIndex) instanceof MondrianGuiDef.CubeGrant) {
2025                        path = tpath.getPathComponent(parentIndex);
2026                        break;
2027                    }
2028                }
2029    
2030            }
2031    
2032            if (!(path instanceof MondrianGuiDef.CubeGrant)) {
2033                JOptionPane.showMessageDialog(this, getResourceConverter().getString("schemaExplorer.cubeGrantNotSelected.alert","Cube Grant not selected."), alert, JOptionPane.WARNING_MESSAGE);
2034                return;
2035            }
2036    
2037            MondrianGuiDef.CubeGrant cubeGrant = (MondrianGuiDef.CubeGrant) path;
2038    
2039            MondrianGuiDef.HierarchyGrant hieGrant = new MondrianGuiDef.HierarchyGrant();
2040            hieGrant.access = ""; //get unique name //"New Dimension Usage" + cube.dimensions.length;
2041            hieGrant.memberGrants = new MondrianGuiDef.MemberGrant[0];
2042    
2043            //add cube to schema
2044            NodeDef[] temp = cubeGrant.hierarchyGrants;
2045            cubeGrant.hierarchyGrants = new MondrianGuiDef.HierarchyGrant[temp.length + 1];
2046            for (int i = 0; i < temp.length; i++) {
2047                cubeGrant.hierarchyGrants[i] = (MondrianGuiDef.HierarchyGrant) temp[i];}
2048    
2049            cubeGrant.hierarchyGrants[cubeGrant.hierarchyGrants.length - 1] = hieGrant;
2050    
2051            Object [] parentPathObjs = new Object[parentIndex + 1];
2052            for (int i = 0; i <= parentIndex; i++) {
2053                parentPathObjs[i] = tpath.getPathComponent(i) ;
2054            }
2055            TreePath parentPath = new TreePath(parentPathObjs);
2056            tree.setSelectionPath(parentPath.pathByAddingChild(hieGrant));
2057    
2058            refreshTree(tree.getSelectionPath());
2059            setTableCellFocus(0);
2060        }
2061    
2062        protected void addMemberGrant(ActionEvent evt) {
2063            TreePath tpath = tree.getSelectionPath();
2064            int parentIndex = -1;
2065            Object path = null;
2066            if (tpath != null) {
2067                for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0; parentIndex--) {
2068                    if (tpath.getPathComponent(parentIndex) instanceof MondrianGuiDef.HierarchyGrant) {
2069                        path = tpath.getPathComponent(parentIndex);
2070                        break;
2071                    }
2072                }
2073    
2074            }
2075    
2076            if (!(path instanceof MondrianGuiDef.HierarchyGrant)) {
2077                JOptionPane.showMessageDialog(this, getResourceConverter().getString("schemaExplorer.hierarchyGrantNotSelected.alert","Hierarchy Grant not selected."), alert, JOptionPane.WARNING_MESSAGE);
2078                return;
2079            }
2080    
2081            MondrianGuiDef.HierarchyGrant hieGrant = (MondrianGuiDef.HierarchyGrant) path;
2082    
2083            MondrianGuiDef.MemberGrant memberGrant = new MondrianGuiDef.MemberGrant();
2084            memberGrant.access = "";
2085    
2086            //add cube to schema
2087            NodeDef[] temp = hieGrant.memberGrants;
2088            hieGrant.memberGrants = new MondrianGuiDef.MemberGrant[temp.length + 1];
2089            for (int i = 0; i < temp.length; i++) {
2090                hieGrant.memberGrants[i] = (MondrianGuiDef.MemberGrant) temp[i];}
2091    
2092            hieGrant.memberGrants[hieGrant.memberGrants.length - 1] = memberGrant;
2093    
2094            Object [] parentPathObjs = new Object[parentIndex + 1];
2095            for (int i = 0; i <= parentIndex; i++) {
2096                parentPathObjs[i] = tpath.getPathComponent(i) ;
2097            }
2098            TreePath parentPath = new TreePath(parentPathObjs);
2099            tree.setSelectionPath(parentPath.pathByAddingChild(memberGrant));
2100    
2101            refreshTree(tree.getSelectionPath());
2102            setTableCellFocus(0);
2103        }
2104    
2105    
2106        /**
2107         * @param evt
2108         */
2109        protected void addLevel(ActionEvent evt) {
2110            TreePath tpath = tree.getSelectionPath();
2111            int parentIndex = -1;
2112            Object path = null;
2113            if (tpath != null) {
2114                for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0; parentIndex--) {
2115                    if (tpath.getPathComponent(parentIndex) instanceof MondrianGuiDef.Hierarchy) {
2116                        path = tpath.getPathComponent(parentIndex);
2117                        break;
2118                    }
2119                }
2120    
2121            }
2122            if (!(path instanceof MondrianGuiDef.Hierarchy)) {
2123                JOptionPane.showMessageDialog(this, getResourceConverter().getString("schemaExplorer.hierarchyNotSelected.alert","Hierarchy not selected."), alert, JOptionPane.WARNING_MESSAGE);
2124                return;
2125            }
2126    
2127            MondrianGuiDef.Hierarchy hierarchy = (MondrianGuiDef.Hierarchy) path;
2128    
2129            MondrianGuiDef.Level level = new MondrianGuiDef.Level();
2130            level.uniqueMembers = false;
2131            level.name = "";
2132            level.properties = new MondrianGuiDef.Property[0];
2133    
2134            //add cube to schema
2135            level.name = getNewName(getResourceConverter().getString("schemaExplorer.newLevel.title","New Level"), hierarchy.levels);
2136            NodeDef[] temp = hierarchy.levels;
2137            hierarchy.levels = new MondrianGuiDef.Level[temp.length + 1];
2138            for (int i = 0; i < temp.length; i++) {
2139                hierarchy.levels[i] = (MondrianGuiDef.Level) temp[i];}
2140    
2141            hierarchy.levels[hierarchy.levels.length - 1] = level;
2142    
2143            Object [] parentPathObjs = new Object[parentIndex + 1];
2144            for (int i = 0; i <= parentIndex; i++) {
2145                parentPathObjs[i] = tpath.getPathComponent(i) ;
2146            }
2147            TreePath parentPath = new TreePath(parentPathObjs);
2148            tree.setSelectionPath(parentPath.pathByAddingChild(level));
2149    
2150            refreshTree(tree.getSelectionPath());
2151            setTableCellFocus(0);
2152        }
2153    
2154        protected void addSQL(ActionEvent evt) {
2155            TreePath tpath = tree.getSelectionPath();
2156            int parentIndex = -1;
2157            Object path = null;
2158            if (tpath != null) {
2159                for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0; parentIndex--) {
2160                    if (tpath.getPathComponent(parentIndex) instanceof MondrianGuiDef.ExpressionView) {  // parent could also be MondrianGuiDef.Expression
2161                        path = tpath.getPathComponent(parentIndex);
2162                        break;
2163                    }
2164                }
2165    
2166            }
2167            //Object path = tree.getSelectionPath().getLastPathComponent();
2168            if (!(path instanceof MondrianGuiDef.ExpressionView)) {
2169                JOptionPane.showMessageDialog(this, getResourceConverter().getString("schemaExplorer.expressionNotSelected.alert","Expression not selected."), alert, JOptionPane.WARNING_MESSAGE);
2170                return;
2171            }
2172    
2173            MondrianGuiDef.ExpressionView expview = (MondrianGuiDef.ExpressionView) path;
2174    
2175            MondrianGuiDef.SQL sql = new MondrianGuiDef.SQL();
2176            sql.dialect = "generic";
2177            //add sql to ExpressionView
2178            NodeDef[] temp = expview.expressions;
2179            expview.expressions = new MondrianGuiDef.SQL[temp.length + 1];
2180            for (int i = 0; i < temp.length; i++) {
2181                expview.expressions[i] = (MondrianGuiDef.SQL) temp[i];}
2182    
2183            expview.expressions[expview.expressions.length - 1] = sql;
2184    
2185            Object [] parentPathObjs = new Object[parentIndex + 1];
2186            for (int i = 0; i <= parentIndex; i++) {
2187                parentPathObjs[i] = tpath.getPathComponent(i) ;
2188            }
2189            TreePath parentPath = new TreePath(parentPathObjs);
2190            tree.setSelectionPath(parentPath.pathByAddingChild(sql));
2191    
2192            refreshTree(tree.getSelectionPath());
2193            setTableCellFocus(0);
2194        }
2195    
2196    
2197        protected void addKeyExp(ActionEvent evt) {
2198            TreePath tpath = tree.getSelectionPath();
2199            int parentIndex = -1;
2200            Object path = null;
2201            if (tpath != null) {
2202                for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0; parentIndex--) {
2203                    if (tpath.getPathComponent(parentIndex) instanceof MondrianGuiDef.Level) {
2204                        path = tpath.getPathComponent(parentIndex);
2205                        break;
2206                    }
2207                }
2208    
2209            }
2210            //Object path = tree.getSelectionPath().getLastPathComponent();
2211            if (!(path instanceof MondrianGuiDef.Level)) {
2212                JOptionPane.showMessageDialog(this, getResourceConverter().getString("schemaExplorer.levelNotSelected.alert","Level not selected."), alert, JOptionPane.WARNING_MESSAGE);
2213                return;
2214            }
2215    
2216            MondrianGuiDef.Level level = (MondrianGuiDef.Level) path;
2217    
2218            MondrianGuiDef.KeyExpression keyExp = new MondrianGuiDef.KeyExpression();
2219            keyExp.expressions = new MondrianGuiDef.SQL[1];    // min 1
2220            keyExp.expressions[0] = new MondrianGuiDef.SQL();
2221            keyExp.expressions[0].dialect = "generic";
2222            keyExp.expressions[0].cdata = "";
2223            level.keyExp = keyExp;
2224    
2225            Object [] parentPathObjs = new Object[parentIndex + 1];
2226            for (int i = 0; i <= parentIndex; i++) {
2227                parentPathObjs[i] = tpath.getPathComponent(i) ;
2228            }
2229            TreePath parentPath = new TreePath(parentPathObjs);
2230            tree.setSelectionPath(parentPath.pathByAddingChild(keyExp));
2231    
2232            refreshTree(tree.getSelectionPath());
2233        }
2234    
2235        protected void addNameExp(ActionEvent evt) {
2236            TreePath tpath = tree.getSelectionPath();
2237            int parentIndex = -1;
2238            Object path = null;
2239            if (tpath != null) {
2240                for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0; parentIndex--) {
2241                    if (tpath.getPathComponent(parentIndex) instanceof MondrianGuiDef.Level) {
2242                        path = tpath.getPathComponent(parentIndex);
2243                        break;
2244                    }
2245                }
2246    
2247            }
2248            if (!(path instanceof MondrianGuiDef.Level)) {
2249                JOptionPane.showMessageDialog(this, getResourceConverter().getString("schemaExplorer.levelNotSelected.alert","Level not selected."), alert, JOptionPane.WARNING_MESSAGE);
2250                return;
2251            }
2252    
2253            MondrianGuiDef.Level level = (MondrianGuiDef.Level) path;
2254    
2255            MondrianGuiDef.NameExpression nameExp = new MondrianGuiDef.NameExpression();
2256            nameExp.expressions = new MondrianGuiDef.SQL[1];    // min 1
2257            nameExp.expressions[0] = new MondrianGuiDef.SQL();
2258            nameExp.expressions[0].dialect = "generic";
2259            nameExp.expressions[0].cdata = "";
2260            level.nameExp = nameExp;
2261    
2262            Object [] parentPathObjs = new Object[parentIndex + 1];
2263            for (int i = 0; i <= parentIndex; i++) {
2264                parentPathObjs[i] = tpath.getPathComponent(i) ;
2265            }
2266            TreePath parentPath = new TreePath(parentPathObjs);
2267            tree.setSelectionPath(parentPath.pathByAddingChild(nameExp));
2268    
2269            refreshTree(tree.getSelectionPath());
2270        }
2271    
2272        protected void addOrdinalExp(ActionEvent evt) {
2273            TreePath tpath = tree.getSelectionPath();
2274            int parentIndex = -1;
2275            Object path = null;
2276            if (tpath != null) {
2277                for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0; parentIndex--) {
2278                    if (tpath.getPathComponent(parentIndex) instanceof MondrianGuiDef.Level) {
2279                        path = tpath.getPathComponent(parentIndex);
2280                        break;
2281                    }
2282                }
2283    
2284            }
2285            if (!(path instanceof MondrianGuiDef.Level)) {
2286                JOptionPane.showMessageDialog(this, getResourceConverter().getString("schemaExplorer.levelNotSelected.alert","Level not selected."), alert, JOptionPane.WARNING_MESSAGE);
2287                return;
2288            }
2289    
2290            MondrianGuiDef.Level level = (MondrianGuiDef.Level) path;
2291    
2292            MondrianGuiDef.OrdinalExpression ordinalExp = new MondrianGuiDef.OrdinalExpression();
2293            ordinalExp.expressions = new MondrianGuiDef.SQL[1];    // min 1
2294            ordinalExp.expressions[0] = new MondrianGuiDef.SQL();
2295            ordinalExp.expressions[0].dialect = "generic";
2296            ordinalExp.expressions[0].cdata = "";
2297            level.ordinalExp = ordinalExp;
2298    
2299            Object [] parentPathObjs = new Object[parentIndex + 1];
2300            for (int i = 0; i <= parentIndex; i++) {
2301                parentPathObjs[i] = tpath.getPathComponent(i) ;
2302            }
2303            TreePath parentPath = new TreePath(parentPathObjs);
2304            tree.setSelectionPath(parentPath.pathByAddingChild(ordinalExp));
2305    
2306            refreshTree(tree.getSelectionPath());
2307        }
2308    
2309        protected void addParentExp(ActionEvent evt) {
2310            TreePath tpath = tree.getSelectionPath();
2311            int parentIndex = -1;
2312            Object path = null;
2313            if (tpath != null) {
2314                for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0; parentIndex--) {
2315                    if (tpath.getPathComponent(parentIndex) instanceof MondrianGuiDef.Level) {
2316                        path = tpath.getPathComponent(parentIndex);
2317                        break;
2318                    }
2319                }
2320    
2321            }
2322            if (!(path instanceof MondrianGuiDef.Level)) {
2323                JOptionPane.showMessageDialog(this, getResourceConverter().getString("schemaExplorer.levelNotSelected.alert","Level not selected."), alert, JOptionPane.WARNING_MESSAGE);
2324                return;
2325            }
2326    
2327            MondrianGuiDef.Level level = (MondrianGuiDef.Level) path;
2328    
2329            MondrianGuiDef.ParentExpression parentExp = new MondrianGuiDef.ParentExpression();
2330            parentExp.expressions = new MondrianGuiDef.SQL[1];    // min 1
2331            parentExp.expressions[0] = new MondrianGuiDef.SQL();
2332            parentExp.expressions[0].dialect = "generic";
2333            parentExp.expressions[0].cdata = "";
2334            level.parentExp = parentExp;
2335    
2336            Object [] parentPathObjs = new Object[parentIndex + 1];
2337            for (int i = 0; i <= parentIndex; i++) {
2338                parentPathObjs[i] = tpath.getPathComponent(i) ;
2339            }
2340            TreePath parentPath = new TreePath(parentPathObjs);
2341            tree.setSelectionPath(parentPath.pathByAddingChild(parentExp));
2342    
2343            refreshTree(tree.getSelectionPath());
2344        }
2345    
2346        protected void addMeasureExp(ActionEvent evt) {
2347            TreePath tpath = tree.getSelectionPath();
2348            int parentIndex = -1;
2349            Object path = null;
2350            if (tpath != null) {
2351                for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0; parentIndex--) {
2352                    if (tpath.getPathComponent(parentIndex) instanceof MondrianGuiDef.Measure) {
2353                        path = tpath.getPathComponent(parentIndex);
2354                        break;
2355                    }
2356                }
2357    
2358            }
2359            if (!(path instanceof MondrianGuiDef.Measure)) {
2360                JOptionPane.showMessageDialog(this, getResourceConverter().getString("schemaExplorer.measureNotSelected.alert","Measure not selected."), alert, JOptionPane.WARNING_MESSAGE);
2361                return;
2362            }
2363    
2364            MondrianGuiDef.Measure measure = (MondrianGuiDef.Measure) path;
2365    
2366            MondrianGuiDef.MeasureExpression measureExp = new MondrianGuiDef.MeasureExpression();
2367            measureExp.expressions = new MondrianGuiDef.SQL[1];    // min 1
2368            measureExp.expressions[0] = new MondrianGuiDef.SQL();
2369            measureExp.expressions[0].dialect = "generic";
2370            measureExp.expressions[0].cdata = "";
2371            measure.measureExp = measureExp;
2372    
2373            Object [] parentPathObjs = new Object[parentIndex + 1];
2374            for (int i = 0; i <= parentIndex; i++) {
2375                parentPathObjs[i] = tpath.getPathComponent(i) ;
2376            }
2377            TreePath parentPath = new TreePath(parentPathObjs);
2378            tree.setSelectionPath(parentPath.pathByAddingChild(measureExp));
2379    
2380            refreshTree(tree.getSelectionPath());
2381        }
2382    
2383        protected void addRelation(ActionEvent evt) {
2384            TreePath tpath = tree.getSelectionPath();
2385            int parentIndex = -1;
2386            Object path = null;
2387            if (tpath != null) {
2388                for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0; parentIndex--) {
2389                    if (tpath.getPathComponent(parentIndex) instanceof MondrianGuiDef.Hierarchy) {
2390                        path = tpath.getPathComponent(parentIndex);
2391                        break;
2392                    }
2393                }
2394    
2395            }
2396    
2397            if (!(path instanceof MondrianGuiDef.Hierarchy)) {
2398                JOptionPane.showMessageDialog(this, getResourceConverter().getString("schemaExplorer.hierarchyNotSelected.alert","Hierarchy not selected."), alert, JOptionPane.WARNING_MESSAGE);
2399                return;
2400            }
2401    
2402            MondrianGuiDef.Hierarchy hierarchy = (MondrianGuiDef.Hierarchy) path;
2403    
2404            MondrianGuiDef.RelationOrJoin relation = new MondrianGuiDef.Table("", "Table", "");
2405    
2406            //add relation to hierarchy
2407            hierarchy.relation = relation;
2408    
2409            Object [] parentPathObjs = new Object[parentIndex + 1];
2410            for (int i = 0; i <= parentIndex; i++) {
2411                parentPathObjs[i] = tpath.getPathComponent(i) ;
2412            }
2413            TreePath parentPath = new TreePath(parentPathObjs);
2414            tree.setSelectionPath(parentPath.pathByAddingChild(relation));
2415    
2416            refreshTree(tree.getSelectionPath());
2417            setTableCellFocus(0);
2418        }
2419    
2420        protected void addHierarchy(ActionEvent evt) {
2421            TreePath tpath = tree.getSelectionPath();
2422            int parentIndex = -1;
2423            Object path = null;
2424            if (tpath != null) {
2425                for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0; parentIndex--) {
2426                    if (tpath.getPathComponent(parentIndex) instanceof MondrianGuiDef.Dimension) {
2427                        path = tpath.getPathComponent(parentIndex);
2428                        break;
2429                    }
2430                }
2431    
2432            }
2433    
2434            if (!(path instanceof MondrianGuiDef.Dimension)) {
2435                JOptionPane.showMessageDialog(this, getResourceConverter().getString("schemaExplorer.dimensionNotSelected.alert","Dimension not selected."), alert, JOptionPane.WARNING_MESSAGE);
2436                return;
2437            }
2438    
2439            MondrianGuiDef.Dimension dimension = (MondrianGuiDef.Dimension) path;
2440    
2441            MondrianGuiDef.Hierarchy hierarchy = new MondrianGuiDef.Hierarchy();
2442    
2443            hierarchy.name = "";
2444            hierarchy.hasAll = Boolean.TRUE; //new Boolean(false);
2445            hierarchy.levels = new MondrianGuiDef.Level[0];
2446            hierarchy.memberReaderParameters = new MondrianGuiDef.MemberReaderParameter[0];
2447            hierarchy.relation = new MondrianGuiDef.Table("", "Table", "");
2448    
2449            hierarchy.name = getNewName(getResourceConverter().getString("schemaExplorer.newHierarchy.title","New Hierarchy"), dimension.hierarchies);
2450            NodeDef[] temp = dimension.hierarchies;
2451            dimension.hierarchies = new MondrianGuiDef.Hierarchy[temp.length + 1];
2452            for (int i = 0; i < temp.length; i++) {
2453                dimension.hierarchies[i] = (MondrianGuiDef.Hierarchy) temp[i];}
2454    
2455            dimension.hierarchies[dimension.hierarchies.length - 1] = hierarchy;
2456    
2457            Object [] parentPathObjs = new Object[parentIndex + 1];
2458            for (int i = 0; i <= parentIndex; i++) {
2459                parentPathObjs[i] = tpath.getPathComponent(i) ;
2460            }
2461            TreePath parentPath = new TreePath(parentPathObjs);
2462            tree.setSelectionPath(parentPath.pathByAddingChild(hierarchy));
2463            refreshTree(tree.getSelectionPath());
2464            setTableCellFocus(0);
2465        }
2466    
2467    
2468        /**
2469         * @param evt
2470         */
2471        protected void addProperty(ActionEvent evt) {
2472            TreePath tpath = tree.getSelectionPath();
2473            int parentIndex = -1;
2474            Object path = null;
2475            if (tpath != null) {
2476                for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0; parentIndex--) {
2477                    if (tpath.getPathComponent(parentIndex) instanceof MondrianGuiDef.Level) {
2478                        path = tpath.getPathComponent(parentIndex);
2479                        break;
2480                    }
2481                }
2482    
2483            }
2484    
2485            if (!(path instanceof MondrianGuiDef.Level)) {
2486                JOptionPane.showMessageDialog(this, getResourceConverter().getString("schemaExplorer.levelNotSelected.alert","Level not selected."), alert, JOptionPane.WARNING_MESSAGE);
2487                return;
2488            }
2489    
2490    
2491            MondrianGuiDef.Level level = (MondrianGuiDef.Level) path;
2492    
2493            MondrianGuiDef.Property property = new MondrianGuiDef.Property();
2494            property.name = "";
2495    
2496            //add cube to schema
2497            if (level.properties == null) {
2498                level.properties = new MondrianGuiDef.Property[0];
2499            }
2500            property.name = getNewName(getResourceConverter().getString("schemaExplorer.newProperty.title","New Property"), level.properties);
2501            NodeDef[] temp = level.properties;
2502            level.properties = new MondrianGuiDef.Property[temp.length + 1];
2503            for (int i = 0; i < temp.length; i++) {
2504                level.properties[i] = (MondrianGuiDef.Property) temp[i];
2505            }
2506    
2507            level.properties[level.properties.length - 1] = property;
2508    
2509            Object [] parentPathObjs = new Object[parentIndex + 1];
2510            for (int i = 0; i <= parentIndex; i++) {
2511                parentPathObjs[i] = tpath.getPathComponent(i) ;
2512            }
2513            TreePath parentPath = new TreePath(parentPathObjs);
2514            tree.setSelectionPath(parentPath.pathByAddingChild(property));
2515    
2516            refreshTree(tree.getSelectionPath());
2517            setTableCellFocus(0);
2518        }
2519    
2520        /**
2521         * @param evt
2522         */
2523        protected void addClosure(ActionEvent evt) {
2524            TreePath tpath = tree.getSelectionPath();
2525            int parentIndex = -1;
2526            Object path = null;
2527            if (tpath != null) {
2528                for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0; parentIndex--) {
2529                    if (tpath.getPathComponent(parentIndex) instanceof MondrianGuiDef.Level) {
2530                        path = tpath.getPathComponent(parentIndex);
2531                        break;
2532                    }
2533                }
2534    
2535            }
2536    
2537            if (!(path instanceof MondrianGuiDef.Level)) {
2538                JOptionPane.showMessageDialog(this, getResourceConverter().getString("schemaExplorer.levelNotSelected.alert","Level not selected."), alert, JOptionPane.WARNING_MESSAGE);
2539                return;
2540            }
2541    
2542            MondrianGuiDef.Level level = (MondrianGuiDef.Level) path;
2543            MondrianGuiDef.Closure closure = new MondrianGuiDef.Closure();
2544            closure.parentColumn = "";
2545            closure.childColumn = "";
2546            closure.table = new MondrianGuiDef.Table("", "Table", "");
2547            if (level.closure == null) {
2548                level.closure = closure;
2549            }
2550    
2551            Object [] parentPathObjs = new Object[parentIndex + 1];
2552            for (int i = 0; i <= parentIndex; i++) {
2553                parentPathObjs[i] = tpath.getPathComponent(i) ;
2554            }
2555            TreePath parentPath = new TreePath(parentPathObjs);
2556            tree.setSelectionPath(parentPath.pathByAddingChild(closure));
2557    
2558            refreshTree(tree.getSelectionPath());
2559            setTableCellFocus(0);
2560        }
2561    
2562        public MondrianGuiDef.Schema getSchema() {
2563            return this.schema;
2564        }
2565    
2566        /**
2567         * returns the schema file
2568         * @return File
2569         */
2570        public File getSchemaFile() {
2571            return this.schemaFile;
2572        }
2573    
2574        /**
2575         * sets the schema file
2576         * @param f
2577         */
2578        public void setSchemaFile(File f) {
2579            this.schemaFile = f;
2580        }
2581    
2582        public Object lastSelected;
2583    
2584        /**
2585         * Called whenever the value of the selection changes.
2586         *
2587         * @param e the event that characterizes the change.
2588         */
2589        public void valueChanged(TreeSelectionEvent e) {
2590            if (propertyTable.isEditing() && (lastSelected != e.getPath().getLastPathComponent())) {
2591                SchemaPropertyCellEditor sce = (SchemaPropertyCellEditor) propertyTable.getCellEditor();
2592                if (sce != null) {
2593                    TreeSelectionEvent e2 = e;
2594                    sce.stopCellEditing();
2595                    e = e2;
2596                }
2597    
2598            }
2599            lastSelected = e.getPath().getLastPathComponent();
2600    
2601            String selectedFactTable = null;
2602            String selectedFactTableSchema = null;
2603    
2604            for (int i = e.getPath().getPathCount() - 1; i >= 0; i--) {
2605                Object comp = e.getPath().getPathComponent(i);
2606                if (comp instanceof MondrianGuiDef.Cube &&  ((MondrianGuiDef.Cube) comp).fact != null) {
2607                    selectedFactTable = ((MondrianGuiDef.Table) ((MondrianGuiDef.Cube) comp).fact).name;
2608                    selectedFactTableSchema = ((MondrianGuiDef.Table) ((MondrianGuiDef.Cube) comp).fact).schema;
2609                }
2610            }
2611            TreePath tpath = e.getPath();
2612            Object o = tpath.getLastPathComponent();
2613            Object po = null;
2614            // look for parent information
2615            TreePath parentTpath = tpath.getParentPath();
2616            String parentName = "";
2617            String elementName = "";
2618            if (parentTpath != null) {
2619                po = parentTpath.getLastPathComponent();
2620                Class parentClassName = po.getClass();
2621                try {
2622                    Field nameField = po.getClass().getField("name");
2623                    elementName = (String) nameField.get(po);
2624                    if (elementName == null) {
2625                        elementName = "";
2626                    } else {
2627                        elementName = "'" + elementName + "'";
2628                    }
2629                } catch (Exception ex) {
2630                    elementName = "";
2631                }
2632                int pos = parentClassName.toString().lastIndexOf("$");
2633                if (pos > 0) {
2634                    parentName = parentClassName.toString().substring(pos + 1);
2635                }
2636            }
2637    
2638            // Begin : For xml edit mode display
2639            StringWriter sxml = new StringWriter();
2640            org.eigenbase.xom.XMLOutput pxml = new org.eigenbase.xom.XMLOutput(sxml);
2641            pxml.setIndentString("        ");
2642            // End : For xml edit mode display
2643    
2644            String[] pNames = DEF_DEFAULT;
2645    
2646            validStatusLabel.setText(renderer.invalid(tree, e.getPath(), o));
2647            validStatusLabel2.setText(validStatusLabel.getText());
2648    
2649            if (o instanceof MondrianGuiDef.Column) {
2650                pNames = DEF_COLUMN;
2651                targetLabel.setText(getResourceConverter().getString("common.column.title",LBL_COLUMN));
2652            } else if (o instanceof MondrianGuiDef.Cube) {
2653                pNames = DEF_CUBE;
2654                targetLabel.setText(getResourceConverter().getString("common.cube.title",LBL_CUBE));
2655                ((MondrianGuiDef.Cube) o).displayXML(pxml, 0);
2656            } else if (o instanceof MondrianGuiDef.Dimension) {
2657                pNames = DEF_DIMENSION;
2658                if (po instanceof MondrianGuiDef.Schema) {
2659                    targetLabel.setText(getResourceConverter().getString("common.sharedDimension.title",
2660                            "Shared Dimension"));
2661                } else {
2662                    targetLabel.setText(getResourceConverter().getFormattedString("schemaExplorer.dimensionElementParent.title",
2663                            "Dimension for {0} {1}",
2664                                new String[] { elementName, parentName }));
2665                }
2666                ((MondrianGuiDef.Dimension) o).displayXML(pxml, 0);
2667            } else if (o instanceof MondrianGuiDef.DimensionUsage) {
2668                pNames = DEF_DIMENSION_USAGE;
2669                targetLabel.setText(getResourceConverter().getFormattedString("schemaExplorer.dimensionUsageForElement.title",
2670                        "Dimension Usage for {0} {1}",
2671                            new String[] { elementName, parentName }));
2672                //targetLabel.setText(LBL_DIMENSION_USAGE + " for " + elementName + " " +
2673                //        parentName);
2674                ((MondrianGuiDef.DimensionUsage) o).displayXML(pxml, 0);
2675            } else if (o instanceof MondrianGuiDef.KeyExpression) {
2676                pNames = DEF_DEFAULT;
2677                targetLabel.setText(getResourceConverter().getString("common.keyExpression.title",LBL_KEY_EXPRESSION));
2678                ((MondrianGuiDef.ExpressionView) o).displayXML(pxml, 0);
2679            } else if (o instanceof MondrianGuiDef.NameExpression) {
2680                pNames = DEF_DEFAULT;
2681                targetLabel.setText(getResourceConverter().getString("common.nameExpression.title",LBL_NAME_EXPRESSION));
2682                ((MondrianGuiDef.ExpressionView) o).displayXML(pxml, 0);
2683            } else if (o instanceof MondrianGuiDef.OrdinalExpression) {
2684                pNames = DEF_DEFAULT;
2685                targetLabel.setText(getResourceConverter().getString("common.ordinalExpression.title",LBL_ORDINAL_EXPRESSION));
2686                ((MondrianGuiDef.ExpressionView) o).displayXML(pxml, 0);
2687            } else if (o instanceof MondrianGuiDef.ParentExpression) {
2688                pNames = DEF_DEFAULT;
2689                targetLabel.setText(getResourceConverter().getString("common.parentExpression.title",LBL_PARENT_EXPRESSION));
2690                ((MondrianGuiDef.ExpressionView) o).displayXML(pxml, 0);
2691            } else if (o instanceof MondrianGuiDef.ExpressionView) {
2692                pNames = DEF_EXPRESSION_VIEW;
2693                targetLabel.setText(getResourceConverter().getString("common.expressionView.title",LBL_EXPRESSION_VIEW));
2694                ((MondrianGuiDef.ExpressionView) o).displayXML(pxml, 0);
2695            } else if (o instanceof MondrianGuiDef.MeasureExpression) {
2696                pNames = DEF_DEFAULT;
2697                targetLabel.setText(getResourceConverter().getString("common.measureExpression.title",LBL_MEASURE_EXPRESSION));
2698                ((MondrianGuiDef.ExpressionView) o).displayXML(pxml, 0);
2699            } else if (o instanceof MondrianGuiDef.Hierarchy) {
2700                pNames = DEF_HIERARCHY;
2701                targetLabel.setText(getResourceConverter().getFormattedString("schemaExplorer.hierarchyElementParent.title",
2702                        "Hierarchy for {0} {1}",
2703                            new String[] { elementName, parentName }));
2704                ((MondrianGuiDef.Hierarchy) o).displayXML(pxml, 0);
2705            } else if (o instanceof MondrianGuiDef.Join) {
2706                pNames = DEF_JOIN;
2707                if (parentName.equalsIgnoreCase("Join")) {
2708                    Object parentJoin = parentTpath.getLastPathComponent();
2709                    int indexOfChild = tree.getModel().getIndexOfChild(parentJoin, o);
2710                    switch (indexOfChild) {
2711                    case 0:
2712                        targetLabel.setText(getResourceConverter().getString("common.leftJoin.title","Left : " + LBL_JOIN));
2713                        break;
2714                    case 1:
2715                        targetLabel.setText(getResourceConverter().getString("common.rightJoin.title","Right : " + LBL_JOIN));
2716                    }
2717                } else {
2718                    targetLabel.setText(getResourceConverter().getFormattedString("schemaExplorer.generalJoinForElement.title",
2719                            "Join for {0} {1}",
2720                                new String[] { elementName, parentName }));
2721                }
2722                ((MondrianGuiDef.Join) o).displayXML(pxml, 0);
2723            } else if (o instanceof MondrianGuiDef.Level) {
2724                pNames = DEF_LEVEL;
2725                targetLabel.setText(getResourceConverter().getFormattedString("schemaExplorer.levelForElement.title",
2726                        "Level for {0} {1}",
2727                            new String[] { elementName, parentName }));
2728                ((MondrianGuiDef.Level) o).displayXML(pxml, 0);
2729            } else if (o instanceof MondrianGuiDef.Measure) {
2730                pNames = DEF_MEASURE;
2731                targetLabel.setText(getResourceConverter().getFormattedString("schemaExplorer.measureForElement.title",
2732                        "Measure for {0} {1}",
2733                            new String[] { elementName, parentName }));
2734                ((MondrianGuiDef.Measure) o).displayXML(pxml, 0);
2735            } else if (o instanceof MondrianGuiDef.CalculatedMember) {
2736                pNames = DEF_CALCULATED_MEMBER;
2737                targetLabel.setText(getResourceConverter().getFormattedString("schemaExplorer.calculatedMemberForElement.title",
2738                        "Calculated Member for {0} {1}",
2739                            new String[] { elementName, parentName }));
2740                ((MondrianGuiDef.CalculatedMember) o).displayXML(pxml, 0);
2741            } else if (o instanceof MondrianGuiDef.CalculatedMemberProperty) {
2742                pNames = DEF_CALCULATED_MEMBER_PROPERTY;
2743                targetLabel.setText(getResourceConverter().getString("common.calculatedMemberProperty.title",LBL_CALCULATED_MEMBER_PROPERTY));
2744            } else if (o instanceof MondrianGuiDef.NamedSet) {
2745                pNames = DEF_NAMED_SET;
2746                targetLabel.setText(getResourceConverter().getFormattedString("schemaExplorer.namedSetForElement.title",
2747                        "Named Set for {0} {1}",
2748                            new String[] { elementName, parentName }));
2749                ((MondrianGuiDef.NamedSet) o).displayXML(pxml, 0);
2750            } else if (o instanceof MondrianGuiDef.UserDefinedFunction) {
2751                pNames = DEF_USER_DEFINED_FUNCTION;
2752                targetLabel.setText(getResourceConverter().getFormattedString("schemaExplorer.userDefinedFunctionForElement.title",
2753                        "User Defined Function for {0} {1}",
2754                            new String[] { elementName, parentName }));
2755                ((MondrianGuiDef.UserDefinedFunction) o).displayXML(pxml, 0);
2756            } else if (o instanceof MondrianGuiDef.MemberReaderParameter) {
2757                pNames = DEF_PARAMETER;
2758                targetLabel.setText(getResourceConverter().getString("common.parameter.title",LBL_PARAMETER));
2759            } else if (o instanceof MondrianGuiDef.Property) {
2760                pNames = DEF_PROPERTY;
2761                targetLabel.setText(getResourceConverter().getString("common.property.title",LBL_PROPERTY));
2762                ((MondrianGuiDef.Property) o).displayXML(pxml, 0);
2763            } else if (o instanceof MondrianGuiDef.Closure) {
2764                pNames = DEF_CLOSURE;
2765                targetLabel.setText(getResourceConverter().getString("common.closure.title",LBL_CLOSURE));
2766                ((MondrianGuiDef.Closure) o).displayXML(pxml, 0);
2767            } else if (o instanceof MondrianGuiDef.Schema) {
2768                pNames = DEF_SCHEMA;
2769                targetLabel.setText(getResourceConverter().getString("common.schema.title",LBL_SCHEMA));
2770                ((MondrianGuiDef.Schema) o).displayXML(pxml, 0);
2771            } else if (o instanceof MondrianGuiDef.SQL) {
2772                pNames = DEF_SQL;
2773                targetLabel.setText(getResourceConverter().getString("common.sql.title",LBL_SQL));
2774                ((MondrianGuiDef.SQL) o).displayXML(pxml, 0);
2775            } else if (o instanceof MondrianGuiDef.Table) {
2776                pNames = DEF_TABLE;
2777                targetLabel.setText(getResourceConverter().getFormattedString("schemaExplorer.tableForElement.title",
2778                        "Table for {0} {1}",
2779                            new String[] { elementName, parentName }));
2780                ((MondrianGuiDef.Table) o).displayXML(pxml, 0);
2781            } else if (o instanceof MondrianGuiDef.AggName) {
2782                pNames = DEF_AGG_NAME;
2783                targetLabel.setText(getResourceConverter().getString("common.aggName.title",LBL_AGG_NAME));
2784                ((MondrianGuiDef.AggName) o).displayXML(pxml, 0);
2785            } else if (o instanceof MondrianGuiDef.AggIgnoreColumn) {
2786                pNames = DEF_AGG_IGNORE_COLUMN;
2787                targetLabel.setText(getResourceConverter().getString("common.aggIgnoreColumn.title",LBL_AGG_IGNORE_COLUMN));
2788                ((MondrianGuiDef.AggIgnoreColumn) o).displayXML(pxml, 0);
2789            } else if (o instanceof MondrianGuiDef.AggForeignKey) {
2790                pNames = DEF_AGG_FOREIGN_KEY;
2791                targetLabel.setText(getResourceConverter().getString("common.aggForeignKey.title",LBL_AGG_FOREIGN_KEY));
2792                ((MondrianGuiDef.AggForeignKey) o).displayXML(pxml, 0);
2793            } else if (o instanceof MondrianGuiDef.AggMeasure) {
2794                pNames = DEF_AGG_MEASURE;
2795                targetLabel.setText(getResourceConverter().getString("common.aggMeasure.title",LBL_AGG_MEASURE));
2796                ((MondrianGuiDef.AggMeasure) o).displayXML(pxml, 0);
2797            } else if (o instanceof MondrianGuiDef.AggLevel) {
2798                pNames = DEF_AGG_LEVEL;
2799                targetLabel.setText(getResourceConverter().getString("common.aggLevel.title",LBL_AGG_LEVEL));
2800                ((MondrianGuiDef.AggLevel) o).displayXML(pxml, 0);
2801            } else if (o instanceof MondrianGuiDef.AggExclude) {
2802                pNames = DEF_AGG_EXCLUDE;
2803                targetLabel.setText(getResourceConverter().getString("common.aggExclude.title",LBL_AGG_EXCLUDE));
2804                ((MondrianGuiDef.AggExclude) o).displayXML(pxml, 0);
2805            } else if (o instanceof MondrianGuiDef.AggPattern) {
2806                pNames = DEF_AGG_PATTERN;
2807                targetLabel.setText(getResourceConverter().getString("common.aggPattern.title",LBL_AGG_PATTERN));
2808                ((MondrianGuiDef.AggPattern) o).displayXML(pxml, 0);
2809            } else if (o instanceof MondrianGuiDef.AggFactCount) {
2810                pNames = DEF_AGG_FACT_COUNT;
2811                targetLabel.setText(getResourceConverter().getString("common.aggFactCount.title",LBL_AGG_FACT_COUNT));
2812                ((MondrianGuiDef.AggFactCount) o).displayXML(pxml, 0);
2813    
2814            } else if (o instanceof MondrianGuiDef.View) {
2815                pNames = DEF_VIEW;
2816                targetLabel.setText(getResourceConverter().getString("common.view.title",LBL_VIEW));
2817    
2818            } else if (o instanceof MondrianGuiDef.Role) {
2819                pNames = DEF_ROLE;
2820                targetLabel.setText(getResourceConverter().getFormattedString("schemaExplorer.roleElementParent.title",
2821                        "Role for {0} {1}",
2822                            new String[] { elementName, parentName }));
2823                ((MondrianGuiDef.Role) o).displayXML(pxml, 0);
2824            } else if (o instanceof MondrianGuiDef.SchemaGrant) {
2825                pNames = DEF_SCHEMA_GRANT;
2826                targetLabel.setText(getResourceConverter().getString("common.schemaGrant.title",LBL_SCHEMA_GRANT));
2827                ((MondrianGuiDef.SchemaGrant) o).displayXML(pxml, 0);
2828            } else if (o instanceof MondrianGuiDef.CubeGrant) {
2829                pNames = DEF_CUBE_GRANT;
2830                targetLabel.setText(getResourceConverter().getString("common.cubeGrant.title",LBL_CUBE_GRANT));
2831                ((MondrianGuiDef.CubeGrant) o).displayXML(pxml, 0);
2832            } else if (o instanceof MondrianGuiDef.DimensionGrant) {
2833                pNames = DEF_DIMENSION_GRANT;
2834                targetLabel.setText(getResourceConverter().getString("common.dimensionGrant.title",LBL_DIMENSION_GRANT));
2835                ((MondrianGuiDef.DimensionGrant) o).displayXML(pxml, 0);
2836            } else if (o instanceof MondrianGuiDef.HierarchyGrant) {
2837                pNames = DEF_HIERARCHY_GRANT;
2838                targetLabel.setText(getResourceConverter().getString("common.hierarchyGrant.title",LBL_HIERARCHY_GRANT));
2839                ((MondrianGuiDef.HierarchyGrant) o).displayXML(pxml, 0);
2840            } else if (o instanceof MondrianGuiDef.MemberGrant) {
2841                pNames = DEF_MEMBER_GRANT;
2842                targetLabel.setText(getResourceConverter().getString("common.memberGrant.title",LBL_MEMBER_GRANT));
2843                ((MondrianGuiDef.MemberGrant) o).displayXML(pxml, 0);
2844    
2845            } else if (o instanceof MondrianGuiDef.VirtualCube) {
2846                pNames = DEF_VIRTUAL_CUBE;
2847                targetLabel.setText(getResourceConverter().getFormattedString("schemaExplorer.virtualCubeElementParent.title",
2848                        "Virtual Cube for {0} {1}",
2849                            new String[] { elementName, parentName }));
2850                ((MondrianGuiDef.VirtualCube) o).displayXML(pxml, 0);
2851            } else if (o instanceof MondrianGuiDef.VirtualCubeDimension) {
2852                pNames = DEF_VIRTUAL_CUBE_DIMENSION;
2853                targetLabel.setText(getResourceConverter().getFormattedString("schemaExplorer.virtualCubeDimensionElementParent.title",
2854                        "Virtual Cube Dimension for {0} {1}",
2855                            new String[] { elementName, parentName }));
2856                ((MondrianGuiDef.VirtualCubeDimension) o).displayXML(pxml, 0);
2857            } else if (o instanceof MondrianGuiDef.VirtualCubeMeasure) {
2858                pNames = DEF_VIRTUAL_CUBE_MEASURE;
2859                targetLabel.setText(getResourceConverter().getString("common.virtualCubeMeasure.title",LBL_VIRTUAL_CUBE_MEASURE));
2860                ((MondrianGuiDef.VirtualCubeMeasure) o).displayXML(pxml, 0);
2861            } else {
2862                targetLabel.setText(getResourceConverter().getString("common.unknownType.title",LBL_UNKNOWN_TYPE));
2863            }
2864    
2865            //jEditorPaneXML.setText(sxml.toString());  // removed because it caused the scrollbar for new element selected to reach at the end.
2866            try {
2867                jEditorPaneXML.read(new StringReader(sxml.toString()),null);
2868            } catch (Exception ex) {
2869                //
2870            }
2871            targetLabel2.setText(targetLabel.getText());
2872    
2873            PropertyTableModel ptm = new PropertyTableModel(workbench, o, pNames);
2874    
2875            ptm.setFactTable(selectedFactTable);
2876            ptm.setFactTableSchema(selectedFactTableSchema);
2877    
2878            // generate a list of pre-existing names of siblings in parent component for checking unique names
2879            Object parent = null;
2880            for (int i = e.getPath().getPathCount() - 1 - 1; i >= 0; i--) {
2881                parent = e.getPath().getPathComponent(i);   // get parent path
2882                break;
2883            }
2884            if (parent != null) {
2885                //System.out.println("parent type="+parent.getClass());
2886                Field[] fs = parent.getClass().getFields();
2887                ArrayList<Object> names = new ArrayList<Object>();
2888                for (int i = 0; i < fs.length; i++) {
2889                    if (fs[i].getType().isArray() && (fs[i].getType().getComponentType().isInstance(o))) {
2890                        // selected schema object is an instance of parent's field (an array).
2891                        //System.out.println("parent Field type="+fs[i].getType().getComponentType());
2892                        //System.out.println("parent Field name="+fs[i].getName());
2893                        try {
2894                            Field fname = fs[i].getType().getComponentType().getField("name"); // name field of array's objects.
2895                            Object objs = fs[i].get(parent); // get the parent's array of child objects
2896                            for (int j = 0; j < Array.getLength(objs); j++) {
2897                                Object child = Array.get(objs, j);
2898                                Object vname = fname.get(child);
2899                                names.add(vname);
2900                            }
2901                            ptm.setNames(names);
2902                        } catch (Exception ex) {
2903                            //name field dosen't exist, skip parent object.
2904                        }
2905                        break;
2906                    }
2907                }
2908            }
2909    
2910            propertyTable.setModel(ptm);
2911            propertyTable.getColumnModel().getColumn(0).setMaxWidth(150);
2912            propertyTable.getColumnModel().getColumn(0).setMinWidth(150);
2913            //propertyTable.getColumnModel().getColumn(0).setCellRenderer(new SchemaPropertyCellRenderer());
2914    
2915            for (int i = 0; i < propertyTable.getRowCount(); i++) {
2916                TableCellRenderer renderer = propertyTable.getCellRenderer(i, 1);
2917                Component comp = renderer.getTableCellRendererComponent(propertyTable, propertyTable.getValueAt(i, 1), false, false, i, 1);
2918                try {
2919                    int height = comp.getMaximumSize().height;
2920                    propertyTable.setRowHeight(i, height);
2921                } catch (Exception ea) {
2922                }
2923            }
2924        }
2925    
2926        /**
2927         * @see javax.swing.event.CellEditorListener#editingCanceled(ChangeEvent)
2928         */
2929        public void editingCanceled(ChangeEvent e) {
2930            updater.update();
2931        }
2932    
2933        /**
2934         * @see javax.swing.event.CellEditorListener#editingStopped(ChangeEvent)
2935         */
2936        public void editingStopped(ChangeEvent e) {
2937    
2938            setDirty(true);
2939            if (! dirtyFlag || ((PropertyTableModel) propertyTable.getModel()).target instanceof MondrianGuiDef.Schema) {
2940                setDirtyFlag(true);   // true means dirty indication shown on title
2941                setTitle();
2942            }
2943    
2944            String emsg = ((PropertyTableModel) propertyTable.getModel()).getErrorMsg();
2945            if (emsg != null) {
2946                JOptionPane.showMessageDialog(this,emsg , "Error", JOptionPane.ERROR_MESSAGE);
2947                ((PropertyTableModel) propertyTable.getModel()).setErrorMsg(null);
2948            }
2949    
2950            updater.update();
2951        }
2952    
2953        class PopupTrigger extends MouseAdapter {
2954    
2955            public void mouseReleased(MouseEvent e) {
2956                if (e.isPopupTrigger()) {
2957                    int x = e.getX();
2958                    int y = e.getY();
2959                    TreePath path = tree.getPathForLocation(x, y);
2960                    if (path != null) {
2961                        jPopupMenu.removeAll();
2962                        Object pathSelected = path.getLastPathComponent();
2963                        if (pathSelected instanceof MondrianGuiDef.Schema) {
2964                            jPopupMenu.add(addCube);
2965                            jPopupMenu.add(addDimension);
2966                            jPopupMenu.add(addNamedSet);
2967                            jPopupMenu.add(addUserDefinedFunction);
2968                            jPopupMenu.add(jSeparator1);
2969                            jPopupMenu.add(addVirtualCube);
2970                            jPopupMenu.add(addRole);
2971                        } else if (pathSelected instanceof MondrianGuiDef.Cube) {
2972                            jPopupMenu.add(addDimension);
2973                            jPopupMenu.add(addDimensionUsage);
2974                            jPopupMenu.add(addMeasure);
2975                            jPopupMenu.add(addCalculatedMember);
2976                            jPopupMenu.add(addNamedSet);
2977                            jPopupMenu.add(jSeparator1);
2978                            jPopupMenu.add(delete);
2979                        } else if (pathSelected instanceof MondrianGuiDef.Dimension) {
2980                            jPopupMenu.add(addHierarchy);
2981                            jPopupMenu.add(jSeparator1);
2982                            jPopupMenu.add(delete);
2983                        } else if (pathSelected instanceof MondrianGuiDef.Hierarchy) {
2984                            jPopupMenu.add(addLevel);
2985                            jPopupMenu.add(addRelation);
2986                            jPopupMenu.add(jSeparator1);
2987                            jPopupMenu.add(delete);
2988                            if (((MondrianGuiDef.Hierarchy) pathSelected).relation == null) {
2989                                addRelation.setEnabled(true);
2990                            } else {
2991                                addRelation.setEnabled(false);
2992                            }
2993                        } else if (pathSelected instanceof MondrianGuiDef.Level) {
2994                            jPopupMenu.add(addProperty);
2995                            jPopupMenu.add(addKeyExp);
2996                            if (((MondrianGuiDef.Level) pathSelected).keyExp == null) {
2997                                addKeyExp.setEnabled(true);
2998                            } else {
2999                                addKeyExp.setEnabled(false);
3000                            }
3001                            jPopupMenu.add(addNameExp);
3002                            if (((MondrianGuiDef.Level) pathSelected).nameExp == null) {
3003                                addNameExp.setEnabled(true);
3004                            } else {
3005                                addNameExp.setEnabled(false);
3006                            }
3007                            jPopupMenu.add(addOrdinalExp);
3008                            if (((MondrianGuiDef.Level) pathSelected).ordinalExp == null) {
3009                                addOrdinalExp.setEnabled(true);
3010                            } else {
3011                                addOrdinalExp.setEnabled(false);
3012                            }
3013                            jPopupMenu.add(addParentExp);
3014                            if (((MondrianGuiDef.Level) pathSelected).parentExp == null) {
3015                                addParentExp.setEnabled(true);
3016                            } else {
3017                                addParentExp.setEnabled(false);
3018                            }
3019                            jPopupMenu.add(addClosure);
3020                            if (((MondrianGuiDef.Level) pathSelected).closure == null) {
3021                                addClosure.setEnabled(true);
3022                            } else {
3023                                addClosure.setEnabled(false);
3024                            }
3025                            jPopupMenu.add(jSeparator1);
3026                            jPopupMenu.add(delete);
3027                        } else if (pathSelected instanceof MondrianGuiDef.KeyExpression ||
3028                                pathSelected instanceof MondrianGuiDef.NameExpression ||
3029                                pathSelected instanceof MondrianGuiDef.OrdinalExpression ||
3030                                pathSelected instanceof MondrianGuiDef.ParentExpression) {
3031                            jPopupMenu.add(addSQL);
3032                            jPopupMenu.add(jSeparator1);
3033                            jPopupMenu.add(delete);
3034                        } else if (pathSelected instanceof MondrianGuiDef.RelationOrJoin) {
3035                            Object po = path.getParentPath().getLastPathComponent();
3036                            if (! (po instanceof MondrianGuiDef.RelationOrJoin) &&
3037                                ! (po instanceof MondrianGuiDef.Closure)) {
3038                                if (po instanceof MondrianGuiDef.Cube) {
3039                                    jPopupMenu.add(addAggName);
3040                                    jPopupMenu.add(addAggPattern);
3041                                    jPopupMenu.add(addAggExclude);
3042                                } else {
3043                                    jPopupMenu.add(delete);
3044                                }
3045                            } else {
3046                                return;
3047                            }
3048                        } else if (pathSelected instanceof MondrianGuiDef.Measure) {
3049                            jPopupMenu.add(addMeasureExp);
3050                            if (((MondrianGuiDef.Measure) pathSelected).measureExp == null) {
3051                                addMeasureExp.setEnabled(true);
3052                            } else {
3053                                addMeasureExp.setEnabled(false);
3054                            }
3055                            jPopupMenu.add(jSeparator1);
3056                            jPopupMenu.add(delete);
3057                        } else if (pathSelected instanceof MondrianGuiDef.MeasureExpression) {
3058                            jPopupMenu.add(addSQL);
3059                            addSQL.setEnabled(true);
3060                            jPopupMenu.add(jSeparator1);
3061                            jPopupMenu.add(delete);
3062                        } else if (pathSelected instanceof MondrianGuiDef.Closure) {
3063                            jPopupMenu.add(delete);
3064                        } else if (pathSelected instanceof MondrianGuiDef.AggName ||
3065                                pathSelected instanceof MondrianGuiDef.AggPattern) {
3066                            jPopupMenu.add(addAggFactCount);
3067                            jPopupMenu.add(addAggIgnoreColumn);
3068                            jPopupMenu.add(addAggForeignKey);
3069                            jPopupMenu.add(addAggMeasure);
3070                            jPopupMenu.add(addAggLevel);
3071                            if (pathSelected instanceof MondrianGuiDef.AggPattern) {
3072                                jPopupMenu.add(addAggExclude);
3073                                if (((MondrianGuiDef.AggPattern) pathSelected).factcount == null) {
3074                                    addAggFactCount.setEnabled(true);
3075                                } else {
3076                                    addAggFactCount.setEnabled(false);
3077                                }
3078                            } else {
3079                                if (((MondrianGuiDef.AggName) pathSelected).factcount == null) {
3080                                    addAggFactCount.setEnabled(true);
3081                                } else {
3082                                    addAggFactCount.setEnabled(false);
3083                                }
3084                            }
3085                            jPopupMenu.add(jSeparator1);
3086                            jPopupMenu.add(delete);
3087                        } else if (pathSelected instanceof MondrianGuiDef.VirtualCube) {
3088                            jPopupMenu.add(addVirtualCubeDimension);
3089                            jPopupMenu.add(addVirtualCubeMeasure);
3090                            jPopupMenu.add(addCalculatedMember);
3091                            jPopupMenu.add(jSeparator1);
3092                            jPopupMenu.add(delete);
3093                        } else if (pathSelected instanceof MondrianGuiDef.Role) {
3094                            jPopupMenu.add(addSchemaGrant);
3095                            jPopupMenu.add(jSeparator1);
3096                            jPopupMenu.add(delete);
3097                        } else if (pathSelected instanceof MondrianGuiDef.SchemaGrant) {
3098                            jPopupMenu.add(addCubeGrant);
3099                            jPopupMenu.add(jSeparator1);
3100                            jPopupMenu.add(delete);
3101                        } else if (pathSelected instanceof MondrianGuiDef.CubeGrant) {
3102                            jPopupMenu.add(addDimensionGrant);
3103                            jPopupMenu.add(addHierarchyGrant);
3104                            jPopupMenu.add(jSeparator1);
3105                            jPopupMenu.add(delete);
3106                        } else if (pathSelected instanceof MondrianGuiDef.HierarchyGrant) {
3107                            jPopupMenu.add(addMemberGrant);
3108                            jPopupMenu.add(jSeparator1);
3109                            jPopupMenu.add(delete);
3110                        } else {
3111                            jPopupMenu.add(delete);
3112                        } /* else {
3113                            return;
3114                        }*/
3115                        jPopupMenu.show(tree, x, y);
3116                    }
3117                }
3118            }
3119        }
3120    
3121        static final String[] DEF_DEFAULT = {};
3122        static final String[] DEF_VIRTUAL_CUBE = { "name", "caption", "enabled"};
3123        static final String[] DEF_VIRTUAL_CUBE_MEASURE = { "name", "cubeName", "visible" };
3124        static final String[] DEF_VIRTUAL_CUBE_DIMENSION = { "name", "cubeName", "caption", "foreignKey" };
3125        static final String[] DEF_VIEW = { "alias" };
3126        static final String[] DEF_TABLE = { "schema" , "name", "alias"};
3127        static final String[] DEF_AGG_FACT_COUNT = { "column"};
3128        static final String[] DEF_AGG_NAME = { "name", "ignorecase"};
3129        static final String[] DEF_AGG_PATTERN = { "pattern", "ignorecase"};
3130        static final String[] DEF_AGG_EXCLUDE = { "pattern", "name" , "ignorecase"};
3131        static final String[] DEF_AGG_IGNORE_COLUMN = { "column"};
3132        static final String[] DEF_AGG_FOREIGN_KEY = { "factColumn" , "aggColumn"};
3133        static final String[] DEF_AGG_MEASURE = { "column" , "name"};
3134        static final String[] DEF_AGG_LEVEL = { "column" , "name"};
3135    
3136        static final String[] DEF_CLOSURE = { "parentColumn" , "childColumn"};
3137        static final String[] DEF_RELATION = { "name" };
3138        static final String[] DEF_SQL = { "cdata", "dialect" }; //?
3139        static final String[] DEF_SCHEMA = {"name", "measuresCaption", "defaultRole"};
3140        static final String[] DEF_PROPERTY = { "name", "column", "type", "formatter", "caption" };
3141        static final String[] DEF_PARAMETER = { "name", "value" }; //?
3142        static final String[] DEF_MEASURE = { "name", "aggregator", "column", "formatString", "visible", "datatype", "formatter", "caption"};
3143    
3144        static final String[] DEF_CALCULATED_MEMBER = { "name", "caption", "dimension", "visible", "formula | formulaElement.cdata", "formatString"};
3145        static final String[] DEF_FORMULA = { "cdata" };
3146        static final String[] DEF_CALCULATED_MEMBER_PROPERTY = { "name", "caption", "expression", "value"};
3147        static final String[] DEF_NAMED_SET = { "name", "formula" };
3148        static final String[] DEF_USER_DEFINED_FUNCTION = { "name", "className" };
3149    
3150        static final String[] DEF_LEVEL = { "name", "table", "column", "nameColumn", "parentColumn", "nullParentValue", "ordinalColumn", "type", "uniqueMembers", "levelType","hideMemberIf", "approxRowCount", "caption", "captionColumn", "formatter"};
3151        static final String[] DEF_JOIN = { "leftAlias", "leftKey", "rightAlias", "rightKey"};
3152        static final String[] DEF_HIERARCHY = { "name", "hasAll", "allMemberName", "allMemberCaption", "allLevelName", "defaultMember", "memberReaderClass", "primaryKeyTable", "primaryKey", "caption" };
3153        static final String[] DEF_EXPRESSION_VIEW = {};
3154        static final String[] DEF_DIMENSION_USAGE = { "name", "foreignKey", "source", "level", "usagePrefix", "caption" };
3155        static final String[] DEF_DIMENSION = { "name", "foreignKey", "type", "usagePrefix", "caption"};
3156        static final String[] DEF_CUBE = { "name", "caption", "cache", "enabled" };
3157        static final String[] DEF_ROLE = { "name" };
3158        static final String[] DEF_SCHEMA_GRANT = { "access" };
3159        static final String[] DEF_CUBE_GRANT = { "access", "cube" };
3160        static final String[] DEF_DIMENSION_GRANT = { "access", "dimension" };
3161        static final String[] DEF_HIERARCHY_GRANT = { "access", "hierarchy", "topLevel", "bottomLevel" };
3162        static final String[] DEF_MEMBER_GRANT = { "access", "member" };
3163        static final String[] DEF_COLUMN = { "name", "table" };   //?
3164    
3165        private static final String LBL_COLUMN = "Column";
3166        private static final String LBL_CUBE = "Cube";
3167        private static final String LBL_ROLE = "Role";
3168        private static final String LBL_SCHEMA_GRANT = "Schema Grant";
3169        private static final String LBL_CUBE_GRANT = "Cube Grant";
3170        private static final String LBL_DIMENSION_GRANT = "Dimension Grant";
3171        private static final String LBL_HIERARCHY_GRANT = "Hierarchy Grant";
3172        private static final String LBL_MEMBER_GRANT = "Member Grant";
3173        private static final String LBL_DIMENSION = "Dimension";
3174        private static final String LBL_DIMENSION_USAGE = "Dimension Usage";
3175        private static final String LBL_EXPRESSION_VIEW = "Expression View";
3176        private static final String LBL_KEY_EXPRESSION = "Key Expression";
3177        private static final String LBL_NAME_EXPRESSION = "Name Expression";
3178        private static final String LBL_ORDINAL_EXPRESSION = "Ordinal Expression";
3179        private static final String LBL_PARENT_EXPRESSION = "Parent Expression";
3180        private static final String LBL_MEASURE_EXPRESSION = "Measure Expression";
3181        private static final String LBL_HIERARCHY = "Hierarchy";
3182        private static final String LBL_JOIN = "Join";
3183        private static final String LBL_LEVEL = "Level";
3184        private static final String LBL_MEASURE = "Measure";
3185        private static final String LBL_CALCULATED_MEMBER = "Calculated Member";
3186        private static final String LBL_CALCULATED_MEMBER_PROPERTY = "Calculated Member Property";
3187        private static final String LBL_NAMED_SET = "Named Set";
3188        private static final String LBL_USER_DEFINED_FUNCTION = "User Defined Function";
3189        private static final String LBL_PARAMETER = "Parameter";
3190        private static final String LBL_PROPERTY = "Property";
3191        private static final String LBL_SCHEMA = "Schema";
3192        private static final String LBL_SQL = "SQL";
3193        private static final String LBL_TABLE = "Table";
3194        private static final String LBL_CLOSURE = "Closure";
3195    
3196        private static final String LBL_AGG_NAME = "Aggregate Name";
3197        private static final String LBL_AGG_IGNORE_COLUMN = "Aggregate Ignore Column";
3198        private static final String LBL_AGG_FOREIGN_KEY = "Aggregate Foreign Key";
3199        private static final String LBL_AGG_MEASURE = "Aggregate Measure";
3200        private static final String LBL_AGG_LEVEL = "Aggregate Level";
3201        private static final String LBL_AGG_PATTERN = "Aggregate Pattern";
3202        private static final String LBL_AGG_EXCLUDE = "Aggregate Exclude";
3203        private static final String LBL_AGG_FACT_COUNT = "Aggregate Fact Count";
3204    
3205        private static final String LBL_VIEW = "View";
3206        private static final String LBL_VIRTUAL_CUBE = "Virtual Cube";
3207        private static final String LBL_VIRTUAL_CUBE_DIMENSION = "Virtual Cube Dimension";
3208        private static final String LBL_VIRTUAL_CUBE_MEASURE = "Virtual Cube Measure";
3209        private static final String LBL_UNKNOWN_TYPE = "Unknown Type";
3210    
3211        private static String alert = "Alert";
3212    
3213        private AbstractAction arrowButtonUpAction;
3214        private AbstractAction arrowButtonDownAction;
3215    
3216        private AbstractAction addCube;
3217        private AbstractAction addRole;
3218        private AbstractAction addSchemaGrant;
3219        private AbstractAction addCubeGrant;
3220        private AbstractAction addDimensionGrant;
3221        private AbstractAction addHierarchyGrant;
3222        private AbstractAction addMemberGrant;
3223    
3224        private AbstractAction addDimension;
3225        private AbstractAction addDimensionUsage;
3226        private AbstractAction addHierarchy;
3227        private AbstractAction addNamedSet;
3228        private AbstractAction addUserDefinedFunction;
3229        private AbstractAction addCalculatedMember;
3230    
3231        private AbstractAction addMeasure;
3232        private AbstractAction addMeasureExp;
3233        private AbstractAction addLevel;
3234        private AbstractAction addSQL;
3235        private AbstractAction addKeyExp;
3236        private AbstractAction addNameExp;
3237        private AbstractAction addOrdinalExp;
3238        private AbstractAction addParentExp;
3239        private AbstractAction addRelation;
3240        private AbstractAction addProperty;
3241        private AbstractAction addClosure;
3242    
3243        private AbstractAction addAggName;
3244        private AbstractAction addAggIgnoreColumn;
3245        private AbstractAction addAggForeignKey;
3246        private AbstractAction addAggMeasure;
3247        private AbstractAction addAggLevel;
3248        private AbstractAction addAggPattern;
3249        private AbstractAction addAggExclude;
3250        private AbstractAction addAggFactCount;
3251    
3252        private AbstractAction addVirtualCube;
3253        private AbstractAction addVirtualCubeDimension;
3254        private AbstractAction addVirtualCubeMeasure;
3255    
3256        private AbstractAction delete;
3257    
3258        private AbstractAction editMode;
3259    
3260        private JTable propertyTable;
3261        private JPanel jPanel1;
3262        private JPanel jPanel2;
3263        private JPanel jPanel3;
3264        private JButton addLevelButton;
3265        private JScrollPane jScrollPane2;
3266        private JScrollPane jScrollPane1;
3267        private JButton addPropertyButton;
3268        private JButton pasteButton;
3269        private JLabel targetLabel;
3270        private JLabel validStatusLabel;
3271        private JLabel targetLabel2;
3272        private JLabel validStatusLabel2;
3273        private JTree tree;
3274        private JSplitPane jSplitPane1;
3275    
3276        private JButton addDimensionButton;
3277        private JButton addDimensionUsageButton;
3278        private JButton addHierarchyButton;
3279        private JButton addNamedSetButton;
3280        private JButton addUserDefinedFunctionButton;
3281        private JButton addCalculatedMemberButton;
3282        private JButton cutButton;
3283        private JButton addMeasureButton;
3284        private JButton addCubeButton;
3285        private JButton addRoleButton;
3286        private JButton addVirtualCubeButton;
3287        private JButton addVirtualCubeDimensionButton;
3288        private JButton addVirtualCubeMeasureButton;
3289    
3290        private JButton deleteButton;
3291        private JToggleButton editModeButton;
3292        private JButton copyButton;
3293        private JToolBar jToolBar1;
3294        private JPopupMenu jPopupMenu;
3295    
3296        private JSeparator jSeparator1;
3297    
3298        private JPanel footer;
3299        private JLabel databaseLabel;
3300    
3301        private JPanel jPanelXML;
3302        private JScrollPane jScrollPaneXML;
3303        private JEditorPane jEditorPaneXML;
3304    
3305        public boolean isNewFile() {
3306            return newFile;
3307        }
3308    
3309        public void setNewFile(boolean newFile) {
3310            this.newFile = newFile;
3311        }
3312    
3313        public boolean isDirty() {
3314            return dirty;
3315        }
3316    
3317        public void setDirty(boolean dirty) {
3318            this.dirty = dirty;
3319        }
3320    
3321        public void setTitle() {
3322            // sets the title of Internal Frame within which this schema explorer is displayed.
3323            // The title includes schema name and schema file name
3324    
3325            parentIFrame.setTitle(getResourceConverter().getFormattedString("schemaExplorer.frame.title",
3326                    "Schema - {0} ({1}){2}",
3327                        new String[] { schema.name, schemaFile.getName(), isDirty() ? "*" : "" }));
3328    
3329            parentIFrame.setToolTipText(schemaFile.toString());
3330        }
3331    
3332        public void setDirtyFlag(boolean dirtyFlag) {
3333            this.dirtyFlag = dirtyFlag;
3334        }
3335    
3336        public Object getParentObject() {
3337            TreePath tPath = tree.getSelectionPath();
3338            if ((tPath != null) && (tPath.getParentPath() != null)) {
3339                return tPath.getParentPath().getLastPathComponent();
3340            }
3341            return null;
3342        }
3343    
3344        public String getJdbcConnectionUrl() {
3345            return this.jdbcMetaData.jdbcConnectionUrl;
3346        }
3347    
3348        public String getJdbcUsername() {
3349            return this.jdbcMetaData.jdbcUsername;
3350        }
3351    
3352        public String getJdbcPassword() {
3353            return this.jdbcMetaData.jdbcPassword;
3354        }
3355    
3356        public String getErrMsg() {
3357            return errMsg;
3358        }
3359    
3360        public boolean isEditModeXML() {
3361            return editModeXML; // used by schema frame focuslistener in workbench/desktoppane
3362        }
3363    
3364        public I18n getResourceConverter() {
3365            return workbench.getResourceConverter();
3366        }
3367    }
3368    
3369    // End SchemaExplorer.java