Seam SVN: r11895 - in modules/remoting/trunk/src/main: java/org/jboss/seam/remoting/model and 1 other directories.
by seam-commits@lists.jboss.org
Author: shane.bryzak(a)jboss.com
Date: 2009-12-30 18:38:56 -0500 (Wed, 30 Dec 2009)
New Revision: 11895
Modified:
modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/MarshalUtils.java
modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/model/ModelHandler.java
modules/remoting/trunk/src/main/resources/org/jboss/seam/remoting/remote.js
Log:
fixed model apply updates response handling
Modified: modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/MarshalUtils.java
===================================================================
--- modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/MarshalUtils.java 2009-12-30 20:57:38 UTC (rev 11894)
+++ modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/MarshalUtils.java 2009-12-30 23:38:56 UTC (rev 11895)
@@ -18,7 +18,7 @@
private static final byte[] RESULT_TAG_OPEN = "<result>".getBytes();
private static final byte[] RESULT_TAG_CLOSE = "</result>".getBytes();
- private static final byte[] MODEL_TAG_OPEN_START = "<model uid=\"".getBytes();
+ private static final byte[] MODEL_TAG_OPEN_START = "<model id=\"".getBytes();
private static final byte[] MODEL_TAG_OPEN_END = "\">".getBytes();
private static final byte[] MODEL_TAG_CLOSE = "</model>".getBytes();
Modified: modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/model/ModelHandler.java
===================================================================
--- modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/model/ModelHandler.java 2009-12-30 20:57:38 UTC (rev 11894)
+++ modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/model/ModelHandler.java 2009-12-30 23:38:56 UTC (rev 11895)
@@ -207,7 +207,7 @@
private Model processApplyRequest(Element modelElement)
throws Exception
{
- Model model = registry.getModel(modelElement.attributeValue("uid"));
+ Model model = registry.getModel(modelElement.attributeValue("id"));
model.setAction(null);
CallContext ctx = new CallContext(beanManager);
@@ -258,19 +258,19 @@
{
out.write(ENVELOPE_TAG_OPEN);
+ out.write(HEADER_OPEN);
+ out.write(CONTEXT_TAG_OPEN);
if (ctx.getConversationId() != null)
{
- out.write(HEADER_OPEN);
- out.write(CONTEXT_TAG_OPEN);
out.write(CONVERSATION_ID_TAG_OPEN);
out.write(ctx.getConversationId().getBytes());
out.write(CONVERSATION_ID_TAG_CLOSE);
- out.write(CALL_ID_TAG_OPEN);
- out.write(ctx.getCallId().toString().getBytes());
- out.write(CALL_ID_TAG_CLOSE);
- out.write(CONTEXT_TAG_CLOSE);
- out.write(HEADER_CLOSE);
}
+ out.write(CALL_ID_TAG_OPEN);
+ out.write(ctx.getCallId().toString().getBytes());
+ out.write(CALL_ID_TAG_CLOSE);
+ out.write(CONTEXT_TAG_CLOSE);
+ out.write(HEADER_CLOSE);
out.write(BODY_TAG_OPEN);
Modified: modules/remoting/trunk/src/main/resources/org/jboss/seam/remoting/remote.js
===================================================================
--- modules/remoting/trunk/src/main/resources/org/jboss/seam/remoting/remote.js 2009-12-30 20:57:38 UTC (rev 11894)
+++ modules/remoting/trunk/src/main/resources/org/jboss/seam/remoting/remote.js 2009-12-30 23:38:56 UTC (rev 11895)
@@ -516,7 +516,7 @@
}
}
-Seam.preProcessModelFetchResponse = function(call) {
+Seam.preProcessModelResponse = function(call) {
var cn = Seam.Xml.childNode;
var b = cn(call.response.documentElement, "body");
if (b) {
@@ -525,19 +525,19 @@
var refsNode = cn(m, "refs");
var u = Seam.validateRefs(refsNode);
if (u.length > 0) {
- call.handler = Seam.processModelFetchResponse;
+ call.handler = Seam.processModelResponse;
var c = Seam.createImportBeansCall(u, null, call);
var envelope = Seam.createEnvelope(Seam.createHeader(c.id), c.data);
Seam.pendingCalls.put(c.id, c);
Seam.sendAjaxRequest(envelope, Seam.PATH_EXECUTE, Seam.processResponse, false);
} else {
- Seam.processModelFetchResponse(call);
+ Seam.processModelResponse(call);
}
}
}
}
-Seam.processModelFetchResponse = function(call) {
+Seam.processModelResponse = function(call) {
Seam.pendingCalls.remove(call.callId);
var cn = Seam.Xml.childNode;
var b = cn(call.response.documentElement, "body");
@@ -919,7 +919,7 @@
Seam.Model.prototype.createFetchRequest = function(a) {
var callId = "" + Seam.__callId++;
- var d = "<model operation=\"fetch\" callId=\"" + callId + "\">";
+ var d = "<model operation=\"fetch\">";
var refs = [];
if (a) {
d += "<action>";
@@ -968,12 +968,12 @@
}
}
d += "</model>";
- return {data:d, id:callId, model:this, handler: Seam.preProcessModelFetchResponse};
+ return {data:d, id:callId, model:this, handler: Seam.preProcessModelResponse};
}
Seam.Model.prototype.processResponse = function(modelNode) {
var refsNode = Seam.Xml.childNode(modelNode, "refs");
- this.id = modelNode.getAttribute("uid");
+ this.id = modelNode.getAttribute("id");
var valueNodes = Seam.Xml.childNodes(modelNode, "value");
this.sourceRefs = Seam.unmarshalRefs(refsNode);
this.workingRefs = Seam.cloneObject(this.sourceRefs);
@@ -997,7 +997,7 @@
Seam.Model.prototype.createApplyRequest = function(a, delta) {
var callId = "" + Seam.__callId++;
- var d = "<model uid=\"" + this.id + "\" operation=\"apply\">";
+ var d = "<model id=\"" + this.id + "\" operation=\"apply\">";
var refs = delta.buildRefs();
if (a) {
d += "<action>";
@@ -1048,7 +1048,7 @@
d += "</refs>";
}
d += "</model>";
- return {data:d, id:callId, model:this, handler: null};
+ return {data:d, id:callId, model:this, handler: Seam.preProcessModelResponse};
}
Seam.Model.prototype.getRefId = function(v) {
15 years
Seam SVN: r11894 - in modules/remoting/trunk/src/main: java/org/jboss/seam/remoting/wrapper and 1 other directories.
by seam-commits@lists.jboss.org
Author: shane.bryzak(a)jboss.com
Date: 2009-12-30 15:57:38 -0500 (Wed, 30 Dec 2009)
New Revision: 11894
Modified:
modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/model/ModelHandler.java
modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/wrapper/BeanWrapper.java
modules/remoting/trunk/src/main/resources/org/jboss/seam/remoting/remote.js
Log:
implemented dynamic type loading for model fetch requests
Modified: modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/model/ModelHandler.java
===================================================================
--- modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/model/ModelHandler.java 2009-12-30 11:06:46 UTC (rev 11893)
+++ modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/model/ModelHandler.java 2009-12-30 20:57:38 UTC (rev 11894)
@@ -88,44 +88,36 @@
conversationContext.setActive(true);
}
- Set<Model> models = new HashSet<Model>();
+ Element modelElement = env.element("body").element("model");
+ String operation = modelElement.attributeValue("operation");
- for (Element modelElement : (List<Element>) env.element("body").elements("model"))
- {
- String operation = modelElement.attributeValue("operation");
-
- if ("fetch".equals(operation))
- {
- processFetchRequest(modelElement, models);
- }
- else if ("apply".equals(operation))
- {
- processApplyRequest(modelElement, models);
- }
+ Model model = null;
+
+ if ("fetch".equals(operation))
+ {
+ model = processFetchRequest(modelElement);
}
-
- for (Model model : models)
+ else if ("apply".equals(operation))
{
- if (model.getAction() != null && model.getAction().getException() != null)
- {
- response.getOutputStream().write(ENVELOPE_TAG_OPEN);
- response.getOutputStream().write(BODY_TAG_OPEN);
- MarshalUtils.marshalException(model.getAction().getException(),
- model.getAction().getContext(), response.getOutputStream());
- response.getOutputStream().write(BODY_TAG_CLOSE);
- response.getOutputStream().write(ENVELOPE_TAG_CLOSE);
- response.getOutputStream().flush();
- return;
- }
+ model = processApplyRequest(modelElement);
}
-
- for (Model model : models)
+
+ if (model.getAction() != null && model.getAction().getException() != null)
{
- model.evaluate();
+ response.getOutputStream().write(ENVELOPE_TAG_OPEN);
+ response.getOutputStream().write(BODY_TAG_OPEN);
+ MarshalUtils.marshalException(model.getAction().getException(),
+ model.getAction().getContext(), response.getOutputStream());
+ response.getOutputStream().write(BODY_TAG_CLOSE);
+ response.getOutputStream().write(ENVELOPE_TAG_CLOSE);
+ response.getOutputStream().flush();
+ return;
}
+ model.evaluate();
+
ctx.setConversationId(conversation.isTransient() ? null : conversation.getId());
- marshalResponse(models, ctx, response.getOutputStream());
+ marshalResponse(model, ctx, response.getOutputStream());
}
finally
{
@@ -139,11 +131,10 @@
}
@SuppressWarnings({ "unchecked" })
- private void processFetchRequest(Element modelElement, Set<Model> models)
+ private Model processFetchRequest(Element modelElement)
throws Exception
{
Model model = registry.createModel();
- models.add(model);
if (modelElement.elements("action").size() > 0)
{
@@ -171,7 +162,9 @@
if (model.getAction() != null)
{
model.getAction().execute();
- }
+ }
+
+ return model;
}
@SuppressWarnings("unchecked")
@@ -211,11 +204,10 @@
}
@SuppressWarnings("unchecked")
- private void processApplyRequest(Element modelElement, Set<Model> models)
+ private Model processApplyRequest(Element modelElement)
throws Exception
{
Model model = registry.getModel(modelElement.attributeValue("uid"));
- models.add(model);
model.setAction(null);
CallContext ctx = new CallContext(beanManager);
@@ -256,10 +248,12 @@
if (model.getAction() != null)
{
model.getAction().execute();
- }
+ }
+
+ return model;
}
- private void marshalResponse(Set<Model> models, RequestContext ctx,
+ private void marshalResponse(Model model, RequestContext ctx,
OutputStream out) throws IOException
{
out.write(ENVELOPE_TAG_OPEN);
@@ -271,16 +265,16 @@
out.write(CONVERSATION_ID_TAG_OPEN);
out.write(ctx.getConversationId().getBytes());
out.write(CONVERSATION_ID_TAG_CLOSE);
+ out.write(CALL_ID_TAG_OPEN);
+ out.write(ctx.getCallId().toString().getBytes());
+ out.write(CALL_ID_TAG_CLOSE);
out.write(CONTEXT_TAG_CLOSE);
out.write(HEADER_CLOSE);
}
out.write(BODY_TAG_OPEN);
- for (Model model : models)
- {
- MarshalUtils.marshalModel(model, out);
- }
+ MarshalUtils.marshalModel(model, out);
out.write(BODY_TAG_CLOSE);
out.write(ENVELOPE_TAG_CLOSE);
Modified: modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/wrapper/BeanWrapper.java
===================================================================
--- modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/wrapper/BeanWrapper.java 2009-12-30 11:06:46 UTC (rev 11893)
+++ modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/wrapper/BeanWrapper.java 2009-12-30 20:57:38 UTC (rev 11894)
@@ -7,6 +7,7 @@
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.List;
+import java.util.Set;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
@@ -244,19 +245,20 @@
cls = cls.getSuperclass();
}
- // TODO fix this, bean might not have a name
- Bean<?> bean = beanManager.getBeans(cls).iterator().next();
- String componentName = bean.getName();
-
- if (componentName != null)
+ String componentName = cls.getName();
+
+ Set<Bean<?>> beans = beanManager.getBeans(cls);
+ if (beans.size() > 0)
{
- out.write(componentName.getBytes());
- }
- else
- {
- out.write(cls.getName().getBytes());
- }
+ Bean<?> bean = beanManager.getBeans(cls).iterator().next();
+ if (bean.getName() != null)
+ {
+ componentName = bean.getName();
+ }
+ }
+ out.write(componentName.getBytes());
+
out.write(BEAN_START_TAG_CLOSE);
for (String propertyName : getMetadataCache().getAccessibleProperties(cls).keySet())
Modified: modules/remoting/trunk/src/main/resources/org/jboss/seam/remoting/remote.js
===================================================================
--- modules/remoting/trunk/src/main/resources/org/jboss/seam/remoting/remote.js 2009-12-30 11:06:46 UTC (rev 11893)
+++ modules/remoting/trunk/src/main/resources/org/jboss/seam/remoting/remote.js 2009-12-30 20:57:38 UTC (rev 11894)
@@ -66,7 +66,7 @@
Seam.beans[name] = t;
}
-Seam.loadBeans = function() {
+Seam.importBeans = function() {
var names = [];
var cb = null;
for (var i=0; i<arguments.length; i++) {
@@ -82,17 +82,22 @@
cb = arguments[i];
}
}
- var n = "org.jboss.seam.remoting.BeanMetadata";
- if (!Seam.isBeanRegistered(n)) Seam.registerBean(n, {name: "str", methods: "Seam.Map", properties: "Seam.Map"});
- var c = Seam.createLoadBeansCall([names], cb);
+
+ var c = Seam.createImportBeansCall(names, cb);
var envelope = Seam.createEnvelope(Seam.createHeader(c.id), c.data);
Seam.pendingCalls.put(c.id, c);
Seam.sendAjaxRequest(envelope, Seam.PATH_EXECUTE, Seam.processResponse, false);
}
-Seam.createLoadBeansCall = function(names, callback, originalCall) {
- var c = Seam.createCall("org.jboss.seam.remoting.MetadataCache", "loadBeans", names, callback);
- c.handler = Seam.processLoadBeansResponse;
+Seam.createImportBeansCall = function(names, callback, originalCall) {
+ var n = "org.jboss.seam.remoting.BeanMetadata";
+ if (!Seam.isBeanRegistered(n)) {
+ Seam.registerBean(n, {name: "str", methods: "Seam.Map", properties: "Seam.Map"});
+ Seam.registerBean("org.jboss.seam.remoting.MetadataCache", null, {loadBeans:1});
+ }
+
+ var c = Seam.createCall(new Seam.beans["org.jboss.seam.remoting.MetadataCache"](), "loadBeans", [names], callback);
+ c.handler = Seam.processImportBeansResponse;
if (originalCall) c.originalCall = originalCall;
return c;
}
@@ -315,7 +320,7 @@
Seam.createCall = function(component, methodName, params, callback, exceptionHandler) {
var callId = "" + Seam.__callId++;
- if (!callback) callback = component.__callback[methodName];
+ if (!callback && component.__callback) callback = component.__callback[methodName];
var d = "<call><target>" + Seam.getBeanType(component).__name + "</target>";
if (component.__qualifiers != null) {
d += "<qualifiers>";
@@ -434,7 +439,7 @@
r.send(env);
}
-Seam.processLoadBeansResponse = function(call) {
+Seam.processImportBeansResponse = function(call) {
var cn = Seam.Xml.childNode;
Seam.pendingCalls.remove(call.callId);
var n = cn(cn(call.response.documentElement, "body"), "result");
@@ -479,10 +484,10 @@
var n = cn(bodyNode, "result");
if (n) {
var refsNode = cn(n, "refs");
- var u = Seam.validateRefs(refsNode, call);
+ var u = Seam.validateRefs(refsNode);
if (u.length > 0) {
call.handler = Seam.processCallResponse;
- var c = Seam.createLoadBeansCall(u, null, call);
+ var c = Seam.createImportBeansCall(u, null, call);
var envelope = Seam.createEnvelope(Seam.createHeader(c.id), c.data);
Seam.pendingCalls.put(c.id, c);
Seam.sendAjaxRequest(envelope, Seam.PATH_EXECUTE, Seam.processResponse, false);
@@ -511,19 +516,37 @@
}
}
-Seam.preProcessModelResponse = function(call) {
- var bodyNode = cn(doc.documentElement, "body");
- if (bodyNode) {
- var n = Seam.Xml.childNodes(bodyNode, "model");
- for (var i=0; i<n.length; i++) {
- var callId = n[i].getAttribute("callId");
- var call = Seam.pendingCalls.get(callId);
- Seam.pendingCalls.remove(callId);
- if (call.model) call.model.processResponse(n[i]);
+Seam.preProcessModelFetchResponse = function(call) {
+ var cn = Seam.Xml.childNode;
+ var b = cn(call.response.documentElement, "body");
+ if (b) {
+ var m = cn(b, "model");
+ if (m) {
+ var refsNode = cn(m, "refs");
+ var u = Seam.validateRefs(refsNode);
+ if (u.length > 0) {
+ call.handler = Seam.processModelFetchResponse;
+ var c = Seam.createImportBeansCall(u, null, call);
+ var envelope = Seam.createEnvelope(Seam.createHeader(c.id), c.data);
+ Seam.pendingCalls.put(c.id, c);
+ Seam.sendAjaxRequest(envelope, Seam.PATH_EXECUTE, Seam.processResponse, false);
+ } else {
+ Seam.processModelFetchResponse(call);
+ }
}
}
}
+Seam.processModelFetchResponse = function(call) {
+ Seam.pendingCalls.remove(call.callId);
+ var cn = Seam.Xml.childNode;
+ var b = cn(call.response.documentElement, "body");
+ if (b) {
+ var n = cn(b, "model");
+ if (call.model) call.model.processResponse(n);
+ }
+}
+
Seam.displayError = function(code) {
alert("There was an error processing your request. Error code: " + code);
}
@@ -945,7 +968,7 @@
}
}
d += "</model>";
- return {data:d, id:callId, model:this, handler: null};
+ return {data:d, id:callId, model:this, handler: Seam.preProcessModelFetchResponse};
}
Seam.Model.prototype.processResponse = function(modelNode) {
@@ -974,7 +997,7 @@
Seam.Model.prototype.createApplyRequest = function(a, delta) {
var callId = "" + Seam.__callId++;
- var d = "<model uid=\"" + this.id + "\" operation=\"apply\" callId=\"" + callId + "\">";
+ var d = "<model uid=\"" + this.id + "\" operation=\"apply\">";
var refs = delta.buildRefs();
if (a) {
d += "<action>";
15 years
Seam SVN: r11893 - modules/remoting/trunk/src/main/resources/org/jboss/seam/remoting.
by seam-commits@lists.jboss.org
Author: shane.bryzak(a)jboss.com
Date: 2009-12-30 06:06:46 -0500 (Wed, 30 Dec 2009)
New Revision: 11893
Modified:
modules/remoting/trunk/src/main/resources/org/jboss/seam/remoting/remote.js
Log:
implemented dynamic type loading for execution requests
Modified: modules/remoting/trunk/src/main/resources/org/jboss/seam/remoting/remote.js
===================================================================
--- modules/remoting/trunk/src/main/resources/org/jboss/seam/remoting/remote.js 2009-12-30 10:42:54 UTC (rev 11892)
+++ modules/remoting/trunk/src/main/resources/org/jboss/seam/remoting/remote.js 2009-12-30 11:06:46 UTC (rev 11893)
@@ -84,28 +84,19 @@
}
var n = "org.jboss.seam.remoting.BeanMetadata";
if (!Seam.isBeanRegistered(n)) Seam.registerBean(n, {name: "str", methods: "Seam.Map", properties: "Seam.Map"});
- var callback = function(beans) {
- for (var i=0; i<beans.length; i++) {
- var meta = beans[i];
- if (meta.beanType == "state") {
- var props = {};
- for (var j=0;j<meta.properties.elements.length; j++) {
- props[meta.properties.elements[j].key] = meta.properties.elements[j].value;
- }
- Seam.registerBean(meta.name, props);
- } else if (meta.beanType == "action") {
- var methods = {};
- for (var j=0; j<meta.methods.elements.length; j++) {
- methods[meta.methods.elements[j].key] = meta.methods.elements[j].value;
- }
- Seam.registerBean(meta.name, null, methods);
- }
- }
- if (cb) cb();
- }
- Seam.execute("org.jboss.seam.remoting.MetadataCache", "loadBeans", [names], callback);
+ var c = Seam.createLoadBeansCall([names], cb);
+ var envelope = Seam.createEnvelope(Seam.createHeader(c.id), c.data);
+ Seam.pendingCalls.put(c.id, c);
+ Seam.sendAjaxRequest(envelope, Seam.PATH_EXECUTE, Seam.processResponse, false);
}
+Seam.createLoadBeansCall = function(names, callback, originalCall) {
+ var c = Seam.createCall("org.jboss.seam.remoting.MetadataCache", "loadBeans", names, callback);
+ c.handler = Seam.processLoadBeansResponse;
+ if (originalCall) c.originalCall = originalCall;
+ return c;
+}
+
Seam.getBeanMetadata = function(obj) {
var b = Seam.getBeanType(obj);
return b ? b.__metadata : undefined;
@@ -381,13 +372,9 @@
Seam.execute = function(component, methodName, params, callback, exceptionHandler) {
var c = Seam.createCall(component, methodName, params, callback, exceptionHandler);
- if (Seam.inBatch) {
- Seam.batchedCalls.push(c);
- } else {
- var envelope = Seam.createEnvelope(Seam.createHeader(c.id), c.data);
- Seam.pendingCalls.put(c.id, c);
- Seam.sendAjaxRequest(envelope, Seam.PATH_EXECUTE, Seam.processResponse, false);
- }
+ var envelope = Seam.createEnvelope(Seam.createHeader(c.id), c.data);
+ Seam.pendingCalls.put(c.id, c);
+ Seam.sendAjaxRequest(envelope, Seam.PATH_EXECUTE, Seam.processResponse, false);
return c;
}
@@ -447,6 +434,44 @@
r.send(env);
}
+Seam.processLoadBeansResponse = function(call) {
+ var cn = Seam.Xml.childNode;
+ Seam.pendingCalls.remove(call.callId);
+ var n = cn(cn(call.response.documentElement, "body"), "result");
+ var valueNode = cn(n, "value");
+ var exceptionNode = cn(n, "exception");
+ if (exceptionNode != null && call.exceptionHandler != null) {
+ var msgNode = cn(exceptionNode, "message");
+ var msg = Seam.unmarshalValue(msgNode.firstChild);
+ call.exceptionHandler(new Seam.Exception(msg));
+ } else {
+ var refsNode = cn(n, "refs");
+ var refs = Seam.unmarshalRefs(refsNode);
+ var v = Seam.unmarshalValue(valueNode.firstChild, refs);
+ for (var i=0; i<v.length; i++) {
+ var meta = v[i];
+ if (meta.beanType == "state") {
+ var props = {};
+ for (var j=0;j<meta.properties.elements.length; j++) {
+ props[meta.properties.elements[j].key] = meta.properties.elements[j].value;
+ }
+ Seam.registerBean(meta.name, props);
+ } else if (meta.beanType == "action") {
+ var methods = {};
+ for (var j=0; j<meta.methods.elements.length; j++) {
+ methods[meta.methods.elements[j].key] = meta.methods.elements[j].value;
+ }
+ Seam.registerBean(meta.name, null, methods);
+ }
+ }
+ if (call.callback) {
+ call.callback(v, call.context);
+ } else if (call.originalCall) {
+ call.originalCall.handler(call.originalCall);
+ }
+ }
+}
+
Seam.preProcessCallResponse = function(call) {
var cn = Seam.Xml.childNode;
var bodyNode = cn(call.response.documentElement, "body");
@@ -456,7 +481,11 @@
var refsNode = cn(n, "refs");
var u = Seam.validateRefs(refsNode, call);
if (u.length > 0) {
- // todo load the unknown types
+ call.handler = Seam.processCallResponse;
+ var c = Seam.createLoadBeansCall(u, null, call);
+ var envelope = Seam.createEnvelope(Seam.createHeader(c.id), c.data);
+ Seam.pendingCalls.put(c.id, c);
+ Seam.sendAjaxRequest(envelope, Seam.PATH_EXECUTE, Seam.processResponse, false);
} else {
Seam.processCallResponse(call);
}
@@ -479,7 +508,7 @@
var refs = Seam.unmarshalRefs(refsNode);
var v = Seam.unmarshalValue(valueNode.firstChild, refs);
call.callback(v, call.context);
- }
+ }
}
Seam.preProcessModelResponse = function(call) {
@@ -524,14 +553,6 @@
}
}
-Seam.processLoadTypes = function(callId) {
- var call = Seam.pendingCalls.get(callId);
- if (call) {
- Seam.pendingCalls.remove(callId);
- if (call.model) call.model.processResponse(call.model.modelNode, true);
- }
-}
-
Seam.unmarshalContext = function(ctxNode, context) {
var c = Seam.Xml.childNode(ctxNode, "conversationId");
if (c) context.setConversationId(c.firstChild.nodeValue);
15 years
Seam SVN: r11892 - in modules/remoting/trunk: src/main/java/org/jboss/seam/remoting and 2 other directories.
by seam-commits@lists.jboss.org
Author: shane.bryzak(a)jboss.com
Date: 2009-12-30 05:42:54 -0500 (Wed, 30 Dec 2009)
New Revision: 11892
Modified:
modules/remoting/trunk/examples/model/src/main/webapp/model.html
modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/Call.java
modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/ExecutionHandler.java
modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/MarshalUtils.java
modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/RequestContext.java
modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/RequestHandler.java
modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/model/Model.java
modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/model/ModelHandler.java
modules/remoting/trunk/src/main/resources/org/jboss/seam/remoting/remote.js
Log:
rewrite call handling, removed support for batch requests
Modified: modules/remoting/trunk/examples/model/src/main/webapp/model.html
===================================================================
--- modules/remoting/trunk/examples/model/src/main/webapp/model.html 2009-12-29 09:13:05 UTC (rev 11891)
+++ modules/remoting/trunk/examples/model/src/main/webapp/model.html 2009-12-30 10:42:54 UTC (rev 11892)
@@ -11,7 +11,6 @@
<h1>Seam Remoting - Model Example</h1>
<script type="text/javascript" src="seam/resource/remoting/resource/remote.js"></script>
- <script type="text/javascript" src="seam/resource/remoting/interface.js?org.jboss.seam.remoting.examples.model.Customer"></script>
<script type="text/javascript">
//<![CDATA[
Modified: modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/Call.java
===================================================================
--- modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/Call.java 2009-12-29 09:13:05 UTC (rev 11891)
+++ modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/Call.java 2009-12-30 10:42:54 UTC (rev 11892)
@@ -31,8 +31,6 @@
private BeanManager beanManager;
- private String id;
-
private String methodName;
private Throwable exception;
@@ -46,11 +44,9 @@
private Bean<?> targetBean = null;
- public Call(BeanManager beanManager, String id, String beanName,
- String qualifiers, String methodName)
+ public Call(BeanManager beanManager, String beanName, String qualifiers, String methodName)
{
this.beanManager = beanManager;
- this.id = id;
this.methodName = methodName;
this.context = new CallContext(beanManager);
@@ -134,16 +130,6 @@
}
/**
- * Returns the id of this call.
- *
- * @return String
- */
- public String getId()
- {
- return id;
- }
-
- /**
* Returns the object graph constraints annotated on the method that is
* called.
*
Modified: modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/ExecutionHandler.java
===================================================================
--- modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/ExecutionHandler.java 2009-12-29 09:13:05 UTC (rev 11891)
+++ modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/ExecutionHandler.java 2009-12-30 10:42:54 UTC (rev 11892)
@@ -4,9 +4,7 @@
import java.io.IOException;
import java.io.OutputStream;
import java.io.StringReader;
-import java.util.ArrayList;
import java.util.Iterator;
-import java.util.List;
import javax.enterprise.context.Conversation;
import javax.enterprise.inject.spi.BeanManager;
@@ -76,19 +74,14 @@
}
// Extract the calls from the request
- List<Call> calls = unmarshalCalls(env);
+ Call call = unmarshalCall(env);
+ call.execute();
- // Execute each of the calls
- for (Call call : calls)
- {
- call.execute();
- }
-
// Store the conversation ID in the outgoing context
ctx.setConversationId(conversation.getId());
// Package up the response
- marshalResponse(calls, ctx, response.getOutputStream());
+ marshalResponse(call, ctx, response.getOutputStream());
}
/**
@@ -99,57 +92,49 @@
* @throws Exception
*/
@SuppressWarnings("unchecked")
- private List<Call> unmarshalCalls(Element env) throws Exception
+ private Call unmarshalCall(Element env) throws Exception
{
try
{
- List<Call> calls = new ArrayList<Call>();
+ Element callElement = env.element("body").element("call");
+
+ Element targetNode = callElement.element("target");
+ Element qualifiersNode = callElement.element("qualifiers");
+ Element methodNode = callElement.element("method");
+
+ Call call = new Call(beanManager, targetNode.getText(),
+ qualifiersNode != null ? qualifiersNode.getText() : null,
+ methodNode.getText());
- List<Element> callElements = env.element("body").elements("call");
+ // First reconstruct all the references
+ Element refsNode = callElement.element("refs");
+
+ Iterator iter = refsNode.elementIterator("ref");
+ while (iter.hasNext())
+ {
+ call.getContext()
+ .createWrapperFromElement((Element) iter.next());
+ }
- for (Element e : callElements)
- {
- Element targetNode = e.element("target");
- Element qualifiersNode = e.element("qualifiers");
- Element methodNode = e.element("method");
-
- Call call = new Call(beanManager, e.attributeValue("id"),
- targetNode.getText(),
- qualifiersNode != null ? qualifiersNode.getText() : null,
- methodNode.getText());
+ // Now unmarshal the ref values
+ for (Wrapper w : call.getContext().getInRefs().values())
+ {
+ w.unmarshal();
+ }
- // First reconstruct all the references
- Element refsNode = e.element("refs");
-
- Iterator iter = refsNode.elementIterator("ref");
- while (iter.hasNext())
- {
- call.getContext()
- .createWrapperFromElement((Element) iter.next());
- }
+ Element paramsNode = callElement.element("params");
- // Now unmarshal the ref values
- for (Wrapper w : call.getContext().getInRefs().values())
- {
- w.unmarshal();
- }
+ // Then process the param values
+ iter = paramsNode.elementIterator("param");
+ while (iter.hasNext())
+ {
+ Element param = (Element) iter.next();
- Element paramsNode = e.element("params");
-
- // Then process the param values
- iter = paramsNode.elementIterator("param");
- while (iter.hasNext())
- {
- Element param = (Element) iter.next();
-
- call.addParameter(call.getContext().createWrapperFromElement(
- (Element) param.elementIterator().next()));
- }
-
- calls.add(call);
+ call.addParameter(call.getContext().createWrapperFromElement(
+ (Element) param.elementIterator().next()));
}
- return calls;
+ return call;
}
catch (Exception ex)
{
@@ -167,29 +152,27 @@
* OutputStream The stream to write to
* @throws IOException
*/
- private void marshalResponse(List<Call> calls, RequestContext ctx,
- OutputStream out) throws IOException
+ private void marshalResponse(Call call, RequestContext ctx, OutputStream out)
+ throws IOException
{
out.write(ENVELOPE_TAG_OPEN);
-
+ out.write(HEADER_OPEN);
+ out.write(CONTEXT_TAG_OPEN);
if (ctx.getConversationId() != null)
{
- out.write(HEADER_OPEN);
- out.write(CONTEXT_TAG_OPEN);
out.write(CONVERSATION_ID_TAG_OPEN);
out.write(ctx.getConversationId().getBytes());
out.write(CONVERSATION_ID_TAG_CLOSE);
- out.write(CONTEXT_TAG_CLOSE);
- out.write(HEADER_CLOSE);
}
+ out.write(CALL_ID_TAG_OPEN);
+ out.write(ctx.getCallId().toString().getBytes());
+ out.write(CALL_ID_TAG_CLOSE);
+ out.write(CONTEXT_TAG_CLOSE);
+ out.write(HEADER_CLOSE);
out.write(BODY_TAG_OPEN);
+ MarshalUtils.marshalCallResult(call, out);
- for (Call call : calls)
- {
- MarshalUtils.marshalCallResult(call, out);
- }
-
out.write(BODY_TAG_CLOSE);
out.write(ENVELOPE_TAG_CLOSE);
out.flush();
Modified: modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/MarshalUtils.java
===================================================================
--- modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/MarshalUtils.java 2009-12-29 09:13:05 UTC (rev 11891)
+++ modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/MarshalUtils.java 2009-12-30 10:42:54 UTC (rev 11892)
@@ -15,8 +15,6 @@
*/
public class MarshalUtils
{
- private static final byte[] RESULT_TAG_OPEN_START = "<result id=\"".getBytes();
- private static final byte[] RESULT_TAG_OPEN_END = "\">".getBytes();
private static final byte[] RESULT_TAG_OPEN = "<result>".getBytes();
private static final byte[] RESULT_TAG_CLOSE = "</result>".getBytes();
@@ -40,16 +38,7 @@
public static void marshalCallResult(Call call, OutputStream out)
throws IOException
{
- if (call.getId() != null)
- {
- out.write(RESULT_TAG_OPEN_START);
- out.write(call.getId().getBytes());
- out.write(RESULT_TAG_OPEN_END);
- }
- else
- {
- out.write(RESULT_TAG_OPEN);
- }
+ out.write(RESULT_TAG_OPEN);
if (call.getException() != null)
{
@@ -84,14 +73,7 @@
throws IOException
{
out.write(MODEL_TAG_OPEN_START);
- out.write(model.getId().getBytes());
-
- if (model.getCallId() != null)
- {
- out.write("\" callId=\"".getBytes());
- out.write(model.getCallId().getBytes());
- }
-
+ out.write(model.getId().getBytes());
out.write(MODEL_TAG_OPEN_END);
for (String alias : model.getBeanProperties().keySet())
Modified: modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/RequestContext.java
===================================================================
--- modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/RequestContext.java 2009-12-29 09:13:05 UTC (rev 11891)
+++ modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/RequestContext.java 2009-12-30 10:42:54 UTC (rev 11892)
@@ -20,11 +20,17 @@
{
setConversationId(convId.getText());
}
+ Element callId = context.element("callId");
+ if (callId != null)
+ {
+ setCallId(Long.valueOf(callId.getText()));
+ }
}
}
}
private String conversationId;
+ private Long callId;
public String getConversationId()
{
@@ -35,4 +41,14 @@
{
this.conversationId = conversationId;
}
+
+ public Long getCallId()
+ {
+ return callId;
+ }
+
+ public void setCallId(Long callId)
+ {
+ this.callId = callId;
+ }
}
Modified: modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/RequestHandler.java
===================================================================
--- modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/RequestHandler.java 2009-12-29 09:13:05 UTC (rev 11891)
+++ modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/RequestHandler.java 2009-12-30 10:42:54 UTC (rev 11892)
@@ -18,15 +18,12 @@
static final byte[] REF_TAG_OPEN_START = "<ref id=\"".getBytes();
static final byte[] REF_TAG_OPEN_END = "\">".getBytes();
static final byte[] REF_TAG_CLOSE = "</ref>".getBytes();
-
-
static final byte[] HEADER_OPEN = "<header>".getBytes();
static final byte[] HEADER_CLOSE = "</header>".getBytes();
- static final byte[] CONVERSATION_ID_TAG_OPEN = "<conversationId>"
- .getBytes();
- static final byte[] CONVERSATION_ID_TAG_CLOSE = "</conversationId>"
- .getBytes();
-
+ static final byte[] CONVERSATION_ID_TAG_OPEN = "<conversationId>".getBytes();
+ static final byte[] CONVERSATION_ID_TAG_CLOSE = "</conversationId>".getBytes();
+ static final byte[] CALL_ID_TAG_OPEN = "<callId>".getBytes();
+ static final byte[] CALL_ID_TAG_CLOSE = "</callId>".getBytes();
static final byte[] CONTEXT_TAG_OPEN = "<context>".getBytes();
static final byte[] CONTEXT_TAG_CLOSE = "</context>".getBytes();
Modified: modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/model/Model.java
===================================================================
--- modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/model/Model.java 2009-12-29 09:13:05 UTC (rev 11891)
+++ modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/model/Model.java 2009-12-30 10:42:54 UTC (rev 11892)
@@ -31,7 +31,6 @@
private BeanManager beanManager;
private String id;
- private String callId;
private CallContext callContext;
private Call action;
@@ -121,17 +120,7 @@
callContext = new CallContext(beanManager);
beanProperties = new HashMap<String, BeanProperty>();
}
-
- public void setCallId(String callId)
- {
- this.callId = callId;
- }
-
- public String getCallId()
- {
- return callId;
- }
-
+
/**
* Evaluate each of the model's bean properties, expressions, etc and
* store the values in the BeanProperty map.
Modified: modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/model/ModelHandler.java
===================================================================
--- modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/model/ModelHandler.java 2009-12-29 09:13:05 UTC (rev 11891)
+++ modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/model/ModelHandler.java 2009-12-30 10:42:54 UTC (rev 11892)
@@ -93,15 +93,14 @@
for (Element modelElement : (List<Element>) env.element("body").elements("model"))
{
String operation = modelElement.attributeValue("operation");
- String callId = modelElement.attributeValue("callId");
if ("fetch".equals(operation))
{
- processFetchRequest(modelElement, models, callId);
+ processFetchRequest(modelElement, models);
}
else if ("apply".equals(operation))
{
- processApplyRequest(modelElement, models, callId);
+ processApplyRequest(modelElement, models);
}
}
@@ -140,16 +139,15 @@
}
@SuppressWarnings({ "unchecked" })
- private void processFetchRequest(Element modelElement, Set<Model> models, String callId)
+ private void processFetchRequest(Element modelElement, Set<Model> models)
throws Exception
{
Model model = registry.createModel();
- models.add(model);
- model.setCallId(callId);
+ models.add(model);
if (modelElement.elements("action").size() > 0)
{
- unmarshalAction(modelElement.element("action"), model, callId);
+ unmarshalAction(modelElement.element("action"), model);
}
for (Element beanElement : (List<Element>) modelElement.elements("bean"))
@@ -177,7 +175,7 @@
}
@SuppressWarnings("unchecked")
- private void unmarshalAction(Element actionElement, Model model, String callId)
+ private void unmarshalAction(Element actionElement, Model model)
{
Element targetElement = actionElement.element("target");
Element qualifiersElement = actionElement.element("qualifiers");
@@ -185,7 +183,7 @@
Element paramsElement = actionElement.element("params");
Element refsElement = actionElement.element("refs");
- model.setAction(new Call(beanManager, callId, targetElement.getTextTrim(),
+ model.setAction(new Call(beanManager, targetElement.getTextTrim(),
qualifiersElement != null ? qualifiersElement.getTextTrim() : null,
methodElement != null ? methodElement.getTextTrim() : null));
@@ -213,12 +211,11 @@
}
@SuppressWarnings("unchecked")
- private void processApplyRequest(Element modelElement, Set<Model> models, String callId)
+ private void processApplyRequest(Element modelElement, Set<Model> models)
throws Exception
{
Model model = registry.getModel(modelElement.attributeValue("uid"));
models.add(model);
- model.setCallId(callId);
model.setAction(null);
CallContext ctx = new CallContext(beanManager);
@@ -253,7 +250,7 @@
if (modelElement.elements("action").size() > 0)
{
- unmarshalAction(modelElement.element("action"), model, callId);
+ unmarshalAction(modelElement.element("action"), model);
}
if (model.getAction() != null)
Modified: modules/remoting/trunk/src/main/resources/org/jboss/seam/remoting/remote.js
===================================================================
--- modules/remoting/trunk/src/main/resources/org/jboss/seam/remoting/remote.js 2009-12-29 09:13:05 UTC (rev 11891)
+++ modules/remoting/trunk/src/main/resources/org/jboss/seam/remoting/remote.js 2009-12-30 10:42:54 UTC (rev 11892)
@@ -70,14 +70,40 @@
var names = [];
var cb = null;
for (var i=0; i<arguments.length; i++) {
- if (typeof arguments[i] != "function")
- names.push(arguments[i]);
- else
- cb = arguments[i];
+ if (typeof arguments[i] != "function") {
+ if (arguments[i] instanceof Array) {
+ for (var j=0; j<arguments[i].length; j++) {
+ names.push(arguments[i][j]);
+ }
+ } else {
+ names.push(arguments[i]);
+ }
+ } else {
+ cb = arguments[i];
+ }
}
var n = "org.jboss.seam.remoting.BeanMetadata";
if (!Seam.isBeanRegistered(n)) Seam.registerBean(n, {name: "str", methods: "Seam.Map", properties: "Seam.Map"});
- Seam.execute("org.jboss.seam.remoting.MetadataCache", "loadBeans", [names], cb);
+ var callback = function(beans) {
+ for (var i=0; i<beans.length; i++) {
+ var meta = beans[i];
+ if (meta.beanType == "state") {
+ var props = {};
+ for (var j=0;j<meta.properties.elements.length; j++) {
+ props[meta.properties.elements[j].key] = meta.properties.elements[j].value;
+ }
+ Seam.registerBean(meta.name, props);
+ } else if (meta.beanType == "action") {
+ var methods = {};
+ for (var j=0; j<meta.methods.elements.length; j++) {
+ methods[meta.methods.elements[j].key] = meta.methods.elements[j].value;
+ }
+ Seam.registerBean(meta.name, null, methods);
+ }
+ }
+ if (cb) cb();
+ }
+ Seam.execute("org.jboss.seam.remoting.MetadataCache", "loadBeans", [names], callback);
}
Seam.getBeanMetadata = function(obj) {
@@ -129,13 +155,11 @@
Seam.Context = function() {
this.conversationId = null;
- Seam.Context.prototype.setConversationId = function(conversationId) {
- this.conversationId = conversationId;
- }
-
- Seam.Context.prototype.getConversationId = function() {
- return this.conversationId;
- }
+ this.callId = null;
+ Seam.Context.prototype.setConversationId = function(conversationId) { this.conversationId = conversationId; }
+ Seam.Context.prototype.getConversationId = function() { return this.conversationId; }
+ Seam.Context.prototype.setCallId = function(callId) { this.callId = callId; }
+ Seam.Context.prototype.getCallId = function() { return this.callId; }
}
Seam.context = new Seam.Context();
@@ -301,8 +325,7 @@
Seam.createCall = function(component, methodName, params, callback, exceptionHandler) {
var callId = "" + Seam.__callId++;
if (!callback) callback = component.__callback[methodName];
- var d = "<call id=\"" + callId + "\">\n" +
- "<target>" + Seam.getBeanType(component).__name + "</target>";
+ var d = "<call><target>" + Seam.getBeanType(component).__name + "</target>";
if (component.__qualifiers != null) {
d += "<qualifiers>";
for (var i=0; i<component.__qualifiers.length; i++) {
@@ -311,7 +334,7 @@
}
d += "</qualifiers>";
}
- d += "<method>" + methodName + "</method>" + "<params>";
+ d += "<method>" + methodName + "</method><params>";
var refs = [];
for (var i=0; i<params.length; i++) {
d += "<param>" + Seam.serializeValue(params[i], null, refs) + "</param>";
@@ -321,11 +344,11 @@
d += "<ref id=\"" + i + "\">" + Seam.serializeType(refs[i], refs) + "</ref>";
}
d += "</refs></call>";
- return {data: d, id: callId, callback: callback, exceptionHandler: exceptionHandler};
+ return {data: d, id: callId, callback: callback, exceptionHandler: exceptionHandler, handler: Seam.preProcessCallResponse};
}
-Seam.createHeader = function() {
- var h = "<context>";
+Seam.createHeader = function(callId) {
+ var h = "<context><callId>" + callId + "</callId>";
if (Seam.context.getConversationId()) {
h += "<conversationId>" + Seam.context.getConversationId() + "</conversationId>";
}
@@ -343,34 +366,7 @@
Seam.__callId = 0;
Seam.pendingCalls = new Seam.Map();
-Seam.inBatch = false;
-Seam.batchedCalls = [];
-Seam.startBatch = function() {
- Seam.inBatch = true;
- Seam.batchedCalls.length = 0;
-}
-
-Seam.executeBatch = function() {
- if (!Seam.inBatch) return;
- var d = "";
- for (var i=0; i<Seam.batchedCalls.length; i++) {
- Seam.pendingCalls.put(Seam.batchedCalls[i].id, Seam.batchedCalls[i]);
- d += Seam.batchedCalls[i].data;
- }
- var envelope = Seam.createEnvelope(Seam.createHeader(), d);
- Seam.batchAsyncReq = Seam.sendAjaxRequest(envelope, Seam.PATH_EXECUTE,
- Seam.processResponse, false);
- Seam.inBatch = false;
-}
-
-Seam.cancelBatch = function() {
- Seam.inBatch = false;
- for (var i=0; i<Seam.batchedCalls.length; i++) {
- Seam.pendingCalls.remove(Seam.batchedCalls[i].id);
- }
-}
-
Seam.cancelCall = function(callId) {
var c = Seam.pendingCalls.get(callId);
Seam.pendingCalls.remove(callId);
@@ -386,9 +382,9 @@
Seam.execute = function(component, methodName, params, callback, exceptionHandler) {
var c = Seam.createCall(component, methodName, params, callback, exceptionHandler);
if (Seam.inBatch) {
- Seam.batchedCalls[Seam.batchedCalls.length] = c;
+ Seam.batchedCalls.push(c);
} else {
- var envelope = Seam.createEnvelope(Seam.createHeader(), c.data);
+ var envelope = Seam.createEnvelope(Seam.createHeader(c.id), c.data);
Seam.pendingCalls.put(c.id, c);
Seam.sendAjaxRequest(envelope, Seam.PATH_EXECUTE, Seam.processResponse, false);
}
@@ -405,7 +401,6 @@
} else {
r = new ActiveXObject("Microsoft.XMLHTTP");
}
-
r.onreadystatechange = function() {
if (r.readyState == 4) {
var inScope = typeof(Seam) == "undefined" ? false : true;
@@ -452,6 +447,54 @@
r.send(env);
}
+Seam.preProcessCallResponse = function(call) {
+ var cn = Seam.Xml.childNode;
+ var bodyNode = cn(call.response.documentElement, "body");
+ if (bodyNode) {
+ var n = cn(bodyNode, "result");
+ if (n) {
+ var refsNode = cn(n, "refs");
+ var u = Seam.validateRefs(refsNode, call);
+ if (u.length > 0) {
+ // todo load the unknown types
+ } else {
+ Seam.processCallResponse(call);
+ }
+ }
+ }
+}
+
+Seam.processCallResponse = function(call) {
+ var cn = Seam.Xml.childNode;
+ Seam.pendingCalls.remove(call.callId);
+ var n = cn(cn(call.response.documentElement, "body"), "result");
+ var valueNode = cn(n, "value");
+ var exceptionNode = cn(n, "exception");
+ if (exceptionNode != null && call.exceptionHandler != null) {
+ var msgNode = cn(exceptionNode, "message");
+ var msg = Seam.unmarshalValue(msgNode.firstChild);
+ call.exceptionHandler(new Seam.Exception(msg));
+ } else if (call.callback != null) {
+ var refsNode = cn(n, "refs");
+ var refs = Seam.unmarshalRefs(refsNode);
+ var v = Seam.unmarshalValue(valueNode.firstChild, refs);
+ call.callback(v, call.context);
+ }
+}
+
+Seam.preProcessModelResponse = function(call) {
+ var bodyNode = cn(doc.documentElement, "body");
+ if (bodyNode) {
+ var n = Seam.Xml.childNodes(bodyNode, "model");
+ for (var i=0; i<n.length; i++) {
+ var callId = n[i].getAttribute("callId");
+ var call = Seam.pendingCalls.get(callId);
+ Seam.pendingCalls.remove(callId);
+ if (call.model) call.model.processResponse(n[i]);
+ }
+ }
+}
+
Seam.displayError = function(code) {
alert("There was an error processing your request. Error code: " + code);
}
@@ -466,50 +509,49 @@
if (!doc.documentElement) return;
var ctx = new Seam.Context;
var headerNode = cn(doc.documentElement, "header");
- var bodyNode = cn(doc.documentElement, "body");
if (headerNode) {
var contextNode = cn(headerNode, "context");
if (contextNode) {
Seam.unmarshalContext(contextNode, ctx);
- }
- }
- Seam.context.setConversationId(ctx.getConversationId() ? ctx.getConversationId() : null);
- if (bodyNode) {
- var n = cn(bodyNode, "result");
- if (n) {
- var callId = n.getAttribute("id");
- var call = Seam.pendingCalls.get(callId);
- Seam.pendingCalls.remove(callId);
- if (call && (call.callback || call.exceptionHandler)) {
- var valueNode = cn(n, "value");
- var refsNode = cn(n, "refs");
- var exceptionNode = cn(n, "exception");
- if (exceptionNode != null) {
- var msgNode = cn(exceptionNode, "message");
- var msg = Seam.unmarshalValue(msgNode.firstChild);
- call.exceptionHandler(new Seam.Exception(msg));
- } else {
- var refs = Seam.unmarshalRefs(refsNode);
- var v = Seam.unmarshalValue(valueNode.firstChild, refs);
- call.callback(v, ctx, callId);
- }
+ var call = Seam.pendingCalls.get(ctx.getCallId());
+ Seam.context.setConversationId(ctx.getConversationId() ? ctx.getConversationId() : null);
+ if (call) {
+ call.context = ctx;
+ call.response = doc;
+ if (call.handler) call.handler(call);
}
}
- var n = Seam.Xml.childNodes(bodyNode, "model");
- for (var i=0; i<n.length; i++) {
- var callId = n[i].getAttribute("callId");
- var call = Seam.pendingCalls.get(callId);
- Seam.pendingCalls.remove(callId);
- if (call.model) call.model.processResponse(n[i]);
- }
}
}
+Seam.processLoadTypes = function(callId) {
+ var call = Seam.pendingCalls.get(callId);
+ if (call) {
+ Seam.pendingCalls.remove(callId);
+ if (call.model) call.model.processResponse(call.model.modelNode, true);
+ }
+}
+
Seam.unmarshalContext = function(ctxNode, context) {
var c = Seam.Xml.childNode(ctxNode, "conversationId");
if (c) context.setConversationId(c.firstChild.nodeValue);
+ c = Seam.Xml.childNode(ctxNode, "callId");
+ if (c) context.setCallId(c.firstChild.nodeValue);
}
+Seam.validateRefs = function(refsNode) {
+ var unknowns = [];
+ var cn = Seam.Xml.childNodes(refsNode, "ref");
+ for (var i=0; i<cn.length; i++) {
+ var n = cn[i].firstChild;
+ if (n.tagName == "bean") {
+ var name = n.getAttribute("type");
+ if (!Seam.isBeanRegistered(name)) unknowns.push(name);
+ }
+ }
+ return unknowns;
+}
+
Seam.unmarshalRefs = function(refsNode) {
if (!refsNode) return;
var refs = [];
@@ -826,7 +868,7 @@
Seam.Model.prototype.fetch = function(action, callback) {
this.callback = callback;
var r = this.createFetchRequest(action);
- var env = Seam.createEnvelope(Seam.createHeader(), r.data);
+ var env = Seam.createEnvelope(Seam.createHeader(r.id), r.data);
Seam.pendingCalls.put(r.id, r);
Seam.sendAjaxRequest(env, Seam.PATH_MODEL, Seam.processResponse, false);
}
@@ -882,19 +924,18 @@
}
}
d += "</model>";
- return {data:d, id:callId, model:this};
+ return {data:d, id:callId, model:this, handler: null};
}
Seam.Model.prototype.processResponse = function(modelNode) {
+ var refsNode = Seam.Xml.childNode(modelNode, "refs");
this.id = modelNode.getAttribute("uid");
- var valueNodes = Seam.Xml.childNodes(modelNode, "value");
- var refsNode = Seam.Xml.childNode(modelNode, "refs");
+ var valueNodes = Seam.Xml.childNodes(modelNode, "value");
this.sourceRefs = Seam.unmarshalRefs(refsNode);
this.workingRefs = Seam.cloneObject(this.sourceRefs);
for (var i=0; i<valueNodes.length; i++) {
var value = Seam.unmarshalValue(valueNodes[i].firstChild,this.workingRefs);
this.values.push({alias:valueNodes[i].getAttribute("alias"),value:value, refIndex:i});
-
}
if (this.callback) this.callback(this);
}
@@ -905,7 +946,7 @@
d.scanForChanges(this.values[i].value);
}
var r = this.createApplyRequest(a, d);
- var env = Seam.createEnvelope(Seam.createHeader(), r.data);
+ var env = Seam.createEnvelope(Seam.createHeader(r.id), r.data);
Seam.pendingCalls.put(r.id, r);
Seam.sendAjaxRequest(env, Seam.PATH_MODEL, Seam.processResponse, false);
}
@@ -963,7 +1004,7 @@
d += "</refs>";
}
d += "</model>";
- return {data:d, id:callId, model:this};
+ return {data:d, id:callId, model:this, handler: null};
}
Seam.Model.prototype.getRefId = function(v) {
15 years
Seam SVN: r11891 - modules/remoting/trunk/src/main/resources/org/jboss/seam/remoting.
by seam-commits@lists.jboss.org
Author: shane.bryzak(a)jboss.com
Date: 2009-12-29 04:13:05 -0500 (Tue, 29 Dec 2009)
New Revision: 11891
Modified:
modules/remoting/trunk/src/main/resources/org/jboss/seam/remoting/remote.js
Log:
trim some more fat off remote.js
Modified: modules/remoting/trunk/src/main/resources/org/jboss/seam/remoting/remote.js
===================================================================
--- modules/remoting/trunk/src/main/resources/org/jboss/seam/remoting/remote.js 2009-12-29 08:40:04 UTC (rev 11890)
+++ modules/remoting/trunk/src/main/resources/org/jboss/seam/remoting/remote.js 2009-12-29 09:13:05 UTC (rev 11891)
@@ -12,7 +12,7 @@
if (!Seam.beans[name]) return null;
var b = new Seam.beans[name];
if (arguments.length > 1) {
- b.__qualifiers = new Array();
+ b.__qualifiers = [];
for (var i=1; i<arguments.length; i++) {
b.__qualifiers.push(arguments[i]);
}
@@ -41,7 +41,7 @@
var t = function() {};
t.__name = name;
if (metadata) {
- var m = new Array();
+ var m = [];
for (var f in metadata) {
var s = f.substring(0,1).toUpperCase() + f.substring(1);
t.prototype["set" + s] = function(value) { this[f] = value; };
@@ -53,7 +53,7 @@
for (var m in methods) {
var pc = methods[m];
t.prototype[m] = function() {
- var p = new Array();
+ var p = [];
for (var i=0; i<pc; i++) {
p[i] = arguments[i];
}
@@ -67,10 +67,17 @@
}
Seam.loadBeans = function() {
+ var names = [];
+ var cb = null;
+ for (var i=0; i<arguments.length; i++) {
+ if (typeof arguments[i] != "function")
+ names.push(arguments[i]);
+ else
+ cb = arguments[i];
+ }
var n = "org.jboss.seam.remoting.BeanMetadata";
if (!Seam.isBeanRegistered(n)) Seam.registerBean(n, {name: "str", methods: "Seam.Map", properties: "Seam.Map"});
- var cb = function() {};
- Seam.execute("org.jboss.seam.remoting.MetadataCache", "loadBeans", arguments, cb);
+ Seam.execute("org.jboss.seam.remoting.MetadataCache", "loadBeans", [names], cb);
}
Seam.getBeanMetadata = function(obj) {
@@ -85,7 +92,7 @@
}
},
childNodes: function(e, tag) {
- var n = new Array();
+ var n = [];
for (var i=0; i<e.childNodes.length;i++) {
if (e.childNodes.item(i).tagName == tag) n.push(e.childNodes.item(i));
}
@@ -147,7 +154,7 @@
}
Seam.Map = function() {
- this.elements = new Array();
+ this.elements = [];
Seam.Map.prototype.size = function() {
return this.elements.length;
}
@@ -155,14 +162,14 @@
return this.elements.length == 0;
}
Seam.Map.prototype.keySet = function() {
- var keySet = new Array();
+ var keySet = [];
for (var i=0; i<this.elements.length; i++) {
keySet[keySet.length] = this.elements[i].key;
}
return keySet;
}
Seam.Map.prototype.values = function() {
- var vals = new Array();
+ var vals = [];
for (var i=0; i<this.elements.length; i++) {
vals.push(this.elements[i].value);
}
@@ -305,7 +312,7 @@
d += "</qualifiers>";
}
d += "<method>" + methodName + "</method>" + "<params>";
- var refs = new Array();
+ var refs = [];
for (var i=0; i<params.length; i++) {
d += "<param>" + Seam.serializeValue(params[i], null, refs) + "</param>";
}
@@ -337,7 +344,7 @@
Seam.__callId = 0;
Seam.pendingCalls = new Seam.Map();
Seam.inBatch = false;
-Seam.batchedCalls = new Array();
+Seam.batchedCalls = [];
Seam.startBatch = function() {
Seam.inBatch = true;
@@ -505,8 +512,8 @@
Seam.unmarshalRefs = function(refsNode) {
if (!refsNode) return;
- var refs = new Array();
- var objs = new Array();
+ var refs = [];
+ var objs = [];
var cn = Seam.Xml.childNodes(refsNode, "ref");
for (var i=0; i<cn.length; i++) {
var refId = parseInt(cn[i].getAttribute("id"));
@@ -549,7 +556,7 @@
return decodeURIComponent(data);
case "ref": return refs[parseInt(element.getAttribute("id"))];
case "bag":
- var value = new Array();
+ var value = [];
var cn = Seam.Xml.childNodes(element, "element");
for (var i=0; i<cn.length; i++) {
value.push(Seam.unmarshalValue(cn[i].firstChild, refs));
@@ -575,7 +582,7 @@
if (obj == null) return null;
var m = (refMap == null) ? new Seam.Map() : refMap;
if (obj instanceof Array) {
- var c = new Array();
+ var c = [];
m.put(obj, c);
for (var i=0; i<obj.length; i++) {
c[i] = Seam.cloneObject(obj[i], m);
@@ -639,7 +646,7 @@
this.beanType = null;
this.qualifiers = null;
this.method = null;
- this.params = new Array();
+ this.params = [];
this.expression = null;
Seam.Action.prototype.setBeanType = function(beanType) {
this.beanType = beanType;
@@ -764,7 +771,7 @@
}
Seam.Delta.prototype.buildRefs = function() {
- var refs = new Array();
+ var refs = [];
for (var i=0; i<this.refs.elements.length; i++) {
refs.push(this.refs.elements[i]);
}
@@ -774,11 +781,11 @@
Seam.Model = function() {
this.id = null;
- this.expressions = new Array();
- this.beans = new Array();
- this.values = new Array();
- this.sourceRefs = new Array();
- this.workingRefs = new Array();
+ this.expressions = [];
+ this.beans = [];
+ this.values = [];
+ this.sourceRefs = [];
+ this.workingRefs = [];
this.callback = null;
Seam.Model.prototype.addExpression = function(alias, expr) {
@@ -797,7 +804,7 @@
Seam.Model.prototype.addBean = function(alias, bean) {
var q = null;
if (arguments.length > 2) {
- q = new Array();
+ q = [];
for (var i=2; i<arguments.length; i++) {
q.push(arguments[i]);
}
@@ -808,7 +815,7 @@
Seam.Model.prototype.addBeanProperty = function(alias, bean, property) {
var q = null;
if (arguments.length > 3) {
- q = new Array();
+ q = [];
for (var i=3; i<arguments.length; i++) {
q.push(arguments[i]);
}
@@ -827,7 +834,7 @@
Seam.Model.prototype.createFetchRequest = function(a) {
var callId = "" + Seam.__callId++;
var d = "<model operation=\"fetch\" callId=\"" + callId + "\">";
- var refs = new Array();
+ var refs = [];
if (a) {
d += "<action>";
if (a.beanType) {
15 years
Seam SVN: r11890 - in modules/remoting/trunk/src/main: resources/org/jboss/seam/remoting and 1 other directory.
by seam-commits@lists.jboss.org
Author: shane.bryzak(a)jboss.com
Date: 2009-12-29 03:40:04 -0500 (Tue, 29 Dec 2009)
New Revision: 11890
Modified:
modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/InterfaceGenerator.java
modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/MetadataCache.java
modules/remoting/trunk/src/main/resources/org/jboss/seam/remoting/remote.js
Log:
simplify InterfaceGenerator even further, added loadBeans() remotable method
Modified: modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/InterfaceGenerator.java
===================================================================
--- modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/InterfaceGenerator.java 2009-12-29 04:20:43 UTC (rev 11889)
+++ modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/InterfaceGenerator.java 2009-12-29 08:40:04 UTC (rev 11890)
@@ -1,24 +1,16 @@
package org.jboss.seam.remoting;
-import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Enumeration;
-import java.util.HashMap;
import java.util.HashSet;
-import java.util.Map;
import java.util.Set;
-import javax.enterprise.inject.spi.Bean;
-import javax.enterprise.inject.spi.BeanManager;
import javax.inject.Inject;
-import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.jboss.seam.remoting.BeanMetadata.BeanType;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* Generates JavaScript interface code.
@@ -26,16 +18,8 @@
* @author Shane Bryzak
*/
public class InterfaceGenerator implements RequestHandler
-{
- private static final Logger log = LoggerFactory.getLogger(InterfaceGenerator.class);
-
- @Inject BeanManager beanManager;
+{
@Inject MetadataCache metadataCache;
-
- /**
- * A cache of component interfaces, keyed by name.
- */
- private Map<Class<?>, byte[]> interfaceCache = new HashMap<Class<?>, byte[]>();
/**
* Handles the request
@@ -48,119 +32,29 @@
response.sendError(HttpServletResponse.SC_BAD_REQUEST,
"Invalid request - no component specified");
}
-
- Set<Class<?>> typesCached = new HashSet<Class<?>>();
+
response.setContentType("text/javascript");
+ Set<String> names = new HashSet<String>();
Enumeration<?> e = request.getParameterNames();
while (e.hasMoreElements())
{
- String componentName = ((String) e.nextElement()).trim();
- Class<?> beanClass = null;
-
- Set<Bean<?>> beans = beanManager.getBeans(componentName);
-
- if (!beans.isEmpty())
- {
- beanClass = beans.iterator().next().getBeanClass();
- }
- else
- {
- try
- {
- beanClass = Class.forName(componentName);
- }
- catch (ClassNotFoundException ex)
- {
- log.error(String.format("Component not found: [%s]",
- componentName));
- response.sendError(HttpServletResponse.SC_NOT_FOUND,
- String.format("Component not found: [%s]", componentName));
- }
- }
-
- typesCached.add(beanClass);
+ names.add(((String) e.nextElement()).trim());
}
- generateBeanInterface(typesCached, response.getOutputStream(), null);
+ appendBeanSource(response.getOutputStream(), metadataCache.loadBeans(names));
}
/**
- * Generates the JavaScript code required to invoke the methods of a bean.
+ * Appends the interface code for a set of bean classes to an OutputStream.
*
- * @param classes Set<Class<?>> The bean classes for which to generate JavaScript stubs
- * @param out OutputStream The OutputStream to write the generated JavaScript
- * @param types Set<Type> Used to keep track of which bean classes have been
- * generated, can be null
- * @throws IOException Thrown if there is an error writing to the OutputStream
- */
- public void generateBeanInterface(Set<Class<?>> classes, OutputStream out,
- Set<BeanMetadata> types) throws IOException
- {
- if (types == null)
- {
- types = new HashSet<BeanMetadata>();
- }
-
- for (Class<?> beanClass : classes)
- {
- if (beanClass != null)
- {
- if (!interfaceCache.containsKey(beanClass))
- {
- synchronized (interfaceCache)
- {
- if (!interfaceCache.containsKey(beanClass))
- {
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- addDependency(beanClass, types);
- appendBeanSource(bOut, beanClass, types);
- interfaceCache.put(beanClass, bOut.toByteArray());
- }
- }
- }
- out.write(interfaceCache.get(beanClass));
- }
- }
- }
-
- /**
- * Appends component interface code to an OutputStream for a specified
- * component.
- *
- * @param out OutputStream The OutputStream to write to
- * @param beanClass Class<?> The bean class to generate an interface for
- * @param types
- * Set A list of types that have already been generated for this
- * request. If this component has already been generated (i.e. it
- * is in the list) then it won't be generated again
- * @throws IOException
- * If there is an error writing to the OutputStream.
- */
- private void addDependency(Class<?> beanClass, Set<BeanMetadata> types)
- throws IOException
- {
- types.add(metadataCache.getMetadata(beanClass));
-
- for (Class<?> dependencyClass : metadataCache.getDependencies(beanClass))
- {
- if (!types.contains(dependencyClass))
- {
- addDependency(dependencyClass, types);
- }
- }
- }
-
- /**
- * Appends the interface code for a JavaBean (state holding) class to an OutputStream.
- *
* @param out OutputStream
* @param classType Class<?>
* @param types Set<Type>
* @throws IOException
*/
- private void appendBeanSource(OutputStream out, Class<?> classType,
- Set<BeanMetadata> types) throws IOException
+ private void appendBeanSource(OutputStream out, Set<BeanMetadata> types)
+ throws IOException
{
StringBuilder src = new StringBuilder();
Modified: modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/MetadataCache.java
===================================================================
--- modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/MetadataCache.java 2009-12-29 04:20:43 UTC (rev 11889)
+++ modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/MetadataCache.java 2009-12-29 08:40:04 UTC (rev 11890)
@@ -1,5 +1,6 @@
package org.jboss.seam.remoting;
+import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
@@ -16,11 +17,15 @@
import java.util.Set;
import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import javax.inject.Inject;
+import javax.servlet.http.HttpServletResponse;
import org.jboss.seam.remoting.BeanMetadata.BeanType;
import org.jboss.seam.remoting.annotations.WebRemote;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Caches BeanMetadata instances
@@ -30,6 +35,8 @@
@ApplicationScoped
public class MetadataCache
{
+ private static final Logger log = LoggerFactory.getLogger(MetadataCache.class);
+
private Map<Class<?>,BeanMetadata> metadataCache;
private Map<Class<?>, Set<Class<?>>> beanDependencies;
@@ -77,6 +84,53 @@
}
}
+ @WebRemote
+ public Set<BeanMetadata> loadBeans(Set<String> names)
+ {
+ Set<BeanMetadata> meta = new HashSet<BeanMetadata>();
+
+ for (String name : names)
+ {
+ Class<?> beanClass = null;
+
+ Set<Bean<?>> beans = beanManager.getBeans(name);
+
+ if (!beans.isEmpty())
+ {
+ beanClass = beans.iterator().next().getBeanClass();
+ }
+ else
+ {
+ try
+ {
+ beanClass = Class.forName(name);
+ }
+ catch (ClassNotFoundException ex)
+ {
+ log.error(String.format("Component not found: [%s]", name));
+ throw new IllegalArgumentException(String.format("Component not found: [%s]", name));
+ }
+ }
+
+ addBeanDependencies(beanClass, meta);
+ }
+
+ return meta;
+ }
+
+ private void addBeanDependencies(Class<?> beanClass, Set<BeanMetadata> types)
+ {
+ types.add(getMetadata(beanClass));
+
+ for (Class<?> dependencyClass : getDependencies(beanClass))
+ {
+ if (!types.contains(dependencyClass))
+ {
+ addBeanDependencies(dependencyClass, types);
+ }
+ }
+ }
+
private BeanMetadata generateBeanMetadata(Class<?> beanClass)
{
BeanType beanType = BeanType.state;
Modified: modules/remoting/trunk/src/main/resources/org/jboss/seam/remoting/remote.js
===================================================================
--- modules/remoting/trunk/src/main/resources/org/jboss/seam/remoting/remote.js 2009-12-29 04:20:43 UTC (rev 11889)
+++ modules/remoting/trunk/src/main/resources/org/jboss/seam/remoting/remote.js 2009-12-29 08:40:04 UTC (rev 11890)
@@ -32,7 +32,12 @@
return t ? t.__name : undefined;
}
+Seam.isBeanRegistered = function(name) {
+ return Seam.beans[name] != null;
+}
+
Seam.registerBean = function(name, metadata, methods) {
+ if (Seam.isBeanRegistered(name)) return;
var t = function() {};
t.__name = name;
if (metadata) {
@@ -61,8 +66,11 @@
Seam.beans[name] = t;
}
-Seam.isBeanRegistered = function(name) {
- return Seam.beans[name] != null;
+Seam.loadBeans = function() {
+ var n = "org.jboss.seam.remoting.BeanMetadata";
+ if (!Seam.isBeanRegistered(n)) Seam.registerBean(n, {name: "str", methods: "Seam.Map", properties: "Seam.Map"});
+ var cb = function() {};
+ Seam.execute("org.jboss.seam.remoting.MetadataCache", "loadBeans", arguments, cb);
}
Seam.getBeanMetadata = function(obj) {
15 years
Seam SVN: r11889 - in modules/remoting/trunk/src/main: java/org/jboss/seam/remoting/wrapper and 1 other directories.
by seam-commits@lists.jboss.org
Author: shane.bryzak(a)jboss.com
Date: 2009-12-28 23:20:43 -0500 (Mon, 28 Dec 2009)
New Revision: 11889
Added:
modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/BeanMetadata.java
modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/MetadataCache.java
Modified:
modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/InterfaceGenerator.java
modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/wrapper/BeanWrapper.java
modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/wrapper/WrapperFactory.java
modules/remoting/trunk/src/main/resources/org/jboss/seam/remoting/remote.js
Log:
refactored InterfaceGenerator in preparation for dynamic type loading
Added: modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/BeanMetadata.java
===================================================================
--- modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/BeanMetadata.java (rev 0)
+++ modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/BeanMetadata.java 2009-12-29 04:20:43 UTC (rev 11889)
@@ -0,0 +1,66 @@
+package org.jboss.seam.remoting;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Contains the metadata (either the accessible properties or invokable methods)
+ * for a single action or state bean.
+ *
+ * @author Shane Bryzak
+ */
+public class BeanMetadata
+{
+ public enum BeanType {action, state}
+
+ private BeanType beanType;
+
+ private String name;
+ private Map<String,Integer> methods;
+ private Map<String,String> properties;
+
+ public BeanMetadata(BeanType beanType, String name)
+ {
+ this.beanType = beanType;
+ this.name = name;
+
+ if (beanType == BeanType.action)
+ {
+ methods = new HashMap<String,Integer>();
+ }
+ else
+ {
+ properties = new HashMap<String,String>();
+ }
+ }
+
+ public BeanType getBeanType()
+ {
+ return beanType;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public void addMethod(String name, int paramCount)
+ {
+ methods.put(name, paramCount);
+ }
+
+ public void addProperty(String name, String remotingType)
+ {
+ properties.put(name, remotingType);
+ }
+
+ public Map<String,Integer> getMethods()
+ {
+ return methods;
+ }
+
+ public Map<String,String> getProperties()
+ {
+ return properties;
+ }
+}
Modified: modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/InterfaceGenerator.java
===================================================================
--- modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/InterfaceGenerator.java 2009-12-28 22:39:01 UTC (rev 11888)
+++ modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/InterfaceGenerator.java 2009-12-29 04:20:43 UTC (rev 11889)
@@ -3,16 +3,6 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.Calendar;
-import java.util.Collection;
-import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
@@ -26,7 +16,7 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.jboss.seam.remoting.annotations.WebRemote;
+import org.jboss.seam.remoting.BeanMetadata.BeanType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -40,36 +30,26 @@
private static final Logger log = LoggerFactory.getLogger(InterfaceGenerator.class);
@Inject BeanManager beanManager;
+ @Inject MetadataCache metadataCache;
/**
- * Maintain a cache of the accessible fields
- */
- private static Map<Class<?>, Set<String>> accessibleProperties = new HashMap<Class<?>, Set<String>>();
-
- /**
* A cache of component interfaces, keyed by name.
*/
private Map<Class<?>, byte[]> interfaceCache = new HashMap<Class<?>, byte[]>();
/**
- *
- * @param request
- * HttpServletRequest
- * @param response
- * HttpServletResponse
- * @throws Exception
+ * Handles the request
*/
public void handle(final HttpServletRequest request,
final HttpServletResponse response) throws Exception
{
if (request.getQueryString() == null)
{
- throw new ServletException("Invalid request - no component specified");
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST,
+ "Invalid request - no component specified");
}
Set<Class<?>> typesCached = new HashSet<Class<?>>();
- Set<Type> types = new HashSet<Type>();
-
response.setContentType("text/javascript");
Enumeration<?> e = request.getParameterNames();
@@ -94,187 +74,62 @@
{
log.error(String.format("Component not found: [%s]",
componentName));
- throw new ServletException(
- "Invalid request - component not found.");
+ response.sendError(HttpServletResponse.SC_NOT_FOUND,
+ String.format("Component not found: [%s]", componentName));
}
}
typesCached.add(beanClass);
}
- generateBeanInterface(typesCached, response.getOutputStream(), types);
+ generateBeanInterface(typesCached, response.getOutputStream(), null);
}
/**
- * Generates the JavaScript code required to invoke the methods of a
- * component/s.
+ * Generates the JavaScript code required to invoke the methods of a bean.
*
- * @param components
- * Component[] The components to generate javascript for
- * @param out
- * OutputStream The OutputStream to write the generated javascript
- * to
- * @throws IOException
- * Thrown if there is an error writing to the OutputStream
+ * @param classes Set<Class<?>> The bean classes for which to generate JavaScript stubs
+ * @param out OutputStream The OutputStream to write the generated JavaScript
+ * @param types Set<Type> Used to keep track of which bean classes have been
+ * generated, can be null
+ * @throws IOException Thrown if there is an error writing to the OutputStream
*/
public void generateBeanInterface(Set<Class<?>> classes, OutputStream out,
- Set<Type> types) throws IOException
+ Set<BeanMetadata> types) throws IOException
{
- for (Class<?> cls : classes)
+ if (types == null)
{
- if (cls != null)
+ types = new HashSet<BeanMetadata>();
+ }
+
+ for (Class<?> beanClass : classes)
+ {
+ if (beanClass != null)
{
- if (!interfaceCache.containsKey(cls))
+ if (!interfaceCache.containsKey(beanClass))
{
synchronized (interfaceCache)
{
- if (!interfaceCache.containsKey(cls))
+ if (!interfaceCache.containsKey(beanClass))
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- appendBeanSource(bOut, cls, types);
- interfaceCache.put(cls, bOut.toByteArray());
+ addDependency(beanClass, types);
+ appendBeanSource(bOut, beanClass, types);
+ interfaceCache.put(beanClass, bOut.toByteArray());
}
}
}
- out.write(interfaceCache.get(cls));
+ out.write(interfaceCache.get(beanClass));
}
}
}
/**
- * A helper method, used internally by InterfaceGenerator and also when
- * serializing responses. Returns a list of the property names for the
- * specified class which should be included in the generated interface for
- * the type.
- *
- * @param cls
- * Class
- * @return List
- */
- public static Set<String> getAccessibleProperties(Class<?> cls)
- {
- /**
- * @todo This is a hack to get the "real" class - find out if there is an
- * API method in CGLIB that can be used instead
- */
- if (cls.getName().contains("EnhancerByCGLIB"))
- cls = cls.getSuperclass();
-
- if (!accessibleProperties.containsKey(cls))
- {
- synchronized (accessibleProperties)
- {
- if (!accessibleProperties.containsKey(cls))
- {
- Set<String> properties = new HashSet<String>();
-
- Class<?> c = cls;
- while (c != null && !c.equals(Object.class))
- {
- for (Field f : c.getDeclaredFields())
- {
- if (!Modifier.isTransient(f.getModifiers())
- && !Modifier.isStatic(f.getModifiers()))
- {
- String fieldName = f.getName().substring(0, 1)
- .toUpperCase()
- + f.getName().substring(1);
- String getterName = String.format("get%s", fieldName);
- String setterName = String.format("set%s", fieldName);
- Method getMethod = null;
- Method setMethod = null;
-
- try
- {
- getMethod = c.getMethod(getterName);
- }
- catch (SecurityException ex)
- {
- }
- catch (NoSuchMethodException ex)
- {
- // it might be an "is" method...
- getterName = String.format("is%s", fieldName);
- try
- {
- getMethod = c.getMethod(getterName);
- }
- catch (NoSuchMethodException ex2)
- { /* don't care */
- }
- }
-
- try
- {
- setMethod = c.getMethod(setterName, new Class[] { f
- .getType() });
- }
- catch (SecurityException ex)
- {
- }
- catch (NoSuchMethodException ex)
- { /* don't care */
- }
-
- if (Modifier.isPublic(f.getModifiers())
- || (getMethod != null
- && Modifier.isPublic(getMethod
- .getModifiers()) || (setMethod != null && Modifier
- .isPublic(setMethod.getModifiers()))))
- {
- properties.add(f.getName());
- }
- }
- }
-
- //
- for (Method m : c.getDeclaredMethods())
- {
- if (m.getName().startsWith("get")
- || m.getName().startsWith("is"))
- {
- int startIdx = m.getName().startsWith("get") ? 3 : 2;
-
- try
- {
- c.getMethod(String.format("set%s", m.getName()
- .substring(startIdx)), m.getReturnType());
- }
- catch (NoSuchMethodException ex)
- {
- continue;
- }
-
- String propertyName = String.format("%s%s", Character
- .toLowerCase(m.getName().charAt(startIdx)), m
- .getName().substring(startIdx + 1));
-
- if (!properties.contains(propertyName))
- {
- properties.add(propertyName);
- }
- }
- }
-
- c = c.getSuperclass();
- }
-
- accessibleProperties.put(cls, properties);
- }
- }
- }
-
- return accessibleProperties.get(cls);
- }
-
- /**
- * Appends component interface code to an outputstream for a specified
+ * Appends component interface code to an OutputStream for a specified
* component.
*
- * @param out
- * OutputStream The OutputStream to write to
- * @param component
- * Component The component to generate an interface for
+ * @param out OutputStream The OutputStream to write to
+ * @param beanClass Class<?> The bean class to generate an interface for
* @param types
* Set A list of types that have already been generated for this
* request. If this component has already been generated (i.e. it
@@ -282,366 +137,85 @@
* @throws IOException
* If there is an error writing to the OutputStream.
*/
- private void appendBeanSource(OutputStream out, Class<?> beanClass, Set<Type> types)
+ private void addDependency(Class<?> beanClass, Set<BeanMetadata> types)
throws IOException
{
- Set<Class<?>> componentTypes = new HashSet<Class<?>>();
-
- // Check if any of the methods are annotated with @WebRemote, and if so
- // treat it as an "action" component instead of a type component
- for (Method m : beanClass.getDeclaredMethods())
+ types.add(metadataCache.getMetadata(beanClass));
+
+ for (Class<?> dependencyClass : metadataCache.getDependencies(beanClass))
{
- if (m.getAnnotation(WebRemote.class) != null)
+ if (!types.contains(dependencyClass))
{
- componentTypes.add(beanClass);
- break;
+ addDependency(dependencyClass, types);
}
- }
-
- if (componentTypes.isEmpty())
- {
- appendTypeSource(out, beanClass, types);
- return;
- }
-
- // If types already contains all the component types, then return
- boolean foundNew = false;
- for (Class<?> type : componentTypes)
- {
- if (!types.contains(type))
- {
- foundNew = true;
- break;
- }
- }
-
- if (!foundNew)
- {
- return;
- }
-
- String name = beanManager.getBeans(beanClass).iterator().next().getName();
- String beanName = name != null ? name : beanClass.getName();
-
- for (Class<?> type : componentTypes)
- {
- if (types.contains(type))
- {
- break;
- }
- else
- {
- types.add(type);
-
- // Build the bean stub
- StringBuilder componentSrc = new StringBuilder();
- componentSrc.append("Seam.registerBean(\"");
- componentSrc.append(beanName);
- componentSrc.append("\", null, {");
-
- boolean first = true;
- for (Method m : type.getDeclaredMethods())
- {
- if (m.getAnnotation(WebRemote.class) == null)
- continue;
-
- if (!first)
- {
- componentSrc.append(", ");
- }
- else
- {
- first = false;
- }
-
- // Append the return type to the source block
- appendTypeSource(out, m.getGenericReturnType(), types);
-
- componentSrc.append(m.getName());
- componentSrc.append(": ");
- componentSrc.append(m.getGenericParameterTypes().length);
-
- for (int i = 0; i < m.getGenericParameterTypes().length; i++)
- {
- appendTypeSource(out, m.getGenericParameterTypes()[i], types);
- }
- }
- componentSrc.append("});\n");
- out.write(componentSrc.toString().getBytes());
- }
- }
+ }
}
/**
- * Append Javascript interface code for a specified class to a block of code.
+ * Appends the interface code for a JavaBean (state holding) class to an OutputStream.
*
- * @param source
- * StringBuilder The code block to append to
- * @param type
- * Class The type to generate a Javascript interface for
- * @param types
- * Set A list of the types already generated (only include each
- * type once).
- */
- private void appendTypeSource(OutputStream out, Type type, Set<Type> types)
- throws IOException
- {
- if (type instanceof Class<?>)
- {
- Class<?> classType = (Class<?>) type;
-
- if (classType.isArray())
- {
- appendTypeSource(out, classType.getComponentType(), types);
- return;
- }
-
- if (classType.getName().startsWith("java.") || types.contains(type)
- || classType.isPrimitive())
- {
- return;
- }
-
- // Keep track of which types we've already added
- types.add(type);
-
- appendClassSource(out, classType, types);
- }
- else if (type instanceof ParameterizedType)
- {
- for (Type t : ((ParameterizedType) type).getActualTypeArguments())
- {
- appendTypeSource(out, t, types);
- }
- }
- }
-
- /**
- * Appends the interface code for a non-component class to an OutputStream.
- *
- * @param out
- * OutputStream
- * @param classType
- * Class
- * @param types
- * Set
+ * @param out OutputStream
+ * @param classType Class<?>
+ * @param types Set<Type>
* @throws IOException
*/
- private void appendClassSource(OutputStream out, Class<?> classType,
- Set<Type> types) throws IOException
+ private void appendBeanSource(OutputStream out, Class<?> classType,
+ Set<BeanMetadata> types) throws IOException
{
- // Don't generate interfaces for enums
- if (classType.isEnum())
- {
- return;
- }
-
- Bean<?> bean = beanManager.getBeans(classType).iterator().next();
+ StringBuilder src = new StringBuilder();
- String componentName = bean.getName();
- if (componentName == null)
- componentName = classType.getName();
-
- Map<String, String> metadata = new HashMap<String, String>();
-
- String getMethodName = null;
- String setMethodName = null;
-
- for (String propertyName : getAccessibleProperties(classType))
- {
- Type propertyType = null;
-
- Field f = null;
- try
+ for (BeanMetadata meta : types)
+ {
+ if (meta.getBeanType() == BeanType.action)
{
- f = classType.getDeclaredField(propertyName);
- propertyType = f.getGenericType();
- }
- catch (NoSuchFieldException ex)
- {
- setMethodName = String.format("set%s%s", Character
- .toUpperCase(propertyName.charAt(0)), propertyName
- .substring(1));
-
- try
- {
- getMethodName = String.format("get%s%s", Character
- .toUpperCase(propertyName.charAt(0)), propertyName
- .substring(1));
- propertyType = classType.getMethod(getMethodName)
- .getGenericReturnType();
- }
- catch (NoSuchMethodException ex2)
- {
- try
+ src.append("Seam.registerBean(\"");
+ src.append(meta.getName());
+ src.append("\", null, {");
+
+ boolean first = true;
+ for (String methodName : meta.getMethods().keySet())
+ {
+ if (!first)
{
- getMethodName = String.format("is%s%s", Character
- .toUpperCase(propertyName.charAt(0)), propertyName
- .substring(1));
-
- propertyType = classType.getMethod(getMethodName)
- .getGenericReturnType();
+ src.append(", ");
}
- catch (NoSuchMethodException ex3)
+ else
{
- // ???
- continue;
+ first = false;
}
+
+ src.append(methodName);
+ src.append(": ");
+ src.append(meta.getMethods().get(methodName));
}
+ src.append("});\n");
}
-
- appendTypeSource(out, propertyType, types);
-
- // Include types referenced by generic declarations
- if (propertyType instanceof ParameterizedType)
+ else
{
- for (Type t : ((ParameterizedType) propertyType)
- .getActualTypeArguments())
+ src.append("Seam.registerBean(\"");
+ src.append(meta.getName());
+ src.append("\", {");
+
+ boolean first = true;
+ for (String propertyName : meta.getProperties().keySet())
{
- if (t instanceof Class<?>)
+ if (!first)
{
- appendTypeSource(out, t, types);
+ src.append(", ");
}
- }
- }
-
- if (f != null)
- {
- String fieldName = propertyName.substring(0, 1).toUpperCase()
- + propertyName.substring(1);
- String getterName = String.format("get%s", fieldName);
- String setterName = String.format("set%s", fieldName);
-
- try
- {
- classType.getMethod(getterName);
- getMethodName = getterName;
- }
- catch (SecurityException ex)
- {
- }
- catch (NoSuchMethodException ex)
- {
- getterName = String.format("is%s", fieldName);
- try
+ else
{
- if (Modifier.isPublic(classType.getMethod(getterName)
- .getModifiers()))
- getMethodName = getterName;
+ first = false;
}
- catch (NoSuchMethodException ex2)
- { /* don't care */
- }
+
+ src.append(propertyName);
+ src.append(": \"");
+ src.append(meta.getProperties().get(propertyName));
+ src.append("\"");
}
-
- try
- {
- if (Modifier.isPublic(classType.getMethod(setterName,
- f.getType()).getModifiers()))
- setMethodName = setterName;
- }
- catch (SecurityException ex)
- {
- }
- catch (NoSuchMethodException ex)
- { /* don't care */
- }
+ src.append("});\n");
}
-
- // Construct the list of fields.
- if (getMethodName != null || setMethodName != null)
- {
- metadata.put(propertyName, getFieldType(propertyType));
- }
- }
-
- StringBuilder typeSource = new StringBuilder();
- typeSource.append("Seam.registerBean(\"");
- typeSource.append(componentName);
- typeSource.append("\", {");
-
- boolean first = true;
- for (String key : metadata.keySet())
- {
- if (!first)
- typeSource.append(", ");
- typeSource.append(key);
- typeSource.append(": \"");
- typeSource.append(metadata.get(key));
- typeSource.append("\"");
- first = false;
}
-
- typeSource.append("});\n");
-
- out.write(typeSource.toString().getBytes());
+ out.write(src.toString().getBytes());
}
-
- /**
- * Returns the remoting "type" for a specified class.
- *
- * @param type
- * Class
- * @return String
- */
- protected String getFieldType(Type type)
- {
- if (type.equals(String.class)
- || (type instanceof Class<?> && ((Class<?>) type).isEnum())
- || type.equals(BigInteger.class) || type.equals(BigDecimal.class))
- {
- return "str";
- }
- else if (type.equals(Boolean.class) || type.equals(Boolean.TYPE))
- {
- return "bool";
- }
- else if (type.equals(Short.class) || type.equals(Short.TYPE)
- || type.equals(Integer.class) || type.equals(Integer.TYPE)
- || type.equals(Long.class) || type.equals(Long.TYPE)
- || type.equals(Float.class) || type.equals(Float.TYPE)
- || type.equals(Double.class) || type.equals(Double.TYPE)
- || type.equals(Byte.class) || type.equals(Byte.TYPE))
- {
- return "number";
- }
- else if (type instanceof Class<?>)
- {
- Class<?> cls = (Class<?>) type;
- if (Date.class.isAssignableFrom(cls)
- || Calendar.class.isAssignableFrom(cls))
- {
- return "date";
- }
- else if (cls.isArray())
- {
- return "bag";
- }
- else if (cls.isAssignableFrom(Map.class))
- {
- return "map";
- }
- else if (cls.isAssignableFrom(Collection.class))
- {
- return "bag";
- }
- }
- else if (type instanceof ParameterizedType)
- {
- ParameterizedType pt = (ParameterizedType) type;
-
- if (pt.getRawType() instanceof Class<?>
- && Map.class.isAssignableFrom((Class<?>) pt.getRawType()))
- {
- return "map";
- }
- else if (pt.getRawType() instanceof Class<?>
- && Collection.class.isAssignableFrom((Class<?>) pt.getRawType()))
- {
- return "bag";
- }
- }
-
- return "bean";
- }
}
Added: modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/MetadataCache.java
===================================================================
--- modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/MetadataCache.java (rev 0)
+++ modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/MetadataCache.java 2009-12-29 04:20:43 UTC (rev 11889)
@@ -0,0 +1,392 @@
+package org.jboss.seam.remoting;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.inject.Inject;
+
+import org.jboss.seam.remoting.BeanMetadata.BeanType;
+import org.jboss.seam.remoting.annotations.WebRemote;
+
+/**
+ * Caches BeanMetadata instances
+ *
+ * @author Shane Bryzak
+ */
+@ApplicationScoped
+public class MetadataCache
+{
+ private Map<Class<?>,BeanMetadata> metadataCache;
+
+ private Map<Class<?>, Set<Class<?>>> beanDependencies;
+
+ /**
+ * A cache of the accessible properties for a bean class
+ */
+ private Map<Class<?>, Map<String,Type>> accessibleProperties = new HashMap<Class<?>, Map<String,Type>>();
+
+ @Inject BeanManager beanManager;
+
+ public MetadataCache()
+ {
+ metadataCache = new HashMap<Class<?>, BeanMetadata>();
+ beanDependencies = new HashMap<Class<?>, Set<Class<?>>>();
+ }
+
+ public BeanMetadata getMetadata(Class<?> beanClass)
+ {
+ if (beanClass == null) throw new IllegalArgumentException("beanClass cannot be null");
+
+ if (metadataCache.containsKey(beanClass))
+ {
+ return metadataCache.get(beanClass);
+ }
+ else
+ {
+ synchronized(metadataCache)
+ {
+ if (!metadataCache.containsKey(beanClass))
+ {
+ metadataCache.put(beanClass, generateBeanMetadata(beanClass));
+
+ Set<Class<?>> dependencies = beanDependencies.get(beanClass);
+ if (dependencies != null)
+ {
+ for (Class<?> dependency : dependencies)
+ {
+ getMetadata(dependency);
+ }
+ }
+ }
+ }
+ return metadataCache.get(beanClass);
+ }
+ }
+
+ private BeanMetadata generateBeanMetadata(Class<?> beanClass)
+ {
+ BeanType beanType = BeanType.state;
+ String name = beanClass.getName();
+
+ // If any of the methods are annotated with @WebRemote, it's an action bean
+ for (Method m : beanClass.getDeclaredMethods())
+ {
+ if (m.getAnnotation(WebRemote.class) != null)
+ {
+ beanType = BeanType.action;
+ String beanName = beanManager.getBeans(beanClass).iterator().next().getName();
+ if (beanName != null)
+ {
+ name = beanName;
+ }
+ break;
+ }
+ }
+
+ BeanMetadata meta = new BeanMetadata(beanType, name);
+
+ if (beanType == BeanType.state)
+ {
+ populateMetadataProperties(beanClass, meta);
+ }
+ else
+ {
+ populateMetadataMethods(beanClass, meta);
+ }
+
+ return meta;
+ }
+
+ private void populateMetadataProperties(Class<?> beanClass, BeanMetadata meta)
+ {
+ Map<String,Type> props = getAccessibleProperties(beanClass);
+
+ for (String propertyName : props.keySet())
+ {
+ Type propertyType = props.get(propertyName);
+
+ meta.addProperty(propertyName, getFieldType(propertyType));
+ addTypeDependency(beanClass, propertyType);
+ }
+ }
+
+ private void populateMetadataMethods(Class<?> beanClass, BeanMetadata meta)
+ {
+ for (Method m : beanClass.getDeclaredMethods())
+ {
+ if (m.getAnnotation(WebRemote.class) == null) continue;
+ meta.addMethod(m.getName(), m.getParameterTypes().length);
+
+ addTypeDependency(beanClass, m.getGenericReturnType());
+ for (int i = 0; i < m.getGenericParameterTypes().length; i++)
+ {
+ addTypeDependency(beanClass, m.getGenericParameterTypes()[i]);
+ }
+ }
+ }
+
+ private void addTypeDependency(Class<?> beanType, Type dependency)
+ {
+ if (!beanDependencies.containsKey(beanType))
+ {
+ beanDependencies.put(beanType, new HashSet<Class<?>>());
+ }
+
+ Set<Class<?>> dependencies = beanDependencies.get(beanType);
+
+ if (dependencies.contains(dependency)) return;
+
+ if (dependency instanceof Class<?>)
+ {
+ Class<?> classType = (Class<?>) dependency;
+
+ if (classType.isArray())
+ {
+ addTypeDependency(beanType, classType.getComponentType());
+ return;
+ }
+
+ if (classType.getName().startsWith("java.") || classType.isPrimitive()
+ || classType.isEnum())
+ {
+ return;
+ }
+
+ dependencies.add(classType);
+ }
+ else if (dependency instanceof ParameterizedType)
+ {
+ for (Type t : ((ParameterizedType) dependency).getActualTypeArguments())
+ {
+ addTypeDependency(beanType, t);
+ }
+ }
+ }
+
+ /**
+ * Returns the metadata for the specified bean type and all of its reachable
+ * dependencies
+ *
+ * @param beanType
+ * @return
+ */
+ public Set<Class<?>> getDependencies(Class<?> beanType)
+ {
+ return beanDependencies.get(beanType);
+ }
+
+ /**
+ * Returns the remoting "type" for a specified class.
+ *
+ * @param type Type The type for which to return the remoting type.
+ * @return String The remoting type for the specified type.
+ */
+ protected String getFieldType(Type type)
+ {
+ if (type.equals(String.class)
+ || (type instanceof Class<?> && ((Class<?>) type).isEnum())
+ || type.equals(BigInteger.class) || type.equals(BigDecimal.class))
+ {
+ return "str";
+ }
+ else if (type.equals(Boolean.class) || type.equals(Boolean.TYPE))
+ {
+ return "bool";
+ }
+ else if (type.equals(Short.class) || type.equals(Short.TYPE)
+ || type.equals(Integer.class) || type.equals(Integer.TYPE)
+ || type.equals(Long.class) || type.equals(Long.TYPE)
+ || type.equals(Float.class) || type.equals(Float.TYPE)
+ || type.equals(Double.class) || type.equals(Double.TYPE)
+ || type.equals(Byte.class) || type.equals(Byte.TYPE))
+ {
+ return "number";
+ }
+ else if (type instanceof Class<?>)
+ {
+ Class<?> cls = (Class<?>) type;
+ if (Date.class.isAssignableFrom(cls)
+ || Calendar.class.isAssignableFrom(cls))
+ {
+ return "date";
+ }
+ else if (cls.isArray())
+ {
+ return "bag";
+ }
+ else if (cls.isAssignableFrom(Map.class))
+ {
+ return "map";
+ }
+ else if (cls.isAssignableFrom(Collection.class))
+ {
+ return "bag";
+ }
+ }
+ else if (type instanceof ParameterizedType)
+ {
+ ParameterizedType pt = (ParameterizedType) type;
+
+ if (pt.getRawType() instanceof Class<?>
+ && Map.class.isAssignableFrom((Class<?>) pt.getRawType()))
+ {
+ return "map";
+ }
+ else if (pt.getRawType() instanceof Class<?>
+ && Collection.class.isAssignableFrom((Class<?>) pt.getRawType()))
+ {
+ return "bag";
+ }
+ }
+
+ return "bean";
+ }
+
+ /**
+ * A helper method, used internally by InterfaceGenerator and also when
+ * serializing responses. Returns a list of the property names for the
+ * specified class which should be included in the generated interface for
+ * the type.
+ *
+ * @param cls Class The class to scan for accessible properties
+ * @return Set<String> A Set containing the accessible property names
+ */
+ public Map<String,Type> getAccessibleProperties(Class<?> cls)
+ {
+ if (cls.getName().contains("EnhancerByCGLIB"))
+ cls = cls.getSuperclass();
+
+ if (!accessibleProperties.containsKey(cls))
+ {
+ synchronized (accessibleProperties)
+ {
+ if (!accessibleProperties.containsKey(cls))
+ {
+ Map<String, Type> properties = new HashMap<String, Type>();
+
+ Class<?> c = cls;
+ while (c != null && !c.equals(Object.class))
+ {
+ // Scan the declared fields
+ for (Field f : c.getDeclaredFields())
+ {
+ // If we already have this field, continue processing
+ if (properties.containsKey(f.getName()))
+ {
+ continue;
+ }
+
+ // Don't include transient or static fields
+ if (!Modifier.isTransient(f.getModifiers())
+ && !Modifier.isStatic(f.getModifiers()))
+ {
+ if (Modifier.isPublic(f.getModifiers()))
+ {
+ properties.put(f.getName(), f.getGenericType());
+ }
+ else
+ {
+ // Look for a public getter method
+ String fieldName = f.getName().substring(0, 1).toUpperCase()
+ + f.getName().substring(1);
+
+ String getterName = String.format("get%s", fieldName);
+ Method getMethod = null;
+
+ try
+ {
+ getMethod = c.getMethod(getterName);
+ }
+ catch (SecurityException ex) { }
+ catch (NoSuchMethodException ex)
+ {
+ // it might be an "is" method...
+ getterName = String.format("is%s", fieldName);
+ try
+ {
+ getMethod = c.getMethod(getterName);
+ }
+ catch (NoSuchMethodException ex2) { }
+ }
+
+ if (getMethod != null && Modifier.isPublic(getMethod.getModifiers()))
+ {
+ properties.put(f.getName(), getMethod.getGenericReturnType());
+ }
+ else
+ {
+ // Last resort, look for a public setter method
+ String setterName = String.format("set%s", fieldName);
+ Method setMethod = null;
+ try
+ {
+ setMethod = c.getMethod(setterName, new Class[] { f.getType() });
+ }
+ catch (SecurityException ex) { }
+ catch (NoSuchMethodException ex) { }
+
+ if (setMethod != null && Modifier.isPublic(setMethod.getModifiers()))
+ {
+ properties.put(f.getName(), setMethod.getGenericParameterTypes()[0]);
+ }
+ }
+ }
+ }
+ }
+
+ // Scan the declared methods
+ for (Method m : c.getDeclaredMethods())
+ {
+ if (m.getName().startsWith("get") || m.getName().startsWith("is"))
+ {
+ int startIdx = m.getName().startsWith("get") ? 3 : 2;
+
+ try
+ {
+ c.getMethod(String.format("set%s", m.getName()
+ .substring(startIdx)), m.getReturnType());
+ }
+ catch (NoSuchMethodException ex)
+ {
+ // If there is no setter method, ignore and continue processing
+ continue;
+ }
+
+ String propertyName = String.format("%s%s", Character
+ .toLowerCase(m.getName().charAt(startIdx)), m
+ .getName().substring(startIdx + 1));
+
+ if (!properties.containsKey(propertyName))
+ {
+ properties.put(propertyName, m.getGenericReturnType());
+ }
+ }
+ }
+
+ // Recursively scan the class hierarchy
+ c = c.getSuperclass();
+ }
+
+ accessibleProperties.put(cls, properties);
+ }
+ }
+ }
+
+ return accessibleProperties.get(cls);
+ }
+
+}
Modified: modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/wrapper/BeanWrapper.java
===================================================================
--- modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/wrapper/BeanWrapper.java 2009-12-28 22:39:01 UTC (rev 11888)
+++ modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/wrapper/BeanWrapper.java 2009-12-29 04:20:43 UTC (rev 11889)
@@ -12,7 +12,7 @@
import javax.enterprise.inject.spi.BeanManager;
import org.dom4j.Element;
-import org.jboss.seam.remoting.InterfaceGenerator;
+import org.jboss.seam.remoting.MetadataCache;
/**
* @author Shane Bryzak
@@ -35,7 +35,22 @@
{
super(beanManager);
}
+
+ private MetadataCache metadataCache;
+
+ @SuppressWarnings("unchecked")
+ private MetadataCache getMetadataCache()
+ {
+ if (metadataCache == null)
+ {
+ Bean<MetadataCache> bean = (Bean<MetadataCache>) beanManager.getBeans(
+ MetadataCache.class).iterator().next();
+ metadataCache = bean.create(beanManager.createCreationalContext(bean));
+ }
+ return metadataCache;
+ }
+ @SuppressWarnings("unchecked")
@Override
public void setElement(Element element)
{
@@ -244,8 +259,7 @@
out.write(BEAN_START_TAG_CLOSE);
- for (String propertyName : InterfaceGenerator
- .getAccessibleProperties(cls))
+ for (String propertyName : getMetadataCache().getAccessibleProperties(cls).keySet())
{
String fieldPath = path != null && path.length() > 0 ? String.format(
"%s.%s", path, propertyName) : propertyName;
Modified: modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/wrapper/WrapperFactory.java
===================================================================
--- modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/wrapper/WrapperFactory.java 2009-12-28 22:39:01 UTC (rev 11888)
+++ modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/wrapper/WrapperFactory.java 2009-12-29 04:20:43 UTC (rev 11889)
@@ -25,8 +25,9 @@
/**
* A registry of wrapper types
*/
- private Map<String, Class> wrapperRegistry = new HashMap<String, Class>();
+ private Map<String, Class<?>> wrapperRegistry = new HashMap<String, Class<?>>();
+ @SuppressWarnings("unchecked")
private Map<Class, Class> classRegistry = new HashMap<Class, Class>();
/**
@@ -63,12 +64,12 @@
registerWrapperClass(Byte.class, NumberWrapper.class);
}
- public void registerWrapper(String type, Class wrapperClass)
+ public void registerWrapper(String type, Class<?> wrapperClass)
{
wrapperRegistry.put(type, wrapperClass);
}
- public void registerWrapperClass(Class cls, Class wrapperClass)
+ public void registerWrapperClass(Class<?> cls, Class<?> wrapperClass)
{
classRegistry.put(cls, wrapperClass);
}
@@ -78,6 +79,7 @@
return factory;
}
+ @SuppressWarnings("unchecked")
public Wrapper createWrapper(String type, BeanManager beanManager)
{
Class wrapperClass = wrapperRegistry.get(type);
@@ -99,6 +101,7 @@
"Failed to create wrapper for type: %s", type));
}
+ @SuppressWarnings("unchecked")
public Wrapper getWrapperForObject(Object obj, BeanManager beanManager)
{
if (obj == null)
Modified: modules/remoting/trunk/src/main/resources/org/jboss/seam/remoting/remote.js
===================================================================
--- modules/remoting/trunk/src/main/resources/org/jboss/seam/remoting/remote.js 2009-12-28 22:39:01 UTC (rev 11888)
+++ modules/remoting/trunk/src/main/resources/org/jboss/seam/remoting/remote.js 2009-12-29 04:20:43 UTC (rev 11889)
@@ -10,7 +10,7 @@
Seam.createBean = function(name) {
if (!Seam.beans[name]) return null;
- var b = new Seam.beans[name];
+ var b = new Seam.beans[name];
if (arguments.length > 1) {
b.__qualifiers = new Array();
for (var i=1; i<arguments.length; i++) {
@@ -34,8 +34,7 @@
Seam.registerBean = function(name, metadata, methods) {
var t = function() {};
- t.__name = name;
-
+ t.__name = name;
if (metadata) {
var m = new Array();
for (var f in metadata) {
@@ -45,8 +44,7 @@
m.push({field:f, type:metadata[f]});
}
t.__metadata = m;
- }
- else {
+ } else {
for (var m in methods) {
var pc = methods[m];
t.prototype[m] = function() {
@@ -58,9 +56,8 @@
var eh = (arguments.length > (pc + 1)) ? arguments[pc + 1] : undefined;
return Seam.execute(this, m, p, c, eh);
};
- }
+ }
}
-
Seam.beans[name] = t;
}
@@ -138,21 +135,17 @@
if (v1 == v2) return true;
if (v1 instanceof Date && v2 instanceof Date &&
v1.getTime() == v2.getTime()) return true;
-
- return false;
+ return false;
}
Seam.Map = function() {
this.elements = new Array();
-
Seam.Map.prototype.size = function() {
return this.elements.length;
}
-
Seam.Map.prototype.isEmpty = function() {
return this.elements.length == 0;
}
-
Seam.Map.prototype.keySet = function() {
var keySet = new Array();
for (var i=0; i<this.elements.length; i++) {
@@ -160,7 +153,6 @@
}
return keySet;
}
-
Seam.Map.prototype.values = function() {
var vals = new Array();
for (var i=0; i<this.elements.length; i++) {
@@ -168,7 +160,6 @@
}
return vals;
}
-
Seam.Map.prototype.get = function(key) {
for (var i=0; i<this.elements.length; i++) {
var e = this.elements[i];
@@ -176,7 +167,6 @@
}
return null;
}
-
Seam.Map.prototype.put = function(key, value) {
for (var i=0; i<this.elements.length; i++) {
if (Seam.equals(this.elements[i].key, key)) {
@@ -186,7 +176,6 @@
}
this.elements.push({key:key,value:value});
}
-
Seam.Map.prototype.remove = function(key) {
for (var i=0; i<this.elements.length; i++) {
if (Seam.equals(this.elements[i].key, key)) {
@@ -195,7 +184,6 @@
}
}
}
-
Seam.Map.prototype.contains = function(key) {
for (var i=0; i<this.elements.length; i++) {
if (Seam.equals(this.elements[i].key, key)) return true;
@@ -216,8 +204,7 @@
case "map": return Seam.serializeMap(v, refs);
default: return "<str>" + encodeURIComponent(v) + "</str>";
}
- }
- else {
+ } else {
switch (typeof(v)) {
case "number":
return "<number>" + v + "</number>";
@@ -385,8 +372,7 @@
var c = Seam.createCall(component, methodName, params, callback, exceptionHandler);
if (Seam.inBatch) {
Seam.batchedCalls[Seam.batchedCalls.length] = c;
- }
- else {
+ } else {
var envelope = Seam.createEnvelope(Seam.createHeader(), c.data);
Seam.pendingCalls.put(c.id, c);
Seam.sendAjaxRequest(envelope, Seam.PATH_EXECUTE, Seam.processResponse, false);
@@ -401,8 +387,7 @@
if (window.XMLHttpRequest) {
r = new XMLHttpRequest();
if (r.overrideMimeType) r.overrideMimeType('text/xml');
- }
- else {
+ } else {
r = new ActiveXObject("Microsoft.XMLHTTP");
}
@@ -440,8 +425,7 @@
}
}
}
- }
- else {
+ } else {
Seam.displayError(r.status);
}
}
@@ -474,7 +458,7 @@
Seam.unmarshalContext(contextNode, ctx);
}
}
- Seam.context.setConversationId(ctx.getConversationId() ? ctx.getConversationId() : null);
+ Seam.context.setConversationId(ctx.getConversationId() ? ctx.getConversationId() : null);
if (bodyNode) {
var n = cn(bodyNode, "result");
if (n) {
@@ -489,8 +473,7 @@
var msgNode = cn(exceptionNode, "message");
var msg = Seam.unmarshalValue(msgNode.firstChild);
call.exceptionHandler(new Seam.Exception(msg));
- }
- else {
+ } else {
var refs = Seam.unmarshalRefs(refsNode);
var v = Seam.unmarshalValue(valueNode.firstChild, refs);
call.callback(v, ctx, callId);
@@ -581,7 +564,7 @@
Seam.cloneObject = function(obj, refMap) {
if (refMap && refMap.contains(obj)) return refMap.get(obj);
if (typeof obj == "object") {
- if (obj == null) return null;
+ if (obj == null) return null;
var m = (refMap == null) ? new Seam.Map() : refMap;
if (obj instanceof Array) {
var c = new Array();
@@ -589,16 +572,15 @@
for (var i=0; i<obj.length; i++) {
c[i] = Seam.cloneObject(obj[i], m);
}
- return c;
+ return c;
+ } else if (obj instanceof Date) {
+ return new Date(obj.getTime())
}
- else if (obj instanceof Date) {
- return new Date(obj.getTime())
- }
var t = Seam.getBeanType(obj);
var c = (t == undefined) ? new Object() : new t();
m.put(obj, c);
- for (var p in obj) c[p] = Seam.cloneObject(obj[p], m);
- return c;
+ for (var p in obj) c[p] = Seam.cloneObject(obj[p], m);
+ return c;
}
return obj;
}
@@ -635,8 +617,7 @@
document.body.appendChild(d);
var text = document.createTextNode(Seam.loadingMessage);
d.appendChild(text);
- }
- else {
+ } else {
Seam.loadingMsgDiv.innerHTML = Seam.loadingMessage;
Seam.loadingMsgDiv.style.visibility = 'visible';
}
@@ -652,27 +633,22 @@
this.method = null;
this.params = new Array();
this.expression = null;
-
Seam.Action.prototype.setBeanType = function(beanType) {
this.beanType = beanType;
return this;
}
-
Seam.Action.prototype.setQualifiers = function(qualifiers) {
this.qualifiers = qualifiers;
return this;
}
-
Seam.Action.prototype.setMethod = function(method) {
this.method = method;
return this;
}
-
Seam.Action.prototype.addParam = function(param) {
this.params.push(param);
return this;
}
-
Seam.Action.prototype.setExpression = function(expr) {
this.expression = expr;
return this;
@@ -683,13 +659,13 @@
this.propertyChange = new Seam.Map();
Seam.Changeset.prototype.addProperty = function(name, val) {
this.propertyChange.put(name, val);
- }
+ }
}
Seam.Delta = function(model) {
this.model = model;
this.refs = new Seam.Map();
-
+
Seam.Delta.prototype.testEqual = function(v1, v2) {
var eq = this.testEqual;
if (v1 == null) return v2 == null;
@@ -697,32 +673,29 @@
case "number":
return typeof(v2) == "number" && v1 == v2;
case "boolean":
- return typeof(v2) == "boolean" && v1 == v2;
+ return typeof(v2) == "boolean" && v1 == v2;
case "string":
- return typeof(v2) == "string" && v1 == v2;
+ return typeof(v2) == "string" && v1 == v2;
case "object":
if (v1 instanceof Date) {
return (v2 instanceof Date) && v1.getTime() == v2.getTime();
- }
- else if (Seam.getBeanType(v1)) {
+ } else if (Seam.getBeanType(v1)) {
return this.getSourceObject(v1) == v2;
- }
- else if (v1 instanceof Array) {
+ } else if (v1 instanceof Array) {
if (!(v2 instanceof Array)) return false;
if (v1.length != v2.length) return false;
for (var i=0; i<v1.length; i++) {
- if (!eq(v1[i], v2[i])) return false;
+ if (!eq(v1[i], v2[i])) return false;
}
return true;
- }
- else if (v1 instanceof Seam.Map) {
+ } else if (v1 instanceof Seam.Map) {
if (!(v2 instanceof Seam.Map)) return false;
if (v1.size() != v2.size()) return false;
for (var i=0; i<v1.size(); i++) {
var e = v1.elements[i];
if (Seam.getBeanType(e.key) && eq(e.value, v2.get(this.getSourceObject(e.key)))) break;
if (eq(e.value, v2.get(e.key)) && (e.value != null || v2.contains(e.key))) break;
- return false;
+ return false;
}
return true;
}
@@ -738,58 +711,56 @@
}
cs.addProperty(prop, obj[prop]);
}
-
- Seam.Delta.prototype.scanForChanges = function(obj) {
+
+ Seam.Delta.prototype.scanForChanges = function(obj) {
if (obj == null || this.refs.contains(obj)) return;
this.refs.put(obj, null);
if (Seam.getBeanType(obj)) {
var src = this.getSourceObject(obj);
var m = Seam.getBeanMetadata(obj);
for (var i=0; i<m.length; i++) {
- var f=m[i].field;
- var t=m[i].type;
+ var f=m[i].field;
+ var t=m[i].type;
if (src && !this.testEqual(obj[f], src[f])) this.registerPropertyChange(obj, f);
if (t == "bag" || t == "map" || t == "bean") this.scanForChanges(obj[f]);
}
- }
- else if (obj instanceof Array) {
+ } else if (obj instanceof Array) {
var src = this.getSourceObject(obj);
if (!this.testEqual(obj, src)) this.refs.put(obj, true);
for (var i=0; i<obj.length; i++) {
if (Seam.getBeanType(obj[i]) || obj[i] instanceof Array || obj[i] instanceof Seam.Map) {
- this.scanForChanges(obj[i]);
+ this.scanForChanges(obj[i]);
}
}
- }
- else if (obj instanceof Seam.Map) {
+ } else if (obj instanceof Seam.Map) {
var src = this.getSourceObject(obj);
if (!this.testEqual(obj, src)) this.refs.put(obj, true);
for (var i=0; i<obj.elements.length; i++) {
var k = obj.elements[i].key;
var v = obj.elements[i].value;
if (Seam.getBeanType(k) || k instanceof Array || k instanceof Seam.Map) {
- this.scanForChanges(k);
- }
+ this.scanForChanges(k);
+ }
if (Seam.getBeanType(v) || v instanceof Array || v instanceof Seam.Map) {
- this.scanForChanges(v);
+ this.scanForChanges(v);
}
- }
+ }
}
}
Seam.Delta.prototype.getSourceObject = function(obj) {
for (var i=0;i<this.model.workingRefs.length; i++) {
- if (obj == this.model.workingRefs[i]) return this.model.sourceRefs[i];
+ if (obj == this.model.workingRefs[i]) return this.model.sourceRefs[i];
}
return null;
}
-
- Seam.Delta.prototype.buildRefs = function() {
- var refs = new Array();
+
+ Seam.Delta.prototype.buildRefs = function() {
+ var refs = new Array();
for (var i=0; i<this.refs.elements.length; i++) {
refs.push(this.refs.elements[i]);
- }
- return refs;
+ }
+ return refs;
}
}
@@ -825,7 +796,7 @@
}
this.beans.push({alias: alias, bean: bean, qualifiers: q});
}
-
+
Seam.Model.prototype.addBeanProperty = function(alias, bean, property) {
var q = null;
if (arguments.length > 3) {
@@ -835,7 +806,7 @@
}
}
this.beans.push({alias: alias, bean: bean, property: property, qualifiers: q});
- }
+ }
Seam.Model.prototype.fetch = function(action, callback) {
this.callback = callback;
@@ -869,8 +840,7 @@
}
d += "</refs>";
}
- }
- else if (a.expression) {
+ } else if (a.expression) {
d += "<target>" + a.expression + "</target>";
}
d += "</action>";
@@ -908,7 +878,7 @@
this.workingRefs = Seam.cloneObject(this.sourceRefs);
for (var i=0; i<valueNodes.length; i++) {
var value = Seam.unmarshalValue(valueNodes[i].firstChild,this.workingRefs);
- this.values.push({alias:valueNodes[i].getAttribute("alias"),value:value, refIndex:i});
+ this.values.push({alias:valueNodes[i].getAttribute("alias"),value:value, refIndex:i});
}
if (this.callback) this.callback(this);
@@ -924,7 +894,7 @@
Seam.pendingCalls.put(r.id, r);
Seam.sendAjaxRequest(env, Seam.PATH_MODEL, Seam.processResponse, false);
}
-
+
Seam.Model.prototype.createApplyRequest = function(a, delta) {
var callId = "" + Seam.__callId++;
var d = "<model uid=\"" + this.id + "\" operation=\"apply\" callId=\"" + callId + "\">";
@@ -942,8 +912,7 @@
}
d += "</params>";
}
- }
- else if (a.expression) {
+ } else if (a.expression) {
d += "<target>" + a.expression + "</target>";
}
d += "</action>";
@@ -960,17 +929,16 @@
d += "<member name=\"" + v.propertyChange.elements[j].key + "\">";
d += Seam.serializeValue(v.propertyChange.elements[j].value, null, refs);
d += "</member>";
- }
+ }
+ } else {
+ d += Seam.serializeValue(k, null, refs);
}
- else {
- d += Seam.serializeValue(k, null, refs);
- }
d += "</changeset>";
}
}
d += "</delta>";
if (refs.length > 0) {
- d += "<refs>";
+ d += "<refs>";
var idx = this.workingRefs.length;
for (var i=0; i<refs.length; i++) {
if (this.getRefId(refs[i]) != -1) {
@@ -982,11 +950,11 @@
d += "</model>";
return {data:d, id:callId, model:this};
}
-
+
Seam.Model.prototype.getRefId = function(v) {
for (var i=0; i<this.workingRefs.length; i++) {
- if (this.workingRefs[i] == v) return i;
+ if (this.workingRefs[i] == v) return i;
}
return -1;
- }
+ }
}
\ No newline at end of file
15 years
Seam SVN: r11888 - branches/community/Seam_2_2/doc/Seam_Reference_Guide/en-US.
by seam-commits@lists.jboss.org
Author: shane.bryzak(a)jboss.com
Date: 2009-12-28 17:39:01 -0500 (Mon, 28 Dec 2009)
New Revision: 11888
Modified:
branches/community/Seam_2_2/doc/Seam_Reference_Guide/en-US/Controls.xml
Log:
documented includePageParams for s:link and s:button
Modified: branches/community/Seam_2_2/doc/Seam_Reference_Guide/en-US/Controls.xml
===================================================================
--- branches/community/Seam_2_2/doc/Seam_Reference_Guide/en-US/Controls.xml 2009-12-28 22:28:46 UTC (rev 11887)
+++ branches/community/Seam_2_2/doc/Seam_Reference_Guide/en-US/Controls.xml 2009-12-28 22:39:01 UTC (rev 11888)
@@ -87,6 +87,13 @@
<literal>propagation="join"</literal> is used).
</para>
</listitem>
+ <listitem>
+ <para>
+ <literal>includePageParams</literal> — when set to false,
+ page parameters defined in <literal>pages.xml</literal> will be
+ excluded from rendering.
+ </para>
+ </listitem>
</itemizedlist>
<para><emphasis>Usage</emphasis></para>
@@ -202,6 +209,13 @@
<literal>propagation="join"</literal>.)
</para>
</listitem>
+ <listitem>
+ <para>
+ <literal>includePageParams</literal> — when set to false,
+ page parameters defined in <literal>pages.xml</literal> will be
+ excluded from rendering.
+ </para>
+ </listitem>
</itemizedlist>
<para><emphasis>Usage</emphasis></para>
15 years
Seam SVN: r11887 - in branches/community/Seam_2_2: src/excel/org/jboss/seam/excel/csv and 1 other directory.
by seam-commits@lists.jboss.org
Author: danielc.roth
Date: 2009-12-28 17:28:46 -0500 (Mon, 28 Dec 2009)
New Revision: 11887
Modified:
branches/community/Seam_2_2/examples/excel/src/org/jboss/seam/example/excel/ExcelTest.java
branches/community/Seam_2_2/src/excel/org/jboss/seam/excel/csv/CsvExcelWorkbook.java
Log:
JBSEAM-4187
Modified: branches/community/Seam_2_2/examples/excel/src/org/jboss/seam/example/excel/ExcelTest.java
===================================================================
--- branches/community/Seam_2_2/examples/excel/src/org/jboss/seam/example/excel/ExcelTest.java 2009-12-24 17:41:26 UTC (rev 11886)
+++ branches/community/Seam_2_2/examples/excel/src/org/jboss/seam/example/excel/ExcelTest.java 2009-12-28 22:28:46 UTC (rev 11887)
@@ -34,7 +34,7 @@
people.add(new Person("Dan Allen", "Individual", "Seam-gen, Bug fixes"));
people.add(new Person("Matt Drees", "Individual", "Seam Core"));
people.add(new Person("Jacob Orshalick", "Focus IT Solutions LLC", ""));
- people.add(new Person("Nicklas Karlsson", "Individual", "Excel reporting"));
+ people.add(new Person("Nicklas \"Nik\" Karlsson", "Individual", "Excel reporting"));
people.add(new Person("Daniel Roth", "Individual", "Excel reporting"));
people.add(new Person("Judy Guglielmin", "ICESoft Inc.", "ICEFaces integration"));
people.add(new Person("Max Rydahl Andersen", "Red Hat Inc.", "Lead developer JBoss Tools, Hibernate Tools, Seam Tools"));
Modified: branches/community/Seam_2_2/src/excel/org/jboss/seam/excel/csv/CsvExcelWorkbook.java
===================================================================
--- branches/community/Seam_2_2/src/excel/org/jboss/seam/excel/csv/CsvExcelWorkbook.java 2009-12-24 17:41:26 UTC (rev 11886)
+++ branches/community/Seam_2_2/src/excel/org/jboss/seam/excel/csv/CsvExcelWorkbook.java 2009-12-28 22:28:46 UTC (rev 11887)
@@ -31,6 +31,7 @@
private int sheetStartRow = 0;
private final static String DEFAULT_COLUMN_DELIMITER = "\"";
+ private final static String DEFAULT_COLUMN_DELIMITER_REPLACEMENT = "\"\"";
private final static String DEFAULT_LINEBREAK = "\n";
private final static String DEFAULT_COLUMN_SEPERATOR = ",";
@@ -39,6 +40,10 @@
private Log log = Logging.getLog(getClass());
+ protected String getColumnDelimeterReplacement() {
+ return DEFAULT_COLUMN_DELIMITER_REPLACEMENT;
+ }
+
protected String getColumnDelimeter() {
return DEFAULT_COLUMN_DELIMITER;
}
@@ -83,6 +88,8 @@
{
String value = table.get(hash(i, j));
value = (value == null) ? "" : value;
+ if(value.contains(getColumnDelimeter()))
+ value = value.replace(getColumnDelimeter(), getColumnDelimeterReplacement()); //JBSEAM-4187
buffer.append(getColumnDelimeter()).append(value).append(getColumnDelimeter()).append(getColumnSeparator());
}
buffer.deleteCharAt(buffer.length() - 1);
15 years
Seam SVN: r11886 - in modules/envconfig/trunk: src/main/java/org/jboss/seam/envconfig and 1 other directories.
by seam-commits@lists.jboss.org
Author: dan.j.allen
Date: 2009-12-24 12:41:26 -0500 (Thu, 24 Dec 2009)
New Revision: 11886
Modified:
modules/envconfig/trunk/readme.txt
modules/envconfig/trunk/src/main/java/org/jboss/seam/envconfig/Bind.java
modules/envconfig/trunk/src/main/java/org/jboss/seam/envconfig/EnvironmentBinding.java
modules/envconfig/trunk/src/main/java/org/jboss/seam/envconfig/extension/JndiBinder.java
Log:
put example in JavaDoc
fix invalid logic in binder
Modified: modules/envconfig/trunk/readme.txt
===================================================================
--- modules/envconfig/trunk/readme.txt 2009-12-24 17:23:08 UTC (rev 11885)
+++ modules/envconfig/trunk/readme.txt 2009-12-24 17:41:26 UTC (rev 11886)
@@ -15,7 +15,6 @@
public @EnvironmentBinding class EnvironmentVars
{
@Bind("msg") String msg = "Hello World!";
-
}
You can then inject the value into a managed bean as follows:
Modified: modules/envconfig/trunk/src/main/java/org/jboss/seam/envconfig/Bind.java
===================================================================
--- modules/envconfig/trunk/src/main/java/org/jboss/seam/envconfig/Bind.java 2009-12-24 17:23:08 UTC (rev 11885)
+++ modules/envconfig/trunk/src/main/java/org/jboss/seam/envconfig/Bind.java 2009-12-24 17:41:26 UTC (rev 11886)
@@ -34,7 +34,7 @@
{
/**
* The JNDI key to bind the value to. If the value is not a full JNDI name,
- * then the value will be prefixed with 'java:/global/', putting the value
+ * then the value will be prefixed with 'java:global/', putting the value
* into the global JNDI namespace.
*/
String value();
Modified: modules/envconfig/trunk/src/main/java/org/jboss/seam/envconfig/EnvironmentBinding.java
===================================================================
--- modules/envconfig/trunk/src/main/java/org/jboss/seam/envconfig/EnvironmentBinding.java 2009-12-24 17:23:08 UTC (rev 11885)
+++ modules/envconfig/trunk/src/main/java/org/jboss/seam/envconfig/EnvironmentBinding.java 2009-12-24 17:41:26 UTC (rev 11886)
@@ -26,9 +26,37 @@
/**
* A stereotype that can be applied to any class that should be processed for
- * @Bind fields or methods. Any bean with this stereotype applied will default
- * to application-scoped.
- *
+ * {@link @Bind} fields or methods. Any bean with this stereotype applied will
+ * default to application-scoped.
+ *
+ * <pre>
+ * @EnvironmentBinding
+ * public class EnvironmentVars {
+ * @Bind("msg")
+ * String msg = "Hello World!";
+ * }
+ * </pre>
+ *
+ * <p>
+ * EnvironemntBinding classes are expected to contain fields and/or methods
+ * annotated with @Bind. The values of those fields and methods are bound
+ * to the JNDI name provided in the value attribute of the annotation. The value
+ * can be any object. If the JNDI name provided is not prefixed with java:, then
+ * the java:global/ prefix is added to the name.
+ * </p>
+ *
+ * <p>
+ * Once the binding occurs, the JNDI resource can be injected into the field of
+ * a managed bean:
+ * </p>
+ *
+ * <pre>
+ * public class Greeter {
+ * @Resource(lookup = "java:global/msg")
+ * String msg;
+ * }
+ * </pre>
+ *
* @author Matt Corey
*/
@Stereotype
Modified: modules/envconfig/trunk/src/main/java/org/jboss/seam/envconfig/extension/JndiBinder.java
===================================================================
--- modules/envconfig/trunk/src/main/java/org/jboss/seam/envconfig/extension/JndiBinder.java 2009-12-24 17:23:08 UTC (rev 11885)
+++ modules/envconfig/trunk/src/main/java/org/jboss/seam/envconfig/extension/JndiBinder.java 2009-12-24 17:41:26 UTC (rev 11886)
@@ -69,31 +69,29 @@
field.setAccessible(true);
- Bind ann = field.getAnnotation(Bind.class);
- String jndi = ann.value();
- boolean overwrite = ann.overwrite();
- Object val = field.get(beanInstance);
+ Bind binding = field.getAnnotation(Bind.class);
+ String jndiName = binding.value();
+ boolean overwrite = binding.overwrite();
+ Object value = field.get(beanInstance);
- bindValue(jndi, val, overwrite);
+ bindValue(jndiName, value, overwrite);
}
}
}
}
- private void bindValue(String nameSuffix, Object value, boolean overwrite) throws NamingException
+ private void bindValue(String jndiName, Object value, boolean overwrite) throws NamingException
{
InitialContext ic = new InitialContext();
StringBuilder nameToBind = new StringBuilder();
- if (!nameSuffix.matches("java:/?global"))
+ // JNDI name may be java:global, java:module, java:app or java:comp/env
+ // if none of those, then we default to java:global
+ if (!jndiName.startsWith("java:"))
{
- nameToBind.append("java:global");
- if (!nameSuffix.endsWith("/"))
- {
- nameToBind.append('/');
- }
+ nameToBind.append("java:global/");
}
- nameToBind.append(nameSuffix);
+ nameToBind.append(jndiName);
String name = nameToBind.toString();
if (!overwrite) {
15 years