/*
// This software is subject to the terms of the Eclipse Public License v1.0
// Agreement, available at the following URL:
// http://www.eclipse.org/legal/epl-v10.html.
// You must accept the terms of that agreement to use this software.
//
// Copyright (C) 2002-2005 Julian Hyde
// Copyright (C) 2005-2016 Pentaho and others
// Copyright (C) 2006-2007 CINCOM SYSTEMS, INC.
// All Rights Reserved.
*/
package mondrian.gui;
import mondrian.util.CompositeList;
import java.util.*;
import javax.swing.tree.*;
/**
* @author sean
*/
public class SchemaTreeModel extends DefaultTreeModel {
/**
* Creates a SchemaTreeModel.
*/
public SchemaTreeModel() {
super(null);
// TODO Auto-generated constructor stub
}
MondrianGuiDef.Schema schema;
/**
* Creates a new instance of SchemaTreeModel
*/
public SchemaTreeModel(MondrianGuiDef.Schema s) {
super(new DefaultMutableTreeNode(s.name));
this.schema = s;
}
/**
* Returns the child of <code>parent</code> at index <code>index</code>
* in the parent's
* child array. <code>parent</code> must be a node previously obtained
* from this data source. This should not return <code>null</code>
* if <code>index</code>
* is a valid index for <code>parent</code> (that is <code>index >= 0 &&
* index < getChildCount(parent</code>)).
*
* @param parent a node in the tree, obtained from this data source
* @return the child of <code>parent</code> at index <code>index</code>
*/
public Object getChild(Object parent, int index) {
return getChildList(parent).get(index);
}
/**
* Returns an immutable list of child elements of a given element.
*
* @param parent Parent element
* @return List of children
*/
private List<Object> getChildList(Object parent) {
if (parent instanceof MondrianGuiDef.Cube) {
MondrianGuiDef.Cube c = (MondrianGuiDef.Cube) parent;
// Return children in this order: fact table, dimensions, measures,
// calculatedMembers, namedSets
return new CompositeList<Object>(
ifList(c.fact),
Arrays.asList(c.dimensions),
Arrays.asList(c.measures),
Arrays.asList(c.calculatedMembers),
Arrays.asList(c.namedSets),
ifList(c.annotations));
} else if (parent instanceof MondrianGuiDef.Dimension) {
MondrianGuiDef.Dimension d = (MondrianGuiDef.Dimension) parent;
return new CompositeList<Object>(
Arrays.asList((Object[]) d.hierarchies),
ifList(d.annotations));
} else if (parent instanceof MondrianGuiDef.UserDefinedFunction) {
MondrianGuiDef.UserDefinedFunction udf =
(MondrianGuiDef.UserDefinedFunction) parent;
return new CompositeList<Object>(
ifList(udf.script));
} else if (parent instanceof MondrianGuiDef.ExpressionView) {
MondrianGuiDef.ExpressionView ev =
(MondrianGuiDef.ExpressionView) parent;
return Arrays.asList((Object[]) ev.expressions);
} else if (parent instanceof MondrianGuiDef.Hierarchy) {
MondrianGuiDef.Hierarchy h = (MondrianGuiDef.Hierarchy) parent;
return new CompositeList<Object>(
Arrays.asList(h.levels),
Arrays.asList(h.memberReaderParameters),
ifList(h.relation),
ifList(h.annotations));
} else if (parent instanceof MondrianGuiDef.Join) {
MondrianGuiDef.Join j = (MondrianGuiDef.Join) parent;
return Arrays.<Object>asList(
j.left,
j.right);
} else if (parent instanceof MondrianGuiDef.Level) {
MondrianGuiDef.Level level = (MondrianGuiDef.Level) parent;
return new CompositeList<Object>(
Arrays.asList(level.properties),
ifList(level.keyExp),
ifList(level.nameExp),
ifList(level.ordinalExp),
ifList(level.captionExp),
ifList(level.parentExp),
ifList(level.closure),
ifList(level.memberFormatter),
ifList(level.annotations));
} else if (parent instanceof MondrianGuiDef.CellFormatter) {
MondrianGuiDef.CellFormatter f =
(MondrianGuiDef.CellFormatter) parent;
return new CompositeList<Object>(
ifList(f.script));
} else if (parent instanceof MondrianGuiDef.MemberFormatter) {
MondrianGuiDef.MemberFormatter f =
(MondrianGuiDef.MemberFormatter) parent;
return new CompositeList<Object>(
ifList(f.script));
} else if (parent instanceof MondrianGuiDef.PropertyFormatter) {
MondrianGuiDef.PropertyFormatter f =
(MondrianGuiDef.PropertyFormatter) parent;
return new CompositeList<Object>(
ifList(f.script));
} else if (parent instanceof MondrianGuiDef.Property) {
MondrianGuiDef.Property property =
(MondrianGuiDef.Property) parent;
return new CompositeList<Object>(
ifList(property.propertyFormatter));
} else if (parent instanceof MondrianGuiDef.CalculatedMember) {
MondrianGuiDef.CalculatedMember c =
(MondrianGuiDef.CalculatedMember) parent;
return new CompositeList<Object>(
ifList(c.formulaElement),
arrayList(c.memberProperties),
ifList(c.annotations),
ifList(c.cellFormatter));
} else if (parent instanceof MondrianGuiDef.Measure) {
MondrianGuiDef.Measure m = (MondrianGuiDef.Measure) parent;
return new CompositeList<Object>(
ifList(m.measureExp),
arrayList(m.memberProperties),
ifList(m.annotations),
ifList(m.cellFormatter));
} else if (parent instanceof MondrianGuiDef.NamedSet) {
MondrianGuiDef.NamedSet m = (MondrianGuiDef.NamedSet) parent;
return new CompositeList<Object>(
ifList((Object) m.formulaElement),
ifList(m.annotations));
} else if (parent instanceof MondrianGuiDef.Schema) {
MondrianGuiDef.Schema s = (MondrianGuiDef.Schema) parent;
// Return children in this order: cubes, dimensions, namedSets,
// userDefinedFunctions, virtual cubes, roles
return new CompositeList<Object>(
Arrays.asList(s.cubes),
Arrays.asList(s.dimensions),
Arrays.asList(s.namedSets),
Arrays.asList(s.namedSets),
Arrays.asList(s.userDefinedFunctions),
Arrays.asList(s.virtualCubes),
Arrays.asList(s.roles),
Arrays.asList(s.parameters),
ifList(s.annotations));
} else if (parent instanceof MondrianGuiDef.Table) {
MondrianGuiDef.Table t = (MondrianGuiDef.Table) parent;
return new CompositeList<Object>(
arrayList(t.aggTables),
arrayList(t.aggExcludes));
} else if (parent instanceof MondrianGuiDef.AggTable) {
MondrianGuiDef.AggTable t = (MondrianGuiDef.AggTable) parent;
return new CompositeList<Object>(
ifList(t.factcount),
Arrays.asList(t.measuresfactcount),
Arrays.asList(t.ignoreColumns),
Arrays.asList(t.foreignKeys),
Arrays.asList(t.measures),
Arrays.asList(t.levels),
(t instanceof MondrianGuiDef.AggPattern)
? Arrays.asList(((MondrianGuiDef.AggPattern) t).excludes)
: Collections.emptyList());
} else if (parent instanceof MondrianGuiDef.AggLevel) {
MondrianGuiDef.AggLevel t = (MondrianGuiDef.AggLevel) parent;
if (t.properties == null) {
t.properties = new MondrianGuiDef.AggLevelProperty[0];
}
return new CompositeList<Object>(
Arrays.asList(t.properties));
} else if (parent instanceof MondrianGuiDef.View) {
MondrianGuiDef.View v = (MondrianGuiDef.View) parent;
return Arrays.asList((Object[]) v.selects);
} else if (parent instanceof MondrianGuiDef.VirtualCube) {
MondrianGuiDef.VirtualCube c = (MondrianGuiDef.VirtualCube) parent;
return new CompositeList<Object>(
Arrays.asList(c.dimensions),
Arrays.asList(c.measures),
Arrays.asList(c.calculatedMembers),
ifList(c.annotations));
} else if (parent instanceof MondrianGuiDef.VirtualCubeDimension) {
MondrianGuiDef.VirtualCubeDimension d =
(MondrianGuiDef.VirtualCubeDimension) parent;
return ifList((Object)d.annotations);
} else if (parent instanceof MondrianGuiDef.VirtualCubeMeasure) {
MondrianGuiDef.VirtualCubeMeasure m =
(MondrianGuiDef.VirtualCubeMeasure) parent;
return ifList((Object)m.annotations);
} else if (parent instanceof MondrianGuiDef.Role) {
MondrianGuiDef.Role c = (MondrianGuiDef.Role) parent;
return new CompositeList<Object>(
Arrays.asList((Object[]) c.schemaGrants),
ifList((Object)c.annotations));
} else if (parent instanceof MondrianGuiDef.SchemaGrant) {
MondrianGuiDef.SchemaGrant c = (MondrianGuiDef.SchemaGrant) parent;
return Arrays.asList((Object[]) c.cubeGrants);
} else if (parent instanceof MondrianGuiDef.CubeGrant) {
MondrianGuiDef.CubeGrant c = (MondrianGuiDef.CubeGrant) parent;
return new CompositeList<Object>(
Arrays.asList(c.dimensionGrants),
Arrays.asList(c.hierarchyGrants));
} else if (parent instanceof MondrianGuiDef.HierarchyGrant) {
MondrianGuiDef.HierarchyGrant c =
(MondrianGuiDef.HierarchyGrant) parent;
return Arrays.asList((Object[]) c.memberGrants);
} else if (parent instanceof MondrianGuiDef.Closure) {
MondrianGuiDef.Closure c = (MondrianGuiDef.Closure) parent;
return ifList((Object) c.table);
} else if (parent instanceof MondrianGuiDef.Annotations) {
MondrianGuiDef.Annotations annotations =
(MondrianGuiDef.Annotations) parent;
return Arrays.asList((Object[]) annotations.array);
} else {
// In particular: Column, SQL, DimensionUsage have no children.
return Collections.emptyList();
}
}
/**
* Returns a list with zero or one elements.
*
* @param e Element
* @param <T> Element type
* @return List containing element if it is not null, otherwise empty list
*/
private <T> List<T> ifList(T e) {
return e == null
? Collections.<T>emptyList()
: Collections.singletonList(e);
}
/**
* Returns a list with a given set of elements, or an empty list if the
* array is null.
*
* @param e Element
* @param <T> Element type
* @return List containing element if it is not null, otherwise empty list
*/
private <T> List<T> arrayList(T... e) {
return e == null || e.length == 0
? Collections.<T>emptyList()
: e.length == 1
? Collections.singletonList(e[0])
: Arrays.asList(e);
}
/**
* Returns the number of children of <code>parent</code>.
* Returns 0 if the node
* is a leaf or if it has no children. <code>parent</code> must be a node
* previously obtained from this data source.
*
* @param parent a node in the tree, obtained from this data source
* @return the number of children of the node <code>parent</code>
*/
public int getChildCount(Object parent) {
return getChildList(parent).size();
}
/**
* Returns the index of child in parent. If <code>parent</code>
* is <code>null</code> or <code>child</code> is <code>null</code>,
* returns -1.
*
* @param parent a note in the tree, obtained from this data source
* @param child the node we are interested in
* @return the index of the child in the parent, or -1 if either
* <code>child</code> or <code>parent</code> are <code>null</code>
*/
public int getIndexOfChild(Object parent, Object child) {
if (parent == null) {
return -1;
}
final List<Object> list = getChildList(parent);
int i = 0;
for (Object o : list) {
if (equal(o, child)) {
return i;
}
++i;
}
return -1;
}
/**
* Returns whether two XML objects are equal.
*
* @param o1 First object
* @param o2 Second object
* @return Whether objects are equal
*/
private boolean equal(Object o1, Object o2) {
if (o1 == null) {
return o2 == null;
} else if (o1 instanceof MondrianGuiDef.Hierarchy
|| o1 instanceof MondrianGuiDef.SQL)
{
return o1 == o2;
} else {
return o1.equals(o2);
}
}
/**
* Returns the root of the tree. Returns <code>null</code>
* only if the tree has no nodes.
*
* @return the root of the tree
*/
public Object getRoot() {
return schema;
}
/**
* Returns <code>true</code> if <code>node</code> is a leaf.
* It is possible for this method to return <code>false</code>
* even if <code>node</code> has no children.
* A directory in a filesystem, for example,
* may contain no files; the node representing
* the directory is not a leaf, but it also has no children.
*
* @param node a node in the tree, obtained from this data source
* @return true if <code>node</code> is a leaf
*/
public boolean isLeaf(Object node) {
return getChildCount(node) == 0;
}
public void valueForPathChanged(TreePath path, Object newValue) {
//super.valueForPathChanged(path, newValue);
}
}
// End SchemaTreeModel.java