You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by bi...@apache.org on 2008/01/22 15:14:17 UTC
svn commit: r614203 - in /incubator/cxf/trunk/rt/javascript/src:
main/java/org/apache/cxf/javascript/
main/java/org/apache/cxf/javascript/types/
main/resources/org/apache/cxf/javascript/
test/java/org/apache/cxf/javascript/
Author: bimargulies
Date: Tue Jan 22 06:14:16 2008
New Revision: 614203
URL: http://svn.apache.org/viewvc?rev=614203&view=rev
Log:
Read MTOM attachments for text/plain in Javascript.
Modified:
incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/JavascriptUtils.java
incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/types/SchemaJavascriptBuilder.java
incubator/cxf/trunk/rt/javascript/src/main/resources/org/apache/cxf/javascript/cxf-utils.js
incubator/cxf/trunk/rt/javascript/src/test/java/org/apache/cxf/javascript/MtoMTest.java
Modified: incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/JavascriptUtils.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/JavascriptUtils.java?rev=614203&r1=614202&r2=614203&view=diff
==============================================================================
--- incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/JavascriptUtils.java (original)
+++ incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/JavascriptUtils.java Tue Jan 22 06:14:16 2008
@@ -31,12 +31,14 @@
import org.apache.cxf.aegis.type.mtom.AbstractXOPType;
import org.apache.cxf.common.xmlschema.SchemaCollection;
+import org.apache.cxf.common.xmlschema.XmlSchemaConstants;
import org.apache.cxf.databinding.source.mime.MimeAttribute;
import org.apache.cxf.wsdl.WSDLConstants;
import org.apache.ws.commons.schema.XmlSchemaComplexType;
import org.apache.ws.commons.schema.XmlSchemaElement;
import org.apache.ws.commons.schema.XmlSchemaObject;
import org.apache.ws.commons.schema.XmlSchemaSimpleContent;
+import org.apache.ws.commons.schema.XmlSchemaSimpleContentExtension;
import org.apache.ws.commons.schema.XmlSchemaSimpleType;
import org.apache.ws.commons.schema.XmlSchemaType;
import org.apache.ws.commons.schema.constants.Constants;
@@ -269,6 +271,34 @@
return type instanceof XmlSchemaSimpleType
|| (type instanceof XmlSchemaComplexType
&& ((XmlSchemaComplexType)type).getContentModel() instanceof XmlSchemaSimpleContent);
+ }
+
+ /**
+ * Return true for xsd:base64Binary or simple restrictions of it, as in the xmime stock type.
+ * @param type
+ * @return
+ */
+ public static boolean mtomCandidateType(XmlSchemaType type) {
+ if (XmlSchemaConstants.BASE64BINARY_QNAME.equals(type.getQName())) {
+ return true;
+ }
+ // there could be some disagreement whether the following is a good enough test.
+ // what if 'base64binary' was extended in some crazy way? At runtime, either it has
+ // an xop:Include or it doesn't.
+ if (type instanceof XmlSchemaComplexType) {
+ XmlSchemaComplexType complexType = (XmlSchemaComplexType)type;
+ if (complexType.getContentModel() instanceof XmlSchemaSimpleContent) {
+ XmlSchemaSimpleContent content = (XmlSchemaSimpleContent)complexType.getContentModel();
+ if (content.getContent() instanceof XmlSchemaSimpleContentExtension) {
+ XmlSchemaSimpleContentExtension extension =
+ (XmlSchemaSimpleContentExtension)content.getContent();
+ if (XmlSchemaConstants.BASE64BINARY_QNAME.equals(extension.getBaseTypeName())) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
}
/**
Modified: incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/types/SchemaJavascriptBuilder.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/types/SchemaJavascriptBuilder.java?rev=614203&r1=614202&r2=614203&view=diff
==============================================================================
--- incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/types/SchemaJavascriptBuilder.java (original)
+++ incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/types/SchemaJavascriptBuilder.java Tue Jan 22 06:14:16 2008
@@ -558,6 +558,7 @@
XmlSchemaType itemType = itemInfo.getType();
boolean simple = itemType instanceof XmlSchemaSimpleType
|| JavascriptUtils.notVeryComplexType(itemType);
+ boolean mtomCandidate = JavascriptUtils.mtomCandidateType(itemType);
String accessorName = "set" + StringUtils.capitalize(itemInfo.getJavascriptName());
utils.appendLine("cxfjsutils.trace('processing " + itemInfo.getJavascriptName() + "');");
XmlSchemaElement element = (XmlSchemaElement) itemInfo.getParticle();
@@ -597,10 +598,14 @@
// use our utility
utils.appendLine(valueTarget + " = org_apache_cxf_deserialize_anyType(cxfjsutils, curElement);");
} else if (simple) {
- utils.appendLine("value = cxfjsutils.getNodeText(curElement);");
- utils.appendLine(valueTarget
- + " = "
- + utils.javascriptParseExpression(itemType, "value") + ";");
+ if (mtomCandidate) {
+ utils.appendLine(valueTarget + " = cxfjsutils.deserializeBase64orMom(curElement);");
+ } else {
+ utils.appendLine("value = cxfjsutils.getNodeText(curElement);");
+ utils.appendLine(valueTarget
+ + " = "
+ + utils.javascriptParseExpression(itemType, "value") + ";");
+ }
} else {
XmlSchemaComplexType complexType = (XmlSchemaComplexType)itemType;
QName baseQName = complexType.getQName();
Modified: incubator/cxf/trunk/rt/javascript/src/main/resources/org/apache/cxf/javascript/cxf-utils.js
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/javascript/src/main/resources/org/apache/cxf/javascript/cxf-utils.js?rev=614203&r1=614202&r2=614203&view=diff
==============================================================================
--- incubator/cxf/trunk/rt/javascript/src/main/resources/org/apache/cxf/javascript/cxf-utils.js (original)
+++ incubator/cxf/trunk/rt/javascript/src/main/resources/org/apache/cxf/javascript/cxf-utils.js Tue Jan 22 06:14:16 2008
@@ -268,6 +268,243 @@
CxfApacheOrgUtil.prototype.endSoap11Message = org_apache_cxf_end_soap11_message;
+const org_apache_cxf_base64_keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
+
+function org_apache_cxf_base64_encode64array(input) {
+ var output = "";
+ var chr1, chr2, chr3;
+ var enc1, enc2, enc3, enc4;
+ var i = 0;
+
+ do {
+ var count = 1;
+ chr1 = chr2 = chr3 = 0;
+
+ chr1 = input[i++];
+ if (i < input.length) {
+ chr2 = input[i++];
+ count++;
+ }
+
+ if (i < input.length) {
+ chr3 = input[i++];
+ count++;
+ }
+
+ enc1 = chr1 >> 2;
+ enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
+ if (count > 1) {
+ enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
+ if (count > 2)
+ enc4 = chr3 & 63;
+ else
+ enc4 = 64;
+ } else
+ enc3 = enc4 = 64;
+
+ output = output + org_apache_cxf_base64_keyStr.charAt(enc1)
+ + org_apache_cxf_base64_keyStr.charAt(enc2)
+ + org_apache_cxf_base64_keyStr.charAt(enc3)
+ + org_apache_cxf_base64_keyStr.charAt(enc4);
+ } while (i < input.length);
+
+ return output;
+}
+
+function org_apache_cxf_base64_encode64Unicode(input) {
+ var data = new Array(2 + (input.length * 2));
+ data[0] = 0xff;
+ data[1] = 0xfe;
+ for (var x = 0;x < input.length; x++) {
+ var c = input.charCodeAt(x);
+ data[2 + (x * 2)] = c & 0xff;
+ data[3 + (x * 2)] = (c >> 8) & 0xff;
+ }
+ return encode64array(data);
+}
+
+// we may be able to do this more cleanly with unescape( encodeURIComponent(
+// input ) );
+function org_apache_cxf_base64_encode64UTF8(input) {
+
+ // determine how many bytes are needed for the complete conversion
+ var bytesNeeded = 0;
+ for (var i = 0;i < input.length; i++) {
+ if (input.charCodeAt(i) < 0x80) {
+ ++bytesNeeded;
+ } else if (input.charCodeAt(i) < 0x0800) {
+ bytesNeeded += 2;
+ } else if (input.charCodeAt(i) < 0x10000) {
+ bytesNeeded += 3;
+ } else {
+ bytesNeeded += 4;
+ }
+ }
+
+ // allocate a byte[] of the necessary size
+ var data = new Array(bytesNeeded);
+ // do the conversion from character code points to utf-8
+ var bytes = 0;
+ for (var i = 0;i < input.length; i++) {
+ if (input.charCodeAt(i) < 0x80) {
+ data[bytes++] = input.charCodeAt(i);
+ } else if (input.charCodeAt(i) < 0x0800) {
+ data[bytes++] = ((input.charCodeAt(i) >> 6) | 0xC0);
+ data[bytes++] = ((input.charCodeAt(i) & 0x3F) | 0x80);
+ } else if (input.charCodeAt(i) < 0x10000) {
+ data[bytes++] = ((input.charCodeAt(i) >> 12) | 0xE0);
+ data[bytes++] = (((input.charCodeAt(i) >> 6) & 0x3F) | 0x80);
+ data[bytes++] = ((input.charCodeAt(i) & 0x3F) | 0x80);
+ } else {
+ data[bytes++] = ((input.charCodeAt(i) >> 18) | 0xF0);
+ data[bytes++] = (((input.charCodeAt(i) >> 12) & 0x3F) | 0x80);
+ data[bytes++] = (((input.charCodeAt(i) >> 6) & 0x3F) | 0x80);
+ data[bytes++] = ((input.charCodeAt(i) & 0x3F) | 0x80);
+ }
+ }
+ return encode64array(data);
+}
+
+function org_apache_cxf_base64_decode64array(input) {
+ var output = new Array();
+ var chr1, chr2, chr3;
+ var enc1, enc2, enc3, enc4;
+ var i = 0;
+
+ // remove all characters that are not A-Z, a-z, 0-9, +, /, or =
+ input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
+
+ do {
+ enc1 = org_apache_cxf_base64_keyStr.indexOf(input.charAt(i++));
+ enc2 = org_apache_cxf_base64_keyStr.indexOf(input.charAt(i++));
+ enc3 = org_apache_cxf_base64_keyStr.indexOf(input.charAt(i++));
+ enc4 = org_apache_cxf_base64_keyStr.indexOf(input.charAt(i++));
+
+ chr1 = (enc1 << 2) | (enc2 >> 4);
+ chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
+ chr3 = ((enc3 & 3) << 6) | enc4;
+
+ output[output.length] = chr1;
+
+ if (enc3 != 64) {
+ output[output.length] = chr2;
+ }
+ if (enc4 != 64) {
+ output[output.length] = chr3;
+ }
+ } while (i < input.length);
+
+ return output;
+}
+
+const org_apache_cxf_base64_hD = "0123456789ABCDEF";
+function org_apache_cxf_base64_d2h(d) {
+ var h = org_apache_cxf_base64_hD.substr(d & 15, 1);
+ while (d > 15) {
+ d >>= 4;
+ h = org_apache_cxf_base64_hD.substr(d & 15, 1) + h;
+ }
+ return h;
+}
+
+function org_apache_cxf_base64_decode64Unicode(input) {
+ var bytes = org_apache_cxf_base64_decode64array(input);
+ var swap;
+ var output = "";
+ if (bytes[0] == 0xff && bytes[1] == 0xfe) {
+ swap = true;
+ } else if (bytes[0] == 0xfe && bytes[1] == 0xff) {
+ swap = false;
+ } else {
+ confirm("Problem with decoding utf-16");
+ }
+ for (var x = 2;x < bytes.length; x = x + 2) {
+ var c;
+ if (swap)
+ c = (bytes[x + 1] << 8) | bytes[x];
+ else
+ c = (bytes[x] << 8) | bytes[x + 1];
+
+ output = output + String.fromCharCode(c);
+ }
+ return output;
+}
+
+// we may be able to do this more cleanly with decodeURIComponent( escape( input
+// ) );
+function org_apache_cxf_base64_decode64UTF8(input) {
+ var utftext = org_apache_cxf_base64_decode64array(input);
+ var plaintext = "";
+ var cRay = new Array();
+ var i = 0;
+ var c;
+ var c2;
+ var c3;
+ while (i < utftext.length) {
+ c = utftext[i];
+ if (c < 128) {
+ plaintext += String.fromCharCode(c);
+ i++;
+ } else if ((c > 191) && (c < 224)) {
+ c2 = utftext[i + 1];
+ plaintext += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
+ i += 2;
+ } else {
+ c2 = utftext[i + 1];
+ c3 = utftext[i + 2];
+ plaintext += String.fromCharCode(((c & 15) << 12)
+ | ((c2 & 63) << 6) | (c3 & 63));
+ i += 3;
+ }
+ }
+ return plaintext;
+}
+
+// var placeholder = '<xop:Include
+// xmlns:xop="http://www.w3.org/2004/08/xop/include" '
+// + 'href="cid:' + uuid + '" />';
+// var mtomObject = 'Content-Type: text/plain; charset="utf-8";\r\nContent-ID:
+// <'
+// + uuid + '>\r\n\r\n' + value + '\r\n';
+
+const org_apache_cxf_XOP_NS = 'http://www.w3.org/2004/08/xop/include';
+
+function org_apache_cxf_deserialize_MTOM_or_base64(element) {
+ var elementChild = this.getFirstElementChild(element);
+ if (elementChild == null) { // no MTOM, assume base64
+ var base64Text = this.getNodeText(element);
+ // we assume this is text/plain;charset=utf-8. We could check for the
+ // xmime attribute.
+ return org_apache_cxf_base64_decode64UTF8(base64Text);
+ }
+ //
+ if (!org_apache_cxf_isNodeNamedNS(elementChild, org_apache_cxf_XOP_NS, 'Include')) {
+ this.trace('Invalid child element of base64 element');
+ return ''; // we don't knoww what this is, so we throw it out. We could
+ // throw.
+ }
+ var href = elementChild.getAttribute('href');
+ if(!href) {
+ this.trace('missing href for xop:Include');
+ return ''; // we don't knoww what this is, so we throw it out. We could
+ // throw.
+ }
+ // we only support cid:, not URLs.
+ if(href.length < 4 || href.substr(0, 4) != 'cid:') {
+ this.trace('Non-cid href in xop:Include: ' + href);
+ return '';
+ }
+ var cid = href.substr(4);
+ var partobject = this.client.parts[cid];
+ if(!partobject) {
+ this.trace('xop:Include href points to missing attachment: ' + href);
+ return '';
+ }
+ // success.
+ return partobject.data;
+}
+
+CxfApacheOrgUtil.prototype.deserializeBase64orMom = org_apache_cxf_deserialize_MTOM_or_base64;
/*
* Client object sends requests and calls back with responses.
*/
@@ -471,15 +708,15 @@
for (var x = 1;x < strings.length; x = x + 1) {
var str = strings[x];
var valequal = str.indexOf("=");
- if(valequal != -1) {
+ if (valequal != -1) {
var k = str.substr(0, valequal);
- var v = str.substr(valequal+1);
+ var v = str.substr(valequal + 1);
v = org_apache_cxf_trim_string(v);
- if(v.charAt(0) == '"') {
- v = v.substr(1, v.length-2);
+ if (v.charAt(0) == '"') {
+ v = v.substr(1, v.length - 2);
}
- if(v.charAt(0) == "'") {
- v = v.substr(1, v.length-2);
+ if (v.charAt(0) == "'") {
+ v = v.substr(1, v.length - 2);
}
result[org_apache_cxf_trim_string(k.toLowerCase())] = v;
@@ -517,21 +754,22 @@
if (!boundary)
return false;
boundary = "--" + boundary; // the annoying 'extra-dash' convention.
- //var boundarySplitter = org_apache_cxf_regexp_escape(boundary);
+ // var boundarySplitter = org_apache_cxf_regexp_escape(boundary);
var text = this.req.responseText;
// we are willing to use a lot of memory here.
var parts = text.split(boundary);
// now we have the parts.
// now we have to pull headers off the parts.
this.parts = [];
- // the first one is noise due to the initial boundary. The last will just be -- due to MIME.
- for (var px = 1;px < parts.length-1; px++) {
+ // the first one is noise due to the initial boundary. The last will just be
+ // -- due to MIME.
+ for (var px = 1;px < parts.length - 1; px++) {
var seenOneHeader = false;
var x = 0; // misc index.
var parttext = parts[px];
var headers = [];
- nextHeaderLine:
- for(var endX = parttext.indexOf('\r', x); endX != -1; x = endX + 1, endX = parttext.indexOf('\r', x)) {
+ nextHeaderLine : for (var endX = parttext.indexOf('\r', x);endX != -1; x = endX
+ + 1, endX = parttext.indexOf('\r', x)) {
var headerLine = parttext.slice(x, endX);
if (headerLine == "") {
if (parttext.charAt(endX + 1) == '\n')
@@ -547,8 +785,7 @@
headers[hparts[0].toLowerCase()] = org_apache_cxf_trim_string(hparts[1]);
if (parttext.charAt(endX + 1) == '\n')
endX++;
- }
-
+ }
// Now, see about the mime type (if any) and the ID.
var thispart = new Object(); // a constructor seems excessive.
@@ -560,7 +797,7 @@
if (px > 1) {
var cid = headers['content-id'];
// take of < and >
- cid = cid.substr(1, cid.length-2);
+ cid = cid.substr(1, cid.length - 2);
thispart.cid = cid;
this.parts[cid] = thispart;
} else {
Modified: incubator/cxf/trunk/rt/javascript/src/test/java/org/apache/cxf/javascript/MtoMTest.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/javascript/src/test/java/org/apache/cxf/javascript/MtoMTest.java?rev=614203&r1=614202&r2=614203&view=diff
==============================================================================
--- incubator/cxf/trunk/rt/javascript/src/test/java/org/apache/cxf/javascript/MtoMTest.java (original)
+++ incubator/cxf/trunk/rt/javascript/src/test/java/org/apache/cxf/javascript/MtoMTest.java Tue Jan 22 06:14:16 2008
@@ -90,7 +90,8 @@
String errorText = testUtilities.rhinoEvaluateConvert("globalErrorStatusText", String.class);
assertNull(errorStatus);
assertNull(errorText);
- // read out the result string and check it.
+ String unpacked = testUtilities.rhinoEvaluateConvert("globalResponseObject._notXml10", String.class);
+ assertNotNull(unpacked);
return null;
}