001    /*
002    /*
003    // $Id: //open/mondrian/src/main/mondrian/gui/SchemaTreeCellRenderer.java#20 $
004    // This software is subject to the terms of the Common Public License
005    // Agreement, available at the following URL:
006    // http://www.opensource.org/licenses/cpl.html.
007    // Copyright (C) 2002-2008 Julian Hyde and others
008    // Copyright (C) 2006-2007 CINCOM SYSTEMS, INC.
009    // All Rights Reserved.
010    // You must accept the terms of that agreement to use this software.
011    */
012    package mondrian.gui;
013    
014    import java.awt.Component;
015    import java.awt.Dimension;
016    
017    import javax.swing.ImageIcon;
018    import javax.swing.JTree;
019    import javax.swing.tree.TreePath;
020    
021    import mondrian.gui.validate.ValidationUtils;
022    import mondrian.gui.validate.impl.WorkbenchJDBCValidator;
023    import mondrian.gui.validate.impl.WorkbenchMessages;
024    import mondrian.gui.validate.impl.WorkbenchTreeModel;
025    import mondrian.gui.validate.impl.WorkbenchTreeModelPath;
026    
027    import org.eigenbase.xom.ElementDef;
028    
029    /**
030     * Render an entry for the tree.
031     *
032     * @author  sean
033     * @version $Id: //open/mondrian/src/main/mondrian/gui/SchemaTreeCellRenderer.java#20 $
034     */
035    public class SchemaTreeCellRenderer extends javax.swing.tree.DefaultTreeCellRenderer {
036    
037        private final ClassLoader myClassLoader;
038        public boolean invalidFlag;
039        private JDBCMetaData jdbcMetaData;
040        private Workbench workbench;
041    
042        /** Creates a new instance of SchemaTreeCellRenderer */
043    
044        public SchemaTreeCellRenderer(Workbench wb, JDBCMetaData jdbcMetaData) {
045            this();
046            this.workbench = wb;
047            this.jdbcMetaData = jdbcMetaData;
048        }
049        public SchemaTreeCellRenderer() {
050            super();
051            myClassLoader = this.getClass().getClassLoader();
052    
053        }
054    
055        public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
056            super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
057    
058            invalidFlag = isInvalid(tree, value, row);
059    
060            this.setPreferredSize(null); // This allows the layout mgr to calculate the pref size of renderer.
061            if (value instanceof MondrianGuiDef.Cube) {
062                setText(invalidFlag, ((MondrianGuiDef.Cube) value).name);
063                super.setIcon(new ImageIcon(myClassLoader.getResource(workbench.getResourceConverter().getGUIReference("cube"))));
064            } else if (value instanceof MondrianGuiDef.Column) {
065                setText(invalidFlag, ((MondrianGuiDef.Column) value).name);
066            } else if (value instanceof MondrianGuiDef.Dimension) {
067                super.setIcon(new ImageIcon(myClassLoader.getResource(workbench.getResourceConverter().getGUIReference("dimension"))));
068                setText(invalidFlag, ((MondrianGuiDef.CubeDimension) value).name);
069                /* Do not remove this line.
070                 * This sets the preferred width of tree cell displaying dimension name.
071                 * This resolves the ambiguous problem of last char or last word truncated from dimension name in the tree cell.
072                 * This problem was there with only Dimension objects, while all other objects display their names
073                 * without any truncation of characters. Therefore, we have to force the setting of preferred width to desired width
074                 * so that characters do not truncate from dimension name.
075                 * Along with this the preferred size of other objects should be set to null, so that the layout mgr can calculate the
076                 * preferred width in case of other objects.
077                 */
078                this.setPreferredSize(new java.awt.Dimension(this.getPreferredSize().width + 1, 25)); //Do not remove this
079            } else if (value instanceof MondrianGuiDef.DimensionUsage)      {
080                super.setIcon(new ImageIcon(myClassLoader.getResource(workbench.getResourceConverter().getGUIReference("dimensionUsage"))));
081                setText(invalidFlag, ((MondrianGuiDef.CubeDimension) value).name);
082            } else if (value instanceof MondrianGuiDef.KeyExpression) {
083                super.setIcon(new ImageIcon(myClassLoader.getResource(workbench.getResourceConverter().getGUIReference("key"))));
084                setText(workbench.getResourceConverter().getString("common.keyExpression.title","Key Expression"));
085            } else if (value instanceof MondrianGuiDef.NameExpression) {
086                super.setIcon(new ImageIcon(myClassLoader.getResource(workbench.getResourceConverter().getGUIReference("name"))));
087                setText(workbench.getResourceConverter().getString("common.nameExpression.title","Name Expression"));
088            } else if (value instanceof MondrianGuiDef.OrdinalExpression) {
089                super.setIcon(new ImageIcon(myClassLoader.getResource(workbench.getResourceConverter().getGUIReference("ordinal"))));
090                setText(workbench.getResourceConverter().getString("common.ordinalExpression.title","Ordinal Expression"));
091            } else if (value instanceof MondrianGuiDef.ParentExpression) {
092                super.setIcon(new ImageIcon(myClassLoader.getResource(workbench.getResourceConverter().getGUIReference("parent"))));
093                setText(workbench.getResourceConverter().getString("common.parentExpression.title","Parent Expression"));
094            } else if (value instanceof MondrianGuiDef.Expression) {
095                setText(workbench.getResourceConverter().getString("common.expression.title","Expression"));
096            } else if (value instanceof MondrianGuiDef.ExpressionView) {
097                setText(workbench.getResourceConverter().getString("common.expressionView.title","Expression View"));
098            } else if (value instanceof MondrianGuiDef.Hierarchy) {
099                setText(invalidFlag, workbench.getResourceConverter().getString("common.hierarchy.title","Hierarchy"));
100                //setText(((MondrianGuiDef.Hierarchy) value).name);    // hierarchies do not have names
101                super.setIcon(new ImageIcon(myClassLoader.getResource(workbench.getResourceConverter().getGUIReference("hierarchy"))));
102                this.setPreferredSize(new java.awt.Dimension(this.getPreferredSize().width + 1, 25)); //Do not remove this
103    
104            } else if ((value instanceof MondrianGuiDef.RelationOrJoin) ||
105                // REVIEW: '||' is superfluous - a Table is always a RelationOrJoin
106                    (value instanceof MondrianGuiDef.Table)) {
107                TreePath tpath = tree.getPathForRow(row);
108                String prefix = "";
109                if (tpath != null) {
110                    TreePath parentpath = tpath.getParentPath();
111                    if (parentpath != null) {
112                        Object parent = parentpath.getLastPathComponent();
113                        if (parent instanceof MondrianGuiDef.Join) {
114                            int indexOfChild = tree.getModel().getIndexOfChild(parent, value);
115                            switch (indexOfChild) {
116                            case 0:
117                                prefix = workbench.getResourceConverter().getString("common.leftPrefix.title","Left") + " ";
118                                break;
119                            case 1:
120                                prefix = workbench.getResourceConverter().getString("common.rightPrefix.title","Right") + " ";
121                                break;
122                            }
123                        }
124                    }
125                }
126                if (value instanceof MondrianGuiDef.Join) {
127                    setText(workbench.getResourceConverter().getFormattedString("schemaTreeCellRenderer.join.title",
128                            "{0} : Join", new String[] {prefix}));
129                    //setText(prefix + " " + workbench.getResourceConverter().getString("common.join.title","Join"));
130                    super.setIcon(new ImageIcon(myClassLoader.getResource(workbench.getResourceConverter().getGUIReference("join"))));
131                } else if (value instanceof MondrianGuiDef.Table) {
132                    //setText(prefix+"Table: "+ ((MondrianGuiDef.Table) value).name);
133                    setText(workbench.getResourceConverter().getFormattedString("schemaTreeCellRenderer.table.title",
134                            "{0}Table: {1}", new String[] {(prefix.length() == 0 ? "" : prefix + " : "), ((MondrianGuiDef.Table) value).name}));
135                    super.setIcon(new ImageIcon(myClassLoader.getResource(workbench.getResourceConverter().getGUIReference("table"))));
136                }
137                // REVIEW: Need to deal with InlineTable and View here
138                this.getPreferredSize();
139                this.setPreferredSize(new Dimension(this.getPreferredSize().width + 35, 24)); //Do not remove this
140                //this.setSize(new Dimension(this.getPreferredSize().width, 24)); //Do not remove this
141                //this.setPreferredSize(new Dimension(170, 24)); //Do not remove this
142                //setText("Relation");
143    
144            } else if (value instanceof MondrianGuiDef.Level) {
145                setText(invalidFlag, ((MondrianGuiDef.Level) value).name);
146                super.setIcon(new ImageIcon(myClassLoader.getResource(workbench.getResourceConverter().getGUIReference("level"))));
147                /* Do not remove this line.
148                 * This sets the preferred width of tree cell displaying Level name.
149                 * This resolves the ambiguous problem of last char or last word truncated from Level name in the tree cell.
150                 * This problem was there with Level objects, while all other objects display their names
151                 * without any truncation of characters. Therefore, we have to force the setting of preferred width to desired width
152                 * so that characters do not truncate from dimension name.
153                 * Along with this the preferred size of other objects should be set to null, so that the layout mgr can calculate the
154                 * preferred width in case of other objects.
155                 */
156                this.setPreferredSize(new java.awt.Dimension(this.getPreferredSize().width + 1, 25)); //Do not remove this
157            } else if (value instanceof MondrianGuiDef.Measure) {
158    
159                setText(invalidFlag, ((MondrianGuiDef.Measure) value).name);
160                super.setIcon(new ImageIcon(myClassLoader.getResource(workbench.getResourceConverter().getGUIReference("measure"))));
161            } else if (value instanceof MondrianGuiDef.MemberReaderParameter) {
162                setText(invalidFlag, ((MondrianGuiDef.MemberReaderParameter) value).name);
163            } else if (value instanceof MondrianGuiDef.Property) {
164                setText(invalidFlag, ((MondrianGuiDef.Property) value).name);
165                super.setIcon(new ImageIcon(myClassLoader.getResource(workbench.getResourceConverter().getGUIReference("property"))));
166            } else if (value instanceof MondrianGuiDef.Schema) {
167                setText(invalidFlag, workbench.getResourceConverter().getString("common.schema.title","Schema"));
168                super.setIcon(new ImageIcon(myClassLoader.getResource(workbench.getResourceConverter().getGUIReference("schema"))));
169            } else if (value instanceof MondrianGuiDef.NamedSet) {
170                setText(invalidFlag, ((MondrianGuiDef.NamedSet) value).name);
171                super.setIcon(new ImageIcon(myClassLoader.getResource(workbench.getResourceConverter().getGUIReference("namedSet"))));
172            } else if (value instanceof MondrianGuiDef.CalculatedMember) {
173                setText(invalidFlag, ((MondrianGuiDef.CalculatedMember) value).name);
174                super.setIcon(new ImageIcon(myClassLoader.getResource(workbench.getResourceConverter().getGUIReference("calculatedMember"))));
175            } else if (value instanceof MondrianGuiDef.CalculatedMemberProperty) {
176                setText(invalidFlag, ((MondrianGuiDef.CalculatedMemberProperty) value).name);
177                super.setIcon(new ImageIcon(myClassLoader.getResource(workbench.getResourceConverter().getGUIReference("nopic"))));
178            } else if (value instanceof MondrianGuiDef.UserDefinedFunction) {
179                setText(invalidFlag, ((MondrianGuiDef.UserDefinedFunction) value).name);
180                super.setIcon(new ImageIcon(myClassLoader.getResource(workbench.getResourceConverter().getGUIReference("userDefinedFunction"))));
181            } else if (value instanceof MondrianGuiDef.Role) {
182                setText(invalidFlag, ((MondrianGuiDef.Role) value).name);
183                super.setIcon(new ImageIcon(myClassLoader.getResource(workbench.getResourceConverter().getGUIReference("role"))));
184            } else if (value instanceof MondrianGuiDef.SchemaGrant) {
185                setText(invalidFlag, workbench.getResourceConverter().getString("common.schemaGrant.title","Schema Grant"));
186                super.setIcon(new ImageIcon(myClassLoader.getResource(workbench.getResourceConverter().getGUIReference("schemaGrant"))));
187            } else if (value instanceof MondrianGuiDef.CubeGrant) {
188                setText(invalidFlag, workbench.getResourceConverter().getString("common.cubeGrant.title","Cube Grant"));
189                super.setIcon(new ImageIcon(myClassLoader.getResource(workbench.getResourceConverter().getGUIReference("cubeGrant"))));
190            } else if (value instanceof MondrianGuiDef.DimensionGrant) {
191                setText(invalidFlag, workbench.getResourceConverter().getString("common.dimensionGrant.title","Dimension Grant"));
192                super.setIcon(new ImageIcon(myClassLoader.getResource(workbench.getResourceConverter().getGUIReference("dimensionGrant"))));
193            } else if (value instanceof MondrianGuiDef.HierarchyGrant) {
194                setText(invalidFlag, workbench.getResourceConverter().getString("common.hierarchyGrant.title","Hierarchy Grant"));
195                super.setIcon(new ImageIcon(myClassLoader.getResource(workbench.getResourceConverter().getGUIReference("hierarchyGrant"))));
196            } else if (value instanceof MondrianGuiDef.MemberGrant) {
197                setText(invalidFlag, workbench.getResourceConverter().getString("common.memberGrant.title","Member Grant"));
198                super.setIcon(new ImageIcon(myClassLoader.getResource(workbench.getResourceConverter().getGUIReference("memberGrant"))));
199            } else if (value instanceof MondrianGuiDef.SQL) {
200                setText(invalidFlag, ((MondrianGuiDef.SQL) value).dialect);
201                super.setIcon(new ImageIcon(myClassLoader.getResource(workbench.getResourceConverter().getGUIReference("sql"))));
202            } else if (value instanceof MondrianGuiDef.View) {
203                setText(workbench.getResourceConverter().getString("common.view.title","View"));
204            } else if (value instanceof MondrianGuiDef.VirtualCube) {
205                setText(invalidFlag, ((MondrianGuiDef.VirtualCube) value).name);
206                super.setIcon(new ImageIcon(myClassLoader.getResource(workbench.getResourceConverter().getGUIReference("virtualCube"))));
207            } else if (value instanceof MondrianGuiDef.VirtualCubeDimension) {
208                setText(invalidFlag, ((MondrianGuiDef.VirtualCubeDimension) value).name);
209                super.setIcon(new ImageIcon(myClassLoader.getResource(workbench.getResourceConverter().getGUIReference("virtualCubeDimension"))));
210            } else if (value instanceof MondrianGuiDef.VirtualCubeMeasure) {
211                setText(invalidFlag, ((MondrianGuiDef.VirtualCubeMeasure) value).name);
212                super.setIcon(new ImageIcon(myClassLoader.getResource(workbench.getResourceConverter().getGUIReference("virtualCubeMeasure"))));
213            } else if (value instanceof MondrianGuiDef.AggName) {
214                setText(invalidFlag, workbench.getResourceConverter().getString("common.aggName.title","Aggregate Name"));
215                super.setIcon(new ImageIcon(myClassLoader.getResource(workbench.getResourceConverter().getGUIReference("aggTable"))));
216            } else if (value instanceof MondrianGuiDef.AggForeignKey) {
217                setText(invalidFlag, workbench.getResourceConverter().getString("common.aggForeignKey.title","Aggregate Foreign Key"));
218                super.setIcon(new ImageIcon(myClassLoader.getResource(workbench.getResourceConverter().getGUIReference("aggForeignKey"))));
219            } else if (value instanceof MondrianGuiDef.AggIgnoreColumn) {
220                setText(invalidFlag, workbench.getResourceConverter().getString("common.aggIgnoreColumn.title","Aggregate Ignore Column"));
221                super.setIcon(new ImageIcon(myClassLoader.getResource(workbench.getResourceConverter().getGUIReference("aggIgnoreColumn"))));
222            } else if (value instanceof MondrianGuiDef.AggLevel) {
223                setText(invalidFlag, workbench.getResourceConverter().getString("common.aggLevel.title","Aggregate Level"));
224                super.setIcon(new ImageIcon(myClassLoader.getResource(workbench.getResourceConverter().getGUIReference("aggLevel"))));
225            } else if (value instanceof MondrianGuiDef.AggMeasure) {
226                setText(invalidFlag, workbench.getResourceConverter().getString("common.aggMeasure.title","Aggregate Measure"));
227                super.setIcon(new ImageIcon(myClassLoader.getResource(workbench.getResourceConverter().getGUIReference("aggMeasure"))));
228            } else if (value instanceof MondrianGuiDef.AggPattern) {
229                setText(invalidFlag, workbench.getResourceConverter().getString("common.aggPattern.title","Aggregate Pattern"));
230                super.setIcon(new ImageIcon(myClassLoader.getResource(workbench.getResourceConverter().getGUIReference("aggPattern"))));
231            } else if (value instanceof MondrianGuiDef.AggExclude) {
232                setText(invalidFlag, workbench.getResourceConverter().getString("common.aggExclude.title","Aggregate Exclude"));
233                super.setIcon(new ImageIcon(myClassLoader.getResource(workbench.getResourceConverter().getGUIReference("aggExclude"))));
234            } else if (value instanceof MondrianGuiDef.Closure) {
235                setText(invalidFlag, workbench.getResourceConverter().getString("common.closure.title","Closure"));
236                super.setIcon(new ImageIcon(myClassLoader.getResource(workbench.getResourceConverter().getGUIReference("closure"))));
237            } else if (value instanceof ElementDef) {
238                setText(((ElementDef) value).getName());
239            } else {
240                super.setText("");
241            }
242    
243            return this;
244    
245        }
246    
247        // called from external methods
248        public String invalid(JTree tree, TreePath tpath, Object value) {
249            return this.invalid(tree, tpath, value, null, null, null, null);
250        }
251    
252    
253    
254        public String invalid(JTree tree, TreePath tpath, Object value, Object icube, Object iparentDimension, Object iparentHierarchy, Object iparentLevel) {
255            return ValidationUtils.invalid(new WorkbenchMessages(workbench.getResourceConverter()), new WorkbenchJDBCValidator(jdbcMetaData),
256                    new WorkbenchTreeModel((SchemaTreeModel) tree.getModel()), new WorkbenchTreeModelPath(tpath), value, icube, iparentDimension,
257                    iparentHierarchy, iparentLevel);
258        }
259        private boolean isInvalid(JTree tree, Object value, int row) {
260            //return (invalid(tree.getSelectionPath(), value) ==null)?false:true;
261            /* (TreePath) tree.getPathForRow(row) returns null for new objects added to tree in the first run of rendering.
262             * Check for null before calling methods on Treepath returned.
263             */
264            return (invalid(tree, tree.getPathForRow(row), value) == null) ? false : true;
265            //return (invalid(null, value) ==null)?false:true;
266        }
267    
268        public void setText(boolean invalidFlag, String myText) {
269            if (invalidFlag) {
270                myText = "<html><FONT COLOR=RED><b>x</b></FONT><FONT COLOR=" + getForeground().hashCode() + ">" + myText + "</FONT></html>";
271            }
272            setText(myText);
273        }
274    }
275    
276    // End SchemaTreeCellRenderer.java