Skip to content

Commit 1ead74f

Browse files
author
pborissow
committed
- Added logic to escape illegal characters in web service responses (e.g. "", "", etc).
- Minor documentation updates. git-svn-id: svn://192.168.0.80/JavaXT/javaxt-exchange@422 2c7b0aa6-e0b2-3c4e-bb4a-8b65b6c465ff
1 parent 3f06b8c commit 1ead74f

File tree

2 files changed

+116
-18
lines changed

2 files changed

+116
-18
lines changed

src/javaxt/exchange/Connection.java

Lines changed: 72 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,22 @@ public Connection(String host, String username, String password) {
2929
this.password = password;
3030
}
3131

32+
33+
//**************************************************************************
34+
//** getHost
35+
//**************************************************************************
36+
/** Returns the URL to the Exchange Web Services (EWS) endpoint.
37+
*/
3238
public String getHost(){
3339
return ews;
3440
}
35-
41+
42+
43+
//**************************************************************************
44+
//** getUserName
45+
//**************************************************************************
46+
/** Returns the username used to bind the Exchange Web Services.
47+
*/
3648
public String getUserName(){
3749
return username;
3850
}
@@ -41,6 +53,10 @@ public String getUserName(){
4153
//**************************************************************************
4254
//** createRequest
4355
//**************************************************************************
56+
/** Returns an HTTP request object configured to execute a web service
57+
* requests. To actually execute a request, users must send a SOAP message
58+
* using one of the Request.write() methods.
59+
*/
4460
protected javaxt.http.Request createRequest(){
4561
javaxt.http.Request request = new javaxt.http.Request(ews);
4662
request.validateSSLCertificates(true);
@@ -55,6 +71,16 @@ protected javaxt.http.Request createRequest(){
5571
//**************************************************************************
5672
//** getResponse
5773
//**************************************************************************
74+
/** Returns a response from a web service service request. The response can
75+
* be either an XML Document or the raw HTTP Response object, depending on
76+
* the parseResponse parameter.
77+
*
78+
* @param request An HTTP Request that has already been "written" to.
79+
*
80+
* @param parseResponse If true, parses the HTTP Response from the server
81+
* and returns an XML Document. If false, does not parse the response and
82+
* returns the raw HTTP Response object.
83+
*/
5884
protected Object getResponse(javaxt.http.Request request, boolean parseResponse) throws ExchangeException {
5985
javaxt.http.Response response = request.getResponse();
6086
int status = response.getStatus();
@@ -76,7 +102,12 @@ protected Object getResponse(javaxt.http.Request request, boolean parseResponse)
76102

77103
if (!parseResponse) return response;
78104

79-
org.w3c.dom.Document xml = response.getXML();
105+
String text = response.getText();
106+
org.w3c.dom.Document xml = javaxt.xml.DOM.createDocument(text);
107+
if (xml==null){ //Possible illegal characters in XML (e.g. "&#x17")
108+
xml = updateXML(text);
109+
}
110+
80111
String error = parseError(xml);
81112
if (error!=null) throw new ExchangeException(error);
82113
//new javaxt.io.File("/temp/exchange-execute-" + new java.util.Date().getTime() + ".xml").write(xml);
@@ -165,21 +196,54 @@ private String parseError(org.w3c.dom.Document xml){
165196
if (attrName.equalsIgnoreCase("ResponseCode")) ResponseCode = attrValue;
166197
if (attrName.equalsIgnoreCase("MessageXml")) MessageXml = javaxt.xml.DOM.getText(details.getChildNodes());
167198

168-
169199
}
170-
171-
172200
return (MessageText + ": " + MessageXml);
173201
}
174202

175203
break;
176204
}
205+
}
206+
}
207+
return null;
208+
}
177209

178210

211+
//**************************************************************************
212+
//** updateXML
213+
//**************************************************************************
214+
/** For whatever reason, Exchange Web Services return XML documents with
215+
* illegal XML characters (e.g. "&#x17"). This is commonly seen in the
216+
* GetItem response messages with HTML (e.g. email messages). To circumvent
217+
* this issue, this method tries to wrap the invalid characters in a CDATA
218+
* block.
219+
*/
220+
private org.w3c.dom.Document updateXML(String text){
221+
222+
//Find error. See if its an illegal character.
223+
while (true)
224+
try{
225+
java.io.InputStream is = new java.io.ByteArrayInputStream(text.getBytes("UTF-8"));
226+
javax.xml.parsers.DocumentBuilderFactory builderFactory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
227+
javax.xml.parsers.DocumentBuilder builder = builderFactory.newDocumentBuilder();
228+
return builder.parse(is);
229+
}
230+
catch(Exception e){
231+
232+
//Parse the error message. Look for errors specific to invalid characters.
233+
//Note this extremely error prone and has only been tested on Java 1.6 in the US Locale...
234+
String error = e.getMessage().trim();
235+
if (error.startsWith("Character reference \"") && error.endsWith("\" is an invalid XML character.")){
236+
String illegalChar = error.substring(error.indexOf("\"")+1, error.lastIndexOf("\""));
237+
String a = text.substring(0, text.indexOf(illegalChar));
238+
String b = text.substring(text.indexOf(illegalChar));
239+
240+
a = a.substring(0, a.lastIndexOf(">")+1) + "<![CDATA[" + a.substring(a.lastIndexOf(">")+1);
241+
b = b.substring(0, b.indexOf("<")) + "]]>" + b.substring(b.indexOf("<")) ;
242+
text = a + b;
243+
}
244+
else{
245+
return null;
179246
}
180-
181247
}
182-
183-
return null;
184248
}
185249
}

