/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.rioproject.tools.ui.browser;
import net.jini.core.entry.Entry;
import net.jini.lookup.entry.ServiceControlled;
import javax.swing.*;
import javax.swing.plaf.metal.MetalLookAndFeel;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeCellRenderer;
import java.awt.*;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.util.logging.Level;
/**
* @version 0.2 06/04/98
*/
abstract class EntryTreePanel extends JPanel {
/**
* running mode.
*
* @serial
*/
private boolean isControllable;
/**
* @serial
*/
private JScrollPane scrollPane;
/**
* @serial
*/
protected JTree tree;
/**
* @serial
*/
protected ObjectNode root;
/**
* @serial
*/
protected DefaultTreeModel model;
/**
* @serial
*/
private boolean showModifier = false;
/**
* @serial
*/
private boolean showPackage = false;
public EntryTreePanel(boolean isControllable) {
this.isControllable = isControllable;
// Init this panel
setLayout(new BorderLayout());
// Init tree node and model (attribute tree nodes)
root = new ObjectNode(isControllable);
//initTree();
model = new DefaultTreeModel(root);
// Init tree view
tree = new JTree(model);
//tree.addMouseListener(new DoubleClicker(this));
tree.setRootVisible(false);
ObjectNodeRenderer renderer = new ObjectNodeRenderer();
tree.setCellRenderer(renderer);
tree.setRowHeight(0); // let the renderer handle it
scrollPane = new JScrollPane(tree);
add(scrollPane, "Center");
tree.validate();
scrollPane.validate();
}
protected abstract Entry[] getEntryArray();
protected void initTree() {
Entry[] entries = getEntryArray();
for (Entry entry : entries) {
// check controllability
boolean nodeControllable = false;
if (isControllable && !(entry instanceof ServiceControlled)) {
nodeControllable = true;
}
ObjectNode node = new ObjectNode(entry, nodeControllable);
root.add(node);
try {
recursiveObjectTree(node);
} catch (IllegalAccessException e) {
Browser.logger.log(Level.INFO, "entry access failed", e);
}
}
}
public void refreshPanel() {
// reconstruct nodes
root.removeAllChildren();
initTree();
model.nodeStructureChanged(root);
tree.validate();
scrollPane.validate();
}
protected void recursiveObjectTree(ObjectNode node)
throws IllegalArgumentException, IllegalAccessException {
Object obj = node.getObject();
if (obj == null)
return;
//Field[] fields = obj.getClass().getDeclaredFields();
Field[] fields = obj.getClass().getFields();
for (Field f : fields) {
if (Introspector.isHidden(f))
continue;
Class clazz = f.getType();
ObjectNode child = null;
String fname = f.getName();
if (clazz.isPrimitive()) {
String clazzName = clazz.toString();
Object fobj = null;
if ("int".equals(clazzName)) {
fobj = f.getInt(obj);
} else if ("boolean".equals(clazzName)) {
fobj = f.getBoolean(obj);
} else if ("byte".equals(clazzName)) {
fobj = f.getByte(obj);
} else if ("char".equals(clazzName)) {
fobj = f.getChar(obj);
} else if ("double".equals(clazzName)) {
fobj = f.getDouble(obj);
} else if ("float".equals(clazzName)) {
fobj = f.getFloat(obj);
} else if ("long".equals(clazzName)) {
fobj = f.getLong(obj);
}
child = new ObjectNode(fobj, clazz, fname, true);
} else if (Introspector.isWrapper(clazz) || Introspector.isString(clazz)) {
child = new ObjectNode(f.get(obj), clazz, fname, true);
} else if (clazz.isArray()) {
child = new ObjectNode(f.get(obj), clazz, fname, false);
child.setAdministrable(node.isAdministrable());
child.setControllable(node.isControllable());
recursiveArrayTree(child, f);
} else {
// unknown type
Object subobj = f.get(obj);
// check if sub object has a viewable members.
if (countViewableFields(clazz) > 0) {
child = new ObjectNode(subobj, clazz, fname, false);
child.setAdministrable(node.isAdministrable());
child.setControllable(node.isControllable());
recursiveObjectTree(child);
} else {
child = new ObjectNode(subobj, clazz, fname, true);
}
}
node.add(child);
}
}
private int countViewableFields(Class clazz) {
int count = 0;
//Field[] fields = obj.getClass().getDeclaredFields();
//Field[] fields = obj.getClass().getFields();
Field[] fields = clazz.getFields();
for (Field f : fields) {
if (Introspector.isHidden(f))
continue;
count++;
}
return count;
}
private void recursiveArrayTree(ObjectNode node, Field f)
throws IllegalArgumentException, IllegalAccessException {
String name = node.getFieldName();
Object aobj = node.getObject();
int length = aobj==null? 0 : Array.getLength(aobj);
Class clazz = f.getType().getComponentType();
if (clazz.isPrimitive() || Introspector.isWrapper(clazz) || Introspector.isString(clazz)) {
// primitive, wrapper objects, string array
for (int i = 0; i < length; i++) {
Object elem = Array.get(aobj, i);
//String fname = name + "[" + i + "]";
ObjectNode child = new ObjectNode(elem, clazz, name, i, true);
node.add(child);
}
} else {
// Object or Array (*sigh*)
for (int i = 0; i < length; i++) {
Object elem = Array.get(aobj, i);
//String fname = name + "[" + i + "]";
ObjectNode child = new ObjectNode(elem, clazz, name, i, false);
recursiveObjectTree(child);
child.setAdministrable(node.isAdministrable());
child.setControllable(node.isControllable());
node.add(child);
}
}
}
class ObjectNodeRenderer implements TreeCellRenderer {
private JLabel label;
public ObjectNodeRenderer() {
label = new JLabel();
label.setOpaque(true);
}
public Component getTreeCellRendererComponent(JTree tree,
Object value,
boolean isSelected,
boolean isExpanded,
boolean isLeaf,
int row,
boolean cellHasFocus) {
//label.setFont(tree.getFont());
label.setForeground(tree.getForeground());
if (isSelected) {
//label.setBackground(UIManager.getColor("Tree.backgroundSelectionColor"));
//label.setForeground(UIManager.getColor("Tree.textSelectionColor"));
label.setBackground(MetalLookAndFeel.getPrimaryControl());
} else {
//label.setBackground(UIManager.getColor("Tree.backgroundNonSelectionColor"));
//label.setForeground(UIManager.getColor("Tree.textNonSelectionColor"));
label.setBackground(tree.getBackground());
}
ObjectNode node = (ObjectNode) value;
label.setText(node.getTitle());
label.setIcon(node.getIcon());
return label;
}
}
}