Skip to content

Commit

Permalink
WELD-1867 Probe Contexts - add support for @ConversationScoped
Browse files Browse the repository at this point in the history
- also fix Bean Archive detail - selected alternatives (stereotypes)
  • Loading branch information
mkouba authored and jharting committed Feb 16, 2015
1 parent 4574a96 commit fd49936
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 46 deletions.
48 changes: 34 additions & 14 deletions probe/core/src/main/client/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ Probe.Router.map(function() {
this.route('observerDetail', {
path : '/observers/:id'
});
this.route('contexts', {
path : '/contexts'
this.route('context', {
path : '/context/:id'
});
this.resource("contextInstance", {
path : "/contexts/:id"
Expand All @@ -82,8 +82,8 @@ Probe.ApplicationView = Ember.View.extend({
currentPathDidChange : function() {
// Workaround to highlight the active tab
Ember.run.next(this, function() {
this.$("ul.nav li:has(a.active)").addClass('active');
this.$("ul.nav li:not(:has(a.active))").removeClass('active');
this.$("ul.nav > li:has(a.active)").addClass('active');
this.$("ul.nav > li:not(:has(a.active))").removeClass('active');
});
}.observes('controller.currentPath')
});
Expand Down Expand Up @@ -347,16 +347,21 @@ Probe.ObserverDetailRoute = Ember.Route.extend(Probe.ResetScroll, {
}
});

Probe.ContextsRoute = Ember.Route.extend({
model : function() {
return $.getJSON(restUrlBase + 'contexts').done(function(data) {
Probe.ContextRoute = Ember.Route.extend(Probe.ResetScroll, {
model : function(params) {
var url = restUrlBase + 'contexts/' + params.id;
if (this.get('cid')) {
url += '?cid=' + this.get('cid');
}
return $.getJSON(url).done(function(data) {
return data;
}).fail(function(jqXHR, textStatus, errorThrown) {
alert('Unable to get JSON data: ' + textStatus);
});
},
actions : {
refreshContexts : function() {
refreshData : function(paramName) {
this.set('cid', this.get('controller.cid'));
this.refresh();
}
}
Expand All @@ -369,12 +374,15 @@ Probe.ContextInstanceRoute = Ember.Route.extend(Probe.ResetScroll, {
controller.set("kindClass", model.kind + ' boxed');
},
model : function(params) {
return $.getJSON(restUrlBase + 'beans/' + params.id + '/instance')
.done(function(data) {
return data;
}).fail(function(jqXHR, textStatus, errorThrown) {
alert('Unable to get JSON data: ' + textStatus);
});
var url = restUrlBase + 'beans/' + params.id + '/instance';
if (params.cid) {
url = url + '?cid=' + params.cid;
}
return $.getJSON(url).done(function(data) {
return data;
}).fail(function(jqXHR, textStatus, errorThrown) {
alert('Unable to get JSON data: ' + textStatus);
});
},
actions : {
refreshData : function() {
Expand Down Expand Up @@ -638,6 +646,18 @@ Probe.EventsController = Ember.ObjectController.extend({
},
});

Probe.ContextController = Ember.ObjectController.extend({
cid : null,
onCidChanged : function() {
this.send('refreshData');
}.observes('cid')
});

Probe.ContextInstanceController = Ember.ObjectController.extend({
cid : null,
queryParams : [ 'cid' ],
});

// HELPERS

Ember.Handlebars.registerBoundHelper('increment', function(integer) {
Expand Down
48 changes: 36 additions & 12 deletions probe/core/src/main/client/probe.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,14 @@
<li>{{#link-to 'configuration'}}Configuration{{/link-to}}</li>
<li>{{#link-to 'beanList'}}Beans{{/link-to}}</li>
<li>{{#link-to 'observerList'}}Observer Methods{{/link-to}}</li>
<li>{{#link-to 'contexts'}}Contexts{{/link-to}}</li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">Contexts <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
{{#each contexts}}
<li>{{#link-to 'context' id}}{{scope}}{{/link-to}}</li>
{{/each}}
</ul>
</li>
<li>{{#link-to 'invocationList'}}Invocation Trees{{/link-to}}</li>
<li>{{#link-to 'events'}}Events{{/link-to}}</li>
</ul>
Expand Down Expand Up @@ -192,7 +199,7 @@ <h1>Weld Configuration</h1>
<h1>Beans</h1>

<div class="btn-line form-control-like">
<form {{action "filter" on="submit"}} class="form-inline">
<form class="form-inline">
<label class="control-label">Bean Archive:</label>
{{view "select"
value=bda
Expand Down Expand Up @@ -497,7 +504,7 @@ <h4 class="modal-title" id="ipInfoModalTitle">Injection Points Info</h4>
<h1>Observer Methods</h1>

<div class="btn-line form-control-like">
<form {{action "filter" on="submit"}} class="form-inline">
<form class="form-inline">
<label class="control-label">Bean Archive:</label>
{{view "select"
value=bda
Expand Down Expand Up @@ -662,32 +669,49 @@ <h1>Observer Method Detail</h1>

<script
type="text/x-handlebars"
data-template-name="contexts">
data-template-name="context">

<h1>Contexts</h1>
<h1>Context - {{scope}}</h1>

{{#if cids}}
<div class="btn-line">
<button {{action 'refreshContexts'}} class="btn btn-default">Refresh</button>
<form class="form-inline">
<label class="control-label">Long-running conversation: </label>
{{view "select"
value=cid
content=cids
prompt="-- NONE SELECTED --"
class="form-control form-control-auto-width"
}}
</form>
</div>
{{/if}}

{{#each}}
<h2>{{unbound scope}}</h2>
<div class="btn-line">
<button {{action 'refreshData'}} class="btn btn-default">Refresh</button>
</div>

<table class="table table-bordered table-striped">
<tr>
<th>Bean <i class="fa fa-lg fa-info-circle" title="Link to bean detail"></i></th>
<th>Instance <i class="fa fa-lg fa-info-circle" title="Link to contextual instance detail"></i></th>
</tr>
{{#with this as parentThis}}
{{#each instances}}
<tr>
<td>{{#link-to 'beanDetail' id}}{{unbound beanClass}}{{/link-to}}</td>
<td>{{#link-to 'contextInstance' id}}{{unbound asString}}{{/link-to}}</td>
<td>{{#link-to 'beanDetail' id}}{{beanClass}}{{/link-to}}</td>
<td>
{{#if parentThis.cid}}
{{#link-to 'contextInstance' id (query-params cid=parentThis.cid)}}{{asString}}{{/link-to}}
{{else}}
{{#link-to 'contextInstance' id}}{{asString}}{{/link-to}}
{{/if}}
</td>
<tr>
{{/each}}
{{/with}}
</table>

{{/each}}

</script>

<script
Expand Down
20 changes: 11 additions & 9 deletions probe/core/src/main/java/org/jboss/weld/probe/Components.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.lang.annotation.Annotation;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

Expand Down Expand Up @@ -49,6 +50,7 @@
import org.jboss.weld.exceptions.IllegalStateException;
import org.jboss.weld.manager.BeanManagerImpl;
import org.jboss.weld.serialization.spi.BeanIdentifier;
import org.jboss.weld.util.collections.ImmutableMap;

/**
* A few utility methods and classes related to CDI components.
Expand All @@ -57,8 +59,8 @@
*/
final class Components {

@SuppressWarnings("rawtypes")
static final Class[] INSPECTABLE_SCOPES = { ApplicationScoped.class, SessionScoped.class };
static final Map<String, Class<? extends Annotation>> INSPECTABLE_SCOPES = ImmutableMap.<String, Class<? extends Annotation>> builder().put("application", ApplicationScoped.class)
.put("session", SessionScoped.class).put("conversation", ConversationScoped.class).build();

private Components() {
}
Expand Down Expand Up @@ -180,13 +182,12 @@ static boolean isBuiltinScope(Class<? extends Annotation> scope) {
|| ConversationScoped.class.equals(scope);
}

static boolean isInspectableScope(String id) {
return INSPECTABLE_SCOPES.containsKey(id);
}

static boolean isInspectableScope(Class<? extends Annotation> scope) {
for (int i = 0; i < INSPECTABLE_SCOPES.length; i++) {
if (INSPECTABLE_SCOPES[i].equals(scope)) {
return true;
}
}
return false;
return INSPECTABLE_SCOPES.containsValue(scope);
}

static SessionBeanType getSessionBeanType(EjbDescriptor<?> ejbDescriptor) {
Expand Down Expand Up @@ -260,7 +261,7 @@ static enum BeanKind {
MANAGED, SESSION, PRODUCER_METHOD, PRODUCER_FIELD, RESOURCE, SYNTHETIC, INTERCEPTOR, DECORATOR, EXTENSION, BUILT_IN;

static BeanKind from(Bean<?> bean) {
if(bean == null) {
if (bean == null) {
return null;
}
if (bean instanceof ForwardingBean) {
Expand Down Expand Up @@ -306,6 +307,7 @@ static BeanKind from(String value) {

/**
* Priority ranges, as defined in {@link javax.interceptor.Interceptor.PRIORITY}
*
* @author Jozef Hartinger
*
*/
Expand Down
63 changes: 53 additions & 10 deletions probe/core/src/main/java/org/jboss/weld/probe/JsonObjects.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@
import static org.jboss.weld.probe.Strings.BEAN_CLASS;
import static org.jboss.weld.probe.Strings.BEAN_DISCOVERY_MODE;
import static org.jboss.weld.probe.Strings.CHILDREN;
import static org.jboss.weld.probe.Strings.CIDS;
import static org.jboss.weld.probe.Strings.CONFIGURATION;
import static org.jboss.weld.probe.Strings.CONTAINER;
import static org.jboss.weld.probe.Strings.CONTEXTS;
import static org.jboss.weld.probe.Strings.DATA;
import static org.jboss.weld.probe.Strings.DECLARED_OBSERVERS;
import static org.jboss.weld.probe.Strings.DECLARED_PRODUCERS;
Expand Down Expand Up @@ -87,18 +89,23 @@
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.enterprise.context.ContextNotActiveException;
import javax.enterprise.context.ConversationScoped;
import javax.enterprise.context.spi.Context;
import javax.enterprise.inject.Any;
import javax.enterprise.inject.Default;
import javax.enterprise.inject.spi.AnnotatedField;
import javax.enterprise.inject.spi.AnnotatedMethod;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.ObserverMethod;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.jboss.weld.Container;
import org.jboss.weld.bean.AbstractProducerBean;
Expand All @@ -111,6 +118,8 @@
import org.jboss.weld.bootstrap.spi.BeansXml;
import org.jboss.weld.config.ConfigurationKey;
import org.jboss.weld.config.WeldConfiguration;
import org.jboss.weld.context.AbstractConversationContext;
import org.jboss.weld.context.ManagedConversation;
import org.jboss.weld.event.ObserverMethodImpl;
import org.jboss.weld.experimental.Prioritized;
import org.jboss.weld.injection.producer.ProducerFieldProducer;
Expand Down Expand Up @@ -182,7 +191,12 @@ static String createDeploymentJson(BeanManagerImpl beanManager, Probe probe) {
alternatives.add(createSimpleBeanJson(findAlternativeBean(clazz, probe), probe));
}
for (Class<? extends Annotation> stereotype : enablement.getAlternativeStereotypes()) {
alternatives.add(createSimpleBeanJson(findAlternativeStereotypeBean(stereotype, probe), probe));
Set<Bean<?>> beans = findAlternativeStereotypeBeans(stereotype, probe);
if (!beans.isEmpty()) {
for (Bean<?> bean : beans) {
alternatives.add(createSimpleBeanJson(bean, probe));
}
}
}
enablementBuilder.add(ALTERNATIVES, alternatives);
bdaBuilder.add(ENABLEMENT, enablementBuilder);
Expand Down Expand Up @@ -220,6 +234,9 @@ static String createDeploymentJson(BeanManagerImpl beanManager, Probe probe) {
}
deploymentBuilder.add(CONFIGURATION, configBuilder);

// INSPECTABLE CONTEXTS
deploymentBuilder.add(CONTEXTS, createContextsJson(beanManager, probe));

return deploymentBuilder.build();
}

Expand All @@ -241,13 +258,14 @@ static Bean<?> findAlternativeBean(Class<?> beanClass, Probe probe) {
return null;
}

static Bean<?> findAlternativeStereotypeBean(Class<? extends Annotation> stereotype, Probe probe) {
static Set<Bean<?>> findAlternativeStereotypeBeans(Class<? extends Annotation> stereotype, Probe probe) {
Set<Bean<?>> beans = new HashSet<Bean<?>>();
for (Bean<?> bean : probe.getBeans()) {
if (bean.isAlternative() && bean.getStereotypes().contains(stereotype)) {
return bean;
beans.add(bean);
}
}
return null;
return beans;
}

/**
Expand Down Expand Up @@ -676,19 +694,44 @@ static String createContextualInstanceJson(Bean<?> bean, Object contextualInstan
}
}

@SuppressWarnings("unchecked")
static String createContextsJson(BeanManagerImpl beanManager, Probe probe) {
static JsonArrayBuilder createContextsJson(BeanManagerImpl beanManager, Probe probe) {
JsonArrayBuilder contexts = Json.newArrayBuilder();
for (int i = 0; i < Components.INSPECTABLE_SCOPES.length; i++) {
contexts.add(createContextJson(Components.INSPECTABLE_SCOPES[i], beanManager, probe));
for (Entry<String, Class<? extends Annotation>> entry : Components.INSPECTABLE_SCOPES.entrySet()) {
contexts.add(createSimpleContextJson(entry.getKey(), entry.getValue()));
}
return contexts.build();
return contexts;
}

static JsonObjectBuilder createContextJson(Class<? extends Annotation> scope, BeanManagerImpl beanManager, Probe probe) {
static JsonObjectBuilder createSimpleContextJson(String id, Class<? extends Annotation> scope) {
JsonObjectBuilder builder = Json.newObjectBuilder();
builder.add(SCOPE, scope.getName());
builder.add(ID, id);
return builder;
}

static JsonObjectBuilder createContextJson(String id, Class<? extends Annotation> scope, BeanManagerImpl beanManager, Probe probe, HttpServletRequest req) {
JsonObjectBuilder builder = createSimpleContextJson(id, scope).setIgnoreEmptyBuilders(true);

builder.add(INSTANCES, inspectContext(scope, beanManager, probe));

if (ConversationScoped.class.equals(scope)) {
HttpSession session = req.getSession(false);
if (session != null) {
// Get all available conversation ids
Object conversationsAttribute = session.getAttribute(AbstractConversationContext.CONVERSATIONS_ATTRIBUTE_NAME);
if (conversationsAttribute != null && conversationsAttribute instanceof Map) {
@SuppressWarnings("unchecked")
Map<String, ManagedConversation> conversationsMap = (Map<String, ManagedConversation>) conversationsAttribute;
if (!conversationsMap.isEmpty()) {
JsonArrayBuilder cidsBuilder = Json.newArrayBuilder();
for (String cid : conversationsMap.keySet()) {
cidsBuilder.add(cid);
}
builder.add(CIDS, cidsBuilder);
}
}
}
}
return builder;
}

Expand Down
Loading

0 comments on commit fd49936

Please sign in to comment.