src/javaxt/exchange/Mailbox.java

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,29 @@ public Mailbox(Contact contact){
7171
//**************************************************************************
7272
//** getEmailAddress
7373
//**************************************************************************
74+
/** Returns the EmailAddress associated with this Mailbox, or null if the
75+
* EmailAddress is undefined.
76+
*/
7477
public EmailAddress getEmailAddress(){
7578
return EmailAddress;
7679
}
7780

81+
82+
//**************************************************************************
83+
//** setEmailAddress
84+
//**************************************************************************
85+
/** Used to set/update the EmailAddress associated with this Mailbox.
86+
*/
7887
public void setEmailAddress(EmailAddress emailAddress){
7988
this.EmailAddress = emailAddress;
8089
}
8190

91+
92+
//**************************************************************************
93+
//** setEmailAddress
94+
//**************************************************************************
95+
/** Used to set/update the EmailAddress associated with this Mailbox.
96+
*/
8297
public void setEmailAddress(String emailAddress) throws ExchangeException {
8398
setEmailAddress(new EmailAddress(emailAddress));
8499
}
@@ -108,6 +123,8 @@ public String getDomainAddress(){
108123
//**************************************************************************
109124
//** getName
110125
//**************************************************************************
126+
/** Returns the display name associated with this Mailbox (e.g. "John Smith").
127+
*/
111128
public String getName(){
112129
return Name;
113130
}
@@ -149,8 +166,12 @@ protected String toXML(String namespace){
149166
}
150167

151168

152-
153-
169+
//**************************************************************************
170+
//** toString
171+
//**************************************************************************
172+
/** Returns a string representation of this Mailbox (e.g.
173+
* "John Smith &lt;jsmith@acme.com&gt;").
174+
*/
154175
public String toString(){
155176
if (Name!=null && EmailAddress!=null) return Name + " <" + EmailAddress + ">";
156177
if (EmailAddress!=null) return EmailAddress.toString();
@@ -159,6 +180,12 @@ public String toString(){
159180
}
160181

161182

183+
//**************************************************************************
184+
//** equals
185+
//**************************************************************************
186+
/** Used to compare this Mailbox to another. Returns true if the hashcodes
187+
* match.
188+
*/
162189
public boolean equals(Object obj){
163190
if (obj!=null){
164191
if (obj instanceof Mailbox){
@@ -168,14 +195,25 @@ public boolean equals(Object obj){
168195
return false;
169196
}
170197

198+
199+
//**************************************************************************
200+
//** hashCode
201+
//**************************************************************************
202+
/** Returns the hashcode associated with the EmailAddress. If the
203+
* EmailAddress is undefined, returns the hashcode of the domain address.
204+
* If both the EmailAddress and domain address are undefined, returns 0.
205+
*/
171206
public int hashCode(){
172-
return (EmailAddress != null) ? EmailAddress.hashCode() : 0;
207+
return (EmailAddress!=null) ? EmailAddress.hashCode() :
208+
(domainAddress!=null? domainAddress.hashCode() : 0);
173209
}
174210

175211

176-
/** Attempts to resolve a user name, email address, or an ADSI string to a
177-
* Mailbox and Contact.
178-
* @return
212+
//**************************************************************************
213+
//** resolveName
214+
//**************************************************************************
215+
/** Attempts to resolve a user name, email address, or a domain address to a
216+
* Mailbox.
179217
*/
180218
public static Mailbox resolveName(String name, Connection conn) throws ExchangeException {
181219
StringBuffer str = new StringBuffer();
@@ -184,17 +222,14 @@ public static Mailbox resolveName(String name, Connection conn) throws ExchangeE
184222
str.append("<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" "
185223
+ "xmlns:t=\"http://schemas.microsoft.com/exchange/services/2006/types\" "
186224
+ "xmlns:m=\"http://schemas.microsoft.com/exchange/services/2006/messages\">");
187-
//+ "<soap:Header><t:RequestServerVersion Version=\"Exchange2007\"/></soap:Header>"
188225
str.append("<soap:Body>");
189226
str.append("<m:ResolveNames ReturnFullContactData=\"false\" >");
190227
str.append("<m:UnresolvedEntry>");
191228
str.append(name);
192229
str.append("</m:UnresolvedEntry>");
193230
str.append("</m:ResolveNames>");
194-
195231
str.append("</soap:Body>");
196232
str.append("</soap:Envelope>");
197-
198233

199234
org.w3c.dom.Document xml = conn.execute(str.toString());
200235
org.w3c.dom.Node[] items = javaxt.xml.DOM.getElementsByTagName("Resolution", xml);
@@ -203,7 +238,6 @@ public static Mailbox resolveName(String name, Connection conn) throws ExchangeE
203238
for (int i=0; i<nodes.getLength(); i++){
204239
org.w3c.dom.Node node = nodes.item(i);
205240
if (node.getNodeType()==1){
206-
//System.out.println(node.getNodeName());
207241
String nodeName = node.getNodeName();
208242
if (nodeName.contains(":")) nodeName = nodeName.substring(nodeName.indexOf(":")+1);
209243
if (nodeName.equalsIgnoreCase("Mailbox")){

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy