Author: kevin1219
Date: Mon Aug 25 14:50:07 2008
New Revision: 2605

Added:
   trunk/src/ca/sqlpower/architect/swingui/olap/OLAPObjectNameValidator.java
Modified:
   trunk/src/ca/sqlpower/architect/olap/OLAPSession.java
   trunk/src/ca/sqlpower/architect/olap/OLAPUtil.java
   trunk/src/ca/sqlpower/architect/olap/SchemaWatcher.java
   trunk/src/ca/sqlpower/architect/swingui/olap/CubeEditPanel.java
   trunk/src/ca/sqlpower/architect/swingui/olap/DimensionEditPanel.java
   trunk/src/ca/sqlpower/architect/swingui/olap/VirtualCubePane.java

Log:
Renamed findCube/findDimension to be findReferencedCube/Dimension because that's what they where. Also changed the way the search was done. Now that SchemaWatcher has maps of dimensions and cubes, might as well take advantage of it. Also added other methods for find cubes, dimensions, cube dimensions by names that makes use of the SchemaWatcher methods. Added a name validator for OLAPObjects that will help us enforce unique names. It's not used for editing cubes and dimensions. I'll extend this as I add maps to the SchemaWatcher.

Modified: trunk/src/ca/sqlpower/architect/olap/OLAPSession.java
==============================================================================
--- trunk/src/ca/sqlpower/architect/olap/OLAPSession.java       (original)
+++ trunk/src/ca/sqlpower/architect/olap/OLAPSession.java Mon Aug 25 14:50:07 2008
@@ -23,6 +23,9 @@
 import java.util.List;

 import ca.sqlpower.architect.SQLDatabase;
+import ca.sqlpower.architect.olap.MondrianModel.Cube;
+import ca.sqlpower.architect.olap.MondrianModel.CubeDimension;
+import ca.sqlpower.architect.olap.MondrianModel.Dimension;
 import ca.sqlpower.architect.olap.MondrianModel.Schema;

 /**
@@ -132,5 +135,37 @@
     public boolean removeChild(OLAPObject child) {
         throw new UnsupportedOperationException(
"OLAPSession has exactly one child (the Schema) for its entire lifetime");
+    }
+
+    /**
+     * Returns a public dimension in the child schema with the given name.
+     *
+     * @param name The name to search by.
+     * @return A public Dimension with the name, or null if not found.
+     */
+    public Dimension findPublicDimension(String name) {
+        return schemaWatcher.findPublicDimension(name);
+    }
+
+    /**
+ * Returns a CubeDimension in the child schema with the given name and in a
+     * particular Cube.
+     *
+     * @param cubeName Name of the Cube to search in.
+     * @param dimName Name of the CubeDimension to search for.
+ * @return A CubeDimension in the Cube with the name, or null if not found.
+     */
+ public CubeDimension findCubeDimension(String cubeName, String dimName) {
+        return schemaWatcher.findCubeDimension(cubeName, dimName);
+    }
+
+    /**
+     * Returns a Cube in the child schema with the given name.
+     *
+     * @param name The name to search by.
+     * @return A Cube with the name, or null if not found.
+     */
+    public Cube findCube(String name) {
+        return schemaWatcher.findCube(name);
     }
 }

Modified: trunk/src/ca/sqlpower/architect/olap/OLAPUtil.java
==============================================================================
--- trunk/src/ca/sqlpower/architect/olap/OLAPUtil.java  (original)
+++ trunk/src/ca/sqlpower/architect/olap/OLAPUtil.java Mon Aug 25 14:50:07 2008
@@ -251,72 +251,96 @@
     }

     /**
- * Finds and returns a Cube in the given schema with the given name. Note - * that this might not be accurate if the schema contains cubes with the
-     * same name.
+     * Finds and returns the Cube that the given CubeUsage references.
      *
-     * @param sch
-     *            The schema to search in.
-     * @param name
-     *            Name of the cube to search for.
+     * @param CubeUsage
+ * The CubeUsage to search by, OLAPSession ancestor must not be
+     *            null.
      *
- * @return A Cube with the given name from the given schema, null if not
-     *         found.
+ * @return The Cube that the CubeUsage references, or null if not found.
      */
