package org.jacorb.naming.namemanager;
/*
* JacORB - a free Java ORB
*
* Copyright (C) 1997-2014 Gerald Brose / The JacORB Team.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Library General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option) any
* later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more
* details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
import java.util.HashSet;
import java.util.Vector;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import org.jacorb.orb.iiop.IIOPAddress;
import org.jacorb.orb.iiop.IIOPProfile;
import org.omg.CORBA.ORB;
import org.omg.CosNaming.Binding;
import org.omg.CosNaming.BindingIteratorHolder;
import org.omg.CosNaming.BindingListHolder;
import org.omg.CosNaming.BindingType;
import org.omg.CosNaming.NameComponent;
import org.omg.CosNaming.NamingContext;
import org.omg.CosNaming.NamingContextHelper;
/**
* @author Gerald Brose, FU Berlin
*/
public class ContextNode
{
protected Binding[] contents;
public boolean matched;
public boolean used;
public NamingContext context;
private DefaultMutableTreeNode myDefaultNode;
private DefaultTreeModel model;
private Binding binding;
private Vector bindingData;
private String myName;
private ORB orb;
private static HashSet<String> contexts = new HashSet<String>();
public ContextNode (ORB orb, NamingContext context, DefaultTreeModel model)
{
used = false;
this.model = model;
this.context = context;
this.orb = orb;
}
public ContextNode (ORB orb, NamingContext context, Binding b, DefaultTreeModel model)
{
used = false;
this.model = model;
this.context = context;
binding = b;
this.orb = orb;
}
/**
*
*/
public void display ()
{
contexts.clear();
update ();
if (bindingData != null)
NSTree.nsTable.setData (bindingData, this);
}
public boolean equals (ContextNode bnode)
{
return toString ().equals (bnode.toString ());
}
public NameComponent[] getName ()
{
return binding.binding_name;
}
/**
*
* @param node javax.swing.tree.DefaultMutableTreeNode
*/
public void setNode (DefaultMutableTreeNode node)
{
this.myDefaultNode = node;
}
public String toString ()
{
if (binding == null)
{
return "RootContext";
}
if (myName == null)
{
NameComponent[] name = binding.binding_name;
String kind = name[name.length - 1].kind;
myName = name[name.length - 1].id + (kind != null && kind.length () > 0 ? "." + kind : "");
}
return myName;
}
public void unbind (NameComponent[] nc) throws org.omg.CosNaming.NamingContextPackage.NotFound,
org.omg.CosNaming.NamingContextPackage.CannotProceed,
org.omg.CosNaming.NamingContextPackage.InvalidName
{
context.unbind (nc);
}
/**
* update the content of this node and all its children
*/
public synchronized void update ()
{
try
{
if( isMarked(this.context))
{
System.out.println ("Loop detected for " + this.context);
return;
}
mark(this.context);
BindingListHolder blsoh = new BindingListHolder ();
BindingIteratorHolder bioh = new BindingIteratorHolder ();
ContextNode context_node;
/*
* Use Integer.MAX_VALUE to avoid creating BindingIterators on the
* server side.
*/
context.list (Integer.MAX_VALUE, blsoh, bioh);
Binding[] bindings = blsoh.value;
int childCount = myDefaultNode.getChildCount ();
// set up lists of object bindings and subcontext bindings
int context_count = 0;
int object_count = 0;
for (int i = 0; i < bindings.length; i++)
{
if (bindings[i].binding_type == BindingType.ncontext)
context_count++;
else
object_count++;
}
ContextNode[] contexts = new ContextNode[context_count];
Binding[] objects = new Binding[object_count];
for (int i = 0; i < bindings.length; i++)
{
if (bindings[i].binding_type == BindingType.ncontext)
contexts[--context_count] = new ContextNode (orb,
NamingContextHelper.narrow (context.resolve (bindings[i].binding_name)),
bindings[i], model);
else
objects[--object_count] = bindings[i];
}
// Compare this node's sub contexts and mark those found
// in the list of context bindings as used
for (int i = 0; i < childCount; i++)
{
DefaultMutableTreeNode dmtn = (DefaultMutableTreeNode)myDefaultNode.getChildAt (i);
context_node = (ContextNode)dmtn.getUserObject ();
for (int j = 0; j < contexts.length; j++)
{
if (context_node.equals (contexts[j]))
{
context_node.matched = true;
contexts[j].matched = true;
}
}
}
// Delete those child nodes that were not found in the
// list
Vector removeList = new Vector ();
for (int i = 0; i < childCount; i++)
{
DefaultMutableTreeNode node = (DefaultMutableTreeNode)myDefaultNode.getChildAt (i);
context_node = (ContextNode)node.getUserObject ();
if (!context_node.matched)
{
removeList.addElement (node);
}
else
context_node.matched = false;
}
int rsize = removeList.size ();
for (int i = 0; i < rsize; i++)
{
model.removeNodeFromParent ((DefaultMutableTreeNode)removeList.elementAt (i));
}
bindingData = new Vector ();
// Insert new context nodes found in the list as
// children of this tree node
for (int i = 0; i < contexts.length; i++)
{
if (!contexts[i].matched)
{
contexts[i].used = true;
DefaultMutableTreeNode node = new DefaultMutableTreeNode ();
// tree node and context node need to know each other:
contexts[i].setNode (node);
node.setUserObject (contexts[i]);
node.setAllowsChildren (true);
model.insertNodeInto (node, myDefaultNode, 0);
}
NameComponent last = contexts[i].binding.binding_name[contexts[i].binding.binding_name.length - 1];
NameComponent[] ncs = { last };
org.jacorb.orb.ParsedIOR pior = null;
try
{
pior = ((org.jacorb.orb.Delegate)((org.omg.CORBA.portable.ObjectImpl)context.resolve (ncs))._get_delegate ()).getBaseIOR ();
}
catch (org.omg.CosNaming.NamingContextPackage.NotFound nf)
{
// the named object could have disappeared from the
// naming context in the meantime. If it has, we simply
// continue
continue;
}
Vector row = createRow (last, pior);
bindingData.addElement (row);
}
for (int i = 0; i < objects.length; i++)
{
NameComponent last = objects[i].binding_name[objects[i].binding_name.length - 1];
NameComponent[] ncs = { last };
org.jacorb.orb.ParsedIOR pior = null;
try
{
pior = ((org.jacorb.orb.Delegate)((org.omg.CORBA.portable.ObjectImpl)context.resolve (ncs))._get_delegate ()).getBaseIOR ();
}
catch (org.omg.CosNaming.NamingContextPackage.NotFound nf)
{
// the named object could have disappeared from the
// naming context in the meantime. If it has, we simply
// continue
continue;
}
Vector row = createRow (last, pior);
bindingData.addElement (row);
}
/*
* Destroy binding iterators to reduce resource consumption on servers.
* See OMG Corba Naming Service specification 1.3, chapter 2.3.2
* "Garbage Collection of Iterators".
*/
if (bioh.value != null)
{
bioh.value.destroy ();
}
// recursively update child nodes
childCount = myDefaultNode.getChildCount ();
for (int i = 0; i < childCount; i++)
{
DefaultMutableTreeNode dmtn = (DefaultMutableTreeNode)myDefaultNode.getChildAt (i);
context_node = (ContextNode)dmtn.getUserObject ();
// Name name = new Name(bindings[i].binding_name);
context_node.update ();
}
}
catch (Exception e)
{
e.printStackTrace ();
}
}
private void mark(NamingContext nc) {
contexts.add ( orb.object_to_string(nc));
}
private boolean isMarked(NamingContext nc)
{
return contexts.contains(orb.object_to_string(nc));
}
private Vector createRow (NameComponent last, org.jacorb.orb.ParsedIOR pior)
{
Vector row = new Vector ();
row.addElement (last.id);
row.addElement (last.kind);
row.addElement (pior.getTypeId ());
IIOPProfile p = (IIOPProfile)pior.getEffectiveProfile ();
final IIOPAddress iiopAddress = (IIOPAddress)p.getAddress ();
row.addElement (iiopAddress.getIP ());
row.addElement (Integer.toString (iiopAddress.getPort ()));
return row;
}
}