Author: jleroux
Date: Thu Sep 13 09:57:46 2012
New Revision: 1384258
URL: http://svn.apache.org/viewvc?rev=1384258&view=rev
Log:
"Applied fix from trunk for revision: 1243026"
------------------------------------------------------------------------
r1243026 | jleroux | 2012-02-11 11:50:56 +0100 (sam., 11 févr. 2012) | 12 lines
OFBiz SOAP implementation was not handling
* null values in Map
* BigDecimal
* correctly TimeStamp format (we use xsd:dateTime in ModelService.getTypes())
So CXF was not able to unmarshall a List of Maps with those types in them.
It does not introduce any regressions:
* A new specific SOAP null type is introduced using ("nillable","true") and
("xsi:nil","true) attributes. I had also to set the
http://www.w3.org/2001/XMLSchema-instance schema on the null node. Because it
was impossible to add it in the envelope header, not a big deal anyway.
* I introduced a 'T' in the TimeStamp format. It's is OK, the deserialisation
handles it well (we use xsd:dateTime, see
http://www.w3.org/TR/xmlschema-2/#dateTime)/. We don't handle TimeZone...
* BigDecimal was missing and is now correctly handled. I used 10 decimals and
half up rounding (ROUND_HALF_UP)
Also improves the SOAPEventHandler.sendError() method by passing the
serviceName in the message
------------------------------------------------------------------------
Modified:
ofbiz/branches/release11.04/ (props changed)
ofbiz/branches/release11.04/framework/entity/src/org/ofbiz/entity/serialize/XmlSerializer.java
ofbiz/branches/release11.04/framework/service/src/org/ofbiz/service/ModelService.java
ofbiz/branches/release11.04/framework/webapp/src/org/ofbiz/webapp/event/SOAPEventHandler.java
Propchange: ofbiz/branches/release11.04/
------------------------------------------------------------------------------
Merged /ofbiz/trunk:r1243026
Modified:
ofbiz/branches/release11.04/framework/entity/src/org/ofbiz/entity/serialize/XmlSerializer.java
URL:
http://svn.apache.org/viewvc/ofbiz/branches/release11.04/framework/entity/src/org/ofbiz/entity/serialize/XmlSerializer.java?rev=1384258&r1=1384257&r2=1384258&view=diff
==============================================================================
---
ofbiz/branches/release11.04/framework/entity/src/org/ofbiz/entity/serialize/XmlSerializer.java
(original)
+++
ofbiz/branches/release11.04/framework/entity/src/org/ofbiz/entity/serialize/XmlSerializer.java
Thu Sep 13 09:57:46 2012
@@ -22,6 +22,7 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Serializable;
import java.lang.ref.WeakReference;
+import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
@@ -130,7 +131,7 @@ public class XmlSerializer {
public static Element serializeSingle(Object object, Document document)
throws SerializeException {
if (document == null) return null;
- if (object == null) return document.createElement("null");
+ if (object == null) return makeElement("null", object, document);
// - Standard Objects -
if (object instanceof String) {
@@ -147,9 +148,13 @@ public class XmlSerializer {
return makeElement("std-Boolean", object, document);
} else if (object instanceof Locale) {
return makeElement("std-Locale", object, document);
+ } else if (object instanceof BigDecimal) {
+ String stringValue = ((BigDecimal) object).setScale(10,
BigDecimal.ROUND_HALF_UP).toString();
+ return makeElement("std-BigDecimal", stringValue, document);
// - SQL Objects -
} else if (object instanceof java.sql.Timestamp) {
- return makeElement("sql-Timestamp", object, document);
+ String stringValue = object.toString().replace(' ', 'T');
+ return makeElement("sql-Timestamp", stringValue, document);
} else if (object instanceof java.sql.Date) {
return makeElement("sql-Date", object, document);
} else if (object instanceof java.sql.Time) {
@@ -269,7 +274,15 @@ public class XmlSerializer {
}
public static Element makeElement(String elementName, Object value,
Document document) {
- if (value == null) return document.createElement("null");
+ if (value == null) {
+ Element element = document.createElement("null");
+ element.setAttribute("xsi:nil", "true");
+ // I tried to put the schema in the envelope header (in
createAndSendSOAPResponse)
+ //
resEnv.declareNamespace("http://www.w3.org/2001/XMLSchema-instance", null);
+ // But it gets prefixed and that does not work. So adding in each
instance
+ element.setAttribute("xmlns:xsi",
"http://www.w3.org/2001/XMLSchema-instance");
+ return element;
+ }
Element element = document.createElement(elementName);
element.setAttribute("value", value.toString());
Modified:
ofbiz/branches/release11.04/framework/service/src/org/ofbiz/service/ModelService.java
URL:
http://svn.apache.org/viewvc/ofbiz/branches/release11.04/framework/service/src/org/ofbiz/service/ModelService.java?rev=1384258&r1=1384257&r2=1384258&view=diff
==============================================================================
---
ofbiz/branches/release11.04/framework/service/src/org/ofbiz/service/ModelService.java
(original)
+++
ofbiz/branches/release11.04/framework/service/src/org/ofbiz/service/ModelService.java
Thu Sep 13 09:57:46 2012
@@ -1358,6 +1358,18 @@ public class ModelService extends Abstra
/*--------- Standard Objects --------*/
/*-----------------------------------*/
+ /* null Element */
+ Element stdNullElement = document.createElement("xsd:element");
+ stdNullElement.setAttribute("name", "null");
+ Element stdNullElement0 = document.createElement("xsd:complexType");
+ stdNullElement.appendChild(stdNullElement0);
+ Element stdNullElement1 = document.createElement("xsd:attribute");
+ stdNullElement0.appendChild(stdNullElement1);
+ stdNullElement1.setAttribute("name", "value");
+ stdNullElement1.setAttribute("type", "xsd:string");
+ stdNullElement1.setAttribute("use", "required");
+ stdNullElement1.setAttribute("nillable", "true");
+ schema.appendChild(stdNullElement);
/* std-String Element */
Element stdStringElement = document.createElement("xsd:element");
stdStringElement.setAttribute("name", "std-String");
@@ -1435,6 +1447,17 @@ public class ModelService extends Abstra
stdLocaleElement1.setAttribute("type", "xsd:string");
stdLocaleElement1.setAttribute("use", "required");
schema.appendChild(stdLocaleElement);
+ /* std-BigDecimal Element */
+ Element stdBigDecimalElement = document.createElement("xsd:element");
+ stdBigDecimalElement.setAttribute("name", "std-BigDecimal");
+ Element stdBigDecimalElement0 =
document.createElement("xsd:complexType");
+ stdBigDecimalElement.appendChild(stdBigDecimalElement0);
+ Element stdBigDecimalElement1 =
document.createElement("xsd:attribute");
+ stdBigDecimalElement0.appendChild(stdBigDecimalElement1);
+ stdBigDecimalElement1.setAttribute("name", "value");
+ stdBigDecimalElement1.setAttribute("type", "xsd:decimal");
+ stdBigDecimalElement1.setAttribute("use", "required");
+ schema.appendChild(stdBigDecimalElement);
/*-----------------------------------*/
/*----------- SQL Objects -----------*/
@@ -1645,6 +1668,12 @@ public class ModelService extends Abstra
mapValueComplexType.setAttribute("name", "map-Value");
Element mapValueComplexType0 = document.createElement("xsd:choice");
mapValueComplexType.appendChild(mapValueComplexType0);
+ Element mapValueComplexTypeNull =
document.createElement("xsd:element");
+ mapValueComplexTypeNull.setAttribute("ref", "tns:null");
+ mapValueComplexTypeNull.setAttribute("minOccurs", "1");
+ mapValueComplexTypeNull.setAttribute("maxOccurs", "1");
+ mapValueComplexTypeNull.setAttribute("nillable", "true");
+ mapValueComplexType0.appendChild(mapValueComplexTypeNull);
Element mapValueComplexType1 = document.createElement("xsd:element");
mapValueComplexType1.setAttribute("ref", "tns:std-String");
mapValueComplexType1.setAttribute("minOccurs", "1");
@@ -1771,12 +1800,24 @@ public class ModelService extends Abstra
mapValueComplexType25.setAttribute("maxOccurs", "1");
mapValueComplexType0.appendChild(mapValueComplexType25);
schema.appendChild(mapValueComplexType);
+ Element mapValueComplexType26 = document.createElement("xsd:element");
+ mapValueComplexType26.setAttribute("ref", "tns:std-BigDecimal");
+ mapValueComplexType26.setAttribute("minOccurs", "1");
+ mapValueComplexType26.setAttribute("maxOccurs", "1");
+ mapValueComplexType0.appendChild(mapValueComplexType26);
+ schema.appendChild(mapValueComplexType);
/* col-Collection Complex Type */
Element colCollectionComplexType =
document.createElement("xsd:complexType");
colCollectionComplexType.setAttribute("name", "col-Collection");
Element colCollectionComplexType0 =
document.createElement("xsd:choice");
colCollectionComplexType.appendChild(colCollectionComplexType0);
+ Element colCollectionComplexTypeNull =
document.createElement("xsd:element");
+ colCollectionComplexTypeNull.setAttribute("ref", "tns:null");
+ colCollectionComplexTypeNull.setAttribute("minOccurs", "0");
+ colCollectionComplexTypeNull.setAttribute("maxOccurs", "unbounded");
+ colCollectionComplexTypeNull.setAttribute("nillable", "true");
+ colCollectionComplexType0.appendChild(colCollectionComplexTypeNull);
Element colCollectionComplexType1 =
document.createElement("xsd:element");
colCollectionComplexType1.setAttribute("ref", "tns:std-String");
colCollectionComplexType1.setAttribute("minOccurs", "0");
@@ -1903,6 +1944,12 @@ public class ModelService extends Abstra
colCollectionComplexType25.setAttribute("maxOccurs", "unbounded");
colCollectionComplexType0.appendChild(colCollectionComplexType25);
schema.appendChild(colCollectionComplexType);
+ Element colCollectionComplexType26 =
document.createElement("xsd:element");
+ colCollectionComplexType26.setAttribute("ref", "tns:std-BigDecimal");
+ colCollectionComplexType26.setAttribute("minOccurs", "0");
+ colCollectionComplexType26.setAttribute("maxOccurs", "unbounded");
+ colCollectionComplexType0.appendChild(colCollectionComplexType26);
+ schema.appendChild(colCollectionComplexType);
types.setDocumentationElement(schema);
return types;
Modified:
ofbiz/branches/release11.04/framework/webapp/src/org/ofbiz/webapp/event/SOAPEventHandler.java
URL:
http://svn.apache.org/viewvc/ofbiz/branches/release11.04/framework/webapp/src/org/ofbiz/webapp/event/SOAPEventHandler.java?rev=1384258&r1=1384257&r2=1384258&view=diff
==============================================================================
---
ofbiz/branches/release11.04/framework/webapp/src/org/ofbiz/webapp/event/SOAPEventHandler.java
(original)
+++
ofbiz/branches/release11.04/framework/webapp/src/org/ofbiz/webapp/event/SOAPEventHandler.java
Thu Sep 13 09:57:46 2012
@@ -96,7 +96,7 @@ public class SOAPEventHandler implements
} catch (GenericServiceException e) {
serviceName = null;
} catch (WSDLException e) {
- sendError(response, "Unable to obtain WSDL");
+ sendError(response, "Unable to obtain WSDL", serviceName);
throw new EventHandlerException("Unable to obtain WSDL",
e);
}
@@ -111,7 +111,7 @@ public class SOAPEventHandler implements
}
return null;
} else {
- sendError(response, "Unable to obtain WSDL");
+ sendError(response, "Unable to obtain WSDL", serviceName);
throw new EventHandlerException("Unable to obtain WSDL");
}
}
@@ -136,7 +136,7 @@ public class SOAPEventHandler implements
writer.flush();
return null;
} catch (Exception e) {
- sendError(response, "Unable to obtain WSDL");
+ sendError(response, "Unable to obtain WSDL", null);
throw new EventHandlerException("Unable to obtain WSDL");
}
}
@@ -162,30 +162,31 @@ public class SOAPEventHandler implements
}
}
} catch (Exception e) {
- sendError(response, "Problem processing the service");
+ sendError(response, "Problem processing the service", null);
throw new EventHandlerException("Cannot get the envelope", e);
}
Debug.logVerbose("[Processing]: SOAP Event", module);
+ String serviceName = null;
try {
SOAPBody reqBody = reqEnv.getBody();
validateSOAPBody(reqBody);
OMElement serviceElement = reqBody.getFirstElement();
- String serviceName = serviceElement.getLocalName();
+ serviceName = serviceElement.getLocalName();
Map<String, Object> parameters =
UtilGenerics.cast(SoapSerializer.deserialize(serviceElement.toString(),
delegator));
try {
// verify the service is exported for remote execution and
invoke it
ModelService model =
dispatcher.getDispatchContext().getModelService(serviceName);
if (model == null) {
- sendError(response, "Problem processing the service");
+ sendError(response, "Problem processing the service",
serviceName);
Debug.logError("Could not find Service [" + serviceName +
"].", module);
return null;
}
if (!model.export) {
- sendError(response, "Problem processing the service");
+ sendError(response, "Problem processing the service",
serviceName);
Debug.logError("Trying to call Service [" + serviceName +
"] that is not exported.", module);
return null;
}
@@ -197,19 +198,19 @@ public class SOAPEventHandler implements
} catch (GenericServiceException e) {
if (UtilProperties.getPropertyAsBoolean("service",
"secureSoapAnswer", true)) {
- sendError(response, "Problem processing the service, check
your parameters.");
+ sendError(response, "Problem processing the service, check
your parameters.", serviceName);
} else {
if(e.getMessageList() == null) {
- sendError(response, e.getMessage());
+ sendError(response, e.getMessage(), serviceName);
} else {
- sendError(response, e.getMessageList());
+ sendError(response, e.getMessageList(), serviceName);
}
Debug.logError(e, module);
return null;
}
}
} catch (Exception e) {
- sendError(response, e.getMessage());
+ sendError(response, e.getMessage(), serviceName);
Debug.logError(e, module);
return null;
}
@@ -235,6 +236,7 @@ public class SOAPEventHandler implements
// setup the response
Debug.logVerbose("[EventHandler] : Setting up response message",
module);
String xmlResults = SoapSerializer.serialize(serviceResults);
+ //Debug.log("xmlResults ==================" + xmlResults, module);
XMLStreamReader reader =
XMLInputFactory.newInstance().createXMLStreamReader(new
StringReader(xmlResults));
StAXOMBuilder resultsBuilder = new StAXOMBuilder(reader);
OMElement resultSer = resultsBuilder.getDocumentElement();
@@ -271,15 +273,15 @@ public class SOAPEventHandler implements
}
}
- private void sendError(HttpServletResponse res, String errorMessage)
throws EventHandlerException {
+ private void sendError(HttpServletResponse res, String errorMessage,
String serviceName) throws EventHandlerException {
// setup the response
- sendError(res, ServiceUtil.returnError(errorMessage));
+ sendError(res, ServiceUtil.returnError(errorMessage), serviceName);
}
- private void sendError(HttpServletResponse res, List<String>
errorMessages) throws EventHandlerException {
- sendError(res, ServiceUtil.returnError(errorMessages));
+ private void sendError(HttpServletResponse res, List<String>
errorMessages, String serviceName) throws EventHandlerException {
+ sendError(res, ServiceUtil.returnError(errorMessages.toString()),
serviceName);
}
- private void sendError(HttpServletResponse res, Object object) throws
EventHandlerException {
+ private void sendError(HttpServletResponse res, Object object, String
serviceName) throws EventHandlerException {
try {
// setup the response
res.setContentType("text/xml");
@@ -292,11 +294,18 @@ public class SOAPEventHandler implements
SOAPFactory factory = OMAbstractFactory.getSOAP11Factory();
SOAPEnvelope resEnv = factory.createSOAPEnvelope();
SOAPBody resBody = factory.createSOAPBody();
- OMElement errMsg = factory.createOMElement(new QName("Response"));
+ OMElement errMsg = factory.createOMElement(new QName((serviceName
!= null ? serviceName : "") + "Response"));
errMsg.addChild(resultSer.getFirstElement());
resBody.addChild(errMsg);
resEnv.addChild(resBody);
+ // The declareDefaultNamespace method doesn't work see
(https://issues.apache.org/jira/browse/AXIS2-3156)
+ // so the following doesn't work:
+ // resService.declareDefaultNamespace(ModelService.TNS);
+ // instead, create the xmlns attribute directly:
+ OMAttribute defaultNS = factory.createOMAttribute("xmlns", null,
ModelService.TNS);
+ errMsg.addAttribute(defaultNS);
+
// log the response message
if (Debug.verboseOn()) {
try {