-    public static Cube findCube(Schema sch, String name) {
-        for (Cube c : sch.getCubes()) {
-            if (c.getName().equals(name)) {
-                return c;
-            }
+    public static Cube findReferencedCube(CubeUsage cu) {
+        OLAPSession olapSession = getSession(cu);
+        if (olapSession == null) {
+ throw new IllegalArgumentException("Can't find OLAPSession ancestor: " + cu);
         }
-        return null;
+        return olapSession.findCube(cu.getCubeName());
     }

     /**
-     * Finds and returns a Dimension in the given schema that the given
- * CubeDimension represents. This is useful for finding the base Dimension - * that a DimensionUsage or a VirtualCubeDimension refers to. It is safe to - * call this method with a Dimension as parameter, it will just return the - * same object. Note that this might not be accurate if there are dimensions
-     * with the same name.
+     * Finds and returns the base Dimension that the given CubeDimension
+ * references. It is safe to call this method with a Dimension as parameter,
+     * it will just return the same object.
      *
-     * @param sch
-     *            The schema to search in.
      * @param cubeDim
- * The CubeDimension "reference" to the base Dimension that will
-     *            be returned.
- * @return The base Dimension that the given CubeDimension represents, null
-     *         if not found.
+ * The CubeDimension to search by, OLAPSession ancestor must not
+     *            be null.
+ * @return The base Dimension that the CubeDimension represents, or null if
+     *         not found.
      */
- public static Dimension findDimension(Schema sch, CubeDimension cubeDim) { + public static Dimension findReferencedDimension(CubeDimension cubeDim) {
+        OLAPSession olapSession = getSession(cubeDim);
+        if (olapSession == null) {
+ throw new IllegalArgumentException("Can't find OLAPSession ancestor: " + cubeDim);
+        }
+
         if (cubeDim instanceof Dimension) {
             return (Dimension) cubeDim;
         } else if (cubeDim instanceof DimensionUsage) {
-            for (Dimension dim : sch.getDimensions()) {
- if (dim.getName().equals(((DimensionUsage) cubeDim).getSource())) {
-                    return dim;
-                }
-            }
+            String dimName = ((DimensionUsage) cubeDim).getSource();
+            return olapSession.findPublicDimension(dimName);
         } else if (cubeDim instanceof VirtualCubeDimension) {
             VirtualCubeDimension vCubeDim = (VirtualCubeDimension) cubeDim;
             if (vCubeDim.getCubeName() == null) {
-                for (Dimension d : sch.getDimensions()) {
-                    if (d.getName().equals(vCubeDim.getName())) {
-                        return d;
-                    }
-                }
+                return olapSession.findPublicDimension(vCubeDim.getName());
             } else {
-                Cube c = findCube(sch, vCubeDim.getCubeName());
-                for (CubeDimension d : c.getDimensions()) {
-                    if (d.getName().equals(vCubeDim.getName())) {
-                        return findDimension(sch, d);
-                    }
+ CubeDimension cd = olapSession.findCubeDimension(vCubeDim.getCubeName(), vCubeDim.getName());
+
+                if (cd == null) {
+                    return null;
+                } else if (cd instanceof Dimension) {
+                    return (Dimension) cd;
+                } else if (cd instanceof DimensionUsage) {
+                    DimensionUsage du = (DimensionUsage) cd;
+                    return olapSession.findPublicDimension(du.getSource());
+                } else {
+ throw new IllegalStateException("Invalid reference by VirtualCubeDimension: " + vCubeDim);
                 }
             }
         } else {
             // How do you enter the 4th dimension?!?!? ;)
throw new UnsupportedOperationException("CubeDimension of type " + cubeDim.getClass() + " not recognized.");
         }
-        return null;
+    }
+
+    /**
+     * Checks if the given name would be unique for the given OLAPObject.
+     *
+     * @param oo
+     *            The OLAPObject to check, OLAPSession ancestor must not be
+     *            null.
+     * @param name
+     *            The name to check for.
+ * @return True if the given object is the only object in its schema with
+     *         the given name, false otherwise.
+     */
+    public static boolean isNameUnique(OLAPObject oo, String name) {
+        OLAPSession olapSession = getSession(oo);
+        if (olapSession == null) {
+ throw new IllegalArgumentException("Can't find OLAPSession ancestor: " + oo);
+        }
+
+        OLAPObject foundObj;
+        if (oo instanceof Cube) {
+            foundObj = olapSession.findCube(name);
+ } else if (oo instanceof Dimension && oo.getParent() instanceof Schema) {
+            foundObj = olapSession.findPublicDimension(name);
+ } else if (oo instanceof CubeDimension && oo.getParent() instanceof Cube) { + foundObj = olapSession.findCubeDimension(oo.getParent().getName(), oo.getName());
+        } else {
+            return true;
+        }
+
+        return foundObj == null || foundObj == oo;
     }
 }

Modified: trunk/src/ca/sqlpower/architect/olap/SchemaWatcher.java
==============================================================================
--- trunk/src/ca/sqlpower/architect/olap/SchemaWatcher.java     (original)
+++ trunk/src/ca/sqlpower/architect/olap/SchemaWatcher.java Mon Aug 25 14:50:07 2008
@@ -447,6 +447,45 @@
     }

     /**
+     * Searches through the map of public dimensions for one with the given
+     * name and returns it.
+     *
+     * @param name
+     *            The name to search by.
+     * @return A Dimension with the given name, or null if none found.
+     */
+    public Dimension findPublicDimension(String name) {
+        return publicDimensions.get(name);
+    }
+
+    /**
+     * Searches through the map of CubeDimensions for one with a
+ * [EMAIL PROTECTED] CubeDimensionKey} that matches the given cube name and dimension
+     * name and returns it.
+     *
+     * @param cubeName
+     *            Part of the [EMAIL PROTECTED] CubeDimensionKey} to search by.
+     * @param dimName
+     *            Part of the [EMAIL PROTECTED] CubeDimensionKey} to search by.
+ * @return A CubeDimension identified by a [EMAIL PROTECTED] CubeDimensionKey} that
+     *         represents the given names, or null with none found.
+     */
+ public CubeDimension findCubeDimension(String cubeName, String dimName) {
+        return cubeDimensions.get(new CubeDimensionKey(cubeName, dimName));
+    }
+
+    /**
+     * Finds and returns the map of Cubes for one with the given name.
+     *
+     * @param name
+     *            The name to search by.
+     * @return A Cube with the given name, or null if none found.
+     */
+    public Cube findCube(String name) {
+        return cubes.get(name);
+    }
+
+    /**
* A composite key class that holds the cubeName and name properties in a * VirtualCubeDimension. The cubeName property identifies the name of Cube * that holds the CubeDimension and the name property identifies the name of
@@ -515,5 +554,4 @@
             return getCubeName() + "." + getDimensionName();
         }
     }
-
 }

Modified: trunk/src/ca/sqlpower/architect/swingui/olap/CubeEditPanel.java
==============================================================================
--- trunk/src/ca/sqlpower/architect/swingui/olap/CubeEditPanel.java (original) +++ trunk/src/ca/sqlpower/architect/swingui/olap/CubeEditPanel.java Mon Aug 25 14:50:07 2008
@@ -34,12 +34,16 @@
 import ca.sqlpower.architect.olap.MondrianModel.Cube;
 import ca.sqlpower.architect.olap.MondrianModel.Measure;
 import ca.sqlpower.architect.olap.MondrianModel.Table;
-import ca.sqlpower.swingui.DataEntryPanel;
+import ca.sqlpower.validation.Validator;
+import ca.sqlpower.validation.swingui.FormValidationHandler;
+import ca.sqlpower.validation.swingui.StatusComponent;
+import ca.sqlpower.validation.swingui.ValidatableDataEntryPanel;
+import ca.sqlpower.validation.swingui.ValidationHandler;

 import com.jgoodies.forms.builder.DefaultFormBuilder;
 import com.jgoodies.forms.layout.FormLayout;

-public class CubeEditPanel implements DataEntryPanel {
+public class CubeEditPanel implements ValidatableDataEntryPanel {

     private final Cube cube;
     private final JPanel panel;
@@ -49,6 +53,12 @@
     private JComboBox tableChooser;

     /**
+     * Validation handler for errors in the dialog
+     */
+    private FormValidationHandler handler;
+    private StatusComponent status = new StatusComponent();
+
+    /**
      * Creates a new property editor for the given OLAP Cube.
      *
      * @param cube The data model of the cube to edit
@@ -62,6 +72,7 @@
                 "left:max(40dlu;pref), 3dlu, 80dlu:grow", "");
         DefaultFormBuilder builder = new DefaultFormBuilder(layout);
         builder.setDefaultDialogBorder();
+        builder.append(status, 3);
         builder.append("Name", nameField = new JTextField(cube.getName()));
builder.append("Table", tableChooser = new JComboBox(new Vector<SQLTable>(tables))); builder.append("Caption", captionField = new JTextField(cube.getCaption()));
@@ -78,6 +89,10 @@
             }
         }
         panel = builder.getPanel();
+
+        handler = new FormValidationHandler(status);
+        Validator validator = new OLAPObjectNameValidator(cube, true);
+        handler.addValidateObject(nameField, validator);
     }

     public boolean applyChanges() {
@@ -114,5 +129,9 @@

     public boolean hasUnsavedChanges() {
         return true;
+    }
+
+    public ValidationHandler getValidationHandler() {
+        return handler;
     }
 }

Modified: trunk/src/ca/sqlpower/architect/swingui/olap/DimensionEditPanel.java
==============================================================================
--- trunk/src/ca/sqlpower/architect/swingui/olap/DimensionEditPanel.java (original) +++ trunk/src/ca/sqlpower/architect/swingui/olap/DimensionEditPanel.java Mon Aug 25 14:50:07 2008
@@ -26,12 +26,16 @@

 import mondrian.olap.DimensionType;
 import ca.sqlpower.architect.olap.MondrianModel.Dimension;
-import ca.sqlpower.swingui.DataEntryPanel;
+import ca.sqlpower.validation.Validator;
+import ca.sqlpower.validation.swingui.FormValidationHandler;
+import ca.sqlpower.validation.swingui.StatusComponent;
+import ca.sqlpower.validation.swingui.ValidatableDataEntryPanel;
+import ca.sqlpower.validation.swingui.ValidationHandler;

 import com.jgoodies.forms.builder.DefaultFormBuilder;
 import com.jgoodies.forms.layout.FormLayout;

-public class DimensionEditPanel implements DataEntryPanel {
+public class DimensionEditPanel implements ValidatableDataEntryPanel {

     private final Dimension dimension;
     private final JPanel panel;
@@ -40,6 +44,12 @@
     private JComboBox typeBox;

     /**
+     * Validation handler for errors in the dialog
+     */
+    private FormValidationHandler handler;
+    private StatusComponent status = new StatusComponent();
+
+    /**
      * Creates a new property editor for the given OLAP dimension.
      *
      * @param dimension The dimension to edit
@@ -51,6 +61,7 @@
                 "left:max(40dlu;pref), 3dlu, 80dlu:grow", "");
         DefaultFormBuilder builder = new DefaultFormBuilder(layout);
         builder.setDefaultDialogBorder();
+        builder.append(status, 3);
builder.append("Name", nameField = new JTextField(dimension.getName())); builder.append("Caption", captionField = new JTextField(dimension.getCaption())); builder.append("Type", typeBox = new JComboBox(DimensionType.values()));
@@ -60,6 +71,10 @@
             typeBox.setSelectedItem(DimensionType.StandardDimension);
         }
         panel = builder.getPanel();
+
+        handler = new FormValidationHandler(status);
+        Validator validator = new OLAPObjectNameValidator(dimension, true);
+        handler.addValidateObject(nameField, validator);
     }
     public boolean applyChanges() {
dimension.startCompoundEdit("Started modifying dimension properties");
@@ -89,6 +104,9 @@

     public boolean hasUnsavedChanges() {
         return true;
+    }
+    public ValidationHandler getValidationHandler() {
+        return handler;
     }

 }

Added: trunk/src/ca/sqlpower/architect/swingui/olap/OLAPObjectNameValidator.java
==============================================================================
--- (empty file)
+++ trunk/src/ca/sqlpower/architect/swingui/olap/OLAPObjectNameValidator.java Mon Aug 25 14:50:07 2008
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2008, SQL Power Group Inc.
+ *
+ * This file is part of Power*Architect.
+ *
+ * Power*Architect is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Power*Architect is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package ca.sqlpower.architect.swingui.olap;
+
+import ca.sqlpower.architect.olap.OLAPObject;
+import ca.sqlpower.architect.olap.OLAPUtil;
+import ca.sqlpower.validation.Status;
+import ca.sqlpower.validation.ValidateResult;
+import ca.sqlpower.validation.Validator;
+
+/**
+ * A simple validator for OLAPObjects that checks for empty and unique names.
+ *
+ */
+public class OLAPObjectNameValidator implements Validator {
+
+    private final OLAPObject oo;
+
+    /**
+ * Indicates whether to check if the name is empty or null; true to check,
+     * false for otherwise.
+     */
+    private final boolean checkEmptyName;
+
+    public OLAPObjectNameValidator(OLAPObject oo, boolean checkEmptyName) {
+        this.oo = oo;
+        this.checkEmptyName = checkEmptyName;
+    }
+
+    public ValidateResult validate(Object contents) {
+        String value = (String) contents;
+ if (checkEmptyName && (value == null || value.trim().length() == 0)) {
+            return ValidateResult.createValidateResult(Status.FAIL,
+                    "A name is required.");
+        } else if (OLAPUtil.isNameUnique(oo, value)) {
+            return ValidateResult.createValidateResult(Status.OK, "");
+        } else {
+ return ValidateResult.createValidateResult(Status.FAIL, "Name already exists.");
+        }
+    }
+
+}

Modified: trunk/src/ca/sqlpower/architect/swingui/olap/VirtualCubePane.java
==============================================================================
--- trunk/src/ca/sqlpower/architect/swingui/olap/VirtualCubePane.java (original) +++ trunk/src/ca/sqlpower/architect/swingui/olap/VirtualCubePane.java Mon Aug 25 14:50:07 2008
@@ -28,7 +28,6 @@
 import ca.sqlpower.architect.olap.MondrianModel.CubeUsage;
 import ca.sqlpower.architect.olap.MondrianModel.CubeUsages;
 import ca.sqlpower.architect.olap.MondrianModel.Dimension;
-import ca.sqlpower.architect.olap.MondrianModel.Schema;
 import ca.sqlpower.architect.olap.MondrianModel.VirtualCube;
 import ca.sqlpower.architect.olap.MondrianModel.VirtualCubeDimension;
 import ca.sqlpower.architect.olap.MondrianModel.VirtualCubeMeasure;
@@ -81,12 +80,13 @@
             panel = null;
         } else if (coord.getIndex() > PlayPenCoordinate.ITEM_INDEX_TITLE){
             if (coord.getItem() instanceof CubeUsage) {
-                String name = ((CubeUsage) coord.getItem()).getCubeName();
- Cube c = OLAPUtil.findCube((Schema) model.getParent(), name);
+                CubeUsage cu = (CubeUsage) coord.getItem();
+                Cube c = OLAPUtil.findReferencedCube(cu);
if (c == null) throw new NullPointerException("Couldn't find cube!");
                 panel = new CubeEditPanel(c);
             } else if (coord.getItem() instanceof VirtualCubeDimension) {
- Dimension d = OLAPUtil.findDimension((Schema) model.getParent(), ((VirtualCubeDimension) coord.getItem())); + VirtualCubeDimension vcd = (VirtualCubeDimension) coord.getItem();
+                Dimension d = OLAPUtil.findReferencedDimension(vcd);
if (d == null) throw new NullPointerException("Couldn't find dimension!");
                 panel = new DimensionEditPanel(d);
             } else if (coord.getItem() instanceof VirtualCubeMeasure) {

Reply via email to