Index: features/org.eclipse.mat.feature/feature.xml =================================================================== --- features/org.eclipse.mat.feature/feature.xml (revision 1527) +++ features/org.eclipse.mat.feature/feature.xml (working copy) @@ -112,4 +112,11 @@ version="0.0.0" unpack="false"/> + + Index: features/org.eclipse.mat.ui.rcp.feature/feature.xml =================================================================== --- features/org.eclipse.mat.ui.rcp.feature/feature.xml (revision 1527) +++ features/org.eclipse.mat.ui.rcp.feature/feature.xml (working copy) @@ -113,6 +113,13 @@ unpack="false"/> + + ../plugins/org.eclipse.mat.ui.rcp ../plugins/org.eclipse.mat.ibmdumps ../plugins/org.eclipse.mat.jruby.resolver + ../plugins/org.eclipse.mat.javaee ../features/org.eclipse.mat.chart.feature ../features/org.eclipse.mat.feature Index: plugins/org.eclipse.mat.javaee/.classpath =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/xml Index: plugins/org.eclipse.mat.javaee/.classpath =================================================================== --- plugins/org.eclipse.mat.javaee/.classpath (revision 0) +++ plugins/org.eclipse.mat.javaee/.classpath (working copy) Property changes on: plugins/org.eclipse.mat.javaee/.classpath ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/xml \ No newline at end of property Index: plugins/org.eclipse.mat.javaee/.project =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/xml Index: plugins/org.eclipse.mat.javaee/.project =================================================================== --- plugins/org.eclipse.mat.javaee/.project (revision 0) +++ plugins/org.eclipse.mat.javaee/.project (working copy) Property changes on: plugins/org.eclipse.mat.javaee/.project ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/xml \ No newline at end of property Index: plugins/org.eclipse.mat.javaee/.settings/org.eclipse.jdt.core.prefs =================================================================== --- plugins/org.eclipse.mat.javaee/.settings/org.eclipse.jdt.core.prefs (revision 0) +++ plugins/org.eclipse.mat.javaee/.settings/org.eclipse.jdt.core.prefs (working copy) @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.5 Index: plugins/org.eclipse.mat.javaee/META-INF/MANIFEST.MF =================================================================== --- plugins/org.eclipse.mat.javaee/META-INF/MANIFEST.MF (revision 0) +++ plugins/org.eclipse.mat.javaee/META-INF/MANIFEST.MF (working copy) @@ -0,0 +1,17 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %Bundle-Name +Bundle-SymbolicName: org.eclipse.mat.javaee;singleton:=true +Bundle-Version: 1.5.0.qualifier +Bundle-Vendor: %Bundle-Vendor +Require-Bundle: org.eclipse.core.runtime;bundle-version="3.3.100", + org.eclipse.mat.api;bundle-version="1.5.0" +Bundle-Activator: org.eclipse.mat.javaee.JavaEEPlugin +Bundle-ActivationPolicy: lazy +Bundle-RequiredExecutionEnvironment: J2SE-1.5 +Bundle-Localization: plugin +Bundle-Copyright: Copyright (c) 2014 Red Hat Inc. + All rights reserved. This program and the accompanying materials + are made available under the terms of the Eclipse Public License v1.0 + which accompanies this distribution, and is available at + http://www.eclipse.org/legal/epl-v10.html Index: plugins/org.eclipse.mat.javaee/META-INF/reports/javaee-overview.xml =================================================================== --- plugins/org.eclipse.mat.javaee/META-INF/reports/javaee-overview.xml (revision 0) +++ plugins/org.eclipse.mat.javaee/META-INF/reports/javaee-overview.xml (working copy) @@ -0,0 +1,29 @@ +
+ + + javaee-http-sessions + + + javaee-http-session-attributes + + + javaee-http-requests + + + javaee-servlets + + + javaee-ejb-stateful + +
\ No newline at end of file Index: plugins/org.eclipse.mat.javaee/about.html =================================================================== --- plugins/org.eclipse.mat.javaee/about.html (revision 0) +++ plugins/org.eclipse.mat.javaee/about.html (working copy) @@ -0,0 +1,28 @@ + + + + +About + + +

About This Content

+ +

June 5, 2006

+

License

+ +

The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available +at http://www.eclipse.org/legal/epl-v10.html. +For purposes of the EPL, "Program" will mean the Content.

+ +

If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at http://www.eclipse.org.

