package org.jboss.naming;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Proxy;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.LinkRef;
import javax.naming.NameClassPair;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import org.jboss.ejb.Container;
import org.jboss.ejb.EjbModule;
import org.jboss.system.ServiceMBeanSupport;
public class JNDIView
extends ServiceMBeanSupport
implements JNDIViewMBean
{
public JNDIView()
{
}
public String list(boolean verbose)
{
StringBuffer buffer = new StringBuffer(4096);
Set ejbModules = null;
Context context = null;
ClassLoader currentLoader = Thread.currentThread().getContextClassLoader();
try
{
ejbModules = server.queryNames(EjbModule.EJB_MODULE_QUERY_NAME, null);
}
catch (Throwable e)
{
log.error("getDeployedApplications failed", e);
buffer.append("Failed to getDeployedApplications\n");
formatException(buffer, e);
buffer.insert(0, "<pre>");
buffer.append("</pre>");
return buffer.toString();
}
for (Iterator i = ejbModules.iterator(); i.hasNext();)
{
ObjectName app = (ObjectName) i.next();
String module = app.getKeyProperty("module");
if( module == null )
module = app.toString();
buffer.append("<h1>Ejb Module: " + module + "</h1>\n");
try
{
Collection containers = (Collection) server.getAttribute(app, "Containers");
for (Iterator iter = containers.iterator(); iter.hasNext();)
{
Container con = (Container) iter.next();
Thread.currentThread().setContextClassLoader(con.getClassLoader());
String bean = con.getBeanMetaData().getEjbName();
buffer.append("<h2>java:comp namespace of the " + bean + " bean:</h2>\n");
try
{
context = new InitialContext();
context = (Context) context.lookup("java:comp");
}
catch (NamingException e)
{
buffer.append("Failed on lookup, " + e.toString(true));
formatException(buffer, e);
continue;
}
buffer.append("<pre>\n");
list(context, " ", buffer, verbose);
buffer.append("</pre>\n");
}
}
catch (Throwable e)
{
log.error("getConainers failed", e);
buffer.append("<pre>");
buffer.append("Failed to get ejbs in module\n");
formatException(buffer, e);
buffer.append("</pre>");
}
}
Thread.currentThread().setContextClassLoader(currentLoader);
try
{
context = new InitialContext();
context = (Context) context.lookup("java:");
buffer.append("<h1>java: Namespace</h1>\n");
buffer.append("<pre>\n");
list(context, " ", buffer, verbose);
buffer.append("</pre>\n");
}
catch (NamingException e)
{
log.error("lookup for java: failed", e);
buffer.append("Failed to get InitialContext, " + e.toString(true));
formatException(buffer, e);
}
try
{
context = new InitialContext();
buffer.append("<h1>Global JNDI Namespace</h1>\n");
buffer.append("<pre>\n");
list(context, " ", buffer, verbose);
buffer.append("</pre>\n");
}
catch (NamingException e)
{
log.error("Failed to get InitialContext", e);
buffer.append("Failed to get InitialContext, " + e.toString(true));
formatException(buffer, e);
}
return buffer.toString();
}
public String listXML()
{
StringBuffer buffer = new StringBuffer(4096);
Set ejbModules = null;
Context context = null;
ClassLoader currentLoader = Thread.currentThread().getContextClassLoader();
try
{
ejbModules = server.queryNames(EjbModule.EJB_MODULE_QUERY_NAME, null);
}
catch (Exception e)
{
log.error("getDeployedApplications failed", e);
openJndiTag(buffer);
appendErrorTag(buffer,
"Failed to getDeployedApplications " + e.toString());
closeJndiTag(buffer);
return buffer.toString();
}
openJndiTag(buffer);
for (Iterator i = ejbModules.iterator(); i.hasNext();)
{
ObjectName app = (ObjectName) i.next();
openEjbModuleTag(buffer, app.getKeyProperty("url"));
listModuleContainers(buffer, app);
closeEjbModuleTag(buffer);
}
Thread.currentThread().setContextClassLoader(currentLoader);
try
{
context = new InitialContext();
context = (Context) context.lookup("java:");
}
catch (NamingException e)
{
log.error("Failed to get InitialContext for (java:)", e);
appendErrorTag(buffer,
"Failed to get InitialContext for (java:), " +
e.toString(true));
}
if (context != null)
{
openContextTag(buffer);
appendJavaNameTag(buffer);
try
{
listXML(context, buffer);
}
catch (Throwable t)
{
log.error("Failed to list contents of (java:)", t);
appendErrorTag(buffer,
"Failed to list contents of (java:), " +
t.toString());
}
closeContextTag(buffer);
}
try
{
context = new InitialContext();
}
catch (NamingException e)
{
log.error("Failed to get InitialContext", e);
appendErrorTag(buffer,
"Failed to get InitialContext, " + e.toString(true));
}
if (context != null)
{
openContextTag(buffer);
appendGlobalNameTag(buffer);
try
{
listXML(context, buffer);
}
catch (Throwable t)
{
log.error("Failed to list global contents ", t);
appendErrorTag(buffer,
"Failed to list global contents, " + t.toString());
}
closeContextTag(buffer);
}
closeJndiTag(buffer);
return buffer.toString();
}
protected ObjectName getObjectName(MBeanServer server, ObjectName name)
throws javax.management.MalformedObjectNameException
{
return name == null ? OBJECT_NAME : name;
}
private void list(Context ctx, String indent, StringBuffer buffer, boolean verbose)
{
ClassLoader loader = Thread.currentThread().getContextClassLoader();
try
{
NamingEnumeration ne = ctx.list("");
while (ne.hasMore())
{
NameClassPair pair = (NameClassPair) ne.next();
log.trace("pair: " + pair);
String name = pair.getName();
String className = pair.getClassName();
boolean recursive = false;
boolean isLinkRef = false;
boolean isProxy = false;
Class c = null;
try
{
c = loader.loadClass(className);
log.trace("type: " + c);
if (Context.class.isAssignableFrom(c))
recursive = true;
if (LinkRef.class.isAssignableFrom(c))
isLinkRef = true;
isProxy = Proxy.isProxyClass(c);
}
catch (ClassNotFoundException cnfe)
{
if (className.startsWith("$Proxy"))
{
isProxy = true;
try
{
Object p = ctx.lookup(name);
c = p.getClass();
}
catch (NamingException e)
{
Throwable t = e.getRootCause();
if (t instanceof ClassNotFoundException)
{
String msg = t.getMessage();
if (msg != null)
{
className = msg;
}
}
}
}
}
buffer.append(indent + " +- " + name);
if (isLinkRef)
{
try
{
log.trace("looking up LinkRef; name=" + name);
Object obj = ctx.lookupLink(name);
log.trace("Object type: " + obj.getClass());
LinkRef link = (LinkRef) obj;
buffer.append("[link -> ");
buffer.append(link.getLinkName());
buffer.append(']');
}
catch (Throwable t)
{
log.debug("Invalid LinkRef for: " + name, t);
buffer.append("invalid]");
}
}
if (isProxy)
{
buffer.append(" (proxy: " + pair.getClassName());
if (c != null)
{
Class[] ifaces = c.getInterfaces();
buffer.append(" implements ");
for (int i = 0; i < ifaces.length; i++)
{
buffer.append(ifaces[i]);
buffer.append(',');
}
buffer.setCharAt(buffer.length() - 1, ')');
}
else
{
buffer.append(" implements " + className + ")");
}
}
else if (verbose)
{
buffer.append(" (class: " + pair.getClassName() + ")");
}
buffer.append('\n');
if (recursive)
{
try
{
Object value = ctx.lookup(name);
if (value instanceof Context)
{
Context subctx = (Context) value;
list(subctx, indent + " | ", buffer, verbose);
}
else
{
buffer.append(indent + " | NonContext: " + value);
buffer.append('\n');
}
}
catch (Throwable t)
{
buffer.append("Failed to lookup: " + name + ", errmsg=" + t.getMessage());
buffer.append('\n');
}
}
}
ne.close();
}
catch (NamingException ne)
{
buffer.append("error while listing context " + ctx.toString() + ": " + ne.toString(true));
formatException(buffer, ne);
}
}
private void listXML(Context ctx, StringBuffer buffer)
{
ClassLoader loader = Thread.currentThread().getContextClassLoader();
try
{
NamingEnumeration ne = ctx.list("");
while (ne.hasMore())
{
NameClassPair pair = (NameClassPair) ne.next();
boolean recursive = false;
boolean isLinkRef = false;
try
{
Class c = loader.loadClass(pair.getClassName());
if (Context.class.isAssignableFrom(c))
recursive = true;
if (LinkRef.class.isAssignableFrom(c))
isLinkRef = true;
}
catch (ClassNotFoundException cnfe)
{
}
String name = pair.getName();
if (isLinkRef)
{
Object obj = null;
LinkRef link = null;
try
{
obj = ctx.lookupLink(name);
link = (LinkRef) obj;
}
catch (Throwable t)
{
log.error("Invalid LinkRef for: " + name, t);
appendLinkRefErrorTag(buffer);
}
appendLinkRefTag(buffer, link, pair);
}
else
{
if (recursive)
{
Object value = null;
try
{
value = ctx.lookup(name);
}
catch (Throwable t)
{
appendErrorTag(buffer,
"Failed to lookup: " + name +
", errmsg=" + t.getMessage());
}
if (value instanceof Context)
{
Context subctx = (Context) value;
openContextTag(buffer);
appendNCPTag(buffer, pair);
try
{
listXML(subctx, buffer);
}
catch (Throwable t)
{
appendErrorTag(buffer,
"Failed to list contents of: " + name +
", errmsg=" + t.getMessage());
}
closeContextTag(buffer);
}
else
{
appendNonContextTag(buffer, pair);
}
}
else
{
appendLeafTag(buffer, pair);
}
}
}
ne.close();
}
catch (NamingException ne)
{
appendErrorTag(buffer,
"error while listing context " +
ctx.toString() + ": " + ne.toString(true));
}
}
private void listModuleContainers(StringBuffer buffer, ObjectName app)
{
Collection containers = null;
try
{
containers = (Collection) server.getAttribute(app, "Containers");
}
catch (Throwable t)
{
log.error("getContainers failed", t);
appendPreExceptionTag(buffer, "Failed to get ejbs in module", t);
}
for (Iterator iter = containers.iterator(); iter.hasNext();)
{
listContainerContext(buffer, (Container) iter.next());
}
}
private void listContainerContext(StringBuffer buffer, Container con)
{
Thread.currentThread().setContextClassLoader(con.getClassLoader());
String bean = con.getBeanMetaData().getEjbName();
openContextTag(buffer);
appendBeanTag(buffer, bean);
Context context = null;
try
{
context = new InitialContext();
context = (Context) context.lookup("java:comp");
}
catch (NamingException e)
{
appendErrorTag(buffer,
"Failed on lookup " + e.toString(true));
context = null;
}
if (context != null)
{
try
{
listXML(context, buffer);
}
catch (Throwable t)
{
appendErrorTag(buffer,
"Failed on list contents, " + t.toString());
}
}
closeContextTag(buffer);
}
private void openJndiTag(StringBuffer buffer)
{
buffer.append("<jndi>\n");
}
private void closeJndiTag(StringBuffer buffer)
{
buffer.append("</jndi>\n");
}
private void openEjbModuleTag(StringBuffer buffer, String file)
{
buffer.append("<ejbmodule>\n");
buffer.append("<file>" + file + "</file>\n");
}
private void closeEjbModuleTag(StringBuffer buffer)
{
buffer.append("</ejbmodule>\n");
}
private void appendPreExceptionTag(StringBuffer buffer,
String msg,
Throwable t)
{
buffer.append("<pre>\n" + msg+"\n");
formatException(buffer, t);
buffer.append("</pre>\n");
}
private void appendBeanTag(StringBuffer buffer, String bean)
{
buffer.append("<name>java:comp</name>\n");
buffer.append("<attribute name='bean'>" + bean + "</attribute>\n");
}
private void appendJavaNameTag(StringBuffer buffer)
{
buffer.append("<name>java:</name>\n");
}
private void appendGlobalNameTag(StringBuffer buffer)
{
buffer.append("<name>Global</name>\n");
}
private void appendLinkRefTag(StringBuffer buffer,
LinkRef link,
NameClassPair ncp)
{
buffer.append("<link-ref>\n");
buffer.append("<name>" + ncp.getName() + "</name>\n");
try
{
String lName = link.getLinkName();
buffer.append("<link>" + lName + "</link>\n");
}
catch (NamingException e)
{
appendErrorTag(buffer,
"Failed to getLinkName, " + e.toString(true));
}
buffer.append("<attribute name='class'>" + ncp.getClassName() +
"</attribute>\n");
buffer.append("</link-ref>\n");
}
private void appendLinkRefErrorTag(StringBuffer buffer)
{
buffer.append("<link-ref>\n");
buffer.append("<name>Invalid</name>\n");
buffer.append("</link-ref>\n");
}
private void openContextTag(StringBuffer buffer)
{
buffer.append("<context>\n");
}
private void closeContextTag(StringBuffer buffer)
{
buffer.append("</context>\n");
}
private void appendNonContextTag(StringBuffer buffer, NameClassPair ncp)
{
buffer.append("<non-context>\n");
appendNCPTag(buffer, ncp);
buffer.append("</non-context>\n");
}
private void appendLeafTag(StringBuffer buffer, NameClassPair ncp)
{
buffer.append("<leaf>\n");
appendNCPTag(buffer, ncp);
buffer.append("</leaf>\n");
}
private void appendNCPTag(StringBuffer buffer, NameClassPair ncp)
{
buffer.append("<name>" + ncp.getName() + "</name>\n");
buffer.append("<attribute name='class'>" + ncp.getClassName() +
"</attribute>\n");
}
private void appendErrorTag(StringBuffer buffer, String msg)
{
buffer.append("<error>\n");
buffer.append("<message>" + msg + "</message>\n");
buffer.append("</error>\n");
}
private void formatException(StringBuffer buffer, Throwable t)
{
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
buffer.append("<pre>\n");
t.printStackTrace(pw);
buffer.append(sw.toString());
buffer.append("</pre>\n");
}
}