You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@river.apache.org by gt...@apache.org on 2014/01/13 04:35:26 UTC
[19/40] Ongoing work to add client profile and run browser inside it.
http://git-wip-us.apache.org/repos/asf/river-container/blob/7ff8b15a/browser/src/main/java/org/apache/river/container/examples/browser/MetalIcons.java
----------------------------------------------------------------------
diff --git a/browser/src/main/java/org/apache/river/container/examples/browser/MetalIcons.java b/browser/src/main/java/org/apache/river/container/examples/browser/MetalIcons.java
new file mode 100644
index 0000000..30987bb
--- /dev/null
+++ b/browser/src/main/java/org/apache/river/container/examples/browser/MetalIcons.java
@@ -0,0 +1,348 @@
+/*
+ * 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.apache.river.container.examples.browser;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import javax.swing.plaf.metal.MetalLookAndFeel;
+import java.io.Serializable;
+import javax.swing.Icon;
+
+/**
+ * Based on "MetalIconFactory.java"
+ *
+ * @author Sun Microsystems, Inc.
+ *
+ */
+class MetalIcons implements Serializable {
+
+ private static Icon blueFolderIcon;
+ private static Icon blueFileIcon;
+ private static Icon orangeFolderIcon;
+ private static Icon orangeFileIcon;
+ private static Icon grayFolderIcon;
+ private static Icon grayFileIcon;
+ private static Icon unusableFolderIcon;
+ private static Icon unusableFileIcon;
+
+ // Colors for Orange icons
+ private static Color orangeDarkShadowColor = new Color(0xcc, 0x99, 0x66);
+ private static Color orangeColor = new Color(0xff, 0x99, 0x33);
+ private static Color orangeShadowColor = new Color(0xcc, 0x99, 0x66);
+ private static Color orangeInfoColor = new Color(0x99, 0x00, 0x33);
+ private static Color orangeHighlightColor = new Color(0xff, 0xff, 0x33);
+
+ // Colors for Gray icons
+ private static Color grayDarkShadowColor = new Color(0x99, 0x99, 0x99);
+ private static Color grayColor = new Color(0xbb, 0xbb, 0xbb);
+ private static Color grayShadowColor = new Color(0xaa, 0xaa, 0xaa);
+ private static Color grayInfoColor = new Color(0x88, 0x88, 0x88);
+ private static Color grayHighlightColor = new Color(0xdd, 0xdd, 0xdd);
+
+ // Constants
+ public static final boolean DARK = false;
+ public static final boolean LIGHT = true;
+
+ // Accessor functions for Icons. Does the caching work.
+ public static Icon getBlueFolderIcon() {
+ if(blueFolderIcon == null)
+ blueFolderIcon = new BlueFolderIcon();
+ return blueFolderIcon;
+ }
+
+ public static Icon getBlueFileIcon() {
+ if(blueFileIcon == null)
+ blueFileIcon = new BlueFileIcon();
+ return blueFileIcon;
+ }
+
+ public static Icon getOrangeFolderIcon() {
+ if(orangeFolderIcon == null)
+ orangeFolderIcon = new OrangeFolderIcon();
+ return orangeFolderIcon;
+ }
+
+ public static Icon getOrangeFileIcon() {
+ if(orangeFileIcon == null)
+ orangeFileIcon = new OrangeFileIcon();
+ return orangeFileIcon;
+ }
+
+ public static Icon getGrayFolderIcon() {
+ if(grayFolderIcon == null)
+ grayFolderIcon = new GrayFolderIcon();
+ return grayFolderIcon;
+ }
+
+ public static Icon getGrayFileIcon() {
+ if(grayFileIcon == null)
+ grayFileIcon = new GrayFileIcon();
+ return grayFileIcon;
+ }
+
+ public static Icon getUnusableFolderIcon() {
+ if(unusableFolderIcon == null)
+ unusableFolderIcon = new UnusableFolderIcon();
+ return unusableFolderIcon;
+ }
+
+ public static Icon getUnusableFileIcon() {
+ if(unusableFileIcon == null)
+ unusableFileIcon = new UnusableFileIcon();
+ return unusableFileIcon;
+ }
+
+
+ static private final Dimension folderIcon16Size = new Dimension( 16, 16 );
+ static private final Dimension fileIcon16Size = new Dimension( 16, 16 );
+
+ /**
+ */
+ static class BlueFolderIcon extends FolderIcon16 implements Icon {
+ public void paintIcon(Component c, Graphics g, int x, int y) {
+ super.paintIcon(c, g, x, y,
+ MetalLookAndFeel.getPrimaryControlDarkShadow(),
+ MetalLookAndFeel.getPrimaryControl(),
+ MetalLookAndFeel.getPrimaryControlShadow(),
+ MetalLookAndFeel.getPrimaryControlInfo(),
+ MetalLookAndFeel.getPrimaryControlHighlight());
+ }
+ public int getShift() { return -1; }
+ public int getAdditionalHeight() { return 2; }
+ }
+
+ static class OrangeFolderIcon extends FolderIcon16 implements Icon {
+ public void paintIcon(Component c, Graphics g, int x, int y) {
+ super.paintIcon(c, g, x, y,
+ orangeDarkShadowColor,
+ orangeColor,
+ orangeShadowColor,
+ orangeInfoColor,
+ orangeHighlightColor);
+ }
+ public int getShift() { return -1; }
+ public int getAdditionalHeight() { return 2; }
+ }
+
+ static class GrayFolderIcon extends FolderIcon16 implements Icon {
+ public void paintIcon(Component c, Graphics g, int x, int y) {
+ super.paintIcon(c, g, x, y,
+ grayDarkShadowColor,
+ grayColor,
+ grayShadowColor,
+ grayInfoColor,
+ grayHighlightColor);
+ }
+ public int getShift() { return -1; }
+ public int getAdditionalHeight() { return 2; }
+ }
+
+ static class UnusableFolderIcon extends FolderIcon16 implements Icon {
+ public void paintIcon(Component c, Graphics g, int x, int y) {
+ super.paintIcon(c, g, x, y,
+ grayDarkShadowColor,
+ grayColor,
+ grayShadowColor,
+ grayInfoColor,
+ grayHighlightColor);
+ super.drawCross(c, g, x, y);
+ }
+ public int getShift() { return -1; }
+ public int getAdditionalHeight() { return 2; }
+ }
+
+ /**
+ */
+ private static abstract class FolderIcon16 implements Serializable {
+
+ public void paintIcon(Component c, Graphics g, int x, int y,
+ Color controlDarkShadowColor,
+ Color controlColor,
+ Color controlShadowColor,
+ Color controlInfoColor,
+ Color controlHighlightColor) {
+ g.translate( x, y + getShift() );
+
+ int right = folderIcon16Size.width - 1;
+ int bottom = folderIcon16Size.height - 1;
+
+ // Draw tab top
+ g.setColor( controlDarkShadowColor );
+ g.drawLine( right - 5, 3, right, 3 );
+ g.drawLine( right - 6, 4, right, 4 );
+
+ // Draw folder front
+ g.setColor( controlColor );
+ g.fillRect( 2, 7, 13, 8 );
+
+ // Draw tab bottom
+ g.setColor( controlShadowColor );
+ g.drawLine( right - 6, 5, right - 1, 5 );
+
+ // Draw outline
+ g.setColor( controlInfoColor );
+ g.drawLine( 0, 6, 0, bottom ); // left side
+ g.drawLine( 1, 5, right - 7, 5 ); // first part of top
+ g.drawLine( right - 6, 6, right - 1, 6 ); // second part of top
+ g.drawLine( right, 5, right, bottom ); // right side
+ g.drawLine( 0, bottom, right, bottom ); // bottom
+
+ // Draw highlight
+ g.setColor( controlHighlightColor );
+ g.drawLine( 1, 6, 1, bottom - 1 );
+ g.drawLine( 1, 6, right - 7, 6 );
+ g.drawLine( right - 6, 7, right - 1, 7 );
+
+ g.translate( -x, -(y + getShift()) );
+ }
+
+ public void drawCross(Component c, Graphics g, int x, int y) {
+ g.translate( x, y + getShift() );
+
+ int right = folderIcon16Size.width - 1;
+ int bottom = folderIcon16Size.height - 1;
+
+ // Draw tab top
+ Color crossColor = Color.red;
+ g.setColor( crossColor );
+ g.drawLine( 2, 2, right, bottom );
+ g.drawLine( 2, bottom, right, 2 );
+ }
+
+ public int getShift() { return 0; }
+ public int getAdditionalHeight() { return 0; }
+
+ public int getIconWidth() { return folderIcon16Size.width; }
+ public int getIconHeight() { return folderIcon16Size.height + getAdditionalHeight(); }
+ }
+
+
+
+
+ static class BlueFileIcon extends FileIcon16 implements Icon {
+ public void paintIcon(Component c, Graphics g, int x, int y) {
+ super.paintIcon(c, g, x, y,
+ MetalLookAndFeel.getPrimaryControlHighlight(),
+ MetalLookAndFeel.getPrimaryControlInfo(),
+ MetalLookAndFeel.getPrimaryControl());
+ }
+ public int getShift() { return -1; }
+ public int getAdditionalHeight() { return 2; }
+ }
+
+ static class OrangeFileIcon extends FileIcon16 implements Icon {
+ public void paintIcon(Component c, Graphics g, int x, int y) {
+ super.paintIcon(c, g, x, y,
+ orangeHighlightColor,
+ orangeInfoColor,
+ orangeColor);
+ }
+ public int getShift() { return -1; }
+ public int getAdditionalHeight() { return 2; }
+ }
+
+ static class GrayFileIcon extends FileIcon16 implements Icon {
+ public void paintIcon(Component c, Graphics g, int x, int y) {
+ super.paintIcon(c, g, x, y,
+ grayHighlightColor,
+ grayInfoColor,
+ grayColor);
+ }
+ public int getShift() { return -1; }
+ public int getAdditionalHeight() { return 2; }
+ }
+
+ static class UnusableFileIcon extends FileIcon16 implements Icon {
+ public void paintIcon(Component c, Graphics g, int x, int y) {
+ super.paintIcon(c, g, x, y,
+ grayHighlightColor,
+ grayInfoColor,
+ grayColor);
+ super.drawCross(c, g, x, y);
+ }
+ public int getShift() { return -1; }
+ public int getAdditionalHeight() { return 2; }
+ }
+
+ /**
+ */
+ private static abstract class FileIcon16 implements Serializable {
+ public void paintIcon(Component c, Graphics g, int x, int y,
+ Color controlHighlightColor,
+ Color controlInfoColor,
+ Color controlColor) {
+ g.translate( x, y + getShift() );
+
+ int right = fileIcon16Size.width - 1;
+ int bottom = fileIcon16Size.height - 1;
+
+ // Draw fill
+ g.setColor( controlHighlightColor );
+ g.fillRect( 4, 2, 9, 12 );
+
+ // Draw frame
+ g.setColor( controlInfoColor );
+ g.drawLine( 2, 0, 2, bottom ); // left
+ g.drawLine( 2, 0, right - 4, 0 ); // top
+ g.drawLine( 2, bottom, right - 1, bottom ); // bottom
+ g.drawLine( right - 1, 6, right - 1, bottom ); // right
+ g.drawLine( right - 6, 2, right - 2, 6 ); // slant 1
+ g.drawLine( right - 5, 1, right - 4, 1 ); // part of slant 2
+ g.drawLine( right - 3, 2, right - 3, 3 ); // part of slant 2
+ g.drawLine( right - 2, 4, right - 2, 5 ); // part of slant 2
+
+ // Draw highlight
+ g.setColor( controlColor );
+ g.drawLine( 3, 1, 3, bottom - 1 ); // left
+ g.drawLine( 3, 1, right - 6, 1 ); // top
+ g.drawLine( right - 2, 7, right - 2, bottom - 1 ); // right
+ g.drawLine( right - 5, 2, right - 3, 4 ); // slant
+ g.drawLine( 3, bottom - 1, right - 2, bottom - 1 ); // bottom
+
+ g.translate( -x, -(y + getShift()) );
+ }
+
+ public void drawCross(Component c, Graphics g, int x, int y) {
+ g.translate( x, y + getShift() );
+
+ int right = folderIcon16Size.width - 1;
+ int bottom = folderIcon16Size.height - 1;
+
+ // Draw tab top
+ Color crossColor = Color.red;
+ g.setColor( crossColor );
+ g.drawLine( 1, 1, right - 1, bottom - 1 );
+ g.drawLine( 1, bottom - 1, right - 1, 1 );
+ }
+
+ public int getShift() { return 0; }
+ public int getAdditionalHeight() { return 0; }
+
+ public int getIconWidth() { return fileIcon16Size.width; }
+ public int getIconHeight() { return fileIcon16Size.height + getAdditionalHeight(); }
+ }
+
+
+ static class TreeLeafIcon extends FileIcon16 {
+ public int getShift() { return 2; }
+ public int getAdditionalHeight() { return 4; }
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/river-container/blob/7ff8b15a/browser/src/main/java/org/apache/river/container/examples/browser/ObjectNode.java
----------------------------------------------------------------------
diff --git a/browser/src/main/java/org/apache/river/container/examples/browser/ObjectNode.java b/browser/src/main/java/org/apache/river/container/examples/browser/ObjectNode.java
new file mode 100644
index 0000000..6409ba1
--- /dev/null
+++ b/browser/src/main/java/org/apache/river/container/examples/browser/ObjectNode.java
@@ -0,0 +1,316 @@
+/*
+ * 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.apache.river.container.examples.browser;
+
+import java.lang.reflect.Field;
+import javax.swing.tree.TreeModel;
+import javax.swing.tree.TreePath;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.Icon;
+
+/**
+ *
+ * @author Sun Microsystems, Inc.
+ *
+ * @version 0.2 06/04/98
+ *
+ */
+class ObjectNode extends DefaultMutableTreeNode implements java.io.Serializable {
+
+ // "classname", "classname fieldName" or "classname fieldName=value"
+ /**
+ * @serial
+ */
+ private String name;
+
+ /**
+ * @serial
+ */
+ private Object obj;
+
+ /**
+ * @serial
+ */
+ private Class clazz;
+
+ /**
+ * @serial
+ */
+ private String fieldName;
+
+ /**
+ * @serial
+ */
+ private int arrayIndex = -1;
+
+ /**
+ * @serial
+ */
+ private boolean editable = false;
+
+ /**
+ * @serial
+ */
+ private boolean isLeaf;
+
+ /**
+ * @serial
+ */
+ private boolean isAdministrable; // root level
+
+ /**
+ * @serial
+ */
+ private boolean isControllable; // entry level
+
+ /**
+ * @serial
+ */
+ private boolean isRoot = false;
+
+ /**
+ * @serial
+ */
+ private boolean isEntryTop = false;
+
+ // icons
+ private static Icon[] icons = new Icon[6];
+ static {
+ icons[0] = MetalIcons.getBlueFolderIcon(); // Administrable Service, Controllable Attribute
+ icons[1] = MetalIcons.getGrayFolderIcon(); // Non-administrable Service
+ icons[2] = MetalIcons.getOrangeFolderIcon(); // Uncontrollable Attribute
+ icons[3] = MetalIcons.getBlueFileIcon(); // Administrable Service, Controllable Attribute
+ icons[4] = MetalIcons.getGrayFileIcon(); // Non-administrable Service
+ icons[5] = MetalIcons.getOrangeFileIcon(); // Uncontrollable Attribute
+ }
+
+ /**
+ Constructor for a root node.
+ */
+ public ObjectNode(boolean isAdministrable) {
+ this("Root node", "".getClass(), null, -1, false);
+
+ this.isAdministrable = isAdministrable;
+ this.isRoot = true;
+ this.isEntryTop = true;
+ }
+
+ /**
+ Constructor for an entry (attribute) top nodes.
+ */
+ public ObjectNode(Object obj, boolean isControllable) {
+ this(obj, obj.getClass(), null, -1, false);
+
+ this.isControllable = isControllable;
+ this.isEntryTop = true;
+ }
+
+ /**
+ Constructor for an ordinary field.
+ */
+ public ObjectNode(Object obj, Class clazz, String fieldName, boolean isLeaf) {
+ this(obj, clazz, fieldName, -1, isLeaf);
+ }
+
+ /**
+ Constructor for an array element.
+ */
+ public ObjectNode(Object obj, Class clazz, String fieldName, int arrayIndex, boolean isLeaf) {
+ this.obj = obj;
+ this.clazz = clazz;
+ this.fieldName = fieldName;
+ this.arrayIndex = arrayIndex;
+ this.isLeaf = isLeaf;
+
+ super.setAllowsChildren(! isLeaf);
+ setNodeName();
+ }
+
+ private void setNodeName() {
+ name = Introspector.getTypename(clazz, false);
+ if(fieldName != null)
+ name += " " + fieldName;
+
+ if(isLeaf) {
+ //Class clazz = obj.getClass();
+ String value = "";
+ if(arrayIndex >= 0)
+ value += ("[" + arrayIndex + "]");
+ value += "=";
+ if(clazz.isPrimitive()){
+ value += "" + obj;
+ editable = false;
+ } else if(Introspector.isWrapper(clazz)){
+ // Wrapper objects
+ value += "" + obj;
+ editable = true;
+ } else if(Introspector.isString(clazz)) {
+ value += "\"" + obj + "\"";
+ editable = true;
+ } else {
+ value += (obj == null ? "null" : obj.toString());
+ }
+ name += value;
+ } else if(obj == null) {
+ name += "=null";
+ }
+
+ super.setUserObject(name);
+ }
+
+ public void add(ObjectNode child){
+ child.setAdministrable(isAdministrable);
+ if(! isRoot){
+ child.setControllable(isControllable);
+ }
+
+ super.add(child);
+ }
+
+ public Object getEntryTop() {
+ ObjectNode snode = this;
+ do {
+ snode = (ObjectNode) snode.getParent();
+ } while(! snode.isEntryTop());
+
+ return snode.getObject();
+ }
+
+ protected boolean isEntryTop() {
+ return isEntryTop;
+ }
+
+ public void setObjectRecursive() throws NoSuchFieldException, IllegalAccessException {
+ ObjectNode pnode = this;
+ do {
+ pnode = (ObjectNode) pnode.getParent();
+ Object pobj = pnode.getObject();
+ // Needs to think about array modifications
+ Field f = pobj.getClass().getField(fieldName);
+ f.set(pobj, obj);
+ } while(! pnode.isEntryTop());
+ }
+
+ public String getTitle() {
+ return name;
+ }
+
+ public Icon getIcon() {
+ /*
+ if(isAdministrable){
+ if(isControllable){
+ if(isLeaf) return icons[3];
+ else return icons[0];
+ } else {
+ if(isLeaf) return icons[5];
+ else return icons[2];
+ }
+ } else {
+ if(isLeaf) return icons[4];
+ else return icons[1];
+ }
+ */
+ if(isAdministrable && isControllable)
+ if(isLeaf) return icons[3];
+ else return icons[0];
+ else
+ if(isLeaf) return icons[4];
+ else return icons[1];
+ }
+
+
+ // Overwrite
+ public void setUserObject(Object obj){
+ if(obj instanceof String)
+ name = (String) obj;
+
+ super.setUserObject(obj);
+ }
+
+ public Object getUserObject(){
+ return name;
+ }
+
+ public String toString() {
+ return name;
+ }
+
+ public String getFieldName() {
+ return fieldName;
+ }
+
+ public Object getObject() {
+ return obj;
+ }
+
+ public boolean isEditable() {
+ return editable;
+ }
+
+ public boolean isAdministrable() {
+ return isAdministrable;
+ }
+
+ public void setAdministrable(boolean val) {
+ isAdministrable = val;
+ }
+
+ public boolean isControllable() {
+ return isControllable;
+ }
+
+ public void setControllable(boolean val) {
+ isControllable = val;
+ }
+
+ public Object setValue(Object val) throws NumberFormatException {
+ String clazzName = clazz.getName();
+ Object newObj = null;
+
+ if(val instanceof String || val == null) {
+ String sval = (String) val;
+ if(clazzName.equals("java.lang.Integer"))
+ newObj = new Integer(sval);
+ else if(clazzName.equals("java.lang.Boolean"))
+ newObj = new Boolean(sval);
+ else if(clazzName.equals("java.lang.Byte"))
+ newObj = new Byte(sval);
+ else if(clazzName.equals("java.lang.Character"))
+ newObj = new Character(sval.charAt(0));
+ else if(clazzName.equals("java.lang.Double"))
+ newObj = new Double(sval);
+ else if(clazzName.equals("java.lang.Float"))
+ newObj = new Float(sval);
+ else if(clazzName.equals("java.lang.Long"))
+ newObj = new Long(sval);
+ else if(clazzName.equals("java.lang.String"))
+ newObj = new String(sval); // clone
+ } else if(val.getClass().equals(obj.getClass())) {
+ // same class type
+ newObj = val;
+ }
+
+ Object oldObj = obj;
+ obj = newObj;
+
+ setNodeName();
+
+ return oldObj;
+ }
+}
http://git-wip-us.apache.org/repos/asf/river-container/blob/7ff8b15a/browser/src/main/java/org/apache/river/container/examples/browser/ServiceBrowser.java
----------------------------------------------------------------------
diff --git a/browser/src/main/java/org/apache/river/container/examples/browser/ServiceBrowser.java b/browser/src/main/java/org/apache/river/container/examples/browser/ServiceBrowser.java
new file mode 100644
index 0000000..6af743b
--- /dev/null
+++ b/browser/src/main/java/org/apache/river/container/examples/browser/ServiceBrowser.java
@@ -0,0 +1,282 @@
+/*
+ * 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.apache.river.container.examples.browser;
+
+import net.jini.core.lookup.ServiceItem;
+import net.jini.core.lookup.ServiceRegistrar;
+import net.jini.core.lookup.ServiceMatches;
+import net.jini.core.lookup.ServiceTemplate;
+import net.jini.core.entry.Entry;
+import net.jini.lookup.ui.factory.JFrameFactory;
+import net.jini.lookup.entry.UIDescriptor;
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.Rectangle;
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.util.logging.Level;
+import javax.swing.JFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JPopupMenu;
+import javax.swing.event.PopupMenuListener;
+import javax.swing.event.PopupMenuEvent;
+
+/**
+ * A browser utility to browse entries in a specified space.
+ *
+ * @author Sun Microsystems, Inc.
+ *
+ * @version 0.2 06/04/98
+ *
+ */
+class ServiceBrowser extends JFrame {
+ private Browser browser;
+ private AttributePanel attrPanel;
+ private final static int MINIMUM_WINDOW_WIDTH = 320;
+
+ public ServiceBrowser(ServiceItem item,
+ ServiceRegistrar registrar,
+ Browser browser)
+ {
+ super("ServiceItem Browser");
+
+ this.browser = browser;
+ // init main components
+ attrPanel = new AttributePanel(item, registrar);
+
+ // add menu and attr panel
+ getContentPane().setLayout(new BorderLayout());
+ getContentPane().add(new BrowserMenuBar(), "North");
+ getContentPane().add(attrPanel, "Center");
+
+ validate();
+ pack();
+ setSize(((getSize().width < MINIMUM_WINDOW_WIDTH) ? MINIMUM_WINDOW_WIDTH : getSize().width),
+ getSize().height);
+
+ // center in parent frame
+ Rectangle bounds = browser.getBounds();
+ Dimension dialogSize = getPreferredSize();
+ int xpos = bounds.x + (bounds.width - dialogSize.width)/ 2;
+ int ypos = bounds.y + (bounds.height - dialogSize.height)/2;
+ setLocation((xpos < 0) ? 0 : xpos,
+ (ypos < 0) ? 0 : ypos);
+ }
+
+
+ class BrowserMenuBar extends JMenuBar {
+ public BrowserMenuBar() {
+ JMenuItem mitem;
+
+ // "File" Menu
+ JMenu fileMenu = (JMenu) add(new JMenu("File"));
+ mitem = (JMenuItem) fileMenu.add(new JMenuItem("Refresh"));
+ mitem.addActionListener(browser.wrap(new ActionListener() {
+ public void actionPerformed(ActionEvent ev) {
+ attrPanel.refreshPanel();
+ }
+ }));
+ mitem = (JMenuItem) fileMenu.add(new JMenuItem("Close"));
+ mitem.addActionListener(browser.wrap(new ActionListener() {
+ public void actionPerformed(ActionEvent ev) {
+ ServiceBrowser.this.setVisible(false);
+ }
+ }));
+ }
+ }
+
+ class AttributePanel extends EntryTreePanel {
+ private ServiceItem item;
+ private ServiceRegistrar registrar;
+
+ public AttributePanel(ServiceItem item, ServiceRegistrar registrar) {
+ super(false); // Entries are not editable.
+
+ this.item = item;
+ this.registrar = registrar;
+
+ tree.addMouseListener(browser.wrap(new ServiceBrowser.MouseReceiver(item,
+ uiDescriptorPopup())));
+
+ refreshPanel();
+ }
+
+ protected Entry[] getEntryArray() {
+ try{
+ ServiceMatches matches = registrar.lookup(new ServiceTemplate(item.serviceID,
+ new Class[] { item.service.getClass() },
+ new Entry[] {}),
+ 10);
+ if(matches.totalMatches != 1)
+ Browser.logger.log(Level.INFO, "unexpected lookup matches: {0}",
+ new Integer(matches.totalMatches));
+ else
+ return matches.items[0].attributeSets;
+ } catch (Throwable t) {
+ Browser.logger.log(Level.INFO, "lookup failed", t);
+ }
+ return null;
+ }
+ }
+
+ // provides support for ServiceUI
+ public class UIDescriptorPopup extends JPopupMenu implements ActionListener,
+ PopupMenuListener {
+
+ protected transient JMenuItem showUIItem;
+ protected transient ServiceItem serviceItem;
+
+ public UIDescriptorPopup() {
+ super();
+
+ showUIItem = new JMenuItem("Show UI");
+
+ showUIItem.addActionListener(this);
+ showUIItem.setActionCommand("showUI");
+ add(showUIItem);
+
+ addPopupMenuListener(this);
+ setOpaque(true);
+ setLightWeightPopupEnabled(true);
+ }
+
+ public void actionPerformed(ActionEvent anEvent) {
+
+ UIDescriptor uiDescriptor = getSelectedUIDescriptor();
+
+ if (uiDescriptor == null) {
+ return;
+ }
+
+ try {
+ JFrameFactory uiFactory = (JFrameFactory)
+ uiDescriptor.getUIFactory(Thread.currentThread().getContextClassLoader());
+ JFrame frame = uiFactory.getJFrame(serviceItem);
+
+ frame.validate();
+ frame.setVisible(true);
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+
+ return;
+ }
+ }
+
+ public void popupMenuWillBecomeVisible(PopupMenuEvent ev) {
+ }
+
+ public void popupMenuWillBecomeInvisible(PopupMenuEvent ev) {
+ }
+
+ public void popupMenuCanceled(PopupMenuEvent ev) {
+ }
+
+ public void setServiceItem(ServiceItem anItem) {
+ serviceItem = anItem;
+ }
+ }
+
+ class MouseReceiver extends MouseAdapter {
+
+ private ServiceBrowser.UIDescriptorPopup popup;
+ private ServiceItem serviceItem;
+
+ public MouseReceiver(ServiceItem aServiceItem,
+ ServiceBrowser.UIDescriptorPopup popup) {
+ this.popup = popup;
+ serviceItem = aServiceItem;
+ }
+
+ public void mouseReleased(MouseEvent ev) {
+
+ higlightSelection(ev);
+
+ if (!ev.isPopupTrigger()) {
+ return;
+ }
+
+ UIDescriptor selectedDescriptor = getSelectedUIDescriptor();
+
+ if (selectedDescriptor == null) {
+ return;
+ }
+
+ if (!"javax.swing".equals(selectedDescriptor.toolkit)) {
+ return;
+ }
+
+ popup.setServiceItem(serviceItem);
+ popup.show(ev.getComponent(), ev.getX(), ev.getY());
+ }
+
+ public void mousePressed(MouseEvent ev) {
+
+ higlightSelection(ev);
+
+ if (!ev.isPopupTrigger()) {
+ return;
+ }
+
+ UIDescriptor selectedDescriptor = getSelectedUIDescriptor();
+
+ if (selectedDescriptor == null) {
+ return;
+ }
+
+ if (!"javax.swing".equals(selectedDescriptor.toolkit)) {
+ return;
+ }
+
+ popup.setServiceItem(serviceItem);
+ popup.show(ev.getComponent(), ev.getX(), ev.getY());
+ }
+ }
+
+ private UIDescriptor getSelectedUIDescriptor() {
+
+ ObjectNode selectedNode =
+ (ObjectNode) attrPanel.tree.getLastSelectedPathComponent();
+
+ if (selectedNode == null) {
+ return null;
+ }
+
+ Object selectedObject = selectedNode.getObject();
+
+ try {
+ return (UIDescriptor) selectedObject;
+ }
+ catch (ClassCastException e) {
+ return null;
+ }
+ }
+
+ private void higlightSelection(MouseEvent anEvent) {
+ attrPanel.tree.setSelectionPath(attrPanel.tree.getPathForLocation(
+ anEvent.getX(), anEvent.getY()));
+ }
+
+ private ServiceBrowser.UIDescriptorPopup uiDescriptorPopup() {
+ return new ServiceBrowser.UIDescriptorPopup();
+ }
+}
http://git-wip-us.apache.org/repos/asf/river-container/blob/7ff8b15a/browser/src/main/java/org/apache/river/container/examples/browser/ServiceEditor.java
----------------------------------------------------------------------
diff --git a/browser/src/main/java/org/apache/river/container/examples/browser/ServiceEditor.java b/browser/src/main/java/org/apache/river/container/examples/browser/ServiceEditor.java
new file mode 100644
index 0000000..ee972da
--- /dev/null
+++ b/browser/src/main/java/org/apache/river/container/examples/browser/ServiceEditor.java
@@ -0,0 +1,1213 @@
+/*
+ * 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.apache.river.container.examples.browser;
+
+import com.sun.jini.admin.DestroyAdmin;
+import com.sun.jini.config.Config;
+import com.sun.jini.logging.Levels;
+import com.sun.jini.proxy.BasicProxyTrustVerifier;
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.net.MalformedURLException;
+import java.rmi.server.ExportException;
+import java.util.StringTokenizer;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.DefaultListModel;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JList;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.JScrollPane;
+import javax.swing.JTree;
+import javax.swing.SwingUtilities;
+import javax.swing.event.PopupMenuEvent;
+import javax.swing.event.PopupMenuListener;
+import javax.swing.tree.TreePath;
+import net.jini.admin.JoinAdmin;
+import net.jini.config.ConfigurationException;
+import net.jini.core.discovery.LookupLocator;
+import net.jini.core.entry.Entry;
+import net.jini.core.event.EventRegistration;
+import net.jini.core.event.RemoteEvent;
+import net.jini.core.event.RemoteEventListener;
+import net.jini.core.lease.Lease;
+import net.jini.core.lookup.ServiceEvent;
+import net.jini.core.lookup.ServiceItem;
+import net.jini.core.lookup.ServiceMatches;
+import net.jini.core.lookup.ServiceRegistrar;
+import net.jini.core.lookup.ServiceTemplate;
+import net.jini.export.Exporter;
+import net.jini.jeri.BasicILFactory;
+import net.jini.jeri.BasicJeriExporter;
+import net.jini.jeri.tcp.TcpServerEndpoint;
+import net.jini.lookup.DiscoveryAdmin;
+import net.jini.lookup.entry.UIDescriptor;
+import net.jini.lookup.ui.factory.JFrameFactory;
+import net.jini.security.TrustVerifier;
+import net.jini.security.proxytrust.ServerProxyTrust;
+
+/**
+ * ServiceEditor is a gui-based utility to add/modify
+ * attributes, groups and lookup locators.
+ * And also supports some well known admin interfaces.
+ * (DestroyAdmin, DiscoveryAdmin)
+ *
+ * <p>
+ * current issues<br>
+ * <ul>
+ * <li> can't operate(add/remove/modify) array elements in an entry.
+ * <li> does not support EntryBean.
+ * <li> field modification is not based on EditableTree
+ * </ul>
+ *
+ * @author Sun Microsystems, Inc.
+ */
+class ServiceEditor extends JFrame {
+ private static final Logger logger = Browser.logger;
+
+ private Browser browser;
+ private ServiceItem item;
+ private ServiceRegistrar registrar;
+ protected Object admin;
+ private ServiceTemplate stmpl;
+ private NotifyReceiver receiver;
+ private Lease elease = null;
+ private long eventID = 0;
+ private long seqNo = Long.MAX_VALUE;
+ private AttributeTreePanel attrPanel;
+
+ private final static int MINIMUM_WINDOW_WIDTH = 320;
+
+ public ServiceEditor(ServiceItem item,
+ Object admin,
+ ServiceRegistrar registrar,
+ Browser browser)
+ {
+ super("ServiceItem Editor");
+
+ this.item = item;
+ this.admin = admin;
+ this.registrar = registrar;
+ this.browser = browser;
+
+ // init main components
+ attrPanel = new AttributeTreePanel();
+
+ // setup notify
+ try {
+ stmpl = new ServiceTemplate(item.serviceID,
+ new Class[] { item.service.getClass() },
+ new Entry[] {});
+ receiver = new NotifyReceiver();
+
+ setupNotify();
+ } catch (Throwable t) {
+ logger.log(Level.INFO, "event registration failed", t);
+ cancelNotify();
+ }
+
+ addWindowListener(browser.wrap(new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ cleanup();
+ }
+ }));
+ // add menu and attr panel
+ getContentPane().setLayout(new BorderLayout());
+ getContentPane().add(new JoinMenuBar(), "North");
+ getContentPane().add(attrPanel, "Center");
+
+ validate();
+ pack();
+ setSize(((getSize().width < MINIMUM_WINDOW_WIDTH) ? MINIMUM_WINDOW_WIDTH : getSize().width),
+ getSize().height);
+
+ // center in parent frame
+ Rectangle bounds = browser.getBounds();
+ Dimension dialogSize = getPreferredSize();
+ int xpos = bounds.x + (bounds.width - dialogSize.width)/ 2;
+ int ypos = bounds.y + (bounds.height - dialogSize.height)/2;
+ setLocation((xpos < 0) ? 0 : xpos,
+ (ypos < 0) ? 0 : ypos);
+ }
+
+ void cleanup() {
+ // cancel lease
+ cancelNotify();
+ // release resources and close all child frames
+ dispose();
+ receiver.unexport();
+ }
+
+ protected void cancelNotify() {
+ if(elease != null) {
+ try {
+ browser.leaseMgr.cancel(elease);
+ } catch (Throwable t) {
+ logger.log(Levels.HANDLED, "event cancellation failed", t);
+ }
+ elease = null;
+ seqNo = Long.MAX_VALUE;
+ }
+ }
+
+ protected void setupNotify() {
+ if(registrar != null) {
+ try {
+ EventRegistration reg =
+ registrar.notify(stmpl,
+ ServiceRegistrar.TRANSITION_MATCH_NOMATCH |
+ ServiceRegistrar.TRANSITION_NOMATCH_MATCH |
+ ServiceRegistrar.TRANSITION_MATCH_MATCH,
+ receiver.proxy,
+ null,
+ Lease.ANY);
+ elease = (Lease) browser.leasePreparer.prepareProxy(reg.getLease());
+ browser.leaseMgr.renewUntil(elease, Lease.ANY,
+ new Browser.LeaseNotify());
+ eventID = reg.getID();
+ seqNo = reg.getSequenceNumber();
+ } catch (Throwable t) {
+ logger.log(Level.INFO, "event registration failed", t);
+ }
+ }
+ }
+
+ private class NotifyReceiver implements RemoteEventListener, ServerProxyTrust
+ {
+ private final Exporter exporter;
+ final RemoteEventListener proxy;
+
+ public NotifyReceiver() throws ConfigurationException, ExportException {
+ exporter = (Exporter)
+ Config.getNonNullEntry(browser.config, Browser.BROWSER,
+ "listenerExporter", Exporter.class,
+ new BasicJeriExporter(
+ TcpServerEndpoint.getInstance(0),
+ new BasicILFactory(),
+ false, false));
+ proxy = (RemoteEventListener) exporter.export(this);
+ }
+
+ public void notify(final RemoteEvent ev) {
+ SwingUtilities.invokeLater(browser.wrap(new Runnable() {
+ public void run() {
+ if (eventID == ev.getID() && seqNo < ev.getSequenceNumber()) {
+ seqNo = ev.getSequenceNumber();
+ attrPanel.receiveNotify(((ServiceEvent) ev).getTransition());
+ }
+ }
+ }));
+ }
+
+ public TrustVerifier getProxyVerifier() {
+ return new BasicProxyTrustVerifier(proxy);
+ }
+
+ void unexport() {
+ exporter.unexport(true);
+ }
+ }
+
+ class JoinMenuBar extends JMenuBar {
+ public JoinMenuBar() {
+ JMenuItem mitem;
+
+ // "File" Menu
+ JMenu fileMenu = (JMenu) add(new JMenu("File"));
+ mitem = (JMenuItem) fileMenu.add(new JMenuItem("Show Info"));
+ mitem.addActionListener(browser.wrap(new ActionListener() {
+ public void actionPerformed(ActionEvent ev) {
+ Class[] infs = Browser.getInterfaces(item.service.getClass());
+ String[] msg = new String[3 + infs.length];
+ msg[0] = "ServiceID: " + item.serviceID;
+ msg[1] = "Service Instance: " + item.service.getClass().getName();
+ if(infs.length == 1)
+ msg[2] = "Implemented Interface:";
+ else
+ msg[2] = "Implemented Interfaces:";
+ for(int i = 0; i < infs.length; i++)
+ msg[3 + i] = " " + infs[i].getName();
+
+ JOptionPane.showMessageDialog(ServiceEditor.this,
+ msg,
+ "ServiceItem Information",
+ JOptionPane.INFORMATION_MESSAGE);
+ }
+ }));
+ mitem = (JMenuItem) fileMenu.add(new JMenuItem("Refresh"));
+ mitem.addActionListener(browser.wrap(new ActionListener() {
+ public void actionPerformed(ActionEvent ev) {
+ attrPanel.refreshPanel();
+ }
+ }));
+ mitem = (JMenuItem) fileMenu.add(new JMenuItem("Close"));
+ mitem.addActionListener(browser.wrap(new ActionListener() {
+ public void actionPerformed(ActionEvent ev) {
+ cleanup();
+ }
+ }));
+
+ // "Edit" Menu
+ JMenu editMenu = (JMenu) add(new JMenu("Edit"));
+ mitem = (JMenuItem) editMenu.add(new JMenuItem("Add Attribute..."));
+ mitem.addActionListener(browser.wrap(new ActionListener() {
+ public void actionPerformed(ActionEvent ev) {
+ attrPanel.addAttr();
+ }
+ }));
+ if(! (admin instanceof JoinAdmin))
+ mitem.setEnabled(false);
+ mitem = (JMenuItem) editMenu.add(new JMenuItem("Remove Attribute"));
+ mitem.addActionListener(browser.wrap(new ActionListener() {
+ public void actionPerformed(ActionEvent ev) {
+ attrPanel.removeAttr();
+ }
+ }));
+ if(! (admin instanceof JoinAdmin))
+ mitem.setEnabled(false);
+
+ // "Admin" Menu
+ JMenu adminMenu = (JMenu) add(new JMenu("Admin"));
+
+ // Group (JoinAdmin)
+ mitem = (JMenuItem) adminMenu.add(new JMenuItem("Joining groups..."));
+ mitem.addActionListener(browser.wrap(new ActionListener() {
+ public void actionPerformed(ActionEvent ev) {
+ new GroupLister("Joining Groups").showFrame();
+ }
+ }));
+ if(! (admin instanceof JoinAdmin))
+ mitem.setEnabled(false);
+
+ // Locator (JoinAdmin)
+ mitem = (JMenuItem) adminMenu.add(new JMenuItem("Joining locators..."));
+ mitem.addActionListener(browser.wrap(new ActionListener() {
+ public void actionPerformed(ActionEvent ev) {
+ new LocatorLister("Joining Locators").showFrame();
+ }
+ }));
+ if(! (admin instanceof JoinAdmin))
+ mitem.setEnabled(false);
+
+ // separator
+ adminMenu.addSeparator();
+
+ // Group (DiscoveryAdmin)
+ mitem = (JMenuItem) adminMenu.add(new JMenuItem("Member groups..."));
+ mitem.addActionListener(browser.wrap(new ActionListener() {
+ public void actionPerformed(ActionEvent ev) {
+ new MemberGroupLister("Member Groups").showFrame();
+ }
+ }));
+ if(! (admin instanceof DiscoveryAdmin))
+ mitem.setEnabled(false);
+
+ // Unicast port (DiscoveryAdmin)
+ mitem = (JMenuItem) adminMenu.add(new JMenuItem("Unicast port..."));
+ mitem.addActionListener(browser.wrap(new ActionListener() {
+ public void actionPerformed(ActionEvent ev) {
+ try {
+ String[] msg = { "Current port is " + ((DiscoveryAdmin) admin).getUnicastPort(),
+ "Input a new value" };
+ String result = JOptionPane.showInputDialog(ServiceEditor.this,
+ msg,
+ "Unicast Port",
+ JOptionPane.QUESTION_MESSAGE);
+
+ if(result == null)
+ return;
+
+ try {
+ int port = Integer.parseInt(result);
+ ((DiscoveryAdmin) admin).setUnicastPort(port);
+ } catch (NumberFormatException e) {
+ JOptionPane.showMessageDialog(ServiceEditor.this,
+ result + " is not acceptable.",
+ "Error",
+ JOptionPane.ERROR_MESSAGE);
+ } catch (Throwable t) {
+ logger.log(Level.INFO, "setting unicast port failed", t);
+ JOptionPane.showMessageDialog(ServiceEditor.this,
+ t.getMessage(),
+ t.getClass().getName(),
+ JOptionPane.ERROR_MESSAGE);
+ }
+ } catch (Throwable t) {
+ logger.log(Level.INFO, "getting unicast port failed", t);
+ JOptionPane.showMessageDialog(ServiceEditor.this,
+ t.getMessage(),
+ t.getClass().getName(),
+ JOptionPane.ERROR_MESSAGE);
+ }
+ }
+ }));
+ if(! (admin instanceof DiscoveryAdmin))
+ mitem.setEnabled(false);
+
+ // separator
+ adminMenu.addSeparator();
+
+ // DestroyAdmin
+ mitem = (JMenuItem) adminMenu.add(new JMenuItem("Destroy"));
+ mitem.addActionListener(browser.wrap(new ActionListener() {
+ public void actionPerformed(ActionEvent ev) {
+ if(JOptionPane.showConfirmDialog(ServiceEditor.this,
+ "Are you sure to destroy this service?",
+ "Query",
+ JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION)
+ try {
+ ((DestroyAdmin) admin).destroy();
+ cleanup();
+ } catch (Throwable t) {
+ logger.log(Level.INFO, "service destroy failed", t);
+ JOptionPane.showMessageDialog(ServiceEditor.this,
+ t.getMessage(),
+ t.getClass().getName(),
+ JOptionPane.ERROR_MESSAGE);
+ }
+ }
+ }));
+ if(! (admin instanceof DestroyAdmin))
+ mitem.setEnabled(false);
+ }
+ }
+
+ class AttributeTreePanel extends EntryTreePanel {
+
+ public AttributeTreePanel() {
+ super(admin instanceof JoinAdmin);
+
+ if(admin instanceof JoinAdmin) {
+ tree.addMouseListener(browser.wrap(new DoubleClicker(this)));
+ }
+ tree.addMouseListener(browser.wrap(new MouseReceiver(item, uiDescriptorPopup())));
+
+ refreshPanel();
+ }
+
+ protected Entry[] getEntryArray() {
+ if(admin instanceof JoinAdmin) {
+ try {
+ item.attributeSets = ((JoinAdmin) admin).getLookupAttributes();
+ } catch (Throwable t) {
+ logger.log(Level.INFO, "obtaining attributes failed", t);
+ }
+ } else {
+ try{
+ ServiceMatches matches = registrar.lookup(stmpl, 1);
+ if(matches.totalMatches != 1)
+ Browser.logger.log(Level.INFO, "unexpected lookup matches: {0}",
+ new Integer(matches.totalMatches));
+ else
+ item.attributeSets = matches.items[0].attributeSets;
+ } catch (Throwable t) {
+ Browser.logger.log(Level.INFO, "lookup failed", t);
+ }
+ }
+ return item.attributeSets;
+ }
+
+ protected void receiveNotify(int transition) {
+
+ if (browser.isAutoConfirm()) {
+ if (transition == ServiceRegistrar.TRANSITION_MATCH_NOMATCH)
+ cleanup();
+ else
+ refreshPanel();
+
+ return;
+ }
+
+ String[] msg =
+ (transition == ServiceRegistrar.TRANSITION_MATCH_NOMATCH) ?
+ new String[]{
+ "Service has been removed from lookup service.",
+ "Do you want to close the service editor window ?"} :
+ new String[]{
+ "Attributes have been modified by another client or the service itself.",
+ "Do you want to refresh the attributes ?"};
+ int result = JOptionPane.showConfirmDialog(AttributeTreePanel.this,
+ msg,
+ "Query",
+ JOptionPane.YES_NO_OPTION);
+
+ if(result == JOptionPane.YES_OPTION) {
+ if (transition == ServiceRegistrar.TRANSITION_MATCH_NOMATCH)
+ cleanup();
+ else
+ refreshPanel();
+ }
+ }
+
+ public void editField(ObjectNode node) {
+
+ String result = JOptionPane.showInputDialog(this,
+ "Input a new value",
+ "Modify a field",
+ JOptionPane.QUESTION_MESSAGE);
+
+ if(result == null){
+ } else {
+ // Save current value as template
+ Entry template = cloneEntry((Entry) node.getEntryTop());
+ Object oldVal = null;
+
+ if(result.length() == 0){
+ oldVal = node.setValue(null);
+ } else {
+ oldVal = node.setValue(result);
+ }
+ // modifyAttribute
+ try {
+ node.setObjectRecursive();
+ Entry attr = (Entry) node.getEntryTop();
+ //Entry template = (Entry) generateTemplate(attr);
+
+ // cancel notify while adding an attribute
+ cancelNotify();
+
+ ((JoinAdmin) admin).modifyLookupAttributes(
+ new Entry[] { template }, new Entry[] { attr });
+
+ setupNotify();
+
+ // Redraw node value
+ model.nodeChanged(node);
+ } catch (Throwable t) {
+ logger.log(Level.INFO, "attribute modification failed", t);
+ // recover tree node
+ try {
+ node.setValue(oldVal);
+ node.setObjectRecursive();
+ } catch (Throwable tt) {
+ logger.log(Levels.HANDLED, "node reset failed", tt);
+ }
+ model.nodeChanged(node);
+ //model.nodeStructureChanged(node);
+
+ // show dialog
+ JOptionPane.showMessageDialog(AttributeTreePanel.this,
+ t.getMessage(),
+ t.getClass().getName(),
+ JOptionPane.ERROR_MESSAGE);
+ }
+ }
+ }
+
+ public void addAttr() {
+
+ String result = JOptionPane.showInputDialog(this,
+ "Input an entry class name",
+ "Add an attribute",
+ JOptionPane.QUESTION_MESSAGE);
+
+ if(result == null || result.length() == 0){
+ } else {
+ try {
+ Class clazz = Class.forName(result);
+ Object attr = clazz.newInstance();
+
+ if(! (attr instanceof Entry)){
+ JOptionPane.showMessageDialog(AttributeTreePanel.this,
+ "Does not implement Entry interface",
+ "Unacceptable Class",
+ JOptionPane.WARNING_MESSAGE);
+
+ } else if(attr instanceof net.jini.lookup.entry.ServiceControlled){
+ JOptionPane.showMessageDialog(AttributeTreePanel.this,
+ "Implements ServiceControlled interface",
+ "Unacceptable Class",
+ JOptionPane.WARNING_MESSAGE);
+ } else {
+ // cancel notify while adding an attribute
+ cancelNotify();
+
+ ((JoinAdmin) admin).addLookupAttributes(
+ new Entry[] { (Entry) attr });
+ // add node of this attribute
+ ObjectNode node = new ObjectNode(attr, true);
+ root.add(node);
+ recursiveObjectTree(node);
+
+ //
+ setupNotify();
+
+ // refresh view
+ model.nodesWereInserted(root,
+ new int[] { model.getIndexOfChild(root, node) });
+ }
+ } catch (ClassNotFoundException e) {
+ JOptionPane.showMessageDialog(AttributeTreePanel.this,
+ e.getMessage(),
+ "Class Not Found",
+ JOptionPane.WARNING_MESSAGE);
+ } catch (Throwable t) {
+ logger.log(Level.INFO, "adding attribute failed", t);
+ JOptionPane.showMessageDialog(AttributeTreePanel.this,
+ t.getMessage(),
+ t.getClass().getName(),
+ JOptionPane.WARNING_MESSAGE);
+ }
+ }
+ }
+
+ public void removeAttr() {
+
+ ObjectNode node = (ObjectNode) tree.getLastSelectedPathComponent();
+ if(node == null){
+ JOptionPane.showMessageDialog(AttributeTreePanel.this,
+ "Select an attribute folder to remove.",
+ "Warning",
+ JOptionPane.WARNING_MESSAGE);
+
+ return;
+ } else if(! node.isControllable()){
+ JOptionPane.showMessageDialog(AttributeTreePanel.this,
+ "This attribute is under service provider's control.",
+ "Warning",
+ JOptionPane.WARNING_MESSAGE);
+
+ return;
+ } else if(! node.isEntryTop()){
+ JOptionPane.showMessageDialog(AttributeTreePanel.this,
+ "Select a top of attribute folder.",
+ "Warning",
+ JOptionPane.WARNING_MESSAGE);
+
+ return;
+ }
+
+ Entry target = (Entry) node.getObject();
+ int result = JOptionPane.showConfirmDialog(AttributeTreePanel.this,
+ new String[] {"Remove attribute:",
+ target.toString() },
+ "Query",
+ JOptionPane.YES_NO_OPTION);
+
+ if(result == JOptionPane.YES_OPTION){
+ // Remote Attribute
+ try {
+
+ // cancel notify while adding an attribute
+ cancelNotify();
+
+ ((JoinAdmin) admin).modifyLookupAttributes(
+ new Entry[] { target }, new Entry[] { null });
+
+ //
+ setupNotify();
+
+ int index = root.getIndex(node);
+ root.remove(node);
+ model.nodesWereRemoved(root, new int[] {index}, new Object[] {node});
+ node = null;
+ } catch (Throwable t) {
+ logger.log(Level.INFO, "attribute removal failed", t);
+ JOptionPane.showMessageDialog(AttributeTreePanel.this,
+ t.getMessage(),
+ t.getClass().getName(),
+ JOptionPane.ERROR_MESSAGE);
+ }
+ }
+ }
+
+ private Entry cloneEntry(Entry attr) {
+ try {
+ Class realClass = attr.getClass();
+ Entry template = (Entry) realClass.newInstance();
+
+ Field[] f = realClass.getFields();
+ for(int i = 0; i < f.length; i++) {
+ if(! usableField(f[i]))
+ continue;
+ f[i].set(template, f[i].get(attr));
+ }
+
+ return template;
+ } catch (Throwable t) {
+ logger.log(Level.INFO, "duplicating entry failed", t);
+ }
+ return null;
+ }
+
+ // from EntryRep
+ private boolean usableField(Field field) {
+ Class desc = field.getDeclaringClass();
+
+ if(desc.isPrimitive()) {
+ throw new IllegalArgumentException("primitive types not allowed in an Entry");
+ }
+
+ // skip anything that isn't a public per-object mutable field
+ int mods = field.getModifiers();
+ return (0 == (mods & (Modifier.TRANSIENT | Modifier.STATIC | Modifier.FINAL)));
+ }
+
+ private Entry generateTemplate(Entry attr) {
+ try {
+ Class realClass = attr.getClass();
+ Entry template = (Entry) realClass.newInstance();
+
+ Field[] f = realClass.getFields();
+ for(int i = 0; i < f.length; i++)
+ f[i].set(template, null);
+
+ return template;
+ } catch (Throwable t) {
+ logger.log(Level.INFO, "instantiating template failed", t);
+ }
+ return null;
+ }
+
+ class DoubleClicker extends MouseAdapter {
+ AttributeTreePanel parent;
+
+ public DoubleClicker(AttributeTreePanel parent){
+ this.parent = parent;
+ }
+
+ public void mouseClicked(MouseEvent ev){
+ if(ev.getClickCount() >= 2){
+ JTree tree = (JTree) ev.getSource();
+ TreePath path = tree.getPathForLocation(ev.getX(), ev.getY());
+ if(path == null)
+ return;
+ ObjectNode node = (ObjectNode) path.getLastPathComponent();
+
+ if(node.isLeaf()){
+ if(! node.isControllable()){
+ JOptionPane.showMessageDialog(AttributeTreePanel.this,
+ "This attribute is under service provider's control.",
+ "Warning",
+ JOptionPane.WARNING_MESSAGE);
+ } else if(node.isEditable() &&
+ ((ObjectNode) node.getParent()).isEntryTop())
+ {
+ parent.editField(node);
+ } else {
+ JOptionPane.showMessageDialog(AttributeTreePanel.this,
+ "This field is not editable.",
+ "Warning",
+ JOptionPane.WARNING_MESSAGE);
+ }
+ }
+
+ tree.scrollPathToVisible(path);
+ }
+ }
+ }
+ }
+
+ abstract class ListerFrame extends JFrame {
+
+ private JList listBox;
+ private JScrollPane scrollPane;
+ protected DefaultListModel model = new DefaultListModel();
+ private DefaultListModel dummyModel = new DefaultListModel(); // to keep away from Swing's bug
+
+ private JButton addButton;
+ private JButton removeButton;
+ private JButton closeButton;
+
+ public ListerFrame(String title) {
+ super(title);
+
+ getContentPane().setLayout(new BorderLayout());
+
+ // create the initial list
+ listBox = new JList(model);
+ listBox.setFixedCellHeight(20);
+ scrollPane = new JScrollPane(listBox);
+ getContentPane().add(scrollPane, "Center");
+ //resetListModel();
+
+ // Create the controls
+ JPanel buttonPanel = new JPanel();
+ addButton = new JButton("Add");
+ addButton.addActionListener(browser.wrap(new ActionListener() {
+ public void actionPerformed(ActionEvent ev) {
+ String result = JOptionPane.showInputDialog(ListerFrame.this, getAddMessage());
+
+ if(result != null){
+ StringTokenizer st = new StringTokenizer(result);
+ String[] tokens = new String[st.countTokens()];
+ for(int i = 0; i < tokens.length; i++)
+ tokens[i] = st.nextToken().trim();
+
+ addItems(tokens);
+ resetListModel();
+ scrollPane.validate();
+ }
+ }
+ }));
+ buttonPanel.add(addButton);
+
+ removeButton = new JButton("Remove");
+ removeButton.addActionListener(browser.wrap(new ActionListener() {
+ public void actionPerformed(ActionEvent ev) {
+ Object[] selected = listBox.getSelectedValues();
+
+ if(selected == null || selected.length == 0){
+ // no items are selected
+ JOptionPane.showMessageDialog(ListerFrame.this,
+ "No items are selected",
+ "Warning",
+ JOptionPane.WARNING_MESSAGE);
+ return;
+ }
+
+ int result = JOptionPane.showConfirmDialog(ListerFrame.this,
+ getRemoveMessage(selected),
+ "Query",
+ JOptionPane.YES_NO_OPTION);
+
+ if(result == JOptionPane.YES_OPTION){
+ removeItems(selected);
+ resetListModel();
+ scrollPane.validate();
+ }
+ }
+ }));
+ buttonPanel.add(removeButton);
+
+ closeButton = new JButton("Close");
+ closeButton.addActionListener(browser.wrap(new ActionListener() {
+ public void actionPerformed(ActionEvent ev) {
+ setVisible(false);
+ }
+ }));
+ buttonPanel.add(closeButton);
+ getContentPane().add(buttonPanel, "South");
+
+ pack();
+ }
+
+ public void showFrame() {
+ // init list data
+ resetListModel();
+
+ // center in parent frame
+ Rectangle bounds = ServiceEditor.this.getBounds();
+ Dimension dialogSize = getPreferredSize();
+
+ setLocation(bounds.x + (bounds.width - dialogSize.width)/ 2,
+ bounds.y + (bounds.height - dialogSize.height)/2);
+
+ setVisible(true);
+ }
+
+ private void resetListModel() {
+ //listBox.setModel(null);
+ listBox.setModel(dummyModel); // to keep away from NullException (Swing's bug)
+
+ model.removeAllElements();
+ initListModel();
+
+ listBox.setModel(model);
+ listBox.clearSelection();
+ listBox.ensureIndexIsVisible(0);
+ listBox.repaint();
+ listBox.revalidate();
+ }
+
+ protected abstract void initListModel();
+
+ protected abstract String getAddMessage();
+
+ protected abstract String getRemoveMessage(Object[] items);
+
+ protected abstract void addItems(String[] items);
+
+ protected abstract void removeItems(Object[] items);
+ }
+
+ class GroupLister extends ListerFrame {
+
+ public GroupLister(String title) {
+ super(title);
+ }
+
+ protected void initListModel() {
+ if (!(admin instanceof JoinAdmin)) {
+ return;
+ }
+
+ try {
+ String[] groups = ((JoinAdmin) admin).getLookupGroups();
+ for(int i = 0; i < groups.length; i++) {
+ model.addElement(new GroupItem(groups[i]));
+ }
+ } catch (Throwable t) {
+ logger.log(Level.INFO, "obtaining groups failed", t);
+ }
+ }
+
+ protected String getAddMessage() {
+ return "Enter adding group(s)";
+ }
+
+ protected String getRemoveMessage(Object[] items) {
+ StringBuffer msg = new StringBuffer();
+ if(items.length > 1)
+ msg.append("Remove these groups : ");
+ else
+ msg.append("Remove a group : ");
+ for(int i = 0; i < items.length; i++) {
+ if(i != 0)
+ msg.append(", ");
+ msg.append(((GroupItem) items[i]).toString());
+ }
+ return msg.toString();
+ }
+
+ protected void addItems(String[] items) {
+ // check "public"
+ String[] grps = new String[items.length];
+ for(int i = 0; i < items.length; i++)
+ grps[i] = new GroupItem(items[i]).group;
+
+ try {
+ ((JoinAdmin) admin).addLookupGroups(grps);
+ } catch (Throwable t) {
+ logger.log(Level.INFO, "adding groups failed", t);
+ }
+ }
+
+ protected void removeItems(Object[] items) {
+ String[] grps = new String[items.length];
+ for(int i = 0; i < items.length; i++)
+ grps[i] = ((GroupItem) items[i]).group;
+
+ try {
+ ((JoinAdmin) admin).removeLookupGroups(grps);
+ } catch (Throwable t) {
+ logger.log(Level.INFO, "removing groups failed", t);
+ }
+ }
+ }
+
+ class MemberGroupLister extends ListerFrame {
+
+ public MemberGroupLister(String title) {
+ super(title);
+ }
+
+ protected void initListModel() {
+ try {
+ String[] groups = ((DiscoveryAdmin) admin).getMemberGroups();
+ for(int i = 0; i < groups.length; i++) {
+ model.addElement(new GroupItem(groups[i]));
+ }
+ } catch (Throwable t) {
+ logger.log(Level.INFO, "obtaining groups failed", t);
+ }
+ }
+
+ protected String getAddMessage() {
+ return "Enter adding group(s)";
+ }
+
+ protected String getRemoveMessage(Object[] items) {
+ StringBuffer msg = new StringBuffer();
+ if(items.length > 1)
+ msg.append("Remove these groups : ");
+ else
+ msg.append("Remove a group : ");
+ for(int i = 0; i < items.length; i++) {
+ if(i != 0)
+ msg.append(", ");
+ msg.append(((GroupItem) items[i]).toString());
+ }
+ return msg.toString();
+ }
+
+ protected void addItems(String[] items) {
+ // check "public"
+ String[] grps = new String[items.length];
+ for(int i = 0; i < items.length; i++)
+ grps[i] = new GroupItem(items[i]).group;
+
+ try {
+ ((DiscoveryAdmin) admin).addMemberGroups(grps);
+ } catch (Throwable t) {
+ logger.log(Level.INFO, "adding groups failed", t);
+ }
+ }
+
+ protected void removeItems(Object[] items) {
+ String[] grps = new String[items.length];
+ for(int i = 0; i < items.length; i++)
+ grps[i] = ((GroupItem) items[i]).group;
+
+ try {
+ ((DiscoveryAdmin) admin).removeMemberGroups(grps);
+ } catch (Throwable t){
+ logger.log(Level.INFO, "removing groups failed", t);
+ }
+ }
+ }
+
+ class GroupItem {
+ public String group;
+
+ public GroupItem(String group) {
+ if(group.equals("public"))
+ this.group = "";
+ else
+ this.group = group;
+ }
+
+ public String toString() {
+ if("".equals(group))
+ return "public";
+ else
+ return group;
+ }
+ }
+
+ class LocatorLister extends ListerFrame {
+
+ public LocatorLister(String title) {
+ super(title);
+ }
+
+ protected void initListModel() {
+ if (!(admin instanceof JoinAdmin)) {
+ return;
+ }
+
+ try {
+ LookupLocator[] locators = ((JoinAdmin) admin).getLookupLocators();
+ for(int i = 0; i < locators.length; i++) {
+ model.addElement(locators[i]);
+ }
+ } catch (Throwable t) {
+ logger.log(Level.INFO, "obtaining locators failed", t);
+ }
+ }
+
+ protected String getAddMessage() {
+ return "Enter a new locator's URL";
+ }
+
+ protected String getRemoveMessage(Object[] items) {
+ StringBuffer msg = new StringBuffer();
+ if(items.length > 1)
+ msg.append("Remove these locators : ");
+ else
+ msg.append("Remove a locator : ");
+ for(int i = 0; i < items.length; i++) {
+ if(i != 0)
+ msg.append(", ");
+ msg.append(items[i].toString());
+ }
+ return msg.toString();
+ }
+
+ protected void addItems(String[] items) {
+ LookupLocator[] locs = new LookupLocator[items.length];
+ for(int i = 0; i < items.length; i++) {
+ try {
+ locs[i] = new LookupLocator(items[i]);
+ } catch (MalformedURLException e) {
+ JOptionPane.showMessageDialog(LocatorLister.this,
+ "\"" + items[i] + "\": " +
+ e.getMessage(),
+ "Bad Locator",
+ JOptionPane.WARNING_MESSAGE);
+ return;
+ }
+ }
+
+ try {
+ ((JoinAdmin) admin).addLookupLocators(locs);
+ } catch (Throwable t){
+ logger.log(Level.INFO, "adding locators failed", t);
+ }
+ }
+
+ protected void removeItems(Object[] items) {
+ LookupLocator[] locs = new LookupLocator[items.length];
+ for(int i = 0; i < items.length; i++)
+ locs[i] = (LookupLocator) items[i];
+
+ try {
+ ((JoinAdmin) admin).removeLookupLocators(locs);
+ } catch (Throwable t) {
+ logger.log(Level.INFO, "removing locators failed", t);
+ }
+ }
+ }
+
+ // provides support for ServiceUI
+ public class UIDescriptorPopup extends JPopupMenu implements ActionListener,
+ PopupMenuListener {
+
+ protected transient JMenuItem showUIItem;
+ protected transient ServiceItem serviceItem;
+
+ public UIDescriptorPopup() {
+ super();
+
+ showUIItem = new JMenuItem("Show UI");
+
+ showUIItem.addActionListener(this);
+ showUIItem.setActionCommand("showUI");
+ add(showUIItem);
+
+ addPopupMenuListener(this);
+ setOpaque(true);
+ setLightWeightPopupEnabled(true);
+ }
+
+ public void actionPerformed(ActionEvent anEvent) {
+
+ UIDescriptor uiDescriptor = getSelectedUIDescriptor();
+
+ if (uiDescriptor == null) {
+ return;
+ }
+
+ try {
+ JFrameFactory uiFactory = (JFrameFactory)
+ uiDescriptor.getUIFactory(Thread.currentThread().getContextClassLoader());
+ JFrame frame = uiFactory.getJFrame(serviceItem);
+
+ frame.validate();
+ frame.setVisible(true);
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+
+ return;
+ }
+ }
+
+ public void popupMenuWillBecomeVisible(PopupMenuEvent ev) {
+ }
+
+ public void popupMenuWillBecomeInvisible(PopupMenuEvent ev) {
+ }
+
+ public void popupMenuCanceled(PopupMenuEvent ev) {
+ }
+
+ public void setServiceItem(ServiceItem anItem) {
+ serviceItem = anItem;
+ }
+ }
+
+ class MouseReceiver extends MouseAdapter {
+
+ private ServiceEditor.UIDescriptorPopup popup;
+ private ServiceItem serviceItem;
+
+ public MouseReceiver(ServiceItem aServiceItem,
+ ServiceEditor.UIDescriptorPopup popup) {
+ this.popup = popup;
+ serviceItem = aServiceItem;
+ }
+
+ public void mouseReleased(MouseEvent ev) {
+
+ higlightSelection(ev);
+
+ if (!ev.isPopupTrigger()) {
+ return;
+ }
+
+ UIDescriptor selectedDescriptor = getSelectedUIDescriptor();
+
+ if (selectedDescriptor == null) {
+ return;
+ }
+
+ if (!"javax.swing".equals(selectedDescriptor.toolkit)) {
+ return;
+ }
+
+ popup.setServiceItem(serviceItem);
+ popup.show(ev.getComponent(), ev.getX(), ev.getY());
+ }
+
+ public void mousePressed(MouseEvent ev) {
+
+ higlightSelection(ev);
+
+ if (!ev.isPopupTrigger()) {
+ return;
+ }
+
+ UIDescriptor selectedDescriptor = getSelectedUIDescriptor();
+
+ if (selectedDescriptor == null) {
+ return;
+ }
+
+ if (!"javax.swing".equals(selectedDescriptor.toolkit)) {
+ return;
+ }
+
+ popup.setServiceItem(serviceItem);
+ popup.show(ev.getComponent(), ev.getX(), ev.getY());
+ }
+ }
+
+ private UIDescriptor getSelectedUIDescriptor() {
+
+ ObjectNode selectedNode =
+ (ObjectNode) attrPanel.tree.getLastSelectedPathComponent();
+
+ if (selectedNode == null) {
+ return null;
+ }
+
+ Object selectedObject = selectedNode.getObject();
+
+ try {
+ return (UIDescriptor) selectedObject;
+ }
+ catch (ClassCastException e) {
+ return null;
+ }
+ }
+
+ private void higlightSelection(MouseEvent event) {
+ attrPanel.tree.setSelectionPath(attrPanel.tree.getPathForLocation(
+ event.getX(), event.getY()));
+ }
+
+ private ServiceEditor.UIDescriptorPopup uiDescriptorPopup() {
+ return new ServiceEditor.UIDescriptorPopup();
+ }
+}