+ + + \ No newline at end of file Index: plugins/org.eclipse.mat.javaee/build.properties =================================================================== --- plugins/org.eclipse.mat.javaee/build.properties (revision 0) +++ plugins/org.eclipse.mat.javaee/build.properties (working copy) @@ -0,0 +1,18 @@ +############################################################################### +# Copyright (c) 2014 Red Hat Inc. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Red Hat Inc - initial API and implementation +############################################################################### + +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml,\ + plugin.properties,\ + about.html Index: plugins/org.eclipse.mat.javaee/plugin.properties =================================================================== --- plugins/org.eclipse.mat.javaee/plugin.properties (revision 0) +++ plugins/org.eclipse.mat.javaee/plugin.properties (working copy) @@ -0,0 +1,13 @@ +############################################################################### +# Copyright (c) 2014 Red Hat Inc. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Red Hat Inc - initial API and implementation +############################################################################### +#Properties file for org.eclipse.mat.hprof +Bundle-Vendor = Eclipse Memory Analyzer +Bundle-Name = Memory Analyzer - Java EE queries and reports Index: plugins/org.eclipse.mat.javaee/plugin.xml =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/xml Index: plugins/org.eclipse.mat.javaee/plugin.xml =================================================================== --- plugins/org.eclipse.mat.javaee/plugin.xml (revision 0) +++ plugins/org.eclipse.mat.javaee/plugin.xml (working copy) Property changes on: plugins/org.eclipse.mat.javaee/plugin.xml ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/xml \ No newline at end of property Index: plugins/org.eclipse.mat.javaee/pom.xml =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/xml Index: plugins/org.eclipse.mat.javaee/pom.xml =================================================================== --- plugins/org.eclipse.mat.javaee/pom.xml (revision 0) +++ plugins/org.eclipse.mat.javaee/pom.xml (working copy) Property changes on: plugins/org.eclipse.mat.javaee/pom.xml ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/xml \ No newline at end of property Index: plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/BaseObjectQuery.java =================================================================== --- plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/BaseObjectQuery.java (revision 0) +++ plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/BaseObjectQuery.java (working copy) @@ -0,0 +1,161 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat Inc + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc - initial API and implementation + *******************************************************************************/ +package org.eclipse.mat.javaee; + +import java.lang.reflect.Array; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import org.eclipse.mat.SnapshotException; +import org.eclipse.mat.query.Column; +import org.eclipse.mat.query.IContextObject; +import org.eclipse.mat.query.IQuery; +import org.eclipse.mat.query.IResult; +import org.eclipse.mat.query.IResultTree; +import org.eclipse.mat.query.ResultMetaData; +import org.eclipse.mat.query.annotations.Argument; +import org.eclipse.mat.snapshot.ISnapshot; +import org.eclipse.mat.snapshot.query.IHeapObjectArgument; +import org.eclipse.mat.util.IProgressListener; + +/* O is the "overview" node type*/ +public abstract class BaseObjectQuery implements IQuery { + private final Class oClass; + + @Argument public ISnapshot snapshot; + + @Argument(isMandatory = false, flag = Argument.UNFLAGGED) + public IHeapObjectArgument objects; + + public BaseObjectQuery(Class oClass) { + this.oClass = oClass; + } + + public IResult execute(IProgressListener listener) throws Exception { + List source = ((objects != null) ? new IntArrayList(objects.getIds(listener)) : findObjects(snapshot)); + O[] result = buildResults(source).toArray((O[]) Array.newInstance(oClass, source.size())); + + Arrays.sort(result, new Comparator() { + public int compare(O o1, O o2) { + return o1.getRetainedHeap() > o2.getRetainedHeap() ? -1 : o1.getRetainedHeap() == o2.getRetainedHeap() ? 0 : 1; + } + }); + + return new ResultList(result); + } + + protected abstract List buildResults(List source) throws SnapshotException; + protected abstract List findObjects(ISnapshot snapshot) throws SnapshotException; + protected abstract boolean overviewHasChildren(O row); + protected abstract Column[] getColumns(); + + protected Object getOverviewColumnValue(O row, int columnIndex) { + JavaEEPlugin.error("Unexpected column index " + columnIndex); + return null; + } + + protected Object getColumnValue(Object row, int columnIndex) { + if (row.getClass().isAssignableFrom(oClass)) { + return getOverviewColumnValue((O)row, columnIndex); + } else if (row instanceof GraftedResultTree.Proxy) { + return ((GraftedResultTree.Proxy)row).getColumnValue(columnIndex); + } else { + JavaEEPlugin.error("Unexpected row class " + row.getClass().getName()); + return null; + } + } + + protected IContextObject getContext(Object row) { + if (row.getClass().isAssignableFrom(oClass)) { + final O node = (O) row; + return new IContextObject() { + public int getObjectId() { + return node.getId(); + } + }; + } else if (row instanceof GraftedResultTree.Proxy) { + GraftedResultTree.Proxy proxy = (GraftedResultTree.Proxy) row; + //return proxy.getContext(); FIXME bad performance?!? + return null; + } else { + JavaEEPlugin.error("Unexpected row class " + row.getClass().getName()); + return null; + } + } + + + protected boolean hasChildren(Object row) { + if (row.getClass().isAssignableFrom(oClass)) { + return overviewHasChildren((O)row); + } else if (row instanceof GraftedResultTree.Proxy) { + return ((GraftedResultTree.Proxy)row).hasChildren(); + } else { + JavaEEPlugin.error("Unexpected row class " + row.getClass().getName()); + return false; + } + } + + protected List getChildren(Object row) { + if (row.getClass().isAssignableFrom(oClass)) { + return getOverviewChildren((O)row); + } else if (row instanceof GraftedResultTree.Proxy) { + GraftedResultTree.Proxy proxy = (GraftedResultTree.Proxy) row; + return proxy.getChildren(); + } else { + JavaEEPlugin.error("Unexpected row class " + row.getClass().getName()); + return null; + } + } + + protected List getOverviewChildren(O row) { + return Collections.emptyList(); + } + + + private class ResultList implements IResultTree { + private final O[] results; + + public ResultList(O[] sessions) { + this.results = sessions; + } + + public Object getColumnValue(Object row, int columnIndex) { + return BaseObjectQuery.this.getColumnValue(row, columnIndex); + } + + public Column[] getColumns() { + return BaseObjectQuery.this.getColumns(); + } + + public IContextObject getContext(Object row) { + return BaseObjectQuery.this.getContext(row); + } + + public ResultMetaData getResultMetaData() { + return new ResultMetaData.Builder() + .build(); + } + + public List getElements() { + return Arrays.asList(results); + } + + public boolean hasChildren(Object row) { + return BaseObjectQuery.this.hasChildren(row); + } + + public List getChildren(Object row) { + return BaseObjectQuery.this.getChildren(row); + } + } +} Index: plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/GraftedResultTree.java =================================================================== --- plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/GraftedResultTree.java (revision 0) +++ plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/GraftedResultTree.java (working copy) @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat Inc + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc - initial API and implementation + *******************************************************************************/ +package org.eclipse.mat.javaee; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.mat.query.IContextObject; +import org.eclipse.mat.query.IResultTree; + +public class GraftedResultTree { + private final IResultTree subtree; + private final int[] columnMapping; + + private GraftedResultTree(IResultTree tree, final int[] columnMapping) { + if (Utils.max(columnMapping) > tree.getColumns().length) { + throw new IllegalArgumentException("Mapped to non-existant columns"); + } + + this.subtree = tree; + this.columnMapping = columnMapping; + } + + public static List graft(IResultTree child, Object root, final int[] columnMapping) { + GraftedResultTree tree = new GraftedResultTree(child, columnMapping); + List children = child.getElements(); + List results = new ArrayList(children.size()); + for (Object o: children) { + results.add(tree.proxy(o)); + } + return results; + } + + private Proxy proxy(Object o) { + return new Proxy(o); + } + + public class Proxy { + private final Object o; + + public Proxy(Object o) { + this.o = o; + } + + public List getChildren() { + List children = subtree.getChildren(o); + List results = new ArrayList(children.size()); + for (Object c: children) { + results.add(new Proxy(c)); + } + return results; + } + + public boolean hasChildren() { + return subtree.hasChildren(o); + } + + public IContextObject getContext() { + return subtree.getContext(o); + } + + public Object getColumnValue(int columnIndex) { + int col = columnMapping[columnIndex]; + if (col >= 0) + return subtree.getColumnValue(o, col); + else + return null; + } + } +} Index: plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/IOverviewNode.java =================================================================== --- plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/IOverviewNode.java (revision 0) +++ plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/IOverviewNode.java (working copy) @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat Inc + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc - initial API and implementation + *******************************************************************************/ +package org.eclipse.mat.javaee; + +public interface IOverviewNode { + long getRetainedHeap(); + int getId(); +} Index: plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/IntArrayList.java =================================================================== --- plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/IntArrayList.java (revision 0) +++ plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/IntArrayList.java (working copy) @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat Inc + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc - initial API and implementation + *******************************************************************************/ +package org.eclipse.mat.javaee; + +import java.util.AbstractList; +import java.util.RandomAccess; + +public class IntArrayList extends AbstractList implements RandomAccess { + private final int[] elements; + + public IntArrayList(int[] elements) { + this.elements = elements; + } + + public Integer get(int index) { + return elements[index]; + } + + public int size() { + return elements.length; + } + +} Index: plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/JavaEEPlugin.java =================================================================== --- plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/JavaEEPlugin.java (revision 0) +++ plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/JavaEEPlugin.java (working copy) @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat Inc + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc - initial API and implementation + *******************************************************************************/ +package org.eclipse.mat.javaee; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Plugin; +import org.eclipse.core.runtime.Status; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +public class JavaEEPlugin extends Plugin implements BundleActivator { + public static final String PLUGIN_ID = "org.eclipse.mat.javaee"; //$NON-NLS-1$ + + private static JavaEEPlugin plugin; + + public JavaEEPlugin() { + + } + + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + } + + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + public static JavaEEPlugin getDefault() { + return plugin; + } + + public static void log(IStatus status) { + getDefault().getLog().log(status); + } + + public static void error(Throwable e) { + error("Internal error", e); + } + + public static void error(String message, Throwable e) { + log(new Status(IStatus.ERROR, PLUGIN_ID, message, e)); + } + + public static void error(String message) { + log(new Status(IStatus.ERROR, PLUGIN_ID, message)); + } + + public static void warning(String message) { + log(new Status(IStatus.WARNING, PLUGIN_ID, message)); + } + + public static void warning(String message, Throwable e) { + log(new Status(IStatus.WARNING, PLUGIN_ID, message, e)); + } + + public static void info(String message) { + log(new Status(IStatus.INFO, PLUGIN_ID, message)); + + } + + public static void log(int severity, String message) { + log(new Status(severity, PLUGIN_ID, message)); + } +} Index: plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/SimpleObjectQuery.java =================================================================== --- plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/SimpleObjectQuery.java (revision 0) +++ plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/SimpleObjectQuery.java (working copy) @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat Inc + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc - initial API and implementation + *******************************************************************************/ +package org.eclipse.mat.javaee; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.mat.SnapshotException; +import org.eclipse.mat.snapshot.model.IObject; + +public abstract class SimpleObjectQuery extends BaseObjectQuery { + public SimpleObjectQuery(Class oClass) { + super(oClass); + } + + protected List buildResults(List source) throws SnapshotException { + List result = new ArrayList(); + for (int id: source) { + O o = createOverviewNode(snapshot.getObject(id)); + if (o != null) + result.add(o); + } + return result; + } + + protected abstract O createOverviewNode(IObject obj); +} Index: plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/Utils.java =================================================================== --- plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/Utils.java (revision 0) +++ plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/Utils.java (working copy) @@ -0,0 +1,118 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat Inc + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc - initial API and implementation + *******************************************************************************/ +package org.eclipse.mat.javaee; + +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +import org.eclipse.mat.SnapshotException; +import org.eclipse.mat.inspections.collections.CollectionUtil; +import org.eclipse.mat.inspections.collections.CollectionUtil.Info; +import org.eclipse.mat.snapshot.ISnapshot; +import org.eclipse.mat.snapshot.model.Field; +import org.eclipse.mat.snapshot.model.IClass; +import org.eclipse.mat.snapshot.model.IObject; +import org.eclipse.mat.snapshot.model.ObjectReference; +import org.eclipse.mat.util.VoidProgressListener; + +public final class Utils { + public static Integer max(int[] columnMapping) { + if (columnMapping == null || columnMapping.length == 0) + return null; + + int cur = columnMapping[0]; + for (int i = 0; i < columnMapping.length; i++) { + if (columnMapping[i] > cur) + cur = columnMapping[i]; + } + return cur; + } + + public static IObject resolveIObject(IObject o, String field, String... fields) throws SnapshotException { + IObject cur = (IObject)o.resolveValue(field); + for (int i = 0; i < fields.length && cur != null; i++) { + cur = (IObject)cur.resolveValue(fields[i]); + } + return cur; + } + + // only works if a.equals(b) = (a == b) + public static IObject resolveMapValueByKeyIdentity(IObject map, IObject key) throws SnapshotException { + for (Map.Entry entry: iterateMap(map)) { + if (entry.getKey().equals(key)) + return entry.getValue(); + } + return null; + } + + public static Iterable> iterateMap(IObject map) throws SnapshotException { + final Info info = CollectionUtil.getInfo(map); + final String keyField = info.getEntryKeyField(); + final String valueField = info.getEntryValueField(); + final ISnapshot snapshot = map.getSnapshot(); + final int[] entries = info.getCollectionExtractor().extractEntries(map.getObjectId(), info, snapshot, new VoidProgressListener()); + + final Iterator iter = new IntArrayList(entries).iterator(); + return new Iterable>() { + public Iterator> iterator() { + return new Iterator>() { + public Map.Entry next() { + Integer id = iter.next(); + + try { + IObject entry = snapshot.getObject(id); + final IObject key = resolveIObject(entry, keyField); + final IObject value = resolveIObject(entry, valueField); + return new Map.Entry() { + public IObject getKey() { + return key; + } + + public IObject getValue() { + return value; + } + + public IObject setValue(IObject value) { + throw new IllegalArgumentException(); + } + }; + } catch (SnapshotException e) { + throw new RuntimeException(e); + } + } + + public boolean hasNext() { + return iter.hasNext(); + } + + public void remove() { + throw new IllegalArgumentException(); + } + }; + } + }; + } + + public static IObject findStaticObjectField(IClass clazz, String fieldName) throws SnapshotException { + return ((ObjectReference)findStaticField(clazz, fieldName)).getObject(); + } + + public static Object findStaticField(IClass clazz, String fieldName) { + for (IClass c = clazz; c != null; c = c.getSuperClass()) { + for (Field f: c.getStaticFields()) { + if (f.getName().equals(fieldName)) + return f.getValue(); + } + } + return null; + } +} Index: plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/ejb/StatefulEjbQuery.java =================================================================== --- plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/ejb/StatefulEjbQuery.java (revision 0) +++ plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/ejb/StatefulEjbQuery.java (working copy) @@ -0,0 +1,250 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat Inc + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc - initial API and implementation + *******************************************************************************/ +package org.eclipse.mat.javaee.ejb; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.eclipse.mat.SnapshotException; +import org.eclipse.mat.javaee.GraftedResultTree; +import org.eclipse.mat.javaee.IOverviewNode; +import org.eclipse.mat.javaee.JavaEEPlugin; +import org.eclipse.mat.javaee.SimpleObjectQuery; +import org.eclipse.mat.javaee.ejb.api.StatefulEjbExtractor; +import org.eclipse.mat.javaee.impl.EjbExtractors; +import org.eclipse.mat.query.Column; +import org.eclipse.mat.query.IContextObject; +import org.eclipse.mat.query.IResultTree; +import org.eclipse.mat.query.annotations.Category; +import org.eclipse.mat.query.annotations.CommandName; +import org.eclipse.mat.query.annotations.Help; +import org.eclipse.mat.query.annotations.Name; +import org.eclipse.mat.snapshot.ISnapshot; +import org.eclipse.mat.snapshot.model.IClass; +import org.eclipse.mat.snapshot.model.IObject; +import org.eclipse.mat.snapshot.query.ObjectListResult; + +@Category("Enterprise Java/EJB") +@Name("Stateful EJBs") +@CommandName("javaee-ejb-stateful") +@Help("Shows Stateful EJBs") +public class StatefulEjbQuery extends SimpleObjectQuery { + private static final Column[] COLUMNS = { + new Column("Component", String.class), + new Column("Module", String.class), + new Column("Application", String.class), + new Column("Distinct Name", String.class), + new Column("Class", String.class), + new Column("Instances", Integer.class), + new Column("Size", Long.class), + }; + private static final int[] GRAFTED_COLUMN_MAPPING = {0, 1, -1, -1, -1, -1, -1, 2}; + + final static class StatefulEJbOverviewNode implements IOverviewNode { + private final IObject request; + // TODO: do we need to cache this? + private final StatefulEjbExtractor extractor; + + public StatefulEJbOverviewNode(IObject request) { + this.request = request; + this.extractor = EjbExtractors.getStatefulEjbExtractor(request); + } + + public long getRetainedHeap() { + return request.getRetainedHeapSize(); + } + + public int getId() { + return request.getObjectId(); + } + + private StatefulEjbExtractor getExtractor() { + return extractor; + } + + public String getComponentName() { + return getExtractor().getComponentName(request); + } + + public String getModuleName() { + return getExtractor().getModuleName(request); + } + + public String getApplicationName() { + return getExtractor().getApplicationName(request); + } + + public String getDistinctName() { + return getExtractor().getDistinctName(request); + } + + public IClass getComponentClass() { + return getExtractor().getComponentClass(request); + } + + public Integer getInstanceCount() { + return getExtractor().getInstanceCount(request); + } + + public Map getInstances() { + return getExtractor().getInstances(request); + } + } + + private static class StatefulEJbInstanceNode { + private final IObject key; + private final IObject instance; + + public StatefulEJbInstanceNode(IObject key, IObject instance) { + this.key = key; + this.instance = instance; + } + + public IObject getKey() { + return key; + } + + public IObject getInstance() { + return instance; + } + + public long getRetainedHeap() { + return instance.getRetainedHeapSize(); + } + } + + + public StatefulEjbQuery() { + super(StatefulEJbOverviewNode.class); + } + + protected List findObjects(ISnapshot snapshot) throws SnapshotException { + return EjbExtractors.findStatefulEjbs(snapshot); + } + + protected StatefulEJbOverviewNode createOverviewNode(IObject obj) { + return new StatefulEJbOverviewNode(obj); + } + + protected boolean overviewHasChildren(StatefulEJbOverviewNode row) { + return true; + } + + protected Column[] getColumns() { + return COLUMNS; + } + + @Override + protected Object getOverviewColumnValue(StatefulEJbOverviewNode row, int columnIndex) { + switch (columnIndex) { + case 0: + return row.getComponentName(); + case 1: + return row.getModuleName(); + case 2: + return row.getApplicationName(); + case 3: + return row.getDistinctName(); + case 4: + return row.getComponentClass().getName(); + case 5: + return row.getInstanceCount(); + case 6: + return row.getRetainedHeap(); + default: + return super.getOverviewColumnValue(row, columnIndex); + } + } + + @Override + protected List getOverviewChildren(StatefulEJbOverviewNode row) { + Map instances = row.getInstances(); + List results = new ArrayList(instances.size()); + for (Map.Entry i: instances.entrySet()) { + results.add(new StatefulEJbInstanceNode(i.getKey(), i.getValue())); + } + return results; + } + + + @Override + protected Object getColumnValue(Object row, int columnIndex) { + if (row instanceof StatefulEJbInstanceNode) { + StatefulEJbInstanceNode node = (StatefulEJbInstanceNode)row; + switch (columnIndex) { + case 0: + return node.getKey().getDisplayName(); + case 1: + return null; + case 2: + return null; + case 3: + return null; + case 4: + return node.getInstance(); + case 5: + return null; + case 6: + return node.getRetainedHeap(); + default: + JavaEEPlugin.error("Unexpected column index " + columnIndex); + return null; + } + } else { + return super.getColumnValue(row, columnIndex); + } + } + + + @Override + protected boolean hasChildren(Object row) { + if (row instanceof StatefulEJbInstanceNode) { + StatefulEJbInstanceNode node = (StatefulEJbInstanceNode) row; + return !node.getInstance().getOutboundReferences().isEmpty(); + } else { + return super.hasChildren(row); + } + } + + @Override + protected List getChildren(Object row) { + try { + if (row instanceof StatefulEJbInstanceNode) { + StatefulEJbInstanceNode node = (StatefulEJbInstanceNode) row; + // Create an outbound tree and graft it onto the main tree + IObject instance = node.getInstance(); + int[] outbounds = instance.getSnapshot().getOutboundReferentIds(instance.getObjectId()); + IResultTree subtree = new ObjectListResult.Outbound(instance.getSnapshot(), outbounds); + return GraftedResultTree.graft(subtree, instance, GRAFTED_COLUMN_MAPPING); + } else { + return super.getChildren(row); + } + } catch (SnapshotException e) { + JavaEEPlugin.error(e); + return null; + } + } + + @Override + protected IContextObject getContext(Object row) { + if (row instanceof StatefulEJbInstanceNode) { + final StatefulEJbInstanceNode node = (StatefulEJbInstanceNode) row; + return new IContextObject() { + public int getObjectId() { + return node.getInstance().getObjectId(); + } + }; + } else { + return super.getContext(row); + } + } +} Index: plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/ejb/api/StatefulEjbExtractor.java =================================================================== --- plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/ejb/api/StatefulEjbExtractor.java (revision 0) +++ plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/ejb/api/StatefulEjbExtractor.java (working copy) @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat Inc + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc - initial API and implementation + *******************************************************************************/ +package org.eclipse.mat.javaee.ejb.api; + +import java.util.Map; + +import org.eclipse.mat.snapshot.model.IClass; +import org.eclipse.mat.snapshot.model.IObject; + +public interface StatefulEjbExtractor { + String getComponentName(IObject request); + String getModuleName(IObject request); + String getApplicationName(IObject request); + String getDistinctName(IObject request); + IClass getComponentClass(IObject request); + Integer getInstanceCount(IObject request); + Map getInstances(IObject request); +} Index: plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/EjbExtractors.java =================================================================== --- plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/EjbExtractors.java (revision 0) +++ plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/EjbExtractors.java (working copy) @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat Inc + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc - initial API and implementation + *******************************************************************************/ +package org.eclipse.mat.javaee.impl; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.mat.SnapshotException; +import org.eclipse.mat.javaee.ejb.api.StatefulEjbExtractor; +import org.eclipse.mat.javaee.impl.ejb.jboss.JBossStatefulEjbExtractor; +import org.eclipse.mat.snapshot.ISnapshot; +import org.eclipse.mat.snapshot.model.IObject; + +public class EjbExtractors extends Extractors { + public static List findStatefulEjbs(ISnapshot snapshot) throws SnapshotException { + return findObjects(snapshot, STATEFUL_EJB_EXTRACTORS); + } + + public static StatefulEjbExtractor getStatefulEjbExtractor(IObject object) { + return getExtractor(object, STATEFUL_EJB_EXTRACTORS); + } + + + private static final Map STATEFUL_EJB_EXTRACTORS; + static { + STATEFUL_EJB_EXTRACTORS = new HashMap(); + STATEFUL_EJB_EXTRACTORS.put("org.jboss.as.ejb3.component.stateful.StatefulSessionComponent", new JBossStatefulEjbExtractor()); + } +} Index: plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/Extractors.java =================================================================== --- plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/Extractors.java (revision 0) +++ plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/Extractors.java (working copy) @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat Inc + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc - initial API and implementation + *******************************************************************************/ +package org.eclipse.mat.javaee.impl; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import org.eclipse.mat.SnapshotException; +import org.eclipse.mat.snapshot.ISnapshot; +import org.eclipse.mat.snapshot.model.IClass; +import org.eclipse.mat.snapshot.model.IObject; + +public class Extractors { + protected static List findObjects(ISnapshot snapshot, Map extractors) throws SnapshotException { + List ids = new ArrayList(); + for (String name: extractors.keySet()) { + Collection classes = snapshot.getClassesByName(name, true); + if (classes != null) { + for (IClass clazz : classes) { + for (int id: clazz.getObjectIds()) + ids.add(id); + } + } + } + return ids; + } + + protected static T getExtractor(IObject object, Map extractors) { + for (IClass klass = object.getClazz(); klass != null; klass = klass.getSuperClass()) { + T extractor = extractors.get(klass.getName()); + if (extractor != null) + return extractor; + } + return null; + } +} Index: plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/ServletExtractors.java =================================================================== --- plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/ServletExtractors.java (revision 0) +++ plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/ServletExtractors.java (working copy) @@ -0,0 +1,93 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat Inc + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc - initial API and implementation + *******************************************************************************/ +package org.eclipse.mat.javaee.impl; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.mat.SnapshotException; +import org.eclipse.mat.javaee.impl.servlet.GenericServletExtractor; +import org.eclipse.mat.javaee.impl.servlet.HttpServletExtractor; +import org.eclipse.mat.javaee.impl.servlet.catalina.CatalinaRequestExtractor; +import org.eclipse.mat.javaee.impl.servlet.catalina.CatalinaRequestFacadeExtractor; +import org.eclipse.mat.javaee.impl.servlet.catalina.CatalinaSessionExtractor; +import org.eclipse.mat.javaee.impl.servlet.catalina.CatalinaWrapperFacadeServletConfigExtractor; +import org.eclipse.mat.javaee.impl.servlet.catalina.CatalinaWrapperServletConfigExtractor; +import org.eclipse.mat.javaee.impl.servlet.jasper.JasperJspServletExtractor; +import org.eclipse.mat.javaee.impl.servlet.undertow.UndertowRequestExtractor; +import org.eclipse.mat.javaee.impl.servlet.undertow.UndertowServletConfigExtractor; +import org.eclipse.mat.javaee.impl.servlet.undertow.UndertowSessionExtractor; +import org.eclipse.mat.javaee.servlet.api.RequestExtractor; +import org.eclipse.mat.javaee.servlet.api.ServletConfigExtractor; +import org.eclipse.mat.javaee.servlet.api.ServletExtractor; +import org.eclipse.mat.javaee.servlet.api.SessionExtractor; +import org.eclipse.mat.snapshot.ISnapshot; +import org.eclipse.mat.snapshot.model.IObject; + +public class ServletExtractors extends Extractors { + public static List findHttpSessions(ISnapshot snapshot) throws SnapshotException { + return findObjects(snapshot, SESSION_EXTRACTORS); + } + + public static List findHttpRequests(ISnapshot snapshot) throws SnapshotException { + return findObjects(snapshot, REQUEST_EXTRACTORS); + } + + public static List findServlets(ISnapshot snapshot) throws SnapshotException { + return findObjects(snapshot, SERVLET_EXTRACTORS); + } + + public static SessionExtractor getSessionExtractor(IObject object) { + return getExtractor(object, SESSION_EXTRACTORS); + } + + public static RequestExtractor getRequestExtractor(IObject object) { + return getExtractor(object, REQUEST_EXTRACTORS); + } + + public static ServletExtractor getServletExtractor(IObject object) { + return getExtractor(object, SERVLET_EXTRACTORS); + } + + public static ServletConfigExtractor getServletConfigExtractor(IObject object) { + return getExtractor(object, SERVLET_CONFIG_EXTRACTORS); + } + + + + private static final Map SESSION_EXTRACTORS; + private static final Map REQUEST_EXTRACTORS; + private static final Map SERVLET_EXTRACTORS; + private static final Map SERVLET_CONFIG_EXTRACTORS; + static { + SESSION_EXTRACTORS = new HashMap(); + SESSION_EXTRACTORS.put("org.apache.catalina.session.StandardSession", new CatalinaSessionExtractor()); + SESSION_EXTRACTORS.put("org.jboss.web.tomcat.service.session.SessionBasedClusteredSession", new CatalinaSessionExtractor()); + SESSION_EXTRACTORS.put("io.undertow.server.session.InMemorySessionManager$InMemorySession", new UndertowSessionExtractor()); + + /* Keep this in sync with the annotations on HttpServletRequestResolver */ + REQUEST_EXTRACTORS = new HashMap(); + REQUEST_EXTRACTORS.put("org.apache.catalina.connector.Request", new CatalinaRequestExtractor()); + REQUEST_EXTRACTORS.put("org.apache.catalina.connector.RequestFacade", new CatalinaRequestFacadeExtractor()); + REQUEST_EXTRACTORS.put("io.undertow.servlet.spec.HttpServletRequestImpl", new UndertowRequestExtractor()); + + SERVLET_EXTRACTORS = new HashMap(); + SERVLET_EXTRACTORS.put("org.apache.jasper.runtime.HttpJspBase", new JasperJspServletExtractor()); + SERVLET_EXTRACTORS.put("javax.servlet.http.HttpServlet", new HttpServletExtractor()); + SERVLET_EXTRACTORS.put("javax.servlet.GenericServlet", new GenericServletExtractor()); + + SERVLET_CONFIG_EXTRACTORS = new HashMap(); + SERVLET_CONFIG_EXTRACTORS.put("io.undertow.servlet.spec.ServletConfigImpl", new UndertowServletConfigExtractor()); + SERVLET_CONFIG_EXTRACTORS.put("org.apache.catalina.core.StandardWrapperFacade", new CatalinaWrapperFacadeServletConfigExtractor()); + SERVLET_CONFIG_EXTRACTORS.put("org.apache.catalina.core.StandardWrapper", new CatalinaWrapperServletConfigExtractor()); + } +} Index: plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/ejb/jboss/JBossStatefulEjbExtractor.java =================================================================== --- plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/ejb/jboss/JBossStatefulEjbExtractor.java (revision 0) +++ plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/ejb/jboss/JBossStatefulEjbExtractor.java (working copy) @@ -0,0 +1,182 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat Inc + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc - initial API and implementation + *******************************************************************************/ +package org.eclipse.mat.javaee.impl.ejb.jboss; + +import static org.eclipse.mat.javaee.Utils.findStaticObjectField; +import static org.eclipse.mat.javaee.Utils.iterateMap; +import static org.eclipse.mat.javaee.Utils.resolveIObject; +import static org.eclipse.mat.javaee.Utils.resolveMapValueByKeyIdentity; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.mat.SnapshotException; +import org.eclipse.mat.inspections.collections.CollectionUtil; +import org.eclipse.mat.inspections.collections.CollectionUtil.Info; +import org.eclipse.mat.javaee.JavaEEPlugin; +import org.eclipse.mat.javaee.ejb.api.StatefulEjbExtractor; +import org.eclipse.mat.snapshot.model.IClass; +import org.eclipse.mat.snapshot.model.IObject; + +public class JBossStatefulEjbExtractor implements StatefulEjbExtractor { + public String getComponentName(IObject component) { + try { + return (resolveIObject(component, "componentName")).getClassSpecificName(); + } catch (SnapshotException e) { + JavaEEPlugin.error(e); + return null; + } + } + + public String getModuleName(IObject component) { + try { + return (resolveIObject(component, "moduleName")).getClassSpecificName(); + } catch (SnapshotException e) { + JavaEEPlugin.error(e); + return null; + } + } + + public String getApplicationName(IObject component) { + try { + return (resolveIObject(component, "applicationName")).getClassSpecificName(); + } catch (SnapshotException e) { + JavaEEPlugin.error(e); + return null; + } + } + + public String getDistinctName(IObject component) { + try { + return (resolveIObject(component, "distinctName")).getClassSpecificName(); + } catch (SnapshotException e) { + JavaEEPlugin.error(e); + return null; + } + } + + public IClass getComponentClass(IObject component) { + try { + return ((IClass)resolveIObject(component, "componentClass")); + } catch (SnapshotException e) { + JavaEEPlugin.error(e); + return null; + } + } + + public Integer getInstanceCount(IObject component) { + try { + IObject instanceMap = resolveInstanceMap(component); + if (instanceMap == null) + return null; + + return CollectionUtil.getInfo(instanceMap).getSize(instanceMap); + } catch (SnapshotException e) { + JavaEEPlugin.error(e); + return null; + } + } + + public Map getInstances(IObject component) { + try { + IObject instanceMap = resolveInstanceMap(component); + if (instanceMap == null) + return null; + + Info info = CollectionUtil.getInfo(instanceMap); + Map instances = new HashMap(info.getSize(instanceMap)); + for (Map.Entry entry: iterateMap(instanceMap)) { + IObject value = entry.getValue(); + final IObject instance; + if (value.getClazz().getName().equals("org.jboss.as.ejb3.cache.impl.backing.NonPassivatingBackingCacheEntry")) { + instance = getAS7Instance(value); + } else if (value.getClazz().getName().equals("org.jboss.as.ejb3.cache.simple.SimpleCache$Entry")) { + instance = getWildfly8Instance(value); + } else { + JavaEEPlugin.warning("Unexpected cahce entry class: " + value.getClazz().getName()); + continue; + } + + instances.put(entry.getKey(), instance); + } + return instances; + } catch (SnapshotException e) { + JavaEEPlugin.error(e); + return null; + } + } + + private IObject resolveInstanceMap(IObject component) { + try { + IObject cache = resolveIObject(component, "cache"); + String cacheClassName = cache.getClazz().getName(); + if (cacheClassName.equals("org.jboss.as.ejb3.cache.impl.SimpleCache")) { + return resolveAS7InstanceMap(cache); + } else if (cacheClassName.equals("org.jboss.as.ejb3.cache.simple.SimpleCache")) { + return resolveWildfly8InstanceMap(cache); + } else { + JavaEEPlugin.error("Unexpected cache class: " + cache.getClazz().getName()); + return null; + } + } catch (SnapshotException e) { + JavaEEPlugin.error(e); + return null; + } + } + + private IObject resolveAS7InstanceMap(IObject cache) throws SnapshotException { + IObject backingCache = resolveIObject(cache, "backingCache"); + if (!backingCache.getClazz().getName().equals("org.jboss.as.ejb3.cache.impl.backing.NonPassivatingBackingCacheImpl")) { + JavaEEPlugin.error("Unexpected backing cache class: " + backingCache.getClazz().getName()); + return null; + } + + return resolveIObject(backingCache, "cache"); + } + + private IObject getAS7Instance(IObject value) throws SnapshotException { + IObject componentInstance = resolveIObject(value, "wrapped"); + if (!componentInstance.getClazz().getName().equals("org.jboss.as.ejb3.component.stateful.StatefulSessionComponentInstance")) { + JavaEEPlugin.warning("Unexpected wrapper class: " + componentInstance.getClazz().getName()); + return null; + } + return resolveIObject(componentInstance, "instanceReference", "value", "instance"); + } + + private IObject resolveWildfly8InstanceMap(IObject cache) throws SnapshotException { + return resolveIObject(cache, "entries"); + } + + private IObject getWildfly8Instance(IObject value) throws SnapshotException { + IObject componentInstance = resolveIObject(value, "value"); + if (!componentInstance.getClazz().getName().equals("org.jboss.as.ejb3.component.stateful.StatefulSessionComponentInstance")) { + JavaEEPlugin.warning("Unexpected wrapper class: " + componentInstance.getClazz().getName()); + return null; + } + IObject data = resolveIObject(componentInstance, "instanceData"); + IObject classBasicComponentInstanceKey = findStaticObjectField(componentInstance.getClazz(), "INSTANCE_KEY"); + return extractWildflyManagedReference(resolveMapValueByKeyIdentity(data, classBasicComponentInstanceKey)); + } + + private IObject extractWildflyManagedReference(IObject ref) throws SnapshotException { + String className = ref.getClazz().getName(); + if (className.equals("org.jboss.as.weld.injection.WeldManagedReferenceFactory$WeldManagedReference")) { + return resolveIObject(ref, "instance"); + } else if (className.equals("org.jboss.as.ejb3.timerservice.TimerServiceBindingSource$TimerServiceManagedReference")) { + // this requires invoking code at runtime, can't do it. + JavaEEPlugin.info("Cannot extract from TimerServiceManagedReference"); + return null; + } else { + JavaEEPlugin.warning("Unexpected reference class" + className); + return null; + } + } +} Index: plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/servlet/GenericServletExtractor.java =================================================================== --- plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/servlet/GenericServletExtractor.java (revision 0) +++ plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/servlet/GenericServletExtractor.java (working copy) @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat Inc + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc - initial API and implementation + *******************************************************************************/ +package org.eclipse.mat.javaee.impl.servlet; + +import org.eclipse.mat.javaee.JavaEEPlugin; +import org.eclipse.mat.javaee.servlet.api.ServletExtractor; +import org.eclipse.mat.snapshot.model.IObject; + +public class GenericServletExtractor implements ServletExtractor { + public String getName(IObject object) { + JavaEEPlugin.warning("Do not know how to get name for " + object.getDisplayName()); + return "- Unknown -"; + } + + public String getServletClass(IObject object) { + return object.getClazz().getName(); + } +} Index: plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/servlet/HttpServletExtractor.java =================================================================== --- plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/servlet/HttpServletExtractor.java (revision 0) +++ plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/servlet/HttpServletExtractor.java (working copy) @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat Inc + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc - initial API and implementation + *******************************************************************************/ +package org.eclipse.mat.javaee.impl.servlet; + +import static org.eclipse.mat.javaee.Utils.resolveIObject; + +import org.eclipse.mat.SnapshotException; +import org.eclipse.mat.javaee.JavaEEPlugin; +import org.eclipse.mat.javaee.impl.ServletExtractors; +import org.eclipse.mat.javaee.servlet.api.ServletConfigExtractor; +import org.eclipse.mat.snapshot.model.IObject; + +public class HttpServletExtractor extends GenericServletExtractor { + @Override + public String getName(IObject object) { + try { + IObject config = resolveIObject(object, "config"); + if (config == null) { + JavaEEPlugin.warning("Did not find servlet config for " + object.getDisplayName()); + return null; + } + ServletConfigExtractor extractor = ServletExtractors.getServletConfigExtractor(config); + return (extractor != null) ? extractor.getName(config) : null; + } catch (SnapshotException e) { + JavaEEPlugin.error(e); + return null; + } + } +} Index: plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/servlet/catalina/CatalinaRequestExtractor.java =================================================================== --- plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/servlet/catalina/CatalinaRequestExtractor.java (revision 0) +++ plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/servlet/catalina/CatalinaRequestExtractor.java (working copy) @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat Inc + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc - initial API and implementation + *******************************************************************************/ +package org.eclipse.mat.javaee.impl.servlet.catalina; + +import static org.eclipse.mat.javaee.Utils.resolveIObject; + +import java.io.UnsupportedEncodingException; +import java.util.Arrays; + +import org.eclipse.mat.SnapshotException; +import org.eclipse.mat.javaee.JavaEEPlugin; +import org.eclipse.mat.javaee.servlet.api.RequestExtractor; +import org.eclipse.mat.snapshot.model.IObject; +import org.eclipse.mat.snapshot.model.IPrimitiveArray; + +public class CatalinaRequestExtractor implements RequestExtractor { + public String getRequestUri(IObject request) { + try { + IObject decodedURI = resolveIObject(request, "coyoteRequest", "decodedUriMB"); + String uri = helperMessageBytesToString(decodedURI); + if (uri != null) + return uri; + + // not in use + return null; + } catch (SnapshotException e) { + JavaEEPlugin.warning("Unable to resolve URI", e); + return null; + } + } + + public boolean isInUse(IObject request) { + try { + IObject context = resolveIObject(request, "context"); + return context != null; + } catch (SnapshotException e) { + JavaEEPlugin.warning("Unable to request context", e); + return false; + } + } + + /* helpers*/ + + private String helperMessageBytesToString(IObject uri) throws SnapshotException { + if (((Boolean) uri.resolveValue("hasStrValue")).booleanValue()) { + return ((IObject)uri.resolveValue("strValue")).toString(); + } + + int type = ((Integer)uri.resolveValue("type")).intValue(); + switch (type) { + case 3: + return helperCharChunkToString(resolveIObject(uri, "charC")); + case 2: + return helperByteChunkToString(resolveIObject(uri, "byteC")); + case 0: + // unused + return null; + default: + JavaEEPlugin.warning("Unexpected Catalina message bytes type " + type); + return null; + } + } + + private String helperCharChunkToString(IObject chunk) throws SnapshotException { + Object ex = extractFromChunk(chunk); + if (ex instanceof String) { + return (String)ex; + } else if (ex instanceof char[]) { + char[] buff = (char[])ex; + return new String(buff); + } else { + JavaEEPlugin.error("Unexpected chunk class " + ex.getClass().getName()); + return null; + } + } + + private String helperByteChunkToString(IObject chunk) throws SnapshotException { + byte[] buff = (byte[])extractFromChunk(chunk); + + IObject enc = resolveIObject(chunk, "enc"); + final String encoding; + if (enc == null) { + encoding = "ISO-8859-1"; + } else { + encoding = enc.getClassSpecificName(); + } + + try { + return new String(buff, 0, buff.length, encoding); + } catch (UnsupportedEncodingException e) { + return "Undecodable buffer (" + encoding + "):" + Arrays.toString(buff); + } + } + + private Object extractFromChunk(IObject chunk) throws SnapshotException { + IPrimitiveArray buff = (IPrimitiveArray)chunk.resolveValue("buff"); + if (buff == null) + return null; + + int start = (Integer)chunk.resolveValue("start"); + int end = (Integer)chunk.resolveValue("end"); + + if (start == end) + return ""; + + return buff.getValueArray(start, end - start); + } +} Index: plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/servlet/catalina/CatalinaRequestFacadeExtractor.java =================================================================== --- plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/servlet/catalina/CatalinaRequestFacadeExtractor.java (revision 0) +++ plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/servlet/catalina/CatalinaRequestFacadeExtractor.java (working copy) @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat Inc + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc - initial API and implementation + *******************************************************************************/ +package org.eclipse.mat.javaee.impl.servlet.catalina; + +import static org.eclipse.mat.javaee.Utils.resolveIObject; + +import org.eclipse.mat.SnapshotException; +import org.eclipse.mat.javaee.JavaEEPlugin; +import org.eclipse.mat.javaee.impl.ServletExtractors; +import org.eclipse.mat.javaee.servlet.api.RequestExtractor; +import org.eclipse.mat.snapshot.model.IObject; + +public class CatalinaRequestFacadeExtractor implements RequestExtractor { + public String getRequestUri(IObject requestFacade) { + IObject root = findRootRequest(requestFacade); + return "Wrapper: " + ServletExtractors.getRequestExtractor(root).getRequestUri(root); + } + + public boolean isInUse(IObject requestFacade) { + IObject root = findRootRequest(requestFacade); + return ServletExtractors.getRequestExtractor(root).isInUse(root); + } + + private IObject findRootRequest(IObject requestFacade) { + try { + for(IObject current = requestFacade;;) { + IObject baseRequest = resolveIObject(current, "request"); + String className = baseRequest.getClazz().getName(); + if (className.equals("org.apache.catalina.connector.RequestFacade")) + current = baseRequest; + else if (className.equals("org.apache.catalina.connector.Request")) { + return baseRequest; + } else + JavaEEPlugin.error("unhandled class: " + className); + return null; + } + } catch (SnapshotException e) { + JavaEEPlugin.error(e); + return null; + } + } +} Index: plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/servlet/catalina/CatalinaSessionExtractor.java =================================================================== --- plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/servlet/catalina/CatalinaSessionExtractor.java (revision 0) +++ plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/servlet/catalina/CatalinaSessionExtractor.java (working copy) @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat Inc + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc - initial API and implementation + *******************************************************************************/ +package org.eclipse.mat.javaee.impl.servlet.catalina; + +import static org.eclipse.mat.javaee.Utils.iterateMap; +import static org.eclipse.mat.javaee.Utils.resolveIObject; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.eclipse.mat.SnapshotException; +import org.eclipse.mat.inspections.collections.CollectionUtil; +import org.eclipse.mat.inspections.collections.CollectionUtil.Info; +import org.eclipse.mat.javaee.JavaEEPlugin; +import org.eclipse.mat.javaee.servlet.api.SessionAttributeData; +import org.eclipse.mat.javaee.servlet.api.SessionExtractor; +import org.eclipse.mat.snapshot.ISnapshot; +import org.eclipse.mat.snapshot.model.IObject; +import org.eclipse.mat.util.VoidProgressListener; + +public class CatalinaSessionExtractor implements SessionExtractor { + // accessCount, thisAccessedTime, principal, notes, isValid, isNew, maxInactiveInterval, manager, listeners, lastAccessedTime, id, facade, expiring, creationTime, authType + + public List buildSessionAttributes(IObject object) { + try { + IObject attrs = resolveIObject(object, "attributes"); + Info mapInfo = CollectionUtil.getInfo(attrs); + String keyField = mapInfo.getEntryKeyField(); + String valueField = mapInfo.getEntryValueField(); + ISnapshot snapshot = object.getSnapshot(); + + ArrayList results = new ArrayList(); + + for (Map.Entry entry: iterateMap(attrs)) { + results.add(new SessionAttributeData(entry.getKey(), entry.getValue())); + } + + return results; + } catch (SnapshotException e) { + JavaEEPlugin.warning("Unable to list session attributes",e); + return new ArrayList(); + } + } + + public String getSessionId(IObject object) { + try { + return resolveIObject(object, "id").getClassSpecificName(); + } catch (SnapshotException e) { + JavaEEPlugin.warning("Unable to resolve id", e); + return null; + } + } +} Index: plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/servlet/catalina/CatalinaWrapperFacadeServletConfigExtractor.java =================================================================== --- plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/servlet/catalina/CatalinaWrapperFacadeServletConfigExtractor.java (revision 0) +++ plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/servlet/catalina/CatalinaWrapperFacadeServletConfigExtractor.java (working copy) @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat Inc + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc - initial API and implementation + *******************************************************************************/ +package org.eclipse.mat.javaee.impl.servlet.catalina; + +import static org.eclipse.mat.javaee.Utils.resolveIObject; + +import org.eclipse.mat.SnapshotException; +import org.eclipse.mat.javaee.JavaEEPlugin; +import org.eclipse.mat.javaee.impl.ServletExtractors; +import org.eclipse.mat.javaee.servlet.api.ServletConfigExtractor; +import org.eclipse.mat.snapshot.model.IObject; + +public class CatalinaWrapperFacadeServletConfigExtractor implements ServletConfigExtractor { + public String getName(IObject config) { + try { + IObject wrapper = resolveIObject(config, "wrapper"); + if (wrapper != null) + return ServletExtractors.getServletConfigExtractor(wrapper).getName(wrapper); + + IObject subconfig = resolveIObject(config, "config"); + if (subconfig != null) + return ServletExtractors.getServletConfigExtractor(subconfig).getName(subconfig); + + JavaEEPlugin.warning("Unhandled Cataline wrapper facade " + config.getDisplayName()); + return null; + } catch (SnapshotException e) { + JavaEEPlugin.error(e); + return null; + } + } +} Index: plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/servlet/catalina/CatalinaWrapperServletConfigExtractor.java =================================================================== --- plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/servlet/catalina/CatalinaWrapperServletConfigExtractor.java (revision 0) +++ plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/servlet/catalina/CatalinaWrapperServletConfigExtractor.java (working copy) @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat Inc + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc - initial API and implementation + *******************************************************************************/ +package org.eclipse.mat.javaee.impl.servlet.catalina; + +import static org.eclipse.mat.javaee.Utils.resolveIObject; + +import org.eclipse.mat.SnapshotException; +import org.eclipse.mat.javaee.JavaEEPlugin; +import org.eclipse.mat.javaee.servlet.api.ServletConfigExtractor; +import org.eclipse.mat.snapshot.model.IObject; + +public class CatalinaWrapperServletConfigExtractor implements ServletConfigExtractor { + public String getName(IObject config) { + try { + return resolveIObject(config, "name").getClassSpecificName(); + } catch (SnapshotException e) { + JavaEEPlugin.error(e); + return null; + } + } +} Index: plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/servlet/jasper/JasperJspServletExtractor.java =================================================================== --- plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/servlet/jasper/JasperJspServletExtractor.java (revision 0) +++ plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/servlet/jasper/JasperJspServletExtractor.java (working copy) @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat Inc + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc - initial API and implementation + *******************************************************************************/ +package org.eclipse.mat.javaee.impl.servlet.jasper; + +import org.eclipse.mat.javaee.JavaEEPlugin; +import org.eclipse.mat.javaee.impl.servlet.HttpServletExtractor; +import org.eclipse.mat.snapshot.model.IObject; + + +public class JasperJspServletExtractor extends HttpServletExtractor { + private static final String JSP_CLASS_PREFIX = "org.apache.jsp."; + + @Override + public String getName(IObject object) { + return getServletClass(object); + } + + @Override + public String getServletClass(IObject object) { + String className = super.getServletClass(object); + if (!className.startsWith(JSP_CLASS_PREFIX)) { + JavaEEPlugin.warning("Unhandled JSP class prefix: " + className); + return className; + } + + return "JSP: " + className.substring(JSP_CLASS_PREFIX.length()).replace('.', '/').replace('_', '.'); + } + +} Index: plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/servlet/undertow/UndertowRequestExtractor.java =================================================================== --- plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/servlet/undertow/UndertowRequestExtractor.java (revision 0) +++ plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/servlet/undertow/UndertowRequestExtractor.java (working copy) @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat Inc + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc - initial API and implementation + *******************************************************************************/ +package org.eclipse.mat.javaee.impl.servlet.undertow; + +import static org.eclipse.mat.javaee.Utils.resolveIObject; + +import org.eclipse.mat.SnapshotException; +import org.eclipse.mat.javaee.JavaEEPlugin; +import org.eclipse.mat.javaee.servlet.api.RequestExtractor; +import org.eclipse.mat.snapshot.model.IObject; + +public class UndertowRequestExtractor implements RequestExtractor { + public String getRequestUri(IObject request) { + try { + return resolveIObject(request, "exchange", "requestURI").getClassSpecificName(); + } catch (SnapshotException e) { + JavaEEPlugin.error(e); + return null; + } + } + + public boolean isInUse(IObject request) { + return true; + } +} Index: plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/servlet/undertow/UndertowServletConfigExtractor.java =================================================================== --- plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/servlet/undertow/UndertowServletConfigExtractor.java (revision 0) +++ plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/servlet/undertow/UndertowServletConfigExtractor.java (working copy) @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat Inc + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc - initial API and implementation + *******************************************************************************/ +package org.eclipse.mat.javaee.impl.servlet.undertow; + +import static org.eclipse.mat.javaee.Utils.resolveIObject; + +import org.eclipse.mat.SnapshotException; +import org.eclipse.mat.javaee.JavaEEPlugin; +import org.eclipse.mat.javaee.servlet.api.ServletConfigExtractor; +import org.eclipse.mat.snapshot.model.IObject; + +public class UndertowServletConfigExtractor implements ServletConfigExtractor { + public String getName(IObject config) { + try { + IObject info = resolveIObject(config, "servletInfo"); + if (info == null) { + JavaEEPlugin.warning("Missing 'servletInfo' field from class " + config.getClazz().getName()); + return null; + } + + return resolveIObject(info, "name").getClassSpecificName(); + } catch (SnapshotException e) { + JavaEEPlugin.error(e); + return null; + } + } + +} Index: plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/servlet/undertow/UndertowSessionExtractor.java =================================================================== --- plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/servlet/undertow/UndertowSessionExtractor.java (revision 0) +++ plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/impl/servlet/undertow/UndertowSessionExtractor.java (working copy) @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat Inc + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc - initial API and implementation + *******************************************************************************/ +package org.eclipse.mat.javaee.impl.servlet.undertow; + +import static org.eclipse.mat.javaee.Utils.iterateMap; +import static org.eclipse.mat.javaee.Utils.resolveIObject; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.eclipse.mat.SnapshotException; +import org.eclipse.mat.inspections.collections.CollectionUtil; +import org.eclipse.mat.inspections.collections.CollectionUtil.Info; +import org.eclipse.mat.javaee.JavaEEPlugin; +import org.eclipse.mat.javaee.servlet.api.SessionAttributeData; +import org.eclipse.mat.javaee.servlet.api.SessionExtractor; +import org.eclipse.mat.snapshot.model.IObject; + +public class UndertowSessionExtractor implements SessionExtractor { + public List buildSessionAttributes(IObject session) { + try { + IObject attrs = resolveIObject(session, "attributes"); + Info info = CollectionUtil.getInfo(attrs); + + List nodes = new ArrayList(info.getSize(attrs)); + for (Map.Entry entry: iterateMap(attrs)) { + nodes.add(new SessionAttributeData(entry.getKey(), entry.getValue())); + } + return nodes; + } catch (SnapshotException e) { + JavaEEPlugin.error(e); + return null; + } + } + + public String getSessionId(IObject session) { + try { + return resolveIObject(session, "session", "sessionId").getClassSpecificName(); + } catch (SnapshotException e) { + JavaEEPlugin.error(e); + return null; + } + } +} Index: plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/servlet/api/RequestExtractor.java =================================================================== --- plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/servlet/api/RequestExtractor.java (revision 0) +++ plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/servlet/api/RequestExtractor.java (working copy) @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat Inc + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc - initial API and implementation + *******************************************************************************/ +package org.eclipse.mat.javaee.servlet.api; + +import org.eclipse.mat.snapshot.model.IObject; + +public interface RequestExtractor { + //List buildRequestAttributes(IObject object); + String getRequestUri(IObject request); + + boolean isInUse(IObject request); +} Index: plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/servlet/api/ServletConfigExtractor.java =================================================================== --- plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/servlet/api/ServletConfigExtractor.java (revision 0) +++ plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/servlet/api/ServletConfigExtractor.java (working copy) @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat Inc + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc - initial API and implementation + *******************************************************************************/ +package org.eclipse.mat.javaee.servlet.api; + +import org.eclipse.mat.snapshot.model.IObject; + +public interface ServletConfigExtractor { + String getName(IObject config); +} Index: plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/servlet/api/ServletExtractor.java =================================================================== --- plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/servlet/api/ServletExtractor.java (revision 0) +++ plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/servlet/api/ServletExtractor.java (working copy) @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat Inc + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc - initial API and implementation + *******************************************************************************/ +package org.eclipse.mat.javaee.servlet.api; + +import org.eclipse.mat.snapshot.model.IObject; + +public interface ServletExtractor { + String getName(IObject object); + String getServletClass(IObject object); +} Index: plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/servlet/api/SessionAttributeData.java =================================================================== --- plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/servlet/api/SessionAttributeData.java (revision 0) +++ plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/servlet/api/SessionAttributeData.java (working copy) @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat Inc + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc - initial API and implementation + *******************************************************************************/ +package org.eclipse.mat.javaee.servlet.api; + +import org.eclipse.mat.snapshot.model.IObject; + +public class SessionAttributeData { + private final IObject key; + private final IObject value; + + public SessionAttributeData(IObject key, IObject value) { + this.key = key; + this.value = value; + } + + public IObject getKey() { + return key; + } + + public IObject getValue() { + return value; + } +} \ No newline at end of file Index: plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/servlet/api/SessionExtractor.java =================================================================== --- plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/servlet/api/SessionExtractor.java (revision 0) +++ plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/servlet/api/SessionExtractor.java (working copy) @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat Inc + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc - initial API and implementation + *******************************************************************************/ +package org.eclipse.mat.javaee.servlet.api; + +import java.util.List; + +import org.eclipse.mat.snapshot.model.IObject; + +public interface SessionExtractor { + List buildSessionAttributes(IObject object); + String getSessionId(IObject object); +} Index: plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/servlet/query/HttpRequestQuery.java =================================================================== --- plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/servlet/query/HttpRequestQuery.java (revision 0) +++ plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/servlet/query/HttpRequestQuery.java (working copy) @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat Inc + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc - initial API and implementation + *******************************************************************************/ +package org.eclipse.mat.javaee.servlet.query; + +import java.util.List; + +import org.eclipse.mat.SnapshotException; +import org.eclipse.mat.javaee.IOverviewNode; +import org.eclipse.mat.javaee.SimpleObjectQuery; +import org.eclipse.mat.javaee.impl.ServletExtractors; +import org.eclipse.mat.query.Column; +import org.eclipse.mat.query.annotations.Category; +import org.eclipse.mat.query.annotations.CommandName; +import org.eclipse.mat.query.annotations.Help; +import org.eclipse.mat.query.annotations.Name; +import org.eclipse.mat.snapshot.ISnapshot; +import org.eclipse.mat.snapshot.model.IObject; + +@Category("Enterprise Java/Web") +@Name("HTTP Requests") +@CommandName("javaee-http-requests") +@Help("Shows HTTP requests") +public class HttpRequestQuery extends SimpleObjectQuery { + private static final Column[] COLUMNS = { + new Column("Name", String.class), + new Column("Value", Object.class), + new Column("Size", Long.class), + }; + + + final static class RequestOverviewNode implements IOverviewNode { + private final IObject request; + + public RequestOverviewNode(IObject request) { + this.request = request; + } + + public long getRetainedHeap() { + return request.getRetainedHeapSize(); + } + + public int getId() { + return request.getObjectId(); + } + + public String getUri() { + return ServletExtractors.getRequestExtractor(request).getRequestUri(request); + } + + public boolean isInUse() { + return ServletExtractors.getRequestExtractor(request).isInUse(request); + } + } + + + + public HttpRequestQuery() { + super(RequestOverviewNode.class); + } + + protected List findObjects(ISnapshot snapshot) throws SnapshotException { + return ServletExtractors.findHttpRequests(snapshot); + } + + protected RequestOverviewNode createOverviewNode(IObject obj) { + return new RequestOverviewNode(obj); + } + + protected boolean overviewHasChildren(RequestOverviewNode row) { + return false; + } + + protected Column[] getColumns() { + return COLUMNS; + } + + @Override + protected Object getOverviewColumnValue(RequestOverviewNode row, int columnIndex) { + boolean inUse = row.isInUse(); + switch (columnIndex) { + case 0: + if (inUse) + return row.getUri(); + else + return "- Not in use -"; + case 1: + return null; + case 2: + return row.getRetainedHeap(); + default: + return super.getOverviewColumnValue(row, columnIndex); + } + } +} Index: plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/servlet/query/HttpSessionAttributesQuery.java =================================================================== --- plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/servlet/query/HttpSessionAttributesQuery.java (revision 0) +++ plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/servlet/query/HttpSessionAttributesQuery.java (working copy) @@ -0,0 +1,229 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat Inc + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc - initial API and implementation + *******************************************************************************/ +package org.eclipse.mat.javaee.servlet.query; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.mat.SnapshotException; +import org.eclipse.mat.javaee.BaseObjectQuery; +import org.eclipse.mat.javaee.GraftedResultTree; +import org.eclipse.mat.javaee.IOverviewNode; +import org.eclipse.mat.javaee.JavaEEPlugin; +import org.eclipse.mat.javaee.impl.ServletExtractors; +import org.eclipse.mat.javaee.servlet.api.SessionAttributeData; +import org.eclipse.mat.javaee.servlet.api.SessionExtractor; +import org.eclipse.mat.query.Column; +import org.eclipse.mat.query.IContextObject; +import org.eclipse.mat.query.IResultTree; +import org.eclipse.mat.query.annotations.Category; +import org.eclipse.mat.query.annotations.CommandName; +import org.eclipse.mat.query.annotations.Help; +import org.eclipse.mat.query.annotations.Name; +import org.eclipse.mat.snapshot.ISnapshot; +import org.eclipse.mat.snapshot.model.IObject; +import org.eclipse.mat.snapshot.query.ObjectListResult; + +@Category("Enterprise Java/Web") +@Name("HTTP Session attributes") +@CommandName("javaee-http-session-attributes") +@Help("Shows HTTP session attributes") +public class HttpSessionAttributesQuery extends BaseObjectQuery { + private static final Column[] COLUMNS = { + new Column("Name", String.class), + new Column("Value", Object.class), + new Column("Size", Long.class), + }; + private static final int[] GRAFTED_COLUMN_MAPPING = {0, 1, 2}; + + + private static class SessionAttributeNode { + public Map sessionValues = new HashMap(); + @SuppressWarnings("unused") public long retainedHeap = 0; + }; + + final static class SessionAttributeOverviewNode implements IOverviewNode { + private final IObject object; + private SessionAttributeNode data = null; + + public SessionAttributeOverviewNode(IObject object, SessionAttributeNode data) { + this.object = object; + this.data = data; + } + + public int getId() { + return object.getObjectId(); + } + + public long getRetainedHeap() { + return object.getRetainedHeapSize(); + } + + public String getName() { + return object.getClassSpecificName(); + } + + public List getSessionValues() { + List values = new ArrayList(); + for (Map.Entry e: data.sessionValues.entrySet()) { + values.add(new SessionAttributeValueNode(e.getKey(), e.getValue())); + } + return values; + } + } + + private static class SessionAttributeValueNode { + private final String sessionId; + private final IObject value; + + public SessionAttributeValueNode(String sessionId, IObject value) { + this.sessionId = sessionId; + this.value = value; + } + + public String getSessionId() { + return sessionId; + } + + public IObject getValue() { + return value; + } + + }; + + + + public HttpSessionAttributesQuery() { + super(SessionAttributeOverviewNode.class); + } + + protected List findObjects(ISnapshot snapshot) throws SnapshotException { + return ServletExtractors.findHttpSessions(snapshot); + } + + protected List buildResults(List source) throws SnapshotException { + Map attributes = new HashMap(); + + for (int id: source) { + IObject obj = snapshot.getObject(id); + SessionExtractor extractor = ServletExtractors.getSessionExtractor(obj); + if (extractor != null) { + final String sessionId = extractor.getSessionId(obj); + for (SessionAttributeData data: extractor.buildSessionAttributes(obj)) { + SessionAttributeNode node = attributes.get(data.getKey()); + if (node == null) { + node = new SessionAttributeNode(); + attributes.put(data.getKey(), node); + } + node.sessionValues.put(sessionId, data.getValue()); + node.retainedHeap += data.getValue().getRetainedHeapSize(); + } + } + } + + List results = new ArrayList(attributes.size()); + for (Map.Entry e: attributes.entrySet()) { + results.add(new SessionAttributeOverviewNode(e.getKey(), e.getValue())); + } + return results; + } + + protected boolean overviewHasChildren(SessionAttributeOverviewNode row) { + return true; + } + + protected Column[] getColumns() { + return COLUMNS; + } + + @Override + protected Object getOverviewColumnValue(SessionAttributeOverviewNode row, int columnIndex) { + switch (columnIndex) { + case 0: + return row.getName(); + case 1: + return null; + case 2: + return row.getRetainedHeap(); + default: + return super.getOverviewColumnValue(row, columnIndex); + } + } + + @Override + protected Object getColumnValue(Object row, int columnIndex) { + if (row instanceof SessionAttributeValueNode) { + SessionAttributeValueNode node = (SessionAttributeValueNode)row; + switch (columnIndex) { + case 0: + return node.getSessionId(); + case 1: + return node.getValue(); + case 2: + return node.getValue().getRetainedHeapSize(); + default: + JavaEEPlugin.error("Unexpected column index " + columnIndex); + return null; + } + } else { + return super.getColumnValue(row, columnIndex); + } + } + + @Override + protected List getOverviewChildren(SessionAttributeOverviewNode row) { + return row.getSessionValues(); + } + + @Override + protected boolean hasChildren(Object row) { + if (row instanceof SessionAttributeValueNode) { + SessionAttributeValueNode node = (SessionAttributeValueNode) row; + return !node.getValue().getOutboundReferences().isEmpty(); + } else { + return super.hasChildren(row); + } + } + + @Override + protected List getChildren(Object row) { + try { + if (row instanceof SessionAttributeValueNode) { + SessionAttributeValueNode node = (SessionAttributeValueNode) row; + // Create an outbound tree and graft it onto the main tree + int[] outbounds = node.getValue().getSnapshot().getOutboundReferentIds(node.getValue().getObjectId()); + IResultTree subtree = new ObjectListResult.Outbound(node.getValue().getSnapshot(), outbounds); + return GraftedResultTree.graft(subtree, node.getValue(), GRAFTED_COLUMN_MAPPING); + } else { + return super.getChildren(row); + } + } catch (SnapshotException e) { + JavaEEPlugin.error(e); + return null; + } + } + + @Override + protected IContextObject getContext(Object row) { + if (row instanceof SessionAttributeValueNode) { + final SessionAttributeValueNode node = (SessionAttributeValueNode) row; + return new IContextObject() { + public int getObjectId() { + return node.getValue().getObjectId(); + } + }; + } else { + return super.getContext(row); + } + } +} Index: plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/servlet/query/HttpSessionQuery.java =================================================================== --- plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/servlet/query/HttpSessionQuery.java (revision 0) +++ plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/servlet/query/HttpSessionQuery.java (working copy) @@ -0,0 +1,176 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat Inc + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc - initial API and implementation + *******************************************************************************/ +package org.eclipse.mat.javaee.servlet.query; + +import java.util.List; + +import org.eclipse.mat.SnapshotException; +import org.eclipse.mat.javaee.GraftedResultTree; +import org.eclipse.mat.javaee.IOverviewNode; +import org.eclipse.mat.javaee.JavaEEPlugin; +import org.eclipse.mat.javaee.SimpleObjectQuery; +import org.eclipse.mat.javaee.impl.ServletExtractors; +import org.eclipse.mat.javaee.servlet.api.SessionAttributeData; +import org.eclipse.mat.query.Column; +import org.eclipse.mat.query.IContextObject; +import org.eclipse.mat.query.IResultTree; +import org.eclipse.mat.query.annotations.Category; +import org.eclipse.mat.query.annotations.CommandName; +import org.eclipse.mat.query.annotations.Help; +import org.eclipse.mat.query.annotations.Name; +import org.eclipse.mat.snapshot.ISnapshot; +import org.eclipse.mat.snapshot.model.IObject; +import org.eclipse.mat.snapshot.query.ObjectListResult; + +@Category("Enterprise Java/Web") +@Name("HTTP Sessions") +@CommandName("javaee-http-sessions") +@Help("Shows HTTP sessions") +public class HttpSessionQuery extends SimpleObjectQuery { + private static final Column[] COLUMNS = { + new Column("Name", String.class), + new Column("Value", Object.class), + new Column("Size", Long.class), + }; + private static final int[] GRAFTED_COLUMN_MAPPING = {0, 1, 2}; + + + final static class SessionOverviewNode implements IOverviewNode { + private final IObject object; + private List attributes = null; + + public SessionOverviewNode(IObject object) { + this.object = object; + } + + public int getId() { + return object.getObjectId(); + } + + public long getRetainedHeap() { + return object.getRetainedHeapSize(); + } + + public synchronized List getAttributes() { + if (attributes == null) { + attributes = ServletExtractors.getSessionExtractor(object).buildSessionAttributes(object); + } + return attributes; + } + + public String getName() { + return ServletExtractors.getSessionExtractor(object).getSessionId(object); + } + } + + + + public HttpSessionQuery() { + super(SessionOverviewNode.class); + } + + protected List findObjects(ISnapshot snapshot) throws SnapshotException { + return ServletExtractors.findHttpSessions(snapshot); + } + + protected SessionOverviewNode createOverviewNode(IObject obj) { + return new SessionOverviewNode(obj); + } + + protected boolean overviewHasChildren(SessionOverviewNode row) { + return true; + } + + protected Column[] getColumns() { + return COLUMNS; + } + + @Override + protected Object getOverviewColumnValue(SessionOverviewNode row, int columnIndex) { + switch (columnIndex) { + case 0: + return row.getName(); + case 1: + return null; + case 2: + return row.getRetainedHeap(); + default: + return super.getOverviewColumnValue(row, columnIndex); + } + } + + @Override + protected Object getColumnValue(Object row, int columnIndex) { + if (row instanceof SessionAttributeData) { + SessionAttributeData node = (SessionAttributeData)row; + switch (columnIndex) { + case 0: + return node.getKey().getClassSpecificName(); + case 1: + return node.getValue(); + case 2: + return node.getValue().getRetainedHeapSize(); + default: + JavaEEPlugin.error("Unexpected column index " + columnIndex); + return null; + } + } else { + return super.getColumnValue(row, columnIndex); + } + } + + @Override + protected List getOverviewChildren(SessionOverviewNode row) { + return row.getAttributes(); + } + + @Override + protected boolean hasChildren(Object row) { + if (row instanceof SessionAttributeData) { + SessionAttributeData node = (SessionAttributeData) row; + return !node.getValue().getOutboundReferences().isEmpty(); + } else { + return super.hasChildren(row); + } + } + + @Override + protected List getChildren(Object row) { + try { + if (row instanceof SessionAttributeData) { + SessionAttributeData node = (SessionAttributeData) row; + // Create an outbound tree and graft it onto the main tree + int[] outbounds = node.getValue().getSnapshot().getOutboundReferentIds(node.getValue().getObjectId()); + IResultTree subtree = new ObjectListResult.Outbound(node.getValue().getSnapshot(), outbounds); + return GraftedResultTree.graft(subtree, node.getValue(), GRAFTED_COLUMN_MAPPING); + } else { + return super.getChildren(row); + } + } catch (SnapshotException e) { + JavaEEPlugin.error(e); + return null; + } + } + + @Override + protected IContextObject getContext(Object row) { + if (row instanceof SessionAttributeData) { + final SessionAttributeData node = (SessionAttributeData) row; + return new IContextObject() { + public int getObjectId() { + return node.getValue().getObjectId(); + } + }; + } else { + return super.getContext(row); + } + } +} Index: plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/servlet/query/ServletQuery.java =================================================================== --- plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/servlet/query/ServletQuery.java (revision 0) +++ plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/servlet/query/ServletQuery.java (working copy) @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat Inc + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc - initial API and implementation + *******************************************************************************/ +package org.eclipse.mat.javaee.servlet.query; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.mat.SnapshotException; +import org.eclipse.mat.javaee.IOverviewNode; +import org.eclipse.mat.javaee.SimpleObjectQuery; +import org.eclipse.mat.javaee.impl.ServletExtractors; +import org.eclipse.mat.query.Column; +import org.eclipse.mat.query.annotations.Category; +import org.eclipse.mat.query.annotations.CommandName; +import org.eclipse.mat.query.annotations.Help; +import org.eclipse.mat.query.annotations.Name; +import org.eclipse.mat.snapshot.ISnapshot; +import org.eclipse.mat.snapshot.model.IObject; + +@Category("Enterprise Java/Web") +@Name("Servlets") +@CommandName("javaee-servlets") +@Help("Shows servlets") +public class ServletQuery extends SimpleObjectQuery { + private static final Column[] COLUMNS = { + new Column("Name", String.class), + new Column("Class", String.class), + new Column("Size", Long.class), + }; + + + final static class ServletOverviewNode implements IOverviewNode { + private final IObject object; + + public ServletOverviewNode(IObject object) { + this.object = object; + } + + public int getId() { + return object.getObjectId(); + } + + public long getRetainedHeap() { + return object.getRetainedHeapSize(); + } + + public String getName() { + return ServletExtractors.getServletExtractor(object).getName(object); + } + + public String getServletClass() { + return ServletExtractors.getServletExtractor(object).getServletClass(object); + } + } + + + + public ServletQuery() { + super(ServletOverviewNode.class); + } + + protected List findObjects(ISnapshot snapshot) throws SnapshotException { + return ServletExtractors.findServlets(snapshot); + } + + protected ServletOverviewNode createOverviewNode(IObject obj) { + return new ServletOverviewNode(obj); + } + + protected boolean overviewHasChildren(ServletOverviewNode row) { + return true; + } + + protected Column[] getColumns() { + return COLUMNS; + } + + @Override + protected Object getOverviewColumnValue(ServletOverviewNode row, int columnIndex) { + switch (columnIndex) { + case 0: + return row.getName(); + case 1: + return row.getServletClass(); + case 2: + return row.getRetainedHeap(); + default: + return super.getOverviewColumnValue(row, columnIndex); + } + } + + @Override + protected List getOverviewChildren(ServletOverviewNode row) { + //return ((ServletOverviewNode)parent).getAttributes(); + return new ArrayList(); + } +} Index: plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/servlet/query/ServletServletRequestResolver.java =================================================================== --- plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/servlet/query/ServletServletRequestResolver.java (revision 0) +++ plugins/org.eclipse.mat.javaee/src/org/eclipse/mat/javaee/servlet/query/ServletServletRequestResolver.java (working copy) @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat Inc + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc - initial API and implementation + *******************************************************************************/ +package org.eclipse.mat.javaee.servlet.query; + +import org.eclipse.mat.SnapshotException; +import org.eclipse.mat.javaee.impl.ServletExtractors; +import org.eclipse.mat.javaee.servlet.api.RequestExtractor; +import org.eclipse.mat.query.results.CompositeResult; +import org.eclipse.mat.query.results.TextResult; +import org.eclipse.mat.report.QuerySpec; +import org.eclipse.mat.snapshot.ISnapshot; +import org.eclipse.mat.snapshot.extension.IRequestDetailsResolver; +import org.eclipse.mat.snapshot.extension.IThreadInfo; +import org.eclipse.mat.snapshot.extension.Subjects; +import org.eclipse.mat.snapshot.model.IObject; +import org.eclipse.mat.util.IProgressListener; + + +@Subjects(value = { + "org.apache.catalina.connector.RequestFacade", + "org.apache.catalina.connector.Request", + "io.undertow.servlet.spec.HttpServletRequestImpl", +}) +public class ServletServletRequestResolver implements IRequestDetailsResolver { + public void complement(ISnapshot snapshot, IThreadInfo thread, + int[] javaLocals, int thisJavaLocal, IProgressListener listener) + throws SnapshotException { + IObject request = snapshot.getObject(thisJavaLocal); + RequestExtractor extractor = ServletExtractors.getRequestExtractor(request); + if (extractor == null) { + System.out.println("WARN unhandled request type" + request.getClazz().getName()); + return; + } + + CompositeResult answer = new CompositeResult(); + + QuerySpec spec = new QuerySpec("URI", new TextResult(extractor.getRequestUri(request))); + answer.addResult(spec); + + thread.addRequest("Enterprise Java web worker thread", answer); + } +}