001/*
002// This software is subject to the terms of the Eclipse Public License v1.0
003// Agreement, available at the following URL:
004// http://www.eclipse.org/legal/epl-v10.html.
005// You must accept the terms of that agreement to use this software.
006//
007// Copyright (C) 2002-2005 Julian Hyde
008// Copyright (C) 2005-2011 Pentaho and others
009// Copyright (C) 2006-2007 CINCOM SYSTEMS, INC.
010// All Rights Reserved.
011*/
012package mondrian.gui;
013
014import org.apache.log4j.Logger;
015
016import org.eigenbase.xom.*;
017
018import java.awt.*;
019import java.awt.event.*;
020import java.io.*;
021import java.lang.reflect.Array;
022import java.lang.reflect.Field;
023import java.util.*;
024import java.util.List;
025import javax.swing.*;
026import javax.swing.border.EtchedBorder;
027import javax.swing.event.*;
028import javax.swing.plaf.basic.BasicArrowButton;
029import javax.swing.table.*;
030import javax.swing.text.DefaultEditorKit;
031import javax.swing.text.PlainDocument;
032import javax.swing.tree.*;
033
034/**
035 * @author sean
036 */
037public class SchemaExplorer
038    extends javax.swing.JPanel
039    implements TreeSelectionListener, CellEditorListener
040{
041    private static final Logger LOGGER = Logger.getLogger(SchemaExplorer.class);
042
043    private final Workbench workbench;
044    private MondrianGuiDef.Schema schema;
045    private SchemaTreeModel model;
046    private SchemaTreeCellRenderer renderer;
047    private File schemaFile;
048    private JTreeUpdater updater;
049    private final ClassLoader myClassLoader;
050    private boolean newFile;
051
052    // indicates file is without changes, dirty=true when some changes are made
053    // to the file
054    private boolean dirty = false;
055
056    // indicates dirty status shown on title
057    private boolean dirtyFlag = false;
058
059    private JInternalFrame parentIFrame;
060    private JdbcMetaData jdbcMetaData;
061    private boolean editModeXML = false;
062    private String errMsg = null;
063
064    /**
065     * Creates new form SchemaExplorer
066     */
067    public SchemaExplorer(Workbench workbench) {
068        this.workbench = workbench;
069        myClassLoader = this.getClass().getClassLoader();
070        initComponents();
071    }
072
073    public SchemaExplorer(
074        Workbench workbench,
075        File f,
076        JdbcMetaData jdbcMetaData,
077        boolean newFile,
078        JInternalFrame parentIFrame)
079    {
080        this(workbench);
081
082        alert =
083            getResourceConverter().getString(
084                "schemaExplorer.alert.title",
085                "Alert");
086
087        // XML editor
088        try {
089            jEditorPaneXML = new JEditorPane();
090        } catch (Exception ex) {
091            LOGGER.error("SchemaExplorer-JEditorPane", ex);
092        }
093
094        jEditorPaneXML.setLayout(new java.awt.BorderLayout());
095        jEditorPaneXML.setEditable(false);
096        jScrollPaneXML = new JScrollPane(jEditorPaneXML);
097        jPanelXML.setLayout(new java.awt.BorderLayout());
098        jPanelXML.add(jScrollPaneXML, java.awt.BorderLayout.CENTER);
099        jPanelXML.add(targetLabel2, java.awt.BorderLayout.NORTH);
100        jPanelXML.add(validStatusLabel2, java.awt.BorderLayout.SOUTH);
101        jPanelXML.setMaximumSize(jPanel1.getMaximumSize());
102        jPanelXML.setPreferredSize(jPanel1.getPreferredSize());
103
104        databaseLabel.setText(
105            getResourceConverter().getFormattedString(
106                "schemaExplorer.database.text",
107                "Database - {0} ({1})",
108                nvl(jdbcMetaData.getDbCatalogName()),
109                jdbcMetaData.getDatabaseProductName()));
110
111        try {
112            Parser xmlParser = XOMUtil.createDefaultParser();
113            this.schemaFile = f;
114            this.setNewFile(newFile);
115            this.parentIFrame = parentIFrame;
116
117            this.jdbcMetaData = jdbcMetaData;
118
119            if (newFile) {
120                schema = new MondrianGuiDef.Schema();
121                schema.parameters = new MondrianGuiDef.Parameter[0];
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 =
127                    new MondrianGuiDef.UserDefinedFunction[0];
128                schema.virtualCubes = new MondrianGuiDef.VirtualCube[0];
129
130                String sname = schemaFile.getName();
131                int ext = sname.indexOf(".");
132                if (ext != -1) {
133                    schema.name = "New " + sname.substring(0, ext);
134                }
135            } else {
136                try {
137                    schema =
138                        new MondrianGuiDef.Schema(
139                            xmlParser.parse(
140                                schemaFile.toURL()));
141                } catch (XOMException ex) {
142                    // Parsing error of the schema file causes default tree of
143                    // colors etc. to be displayed in schema explorer.
144                    // Initialize the schema to display an empty schema if you
145                    // want to show schema explorer for file where parsing
146                    // failed.
147                    ex.printStackTrace();
148                    schema = new MondrianGuiDef.Schema();
149                    schema.parameters = new MondrianGuiDef.Parameter[0];
150                    schema.cubes = new MondrianGuiDef.Cube[0];
151                    schema.dimensions = new MondrianGuiDef.Dimension[0];
152                    schema.namedSets = new MondrianGuiDef.NamedSet[0];
153                    schema.roles = new MondrianGuiDef.Role[0];
154                    schema.userDefinedFunctions =
155                        new MondrianGuiDef.UserDefinedFunction[0];
156                    schema.virtualCubes = new MondrianGuiDef.VirtualCube[0];
157
158                    LOGGER.error(
159                        "Exception  : Schema file parsing failed."
160                        + ex.getMessage(),
161                        ex);
162                    errMsg =
163                        getResourceConverter().getFormattedString(
164                            "schemaExplorer.parsing.error",
165                            "Parsing Error: Could not open file {0}\n{1}",
166                            schemaFile.toString(),
167                            ex.getLocalizedMessage());
168                }
169            }
170            // sets title of i frame with schema name and file name
171            setTitle();
172
173            renderer = new SchemaTreeCellRenderer(workbench, jdbcMetaData);
174            model = new SchemaTreeModel(schema);
175            tree.setModel(model);
176            tree.setCellRenderer(renderer);
177            tree.addTreeSelectionListener(this);
178
179            JComboBox listEditor = new JComboBox(
180                new String[]{
181                    getResourceConverter().getString(
182                        "schemaExplorer.hierarchy.select.join", "Join"),
183                    getResourceConverter().getString(
184                        "schemaExplorer.hierarchy.select.table", "Table")
185                });
186            listEditor.setToolTipText(
187                getResourceConverter().getString(
188                    "schemaExplorer.hierarchy.select.title",
189                    "Select Join or Table Hierarchy"));
190            listEditor.setPreferredSize(
191                new java.awt.Dimension(
192                    listEditor.getPreferredSize().width,
193                    24)); //Do not remove this
194
195            listEditor.addItemListener(
196                new ItemListener() {
197                    public void itemStateChanged(ItemEvent e) {
198                        tree.stopEditing();
199                        TreePath tpath = tree.getSelectionPath();
200                        if (tpath != null) {
201                            TreePath parentpath = tpath.getParentPath();
202                            if (parentpath != null) {
203                                refreshTree(parentpath);
204                            }
205                        }
206                    }
207                });
208
209            TreeCellEditor comboEditor = new DefaultCellEditor(listEditor);
210
211            SchemaTreeCellEditor editor = new SchemaTreeCellEditor(
212                workbench, tree, renderer, comboEditor);
213            tree.setCellEditor(editor);
214            tree.setEditable(true);
215
216
217            SchemaPropertyCellEditor spce = new SchemaPropertyCellEditor(
218                workbench, jdbcMetaData);
219            spce.addCellEditorListener(this);
220            propertyTable.setDefaultEditor(Object.class, spce);
221            // to set background color of attribute columns
222            SchemaPropertyCellRenderer.attributeBackground =
223                jScrollPane2.getBackground();
224            SchemaPropertyCellRenderer spcr =
225                new SchemaPropertyCellRenderer(workbench);
226            propertyTable.setDefaultRenderer(Object.class, spcr);
227        } catch (Exception ex) {
228            LOGGER.error("SchemaExplorer init error", ex);
229        }
230    }
231
232    private static String nvl(String s) {
233        return s == null ? "" : s;
234    }
235
236    /**
237     * Called from within the constructor to initialize the form.
238     */
239    private void initComponents() {
240        jPanelXML = new JPanel();
241        jScrollPaneXML = new JScrollPane();
242
243        footer = new JPanel();
244        databaseLabel = new javax.swing.JLabel();
245
246        jSeparator1 = new JSeparator();
247        jSeparator2 = new JSeparator();
248        jSplitPane1 = new JSplitPane();
249        jPanel1 = new JPanel();
250        jScrollPane2 = new JScrollPane();
251
252        // propertyTable includes changeSelection and processKeyEvent
253        // processing for keyboard navigation
254        propertyTable = new JTable() {
255            public void changeSelection(
256                int rowIndex, int columnIndex, boolean toggle, boolean extend)
257            {
258                if (columnIndex == 0) {
259                    AWTEvent currentEvent = EventQueue.getCurrentEvent();
260                    if (currentEvent instanceof KeyEvent) {
261                        KeyEvent ke = (KeyEvent) currentEvent;
262                        int kcode = ke.getKeyCode();
263                        if (kcode == KeyEvent.VK_TAB) {
264                            if ((ke.getModifiersEx()
265                                 & InputEvent.SHIFT_DOWN_MASK)
266                                == InputEvent.SHIFT_DOWN_MASK)
267                            {
268                                rowIndex -= 1;
269                                if (rowIndex < 0) {
270                                    rowIndex = propertyTable.getRowCount() - 1;
271                                }
272                            }
273                            setTableCellFocus(rowIndex);
274                            return;
275                        }
276                    }
277                }
278                super.changeSelection(rowIndex, columnIndex, toggle, extend);
279            }
280
281            public void processKeyEvent(KeyEvent e) {
282                int kcode = e.getKeyCode();
283                if (kcode == KeyEvent.VK_UP || kcode == KeyEvent.VK_DOWN) {
284                    int row = propertyTable.getSelectedRow();
285                    setTableCellFocus(row);
286                    return;
287                }
288                super.processKeyEvent(e);
289            }
290        };
291
292        targetLabel = new javax.swing.JLabel();
293        validStatusLabel = new javax.swing.JLabel();
294        targetLabel2 = new javax.swing.JLabel();
295        validStatusLabel2 = new javax.swing.JLabel();
296        jPanel2 = new JPanel();
297        jScrollPane1 = new JScrollPane();
298
299        tree = new JTree();
300        tree.getSelectionModel().setSelectionMode(
301            DefaultTreeSelectionModel.SINGLE_TREE_SELECTION);
302
303        ToolTipManager.sharedInstance().registerComponent(tree);
304
305        jToolBar1 = new JToolBar();
306        addCubeButton = new JButton();
307        addDimensionButton = new JButton();
308        addDimensionUsageButton = new JButton();
309        addHierarchyButton = new JButton();
310        addNamedSetButton = new JButton();
311        addUserDefinedFunctionButton = new JButton();
312        addRoleButton = new JButton();
313
314        addMeasureButton = new JButton();
315        addCalculatedMemberButton = new JButton();
316        addLevelButton = new JButton();
317        addPropertyButton = new JButton();
318        addCalculatedMemberPropertyButton = new JButton();
319
320        addVirtualCubeButton = new JButton();
321        addVirtualCubeDimensionButton = new JButton();
322        addVirtualCubeMeasureButton = new JButton();
323
324        cutButton = new JButton(new DefaultEditorKit.CutAction());
325        copyButton = new JButton(new DefaultEditorKit.CopyAction());
326        pasteButton = new JButton(new DefaultEditorKit.PasteAction());
327        deleteButton = new JButton();
328        editModeButton = new JToggleButton();
329
330        setLayout(new BorderLayout());
331
332        jSplitPane1.setDividerLocation(200);
333        jPanel1.setLayout(new BorderLayout());
334
335        propertyTable.setModel(
336            new DefaultTableModel(
337                new Object[][]{
338                },
339                new String[]{
340                    getResourceConverter().getString(
341                        "schemaExplorer.propertyTable.attribute", "Attribute"),
342                    getResourceConverter().getString(
343                        "schemaExplorer.propertyTable.value", "Value")
344                })
345            {
346                Class[] types = {String.class, Object.class};
347                boolean[] canEdit = {false, true};
348
349                public Class getColumnClass(int columnIndex) {
350                    return types[columnIndex];
351                }
352
353                public boolean isCellEditable(int rowIndex, int columnIndex) {
354                    return canEdit[columnIndex];
355                }
356            });
357
358        // Set property table column headers to bold.
359        propertyTable.getTableHeader().setFont(
360            new Font(
361                "Dialog",
362                Font.BOLD,
363                12));
364
365        jScrollPane2.setViewportView(propertyTable);
366
367        jPanel1.add(jScrollPane2, java.awt.BorderLayout.CENTER);
368
369        targetLabel.setFont(new Font("Dialog", 1, 14));
370        targetLabel.setForeground(
371            (Color) UIManager.getDefaults().get(
372                "CheckBoxMenuItem.acceleratorForeground"));
373        targetLabel.setHorizontalAlignment(SwingConstants.CENTER);
374        targetLabel.setText(
375            getResourceConverter().getString(
376                "schemaExplorer.targetLabel.title", "Schema"));
377        targetLabel.setBorder(new EtchedBorder());
378        // up arrow button for property table heading
379        jPanel3 = new JPanel();
380        jPanel3.setLayout(new BorderLayout());
381        BasicArrowButton arrowButtonUp =
382            new BasicArrowButton(SwingConstants.NORTH);
383        BasicArrowButton arrowButtonDown =
384            new BasicArrowButton(SwingConstants.SOUTH);
385        arrowButtonUp.setToolTipText(
386            getResourceConverter().getString(
387                "schemaExplorer.arrowButtonUp.toolTip",
388                "move to parent element"));
389        arrowButtonDown.setToolTipText(
390            getResourceConverter().getString(
391                "schemaExplorer.arrowButtonDown.toolTip",
392                "move to child element"));
393        arrowButtonUpAction = new AbstractAction(
394            getResourceConverter().getString(
395                "schemaExplorer.arrowButtonUp.title", "Arrow button up"))
396        {
397            public void actionPerformed(ActionEvent e) {
398                arrowButtonUpAction(e);
399            }
400        };
401        arrowButtonDownAction = new AbstractAction(
402            getResourceConverter().getString(
403                "schemaExplorer.arrowButtonDown.title", "Arrow button down"))
404        {
405            public void actionPerformed(ActionEvent e) {
406                arrowButtonDownAction(e);
407            }
408        };
409        arrowButtonUp.addActionListener(arrowButtonUpAction);
410        arrowButtonDown.addActionListener(arrowButtonDownAction);
411        jPanel3.add(arrowButtonDown, java.awt.BorderLayout.EAST);
412        jPanel3.add(arrowButtonUp, java.awt.BorderLayout.WEST);
413        jPanel3.add(targetLabel, java.awt.BorderLayout.CENTER);
414
415        jPanel1.add(jPanel3, java.awt.BorderLayout.NORTH);
416        validStatusLabel.setFont(new Font("Dialog", Font.PLAIN, 12));
417        validStatusLabel.setForeground(Color.RED);
418        validStatusLabel.setHorizontalAlignment(SwingConstants.CENTER);
419
420        jPanel1.add(validStatusLabel, java.awt.BorderLayout.SOUTH);
421
422        // for XML viewing
423        targetLabel2.setFont(new Font("Dialog", 1, 14));
424        targetLabel2.setForeground(
425            (Color) UIManager.getDefaults().get(
426                "CheckBoxMenuItem.acceleratorForeground"));
427        targetLabel2.setHorizontalAlignment(SwingConstants.CENTER);
428        targetLabel2.setText(
429            getResourceConverter().getString(
430                "schemaExplorer.targetLabel.title", "Schema"));
431        targetLabel2.setBorder(new EtchedBorder());
432        validStatusLabel2.setFont(new Font("Dialog", Font.PLAIN, 12));
433        validStatusLabel2.setForeground(Color.RED);
434        validStatusLabel2.setHorizontalAlignment(SwingConstants.CENTER);
435
436        jSplitPane1.setRightComponent(jPanel1);
437
438        jPanel2.setLayout(new java.awt.BorderLayout());
439
440        jScrollPane1.setViewportView(tree);
441
442        jPanel2.add(jScrollPane1, java.awt.BorderLayout.CENTER);
443
444        jSplitPane1.setLeftComponent(jPanel2);
445
446
447        //========================================================
448        // actions
449        //========================================================
450        addCube = new AbstractAction(
451            getResourceConverter().getString(
452                "schemaExplorer.addCube.title", "Add Cube"))
453        {
454            public void actionPerformed(ActionEvent e) {
455                addCube(e);
456            }
457        };
458        addParameter = new AbstractAction(
459            getResourceConverter().getString(
460                "schemaExplorer.addParameter.title", "Add Parameter"))
461        {
462            public void actionPerformed(ActionEvent e) {
463                addParameter(e);
464            }
465        };
466
467        addDimension = new AbstractAction(
468            getResourceConverter().getString(
469                "schemaExplorer.addDimension.title", "Add Dimension"))
470        {
471            public void actionPerformed(ActionEvent e) {
472                addDimension(e);
473            }
474        };
475        addDimensionUsage = new AbstractAction(
476            getResourceConverter().getString(
477                "schemaExplorer.addDimensionUsage.title",
478                "Add Dimension Usage"))
479        {
480            public void actionPerformed(ActionEvent e) {
481                addDimensionUsage(e);
482            }
483        };
484        addHierarchy = new AbstractAction(
485            getResourceConverter().getString(
486                "schemaExplorer.addHierarchy.title", "Add Hierarchy"))
487        {
488            public void actionPerformed(ActionEvent e) {
489                addHierarchy(e);
490            }
491        };
492        addNamedSet = new AbstractAction(
493            getResourceConverter().getString(
494                "schemaExplorer.addNamedSet.title", "Add Named Set"))
495        {
496            public void actionPerformed(ActionEvent e) {
497                addNamedSet(e);
498            }
499        };
500        addMeasure = new AbstractAction(
501            getResourceConverter().getString(
502                "schemaExplorer.addMeasure.title", "Add Measure"))
503        {
504            public void actionPerformed(ActionEvent e) {
505                addMeasure(e);
506            }
507        };
508        addCalculatedMember = new AbstractAction(
509            getResourceConverter().getString(
510                "schemaExplorer.addCalculatedMember.title",
511                "Add Calculated Member"))
512        {
513            public void actionPerformed(ActionEvent e) {
514                addCalculatedMember(e);
515            }
516        };
517        addUserDefinedFunction = new AbstractAction(
518            getResourceConverter().getString(
519                "schemaExplorer.addUserDefinedFunction.title",
520                "Add User Defined Function"))
521        {
522            public void actionPerformed(ActionEvent e) {
523                addUserDefinedFunction(e);
524            }
525        };
526        addScript = new AbstractAction(
527            getResourceConverter().getString(
528                "schemaExplorer.addScript.title",
529                "Add Script"))
530        {
531            public void actionPerformed(ActionEvent e) {
532                addScript(e);
533            }
534        };
535        addCellFormatter = new AbstractAction(
536            getResourceConverter().getString(
537                "schemaExplorer.addCellFormatter.title",
538                "Add Cell Formatter"))
539        {
540            public void actionPerformed(ActionEvent e) {
541                addCellFormatter(e);
542            }
543        };
544        addPropertyFormatter = new AbstractAction(
545            getResourceConverter().getString(
546                "schemaExplorer.addPropertyFormatter.title",
547                "Add Property Formatter"))
548        {
549            public void actionPerformed(ActionEvent e) {
550                addPropertyFormatter(e);
551            }
552        };
553        addMemberFormatter = new AbstractAction(
554            getResourceConverter().getString(
555                "schemaExplorer.addMemberFormatter.title",
556                "Add Member Formatter"))
557        {
558            public void actionPerformed(ActionEvent e) {
559                addMemberFormatter(e);
560            }
561        };
562        addRole = new AbstractAction(
563            getResourceConverter().getString(
564                "schemaExplorer.addRole.title", "Add Role"))
565        {
566            public void actionPerformed(ActionEvent e) {
567                addRole(e);
568            }
569        };
570        addSchemaGrant = new AbstractAction(
571            getResourceConverter().getString(
572                "schemaExplorer.addSchemaGrant.title", "Add Schema Grant"))
573        {
574            public void actionPerformed(ActionEvent e) {
575                addSchemaGrant(e);
576            }
577        };
578        addCubeGrant = new AbstractAction(
579            getResourceConverter().getString(
580                "schemaExplorer.addCubeGrant.title", "Add Cube Grant"))
581        {
582            public void actionPerformed(ActionEvent e) {
583                addCubeGrant(e);
584            }
585        };
586        addDimensionGrant = new AbstractAction(
587            getResourceConverter().getString(
588                "schemaExplorer.addDimensionGrant.title",
589                "Add Dimension Grant"))
590        {
591            public void actionPerformed(ActionEvent e) {
592                addDimensionGrant(e);
593            }
594        };
595        addHierarchyGrant = new AbstractAction(
596            getResourceConverter().getString(
597                "schemaExplorer.addHierarchyGrant.title",
598                "Add Hierarchy Grant"))
599        {
600            public void actionPerformed(ActionEvent e) {
601                addHierarchyGrant(e);
602            }
603        };
604        addMemberGrant = new AbstractAction(
605            getResourceConverter().getString(
606                "schemaExplorer.addMemberGrant.title", "Add Member Grant"))
607        {
608            public void actionPerformed(ActionEvent e) {
609                addMemberGrant(e);
610            }
611        };
612        addAnnotations = new AbstractAction(
613            getResourceConverter().getString(
614                "schemaExplorer.addAnnotations.title", "Add Annotations"))
615        {
616            public void actionPerformed(ActionEvent e) {
617                addAnnotations(e);
618            }
619        };
620        addAnnotation = new AbstractAction(
621            getResourceConverter().getString(
622                "schemaExplorer.addAnnotation.title", "Add Annotation"))
623        {
624            public void actionPerformed(ActionEvent e) {
625                addAnnotation(e);
626            }
627        };
628
629        addLevel = new AbstractAction(
630            getResourceConverter().getString(
631                "schemaExplorer.addLevel.title", "Add Level"))
632        {
633            public void actionPerformed(ActionEvent e) {
634                addLevel(e);
635            }
636        };
637        addClosure = new AbstractAction(
638            getResourceConverter().getString(
639                "schemaExplorer.addClosure.title", "Add Closure"))
640        {
641            public void actionPerformed(ActionEvent e) {
642                addClosure(e);
643            }
644        };
645        addKeyExp = new AbstractAction(
646            getResourceConverter().getString(
647                "schemaExplorer.addKeyExpression.title", "Add Key Expression"))
648        {
649            public void actionPerformed(ActionEvent e) {
650                addKeyExp(e);
651            }
652        };
653        addNameExp = new AbstractAction(
654            getResourceConverter().getString(
655                "schemaExplorer.addNameExpression.title",
656                "Add Name Expression"))
657        {
658            public void actionPerformed(ActionEvent e) {
659                addNameExp(e);
660            }
661        };
662        addOrdinalExp = new AbstractAction(
663            getResourceConverter().getString(
664                "schemaExplorer.addOrdinalExpression.title",
665                "Add Ordinal Expression"))
666        {
667            public void actionPerformed(ActionEvent e) {
668                addOrdinalExp(e);
669            }
670        };
671        addCaptionExp = new AbstractAction(
672            getResourceConverter().getString(
673                "schemaExplorer.addCaptionExpression.title",
674                "Add Caption Expression"))
675        {
676            public void actionPerformed(ActionEvent e) {
677                addCaptionExp(e);
678            }
679        };
680        addParentExp = new AbstractAction(
681            getResourceConverter().getString(
682                "schemaExplorer.addParentExpression.title",
683                "Add Parent Expression"))
684        {
685            public void actionPerformed(ActionEvent e) {
686                addParentExp(e);
687            }
688        };
689        addMeasureExp = new AbstractAction(
690            getResourceConverter().getString(
691                "schemaExplorer.addMeasureExpression.title",
692                "Add Measure Expression"))
693        {
694            public void actionPerformed(ActionEvent e) {
695                addMeasureExp(e);
696            }
697        };
698        addFormula = new AbstractAction(
699            getResourceConverter().getString(
700                "schemaExplorer.addFormula.title", "Add Formula"))
701        {
702            public void actionPerformed(ActionEvent e) {
703                addFormula(e);
704            }
705        };
706        addSQL = new AbstractAction(
707            getResourceConverter().getString(
708                "schemaExplorer.addSQL.title", "Add SQL"))
709        {
710            public void actionPerformed(ActionEvent e) {
711                addSQL(e);
712            }
713        };
714        addTable = new AbstractAction(
715            getResourceConverter().getString(
716                "schemaExplorer.addTable.title", "Add Table"))
717        {
718            public void actionPerformed(ActionEvent e) {
719                addTable(e);
720            }
721        };
722        addJoin = new AbstractAction(
723            getResourceConverter().getString(
724                "schemaExplorer.addJoin.title", "Add Join"))
725        {
726            public void actionPerformed(ActionEvent e) {
727                addJoin(e);
728            }
729        };
730        addView = new AbstractAction(
731            getResourceConverter().getString(
732                "schemaExplorer.addView.title", "Add View"))
733        {
734            public void actionPerformed(ActionEvent e) {
735                addView(e);
736            }
737        };
738        addInlineTable = new AbstractAction(
739            getResourceConverter().getString(
740                "schemaExplorer.addInlineTable.title", "Add Inline Table"))
741        {
742            public void actionPerformed(ActionEvent e) {
743                addInlineTable(e);
744            }
745        };
746
747
748        moveLevelUp = new AbstractAction(
749            getResourceConverter().getString(
750                "schemaExplorer.moveLevelUp.title", "Move Up"))
751        {
752            public void actionPerformed(ActionEvent e) {
753                moveLevelUp(e);
754            }
755        };
756
757        moveLevelDown = new AbstractAction(
758            getResourceConverter().getString(
759                "schemaExplorer.moveLevelDown.title", "Move Down"))
760        {
761            public void actionPerformed(ActionEvent e) {
762                moveLevelDown(e);
763            }
764        };
765
766
767        addProperty = new AbstractAction(
768            getResourceConverter().getString(
769                "schemaExplorer.addProperty.title", "Add Property"))
770        {
771            public void actionPerformed(ActionEvent e) {
772                addProperty(e);
773            }
774        };
775
776        addCalculatedMemberProperty = new AbstractAction(
777            getResourceConverter().getString(
778                "schemaExplorer.addCalculatedMemberProperty.title",
779                "Add Calculated Member Property"))
780        {
781            public void actionPerformed(ActionEvent e) {
782                addCalculatedMemberProperty(e);
783            }
784        };
785
786        addVirtualCube = new AbstractAction(
787            getResourceConverter().getString(
788                "schemaExplorer.addVirtualCube.title", "Add Virtual Cube"))
789        {
790            public void actionPerformed(ActionEvent e) {
791                addVirtualCube(e);
792            }
793        };
794        addVirtualCubeDimension = new AbstractAction(
795            getResourceConverter().getString(
796                "schemaExplorer.addVirtualCubeDimension.title",
797                "Add Virtual Cube Dimension"))
798        {
799            public void actionPerformed(ActionEvent e) {
800                addVirtualCubeDimension(e);
801            }
802        };
803        addVirtualCubeMeasure = new AbstractAction(
804            getResourceConverter().getString(
805                "schemaExplorer.addVirtualCubeMeasure.title",
806                "Add Virtual Cube Measure"))
807        {
808            public void actionPerformed(ActionEvent e) {
809                addVirtualCubeMeasure(e);
810            }
811        };
812
813        addAggPattern = new AbstractAction(
814            getResourceConverter().getString(
815                "schemaExplorer.addAggregatePattern.title",
816                "Add Aggregate Pattern"))
817        {
818            public void actionPerformed(ActionEvent e) {
819                addAggPattern(e);
820            }
821        };
822        addAggExclude = new AbstractAction(
823            getResourceConverter().getString(
824                "schemaExplorer.addAggregateExcludeTable.title",
825                "Add Aggregate Exclude Table"))
826        {
827            public void actionPerformed(ActionEvent e) {
828                addAggExclude(e);
829            }
830        };
831        addAggName = new AbstractAction(
832            getResourceConverter().getString(
833                "schemaExplorer.addAggregateName.title", "Add Aggregate Name"))
834        {
835            public void actionPerformed(ActionEvent e) {
836                addAggName(e);
837            }
838        };
839        addAggIgnoreColumn = new AbstractAction(
840            getResourceConverter().getString(
841                "schemaExplorer.addAggregateIgnoreColumn.title",
842                "Add Aggregate Ignore Column"))
843        {
844            public void actionPerformed(ActionEvent e) {
845                addAggIgnoreColumn(e);
846            }
847        };
848        addAggForeignKey = new AbstractAction(
849            getResourceConverter().getString(
850                "schemaExplorer.addAggregateForeignKey.title",
851                "Add Aggregate Foreign Key"))
852        {
853            public void actionPerformed(ActionEvent e) {
854                addAggForeignKey(e);
855            }
856        };
857        addAggMeasure = new AbstractAction(
858            getResourceConverter().getString(
859                "schemaExplorer.addAggregateMeasure.title",
860                "Add Aggregate Measure"))
861        {
862            public void actionPerformed(ActionEvent e) {
863                addAggMeasure(e);
864            }
865        };
866        addAggLevel = new AbstractAction(
867            getResourceConverter().getString(
868                "schemaExplorer.addAggregateLevel.title",
869                "Add Aggregate Level"))
870        {
871            public void actionPerformed(ActionEvent e) {
872                addAggLevel(e);
873            }
874        };
875        addAggFactCount = new AbstractAction(
876            getResourceConverter().getString(
877                "schemaExplorer.addAggregateFactCount.title",
878                "Add Aggregate Fact Count"))
879        {
880            public void actionPerformed(ActionEvent e) {
881                addAggFactCount(e);
882            }
883        };
884
885        delete = new AbstractAction(
886            getResourceConverter().getString(
887                "schemaExplorer.actionDelete.title", "Delete"))
888        {
889            public void actionPerformed(ActionEvent e) {
890                delete(e);
891            }
892        };
893
894        editMode = new AbstractAction(
895            getResourceConverter().getString(
896                "schemaExplorer.actionEdit.title", "EditMode"))
897        {
898            public void actionPerformed(ActionEvent e) {
899                editMode(e);
900            }
901        };
902
903        //========================================================
904        // toolbar buttons
905        //========================================================
906        addCubeButton.setIcon(
907            new ImageIcon(
908                myClassLoader.getResource(
909                    getResourceConverter().getGUIReference("addCube"))));
910        addCubeButton.setToolTipText(
911            getResourceConverter().getString(
912                "schemaExplorer.addCube.title", "Add cube"));
913        addCubeButton.addActionListener(addCube);
914
915        addDimensionButton.setIcon(
916            new ImageIcon(
917                myClassLoader.getResource(
918                    getResourceConverter().getGUIReference("addDimension"))));
919        addDimensionButton.setToolTipText(
920            getResourceConverter().getString(
921                "schemaExplorer.addDimension.title", "Add Dimension"));
922        addDimensionButton.addActionListener(addDimension);
923
924        addDimensionUsageButton.setIcon(
925            new ImageIcon(
926                myClassLoader.getResource(
927                    getResourceConverter().getGUIReference(
928                        "addDimensionUsage"))));
929        addDimensionUsageButton.setToolTipText(
930            getResourceConverter().getString(
931                "schemaExplorer.addDimensionUsage.title",
932                "Add Dimension Usage"));
933        addDimensionUsageButton.addActionListener(addDimensionUsage);
934
935        addHierarchyButton.setIcon(
936            new ImageIcon(
937                myClassLoader.getResource(
938                    getResourceConverter().getGUIReference("addHierarchy"))));
939        addHierarchyButton.setToolTipText(
940            getResourceConverter().getString(
941                "schemaExplorer.addHierarchy.title", "Add Hierarchy"));
942        addHierarchyButton.addActionListener(addHierarchy);
943
944        addNamedSetButton.setIcon(
945            new ImageIcon(
946                myClassLoader.getResource(
947                    getResourceConverter().getGUIReference("addNamedSet"))));
948        addNamedSetButton.setToolTipText(
949            getResourceConverter().getString(
950                "schemaExplorer.addNamedSet.title", "Add Named Set"));
951        addNamedSetButton.addActionListener(addNamedSet);
952
953        addUserDefinedFunctionButton.setIcon(
954            new ImageIcon(
955                myClassLoader.getResource(
956                    getResourceConverter().getGUIReference(
957                        "addUserDefinedFunction"))));
958        addUserDefinedFunctionButton.setToolTipText(
959            getResourceConverter().getString(
960                "schemaExplorer.addUserDefinedFunction.title",
961                "Add User defined Function"));
962        addUserDefinedFunctionButton.addActionListener(addUserDefinedFunction);
963
964        addCalculatedMemberButton.setIcon(
965            new ImageIcon(
966                myClassLoader.getResource(
967                    getResourceConverter().getGUIReference(
968                        "addCalculatedMember"))));
969        addCalculatedMemberButton.setToolTipText(
970            getResourceConverter().getString(
971                "schemaExplorer.addCalculatedMember.title",
972                "Add Calculated Member"));
973        addCalculatedMemberButton.addActionListener(addCalculatedMember);
974
975        addMeasureButton.setIcon(
976            new ImageIcon(
977                myClassLoader.getResource(
978                    getResourceConverter().getGUIReference("addMeasure"))));
979        addMeasureButton.setToolTipText(
980            getResourceConverter().getString(
981                "schemaExplorer.addMeasure.title", "Add Measure"));
982        addMeasureButton.addActionListener(addMeasure);
983
984        addLevelButton.setIcon(
985            new ImageIcon(
986                myClassLoader.getResource(
987                    getResourceConverter().getGUIReference("addLevel"))));
988        addLevelButton.setToolTipText(
989            getResourceConverter().getString(
990                "schemaExplorer.addLevel.title", "Add Level"));
991        addLevelButton.addActionListener(addLevel);
992
993        addPropertyButton.setIcon(
994            new ImageIcon(
995                myClassLoader.getResource(
996                    getResourceConverter().getGUIReference("addProperty"))));
997        addPropertyButton.setToolTipText(
998            getResourceConverter().getString(
999                "schemaExplorer.addProperty.title", "Add Property"));
1000        addPropertyButton.addActionListener(addProperty);
1001
1002        addCalculatedMemberPropertyButton.setIcon(
1003            new ImageIcon(
1004                myClassLoader.getResource(
1005                    getResourceConverter().getGUIReference(
1006                        "addCalculatedMemberProperty"))));
1007        addCalculatedMemberPropertyButton.setToolTipText(
1008            getResourceConverter().getString(
1009                "schemaExplorer.addCalculatedMemberProperty.title",
1010                "Add Calculated Member Property"));
1011        addCalculatedMemberPropertyButton.addActionListener(
1012            addCalculatedMemberProperty);
1013
1014        addVirtualCubeButton.setIcon(
1015            new ImageIcon(
1016                myClassLoader.getResource(
1017                    getResourceConverter().getGUIReference("addVirtualCube"))));
1018        addVirtualCubeButton.setToolTipText(
1019            getResourceConverter().getString(
1020                "schemaExplorer.addVirtualCube.title", "Add Virtual Cube"));
1021        addVirtualCubeButton.addActionListener(addVirtualCube);
1022
1023        addVirtualCubeDimensionButton.setIcon(
1024            new ImageIcon(
1025                myClassLoader.getResource(
1026                    getResourceConverter().getGUIReference(
1027                        "addVirtualCubeDimension"))));
1028        addVirtualCubeDimensionButton.setToolTipText(
1029            getResourceConverter().getString(
1030                "schemaExplorer.addVirtualCubeDimension.title",
1031                "Add Virtual Dimension"));
1032        addVirtualCubeDimensionButton
1033            .addActionListener(addVirtualCubeDimension);
1034
1035        addVirtualCubeMeasureButton.setIcon(
1036            new ImageIcon(
1037                myClassLoader.getResource(
1038                    getResourceConverter().getGUIReference(
1039                        "addVirtualCubeMeasure"))));
1040        addVirtualCubeMeasureButton.setToolTipText(
1041            getResourceConverter().getString(
1042                "schemaExplorer.addVirtualCubeMeasure.title",
1043                "Add Virtual Measure"));
1044        addVirtualCubeMeasureButton.addActionListener(addVirtualCubeMeasure);
1045
1046        addRoleButton.setIcon(
1047            new ImageIcon(
1048                myClassLoader.getResource(
1049                    getResourceConverter().getGUIReference("addRole"))));
1050        addRoleButton.setToolTipText(
1051            getResourceConverter().getString(
1052                "schemaExplorer.addRole.title", "Add Role"));
1053        addRoleButton.addActionListener(addRole);
1054
1055        cutButton.setIcon(
1056            new javax.swing.ImageIcon(
1057                getClass().getResource(
1058                    getResourceConverter().getGUIReference("cut"))));
1059        cutButton.setText("");
1060        cutButton.setToolTipText(
1061            getResourceConverter().getString(
1062                "schemaExplorer.actionCut.title", "Cut"));
1063
1064        copyButton.setIcon(
1065            new javax.swing.ImageIcon(
1066                getClass().getResource(
1067                    getResourceConverter().getGUIReference("copy"))));
1068        copyButton.setText("");
1069        copyButton.setToolTipText(
1070            getResourceConverter().getString(
1071                "schemaExplorer.actionCopy.title", "Copy"));
1072
1073        pasteButton.setIcon(
1074            new javax.swing.ImageIcon(
1075                getClass().getResource(
1076                    getResourceConverter().getGUIReference("paste"))));
1077        pasteButton.setText("");
1078        pasteButton.setToolTipText(
1079            getResourceConverter().getString(
1080                "schemaExplorer.actionPaste.title", "Paste"));
1081
1082        deleteButton.setIcon(
1083            new javax.swing.ImageIcon(
1084                getClass().getResource(
1085                    getResourceConverter().getGUIReference("delete"))));
1086        deleteButton.setToolTipText(
1087            getResourceConverter().getString(
1088                "schemaExplorer.actionDelete.title", "Delete"));
1089        deleteButton.addActionListener(delete);
1090
1091        editModeButton.setIcon(
1092            new javax.swing.ImageIcon(
1093                getClass().getResource(
1094                    getResourceConverter().getGUIReference("edit"))));
1095        editModeButton.setToolTipText(
1096            getResourceConverter().getString(
1097                "schemaExplorer.actionEdit.title", "Edit Mode"));
1098        editModeButton.addActionListener(editMode);
1099
1100        databaseLabel.setIcon(
1101            new javax.swing.ImageIcon(
1102                getClass().getResource(
1103                    getResourceConverter().getGUIReference("database"))));
1104
1105
1106        jToolBar1.add(addCubeButton);
1107        jToolBar1.add(addDimensionButton);
1108        jToolBar1.add(addDimensionUsageButton);
1109        jToolBar1.add(addHierarchyButton);
1110        jToolBar1.add(addNamedSetButton);
1111        jToolBar1.add(addUserDefinedFunctionButton);
1112        jToolBar1.add(addCalculatedMemberButton);
1113        jToolBar1.add(addMeasureButton);
1114        jToolBar1.add(addLevelButton);
1115        jToolBar1.add(addPropertyButton);
1116        jToolBar1.add(addCalculatedMemberPropertyButton);
1117        jToolBar1.addSeparator();
1118        jToolBar1.add(addVirtualCubeButton);
1119        jToolBar1.add(addVirtualCubeDimensionButton);
1120        jToolBar1.add(addVirtualCubeMeasureButton);
1121        jToolBar1.addSeparator();
1122        jToolBar1.add(addRoleButton);
1123        jToolBar1.addSeparator();
1124
1125        jToolBar1.add(cutButton);
1126        jToolBar1.add(copyButton);
1127        jToolBar1.add(pasteButton);
1128        jToolBar1.addSeparator();
1129        jToolBar1.add(deleteButton);
1130        jToolBar1.addSeparator();
1131        jToolBar1.add(editModeButton);
1132
1133        //========================================================
1134        // popup menu
1135        //========================================================
1136        jPopupMenu = new CustomJPopupMenu();
1137
1138        //========================================================
1139        // tree mouse listener
1140        //========================================================
1141        tree.addMouseListener(new PopupTrigger());
1142        tree.addKeyListener(
1143            new KeyAdapter() {
1144                public void keyPressed(KeyEvent e) {
1145                    /*
1146                    keytext=Delete
1147                    keycode=127
1148                    keytext=NumPad .
1149                    keycode=110
1150                     */
1151                    int kcode = e.getKeyCode();
1152                    if (kcode == 127 || kcode == 110) {
1153                        delete(e);
1154                    }
1155                }
1156            });
1157
1158
1159        // add footer for connected database
1160        footer.setLayout(new java.awt.BorderLayout());
1161        footer.add(databaseLabel, java.awt.BorderLayout.CENTER);
1162
1163        //========================================================
1164        // jpanel
1165        //========================================================
1166        this.add(jSplitPane1, java.awt.BorderLayout.CENTER);
1167        this.add(jToolBar1, java.awt.BorderLayout.NORTH);
1168        this.add(footer, java.awt.BorderLayout.SOUTH);
1169
1170        updater = new JTreeUpdater(tree);
1171    }
1172
1173    protected void arrowButtonUpAction(ActionEvent evt) {
1174        TreePath tpath = tree.getSelectionPath();
1175        if (tpath != null) {
1176            TreePath parentpath = tpath.getParentPath();
1177            if (parentpath != null) {
1178                tree.setSelectionPath(parentpath);
1179                refreshTree(parentpath);
1180            }
1181        }
1182    }
1183
1184    protected void arrowButtonDownAction(ActionEvent evt) {
1185        TreePath tpath = tree.getSelectionPath();
1186        if (tpath != null) {
1187            Object current = tpath.getLastPathComponent();
1188            Object child = tree.getModel().getChild(current, 0);
1189            if (child != null) {
1190                Object[] treeObjs = new Object[30];
1191                treeObjs[0] = child;
1192                treeObjs[1] = current;
1193                // traverse upward through tree, saving parent nodes
1194                TreePath parentpath;
1195                parentpath = tpath.getParentPath();
1196                int objCnt = 2;
1197                while (parentpath != null) {
1198                    Object po = parentpath.getLastPathComponent();
1199                    treeObjs[objCnt] = po;
1200                    objCnt += 1;
1201                    parentpath = parentpath.getParentPath();
1202                }
1203                // reverse the array so that schema is first, then the children
1204                Object[] nodes = new Object[objCnt];
1205                int loopCnt = objCnt - 1;
1206                for (int j = 0; j < objCnt; j++) {
1207                    nodes[j] = treeObjs[loopCnt];
1208                    loopCnt--;
1209                }
1210                TreePath childPath = new TreePath(nodes);
1211                tree.setSelectionPath(childPath);
1212                refreshTree(childPath);
1213            }
1214        }
1215    }
1216
1217    /**
1218     * Several methods are called, e.g. editCellAt,  to get the focus set in the
1219     * value column of the specified row.  The attribute column has the
1220     * parameter name and should not receive focus.
1221     */
1222    protected void setTableCellFocus(int row) {
1223        propertyTable.editCellAt(row, 1);
1224        TableCellEditor editor = propertyTable.getCellEditor(row, 1);
1225        Component comp = editor.getTableCellEditorComponent(
1226            propertyTable, propertyTable.getValueAt(row, 1), true, row, 1);
1227    }
1228
1229    /**
1230     * @param evt
1231     */
1232    protected void addCube(ActionEvent evt) {
1233        MondrianGuiDef.Schema schema =
1234            (MondrianGuiDef.Schema) tree.getModel().getRoot();
1235        MondrianGuiDef.Cube cube = new MondrianGuiDef.Cube();
1236
1237        cube.name = "";
1238
1239        cube.dimensions = new MondrianGuiDef.Dimension[0];
1240        cube.measures = new MondrianGuiDef.Measure[0];
1241
1242        /*
1243         * Don't default the table
1244         *
1245        MondrianGuiDef.Table cfact = new MondrianGuiDef.Table("","Table","");
1246        cfact.aggExcludes = new MondrianGuiDef.AggExclude[0];
1247        cfact.aggTables = new MondrianGuiDef.AggTable[0];
1248        cube.fact = cfact;
1249        */
1250
1251        cube.calculatedMembers = new MondrianGuiDef.CalculatedMember[0];
1252        cube.namedSets = new MondrianGuiDef.NamedSet[0];
1253
1254        cube.name =
1255            getNewName(
1256                getResourceConverter().getString(
1257                    "schemaExplorer.newCube.title",
1258                    "New Cube"),
1259                schema.cubes);
1260        cube.cache = Boolean.TRUE;
1261        cube.enabled = Boolean.TRUE;
1262        cube.visible = Boolean.TRUE;
1263        NodeDef[] temp = schema.cubes;
1264        schema.cubes = new MondrianGuiDef.Cube[temp.length + 1];
1265        for (int _i = 0; _i < temp.length; _i++) {
1266            schema.cubes[_i] = (MondrianGuiDef.Cube) temp[_i];
1267        }
1268        schema.cubes[schema.cubes.length - 1] = cube;
1269
1270        tree.setSelectionPath(
1271            (new TreePath(model.getRoot())).pathByAddingChild(
1272                cube));
1273        refreshTree(tree.getSelectionPath());
1274        setTableCellFocus(0);
1275    }
1276
1277    protected void addParameter(ActionEvent evt) {
1278        MondrianGuiDef.Schema schema =
1279            (MondrianGuiDef.Schema) tree.getModel().getRoot();
1280        MondrianGuiDef.Parameter parameter = new MondrianGuiDef.Parameter();
1281
1282        parameter.name = "";
1283
1284        //set the required fields
1285        parameter.name =
1286            getNewName(
1287                getResourceConverter().getString(
1288                    "schemaExplorer.newParameter.title", "New Parameter"),
1289                schema.parameters);
1290        // set the default values
1291        parameter.type = "String";
1292        parameter.modifiable = Boolean.TRUE;
1293
1294        NodeDef[] temp = schema.parameters;
1295        schema.parameters = new MondrianGuiDef.Parameter[temp.length + 1];
1296        for (int _i = 0; _i < temp.length; _i++) {
1297            schema.parameters[_i] = (MondrianGuiDef.Parameter) temp[_i];
1298        }
1299        schema.parameters[schema.parameters.length - 1] = parameter;
1300
1301        tree.setSelectionPath(
1302            (new TreePath(model.getRoot())).pathByAddingChild(
1303                parameter));
1304        refreshTree(tree.getSelectionPath());
1305        setTableCellFocus(0);
1306    }
1307
1308    protected void addRole(ActionEvent evt) {
1309        MondrianGuiDef.Schema schema =
1310            (MondrianGuiDef.Schema) tree.getModel().getRoot();
1311        MondrianGuiDef.Role role = new MondrianGuiDef.Role();
1312
1313        role.name = "";
1314
1315        role.schemaGrants = new MondrianGuiDef.SchemaGrant[0];
1316
1317        //add cube to schema
1318        role.name =
1319            getNewName(
1320                getResourceConverter().getString(
1321                    "schemaExplorer.newRole.title", "New Role"),
1322                schema.roles);
1323        NodeDef[] temp = schema.roles;
1324        schema.roles = new MondrianGuiDef.Role[temp.length + 1];
1325        for (int _i = 0; _i < temp.length; _i++) {
1326            schema.roles[_i] = (MondrianGuiDef.Role) temp[_i];
1327        }
1328        schema.roles[schema.roles.length - 1] = role;
1329
1330        tree.setSelectionPath(
1331            (new TreePath(model.getRoot())).pathByAddingChild(
1332                role));
1333        refreshTree(tree.getSelectionPath());
1334        setTableCellFocus(0);
1335    }
1336
1337    protected void addVirtualCube(ActionEvent evt) {
1338        MondrianGuiDef.Schema schema =
1339            (MondrianGuiDef.Schema) tree.getModel().getRoot();
1340        MondrianGuiDef.VirtualCube cube = new MondrianGuiDef.VirtualCube();
1341
1342        cube.name = "";
1343        cube.dimensions = new MondrianGuiDef.VirtualCubeDimension[0];
1344        cube.measures = new MondrianGuiDef.VirtualCubeMeasure[0];
1345        cube.calculatedMembers = new MondrianGuiDef.CalculatedMember[0];
1346        cube.enabled = Boolean.TRUE;
1347
1348        //add cube to schema
1349        cube.name =
1350            getNewName(
1351                getResourceConverter().getString(
1352                    "schemaExplorer.newVirtualCube.title",
1353                    "New Virtual Cube"),
1354                schema.virtualCubes);
1355        NodeDef[] temp = schema.virtualCubes;
1356        schema.virtualCubes = new MondrianGuiDef.VirtualCube[temp.length + 1];
1357        for (int i = 0; i < temp.length; i++) {
1358            schema.virtualCubes[i] = (MondrianGuiDef.VirtualCube) temp[i];
1359        }
1360        schema.virtualCubes[schema.virtualCubes.length - 1] = cube;
1361
1362        tree.setSelectionPath(
1363            new TreePath(model.getRoot()).pathByAddingChild(
1364                cube));
1365        refreshTree(tree.getSelectionPath());
1366        setTableCellFocus(0);
1367    }
1368
1369    protected void addUserDefinedFunction(ActionEvent evt) {
1370        MondrianGuiDef.Schema schema =
1371            (MondrianGuiDef.Schema) tree.getModel().getRoot();
1372        MondrianGuiDef.UserDefinedFunction udf =
1373            new MondrianGuiDef.UserDefinedFunction();
1374        udf.name = "";
1375        udf.name =
1376            getNewName(
1377                getResourceConverter().getString(
1378                    "schemaExplorer.newUserDefinedFunction.title",
1379                    "New User defined Function"),
1380                schema.userDefinedFunctions);
1381        NodeDef[] temp = schema.userDefinedFunctions;
1382        schema.userDefinedFunctions =
1383            new MondrianGuiDef.UserDefinedFunction[temp.length + 1];
1384        for (int _i = 0; _i < temp.length; _i++) {
1385            schema.userDefinedFunctions[_i] =
1386                (MondrianGuiDef.UserDefinedFunction) temp[_i];
1387        }
1388        schema.userDefinedFunctions[schema.userDefinedFunctions.length - 1] =
1389            udf;
1390        tree.setSelectionPath(
1391            new TreePath(model.getRoot()).pathByAddingChild(
1392                udf));
1393        refreshTree(tree.getSelectionPath());
1394        setTableCellFocus(0);
1395    }
1396
1397    /**
1398     * Updates the tree display after an Add / Delete operation.
1399     */
1400    private void refreshTree(TreePath path) {
1401        setDirty(true);
1402        if (!dirtyFlag) {
1403            setDirtyFlag(true);   // dirty indication shown on title
1404            setTitle();
1405        }
1406        updater.update();
1407        tree.scrollPathToVisible(path);
1408    }
1409
1410    /**
1411     * @param evt
1412     */
1413    protected void addMeasure(ActionEvent evt) {
1414        TreePath tpath = null;
1415        Object path = null;
1416        if (evt.getSource() instanceof Component
1417            && ((Component)evt.getSource())
1418                .getParent() instanceof CustomJPopupMenu)
1419        {
1420            tpath = ((CustomJPopupMenu)((Component)evt.getSource())
1421                    .getParent()).getPath();
1422        } else {
1423            tpath = tree.getSelectionPath();
1424        }
1425        int parentIndex = -1;
1426        if (tpath != null) {
1427            for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0;
1428                parentIndex--)
1429            {
1430                final Object p = tpath.getPathComponent(parentIndex);
1431                if (p instanceof MondrianGuiDef.Cube) {
1432                    path = p;
1433                    break;
1434                }
1435            }
1436        }
1437        //Object path = tree.getSelectionPath().getLastPathComponent();
1438        if (!(path instanceof MondrianGuiDef.Cube)) {
1439            JOptionPane.showMessageDialog(
1440                this,
1441                getResourceConverter().getString(
1442                    "schemaExplorer.cubeNotSelected.alert",
1443                    "Cube not selected."),
1444                alert,
1445                JOptionPane.WARNING_MESSAGE);
1446            return;
1447        }
1448
1449        MondrianGuiDef.Cube cube = (MondrianGuiDef.Cube) path;
1450        MondrianGuiDef.Measure measure = new MondrianGuiDef.Measure();
1451        measure.name = "";
1452        measure.name =
1453            getNewName(
1454                getResourceConverter().getString(
1455                    "schemaExplorer.newMeasure.title",
1456                    "New Measure"),
1457                cube.measures);
1458        measure.visible = Boolean.TRUE;
1459        measure.aggregator = "distinct-count";
1460        NodeDef[] temp = cube.measures;
1461        cube.measures = new MondrianGuiDef.Measure[temp.length + 1];
1462        for (int i = 0; i < temp.length; i++) {
1463            cube.measures[i] = (MondrianGuiDef.Measure) temp[i];
1464        }
1465
1466        cube.measures[cube.measures.length - 1] = measure;
1467
1468        Object[] parentPathObjs = new Object[parentIndex + 1];
1469        for (int i = 0; i <= parentIndex; i++) {
1470            parentPathObjs[i] = tpath.getPathComponent(i);
1471        }
1472        TreePath parentPath = new TreePath(parentPathObjs);
1473        tree.setSelectionPath(parentPath.pathByAddingChild(measure));
1474
1475        refreshTree(tree.getSelectionPath());
1476        setTableCellFocus(0);
1477    }
1478
1479    protected void addAggPattern(ActionEvent evt) {
1480        TreePath tpath = null;
1481        Object path = null;
1482        if (evt.getSource() instanceof Component
1483            && ((Component)evt.getSource())
1484                .getParent() instanceof CustomJPopupMenu)
1485        {
1486            tpath = ((CustomJPopupMenu)((Component)evt.getSource())
1487                    .getParent()).getPath();
1488        } else {
1489            tpath = tree.getSelectionPath();
1490        }
1491        int parentIndex = -1;
1492        if (tpath != null) {
1493            for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0;
1494                parentIndex--)
1495            {
1496                final Object p = tpath.getPathComponent(parentIndex);
1497                if (p instanceof MondrianGuiDef.Table) {
1498                    if (((parentIndex - 1) >= 0)
1499                        && (tpath.getPathComponent(parentIndex - 1)
1500                        instanceof MondrianGuiDef.Cube))
1501                    {
1502                        path = p;
1503                        break;
1504                    }
1505                }
1506            }
1507        }
1508        //Object path = tree.getSelectionPath().getLastPathComponent();
1509        if (!(path instanceof MondrianGuiDef.Table)) {
1510            JOptionPane.showMessageDialog(
1511                this,
1512                getResourceConverter().getString(
1513                    "schemaExplorer.cubeFactTableNotSelected.alert",
1514                    "Cube Fact Table not selected."),
1515                alert,
1516                JOptionPane.WARNING_MESSAGE);
1517            return;
1518        }
1519
1520
1521        MondrianGuiDef.Table factTable = (MondrianGuiDef.Table) path;
1522
1523        MondrianGuiDef.AggPattern aggname = new MondrianGuiDef.AggPattern();
1524        aggname.pattern = "";
1525
1526        //add cube to schema
1527        aggname.ignorecase = Boolean.TRUE;
1528        aggname.factcount = null;
1529        aggname.ignoreColumns = new MondrianGuiDef.AggIgnoreColumn[0];
1530        aggname.foreignKeys = new MondrianGuiDef.AggForeignKey[0];
1531        aggname.measures = new MondrianGuiDef.AggMeasure[0];
1532        aggname.levels = new MondrianGuiDef.AggLevel[0];
1533        aggname.excludes = new MondrianGuiDef.AggExclude[0];
1534
1535        NodeDef[] temp = factTable.aggTables;
1536        factTable.aggTables = new MondrianGuiDef.AggTable[temp.length + 1];
1537        for (int i = 0; i < temp.length; i++) {
1538            factTable.aggTables[i] = (MondrianGuiDef.AggTable) temp[i];
1539        }
1540
1541        factTable.aggTables[factTable.aggTables.length - 1] = aggname;
1542
1543        Object[] parentPathObjs = new Object[parentIndex + 1];
1544        for (int i = 0; i <= parentIndex; i++) {
1545            parentPathObjs[i] = tpath.getPathComponent(i);
1546        }
1547        TreePath parentPath = new TreePath(parentPathObjs);
1548        tree.setSelectionPath(parentPath.pathByAddingChild(aggname));
1549
1550        refreshTree(tree.getSelectionPath());
1551        setTableCellFocus(0);
1552    }
1553
1554    protected void addAggName(ActionEvent evt) {
1555        TreePath tpath = null;
1556        Object path = null;
1557        if (evt.getSource() instanceof Component
1558            && ((Component)evt.getSource())
1559                .getParent() instanceof CustomJPopupMenu)
1560        {
1561            tpath = ((CustomJPopupMenu)((Component)evt.getSource())
1562                    .getParent()).getPath();
1563        } else {
1564            tpath = tree.getSelectionPath();
1565        }
1566        int parentIndex = -1;
1567        if (tpath != null) {
1568            for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0;
1569                parentIndex--)
1570            {
1571                final Object p = tpath.getPathComponent(parentIndex);
1572                if (p instanceof MondrianGuiDef.Table) {
1573                    if (((parentIndex - 1) >= 0)
1574                        && tpath.getPathComponent(parentIndex - 1)
1575                        instanceof MondrianGuiDef.Cube)
1576                    {
1577                        path = p;
1578                        break;
1579                    }
1580                }
1581            }
1582        }
1583        if (!(path instanceof MondrianGuiDef.Table)) {
1584            JOptionPane.showMessageDialog(
1585                this, getResourceConverter().getString(
1586                    "schemaExplorer.tableNotSelected.alert",
1587                    "Table not selected."), alert, JOptionPane.WARNING_MESSAGE);
1588            return;
1589        }
1590
1591        MondrianGuiDef.Table factTable = (MondrianGuiDef.Table) path;
1592
1593        MondrianGuiDef.AggName aggname = new MondrianGuiDef.AggName();
1594        aggname.name = "";
1595
1596        //add cube to schema
1597        aggname.ignorecase = Boolean.TRUE;
1598        aggname.factcount = null;
1599        aggname.ignoreColumns = new MondrianGuiDef.AggIgnoreColumn[0];
1600        aggname.foreignKeys = new MondrianGuiDef.AggForeignKey[0];
1601        aggname.measures = new MondrianGuiDef.AggMeasure[0];
1602        aggname.levels = new MondrianGuiDef.AggLevel[0];
1603
1604
1605        NodeDef[] temp = factTable.aggTables;
1606        if (temp == null) {
1607            factTable.aggTables =
1608                new MondrianGuiDef.AggTable[1];
1609        } else {
1610            factTable.aggTables =
1611                new MondrianGuiDef.AggTable[temp.length + 1];
1612            for (int i = 0; i < temp.length; i++) {
1613                factTable.aggTables[i] = (MondrianGuiDef.AggTable) temp[i];
1614            }
1615        }
1616
1617        factTable.aggTables[factTable.aggTables.length - 1] = aggname;
1618
1619        Object[] parentPathObjs = new Object[parentIndex + 1];
1620        for (int i = 0; i <= parentIndex; i++) {
1621            parentPathObjs[i] = tpath.getPathComponent(i);
1622        }
1623        TreePath parentPath = new TreePath(parentPathObjs);
1624        tree.setSelectionPath(parentPath.pathByAddingChild(aggname));
1625
1626        refreshTree(tree.getSelectionPath());
1627        setTableCellFocus(0);
1628    }
1629
1630    protected void addAggExclude(ActionEvent evt) {
1631        TreePath tpath = null;
1632        Object path = null;
1633        if (evt.getSource() instanceof Component
1634            && ((Component)evt.getSource())
1635                .getParent() instanceof CustomJPopupMenu)
1636        {
1637            tpath = ((CustomJPopupMenu)((Component)evt.getSource())
1638                    .getParent()).getPath();
1639        } else {
1640            tpath = tree.getSelectionPath();
1641        }
1642        int parentIndex = -1;
1643        if (tpath != null) {
1644            for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0;
1645                parentIndex--)
1646            {
1647                // aggexcludes can be added to cube fact table or
1648                final Object p = tpath.getPathComponent(parentIndex);
1649                if (p instanceof MondrianGuiDef.Table) {
1650                    if (((parentIndex - 1) >= 0)
1651                        && tpath.getPathComponent(parentIndex - 1)
1652                        instanceof MondrianGuiDef.Cube)
1653                    {
1654                        path = p;
1655                        break;
1656                    }
1657                } else if (p instanceof MondrianGuiDef.AggPattern) {
1658                    // aggexcludes can also be added to aggregate patterns
1659                    path = p;
1660                    break;
1661                }
1662            }
1663        }
1664        //Object path = tree.getSelectionPath().getLastPathComponent();
1665        if (!(path instanceof MondrianGuiDef.Table
1666              || path instanceof MondrianGuiDef.AggPattern))
1667        {
1668            JOptionPane.showMessageDialog(
1669                this,
1670                getResourceConverter().getString(
1671                    "schemaExplorer.cubeFactTableOrAggPatternNotSelected.alert",
1672                    "Cube Fact Table or Aggregate Pattern not selected."),
1673                alert,
1674                JOptionPane.WARNING_MESSAGE);
1675            return;
1676        }
1677
1678        MondrianGuiDef.AggExclude aggexclude = new MondrianGuiDef.AggExclude();
1679        aggexclude.pattern = "";
1680
1681        aggexclude.ignorecase = Boolean.TRUE;
1682
1683        if (path instanceof MondrianGuiDef.Table) {
1684            MondrianGuiDef.Table parent =
1685                (MondrianGuiDef.Table) path;  // fact table
1686
1687            NodeDef[] temp = parent.aggExcludes;
1688            parent.aggExcludes = new MondrianGuiDef.AggExclude[temp.length + 1];
1689            for (int i = 0; i < temp.length; i++) {
1690                parent.aggExcludes[i] = (MondrianGuiDef.AggExclude) temp[i];
1691            }
1692
1693            parent.aggExcludes[parent.aggExcludes.length - 1] = aggexclude;
1694        } else {
1695            MondrianGuiDef.AggPattern parent =
1696                (MondrianGuiDef.AggPattern) path;  // aggpattern
1697            NodeDef[] temp = parent.excludes;
1698            parent.excludes = new MondrianGuiDef.AggExclude[temp.length + 1];
1699            for (int i = 0; i < temp.length; i++) {
1700                parent.excludes[i] = (MondrianGuiDef.AggExclude) temp[i];
1701            }
1702
1703            parent.excludes[parent.excludes.length - 1] = aggexclude;
1704        }
1705
1706        Object[] parentPathObjs = new Object[parentIndex + 1];
1707        for (int i = 0; i <= parentIndex; i++) {
1708            parentPathObjs[i] = tpath.getPathComponent(i);
1709        }
1710        TreePath parentPath = new TreePath(parentPathObjs);
1711        tree.setSelectionPath(parentPath.pathByAddingChild(aggexclude));
1712
1713        refreshTree(tree.getSelectionPath());
1714        setTableCellFocus(0);
1715    }
1716
1717    protected void addAggIgnoreColumn(ActionEvent evt) {
1718        TreePath tpath = null;
1719        Object path = null;
1720        if (evt.getSource() instanceof Component
1721            && ((Component)evt.getSource())
1722                .getParent() instanceof CustomJPopupMenu)
1723        {
1724            tpath = ((CustomJPopupMenu)((Component)evt.getSource())
1725                    .getParent()).getPath();
1726        } else {
1727            tpath = tree.getSelectionPath();
1728        }
1729        int parentIndex = -1;
1730        if (tpath != null) {
1731            for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0;
1732                parentIndex--)
1733            {
1734                final Object p = tpath.getPathComponent(parentIndex);
1735                if (p instanceof MondrianGuiDef.AggTable) {
1736                    path = p;
1737                    break;
1738                }
1739            }
1740        }
1741        //Object path = tree.getSelectionPath().getLastPathComponent();
1742        if (!(path instanceof MondrianGuiDef.AggTable)) {
1743            JOptionPane.showMessageDialog(
1744                this,
1745                getResourceConverter().getString(
1746                    "schemaExplorer.aggregateTableNotSelected.alert",
1747                    "Aggregate Table not selected."),
1748                alert,
1749                JOptionPane.WARNING_MESSAGE);
1750            return;
1751        }
1752
1753
1754        MondrianGuiDef.AggTable aggTable = (MondrianGuiDef.AggTable) path;
1755
1756        MondrianGuiDef.AggIgnoreColumn aggicol =
1757            new MondrianGuiDef.AggIgnoreColumn();
1758        aggicol.column = "";
1759
1760        NodeDef[] temp = aggTable.ignoreColumns;
1761        aggTable.ignoreColumns =
1762            new MondrianGuiDef.AggIgnoreColumn[temp.length + 1];
1763        for (int i = 0; i < temp.length; i++) {
1764            aggTable.ignoreColumns[i] =
1765                (MondrianGuiDef.AggIgnoreColumn) temp[i];
1766        }
1767
1768        aggTable.ignoreColumns[aggTable.ignoreColumns.length - 1] = aggicol;
1769
1770        Object[] parentPathObjs = new Object[parentIndex + 1];
1771        for (int i = 0; i <= parentIndex; i++) {
1772            parentPathObjs[i] = tpath.getPathComponent(i);
1773        }
1774        TreePath parentPath = new TreePath(parentPathObjs);
1775        tree.setSelectionPath(parentPath.pathByAddingChild(aggicol));
1776
1777        refreshTree(tree.getSelectionPath());
1778        setTableCellFocus(0);
1779    }
1780
1781    protected void addAggForeignKey(ActionEvent evt) {
1782        TreePath tpath = null;
1783        Object path = null;
1784        if (evt.getSource() instanceof Component
1785            && ((Component)evt.getSource())
1786                .getParent() instanceof CustomJPopupMenu)
1787        {
1788            tpath = ((CustomJPopupMenu)((Component)evt.getSource())
1789                    .getParent()).getPath();
1790        } else {
1791            tpath = tree.getSelectionPath();
1792        }
1793        int parentIndex = -1;
1794        if (tpath != null) {
1795            for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0;
1796                parentIndex--)
1797            {
1798                final Object p = tpath.getPathComponent(parentIndex);
1799                if (p instanceof MondrianGuiDef.AggTable) {
1800                    path = p;
1801                    break;
1802                }
1803            }
1804        }
1805        //Object path = tree.getSelectionPath().getLastPathComponent();
1806        if (!(path instanceof MondrianGuiDef.AggTable)) {
1807            JOptionPane.showMessageDialog(
1808                this,
1809                getResourceConverter().getString(
1810                    "schemaExplorer.aggregateTableNotSelected.alert",
1811                    "Aggregate Table not selected."),
1812                alert,
1813                JOptionPane.WARNING_MESSAGE);
1814            return;
1815        }
1816
1817
1818        MondrianGuiDef.AggTable aggTable = (MondrianGuiDef.AggTable) path;
1819
1820        MondrianGuiDef.AggForeignKey aggfkey =
1821            new MondrianGuiDef.AggForeignKey();
1822
1823        NodeDef[] temp = aggTable.foreignKeys;
1824        aggTable.foreignKeys =
1825            new MondrianGuiDef.AggForeignKey[temp.length + 1];
1826        for (int i = 0; i < temp.length; i++) {
1827            aggTable.foreignKeys[i] = (MondrianGuiDef.AggForeignKey) temp[i];
1828        }
1829
1830        aggTable.foreignKeys[aggTable.foreignKeys.length - 1] = aggfkey;
1831
1832        Object[] parentPathObjs = new Object[parentIndex + 1];
1833        for (int i = 0; i <= parentIndex; i++) {
1834            parentPathObjs[i] = tpath.getPathComponent(i);
1835        }
1836        TreePath parentPath = new TreePath(parentPathObjs);
1837        tree.setSelectionPath(parentPath.pathByAddingChild(aggfkey));
1838
1839        refreshTree(tree.getSelectionPath());
1840        setTableCellFocus(0);
1841    }
1842
1843    protected void addAggMeasure(ActionEvent evt) {
1844        TreePath tpath = null;
1845        Object path = null;
1846        if (evt.getSource() instanceof Component
1847            && ((Component)evt.getSource())
1848                .getParent() instanceof CustomJPopupMenu)
1849        {
1850            tpath = ((CustomJPopupMenu)((Component)evt.getSource())
1851                    .getParent()).getPath();
1852        } else {
1853            tpath = tree.getSelectionPath();
1854        }
1855        int parentIndex = -1;
1856        if (tpath != null) {
1857            for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0;
1858                parentIndex--)
1859            {
1860                final Object p = tpath.getPathComponent(parentIndex);
1861                if (p instanceof MondrianGuiDef.AggTable) {
1862                    path = p;
1863                    break;
1864                }
1865            }
1866        }
1867        //Object path = tree.getSelectionPath().getLastPathComponent();
1868        if (!(path instanceof MondrianGuiDef.AggTable)) {
1869            JOptionPane.showMessageDialog(
1870                this,
1871                getResourceConverter().getString(
1872                    "schemaExplorer.aggregateTableNotSelected.alert",
1873                    "Aggregate Table not selected."),
1874                alert,
1875                JOptionPane.WARNING_MESSAGE);
1876            return;
1877        }
1878
1879
1880        MondrianGuiDef.AggTable aggTable = (MondrianGuiDef.AggTable) path;
1881
1882        MondrianGuiDef.AggMeasure aggmeasure = new MondrianGuiDef.AggMeasure();
1883
1884        NodeDef[] temp = aggTable.measures;
1885        aggTable.measures = new MondrianGuiDef.AggMeasure[temp.length + 1];
1886        for (int i = 0; i < temp.length; i++) {
1887            aggTable.measures[i] = (MondrianGuiDef.AggMeasure) temp[i];
1888        }
1889
1890        aggTable.measures[aggTable.measures.length - 1] = aggmeasure;
1891
1892        Object[] parentPathObjs = new Object[parentIndex + 1];
1893        for (int i = 0; i <= parentIndex; i++) {
1894            parentPathObjs[i] = tpath.getPathComponent(i);
1895        }
1896        TreePath parentPath = new TreePath(parentPathObjs);
1897        tree.setSelectionPath(parentPath.pathByAddingChild(aggmeasure));
1898
1899        refreshTree(tree.getSelectionPath());
1900        setTableCellFocus(0);
1901    }
1902
1903    protected void addAggLevel(ActionEvent evt) {
1904        TreePath tpath = null;
1905        Object path = null;
1906        if (evt.getSource() instanceof Component
1907            && ((Component)evt.getSource())
1908                .getParent() instanceof CustomJPopupMenu)
1909        {
1910            tpath = ((CustomJPopupMenu)((Component)evt.getSource())
1911                    .getParent()).getPath();
1912        } else {
1913            tpath = tree.getSelectionPath();
1914        }
1915        int parentIndex = -1;
1916        if (tpath != null) {
1917            for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0;
1918                parentIndex--)
1919            {
1920                final Object p = tpath.getPathComponent(parentIndex);
1921                if (p instanceof MondrianGuiDef.AggTable) {
1922                    path = p;
1923                    break;
1924                }
1925            }
1926        }
1927        if (!(path instanceof MondrianGuiDef.AggTable)) {
1928            JOptionPane.showMessageDialog(
1929                this,
1930                getResourceConverter().getString(
1931                    "schemaExplorer.aggregateTableNotSelected.alert",
1932                    "Aggregate Table not selected."),
1933                alert,
1934                JOptionPane.WARNING_MESSAGE);
1935            return;
1936        }
1937
1938
1939        MondrianGuiDef.AggTable aggTable = (MondrianGuiDef.AggTable) path;
1940
1941        MondrianGuiDef.AggLevel agglevel = new MondrianGuiDef.AggLevel();
1942
1943        NodeDef[] temp = aggTable.levels;
1944        aggTable.levels = new MondrianGuiDef.AggLevel[temp.length + 1];
1945        for (int i = 0; i < temp.length; i++) {
1946            aggTable.levels[i] = (MondrianGuiDef.AggLevel) temp[i];
1947        }
1948
1949        aggTable.levels[aggTable.levels.length - 1] = agglevel;
1950        agglevel.collapsed = Boolean.TRUE;
1951
1952        Object[] parentPathObjs = new Object[parentIndex + 1];
1953        for (int i = 0; i <= parentIndex; i++) {
1954            parentPathObjs[i] = tpath.getPathComponent(i);
1955        }
1956        TreePath parentPath = new TreePath(parentPathObjs);
1957        tree.setSelectionPath(parentPath.pathByAddingChild(agglevel));
1958
1959        refreshTree(tree.getSelectionPath());
1960        setTableCellFocus(0);
1961    }
1962
1963    protected void addAggFactCount(ActionEvent evt) {
1964        TreePath tpath = null;
1965        Object path = null;
1966        if (evt.getSource() instanceof Component
1967            && ((Component)evt.getSource())
1968                .getParent() instanceof CustomJPopupMenu)
1969        {
1970            tpath = ((CustomJPopupMenu)((Component)evt.getSource())
1971                    .getParent()).getPath();
1972        } else {
1973            tpath = tree.getSelectionPath();
1974        }
1975        int parentIndex = -1;
1976        if (tpath != null) {
1977            for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0;
1978                parentIndex--)
1979            {
1980                final Object p = tpath.getPathComponent(parentIndex);
1981                if (p instanceof MondrianGuiDef.AggTable) {
1982                    path = p;
1983                    break;
1984                }
1985            }
1986        }
1987        if (!((path instanceof MondrianGuiDef.AggName)
1988              || (path instanceof MondrianGuiDef.AggPattern)))
1989        {
1990            JOptionPane.showMessageDialog(
1991                this,
1992                getResourceConverter().getString(
1993                    "schemaExplorer.aggregateTableOrAggPatternNotSelected.alert",
1994                    "Aggregate Table or Aggregate Pattern not selected."),
1995                alert,
1996                JOptionPane.WARNING_MESSAGE);
1997            return;
1998        }
1999
2000        MondrianGuiDef.AggFactCount aggFactCount =
2001            new MondrianGuiDef.AggFactCount();
2002        MondrianGuiDef.AggTable aggName = null;
2003        MondrianGuiDef.AggPattern aggPattern = null;
2004        if (path instanceof MondrianGuiDef.AggName) {
2005            aggName = (MondrianGuiDef.AggName) path;
2006            aggName.factcount = new MondrianGuiDef.AggFactCount();
2007        } else {
2008            aggPattern = (MondrianGuiDef.AggPattern) path;
2009            aggPattern.factcount = new MondrianGuiDef.AggFactCount();
2010        }
2011
2012        Object[] parentPathObjs = new Object[parentIndex + 1];
2013        for (int i = 0; i <= parentIndex; i++) {
2014            parentPathObjs[i] = tpath.getPathComponent(i);
2015        }
2016        TreePath parentPath = new TreePath(parentPathObjs);
2017        tree.setSelectionPath(parentPath.pathByAddingChild(aggFactCount));
2018
2019        refreshTree(tree.getSelectionPath());
2020        setTableCellFocus(0);
2021    }
2022
2023    protected void addVirtualCubeMeasure(ActionEvent evt) {
2024        TreePath tpath = null;
2025        Object path = null;
2026        if (evt.getSource() instanceof Component
2027            && ((Component)evt.getSource())
2028                .getParent() instanceof CustomJPopupMenu)
2029        {
2030            tpath = ((CustomJPopupMenu)((Component)evt.getSource())
2031                    .getParent()).getPath();
2032        } else {
2033            tpath = tree.getSelectionPath();
2034        }
2035        int parentIndex = -1;
2036        if (tpath != null) {
2037            for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0;
2038                parentIndex--)
2039            {
2040                final Object p = tpath.getPathComponent(parentIndex);
2041                if (p instanceof MondrianGuiDef.VirtualCube) {
2042                    path = p;
2043                    break;
2044                }
2045            }
2046        }
2047        //Object path = tree.getSelectionPath().getLastPathComponent();
2048        if (!(path instanceof MondrianGuiDef.VirtualCube)) {
2049            JOptionPane.showMessageDialog(
2050                this,
2051                getResourceConverter().getString(
2052                    "schemaExplorer.virtualCubeNotSelected.alert",
2053                    "Virtual Cube not selected."),
2054                alert,
2055                JOptionPane.WARNING_MESSAGE);
2056            return;
2057        }
2058
2059
2060        MondrianGuiDef.VirtualCube cube = (MondrianGuiDef.VirtualCube) path;
2061
2062        MondrianGuiDef.VirtualCubeMeasure measure =
2063            new MondrianGuiDef.VirtualCubeMeasure();
2064        measure.name = "";
2065        measure.name =
2066            getNewName(
2067                getResourceConverter().getString(
2068                    "schemaExplorer.newVirtualMeasure.title",
2069                    "New Virtual Measure"),
2070                cube.measures);
2071        measure.visible = Boolean.TRUE; // default true
2072
2073        NodeDef[] temp = cube.measures;
2074        cube.measures = new MondrianGuiDef.VirtualCubeMeasure[temp.length + 1];
2075        for (int i = 0; i < temp.length; i++) {
2076            cube.measures[i] = (MondrianGuiDef.VirtualCubeMeasure) temp[i];
2077        }
2078
2079        cube.measures[cube.measures.length - 1] = measure;
2080
2081        Object[] parentPathObjs = new Object[parentIndex + 1];
2082        for (int i = 0; i <= parentIndex; i++) {
2083            parentPathObjs[i] = tpath.getPathComponent(i);
2084        }
2085        TreePath parentPath = new TreePath(parentPathObjs);
2086        tree.setSelectionPath(parentPath.pathByAddingChild(measure));
2087
2088        refreshTree(tree.getSelectionPath());
2089        setTableCellFocus(0);
2090    }
2091
2092    protected void addCalculatedMember(ActionEvent evt) {
2093        TreePath tpath = null;
2094        Object path = null;
2095        if (evt.getSource() instanceof Component
2096            && ((Component)evt.getSource())
2097                .getParent() instanceof CustomJPopupMenu)
2098        {
2099            tpath = ((CustomJPopupMenu)((Component)evt.getSource())
2100                    .getParent()).getPath();
2101        } else {
2102            tpath = tree.getSelectionPath();
2103        }
2104        int parentIndex = -1;
2105        if (tpath != null) {
2106            for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0;
2107                parentIndex--)
2108            {
2109                final Object p = tpath.getPathComponent(parentIndex);
2110                if (p instanceof MondrianGuiDef.Cube
2111                    || p instanceof MondrianGuiDef.VirtualCube)
2112                {
2113                    path = p;
2114                    break;
2115                }
2116            }
2117        }
2118        if (!((path instanceof MondrianGuiDef.Cube)
2119              || (path instanceof MondrianGuiDef.VirtualCube)))
2120        {
2121            JOptionPane.showMessageDialog(
2122                this,
2123                getResourceConverter().getString(
2124                    "schemaExplorer.cubeOrVirtualCubeNotSelected.alert",
2125                    "Cube or Virtual Cube not selected."),
2126                alert,
2127                JOptionPane.WARNING_MESSAGE);
2128            return;
2129        }
2130
2131        MondrianGuiDef.Cube cube = null;
2132        MondrianGuiDef.VirtualCube vcube = null;
2133
2134        if (path instanceof MondrianGuiDef.Cube) {
2135            cube = (MondrianGuiDef.Cube) path;
2136        } else {
2137            vcube = (MondrianGuiDef.VirtualCube) path;
2138        }
2139
2140        MondrianGuiDef.CalculatedMember calcmember =
2141            new MondrianGuiDef.CalculatedMember();
2142        calcmember.name = "";
2143        calcmember.dimension = "Measures";
2144        calcmember.visible = Boolean.TRUE;  // default value
2145        calcmember.formatString = "";
2146        calcmember.formula = "";
2147        calcmember.formulaElement = new MondrianGuiDef.Formula();
2148        calcmember.memberProperties =
2149            new MondrianGuiDef.CalculatedMemberProperty[0];
2150
2151        //add cube to schema
2152        if (cube != null) {
2153            calcmember.name =
2154                getNewName(
2155                    getResourceConverter().getString(
2156                        "schemaExplorer.newCalculatedMember.title",
2157                        "New Calculated Member"),
2158                    cube.calculatedMembers);
2159            NodeDef[] temp = cube.calculatedMembers;
2160            cube.calculatedMembers =
2161                new MondrianGuiDef.CalculatedMember[temp.length + 1];
2162            for (int i = 0; i < temp.length; i++) {
2163                cube.calculatedMembers[i] =
2164                    (MondrianGuiDef.CalculatedMember) temp[i];
2165            }
2166
2167            cube.calculatedMembers[cube.calculatedMembers.length - 1] =
2168                calcmember;
2169        } else {
2170            calcmember.name =
2171                getNewName(
2172                    getResourceConverter().getString(
2173                        "schemaExplorer.newCalculatedMember.title",
2174                        "New Calculated Member"),
2175                    vcube.calculatedMembers);
2176            NodeDef[] temp = vcube.calculatedMembers;
2177            vcube.calculatedMembers =
2178                new MondrianGuiDef.CalculatedMember[temp.length + 1];
2179            for (int i = 0; i < temp.length; i++) {
2180                vcube.calculatedMembers[i] =
2181                    (MondrianGuiDef.CalculatedMember) temp[i];
2182            }
2183
2184            vcube.calculatedMembers[vcube.calculatedMembers.length - 1] =
2185                calcmember;
2186        }
2187
2188        Object[] parentPathObjs = new Object[parentIndex + 1];
2189        for (int i = 0; i <= parentIndex; i++) {
2190            parentPathObjs[i] = tpath.getPathComponent(i);
2191        }
2192        TreePath parentPath = new TreePath(parentPathObjs);
2193        tree.setSelectionPath(parentPath.pathByAddingChild(calcmember));
2194
2195        refreshTree(tree.getSelectionPath());
2196        setTableCellFocus(0);
2197    }
2198
2199    protected boolean editMode(EventObject evt) {
2200        // toggle edit mode between xml or properties table form
2201        editModeXML = !isEditModeXML();
2202
2203        editModeButton.setSelected(isEditModeXML());
2204        if (isEditModeXML()) {
2205            jSplitPane1.setRightComponent(jPanelXML);
2206        } else {
2207            jSplitPane1.setRightComponent(jPanel1);
2208        }
2209        // update the workbench view menu
2210        Component o = parentIFrame.getDesktopPane().getParent();
2211        while (o != null) {
2212            if (o.getClass() == Workbench.class) {
2213                ((Workbench) o).getViewXmlMenuItem().setSelected(editModeXML);
2214                break;
2215            }
2216            o = o.getParent();
2217        }
2218        return isEditModeXML();
2219    }
2220
2221    protected void delete(EventObject evt) {
2222        // delete the selected schema object
2223        TreePath tpath = null;
2224        Object path = null;
2225        if (evt.getSource() instanceof Component
2226            && ((Component)evt.getSource())
2227                .getParent() instanceof CustomJPopupMenu)
2228        {
2229            tpath = ((CustomJPopupMenu)((Component)evt.getSource())
2230                    .getParent()).getPath();
2231        } else {
2232            tpath = tree.getSelectionPath();
2233        }
2234        if (tpath == null) {
2235            JOptionPane.showMessageDialog(
2236                this,
2237                getResourceConverter().getString(
2238                    "schemaExplorer.objectToDeleteNotSelected.alert",
2239                    "Object to delete in Schema not selected."),
2240                alert,
2241                JOptionPane.WARNING_MESSAGE);
2242            return;
2243        }
2244        delete(tpath);
2245    }
2246
2247    void delete(TreePath tpath) {
2248        Object child = tpath.getLastPathComponent(); // to be deleted
2249        Object nextSibling = null;
2250        Object prevSibling = null;
2251        Object parent = null;
2252        Object grandparent = null;
2253        boolean grandparentAsSibling = false;
2254
2255        for (int i = tpath.getPathCount() - 1 - 1; i >= 0; i--) {
2256            // get parent path
2257            parent = tpath.getPathComponent(i);
2258            if (tpath.getPathCount() - 3 > 0) {
2259                // get parent path
2260                grandparent = tpath.getPathComponent(i - 1);
2261            }
2262            break;
2263        }
2264        if (parent == null) {
2265            JOptionPane.showMessageDialog(
2266                this,
2267                getResourceConverter().getString(
2268                    "schemaExplorer.cantDeleteObject.alert",
2269                    "Schema object cannot be deleted."),
2270                alert,
2271                JOptionPane.WARNING_MESSAGE);
2272            return;
2273        }
2274
2275        boolean tofind = true;
2276
2277        Field[] fs = parent.getClass().getFields();
2278        for (int i = 0; i < fs.length; i++) {
2279            if (fs[i].getType().isArray()
2280                && (fs[i].getType().getComponentType().isInstance(child)))
2281            {
2282                try {
2283                    // get the parent's array of child objects
2284                    Object parentArr = fs[i].get(parent);
2285                    int parentArrLen = Array.getLength(parentArr);
2286                    Object newArr =
2287                        Array.newInstance(
2288                            fs[i].getType().getComponentType(),
2289                            parentArrLen - 1);
2290                    tofind = true;
2291                    for (int k = 0, m = 0; k < parentArrLen; k++) {
2292                        Object match = Array.get(parentArr, k);
2293
2294                        if (tofind && match.equals(child)) {
2295                            if (child instanceof MondrianGuiDef.CubeDimension) {
2296                                // Check equality of parent class attributes for
2297                                // a special case when child is an object of
2298                                // CubeDimensions
2299                                MondrianGuiDef.CubeDimension matchDim =
2300                                    (MondrianGuiDef.CubeDimension) match;
2301                                MondrianGuiDef.CubeDimension childDim =
2302                                    (MondrianGuiDef.CubeDimension) child;
2303
2304                                if (eq(matchDim.name, childDim.name)
2305                                    && eq(matchDim.caption, childDim.caption)
2306                                    && eq(
2307                                        matchDim.foreignKey,
2308                                        childDim.foreignKey))
2309                                {
2310                                    tofind = false;
2311                                    if (k + 1 < parentArrLen) {
2312                                        nextSibling = Array.get(
2313                                            parentArr, k + 1);
2314                                    }
2315                                    if (k - 1 >= 0) {
2316                                        prevSibling = Array.get(
2317                                            parentArr, k - 1);
2318                                    }
2319                                    continue;
2320                                }
2321                            } else {
2322                                // other cases require no such check
2323                                tofind = false;
2324                                if (k + 1 < parentArrLen) {
2325                                    nextSibling = Array.get(parentArr, k + 1);
2326                                }
2327                                if (k - 1 >= 0) {
2328                                    prevSibling = Array.get(parentArr, k - 1);
2329                                }
2330                                continue;
2331                            }
2332                        }
2333                        Array.set(newArr, m++, match);
2334                    }
2335                    // After deletion check before the saving the new array in
2336                    // parent.  Check for min 1 SQL object(child) in (parent)
2337                    // expression for (grandparent) level.  If 1 or more, save
2338                    // the newarray in parent, otherwise delete parent from
2339                    // grandparent.
2340                    if ((child instanceof MondrianGuiDef.SQL)
2341                        && (parent instanceof MondrianGuiDef.ExpressionView)
2342                        && (Array.getLength(newArr) < 1))
2343                    {
2344                        if (parent instanceof MondrianGuiDef.KeyExpression) {
2345                            ((MondrianGuiDef.Level) grandparent).keyExp = null;
2346                        } else if (parent instanceof
2347                            MondrianGuiDef.NameExpression)
2348                        {
2349                            ((MondrianGuiDef.Level) grandparent).nameExp = null;
2350                        } else if (parent
2351                            instanceof MondrianGuiDef.OrdinalExpression)
2352                        {
2353                            ((MondrianGuiDef.Level) grandparent).ordinalExp =
2354                                null;
2355                        } else if (parent
2356                            instanceof MondrianGuiDef.CaptionExpression)
2357                        {
2358                            ((MondrianGuiDef.Level) grandparent).captionExp =
2359                                null;
2360                        } else if (parent
2361                            instanceof MondrianGuiDef.ParentExpression)
2362                        {
2363                            ((MondrianGuiDef.Level) grandparent).parentExp =
2364                                null;
2365                        } else if (parent
2366                            instanceof MondrianGuiDef.MeasureExpression)
2367                        {
2368                            ((MondrianGuiDef.Measure) grandparent).measureExp =
2369                                null;
2370                        }
2371                        grandparentAsSibling = true;
2372                    } else {
2373                        fs[i].set(parent, newArr);
2374                    }
2375                } catch (Exception ex) {
2376                    // field not found
2377                }
2378                break;
2379            } else if (fs[i].getType().isInstance(child)) {
2380                // parent's field is an instanceof child object'
2381                try {
2382                    if (fs[i].get(parent) == child) {
2383                        fs[i].set(parent, null);
2384                        break;
2385                    }
2386                } catch (Exception ex) {
2387                    LOGGER.error("delete", ex);
2388                    // field not found
2389                }
2390            }
2391        }
2392
2393
2394        // delete the node from set of expended nodes in JTreeUpdater also
2395        TreeExpansionEvent e = null;
2396        e = new TreeExpansionEvent(tree, tpath);
2397        updater.treeCollapsed(e);
2398
2399        if (nextSibling != null) {
2400            tree.setSelectionPath(
2401                tpath.getParentPath().pathByAddingChild(
2402                    nextSibling));
2403        } else if (prevSibling != null) {
2404            tree.setSelectionPath(
2405                tpath.getParentPath().pathByAddingChild(
2406                    prevSibling));
2407        } else if (grandparentAsSibling) {
2408            tree.setSelectionPath(tpath.getParentPath().getParentPath());
2409        } else {
2410            tree.setSelectionPath(tpath.getParentPath());
2411        }
2412        refreshTree(tree.getSelectionPath());
2413    }
2414
2415    private boolean eq(
2416        String o1,
2417        String o2)
2418    {
2419        return o1 == null
2420            ? o2 == null
2421            : o1.equals(o2);
2422    }
2423
2424    /**
2425     * @param evt
2426     */
2427    protected void addDimension(ActionEvent evt) {
2428        TreePath tpath = null;
2429        Object path = null;
2430        if (evt.getSource() instanceof Component
2431            && ((Component)evt.getSource())
2432                .getParent() instanceof CustomJPopupMenu)
2433        {
2434            tpath = ((CustomJPopupMenu)((Component)evt.getSource())
2435                    .getParent()).getPath();
2436        } else {
2437            tpath = tree.getSelectionPath();
2438        }
2439        int parentIndex = -1;
2440        if (tpath != null) {
2441            for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0;
2442                parentIndex--)
2443            {
2444                final Object p = tpath.getPathComponent(parentIndex);
2445                if (p instanceof MondrianGuiDef.Cube
2446                    || p instanceof MondrianGuiDef.Schema)
2447                {
2448                    path = p;
2449                    break;
2450                }
2451            }
2452        }
2453
2454        if (!((path instanceof MondrianGuiDef.Cube)
2455              || (path instanceof MondrianGuiDef.Schema)))
2456        {
2457            JOptionPane.showMessageDialog(
2458                this,
2459                getResourceConverter().getString(
2460                    "schemaExplorer.cubeOrSchemaNotSelected.alert",
2461                    "Cube or Schema not selected."),
2462                alert,
2463                JOptionPane.WARNING_MESSAGE);
2464            return;
2465        }
2466
2467        MondrianGuiDef.Cube cube = null;
2468        MondrianGuiDef.Schema schema = null;
2469
2470        if (path instanceof MondrianGuiDef.Cube) {
2471            cube = (MondrianGuiDef.Cube) path;
2472        } else {
2473            schema = (MondrianGuiDef.Schema) path;
2474        }
2475
2476        MondrianGuiDef.Dimension dimension = new MondrianGuiDef.Dimension();
2477        dimension.name = "";
2478        dimension.visible = Boolean.TRUE;
2479        dimension.type = "StandardDimension";    // default dimension type
2480        dimension.hierarchies = new MondrianGuiDef.Hierarchy[1];
2481        dimension.hierarchies[0] = new MondrianGuiDef.Hierarchy();
2482        dimension.hierarchies[0].name =
2483            getResourceConverter().getString(
2484                "schemaExplorer.newHierarchyInTree.title",
2485                "New Hierarchy 0");
2486        dimension.hierarchies[0].visible = Boolean.TRUE;
2487        dimension.hierarchies[0].hasAll = true;
2488        dimension.hierarchies[0].levels = new MondrianGuiDef.Level[0];
2489        dimension.hierarchies[0].memberReaderParameters =
2490            new MondrianGuiDef.MemberReaderParameter[0];
2491
2492        //add cube to schema
2493        if (cube != null) {
2494            dimension.name =
2495                getNewName(
2496                    getResourceConverter().getString(
2497                        "schemaExplorer.newDimension.title",
2498                        "New Dimension"),
2499                    cube.dimensions);
2500            NodeDef[] temp = cube.dimensions;
2501            cube.dimensions = new MondrianGuiDef.CubeDimension[temp.length + 1];
2502            for (int i = 0; i < temp.length; i++) {
2503                cube.dimensions[i] = (MondrianGuiDef.CubeDimension) temp[i];
2504            }
2505            cube.dimensions[cube.dimensions.length - 1] = dimension;
2506        } else {
2507            dimension.name =
2508                getNewName(
2509                    getResourceConverter().getString(
2510                        "schemaExplorer.newDimension.title",
2511                        "New Dimension"),
2512                    schema.dimensions);
2513            NodeDef[] temp = schema.dimensions;
2514            schema.dimensions = new MondrianGuiDef.Dimension[temp.length + 1];
2515            for (int i = 0; i < temp.length; i++) {
2516                schema.dimensions[i] = (MondrianGuiDef.Dimension) temp[i];
2517            }
2518
2519            schema.dimensions[schema.dimensions.length - 1] = dimension;
2520        }
2521
2522        Object[] parentPathObjs = new Object[parentIndex + 1];
2523        for (int i = 0; i <= parentIndex; i++) {
2524            parentPathObjs[i] = tpath.getPathComponent(i);
2525        }
2526        TreePath parentPath = new TreePath(parentPathObjs);
2527        tree.setSelectionPath(parentPath.pathByAddingChild(dimension));
2528
2529        refreshTree(tree.getSelectionPath());
2530        setTableCellFocus(0);
2531    }
2532
2533
2534    protected void addVirtualCubeDimension(ActionEvent evt) {
2535        TreePath tpath = null;
2536        Object path = null;
2537        if (evt.getSource() instanceof Component
2538            && ((Component)evt.getSource())
2539                .getParent() instanceof CustomJPopupMenu)
2540        {
2541            tpath = ((CustomJPopupMenu)((Component)evt.getSource())
2542                    .getParent()).getPath();
2543        } else {
2544            tpath = tree.getSelectionPath();
2545        }
2546        int parentIndex = -1;
2547        if (tpath != null) {
2548            for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0;
2549                parentIndex--)
2550            {
2551                final Object p = tpath.getPathComponent(parentIndex);
2552                if (p instanceof MondrianGuiDef.VirtualCube) {
2553                    path = p;
2554                    break;
2555                }
2556            }
2557        }
2558
2559        //Object path = tree.getSelectionPath().getLastPathComponent();
2560        if (!(path instanceof MondrianGuiDef.VirtualCube)) {
2561            JOptionPane.showMessageDialog(
2562                this,
2563                getResourceConverter().getString(
2564                    "schemaExplorer.virtualCubeNotSelected.alert",
2565                    "Virtual Cube not selected."),
2566                alert,
2567                JOptionPane.WARNING_MESSAGE);
2568            return;
2569        }
2570
2571        MondrianGuiDef.VirtualCube cube = (MondrianGuiDef.VirtualCube) path;
2572
2573        MondrianGuiDef.VirtualCubeDimension dimension =
2574            new MondrianGuiDef.VirtualCubeDimension();
2575        dimension.name = "";
2576        dimension.name =
2577            getNewName(
2578                getResourceConverter().getString(
2579                    "schemaExplorer.newVirtualDimension.title",
2580                    "New Virtual Dimension"),
2581                cube.dimensions);
2582        NodeDef[] temp = cube.dimensions;
2583        cube.dimensions =
2584            new MondrianGuiDef.VirtualCubeDimension[temp.length + 1];
2585        for (int i = 0; i < temp.length; i++) {
2586            cube.dimensions[i] = (MondrianGuiDef.VirtualCubeDimension) temp[i];
2587        }
2588        cube.dimensions[cube.dimensions.length - 1] = dimension;
2589
2590        Object[] parentPathObjs = new Object[parentIndex + 1];
2591        for (int i = 0; i <= parentIndex; i++) {
2592            parentPathObjs[i] = tpath.getPathComponent(i);
2593        }
2594        TreePath parentPath = new TreePath(parentPathObjs);
2595        tree.setSelectionPath(parentPath.pathByAddingChild(dimension));
2596        refreshTree(tree.getSelectionPath());
2597        setTableCellFocus(0);
2598    }
2599
2600    private String getNewName(String preName, Object[] objs) {
2601        String newName = "";
2602        String workName = preName.trim() + " ";
2603
2604        if (objs != null) {
2605            int objNo = objs.length;
2606            try {
2607                Field f = objs.getClass().getComponentType().getField("name");
2608                boolean exists;
2609                do {
2610                    newName = workName + objNo++;
2611                    exists = existsWithFieldValue(objs, newName, f);
2612                } while (exists);
2613            } catch (Exception ex) {
2614                LOGGER.error("getNewName", ex);
2615            }
2616        } else {
2617            newName = workName + 0;
2618        }
2619        return newName;
2620    }
2621
2622    private static boolean existsWithFieldValue(
2623        Object[] objs,
2624        String seek,
2625        Field f)
2626        throws IllegalAccessException
2627    {
2628        for (int i = 0; i < objs.length; i++) {
2629            String value = (String) f.get(objs[i]);
2630            if (seek.equals(value)) {
2631                return true;
2632            }
2633        }
2634        return false;
2635    }
2636
2637    protected void addNamedSet(ActionEvent evt) {
2638        TreePath tpath = null;
2639        Object path = null;
2640        if (evt.getSource() instanceof Component
2641            && ((Component)evt.getSource())
2642                .getParent() instanceof CustomJPopupMenu)
2643        {
2644            tpath = ((CustomJPopupMenu)((Component)evt.getSource())
2645                    .getParent()).getPath();
2646        } else {
2647            tpath = tree.getSelectionPath();
2648        }
2649        int parentIndex = -1;
2650        if (tpath != null) {
2651            for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0;
2652                parentIndex--)
2653            {
2654                final Object p = tpath.getPathComponent(parentIndex);
2655                if (p instanceof MondrianGuiDef.Cube
2656                    || p instanceof MondrianGuiDef.Schema)
2657                {
2658                    path = p;
2659                    break;
2660                }
2661            }
2662        }
2663
2664        if (!((path instanceof MondrianGuiDef.Cube)
2665              || (path instanceof MondrianGuiDef.Schema)))
2666        {
2667            JOptionPane.showMessageDialog(
2668                this,
2669                getResourceConverter().getString(
2670                    "schemaExplorer.cubeOrSchemaNotSelected.alert",
2671                    "Cube or Schema not selected."),
2672                alert,
2673                JOptionPane.WARNING_MESSAGE);
2674            return;
2675        }
2676
2677
2678        MondrianGuiDef.Cube cube = null;
2679        MondrianGuiDef.Schema schema = null;
2680
2681        if (path instanceof MondrianGuiDef.Cube) {
2682            cube = (MondrianGuiDef.Cube) path;
2683        } else {
2684            schema = (MondrianGuiDef.Schema) path;
2685        }
2686
2687        MondrianGuiDef.NamedSet namedset = new MondrianGuiDef.NamedSet();
2688        namedset.name = "";
2689        namedset.formula = "";
2690        namedset.formulaElement = new MondrianGuiDef.Formula();
2691
2692        //add cube to schema
2693        if (cube != null) {
2694            namedset.name =
2695                getNewName(
2696                    getResourceConverter().getString(
2697                        "schemaExplorer.newNamedSet.title",
2698                        "New Named Set"),
2699                    cube.namedSets);
2700
2701            NodeDef[] temp = cube.namedSets;
2702            cube.namedSets = new MondrianGuiDef.NamedSet[temp.length + 1];
2703            for (int i = 0; i < temp.length; i++) {
2704                cube.namedSets[i] = (MondrianGuiDef.NamedSet) temp[i];
2705            }
2706
2707            cube.namedSets[cube.namedSets.length - 1] = namedset;
2708        } else {
2709            namedset.name =
2710                getNewName(
2711                    getResourceConverter().getString(
2712                        "schemaExplorer.newNamedSet.title",
2713                        "New Named Set"),
2714                    schema.namedSets);
2715            NodeDef[] temp = schema.namedSets;
2716            schema.namedSets = new MondrianGuiDef.NamedSet[temp.length + 1];
2717            for (int i = 0; i < temp.length; i++) {
2718                schema.namedSets[i] = (MondrianGuiDef.NamedSet) temp[i];
2719            }
2720
2721            schema.namedSets[schema.namedSets.length - 1] = namedset;
2722        }
2723
2724        Object[] parentPathObjs = new Object[parentIndex + 1];
2725        for (int i = 0; i <= parentIndex; i++) {
2726            parentPathObjs[i] = tpath.getPathComponent(i);
2727        }
2728        TreePath parentPath = new TreePath(parentPathObjs);
2729        tree.setSelectionPath(parentPath.pathByAddingChild(namedset));
2730
2731        refreshTree(tree.getSelectionPath());
2732        setTableCellFocus(0);
2733    }
2734
2735    protected void addDimensionUsage(ActionEvent evt) {
2736        TreePath tpath = null;
2737        Object path = null;
2738        if (evt.getSource() instanceof Component
2739            && ((Component)evt.getSource())
2740                .getParent() instanceof CustomJPopupMenu)
2741        {
2742            tpath = ((CustomJPopupMenu)((Component)evt.getSource())
2743                    .getParent()).getPath();
2744        } else {
2745            tpath = tree.getSelectionPath();
2746        }
2747        int parentIndex = -1;
2748        if (tpath != null) {
2749            for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0;
2750                parentIndex--)
2751            {
2752                final Object p = tpath.getPathComponent(parentIndex);
2753                if (p instanceof MondrianGuiDef.Cube) {
2754                    path = p;
2755                    break;
2756                }
2757            }
2758        }
2759        //Object path = tree.getSelectionPath().getLastPathComponent();
2760        if (!(path instanceof MondrianGuiDef.Cube)) {
2761            JOptionPane.showMessageDialog(
2762                this,
2763                getResourceConverter().getString(
2764                    "schemaExplorer.cubeNotSelected.alert",
2765                    "Cube not selected."),
2766                alert,
2767                JOptionPane.WARNING_MESSAGE);
2768            return;
2769        }
2770
2771        MondrianGuiDef.Cube cube = (MondrianGuiDef.Cube) path;
2772
2773        MondrianGuiDef.DimensionUsage dimension =
2774            new MondrianGuiDef.DimensionUsage();
2775        dimension.name = "";
2776        dimension.visible = Boolean.TRUE;
2777        dimension.name =
2778            getNewName(
2779                getResourceConverter().getString(
2780                    "schemaExplorer.newDimensionUsage.title",
2781                    "New Dimension Usage"),
2782                cube.dimensions);
2783        NodeDef[] temp = cube.dimensions;
2784        cube.dimensions = new MondrianGuiDef.CubeDimension[temp.length + 1];
2785        for (int i = 0; i < temp.length; i++) {
2786            cube.dimensions[i] = (MondrianGuiDef.CubeDimension) temp[i];
2787        }
2788
2789        cube.dimensions[cube.dimensions.length - 1] = dimension;
2790
2791        Object[] parentPathObjs = new Object[parentIndex + 1];
2792        for (int i = 0; i <= parentIndex; i++) {
2793            parentPathObjs[i] = tpath.getPathComponent(i);
2794        }
2795        TreePath parentPath = new TreePath(parentPathObjs);
2796        tree.setSelectionPath(parentPath.pathByAddingChild(dimension));
2797
2798        refreshTree(tree.getSelectionPath());
2799        setTableCellFocus(0);
2800    }
2801
2802    protected void addSchemaGrant(ActionEvent evt) {
2803        TreePath tpath = null;
2804        Object path = null;
2805        if (evt.getSource() instanceof Component
2806            && ((Component)evt.getSource())
2807                .getParent() instanceof CustomJPopupMenu)
2808        {
2809            tpath = ((CustomJPopupMenu)((Component)evt.getSource())
2810                    .getParent()).getPath();
2811        } else {
2812            tpath = tree.getSelectionPath();
2813        }
2814        int parentIndex = -1;
2815        if (tpath != null) {
2816            for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0;
2817                parentIndex--)
2818            {
2819                final Object p = tpath.getPathComponent(parentIndex);
2820                if (p instanceof MondrianGuiDef.Role) {
2821                    path = p;
2822                    break;
2823                }
2824            }
2825        }
2826        //Object path = tree.getSelectionPath().getLastPathComponent();
2827        if (!(path instanceof MondrianGuiDef.Role)) {
2828            JOptionPane.showMessageDialog(
2829                this,
2830                getResourceConverter().getString(
2831                    "schemaExplorer.roleNotSelected.alert",
2832                    "Role not selected."),
2833                alert, JOptionPane.WARNING_MESSAGE);
2834            return;
2835        }
2836
2837        MondrianGuiDef.Role role = (MondrianGuiDef.Role) path;
2838
2839        MondrianGuiDef.SchemaGrant schemaGrant =
2840            new MondrianGuiDef.SchemaGrant();
2841        schemaGrant.access = "";
2842        schemaGrant.cubeGrants = new MondrianGuiDef.CubeGrant[0];
2843
2844        //add cube to schema
2845        NodeDef[] temp = role.schemaGrants;
2846        role.schemaGrants = new MondrianGuiDef.SchemaGrant[temp.length + 1];
2847        for (int i = 0; i < temp.length; i++) {
2848            role.schemaGrants[i] = (MondrianGuiDef.SchemaGrant) temp[i];
2849        }
2850
2851        role.schemaGrants[role.schemaGrants.length - 1] = schemaGrant;
2852
2853        Object[] parentPathObjs = new Object[parentIndex + 1];
2854        for (int i = 0; i <= parentIndex; i++) {
2855            parentPathObjs[i] = tpath.getPathComponent(i);
2856        }
2857        TreePath parentPath = new TreePath(parentPathObjs);
2858        tree.setSelectionPath(parentPath.pathByAddingChild(schemaGrant));
2859
2860        refreshTree(tree.getSelectionPath());
2861        setTableCellFocus(0);
2862    }
2863
2864    protected void addCubeGrant(ActionEvent evt) {
2865        TreePath tpath = null;
2866        Object path = null;
2867        if (evt.getSource() instanceof Component
2868            && ((Component)evt.getSource())
2869                .getParent() instanceof CustomJPopupMenu)
2870        {
2871            tpath = ((CustomJPopupMenu)((Component)evt.getSource())
2872                    .getParent()).getPath();
2873        } else {
2874            tpath = tree.getSelectionPath();
2875        }
2876        int parentIndex = -1;
2877        if (tpath != null) {
2878            for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0;
2879                parentIndex--)
2880            {
2881                final Object p = tpath.getPathComponent(parentIndex);
2882                if (p instanceof MondrianGuiDef.SchemaGrant) {
2883                    path = p;
2884                    break;
2885                }
2886            }
2887        }
2888
2889        if (!(path instanceof MondrianGuiDef.SchemaGrant)) {
2890            JOptionPane.showMessageDialog(
2891                this,
2892                getResourceConverter().getString(
2893                    "schemaExplorer.schemaGrantNotSelected.alert",
2894                    "Schema Grant not selected."),
2895                alert,
2896                JOptionPane.WARNING_MESSAGE);
2897            return;
2898        }
2899
2900        MondrianGuiDef.SchemaGrant schemaGrant =
2901            (MondrianGuiDef.SchemaGrant) path;
2902
2903        MondrianGuiDef.CubeGrant cubeGrant = new MondrianGuiDef.CubeGrant();
2904        cubeGrant.access = "";
2905        cubeGrant.dimensionGrants = new MondrianGuiDef.DimensionGrant[0];
2906        cubeGrant.hierarchyGrants = new MondrianGuiDef.HierarchyGrant[0];
2907
2908        //add cube to schema
2909        NodeDef[] temp = schemaGrant.cubeGrants;
2910        schemaGrant.cubeGrants = new MondrianGuiDef.CubeGrant[temp.length + 1];
2911        for (int i = 0; i < temp.length; i++) {
2912            schemaGrant.cubeGrants[i] = (MondrianGuiDef.CubeGrant) temp[i];
2913        }
2914
2915        schemaGrant.cubeGrants[schemaGrant.cubeGrants.length - 1] = cubeGrant;
2916
2917        Object[] parentPathObjs = new Object[parentIndex + 1];
2918        for (int i = 0; i <= parentIndex; i++) {
2919            parentPathObjs[i] = tpath.getPathComponent(i);
2920        }
2921        TreePath parentPath = new TreePath(parentPathObjs);
2922        tree.setSelectionPath(parentPath.pathByAddingChild(cubeGrant));
2923
2924        refreshTree(tree.getSelectionPath());
2925        setTableCellFocus(0);
2926    }
2927
2928    protected void addDimensionGrant(ActionEvent evt) {
2929        TreePath tpath = null;
2930        Object path = null;
2931        if (evt.getSource() instanceof Component
2932            && ((Component)evt.getSource())
2933                .getParent() instanceof CustomJPopupMenu)
2934        {
2935            tpath = ((CustomJPopupMenu)((Component)evt.getSource())
2936                    .getParent()).getPath();
2937        } else {
2938            tpath = tree.getSelectionPath();
2939        }
2940        int parentIndex = -1;
2941        if (tpath != null) {
2942            for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0;
2943                parentIndex--)
2944            {
2945                final Object p = tpath.getPathComponent(parentIndex);
2946                if (p instanceof MondrianGuiDef.CubeGrant) {
2947                    path = p;
2948                    break;
2949                }
2950            }
2951        }
2952        //Object path = tree.getSelectionPath().getLastPathComponent();
2953        if (!(path instanceof MondrianGuiDef.CubeGrant)) {
2954            JOptionPane.showMessageDialog(
2955                this,
2956                getResourceConverter().getString(
2957                    "schemaExplorer.cubeGrantNotSelected.alert",
2958                    "Cube Grant not selected."),
2959                alert,
2960                JOptionPane.WARNING_MESSAGE);
2961            return;
2962        }
2963
2964        MondrianGuiDef.CubeGrant cubeGrant = (MondrianGuiDef.CubeGrant) path;
2965
2966        MondrianGuiDef.DimensionGrant dimeGrant =
2967            new MondrianGuiDef.DimensionGrant();
2968        dimeGrant.access = "";
2969
2970        //add cube to schema
2971        NodeDef[] temp = cubeGrant.dimensionGrants;
2972        cubeGrant.dimensionGrants =
2973            new MondrianGuiDef.DimensionGrant[temp.length + 1];
2974        for (int i = 0; i < temp.length; i++) {
2975            cubeGrant.dimensionGrants[i] =
2976                (MondrianGuiDef.DimensionGrant) temp[i];
2977        }
2978
2979        cubeGrant.dimensionGrants[cubeGrant.dimensionGrants.length - 1] =
2980            dimeGrant;
2981
2982        Object[] parentPathObjs = new Object[parentIndex + 1];
2983        for (int i = 0; i <= parentIndex; i++) {
2984            parentPathObjs[i] = tpath.getPathComponent(i);
2985        }
2986        TreePath parentPath = new TreePath(parentPathObjs);
2987        tree.setSelectionPath(parentPath.pathByAddingChild(dimeGrant));
2988
2989        refreshTree(tree.getSelectionPath());
2990        setTableCellFocus(0);
2991    }
2992
2993    protected void addHierarchyGrant(ActionEvent evt) {
2994        TreePath tpath = null;
2995        Object path = null;
2996        if (evt.getSource() instanceof Component
2997            && ((Component)evt.getSource())
2998                .getParent() instanceof CustomJPopupMenu)
2999        {
3000            tpath = ((CustomJPopupMenu)((Component)evt.getSource())
3001                    .getParent()).getPath();
3002        } else {
3003            tpath = tree.getSelectionPath();
3004        }
3005        int parentIndex = -1;
3006        if (tpath != null) {
3007            for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0;
3008                parentIndex--)
3009            {
3010                final Object p = tpath.getPathComponent(parentIndex);
3011                if (p instanceof MondrianGuiDef.CubeGrant) {
3012                    path = p;
3013                    break;
3014                }
3015            }
3016        }
3017
3018        if (!(path instanceof MondrianGuiDef.CubeGrant)) {
3019            JOptionPane.showMessageDialog(
3020                this,
3021                getResourceConverter().getString(
3022                    "schemaExplorer.cubeGrantNotSelected.alert",
3023                    "Cube Grant not selected."),
3024                alert,
3025                JOptionPane.WARNING_MESSAGE);
3026            return;
3027        }
3028
3029        MondrianGuiDef.CubeGrant cubeGrant = (MondrianGuiDef.CubeGrant) path;
3030
3031        MondrianGuiDef.HierarchyGrant hieGrant =
3032            new MondrianGuiDef.HierarchyGrant();
3033        hieGrant.access = "";
3034        hieGrant.memberGrants = new MondrianGuiDef.MemberGrant[0];
3035
3036        //add cube to schema
3037        NodeDef[] temp = cubeGrant.hierarchyGrants;
3038        cubeGrant.hierarchyGrants =
3039            new MondrianGuiDef.HierarchyGrant[temp.length + 1];
3040        for (int i = 0; i < temp.length; i++) {
3041            cubeGrant.hierarchyGrants[i] =
3042                (MondrianGuiDef.HierarchyGrant) temp[i];
3043        }
3044
3045        cubeGrant.hierarchyGrants[cubeGrant.hierarchyGrants.length - 1] =
3046            hieGrant;
3047
3048        Object[] parentPathObjs = new Object[parentIndex + 1];
3049        for (int i = 0; i <= parentIndex; i++) {
3050            parentPathObjs[i] = tpath.getPathComponent(i);
3051        }
3052        TreePath parentPath = new TreePath(parentPathObjs);
3053        tree.setSelectionPath(parentPath.pathByAddingChild(hieGrant));
3054
3055        refreshTree(tree.getSelectionPath());
3056        setTableCellFocus(0);
3057    }
3058
3059    protected void addMemberGrant(ActionEvent evt) {
3060        TreePath tpath = null;
3061        Object path = null;
3062        if (evt.getSource() instanceof Component
3063            && ((Component)evt.getSource())
3064                .getParent() instanceof CustomJPopupMenu)
3065        {
3066            tpath = ((CustomJPopupMenu)((Component)evt.getSource())
3067                    .getParent()).getPath();
3068        } else {
3069            tpath = tree.getSelectionPath();
3070        }
3071        int parentIndex = -1;
3072        if (tpath != null) {
3073            for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0;
3074                parentIndex--)
3075            {
3076                final Object p = tpath.getPathComponent(parentIndex);
3077                if (p instanceof MondrianGuiDef.HierarchyGrant) {
3078                    path = p;
3079                    break;
3080                }
3081            }
3082        }
3083
3084        if (!(path instanceof MondrianGuiDef.HierarchyGrant)) {
3085            JOptionPane.showMessageDialog(
3086                this,
3087                getResourceConverter().getString(
3088                    "schemaExplorer.hierarchyGrantNotSelected.alert",
3089                    "Hierarchy Grant not selected."),
3090                alert,
3091                JOptionPane.WARNING_MESSAGE);
3092            return;
3093        }
3094
3095        MondrianGuiDef.HierarchyGrant hieGrant =
3096            (MondrianGuiDef.HierarchyGrant) path;
3097
3098        MondrianGuiDef.MemberGrant memberGrant =
3099            new MondrianGuiDef.MemberGrant();
3100        memberGrant.access = "";
3101
3102        //add cube to schema
3103        NodeDef[] temp = hieGrant.memberGrants;
3104        hieGrant.memberGrants = new MondrianGuiDef.MemberGrant[temp.length + 1];
3105        for (int i = 0; i < temp.length; i++) {
3106            hieGrant.memberGrants[i] = (MondrianGuiDef.MemberGrant) temp[i];
3107        }
3108
3109        hieGrant.memberGrants[hieGrant.memberGrants.length - 1] = memberGrant;
3110
3111        Object[] parentPathObjs = new Object[parentIndex + 1];
3112        for (int i = 0; i <= parentIndex; i++) {
3113            parentPathObjs[i] = tpath.getPathComponent(i);
3114        }
3115        TreePath parentPath = new TreePath(parentPathObjs);
3116        tree.setSelectionPath(parentPath.pathByAddingChild(memberGrant));
3117
3118        refreshTree(tree.getSelectionPath());
3119        setTableCellFocus(0);
3120    }
3121
3122    protected void addAnnotations(ActionEvent evt) {
3123        TreePath tpath = null;
3124        if (evt.getSource() instanceof Component
3125            && ((Component)evt.getSource())
3126                .getParent() instanceof CustomJPopupMenu)
3127        {
3128            tpath = ((CustomJPopupMenu)((Component)evt.getSource())
3129                    .getParent()).getPath();
3130        } else {
3131            tpath = tree.getSelectionPath();
3132        }
3133        Object path = tree.getSelectionPath().getLastPathComponent();
3134        // Verify that the node selected in the tree is something that supports
3135        // annotations.
3136        if (path == null || (!(path instanceof MondrianGuiDef.Schema)
3137            && !(path instanceof MondrianGuiDef.CubeDimension)
3138            && !(path instanceof MondrianGuiDef.Cube)
3139            && !(path instanceof MondrianGuiDef.VirtualCube)
3140            && !(path instanceof MondrianGuiDef.VirtualCubeMeasure)
3141            && !(path instanceof MondrianGuiDef.Hierarchy)
3142            && !(path instanceof MondrianGuiDef.Level)
3143            && !(path instanceof MondrianGuiDef.Measure)
3144            && !(path instanceof MondrianGuiDef.CalculatedMember)
3145            && !(path instanceof MondrianGuiDef.NamedSet)
3146            && !(path instanceof MondrianGuiDef.Role)))
3147        {
3148            JOptionPane.showMessageDialog(
3149                this, getResourceConverter().getString(
3150                    "schemaExplorer.objectNotSelectedForAnnotations.alert",
3151                    "Please select an object that supports annotations."),
3152                    alert, JOptionPane.WARNING_MESSAGE);
3153            return;
3154        }
3155
3156        MondrianGuiDef.Annotations annotations =
3157            new MondrianGuiDef.Annotations();
3158        annotations.array = new MondrianGuiDef.Annotation[0];
3159        Class cls = path.getClass();
3160        try {
3161            Field field = cls.getField("annotations");
3162            field.set(path, annotations);
3163        } catch (Exception e) {
3164            throw new RuntimeException(e);
3165        }
3166        tree.setSelectionPath(tpath.pathByAddingChild(annotations));
3167
3168        refreshTree(tree.getSelectionPath());
3169    }
3170
3171    protected void addAnnotation(ActionEvent evt) {
3172        TreePath tpath = null;
3173        if (evt.getSource() instanceof Component
3174            && ((Component)evt.getSource())
3175                .getParent() instanceof CustomJPopupMenu)
3176        {
3177            tpath = ((CustomJPopupMenu)((Component)evt.getSource())
3178                    .getParent()).getPath();
3179        } else {
3180            tpath = tree.getSelectionPath();
3181        }
3182        Object path = tree.getSelectionPath().getLastPathComponent();
3183        if (!(path instanceof MondrianGuiDef.Annotations)) {
3184            JOptionPane.showMessageDialog(
3185                this, getResourceConverter().getString(
3186                    "schemaExplorer.annotationsNotSelected.alert",
3187                    "Annotations not selected."),
3188                    alert, JOptionPane.WARNING_MESSAGE);
3189            return;
3190        }
3191
3192        MondrianGuiDef.Annotations annotations =
3193            (MondrianGuiDef.Annotations) path;
3194        MondrianGuiDef.Annotation annotation = new MondrianGuiDef.Annotation();
3195        annotation.name =
3196            getNewName(
3197                getResourceConverter().getString(
3198                    "schemaExplorer.newAnnotation.title",
3199                    "New Annotation"),
3200                annotations.array);
3201
3202        MondrianGuiDef.Annotation[] temp = annotations.array;
3203        annotations.array = new MondrianGuiDef.Annotation[temp.length + 1];
3204        for (int i = 0; i < temp.length; i++) {
3205            annotations.array[i] = (MondrianGuiDef.Annotation) temp[i];
3206        }
3207        annotations.array[annotations.array.length - 1] = annotation;
3208        tree.setSelectionPath(tpath.pathByAddingChild(annotation));
3209
3210        refreshTree(tree.getSelectionPath());
3211        setTableCellFocus(0);
3212    }
3213
3214    /**
3215     * @param evt
3216     */
3217    protected void addLevel(ActionEvent evt) {
3218        TreePath tpath = null;
3219        Object path = null;
3220        if (evt.getSource() instanceof Component
3221            && ((Component)evt.getSource())
3222                .getParent() instanceof CustomJPopupMenu)
3223        {
3224            tpath = ((CustomJPopupMenu)((Component)evt.getSource())
3225                    .getParent()).getPath();
3226        } else {
3227            tpath = tree.getSelectionPath();
3228        }
3229        int parentIndex = -1;
3230        if (tpath != null) {
3231            for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0;
3232                parentIndex--)
3233            {
3234                final Object p = tpath.getPathComponent(parentIndex);
3235                if (p instanceof MondrianGuiDef.Hierarchy) {
3236                    path = p;
3237                    break;
3238                }
3239            }
3240        }
3241        if (!(path instanceof MondrianGuiDef.Hierarchy)) {
3242            JOptionPane.showMessageDialog(
3243                this,
3244                getResourceConverter().getString(
3245                    "schemaExplorer.hierarchyNotSelected.alert",
3246                    "Hierarchy not selected."),
3247                alert,
3248                JOptionPane.WARNING_MESSAGE);
3249            return;
3250        }
3251
3252        MondrianGuiDef.Hierarchy hierarchy = (MondrianGuiDef.Hierarchy) path;
3253
3254        MondrianGuiDef.Level level = new MondrianGuiDef.Level();
3255        level.uniqueMembers = false;
3256        level.visible = Boolean.TRUE;
3257        level.name = "";
3258        level.properties = new MondrianGuiDef.Property[0];
3259        level.name =
3260            getNewName(
3261                getResourceConverter().getString(
3262                    "schemaExplorer.newLevel.title",
3263                    "New Level"),
3264                hierarchy.levels);
3265        NodeDef[] temp = hierarchy.levels;
3266        hierarchy.levels = new MondrianGuiDef.Level[temp.length + 1];
3267        for (int i = 0; i < temp.length; i++) {
3268            hierarchy.levels[i] = (MondrianGuiDef.Level) temp[i];
3269        }
3270
3271        hierarchy.levels[hierarchy.levels.length - 1] = level;
3272
3273        Object[] parentPathObjs = new Object[parentIndex + 1];
3274        for (int i = 0; i <= parentIndex; i++) {
3275            parentPathObjs[i] = tpath.getPathComponent(i);
3276        }
3277        TreePath parentPath = new TreePath(parentPathObjs);
3278        tree.setSelectionPath(parentPath.pathByAddingChild(level));
3279
3280        refreshTree(tree.getSelectionPath());
3281        setTableCellFocus(0);
3282    }
3283
3284    protected void addSQL(ActionEvent evt) {
3285        TreePath tpath = null;
3286        Object path = null;
3287        if (evt.getSource() instanceof Component
3288            && ((Component)evt.getSource())
3289                .getParent() instanceof CustomJPopupMenu)
3290        {
3291            tpath = ((CustomJPopupMenu)((Component)evt.getSource())
3292                    .getParent()).getPath();
3293        } else {
3294            tpath = tree.getSelectionPath();
3295        }
3296        int parentIndex = -1;
3297        if (tpath != null) {
3298            for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0;
3299                parentIndex--)
3300            {
3301                Object p = tpath.getPathComponent(parentIndex);
3302                if (p instanceof MondrianGuiDef.ExpressionView
3303                    || p instanceof MondrianGuiDef.View)
3304                {
3305                    // parent could also be MondrianGuiDef.Expression?
3306                    path = p;
3307                    break;
3308                }
3309            }
3310        }
3311        //Object path = tree.getSelectionPath().getLastPathComponent();
3312        if (path == null) {
3313            JOptionPane.showMessageDialog(
3314                this, getResourceConverter().getString(
3315                    "schemaExplorer.sqlExpressionNotSelected.alert",
3316                    "Expression or View for SQL not selected."),
3317                alert,
3318                JOptionPane.WARNING_MESSAGE);
3319            return;
3320        }
3321
3322        MondrianGuiDef.SQL sql = new MondrianGuiDef.SQL();
3323        sql.dialect = "generic";
3324
3325        if (path instanceof MondrianGuiDef.ExpressionView) {
3326            MondrianGuiDef.ExpressionView expview =
3327                (MondrianGuiDef.ExpressionView) path;
3328            //add sql to ExpressionView
3329            NodeDef[] temp = expview.expressions;
3330            expview.expressions = new MondrianGuiDef.SQL[temp.length + 1];
3331            for (int i = 0; i < temp.length; i++) {
3332                expview.expressions[i] = (MondrianGuiDef.SQL) temp[i];
3333            }
3334
3335            expview.expressions[expview.expressions.length - 1] = sql;
3336        } else {
3337            // Its a View
3338            MondrianGuiDef.View view = (MondrianGuiDef.View) path;
3339            //add sql to ExpressionView
3340            NodeDef[] temp = view.selects;
3341            view.selects = new MondrianGuiDef.SQL[temp.length + 1];
3342            for (int i = 0; i < temp.length; i++) {
3343                view.selects[i] = (MondrianGuiDef.SQL) temp[i];
3344            }
3345
3346            view.selects[view.selects.length - 1] = sql;
3347        }
3348
3349        Object[] parentPathObjs = new Object[parentIndex + 1];
3350        for (int i = 0; i <= parentIndex; i++) {
3351            parentPathObjs[i] = tpath.getPathComponent(i);
3352        }
3353        TreePath parentPath = new TreePath(parentPathObjs);
3354        tree.setSelectionPath(parentPath.pathByAddingChild(sql));
3355
3356        refreshTree(tree.getSelectionPath());
3357        setTableCellFocus(0);
3358    }
3359
3360    protected void addScript(ActionEvent evt) {
3361        TreePath tpath = null;
3362        Object path = null;
3363        if (evt.getSource() instanceof Component
3364            && ((Component)evt.getSource())
3365                .getParent() instanceof CustomJPopupMenu)
3366        {
3367            tpath = ((CustomJPopupMenu)((Component)evt.getSource())
3368                    .getParent()).getPath();
3369        } else {
3370            tpath = tree.getSelectionPath();
3371        }
3372        int parentIndex = -1;
3373        if (tpath != null) {
3374            for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0;
3375                parentIndex--)
3376            {
3377                Object p = tpath.getPathComponent(parentIndex);
3378                if (p instanceof MondrianGuiDef.UserDefinedFunction
3379                    || p instanceof MondrianGuiDef.MemberFormatter
3380                    || p instanceof MondrianGuiDef.CellFormatter
3381                    || p instanceof MondrianGuiDef.PropertyFormatter)
3382                {
3383                    path = p;
3384                    break;
3385                }
3386            }
3387        }
3388        if (path == null) {
3389            JOptionPane.showMessageDialog(
3390                this, getResourceConverter().getString(
3391                    "schemaExplorer.userDefinedFunctionOrFormatterNotSelected.alert",
3392                    "User Defined Function or Formatter not selected."),
3393                alert,
3394                JOptionPane.WARNING_MESSAGE);
3395            return;
3396        }
3397
3398        final MondrianGuiDef.Script script = new MondrianGuiDef.Script();
3399
3400        if (path instanceof MondrianGuiDef.UserDefinedFunction) {
3401            final MondrianGuiDef.UserDefinedFunction parent =
3402                (MondrianGuiDef.UserDefinedFunction) path;
3403            parent.script = script;
3404        } else if (path instanceof MondrianGuiDef.CellFormatter) {
3405            final MondrianGuiDef.CellFormatter parent =
3406                (MondrianGuiDef.CellFormatter) path;
3407            parent.script = script;
3408        } else if (path instanceof MondrianGuiDef.MemberFormatter) {
3409            final MondrianGuiDef.MemberFormatter parent =
3410                (MondrianGuiDef.MemberFormatter) path;
3411            parent.script = script;
3412        } else if (path instanceof MondrianGuiDef.PropertyFormatter) {
3413            final MondrianGuiDef.PropertyFormatter parent =
3414                (MondrianGuiDef.PropertyFormatter) path;
3415            parent.script = script;
3416        }
3417
3418        Object[] parentPathObjs = new Object[parentIndex + 1];
3419        for (int i = 0; i <= parentIndex; i++) {
3420            parentPathObjs[i] = tpath.getPathComponent(i);
3421        }
3422        TreePath parentPath = new TreePath(parentPathObjs);
3423        tree.setSelectionPath(parentPath.pathByAddingChild(script));
3424
3425        refreshTree(tree.getSelectionPath());
3426        setTableCellFocus(0);
3427    }
3428
3429    protected void addCellFormatter(ActionEvent evt) {
3430        TreePath tpath = null;
3431        Object path = null;
3432        if (evt.getSource() instanceof Component
3433            && ((Component)evt.getSource())
3434                .getParent() instanceof CustomJPopupMenu)
3435        {
3436            tpath = ((CustomJPopupMenu)((Component)evt.getSource())
3437                    .getParent()).getPath();
3438        } else {
3439            tpath = tree.getSelectionPath();
3440        }
3441        int parentIndex = -1;
3442        if (tpath != null) {
3443            for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0;
3444                parentIndex--)
3445            {
3446                Object p = tpath.getPathComponent(parentIndex);
3447                if (p instanceof MondrianGuiDef.Measure
3448                    || p instanceof MondrianGuiDef.CalculatedMember)
3449                {
3450                    path = p;
3451                    break;
3452                }
3453            }
3454        }
3455        if (path == null) {
3456            JOptionPane.showMessageDialog(
3457                this, getResourceConverter().getString(
3458                    "schemaExplorer.measureOrCalculatedMemberNotSelected.alert",
3459                    "Measure or Calculated Member not selected."),
3460                alert,
3461                JOptionPane.WARNING_MESSAGE);
3462            return;
3463        }
3464
3465        final MondrianGuiDef.CellFormatter formatter =
3466            new MondrianGuiDef.CellFormatter();
3467
3468        if (path instanceof MondrianGuiDef.Measure) {
3469            final MondrianGuiDef.Measure parent =
3470                (MondrianGuiDef.Measure) path;
3471            parent.cellFormatter = formatter;
3472        } else if (path instanceof MondrianGuiDef.CalculatedMember) {
3473            final MondrianGuiDef.CalculatedMember parent =
3474                (MondrianGuiDef.CalculatedMember) path;
3475            parent.cellFormatter = formatter;
3476        }
3477
3478        Object[] parentPathObjs = new Object[parentIndex + 1];
3479        for (int i = 0; i <= parentIndex; i++) {
3480            parentPathObjs[i] = tpath.getPathComponent(i);
3481        }
3482        TreePath parentPath = new TreePath(parentPathObjs);
3483        tree.setSelectionPath(parentPath.pathByAddingChild(formatter));
3484
3485        refreshTree(tree.getSelectionPath());
3486        setTableCellFocus(0);
3487    }
3488
3489    private static class LevelInfo {
3490       MondrianGuiDef.Level level = null;
3491       Object[] parentPathObjs = null;
3492    }
3493
3494    protected LevelInfo getSelectedLevel(ActionEvent evt) {
3495        final LevelInfo info = new LevelInfo();
3496        TreePath tpath = null;
3497        Object path = null;
3498        if (evt.getSource() instanceof Component
3499            && ((Component)evt.getSource())
3500                .getParent() instanceof CustomJPopupMenu)
3501        {
3502            tpath = ((CustomJPopupMenu)((Component)evt.getSource())
3503                    .getParent()).getPath();
3504        } else {
3505            tpath = tree.getSelectionPath();
3506        }
3507        int parentIndex = -1;
3508
3509        if (tpath != null) {
3510            for (parentIndex = tpath.getPathCount() - 1;
3511                parentIndex >= 0; parentIndex--)
3512            {
3513                Object p = tpath.getPathComponent(parentIndex);
3514                if (p instanceof MondrianGuiDef.Level) {
3515                    path = p;
3516                    break;
3517                }
3518            }
3519        }
3520        if (path == null || !(path instanceof MondrianGuiDef.Level)) {
3521            JOptionPane.showMessageDialog(
3522                this, getResourceConverter().getString(
3523                    "schemaExplorer.levelNotSelected.alert",
3524                    "Level not selected."),
3525                alert,
3526                JOptionPane.WARNING_MESSAGE);
3527            return null;
3528        }
3529        info.level = (MondrianGuiDef.Level) path;
3530        info.parentPathObjs = new Object[parentIndex + 1];
3531        for (int i = 0; i <= parentIndex; i++) {
3532            info.parentPathObjs[i] = tpath.getPathComponent(i);
3533        }
3534
3535        return info;
3536    }
3537
3538    protected void addMemberFormatter(ActionEvent evt) {
3539        final LevelInfo info = getSelectedLevel(evt);
3540        if (info == null) {
3541            return;
3542        }
3543
3544        final MondrianGuiDef.MemberFormatter formatter =
3545            new MondrianGuiDef.MemberFormatter();
3546        info.level.memberFormatter = formatter;
3547
3548        TreePath parentPath = new TreePath(info.parentPathObjs);
3549        tree.setSelectionPath(parentPath.pathByAddingChild(formatter));
3550
3551        refreshTree(tree.getSelectionPath());
3552        setTableCellFocus(0);
3553    }
3554
3555    protected void addPropertyFormatter(ActionEvent evt) {
3556        TreePath tpath = null;
3557        Object path = null;
3558        if (evt.getSource() instanceof Component
3559            && ((Component)evt.getSource())
3560                .getParent() instanceof CustomJPopupMenu)
3561        {
3562            tpath = ((CustomJPopupMenu)((Component)evt.getSource())
3563                    .getParent()).getPath();
3564        } else {
3565            tpath = tree.getSelectionPath();
3566        }
3567        int parentIndex = -1;
3568        if (tpath != null) {
3569            for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0;
3570                parentIndex--)
3571            {
3572                Object p = tpath.getPathComponent(parentIndex);
3573                if (p instanceof MondrianGuiDef.Property) {
3574                    path = p;
3575                    break;
3576                }
3577            }
3578        }
3579        if (path == null) {
3580            JOptionPane.showMessageDialog(
3581                this, getResourceConverter().getString(
3582                    "schemaExplorer.propertyNotSelected.alert",
3583                    "Property not selected."),
3584                alert,
3585                JOptionPane.WARNING_MESSAGE);
3586            return;
3587        }
3588
3589        final MondrianGuiDef.PropertyFormatter formatter =
3590            new MondrianGuiDef.PropertyFormatter();
3591
3592        final MondrianGuiDef.Property parent =
3593            (MondrianGuiDef.Property) path;
3594        parent.propertyFormatter = formatter;
3595
3596        Object[] parentPathObjs = new Object[parentIndex + 1];
3597        for (int i = 0; i <= parentIndex; i++) {
3598            parentPathObjs[i] = tpath.getPathComponent(i);
3599        }
3600        TreePath parentPath = new TreePath(parentPathObjs);
3601        tree.setSelectionPath(parentPath.pathByAddingChild(formatter));
3602
3603        refreshTree(tree.getSelectionPath());
3604        setTableCellFocus(0);
3605    }
3606
3607    protected void addKeyExp(ActionEvent evt) {
3608        final LevelInfo info = getSelectedLevel(evt);
3609        if (info == null) {
3610            return;
3611        }
3612
3613        MondrianGuiDef.KeyExpression keyExp =
3614            new MondrianGuiDef.KeyExpression();
3615        keyExp.expressions = new MondrianGuiDef.SQL[1];    // min 1
3616        keyExp.expressions[0] = new MondrianGuiDef.SQL();
3617        keyExp.expressions[0].dialect = "generic";
3618        keyExp.expressions[0].cdata = "";
3619        info.level.keyExp = keyExp;
3620
3621        TreePath parentPath = new TreePath(info.parentPathObjs);
3622        tree.setSelectionPath(parentPath.pathByAddingChild(keyExp));
3623
3624        refreshTree(tree.getSelectionPath());
3625    }
3626
3627    protected void addNameExp(ActionEvent evt) {
3628        final LevelInfo info = getSelectedLevel(evt);
3629        if (info == null) {
3630            return;
3631        }
3632
3633        MondrianGuiDef.NameExpression nameExp =
3634            new MondrianGuiDef.NameExpression();
3635        nameExp.expressions = new MondrianGuiDef.SQL[1];    // min 1
3636        nameExp.expressions[0] = new MondrianGuiDef.SQL();
3637        nameExp.expressions[0].dialect = "generic";
3638        nameExp.expressions[0].cdata = "";
3639        info.level.nameExp = nameExp;
3640
3641        TreePath parentPath = new TreePath(info.parentPathObjs);
3642        tree.setSelectionPath(parentPath.pathByAddingChild(nameExp));
3643
3644        refreshTree(tree.getSelectionPath());
3645    }
3646
3647    protected void addOrdinalExp(ActionEvent evt) {
3648        final LevelInfo info = getSelectedLevel(evt);
3649        if (info == null) {
3650            return;
3651        }
3652
3653        MondrianGuiDef.OrdinalExpression ordinalExp =
3654            new MondrianGuiDef.OrdinalExpression();
3655        ordinalExp.expressions = new MondrianGuiDef.SQL[1];    // min 1
3656        ordinalExp.expressions[0] = new MondrianGuiDef.SQL();
3657        ordinalExp.expressions[0].dialect = "generic";
3658        ordinalExp.expressions[0].cdata = "";
3659        info.level.ordinalExp = ordinalExp;
3660
3661        TreePath parentPath = new TreePath(info.parentPathObjs);
3662        tree.setSelectionPath(parentPath.pathByAddingChild(ordinalExp));
3663
3664        refreshTree(tree.getSelectionPath());
3665    }
3666
3667    protected void addCaptionExp(ActionEvent evt) {
3668        final LevelInfo info = getSelectedLevel(evt);
3669        if (info == null) {
3670            return;
3671        }
3672
3673        MondrianGuiDef.CaptionExpression captionExp =
3674            new MondrianGuiDef.CaptionExpression();
3675        captionExp.expressions = new MondrianGuiDef.SQL[1];    // min 1
3676        captionExp.expressions[0] = new MondrianGuiDef.SQL();
3677        captionExp.expressions[0].dialect = "generic";
3678        captionExp.expressions[0].cdata = "";
3679        info.level.captionExp = captionExp;
3680
3681        TreePath parentPath = new TreePath(info.parentPathObjs);
3682        tree.setSelectionPath(parentPath.pathByAddingChild(captionExp));
3683
3684        refreshTree(tree.getSelectionPath());
3685    }
3686
3687    protected void addParentExp(ActionEvent evt) {
3688        final LevelInfo info = getSelectedLevel(evt);
3689        if (info == null) {
3690            return;
3691        }
3692
3693        MondrianGuiDef.ParentExpression parentExp =
3694            new MondrianGuiDef.ParentExpression();
3695        parentExp.expressions = new MondrianGuiDef.SQL[1];    // min 1
3696        parentExp.expressions[0] = new MondrianGuiDef.SQL();
3697        parentExp.expressions[0].dialect = "generic";
3698        parentExp.expressions[0].cdata = "";
3699        info.level.parentExp = parentExp;
3700
3701        TreePath parentPath = new TreePath(info.parentPathObjs);
3702        tree.setSelectionPath(parentPath.pathByAddingChild(parentExp));
3703
3704        refreshTree(tree.getSelectionPath());
3705    }
3706
3707    protected void addMeasureExp(ActionEvent evt) {
3708        TreePath tpath = null;
3709        Object path = null;
3710        if (evt.getSource() instanceof Component
3711            && ((Component)evt.getSource())
3712                .getParent() instanceof CustomJPopupMenu)
3713        {
3714            tpath = ((CustomJPopupMenu)((Component)evt.getSource())
3715                    .getParent()).getPath();
3716        } else {
3717            tpath = tree.getSelectionPath();
3718        }
3719        int parentIndex = -1;
3720        if (tpath != null) {
3721            for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0;
3722                parentIndex--)
3723            {
3724                final Object p = tpath.getPathComponent(parentIndex);
3725                if (p instanceof MondrianGuiDef.Measure) {
3726                    path = p;
3727                    break;
3728                }
3729            }
3730        }
3731        if (!(path instanceof MondrianGuiDef.Measure)) {
3732            JOptionPane.showMessageDialog(
3733                this,
3734                getResourceConverter().getString(
3735                    "schemaExplorer.measureNotSelected.alert",
3736                    "Measure not selected."),
3737                alert,
3738                JOptionPane.WARNING_MESSAGE);
3739            return;
3740        }
3741
3742        MondrianGuiDef.Measure measure = (MondrianGuiDef.Measure) path;
3743
3744        MondrianGuiDef.MeasureExpression measureExp =
3745            new MondrianGuiDef.MeasureExpression();
3746        measureExp.expressions = new MondrianGuiDef.SQL[1];    // min 1
3747        measureExp.expressions[0] = new MondrianGuiDef.SQL();
3748        measureExp.expressions[0].dialect = "generic";
3749        measureExp.expressions[0].cdata = "";
3750        measure.measureExp = measureExp;
3751
3752        Object[] parentPathObjs = new Object[parentIndex + 1];
3753        for (int i = 0; i <= parentIndex; i++) {
3754            parentPathObjs[i] = tpath.getPathComponent(i);
3755        }
3756        TreePath parentPath = new TreePath(parentPathObjs);
3757        tree.setSelectionPath(parentPath.pathByAddingChild(measureExp));
3758
3759        refreshTree(tree.getSelectionPath());
3760    }
3761
3762    protected void addFormula(ActionEvent evt) {
3763        TreePath tpath = null;
3764        Object path = null;
3765        if (evt.getSource() instanceof Component
3766            && ((Component)evt.getSource())
3767                .getParent() instanceof CustomJPopupMenu)
3768        {
3769            tpath = ((CustomJPopupMenu)((Component)evt.getSource())
3770                    .getParent()).getPath();
3771        } else {
3772            tpath = tree.getSelectionPath();
3773        }
3774        int parentIndex = -1;
3775        if (tpath != null) {
3776            for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0;
3777                parentIndex--)
3778            {
3779                final Object p = tpath.getPathComponent(parentIndex);
3780                if (p instanceof MondrianGuiDef.NamedSet
3781                    || p instanceof MondrianGuiDef.CalculatedMember)
3782                {
3783                    path = p;
3784                    break;
3785                }
3786            }
3787        }
3788
3789        if (!(path instanceof MondrianGuiDef.NamedSet
3790              || path instanceof MondrianGuiDef.CalculatedMember))
3791        {
3792            JOptionPane.showMessageDialog(
3793                this,
3794                getResourceConverter().getString(
3795                    "schemaExplorer.namedsetOrCalcMemberNotSelected.alert",
3796                    "Named Set or Calculated Member not selected."),
3797                alert,
3798                JOptionPane.WARNING_MESSAGE);
3799            return;
3800        }
3801
3802        MondrianGuiDef.Formula formulaElement = new MondrianGuiDef.Formula();
3803        formulaElement.cdata = "";
3804
3805        if (path instanceof MondrianGuiDef.NamedSet) {
3806            MondrianGuiDef.NamedSet ns = (MondrianGuiDef.NamedSet) path;
3807            ns.formulaElement = formulaElement;
3808        } else if (path instanceof MondrianGuiDef.CalculatedMember) {
3809            MondrianGuiDef.CalculatedMember ns =
3810                (MondrianGuiDef.CalculatedMember) path;
3811            ns.formulaElement = formulaElement;
3812        }
3813
3814        Object[] parentPathObjs = new Object[parentIndex + 1];
3815        for (int i = 0; i <= parentIndex; i++) {
3816            parentPathObjs[i] = tpath.getPathComponent(i);
3817        }
3818        TreePath parentPath = new TreePath(parentPathObjs);
3819        tree.setSelectionPath(parentPath.pathByAddingChild(formulaElement));
3820
3821        refreshTree(tree.getSelectionPath());
3822    }
3823
3824    protected void addTable(ActionEvent evt) {
3825        MondrianGuiDef.RelationOrJoin relation = new MondrianGuiDef.Table(
3826            "", "Table", "", null);
3827        addRelation(evt, relation);
3828    }
3829
3830    protected void addJoin(ActionEvent evt) {
3831        MondrianGuiDef.RelationOrJoin relation = new MondrianGuiDef.Join(
3832            "",
3833            "",
3834            new MondrianGuiDef.Table("", "Table 1", "", null),
3835            "",
3836            "",
3837            new MondrianGuiDef.Table("", "Table 2", "", null));
3838        addRelation(evt, relation);
3839    }
3840
3841    protected void addView(ActionEvent evt) {
3842        MondrianGuiDef.View view = new MondrianGuiDef.View();
3843
3844        view.alias = "";
3845
3846        view.selects = new MondrianGuiDef.SQL[1];
3847
3848        view.selects[0] = new MondrianGuiDef.SQL();
3849        view.selects[0].dialect = "generic";
3850        view.selects[0].cdata = "";
3851
3852        addRelation(evt, view);
3853    }
3854
3855    protected void addInlineTable(ActionEvent evt) {
3856        MondrianGuiDef.InlineTable inlineTable =
3857            new MondrianGuiDef.InlineTable();
3858
3859        inlineTable.alias = "";
3860        inlineTable.columnDefs = new MondrianGuiDef.ColumnDefs();
3861        inlineTable.rows = new MondrianGuiDef.Rows();
3862
3863        addRelation(evt, inlineTable);
3864    }
3865
3866    protected void addRelation(
3867        ActionEvent evt, MondrianGuiDef.RelationOrJoin relation)
3868    {
3869        TreePath tpath = null;
3870        Object path = null;
3871        if (evt.getSource() instanceof Component
3872                && ((Component)evt.getSource()).getParent()
3873                instanceof CustomJPopupMenu)
3874        {
3875            tpath = ((CustomJPopupMenu)((Component)evt.getSource())
3876                .getParent()).getPath();
3877        } else {
3878            tpath = tree.getSelectionPath();
3879        }
3880        int parentIndex = -1;
3881        if (tpath != null) {
3882            for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0;
3883                parentIndex--)
3884            {
3885                Object p = tpath.getPathComponent(parentIndex);
3886                if (p instanceof MondrianGuiDef.Hierarchy
3887                    || p instanceof MondrianGuiDef.Cube)
3888                {
3889                    path = p;
3890                    break;
3891                }
3892            }
3893        }
3894
3895        if (path instanceof MondrianGuiDef.Hierarchy) {
3896            MondrianGuiDef.Hierarchy h = (MondrianGuiDef.Hierarchy) path;
3897
3898            //add relation to hierarchy
3899            h.relation = relation;
3900        } else if (path instanceof MondrianGuiDef.Cube) {
3901            if (!(relation instanceof MondrianGuiDef.Relation)) {
3902                JOptionPane.showMessageDialog(
3903                    this, getResourceConverter().getString(
3904                        "schemaExplorer.relationOrJoinNotRelation.alert",
3905                        "Can't add a Join."),
3906                    alert,
3907                    JOptionPane.WARNING_MESSAGE);
3908                return;
3909            }
3910
3911            MondrianGuiDef.Cube cube = (MondrianGuiDef.Cube) path;
3912
3913            //add relation to cube
3914            cube.fact = (MondrianGuiDef.Relation) relation;
3915        } else {
3916            JOptionPane.showMessageDialog(
3917                this, getResourceConverter().getString(
3918                    "schemaExplorer.hierarchyOrCubeNotSelected.alert",
3919                    "Hierarchy or Cube not selected."),
3920                alert,
3921                JOptionPane.WARNING_MESSAGE);
3922            return;
3923        }
3924
3925        Object[] parentPathObjs = new Object[parentIndex + 1];
3926        for (int i = 0; i <= parentIndex; i++) {
3927            parentPathObjs[i] = tpath.getPathComponent(i);
3928        }
3929        TreePath parentPath = new TreePath(parentPathObjs);
3930        tree.setSelectionPath(parentPath.pathByAddingChild(relation));
3931
3932        refreshTree(tree.getSelectionPath());
3933        setTableCellFocus(0);
3934    }
3935
3936    protected void addHierarchy(ActionEvent evt) {
3937        TreePath tpath = null;
3938        Object path = null;
3939        if (evt.getSource() instanceof Component
3940            && ((Component)evt.getSource())
3941                .getParent() instanceof CustomJPopupMenu)
3942        {
3943            tpath = ((CustomJPopupMenu)((Component)evt.getSource())
3944                    .getParent()).getPath();
3945        } else {
3946            tpath = tree.getSelectionPath();
3947        }
3948        int parentIndex = -1;
3949        if (tpath != null) {
3950            for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0;
3951                parentIndex--)
3952            {
3953                final Object p = tpath.getPathComponent(parentIndex);
3954                if (p instanceof MondrianGuiDef.Dimension) {
3955                    path = p;
3956                    break;
3957                }
3958            }
3959        }
3960
3961        if (!(path instanceof MondrianGuiDef.Dimension)) {
3962            JOptionPane.showMessageDialog(
3963                this,
3964                getResourceConverter().getString(
3965                    "schemaExplorer.dimensionNotSelected.alert",
3966                    "Dimension not selected."),
3967                alert,
3968                JOptionPane.WARNING_MESSAGE);
3969            return;
3970        }
3971
3972        MondrianGuiDef.Dimension dimension = (MondrianGuiDef.Dimension) path;
3973
3974        MondrianGuiDef.Hierarchy hierarchy = new MondrianGuiDef.Hierarchy();
3975
3976        hierarchy.name = "";
3977        hierarchy.hasAll = Boolean.TRUE; //new Boolean(false);
3978        hierarchy.visible = Boolean.TRUE;
3979        hierarchy.levels = new MondrianGuiDef.Level[0];
3980        hierarchy.memberReaderParameters =
3981            new MondrianGuiDef.MemberReaderParameter[0];
3982        hierarchy.name =
3983            getNewName(
3984                getResourceConverter().getString(
3985                    "schemaExplorer.newHierarchy.title",
3986                    "New Hierarchy"),
3987                dimension.hierarchies);
3988        NodeDef[] temp = dimension.hierarchies;
3989        dimension.hierarchies = new MondrianGuiDef.Hierarchy[temp.length + 1];
3990        for (int i = 0; i < temp.length; i++) {
3991            dimension.hierarchies[i] = (MondrianGuiDef.Hierarchy) temp[i];
3992        }
3993
3994        dimension.hierarchies[dimension.hierarchies.length - 1] = hierarchy;
3995
3996        Object[] parentPathObjs = new Object[parentIndex + 1];
3997        for (int i = 0; i <= parentIndex; i++) {
3998            parentPathObjs[i] = tpath.getPathComponent(i);
3999        }
4000        TreePath parentPath = new TreePath(parentPathObjs);
4001        tree.setSelectionPath(parentPath.pathByAddingChild(hierarchy));
4002        refreshTree(tree.getSelectionPath());
4003        setTableCellFocus(0);
4004    }
4005
4006
4007    protected void moveLevelUp(ActionEvent evt) {
4008        final LevelInfo info = getSelectedLevel(evt);
4009        if (info == null) {
4010            return;
4011        }
4012
4013        MondrianGuiDef.Hierarchy hierarchy =
4014            (MondrianGuiDef.Hierarchy)
4015                info.parentPathObjs[info.parentPathObjs.length - 2];
4016
4017        int loc = -1;
4018        for (int i = 0; i < hierarchy.levels.length; i++) {
4019            if (hierarchy.levels[i] == info.level) {
4020              loc = i;
4021              break;
4022            }
4023        }
4024
4025        if (loc > 0) {
4026          MondrianGuiDef.Level tmp = hierarchy.levels[loc - 1];
4027          hierarchy.levels[loc - 1] = info.level;
4028          hierarchy.levels[loc] = tmp;
4029        }
4030
4031        TreePath parentPath = new TreePath(info.parentPathObjs);
4032        tree.setSelectionPath(parentPath);
4033        refreshTree(tree.getSelectionPath());
4034        setTableCellFocus(0);
4035    }
4036
4037    protected void moveLevelDown(ActionEvent evt) {
4038        final LevelInfo info = getSelectedLevel(evt);
4039        if (info == null) {
4040            return;
4041        }
4042
4043        MondrianGuiDef.Hierarchy hierarchy =
4044            (MondrianGuiDef.Hierarchy)
4045                info.parentPathObjs[info.parentPathObjs.length - 2];
4046
4047        int loc = -1;
4048        for (int i = 0; i < hierarchy.levels.length; i++) {
4049            if (hierarchy.levels[i] == info.level) {
4050              loc = i;
4051              break;
4052            }
4053        }
4054
4055        if (loc < hierarchy.levels.length - 1) {
4056          MondrianGuiDef.Level tmp = hierarchy.levels[loc + 1];
4057          hierarchy.levels[loc + 1] = info.level;
4058          hierarchy.levels[loc] = tmp;
4059        }
4060
4061        TreePath parentPath = new TreePath(info.parentPathObjs);
4062        tree.setSelectionPath(parentPath);
4063        refreshTree(tree.getSelectionPath());
4064        setTableCellFocus(0);
4065    }
4066
4067
4068    /**
4069     * @param evt
4070     */
4071    protected void addProperty(ActionEvent evt) {
4072        final LevelInfo info = getSelectedLevel(evt);
4073        if (info == null) {
4074            return;
4075        }
4076
4077        MondrianGuiDef.Property property = new MondrianGuiDef.Property();
4078        property.name = "";
4079
4080        if (info.level.properties == null) {
4081            info.level.properties = new MondrianGuiDef.Property[0];
4082        }
4083        property.name =
4084            getNewName(
4085                getResourceConverter().getString(
4086                    "schemaExplorer.newProperty.title",
4087                    "New Property"),
4088                info.level.properties);
4089        NodeDef[] temp = info.level.properties;
4090        info.level.properties = new MondrianGuiDef.Property[temp.length + 1];
4091        for (int i = 0; i < temp.length; i++) {
4092            info.level.properties[i] = (MondrianGuiDef.Property) temp[i];
4093        }
4094
4095        info.level.properties[info.level.properties.length - 1] = property;
4096
4097        TreePath parentPath = new TreePath(info.parentPathObjs);
4098        tree.setSelectionPath(parentPath.pathByAddingChild(property));
4099
4100        refreshTree(tree.getSelectionPath());
4101        setTableCellFocus(0);
4102    }
4103
4104    /**
4105     * @param evt
4106     */
4107    protected void addCalculatedMemberProperty(ActionEvent evt) {
4108        TreePath tpath = null;
4109        Object path = null;
4110        if (evt.getSource() instanceof Component
4111            && ((Component)evt.getSource())
4112                .getParent() instanceof CustomJPopupMenu)
4113        {
4114            tpath = ((CustomJPopupMenu)((Component)evt.getSource())
4115                    .getParent()).getPath();
4116        } else {
4117            tpath = tree.getSelectionPath();
4118        }
4119        int parentIndex = -1;
4120        if (tpath != null) {
4121            for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0;
4122                parentIndex--)
4123            {
4124                final Object p = tpath.getPathComponent(parentIndex);
4125                if (p instanceof MondrianGuiDef.CalculatedMember
4126                    || p instanceof MondrianGuiDef.Measure)
4127                {
4128                    path = p;
4129                    break;
4130                }
4131            }
4132        }
4133        if (path instanceof MondrianGuiDef.CalculatedMember) {
4134            addCalcMemberPropToCalcMember(
4135                (MondrianGuiDef.CalculatedMember)path, parentIndex, tpath);
4136        } else if (path instanceof MondrianGuiDef.Measure) {
4137            addCalcMemberPropToMeasure(
4138                (MondrianGuiDef.Measure)path, parentIndex, tpath);
4139        } else {
4140            JOptionPane.showMessageDialog(
4141                this, getResourceConverter().getString(
4142                    "schemaExplorer.calculatedMemberNotSelected.alert",
4143                    "Calculated Member or Measure not selected."),
4144                    alert, JOptionPane.WARNING_MESSAGE);
4145        }
4146    }
4147
4148    protected void addCalcMemberPropToCalcMember(
4149        MondrianGuiDef.CalculatedMember calcMember,
4150        int parentIndex,
4151        TreePath tpath)
4152    {
4153        MondrianGuiDef.CalculatedMemberProperty property =
4154            new MondrianGuiDef.CalculatedMemberProperty();
4155        property.name = "";
4156
4157        if (calcMember.memberProperties == null) {
4158            calcMember.memberProperties =
4159                new MondrianGuiDef.CalculatedMemberProperty[0];
4160        }
4161        property.name =
4162            getNewName(
4163                getResourceConverter().getString(
4164                    "schemaExplorer.newProperty.title",
4165                    "New Property"),
4166                calcMember.memberProperties);
4167        NodeDef[] temp = calcMember.memberProperties;
4168        calcMember.memberProperties =
4169            new MondrianGuiDef.CalculatedMemberProperty[temp.length + 1];
4170        for (int i = 0; i < temp.length; i++) {
4171            calcMember.memberProperties[i] =
4172                (MondrianGuiDef.CalculatedMemberProperty) temp[i];
4173        }
4174
4175        calcMember.memberProperties[calcMember.memberProperties.length - 1] =
4176            property;
4177
4178        Object[] parentPathObjs = new Object[parentIndex + 1];
4179        for (int i = 0; i <= parentIndex; i++) {
4180            parentPathObjs[i] = tpath.getPathComponent(i);
4181        }
4182        TreePath parentPath = new TreePath(parentPathObjs);
4183        tree.setSelectionPath(parentPath.pathByAddingChild(property));
4184
4185        refreshTree(tree.getSelectionPath());
4186        setTableCellFocus(0);
4187    }
4188
4189    protected void addCalcMemberPropToMeasure(
4190        MondrianGuiDef.Measure measure,
4191        int parentIndex,
4192        TreePath tpath)
4193    {
4194        MondrianGuiDef.CalculatedMemberProperty property =
4195            new MondrianGuiDef.CalculatedMemberProperty();
4196        property.name = "";
4197
4198        if (measure.memberProperties == null) {
4199            measure.memberProperties =
4200                new MondrianGuiDef.CalculatedMemberProperty[0];
4201        }
4202        property.name =
4203            getNewName(
4204                getResourceConverter().getString(
4205                    "schemaExplorer.newProperty.title",
4206                    "New Property"),
4207                measure.memberProperties);
4208        NodeDef[] temp = measure.memberProperties;
4209        measure.memberProperties =
4210            new MondrianGuiDef.CalculatedMemberProperty[temp.length + 1];
4211        for (int i = 0; i < temp.length; i++) {
4212            measure.memberProperties[i] =
4213                (MondrianGuiDef.CalculatedMemberProperty) temp[i];
4214        }
4215
4216        measure.memberProperties[measure.memberProperties.length - 1] =
4217            property;
4218
4219        Object[] parentPathObjs = new Object[parentIndex + 1];
4220        for (int i = 0; i <= parentIndex; i++) {
4221            parentPathObjs[i] = tpath.getPathComponent(i);
4222        }
4223        TreePath parentPath = new TreePath(parentPathObjs);
4224        tree.setSelectionPath(parentPath.pathByAddingChild(property));
4225
4226        refreshTree(tree.getSelectionPath());
4227        setTableCellFocus(0);
4228    }
4229
4230    /**
4231     * @param evt
4232     */
4233    protected void addClosure(ActionEvent evt) {
4234        TreePath tpath = null;
4235        Object path = null;
4236        if (evt.getSource() instanceof Component
4237            && ((Component)evt.getSource())
4238                .getParent() instanceof CustomJPopupMenu)
4239        {
4240            tpath = ((CustomJPopupMenu)((Component)evt.getSource())
4241                    .getParent()).getPath();
4242        } else {
4243            tpath = tree.getSelectionPath();
4244        }
4245        int parentIndex = -1;
4246        if (tpath != null) {
4247            for (parentIndex = tpath.getPathCount() - 1; parentIndex >= 0;
4248                parentIndex--)
4249            {
4250                final Object p = tpath.getPathComponent(parentIndex);
4251                if (p instanceof MondrianGuiDef.Level) {
4252                    path = p;
4253                    break;
4254                }
4255            }
4256        }
4257
4258        if (!(path instanceof MondrianGuiDef.Level)) {
4259            JOptionPane.showMessageDialog(
4260                this, getResourceConverter().getString(
4261                    "schemaExplorer.levelNotSelected.alert",
4262                    "Level not selected."), alert, JOptionPane.WARNING_MESSAGE);
4263            return;
4264        }
4265
4266        MondrianGuiDef.Level level = (MondrianGuiDef.Level) path;
4267        MondrianGuiDef.Closure closure = new MondrianGuiDef.Closure();
4268        closure.parentColumn = "";
4269        closure.childColumn = "";
4270        closure.table = new MondrianGuiDef.Table("", "Table", "", null);
4271        if (level.closure == null) {
4272            level.closure = closure;
4273        }
4274
4275        Object[] parentPathObjs = new Object[parentIndex + 1];
4276        for (int i = 0; i <= parentIndex; i++) {
4277            parentPathObjs[i] = tpath.getPathComponent(i);
4278        }
4279        TreePath parentPath = new TreePath(parentPathObjs);
4280        tree.setSelectionPath(parentPath.pathByAddingChild(closure));
4281
4282        refreshTree(tree.getSelectionPath());
4283        setTableCellFocus(0);
4284    }
4285
4286    public MondrianGuiDef.Schema getSchema() {
4287        return this.schema;
4288    }
4289
4290    /**
4291     * returns the schema file
4292     *
4293     * @return File
4294     */
4295    public File getSchemaFile() {
4296        return this.schemaFile;
4297    }
4298
4299    /**
4300     * sets the schema file
4301     *
4302     * @param f
4303     */
4304    public void setSchemaFile(File f) {
4305        this.schemaFile = f;
4306    }
4307
4308    public Object lastSelected;
4309
4310    /**
4311     * Called whenever the value of the selection changes.
4312     *
4313     * @param e the event that characterizes the change.
4314     */
4315    public void valueChanged(TreeSelectionEvent e) {
4316        if (propertyTable.isEditing() && (lastSelected != e.getPath()
4317            .getLastPathComponent()))
4318        {
4319            SchemaPropertyCellEditor sce =
4320                (SchemaPropertyCellEditor) propertyTable.getCellEditor();
4321            if (sce != null) {
4322                TreeSelectionEvent e2 = e;
4323                sce.stopCellEditing();
4324                e = e2;
4325            }
4326        }
4327        lastSelected = e.getPath().getLastPathComponent();
4328
4329        String selectedFactTable = null;
4330        String selectedFactTableSchema = null;
4331
4332        for (int i = e.getPath().getPathCount() - 1; i >= 0; i--) {
4333            Object comp = e.getPath().getPathComponent(i);
4334            if (comp instanceof MondrianGuiDef.Cube) {
4335                final MondrianGuiDef.Cube cube = (MondrianGuiDef.Cube) comp;
4336                if (cube.fact instanceof MondrianGuiDef.Table) {
4337                    final MondrianGuiDef.Table table =
4338                        (MondrianGuiDef.Table) cube.fact;
4339                    selectedFactTable = table.name;
4340                    selectedFactTableSchema = table.schema;
4341                }
4342            }
4343        }
4344        TreePath tpath = e.getPath();
4345        Object o = tpath.getLastPathComponent();
4346        Object po = null;
4347        // look for parent information
4348        TreePath parentTpath = tpath.getParentPath();
4349        String parentName = "";
4350        String elementName = "";
4351        if (parentTpath != null) {
4352            po = parentTpath.getLastPathComponent();
4353            Class parentClassName = po.getClass();
4354            try {
4355                Field nameField = po.getClass().getField("name");
4356                elementName = (String) nameField.get(po);
4357                if (elementName == null) {
4358                    elementName = "";
4359                } else {
4360                    elementName = "'" + elementName + "'";
4361                }
4362            } catch (Exception ex) {
4363                elementName = "";
4364            }
4365            int pos = parentClassName.toString().lastIndexOf("$");
4366            if (pos > 0) {
4367                parentName = parentClassName.toString().substring(pos + 1);
4368            }
4369        }
4370
4371        // Begin : For xml edit mode display
4372        StringWriter sxml = new StringWriter();
4373        org.eigenbase.xom.XMLOutput pxml =
4374            new org.eigenbase.xom.XMLOutput(sxml);
4375        pxml.setIndentString("    ");
4376        pxml.setAlwaysQuoteCData(true);
4377
4378        // End : For xml edit mode display
4379
4380        String[] pNames = DEF_DEFAULT;
4381
4382        validStatusLabel.setText(renderer.invalid(tree, e.getPath(), o));
4383        validStatusLabel2.setText(validStatusLabel.getText());
4384
4385        if (o instanceof MondrianGuiDef.Column) {
4386            pNames = DEF_COLUMN;
4387            targetLabel.setText(
4388                getResourceConverter().getString(
4389                    "common.column.title", LBL_COLUMN));
4390        } else if (o instanceof MondrianGuiDef.Cube) {
4391            pNames = DEF_CUBE;
4392            targetLabel.setText(
4393                getResourceConverter().getString(
4394                    "common.cube.title", LBL_CUBE));
4395            ((MondrianGuiDef.Cube) o).displayXML(pxml, 0);
4396        } else if (o instanceof MondrianGuiDef.Dimension) {
4397            pNames = DEF_DIMENSION;
4398            if (po instanceof MondrianGuiDef.Schema) {
4399                targetLabel.setText(
4400                    getResourceConverter().getString(
4401                        "common.sharedDimension.title", "Shared Dimension"));
4402            } else {
4403                targetLabel.setText(
4404                    getResourceConverter().getFormattedString(
4405                        "schemaExplorer.dimensionElementParent.title",
4406                        "Dimension for {0} {1}",
4407                        elementName,
4408                        parentName));
4409            }
4410            ((MondrianGuiDef.Dimension) o).displayXML(pxml, 0);
4411        } else if (o instanceof MondrianGuiDef.DimensionUsage) {
4412            pNames = DEF_DIMENSION_USAGE;
4413            targetLabel.setText(
4414                getResourceConverter().getFormattedString(
4415                    "schemaExplorer.dimensionUsageForElement.title",
4416                    "Dimension Usage for {0} {1}",
4417                    elementName,
4418                    parentName));
4419            ((MondrianGuiDef.DimensionUsage) o).displayXML(pxml, 0);
4420        } else if (o instanceof MondrianGuiDef.KeyExpression) {
4421            pNames = DEF_DEFAULT;
4422            targetLabel.setText(
4423                getResourceConverter().getString(
4424                    "common.keyExpression.title", LBL_KEY_EXPRESSION));
4425            ((MondrianGuiDef.ExpressionView) o).displayXML(pxml, 0);
4426        } else if (o instanceof MondrianGuiDef.NameExpression) {
4427            pNames = DEF_DEFAULT;
4428            targetLabel.setText(
4429                getResourceConverter().getString(
4430                    "common.nameExpression.title", LBL_NAME_EXPRESSION));
4431            ((MondrianGuiDef.ExpressionView) o).displayXML(pxml, 0);
4432        } else if (o instanceof MondrianGuiDef.OrdinalExpression) {
4433            pNames = DEF_DEFAULT;
4434            targetLabel.setText(
4435                getResourceConverter().getString(
4436                    "common.ordinalExpression.title", LBL_ORDINAL_EXPRESSION));
4437            ((MondrianGuiDef.ExpressionView) o).displayXML(pxml, 0);
4438        } else if (o instanceof MondrianGuiDef.ParentExpression) {
4439            pNames = DEF_DEFAULT;
4440            targetLabel.setText(
4441                getResourceConverter().getString(
4442                    "common.parentExpression.title", LBL_PARENT_EXPRESSION));
4443            ((MondrianGuiDef.ExpressionView) o).displayXML(pxml, 0);
4444        } else if (o instanceof MondrianGuiDef.ExpressionView) {
4445            pNames = DEF_EXPRESSION_VIEW;
4446            targetLabel.setText(
4447                getResourceConverter().getString(
4448                    "common.expressionView.title", LBL_EXPRESSION_VIEW));
4449            ((MondrianGuiDef.ExpressionView) o).displayXML(pxml, 0);
4450        } else if (o instanceof MondrianGuiDef.MeasureExpression) {
4451            pNames = DEF_DEFAULT;
4452            targetLabel.setText(
4453                getResourceConverter().getString(
4454                    "common.measureExpression.title", LBL_MEASURE_EXPRESSION));
4455            ((MondrianGuiDef.ExpressionView) o).displayXML(pxml, 0);
4456        } else if (o instanceof MondrianGuiDef.Hierarchy) {
4457            pNames = DEF_HIERARCHY;
4458            targetLabel.setText(
4459                getResourceConverter().getFormattedString(
4460                    "schemaExplorer.hierarchyElementParent.title",
4461                    "Hierarchy for {0} {1}",
4462                    elementName,
4463                    parentName));
4464            ((MondrianGuiDef.Hierarchy) o).displayXML(pxml, 0);
4465        } else if (o instanceof MondrianGuiDef.Join) {
4466            pNames = DEF_JOIN;
4467            if (parentName.equalsIgnoreCase("Join")) {
4468                Object parentJoin = parentTpath.getLastPathComponent();
4469                int indexOfChild = tree.getModel().getIndexOfChild(
4470                    parentJoin, o);
4471                switch (indexOfChild) {
4472                case 0:
4473                    targetLabel.setText(
4474                        getResourceConverter().getString(
4475                            "common.leftJoin.title", "Left : " + LBL_JOIN));
4476                    break;
4477                case 1:
4478                    targetLabel.setText(
4479                        getResourceConverter().getString(
4480                            "common.rightJoin.title", "Right : " + LBL_JOIN));
4481                }
4482            } else {
4483                targetLabel.setText(
4484                    getResourceConverter().getFormattedString(
4485                        "schemaExplorer.generalJoinForElement.title",
4486                        "Join for {0} {1}",
4487                        elementName,
4488                        parentName));
4489            }
4490            ((MondrianGuiDef.Join) o).displayXML(pxml, 0);
4491        } else if (o instanceof MondrianGuiDef.Level) {
4492            pNames = DEF_LEVEL;
4493            targetLabel.setText(
4494                getResourceConverter().getFormattedString(
4495                    "schemaExplorer.levelForElement.title",
4496                    "Level for {0} {1}",
4497                    elementName,
4498                    parentName));
4499            ((MondrianGuiDef.Level) o).displayXML(pxml, 0);
4500        } else if (o instanceof MondrianGuiDef.Measure) {
4501            pNames = DEF_MEASURE;
4502            targetLabel.setText(
4503                getResourceConverter().getFormattedString(
4504                    "schemaExplorer.measureForElement.title",
4505                    "Measure for {0} {1}",
4506                    elementName,
4507                    parentName));
4508            ((MondrianGuiDef.Measure) o).displayXML(pxml, 0);
4509        } else if (o instanceof MondrianGuiDef.CalculatedMember) {
4510            pNames = DEF_CALCULATED_MEMBER;
4511            targetLabel.setText(
4512                getResourceConverter().getFormattedString(
4513                    "schemaExplorer.calculatedMemberForElement.title",
4514                    "Calculated Member for {0} {1}",
4515                    elementName,
4516                    parentName));
4517            ((MondrianGuiDef.CalculatedMember) o).displayXML(pxml, 0);
4518        } else if (o instanceof MondrianGuiDef.CalculatedMemberProperty) {
4519            pNames = DEF_CALCULATED_MEMBER_PROPERTY;
4520            targetLabel.setText(
4521                getResourceConverter().getString(
4522                    "common.calculatedMemberProperty.title",
4523                    LBL_CALCULATED_MEMBER_PROPERTY));
4524        } else if (o instanceof MondrianGuiDef.NamedSet) {
4525            pNames = DEF_NAMED_SET;
4526            targetLabel.setText(
4527                getResourceConverter().getFormattedString(
4528                    "schemaExplorer.namedSetForElement.title",
4529                    "Named Set for {0} {1}",
4530                    elementName,
4531                    parentName));
4532            ((MondrianGuiDef.NamedSet) o).displayXML(pxml, 0);
4533        } else if (o instanceof MondrianGuiDef.Formula) {
4534            pNames = DEF_FORMULA;
4535            targetLabel.setText(
4536                getResourceConverter().getFormattedString(
4537                    "schemaExplorer.formulaForElement.title",
4538                    "Formula for {0} {1}",
4539                    elementName,
4540                    parentName));
4541            ((MondrianGuiDef.Formula) o).displayXML(pxml, 0);
4542        } else if (o instanceof MondrianGuiDef.UserDefinedFunction) {
4543            pNames = DEF_USER_DEFINED_FUNCTION;
4544            targetLabel.setText(
4545                getResourceConverter().getFormattedString(
4546                    "schemaExplorer.userDefinedFunctionForElement.title",
4547                    "User Defined Function for {0} {1}",
4548                    elementName,
4549                    parentName));
4550            ((MondrianGuiDef.UserDefinedFunction) o).displayXML(pxml, 0);
4551        } else if (o instanceof MondrianGuiDef.Script) {
4552            pNames = DEF_SCRIPT;
4553            targetLabel.setText(
4554                getResourceConverter().getFormattedString(
4555                    "schemaExplorer.scriptForElement.title",
4556                    "Script for {0} {1}",
4557                    elementName,
4558                    parentName));
4559            ((MondrianGuiDef.Script) o).displayXML(pxml, 0);
4560        } else if (o instanceof MondrianGuiDef.CellFormatter) {
4561            pNames = DEF_FORMATTER;
4562            targetLabel.setText(
4563                getResourceConverter().getFormattedString(
4564                    "schemaExplorer.cellFormatterForElement.title",
4565                    "Cell Formatter for {0} {1}",
4566                    elementName,
4567                    parentName));
4568            ((MondrianGuiDef.CellFormatter) o).displayXML(pxml, 0);
4569        } else if (o instanceof MondrianGuiDef.PropertyFormatter) {
4570            pNames = DEF_FORMATTER;
4571            targetLabel.setText(
4572                getResourceConverter().getFormattedString(
4573                    "schemaExplorer.propertyFormatterForElement.title",
4574                    "Property Formatter for {0} {1}",
4575                    elementName,
4576                    parentName));
4577            ((MondrianGuiDef.PropertyFormatter) o).displayXML(pxml, 0);
4578        } else if (o instanceof MondrianGuiDef.MemberFormatter) {
4579            pNames = DEF_FORMATTER;
4580            targetLabel.setText(
4581                getResourceConverter().getFormattedString(
4582                    "schemaExplorer.memberFormatterForElement.title",
4583                    "Member Formatter for {0} {1}",
4584                    elementName,
4585                    parentName));
4586            ((MondrianGuiDef.MemberFormatter) o).displayXML(pxml, 0);
4587        } else if (o instanceof MondrianGuiDef.MemberReaderParameter) {
4588            pNames = DEF_PARAMETER;
4589            targetLabel.setText(
4590                getResourceConverter().getString(
4591                    "common.parameter.title", LBL_PARAMETER));
4592        } else if (o instanceof MondrianGuiDef.Property) {
4593            pNames = DEF_PROPERTY;
4594            targetLabel.setText(
4595                getResourceConverter().getString(
4596                    "common.property.title", LBL_PROPERTY));
4597            ((MondrianGuiDef.Property) o).displayXML(pxml, 0);
4598        } else if (o instanceof MondrianGuiDef.Closure) {
4599            pNames = DEF_CLOSURE;
4600            targetLabel.setText(
4601                getResourceConverter().getString(
4602                    "common.closure.title", LBL_CLOSURE));
4603            ((MondrianGuiDef.Closure) o).displayXML(pxml, 0);
4604        } else if (o instanceof MondrianGuiDef.Schema) {
4605            pNames = DEF_SCHEMA;
4606            targetLabel.setText(
4607                getResourceConverter().getString(
4608                    "common.schema.title", LBL_SCHEMA));
4609            ((MondrianGuiDef.Schema) o).displayXML(pxml, 0);
4610        } else if (o instanceof MondrianGuiDef.SQL) {
4611            pNames = DEF_SQL;
4612            targetLabel.setText(
4613                getResourceConverter().getString(
4614                    "common.sql.title", LBL_SQL));
4615            ((MondrianGuiDef.SQL) o).displayXML(pxml, 0);
4616        } else if (o instanceof MondrianGuiDef.Table) {
4617            pNames = DEF_TABLE;
4618            targetLabel.setText(
4619                getResourceConverter().getFormattedString(
4620                    "schemaExplorer.tableForElement.title",
4621                    "Table for {0} {1}",
4622                    elementName,
4623                    parentName));
4624            ((MondrianGuiDef.Table) o).displayXML(pxml, 0);
4625        } else if (o instanceof MondrianGuiDef.AggName) {
4626            pNames = DEF_AGG_NAME;
4627            targetLabel.setText(
4628                getResourceConverter().getString(
4629                    "common.aggName.title", LBL_AGG_NAME));
4630            ((MondrianGuiDef.AggName) o).displayXML(pxml, 0);
4631        } else if (o instanceof MondrianGuiDef.AggIgnoreColumn) {
4632            pNames = DEF_AGG_IGNORE_COLUMN;
4633            targetLabel.setText(
4634                getResourceConverter().getString(
4635                    "common.aggIgnoreColumn.title", LBL_AGG_IGNORE_COLUMN));
4636            ((MondrianGuiDef.AggIgnoreColumn) o).displayXML(pxml, 0);
4637        } else if (o instanceof MondrianGuiDef.AggForeignKey) {
4638            pNames = DEF_AGG_FOREIGN_KEY;
4639            targetLabel.setText(
4640                getResourceConverter().getString(
4641                    "common.aggForeignKey.title", LBL_AGG_FOREIGN_KEY));
4642            ((MondrianGuiDef.AggForeignKey) o).displayXML(pxml, 0);
4643        } else if (o instanceof MondrianGuiDef.AggMeasure) {
4644            pNames = DEF_AGG_MEASURE;
4645            targetLabel.setText(
4646                getResourceConverter().getString(
4647                    "common.aggMeasure.title", LBL_AGG_MEASURE));
4648            ((MondrianGuiDef.AggMeasure) o).displayXML(pxml, 0);
4649        } else if (o instanceof MondrianGuiDef.AggLevel) {
4650            pNames = DEF_AGG_LEVEL;
4651            targetLabel.setText(
4652                getResourceConverter().getString(
4653                    "common.aggLevel.title", LBL_AGG_LEVEL));
4654            ((MondrianGuiDef.AggLevel) o).displayXML(pxml, 0);
4655        } else if (o instanceof MondrianGuiDef.AggExclude) {
4656            pNames = DEF_AGG_EXCLUDE;
4657            targetLabel.setText(
4658                getResourceConverter().getString(
4659                    "common.aggExclude.title", LBL_AGG_EXCLUDE));
4660            ((MondrianGuiDef.AggExclude) o).displayXML(pxml, 0);
4661        } else if (o instanceof MondrianGuiDef.AggPattern) {
4662            pNames = DEF_AGG_PATTERN;
4663            targetLabel.setText(
4664                getResourceConverter().getString(
4665                    "common.aggPattern.title", LBL_AGG_PATTERN));
4666            ((MondrianGuiDef.AggPattern) o).displayXML(pxml, 0);
4667        } else if (o instanceof MondrianGuiDef.AggFactCount) {
4668            pNames = DEF_AGG_FACT_COUNT;
4669            targetLabel.setText(
4670                getResourceConverter().getString(
4671                    "common.aggFactCount.title", LBL_AGG_FACT_COUNT));
4672            ((MondrianGuiDef.AggFactCount) o).displayXML(pxml, 0);
4673
4674        } else if (o instanceof MondrianGuiDef.View) {
4675            pNames = DEF_VIEW;
4676            targetLabel.setText(
4677                getResourceConverter().getString(
4678                    "common.view.title", LBL_VIEW));
4679
4680        } else if (o instanceof MondrianGuiDef.Role) {
4681            pNames = DEF_ROLE;
4682            targetLabel.setText(
4683                getResourceConverter().getFormattedString(
4684                    "schemaExplorer.roleElementParent.title",
4685                    "Role for {0} {1}",
4686                    elementName,
4687                    parentName));
4688            ((MondrianGuiDef.Role) o).displayXML(pxml, 0);
4689        } else if (o instanceof MondrianGuiDef.Parameter) {
4690            pNames = DEF_PARAMETER_SCHEMA;
4691            targetLabel.setText(
4692                getResourceConverter().getString(
4693                    "common.schemaParameter.title", LBL_PARAMETER_SCHEMA));
4694            ((MondrianGuiDef.Parameter) o).displayXML(pxml, 0);
4695        } else if (o instanceof MondrianGuiDef.SchemaGrant) {
4696            pNames = DEF_SCHEMA_GRANT;
4697            targetLabel.setText(
4698                getResourceConverter().getString(
4699                    "common.schemaGrant.title", LBL_SCHEMA_GRANT));
4700            ((MondrianGuiDef.SchemaGrant) o).displayXML(pxml, 0);
4701        } else if (o instanceof MondrianGuiDef.CubeGrant) {
4702            pNames = DEF_CUBE_GRANT;
4703            targetLabel.setText(
4704                getResourceConverter().getString(
4705                    "common.cubeGrant.title", LBL_CUBE_GRANT));
4706            ((MondrianGuiDef.CubeGrant) o).displayXML(pxml, 0);
4707        } else if (o instanceof MondrianGuiDef.DimensionGrant) {
4708            pNames = DEF_DIMENSION_GRANT;
4709            targetLabel.setText(
4710                getResourceConverter().getString(
4711                    "common.dimensionGrant.title", LBL_DIMENSION_GRANT));
4712            ((MondrianGuiDef.DimensionGrant) o).displayXML(pxml, 0);
4713        } else if (o instanceof MondrianGuiDef.HierarchyGrant) {
4714            pNames = DEF_HIERARCHY_GRANT;
4715            targetLabel.setText(
4716                getResourceConverter().getString(
4717                    "common.hierarchyGrant.title", LBL_HIERARCHY_GRANT));
4718            ((MondrianGuiDef.HierarchyGrant) o).displayXML(pxml, 0);
4719        } else if (o instanceof MondrianGuiDef.MemberGrant) {
4720            pNames = DEF_MEMBER_GRANT;
4721            targetLabel.setText(
4722                getResourceConverter().getString(
4723                    "common.memberGrant.title", LBL_MEMBER_GRANT));
4724            ((MondrianGuiDef.MemberGrant) o).displayXML(pxml, 0);
4725
4726        } else if (o instanceof MondrianGuiDef.VirtualCube) {
4727            pNames = DEF_VIRTUAL_CUBE;
4728            targetLabel.setText(
4729                getResourceConverter().getFormattedString(
4730                    "schemaExplorer.virtualCubeElementParent.title",
4731                    "Virtual Cube for {0} {1}",
4732                    elementName,
4733                    parentName));
4734            ((MondrianGuiDef.VirtualCube) o).displayXML(pxml, 0);
4735        } else if (o instanceof MondrianGuiDef.VirtualCubeDimension) {
4736            pNames = DEF_VIRTUAL_CUBE_DIMENSION;
4737            targetLabel.setText(
4738                getResourceConverter().getFormattedString(
4739                    "schemaExplorer.virtualCubeDimensionElementParent.title",
4740                    "Virtual Cube Dimension for {0} {1}",
4741                    elementName,
4742                    parentName));
4743            ((MondrianGuiDef.VirtualCubeDimension) o).displayXML(pxml, 0);
4744        } else if (o instanceof MondrianGuiDef.VirtualCubeMeasure) {
4745            pNames = DEF_VIRTUAL_CUBE_MEASURE;
4746            targetLabel.setText(
4747                getResourceConverter().getString(
4748                    "common.virtualCubeMeasure.title",
4749                    LBL_VIRTUAL_CUBE_MEASURE));
4750            ((MondrianGuiDef.VirtualCubeMeasure) o).displayXML(pxml, 0);
4751        } else if (o instanceof MondrianGuiDef.Annotations) {
4752            pNames = DEF_DEFAULT;
4753            targetLabel.setText(
4754                getResourceConverter().getString(
4755                    "common.annotations.title", LBL_ANNOTATIONS));
4756            ((MondrianGuiDef.Annotations) o).displayXML(pxml, 0);
4757        } else if (o instanceof MondrianGuiDef.Annotation) {
4758            pNames = DEF_ANNOTATION;
4759            targetLabel.setText(
4760                getResourceConverter().getString(
4761                    "common.annotation.title", LBL_ANNOTATION));
4762            ((MondrianGuiDef.Annotation) o).displayXML(pxml, 0);
4763        } else {
4764            targetLabel.setText(
4765                getResourceConverter().getString(
4766                    "common.unknownType.title", LBL_UNKNOWN_TYPE));
4767        }
4768
4769        try {
4770            jEditorPaneXML.read(new StringReader(sxml.toString()), null);
4771            jEditorPaneXML.getDocument().putProperty(
4772                PlainDocument.tabSizeAttribute,
4773                new Integer(2));
4774        } catch (Exception ex) {
4775        }
4776
4777        targetLabel2.setText(targetLabel.getText());
4778
4779        PropertyTableModel ptm = new PropertyTableModel(workbench, o, pNames);
4780
4781        ptm.setFactTable(selectedFactTable);
4782        ptm.setFactTableSchema(selectedFactTableSchema);
4783
4784        // Generate a list of pre-existing names of siblings in parent
4785        // component for checking unique names.
4786        Object parent = null;
4787        for (int i = e.getPath().getPathCount() - 1 - 1; i >= 0; i--) {
4788            parent = e.getPath().getPathComponent(i);   // get parent path
4789            break;
4790        }
4791        if (parent != null) {
4792            //System.out.println("parent type="+parent.getClass());
4793            Field[] fs = parent.getClass().getFields();
4794            List<String> names = new ArrayList<String>();
4795            for (int i = 0; i < fs.length; i++) {
4796                if (fs[i].getType().isArray()
4797                    && (fs[i].getType().getComponentType().isInstance(o)))
4798                {
4799                    // Selected schema object is an instance of parent's field
4800                    // (an array).
4801                    try {
4802                        // name field of array's objects.
4803                        Field fname =
4804                            fs[i].getType().getComponentType().getField("name");
4805                        // get the parent's array of child objects
4806                        Object objs = fs[i].get(parent);
4807                        for (int j = 0; j < Array.getLength(objs); j++) {
4808                            Object child = Array.get(objs, j);
4809                            String vname = (String) fname.get(child);
4810                            names.add(vname);
4811                        }
4812                        ptm.setNames(names);
4813                    } catch (Exception ex) {
4814                        //name field dosen't exist, skip parent object.
4815                    }
4816                    break;
4817                }
4818            }
4819        }
4820
4821        propertyTable.setModel(ptm);
4822        propertyTable.getColumnModel().getColumn(0).setMaxWidth(150);
4823        propertyTable.getColumnModel().getColumn(0).setMinWidth(150);
4824
4825        for (int i = 0; i < propertyTable.getRowCount(); i++) {
4826            TableCellRenderer renderer = propertyTable.getCellRenderer(i, 1);
4827            Component comp =
4828                renderer.getTableCellRendererComponent(
4829                    propertyTable,
4830                    propertyTable.getValueAt(i, 1),
4831                    false,
4832                    false,
4833                    i,
4834                    1);
4835            try {
4836                int height = comp.getMaximumSize().height;
4837                propertyTable.setRowHeight(i, height);
4838            } catch (Exception ea) {
4839            }
4840        }
4841    }
4842
4843    /**
4844     * @see javax.swing.event.CellEditorListener#editingCanceled(ChangeEvent)
4845     */
4846    public void editingCanceled(ChangeEvent e) {
4847        updater.update();
4848    }
4849
4850    /**
4851     * @see javax.swing.event.CellEditorListener#editingStopped(ChangeEvent)
4852     */
4853    public void editingStopped(ChangeEvent e) {
4854        setDirty(true);
4855        if (!dirtyFlag || ((PropertyTableModel) propertyTable
4856            .getModel()).target instanceof MondrianGuiDef.Schema)
4857        {
4858            setDirtyFlag(true);   // true means dirty indication shown on title
4859            setTitle();
4860        }
4861
4862        String emsg =
4863            ((PropertyTableModel) propertyTable.getModel()).getErrorMsg();
4864        if (emsg != null) {
4865            JOptionPane.showMessageDialog(
4866                this, emsg, "Error", JOptionPane.ERROR_MESSAGE);
4867            ((PropertyTableModel) propertyTable.getModel()).setErrorMsg(null);
4868        }
4869
4870        updater.update();
4871    }
4872
4873    class PopupTrigger extends MouseAdapter {
4874
4875        // From MouseAdapter javadoc:
4876        //
4877        // Popup menus are triggered differently
4878        // on different systems. Therefore, isPopupTrigger
4879        // should be checked in both mousePressed
4880        // and mouseReleased
4881        // for proper cross-platform functionality.
4882
4883        public void mousePressed(MouseEvent e) {
4884            showMenu(e);
4885        }
4886
4887        public void mouseReleased(MouseEvent e) {
4888            showMenu(e);
4889        }
4890
4891        public void showMenu(MouseEvent e) {
4892            if (e.isPopupTrigger()) {
4893                int x = e.getX();
4894                int y = e.getY();
4895                TreePath path = tree.getPathForLocation(x, y);
4896                if (path != null) {
4897                    jPopupMenu.setPath(path);
4898                    jPopupMenu.removeAll();
4899                    Object pathSelected = path.getLastPathComponent();
4900                    if (pathSelected instanceof MondrianGuiDef.Schema) {
4901                        MondrianGuiDef.Schema s =
4902                            (MondrianGuiDef.Schema) pathSelected;
4903                        jPopupMenu.add(addCube);
4904                        jPopupMenu.add(addDimension);
4905                        jPopupMenu.add(addNamedSet);
4906                        jPopupMenu.add(addUserDefinedFunction);
4907                        jPopupMenu.add(jSeparator1);
4908                        jPopupMenu.add(addVirtualCube);
4909                        jPopupMenu.add(addRole);
4910                        jPopupMenu.add(addParameter);
4911                        jPopupMenu.add(addAnnotations);
4912                        if (s.annotations == null) {
4913                            addAnnotations.setEnabled(true);
4914                        } else {
4915                            addAnnotations.setEnabled(false);
4916                        }
4917                    } else if (pathSelected instanceof MondrianGuiDef.Cube) {
4918                        jPopupMenu.add(addDimension);
4919                        jPopupMenu.add(addDimensionUsage);
4920                        jPopupMenu.add(addMeasure);
4921                        jPopupMenu.add(addCalculatedMember);
4922                        jPopupMenu.add(addNamedSet);
4923                        jPopupMenu.add(jSeparator1);
4924                        jPopupMenu.add(addTable);
4925                        jPopupMenu.add(addView);
4926                        jPopupMenu.add(addInlineTable);
4927                        jPopupMenu.add(addAnnotations);
4928                        if (((MondrianGuiDef.Cube) pathSelected)
4929                                        .annotations == null)
4930                        {
4931                            addAnnotations.setEnabled(true);
4932                        } else {
4933                            addAnnotations.setEnabled(false);
4934                        }
4935                        jPopupMenu.add(jSeparator2);
4936                        jPopupMenu.add(delete);
4937                        if (((MondrianGuiDef.Cube) pathSelected).fact == null) {
4938                            addMeasure.setEnabled(false);
4939                            addCalculatedMember.setEnabled(false);
4940                            addTable.setEnabled(true);
4941                            addView.setEnabled(true);
4942                            addInlineTable.setEnabled(true);
4943                        } else {
4944                            addMeasure.setEnabled(true);
4945                            addCalculatedMember.setEnabled(true);
4946                            addTable.setEnabled(false);
4947                            addView.setEnabled(false);
4948                            addInlineTable.setEnabled(false);
4949                        }
4950                    } else if (pathSelected
4951                               instanceof MondrianGuiDef.Dimension)
4952                    {
4953                        jPopupMenu.add(addHierarchy);
4954                        jPopupMenu.add(addAnnotations);
4955                        if (((MondrianGuiDef.Dimension) pathSelected)
4956                                        .annotations == null)
4957                        {
4958                            addAnnotations.setEnabled(true);
4959                        } else {
4960                            addAnnotations.setEnabled(false);
4961                        }
4962                        jPopupMenu.add(jSeparator1);
4963                        jPopupMenu.add(delete);
4964                    } else if (pathSelected
4965                               instanceof MondrianGuiDef.Hierarchy)
4966                    {
4967                        jPopupMenu.add(addLevel);
4968                        jPopupMenu.add(jSeparator1);
4969                        jPopupMenu.add(addTable);
4970                        jPopupMenu.add(addJoin);
4971                        jPopupMenu.add(addView);
4972                        jPopupMenu.add(addInlineTable);
4973                        jPopupMenu.add(addAnnotations);
4974                        if (((MondrianGuiDef.Hierarchy) pathSelected)
4975                                        .annotations == null)
4976                        {
4977                            addAnnotations.setEnabled(true);
4978                        } else {
4979                            addAnnotations.setEnabled(false);
4980                        }
4981                        jPopupMenu.add(jSeparator2);
4982                        jPopupMenu.add(delete);
4983                        // Disable Add Level if the relation has not been set
4984                        // Enable Add <Relation>
4985                        if (((MondrianGuiDef.Hierarchy) pathSelected).relation
4986                            == null)
4987                        {
4988                            addLevel.setEnabled(false);
4989                            addTable.setEnabled(true);
4990                            addJoin.setEnabled(true);
4991                            addView.setEnabled(true);
4992                            addInlineTable.setEnabled(true);
4993                        } else {
4994                            // Enable Add Level if the relation has been set,
4995                            // disable Add <Relation>
4996                            addLevel.setEnabled(true);
4997                            addTable.setEnabled(false);
4998                            addJoin.setEnabled(false);
4999                            addView.setEnabled(false);
5000                            addInlineTable.setEnabled(false);
5001                        }
5002                    } else if (pathSelected instanceof MondrianGuiDef.Level) {
5003                        jPopupMenu.add(moveLevelUp);
5004                        jPopupMenu.add(moveLevelDown);
5005                        jPopupMenu.add(addProperty);
5006                        jPopupMenu.add(addKeyExp);
5007                        MondrianGuiDef.Level level =
5008                            (MondrianGuiDef.Level) pathSelected;
5009                        if (level.keyExp == null) {
5010                            addKeyExp.setEnabled(true);
5011                        } else {
5012                            addKeyExp.setEnabled(false);
5013                        }
5014                        jPopupMenu.add(addNameExp);
5015                        if (level.nameExp == null) {
5016                            addNameExp.setEnabled(true);
5017                        } else {
5018                            addNameExp.setEnabled(false);
5019                        }
5020                        jPopupMenu.add(addOrdinalExp);
5021                        if (level.ordinalExp == null) {
5022                            addOrdinalExp.setEnabled(true);
5023                        } else {
5024                            addOrdinalExp.setEnabled(false);
5025                        }
5026                        jPopupMenu.add(addCaptionExp);
5027                        if (level.captionExp == null) {
5028                            addCaptionExp.setEnabled(true);
5029                        } else {
5030                            addCaptionExp.setEnabled(false);
5031                        }
5032                        jPopupMenu.add(addParentExp);
5033                        if (level.parentExp == null) {
5034                            addParentExp.setEnabled(true);
5035                        } else {
5036                            addParentExp.setEnabled(false);
5037                        }
5038                        jPopupMenu.add(addClosure);
5039                        if (level.closure == null) {
5040                            addClosure.setEnabled(true);
5041                        } else {
5042                            addClosure.setEnabled(false);
5043                        }
5044                        jPopupMenu.add(addAnnotations);
5045                        if (level.annotations == null) {
5046                            addAnnotations.setEnabled(true);
5047                        } else {
5048                            addAnnotations.setEnabled(false);
5049                        }
5050                        jPopupMenu.add(addMemberFormatter);
5051                        if (((MondrianGuiDef.Level) pathSelected)
5052                            .memberFormatter == null)
5053                        {
5054                            addMemberFormatter.setEnabled(true);
5055                        } else {
5056                            addMemberFormatter.setEnabled(false);
5057                        }
5058                        jPopupMenu.add(jSeparator1);
5059                        jPopupMenu.add(delete);
5060                    } else if (pathSelected
5061                               instanceof MondrianGuiDef.KeyExpression
5062                               || pathSelected
5063                               instanceof MondrianGuiDef.NameExpression
5064                               || pathSelected
5065                               instanceof MondrianGuiDef.OrdinalExpression
5066                               || pathSelected
5067                               instanceof MondrianGuiDef.CaptionExpression
5068                               || pathSelected
5069                               instanceof MondrianGuiDef.ParentExpression
5070                               || pathSelected
5071                               instanceof MondrianGuiDef.ExpressionView
5072                               || pathSelected
5073                               instanceof MondrianGuiDef.View)
5074                    {
5075                        jPopupMenu.add(addSQL);
5076                        jPopupMenu.add(jSeparator1);
5077                        jPopupMenu.add(delete);
5078                    } else if (pathSelected
5079                               instanceof MondrianGuiDef.RelationOrJoin)
5080                    {
5081                        Object po = path.getParentPath().getLastPathComponent();
5082                        if (!(po instanceof MondrianGuiDef.RelationOrJoin)
5083                            && !(po instanceof MondrianGuiDef.Closure))
5084                        {
5085                            if (po instanceof MondrianGuiDef.Cube) {
5086                                jPopupMenu.add(addAggName);
5087                                jPopupMenu.add(addAggPattern);
5088                                jPopupMenu.add(addAggExclude);
5089                                jPopupMenu.add(jSeparator1);
5090                            }
5091                            jPopupMenu.add(delete);
5092                        } else {
5093                            return;
5094                        }
5095                    } else if (pathSelected instanceof MondrianGuiDef.Measure) {
5096                        jPopupMenu.add(addMeasureExp);
5097                        jPopupMenu.add(addCalculatedMemberProperty);
5098                        if (((MondrianGuiDef.Measure) pathSelected).measureExp
5099                            == null)
5100                        {
5101                            addMeasureExp.setEnabled(true);
5102                        } else {
5103                            addMeasureExp.setEnabled(false);
5104                        }
5105                        jPopupMenu.add(addAnnotations);
5106                        if (((MondrianGuiDef.Measure) pathSelected)
5107                                        .annotations == null)
5108                        {
5109                            addAnnotations.setEnabled(true);
5110                        } else {
5111                            addAnnotations.setEnabled(false);
5112                        }
5113                        jPopupMenu.add(addCellFormatter);
5114                        if (((MondrianGuiDef.Measure) pathSelected)
5115                            .cellFormatter == null)
5116                        {
5117                            addCellFormatter.setEnabled(true);
5118                        } else {
5119                            addCellFormatter.setEnabled(false);
5120                        }
5121                        jPopupMenu.add(jSeparator1);
5122                        jPopupMenu.add(delete);
5123                    } else if (pathSelected
5124                               instanceof MondrianGuiDef.NamedSet)
5125                    {
5126                        jPopupMenu.add(addFormula);
5127                        if (((MondrianGuiDef.NamedSet) pathSelected)
5128                            .formulaElement == null)
5129                        {
5130                            addFormula.setEnabled(false);
5131                        } else {
5132                            addFormula.setEnabled(false);
5133                        }
5134                        jPopupMenu.add(addAnnotations);
5135                        if (((MondrianGuiDef.NamedSet) pathSelected)
5136                                        .annotations == null)
5137                        {
5138                            addAnnotations.setEnabled(true);
5139                        } else {
5140                            addAnnotations.setEnabled(false);
5141                        }
5142                        jPopupMenu.add(jSeparator1);
5143                        jPopupMenu.add(delete);
5144                    } else if (pathSelected
5145                               instanceof MondrianGuiDef.CalculatedMember)
5146                    {
5147                        jPopupMenu.add(addFormula);
5148                        jPopupMenu.add(addCalculatedMemberProperty);
5149                        if (((MondrianGuiDef.CalculatedMember) pathSelected)
5150                            .formulaElement == null)
5151                        {
5152                            addFormula.setEnabled(false);
5153                        } else {
5154                            addFormula.setEnabled(false);
5155                        }
5156                        jPopupMenu.add(addAnnotations);
5157                        if (((MondrianGuiDef.CalculatedMember) pathSelected)
5158                                        .annotations == null)
5159                        {
5160                            addAnnotations.setEnabled(true);
5161                        } else {
5162                            addAnnotations.setEnabled(false);
5163                        }
5164                        jPopupMenu.add(addCellFormatter);
5165                        if (((MondrianGuiDef.CalculatedMember) pathSelected)
5166                            .cellFormatter == null)
5167                        {
5168                            addCellFormatter.setEnabled(true);
5169                        } else {
5170                            addCellFormatter.setEnabled(false);
5171                        }
5172                        jPopupMenu.add(jSeparator1);
5173                        jPopupMenu.add(delete);
5174                    } else if (pathSelected
5175                               instanceof MondrianGuiDef.MeasureExpression)
5176                    {
5177                        jPopupMenu.add(addSQL);
5178                        addSQL.setEnabled(false);
5179                        jPopupMenu.add(jSeparator1);
5180                        jPopupMenu.add(delete);
5181                    } else if (pathSelected instanceof MondrianGuiDef.Closure) {
5182                        jPopupMenu.add(delete);
5183                    } else if (pathSelected instanceof MondrianGuiDef.AggName
5184                               || pathSelected
5185                               instanceof MondrianGuiDef.AggPattern)
5186                    {
5187                        jPopupMenu.add(addAggFactCount);
5188                        jPopupMenu.add(addAggIgnoreColumn);
5189                        jPopupMenu.add(addAggForeignKey);
5190                        jPopupMenu.add(addAggMeasure);
5191                        jPopupMenu.add(addAggLevel);
5192                        if (pathSelected instanceof MondrianGuiDef.AggPattern) {
5193                            jPopupMenu.add(addAggExclude);
5194                            if (((MondrianGuiDef.AggPattern) pathSelected)
5195                                .factcount == null)
5196                            {
5197                                addAggFactCount.setEnabled(true);
5198                            } else {
5199                                addAggFactCount.setEnabled(false);
5200                            }
5201                        } else {
5202                            if (((MondrianGuiDef.AggName) pathSelected)
5203                                .factcount == null)
5204                            {
5205                                addAggFactCount.setEnabled(true);
5206                            } else {
5207                                addAggFactCount.setEnabled(false);
5208                            }
5209                        }
5210                        jPopupMenu.add(jSeparator1);
5211                        jPopupMenu.add(delete);
5212                    } else if (pathSelected
5213                               instanceof MondrianGuiDef.VirtualCube)
5214                    {
5215                        jPopupMenu.add(addVirtualCubeDimension);
5216                        jPopupMenu.add(addVirtualCubeMeasure);
5217                        jPopupMenu.add(addCalculatedMember);
5218                        jPopupMenu.add(addAnnotations);
5219                        if (((MondrianGuiDef.VirtualCube) pathSelected)
5220                                        .annotations == null)
5221                        {
5222                            addAnnotations.setEnabled(true);
5223                        } else {
5224                            addAnnotations.setEnabled(false);
5225                        }
5226                        jPopupMenu.add(jSeparator1);
5227                        jPopupMenu.add(delete);
5228                    } else if (pathSelected instanceof MondrianGuiDef.Role) {
5229                        jPopupMenu.add(addSchemaGrant);
5230                        jPopupMenu.add(addAnnotations);
5231                        if (((MondrianGuiDef.Role) pathSelected).annotations
5232                                        == null)
5233                        {
5234                            addAnnotations.setEnabled(true);
5235                        } else {
5236                            addAnnotations.setEnabled(false);
5237                        }
5238                        jPopupMenu.add(jSeparator1);
5239                        jPopupMenu.add(delete);
5240                    } else if (pathSelected
5241                               instanceof MondrianGuiDef.SchemaGrant)
5242                    {
5243                        jPopupMenu.add(addCubeGrant);
5244                        jPopupMenu.add(jSeparator1);
5245                        jPopupMenu.add(delete);
5246                    } else if (pathSelected
5247                               instanceof MondrianGuiDef.CubeGrant)
5248                    {
5249                        jPopupMenu.add(addDimensionGrant);
5250                        jPopupMenu.add(addHierarchyGrant);
5251                        jPopupMenu.add(jSeparator1);
5252                        jPopupMenu.add(delete);
5253                    } else if (pathSelected
5254                               instanceof MondrianGuiDef.VirtualCubeMeasure)
5255                    {
5256                        jPopupMenu.add(addAnnotations);
5257                        jPopupMenu.add(jSeparator1);
5258                        jPopupMenu.add(delete);
5259                    } else if (pathSelected
5260                               instanceof MondrianGuiDef.HierarchyGrant)
5261                    {
5262                        jPopupMenu.add(addMemberGrant);
5263                        jPopupMenu.add(jSeparator1);
5264                        jPopupMenu.add(delete);
5265                    } else if (pathSelected
5266                        instanceof MondrianGuiDef.Annotations)
5267                    {
5268                        jPopupMenu.add(addAnnotation);
5269                        jPopupMenu.add(jSeparator1);
5270                        jPopupMenu.add(delete);
5271                    } else if (pathSelected
5272                        instanceof MondrianGuiDef.UserDefinedFunction)
5273                    {
5274                        jPopupMenu.add(addScript);
5275                        jPopupMenu.add(delete);
5276                    } else if (pathSelected
5277                        instanceof MondrianGuiDef.Property)
5278                    {
5279                        jPopupMenu.add(addPropertyFormatter);
5280                        jPopupMenu.add(delete);
5281                    } else if (pathSelected
5282                        instanceof MondrianGuiDef.CellFormatter)
5283                    {
5284                        jPopupMenu.add(addScript);
5285                        jPopupMenu.add(delete);
5286                    } else if (pathSelected
5287                        instanceof MondrianGuiDef.MemberFormatter)
5288                    {
5289                        jPopupMenu.add(addScript);
5290                        jPopupMenu.add(delete);
5291                    } else if (pathSelected
5292                        instanceof MondrianGuiDef.PropertyFormatter)
5293                    {
5294                        jPopupMenu.add(addScript);
5295                        jPopupMenu.add(delete);
5296                    } else {
5297                        jPopupMenu.add(delete);
5298                    } /* else {
5299                        return;
5300                    }*/
5301                    jPopupMenu.show(tree, x, y);
5302                }
5303            }
5304        }
5305    }
5306
5307    static final String[] DEF_DEFAULT = {};
5308    static final String[] DEF_VIRTUAL_CUBE = {"name", "description", "caption",
5309        "enabled", "visible"};
5310    static final String[] DEF_VIRTUAL_CUBE_MEASURE = {
5311        "name", "cubeName", "visible"};
5312    static final String[] DEF_VIRTUAL_CUBE_DIMENSION = {
5313        "name", "cubeName", "caption", "foreignKey"};
5314    static final String[] DEF_VIEW = {"alias"};
5315    static final String[] DEF_TABLE = {"schema", "name", "alias"};
5316    static final String[] DEF_AGG_FACT_COUNT = {"column"};
5317    static final String[] DEF_AGG_NAME = {
5318        "name", "ignorecase", "approxRowCount"};
5319    static final String[] DEF_AGG_PATTERN = {"pattern", "ignorecase"};
5320    static final String[] DEF_AGG_EXCLUDE = {"pattern", "name", "ignorecase"};
5321    static final String[] DEF_AGG_IGNORE_COLUMN = {"column"};
5322    static final String[] DEF_AGG_FOREIGN_KEY = {"factColumn", "aggColumn"};
5323    static final String[] DEF_AGG_MEASURE = {"column", "name"};
5324    static final String[] DEF_AGG_LEVEL = {
5325        "column",
5326        "name",
5327        "collapsed"
5328    };
5329
5330    static final String[] DEF_CLOSURE = {"parentColumn", "childColumn"};
5331    static final String[] DEF_RELATION = {"name"};
5332    static final String[] DEF_SQL = {"cdata", "dialect"}; //?
5333    static final String[] DEF_ANNOTATION = {"name", "cdata"};
5334    static final String[] DEF_SCHEMA = {
5335        "name", "description", "measuresCaption", "defaultRole"};
5336    static final String[] DEF_PROPERTY = {
5337        "name", "description", "column", "type", "formatter", "caption"};
5338    static final String[] DEF_PARAMETER_SCHEMA = {
5339        "name", "description", "type", "modifiable", "defaultValue"}; //?
5340    static final String[] DEF_PARAMETER = {"name", "value"}; //?
5341    static final String[] DEF_MEASURE = {
5342        "name",
5343        "description",
5344        "aggregator",
5345        "column",
5346        "formatString",
5347        "datatype",
5348        "formatter",
5349        "caption",
5350        "visible"
5351    };
5352
5353    static final String[] DEF_CALCULATED_MEMBER = {
5354        "name",
5355        "description",
5356        "caption",
5357        "dimension",
5358        "hierarchy",
5359        "parent",
5360        "visible",
5361        "formula | formulaElement.cdata",
5362        "formatString",
5363    };
5364    static final String[] DEF_FORMULA = {"cdata"};
5365    static final String[] DEF_CALCULATED_MEMBER_PROPERTY = {
5366        "name", "description", "caption", "expression", "value"};
5367    static final String[] DEF_NAMED_SET = {"name", "description", "formula",
5368        "caption"};
5369    static final String[] DEF_USER_DEFINED_FUNCTION = {"name", "className"};
5370
5371    static final String[] DEF_SCRIPT = {"language", "cdata"};
5372
5373    static final String[] DEF_LEVEL = {
5374        "name",
5375        "description",
5376        "table",
5377        "column",
5378        "nameColumn",
5379        "parentColumn",
5380        "nullParentValue",
5381        "ordinalColumn",
5382        "type",
5383        "internalType",
5384        "uniqueMembers",
5385        "levelType",
5386        "hideMemberIf",
5387        "approxRowCount",
5388        "caption",
5389        "captionColumn",
5390        "formatter",
5391        "visible"
5392    };
5393    static final String[] DEF_JOIN = {
5394        "leftAlias", "leftKey", "rightAlias", "rightKey"};
5395    static final String[] DEF_HIERARCHY = {
5396        "name",
5397        "description",
5398        "hasAll",
5399        "allMemberName",
5400        "allMemberCaption",
5401        "allLevelName",
5402        "defaultMember",
5403        "memberReaderClass",
5404        "primaryKeyTable",
5405        "primaryKey",
5406        "caption",
5407        "visible"
5408    };
5409    static final String[] DEF_FORMATTER = {"className"};
5410    static final String[] DEF_EXPRESSION_VIEW = {};
5411    static final String[] DEF_DIMENSION_USAGE = {
5412        "name", "foreignKey", "source", "level",
5413        "usagePrefix", "caption", "visible"};
5414    static final String[] DEF_DIMENSION = {
5415        "name", "description", "foreignKey", "type",
5416        "usagePrefix", "caption", "visible"};
5417    static final String[] DEF_CUBE = {"name", "description", "caption",
5418        "cache", "enabled", "visible"};
5419    static final String[] DEF_ROLE = {"name"};
5420    static final String[] DEF_SCHEMA_GRANT = {"access"};
5421    static final String[] DEF_CUBE_GRANT = {"access", "cube"};
5422    static final String[] DEF_DIMENSION_GRANT = {"access", "dimension"};
5423    static final String[] DEF_HIERARCHY_GRANT = {
5424        "access", "hierarchy", "topLevel", "bottomLevel", "rollupPolicy"};
5425    static final String[] DEF_MEMBER_GRANT = {"access", "member"};
5426    static final String[] DEF_COLUMN = {"name", "table"};   //?
5427
5428    private static final String LBL_COLUMN = "Column";
5429    private static final String LBL_CUBE = "Cube";
5430    private static final String LBL_ROLE = "Role";
5431    private static final String LBL_SCHEMA_GRANT = "Schema Grant";
5432    private static final String LBL_CUBE_GRANT = "Cube Grant";
5433    private static final String LBL_DIMENSION_GRANT = "Dimension Grant";
5434    private static final String LBL_HIERARCHY_GRANT = "Hierarchy Grant";
5435    private static final String LBL_MEMBER_GRANT = "Member Grant";
5436    private static final String LBL_DIMENSION = "Dimension";
5437    private static final String LBL_DIMENSION_USAGE = "Dimension Usage";
5438    private static final String LBL_EXPRESSION_VIEW = "Expression View";
5439    private static final String LBL_KEY_EXPRESSION = "Key Expression";
5440    private static final String LBL_NAME_EXPRESSION = "Name Expression";
5441    private static final String LBL_ANNOTATIONS = "Annotations";
5442    private static final String LBL_ANNOTATION = "Annotation";
5443    private static final String LBL_ORDINAL_EXPRESSION = "Ordinal Expression";
5444    private static final String LBL_PARENT_EXPRESSION = "Parent Expression";
5445    private static final String LBL_MEASURE_EXPRESSION = "Measure Expression";
5446    private static final String LBL_HIERARCHY = "Hierarchy";
5447    private static final String LBL_JOIN = "Join";
5448    private static final String LBL_LEVEL = "Level";
5449    private static final String LBL_MEASURE = "Measure";
5450    private static final String LBL_CALCULATED_MEMBER = "Calculated Member";
5451    private static final String LBL_CALCULATED_MEMBER_PROPERTY =
5452        "Calculated Member Property";
5453    private static final String LBL_NAMED_SET = "Named Set";
5454    private static final String LBL_USER_DEFINED_FUNCTION =
5455        "User Defined Function";
5456    private static final String LBL_PARAMETER = "Parameter";
5457    private static final String LBL_PARAMETER_SCHEMA = "Schema Parameter";
5458    private static final String LBL_PROPERTY = "Property";
5459    private static final String LBL_SCHEMA = "Schema";
5460    private static final String LBL_SQL = "SQL";
5461    private static final String LBL_TABLE = "Table";
5462    private static final String LBL_CLOSURE = "Closure";
5463
5464    private static final String LBL_AGG_NAME = "Aggregate Name";
5465    private static final String LBL_AGG_IGNORE_COLUMN =
5466        "Aggregate Ignore Column";
5467    private static final String LBL_AGG_FOREIGN_KEY = "Aggregate Foreign Key";
5468    private static final String LBL_AGG_MEASURE = "Aggregate Measure";
5469    private static final String LBL_AGG_LEVEL = "Aggregate Level";
5470    private static final String LBL_AGG_PATTERN = "Aggregate Pattern";
5471    private static final String LBL_AGG_EXCLUDE = "Aggregate Exclude";
5472    private static final String LBL_AGG_FACT_COUNT = "Aggregate Fact Count";
5473
5474    private static final String LBL_VIEW = "View";
5475    private static final String LBL_VIRTUAL_CUBE = "Virtual Cube";
5476    private static final String LBL_VIRTUAL_CUBE_DIMENSION =
5477        "Virtual Cube Dimension";
5478    private static final String LBL_VIRTUAL_CUBE_MEASURE =
5479        "Virtual Cube Measure";
5480    private static final String LBL_UNKNOWN_TYPE = "Unknown Type";
5481
5482    private static String alert = "Alert";
5483
5484    private AbstractAction arrowButtonUpAction;
5485    private AbstractAction arrowButtonDownAction;
5486
5487    private AbstractAction addCube;
5488    private AbstractAction addRole;
5489    private AbstractAction addParameter;
5490    private AbstractAction addSchemaGrant;
5491    private AbstractAction addCubeGrant;
5492    private AbstractAction addDimensionGrant;
5493    private AbstractAction addHierarchyGrant;
5494    private AbstractAction addMemberGrant;
5495    private AbstractAction addAnnotations;
5496    private AbstractAction addAnnotation;
5497
5498
5499    private AbstractAction addDimension;
5500    private AbstractAction addDimensionUsage;
5501    private AbstractAction addHierarchy;
5502    private AbstractAction addNamedSet;
5503    private AbstractAction addUserDefinedFunction;
5504    private AbstractAction addScript;
5505    private AbstractAction addCalculatedMember;
5506
5507    private AbstractAction addMeasure;
5508    private AbstractAction addMeasureExp;
5509    private AbstractAction addFormula;
5510    private AbstractAction addLevel;
5511    private AbstractAction addSQL;
5512    private AbstractAction addKeyExp;
5513    private AbstractAction addNameExp;
5514    private AbstractAction addOrdinalExp;
5515    private AbstractAction addCaptionExp;
5516    private AbstractAction addParentExp;
5517    //private AbstractAction addRelation;
5518    private AbstractAction addTable;
5519    private AbstractAction addJoin;
5520    private AbstractAction addView;
5521    private AbstractAction addInlineTable;
5522    private AbstractAction moveLevelUp;
5523    private AbstractAction moveLevelDown;
5524    private AbstractAction addProperty;
5525    private AbstractAction addCalculatedMemberProperty;
5526    private AbstractAction addClosure;
5527
5528    private AbstractAction addAggName;
5529    private AbstractAction addAggIgnoreColumn;
5530    private AbstractAction addAggForeignKey;
5531    private AbstractAction addAggMeasure;
5532    private AbstractAction addAggLevel;
5533    private AbstractAction addAggPattern;
5534    private AbstractAction addAggExclude;
5535    private AbstractAction addAggFactCount;
5536
5537    private AbstractAction addVirtualCube;
5538    private AbstractAction addVirtualCubeDimension;
5539    private AbstractAction addVirtualCubeMeasure;
5540
5541    private AbstractAction addCellFormatter;
5542    private AbstractAction addMemberFormatter;
5543    private AbstractAction addPropertyFormatter;
5544
5545    private AbstractAction delete;
5546
5547    private AbstractAction editMode;
5548
5549    private JTable propertyTable;
5550    private JPanel jPanel1;
5551    private JPanel jPanel2;
5552    private JPanel jPanel3;
5553    private JButton addLevelButton;
5554    private JScrollPane jScrollPane2;
5555    private JScrollPane jScrollPane1;
5556    private JButton addPropertyButton;
5557    private JButton addCalculatedMemberPropertyButton;
5558    private JButton pasteButton;
5559    private JLabel targetLabel;
5560    private JLabel validStatusLabel;
5561    private JLabel targetLabel2;
5562    private JLabel validStatusLabel2;
5563    JTree tree;
5564    private JSplitPane jSplitPane1;
5565
5566    private JButton addDimensionButton;
5567    private JButton addDimensionUsageButton;
5568    private JButton addHierarchyButton;
5569    private JButton addNamedSetButton;
5570    private JButton addUserDefinedFunctionButton;
5571    private JButton addCalculatedMemberButton;
5572    private JButton cutButton;
5573    private JButton addMeasureButton;
5574    private JButton addCubeButton;
5575    private JButton addRoleButton;
5576    private JButton addVirtualCubeButton;
5577    private JButton addVirtualCubeDimensionButton;
5578    private JButton addVirtualCubeMeasureButton;
5579
5580    private JButton deleteButton;
5581    private JToggleButton editModeButton;
5582    private JButton copyButton;
5583    private JToolBar jToolBar1;
5584    private CustomJPopupMenu jPopupMenu;
5585    private class CustomJPopupMenu extends JPopupMenu {
5586        private TreePath path;
5587        void setPath(TreePath path) {
5588            this.path = path;
5589        }
5590        public TreePath getPath() {
5591            return path;
5592        }
5593    }
5594
5595    private JSeparator jSeparator1;
5596    private JSeparator jSeparator2;
5597
5598    private JPanel footer;
5599    private JLabel databaseLabel;
5600
5601    private JPanel jPanelXML;
5602    private JScrollPane jScrollPaneXML;
5603    private JEditorPane jEditorPaneXML;
5604
5605    public boolean isNewFile() {
5606        return newFile;
5607    }
5608
5609    public void setNewFile(boolean newFile) {
5610        this.newFile = newFile;
5611    }
5612
5613    public boolean isDirty() {
5614        return dirty;
5615    }
5616
5617    public void setDirty(boolean dirty) {
5618        this.dirty = dirty;
5619    }
5620
5621    public void setTitle() {
5622        // Sets the title of Internal Frame within which this schema explorer is
5623        // displayed.  The title includes schema name and schema file name.
5624        parentIFrame.setTitle(
5625            getResourceConverter().getFormattedString(
5626                "schemaExplorer.frame.title",
5627                "Schema - {0} ({1}){2}",
5628                schema.name,
5629                schemaFile.getName(),
5630                isDirty() ? "*" : ""));
5631
5632        parentIFrame.setToolTipText(schemaFile.toString());
5633    }
5634
5635    public void setDirtyFlag(boolean dirtyFlag) {
5636        this.dirtyFlag = dirtyFlag;
5637    }
5638
5639    public Object getParentObject() {
5640        TreePath tPath = tree.getSelectionPath();
5641        if ((tPath != null) && (tPath.getParentPath() != null)) {
5642            return tPath.getParentPath().getLastPathComponent();
5643        }
5644        return null;
5645    }
5646
5647    public String getJdbcConnectionUrl() {
5648        return this.jdbcMetaData.jdbcConnectionUrl;
5649    }
5650
5651    public String getJdbcUsername() {
5652        return this.jdbcMetaData.jdbcUsername;
5653    }
5654
5655    public String getJdbcPassword() {
5656        return this.jdbcMetaData.jdbcPassword;
5657    }
5658
5659    public String getErrMsg() {
5660        return errMsg;
5661    }
5662
5663    public boolean isEditModeXML() {
5664        // used by schema frame focuslistener in workbench/desktoppane
5665        return editModeXML;
5666    }
5667
5668    public I18n getResourceConverter() {
5669        return workbench.getResourceConverter();
5670    }
5671
5672    public static void getTableNamesForJoin(
5673        MondrianGuiDef.RelationOrJoin aRelOrJoin, Set<String> aTableNames)
5674    {
5675        //EC: Loops join tree and collects table names.
5676        if (aRelOrJoin instanceof MondrianGuiDef.Join) {
5677            MondrianGuiDef.RelationOrJoin theRelOrJoin_L =
5678                ((MondrianGuiDef.Join) aRelOrJoin).left;
5679            MondrianGuiDef.RelationOrJoin theRelOrJoin_R =
5680                ((MondrianGuiDef.Join) aRelOrJoin).right;
5681            for (int i = 0; i < 2; i++) {
5682                // Searches first using the Left Join and then the Right.
5683                MondrianGuiDef.RelationOrJoin theCurrentRelOrJoin =
5684                    (i == 0)
5685                    ? theRelOrJoin_L
5686                    : theRelOrJoin_R;
5687                if (theCurrentRelOrJoin instanceof MondrianGuiDef.Table) {
5688                    MondrianGuiDef.Table theTable =
5689                        ((MondrianGuiDef.Table) theCurrentRelOrJoin);
5690                    String theTableName = (theTable.alias != null
5691                                           && theTable.alias.trim().length()
5692                                              > 0)
5693                        ? theTable.alias
5694                        : theTable.name;
5695                    aTableNames.add(theTableName);
5696                } else {
5697                    //Calls recursively collecting all table names down the join
5698                    //tree.
5699                    getTableNamesForJoin(theCurrentRelOrJoin, aTableNames);
5700                }
5701            }
5702        }
5703    }
5704
5705    public static String[] getTableNameForAlias(
5706        MondrianGuiDef.RelationOrJoin aRelOrJoin, String anAlias)
5707    {
5708        String theTableName = anAlias;
5709        String schemaName = null;
5710
5711        //EC: Loops join tree and finds the table name for an alias.
5712        if (aRelOrJoin instanceof MondrianGuiDef.Join) {
5713            MondrianGuiDef.RelationOrJoin theRelOrJoin_L =
5714                ((MondrianGuiDef.Join) aRelOrJoin).left;
5715            MondrianGuiDef.RelationOrJoin theRelOrJoin_R =
5716                ((MondrianGuiDef.Join) aRelOrJoin).right;
5717            for (int i = 0; i < 2; i++) {
5718                // Searches first using the Left Join and then the Right.
5719                MondrianGuiDef.RelationOrJoin theCurrentRelOrJoin =
5720                    (i == 0)
5721                    ? theRelOrJoin_L
5722                    : theRelOrJoin_R;
5723                if (theCurrentRelOrJoin instanceof MondrianGuiDef.Table) {
5724                    MondrianGuiDef.Table theTable =
5725                        ((MondrianGuiDef.Table) theCurrentRelOrJoin);
5726                    if (theTable.alias != null && theTable.alias
5727                        .equals(anAlias))
5728                    {
5729                        // If the alias was found get its table name and return
5730                        // it.
5731                        theTableName = theTable.name;
5732                        schemaName = theTable.schema;
5733                    }
5734                } else {
5735                    //otherwise continue down the join tree.
5736                    String[] result = getTableNameForAlias(
5737                        theCurrentRelOrJoin, anAlias);
5738                    schemaName = result[0];
5739                    theTableName = result[1];
5740                }
5741            }
5742        }
5743        return new String[]{schemaName, theTableName};
5744    }
5745
5746    public void resetMetaData(JdbcMetaData aMetaData) {
5747        // Update the JdbcMetaData in the SchemaExplorer
5748        jdbcMetaData = aMetaData;
5749
5750        // Update the database label
5751        String theLabel =
5752            getResourceConverter().getFormattedString(
5753                "schemaExplorer.database.text",
5754                "Database - {0} ({1})",
5755                jdbcMetaData.getDbCatalogName(),
5756                jdbcMetaData.getDatabaseProductName());
5757        databaseLabel.setText(theLabel);
5758
5759        // Update the JdbcMetaData in the SchemaTreeCellRenderer.
5760        renderer.setMetaData(aMetaData);
5761
5762        // Update the JdbcMetaData in the SchemaPropertyCellEditor.
5763        TableCellEditor theTableCellEditor = propertyTable.getDefaultEditor(
5764            Object.class);
5765        if (theTableCellEditor instanceof SchemaPropertyCellEditor) {
5766            ((SchemaPropertyCellEditor) theTableCellEditor).setMetaData(
5767                aMetaData);
5768        }
5769    }
5770
5771    public JTreeUpdater getTreeUpdater() {
5772        return updater;
5773    }
5774}
5775
5776// End SchemaExplorer.java