mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-12-23 13:07:59 +01:00
SMACK-425 Introduced smack.parsing.ParsingExceptionCallback, a callback invoked when a exception is thrown while parsing a stanza. Smack is now able to either rethrow the exception ulitmatly causing a disconnect *or* log/ignore the exception and resume parsing after the faulty stanza.
git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/branches/smack_3_3_1@13688 b35dd754-fafc-0310-a699-88a17e54d16e
This commit is contained in:
parent
18a603d932
commit
30bc5afa2b
12 changed files with 524 additions and 8 deletions
|
@ -1,4 +1,3 @@
|
||||||
#Tue Jan 29 23:27:16 CET 2013
|
|
||||||
eclipse.preferences.version=1
|
eclipse.preferences.version=1
|
||||||
editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
|
editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
|
||||||
formatter_profile=_ignite
|
formatter_profile=_ignite
|
||||||
|
@ -37,7 +36,7 @@ sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=
|
||||||
sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
|
sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
|
||||||
sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
|
sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
|
||||||
sp_cleanup.remove_private_constructors=true
|
sp_cleanup.remove_private_constructors=true
|
||||||
sp_cleanup.remove_trailing_whitespaces=false
|
sp_cleanup.remove_trailing_whitespaces=true
|
||||||
sp_cleanup.remove_trailing_whitespaces_all=true
|
sp_cleanup.remove_trailing_whitespaces_all=true
|
||||||
sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
|
sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
|
||||||
sp_cleanup.remove_unnecessary_casts=true
|
sp_cleanup.remove_unnecessary_casts=true
|
||||||
|
|
|
@ -22,6 +22,10 @@ package org.jivesoftware.smack;
|
||||||
|
|
||||||
import org.jivesoftware.smack.Connection.ListenerWrapper;
|
import org.jivesoftware.smack.Connection.ListenerWrapper;
|
||||||
import org.jivesoftware.smack.packet.*;
|
import org.jivesoftware.smack.packet.*;
|
||||||
|
import org.jivesoftware.smack.parsing.ParsingExceptionCallback;
|
||||||
|
import org.jivesoftware.smack.parsing.UnparsedIQ;
|
||||||
|
import org.jivesoftware.smack.parsing.UnparsedMessage;
|
||||||
|
import org.jivesoftware.smack.parsing.UnparsedPresence;
|
||||||
import org.jivesoftware.smack.sasl.SASLMechanism.Challenge;
|
import org.jivesoftware.smack.sasl.SASLMechanism.Challenge;
|
||||||
import org.jivesoftware.smack.sasl.SASLMechanism.Failure;
|
import org.jivesoftware.smack.sasl.SASLMechanism.Failure;
|
||||||
import org.jivesoftware.smack.sasl.SASLMechanism.Success;
|
import org.jivesoftware.smack.sasl.SASLMechanism.Success;
|
||||||
|
@ -176,14 +180,49 @@ class PacketReader {
|
||||||
int eventType = parser.getEventType();
|
int eventType = parser.getEventType();
|
||||||
do {
|
do {
|
||||||
if (eventType == XmlPullParser.START_TAG) {
|
if (eventType == XmlPullParser.START_TAG) {
|
||||||
|
int parserDepth = parser.getDepth();
|
||||||
|
ParsingExceptionCallback callback = connection.getParsingExceptionCallback();
|
||||||
if (parser.getName().equals("message")) {
|
if (parser.getName().equals("message")) {
|
||||||
processPacket(PacketParserUtils.parseMessage(parser));
|
Packet packet;
|
||||||
|
try {
|
||||||
|
packet = PacketParserUtils.parseMessage(parser);
|
||||||
|
} catch (Exception e) {
|
||||||
|
String content = PacketParserUtils.parseContentDepth(parser, parserDepth);
|
||||||
|
UnparsedMessage message = new UnparsedMessage(content, e);
|
||||||
|
if (callback != null) {
|
||||||
|
callback.messageParsingException(e, message);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
processPacket(packet);
|
||||||
}
|
}
|
||||||
else if (parser.getName().equals("iq")) {
|
else if (parser.getName().equals("iq")) {
|
||||||
processPacket(PacketParserUtils.parseIQ(parser, connection));
|
IQ iq;
|
||||||
|
try {
|
||||||
|
iq = PacketParserUtils.parseIQ(parser, connection);
|
||||||
|
} catch (Exception e) {
|
||||||
|
String content = PacketParserUtils.parseContentDepth(parser, parserDepth);
|
||||||
|
UnparsedIQ uniq = new UnparsedIQ(content, e);
|
||||||
|
if (callback != null) {
|
||||||
|
callback.iqParsingException(e, uniq);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
processPacket(iq);
|
||||||
}
|
}
|
||||||
else if (parser.getName().equals("presence")) {
|
else if (parser.getName().equals("presence")) {
|
||||||
processPacket(PacketParserUtils.parsePresence(parser));
|
Presence presence;
|
||||||
|
try {
|
||||||
|
presence = PacketParserUtils.parsePresence(parser);
|
||||||
|
} catch (Exception e) {
|
||||||
|
String content = PacketParserUtils.parseContentDepth(parser, parserDepth);
|
||||||
|
UnparsedPresence unpresence = new UnparsedPresence(content, e);
|
||||||
|
if (callback != null) {
|
||||||
|
callback.presenceParsingException(e, unpresence);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
processPacket(presence);
|
||||||
}
|
}
|
||||||
// We found an opening stream. Record information about it, then notify
|
// We found an opening stream. Record information about it, then notify
|
||||||
// the connectionID lock so that the packet reader startup can finish.
|
// the connectionID lock so that the packet reader startup can finish.
|
||||||
|
|
|
@ -28,6 +28,8 @@ import java.util.Enumeration;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.parsing.ParsingExceptionCallback;
|
||||||
|
import org.jivesoftware.smack.parsing.ThrowException;
|
||||||
import org.xmlpull.mxp1.MXParser;
|
import org.xmlpull.mxp1.MXParser;
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
@ -58,6 +60,12 @@ public final class SmackConfiguration {
|
||||||
private static int localSocks5ProxyPort = 7777;
|
private static int localSocks5ProxyPort = 7777;
|
||||||
private static int packetCollectorSize = 5000;
|
private static int packetCollectorSize = 5000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default parsing exception callback is {@link ThrowException} which will
|
||||||
|
* throw an exception and therefore disconnect the active connection.
|
||||||
|
*/
|
||||||
|
private static ParsingExceptionCallback defaultCallback = new ThrowException();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This automatically enables EntityCaps for new connections if it is set to true
|
* This automatically enables EntityCaps for new connections if it is set to true
|
||||||
*/
|
*/
|
||||||
|
@ -328,6 +336,26 @@ public final class SmackConfiguration {
|
||||||
autoEnableEntityCaps = b;
|
autoEnableEntityCaps = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the default parsing exception callback for all newly created connections
|
||||||
|
*
|
||||||
|
* @param callback
|
||||||
|
* @see ParsingExceptionCallback
|
||||||
|
*/
|
||||||
|
public static void setDefaultParsingExceptionCallback(ParsingExceptionCallback callback) {
|
||||||
|
defaultCallback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the default parsing exception callback
|
||||||
|
*
|
||||||
|
* @return the default parsing exception callback
|
||||||
|
* @see ParsingExceptionCallback
|
||||||
|
*/
|
||||||
|
public static ParsingExceptionCallback getDefaultParsingExceptionCallback() {
|
||||||
|
return defaultCallback;
|
||||||
|
}
|
||||||
|
|
||||||
private static void parseClassToLoad(XmlPullParser parser) throws Exception {
|
private static void parseClassToLoad(XmlPullParser parser) throws Exception {
|
||||||
String className = parser.nextText();
|
String className = parser.nextText();
|
||||||
// Attempt to load the class so that the class can get initialized
|
// Attempt to load the class so that the class can get initialized
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.jivesoftware.smack.filter.PacketFilter;
|
||||||
import org.jivesoftware.smack.packet.Packet;
|
import org.jivesoftware.smack.packet.Packet;
|
||||||
import org.jivesoftware.smack.packet.Presence;
|
import org.jivesoftware.smack.packet.Presence;
|
||||||
import org.jivesoftware.smack.packet.XMPPError;
|
import org.jivesoftware.smack.packet.XMPPError;
|
||||||
|
import org.jivesoftware.smack.parsing.ParsingExceptionCallback;
|
||||||
import org.jivesoftware.smack.util.StringUtils;
|
import org.jivesoftware.smack.util.StringUtils;
|
||||||
import org.jivesoftware.smack.util.dns.HostAddress;
|
import org.jivesoftware.smack.util.dns.HostAddress;
|
||||||
|
|
||||||
|
@ -89,6 +90,8 @@ public class XMPPConnection extends Connection {
|
||||||
private boolean anonymous = false;
|
private boolean anonymous = false;
|
||||||
private boolean usingTLS = false;
|
private boolean usingTLS = false;
|
||||||
|
|
||||||
|
private ParsingExceptionCallback parsingExceptionCallback = SmackConfiguration.getDefaultParsingExceptionCallback();
|
||||||
|
|
||||||
PacketWriter packetWriter;
|
PacketWriter packetWriter;
|
||||||
PacketReader packetReader;
|
PacketReader packetReader;
|
||||||
|
|
||||||
|
@ -202,6 +205,25 @@ public class XMPPConnection extends Connection {
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Install a parsing exception callback, which will be invoked once an exception is encountered while parsing a
|
||||||
|
* stanza
|
||||||
|
*
|
||||||
|
* @param callback the callback to install
|
||||||
|
*/
|
||||||
|
public void setParsingExceptionCallback(ParsingExceptionCallback callback) {
|
||||||
|
parsingExceptionCallback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current active parsing exception callback.
|
||||||
|
*
|
||||||
|
* @return the active exception callback or null if there is none
|
||||||
|
*/
|
||||||
|
public ParsingExceptionCallback getParsingExceptionCallback() {
|
||||||
|
return parsingExceptionCallback;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void login(String username, String password, String resource) throws XMPPException {
|
public synchronized void login(String username, String password, String resource) throws XMPPException {
|
||||||
if (!isConnected()) {
|
if (!isConnected()) {
|
||||||
|
|
51
source/org/jivesoftware/smack/parsing/LogException.java
Normal file
51
source/org/jivesoftware/smack/parsing/LogException.java
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
/**
|
||||||
|
* $RCSfile$
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2013 Florian Schmaus.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smack.parsing;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple parsing exception callback that only logs the encountered parsing exception to stderr.
|
||||||
|
*
|
||||||
|
* @author Florian Schmaus
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class LogException extends ParsingExceptionCallback {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void messageParsingException(Exception e, UnparsedMessage message) throws Exception {
|
||||||
|
System.err.print("Smack message parsing exception: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
System.err.println("Unparsed content: " + message.getContent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void iqParsingException(Exception e, UnparsedIQ iq) throws Exception {
|
||||||
|
System.err.print("Smack iq parsing exception: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
System.err.println("Unparsed content: " + iq.getContent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void presenceParsingException(Exception e, UnparsedPresence presence) throws Exception {
|
||||||
|
System.err.print("Smack presence parsing exception: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
System.err.println("Unparsed content: " + presence.getContent());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
/**
|
||||||
|
* $RCSfile$
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2013 Florian Schmaus.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smack.parsing;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class to receive parsing exceptions.
|
||||||
|
*
|
||||||
|
* If this class is used as callback, then Smack will silently ignore the stanza that caused the parsing exception and
|
||||||
|
* place the parser after the faulty stanza.
|
||||||
|
*
|
||||||
|
* Subclasses may or may not override certain methods of this class. Each of these methods will receive the exception
|
||||||
|
* that caused the parsing error and an instance of an Unparsed Packet type. The latter can be used to inspect the
|
||||||
|
* stanza that caused the parsing error by using the getContent() (for example {@link UnparsedIQ#getContent()})
|
||||||
|
* method.
|
||||||
|
*
|
||||||
|
* Smack provides 2 predefined ParsingExceptionCallback's: {@link LogException} and {@link ThrowException}.
|
||||||
|
*
|
||||||
|
* @author Florian Schmaus
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class ParsingExceptionCallback {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when parsing an message stanza caused an exception.
|
||||||
|
*
|
||||||
|
* @param e
|
||||||
|
* the exception thrown while parsing the message stanza
|
||||||
|
* @param message
|
||||||
|
* the raw message stanza data that caused the exception
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public void messageParsingException(Exception e, UnparsedMessage message) throws Exception {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when parsing an IQ stanza caused an exception.
|
||||||
|
*
|
||||||
|
* @param e
|
||||||
|
* the exception thrown while parsing the iq stanza
|
||||||
|
* @param iq
|
||||||
|
* the raw iq stanza data that caused the exception
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public void iqParsingException(Exception e, UnparsedIQ iq) throws Exception {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when parsing a presence stanza caused an exception.
|
||||||
|
*
|
||||||
|
* @param e
|
||||||
|
* the exception thrown while parsing the presence stanza
|
||||||
|
* @param presence
|
||||||
|
* the raw presence stanza data that caused the exception
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public void presenceParsingException(Exception e, UnparsedPresence presence) throws Exception {
|
||||||
|
}
|
||||||
|
}
|
48
source/org/jivesoftware/smack/parsing/ThrowException.java
Normal file
48
source/org/jivesoftware/smack/parsing/ThrowException.java
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/**
|
||||||
|
* $RCSfile$
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2013 Florian Schmaus.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smack.parsing;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.ConnectionListener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parsing exception callback class that simply throws the encountered parsing exception. This usually leads to an
|
||||||
|
* {@link ConnectionListener#connectionClosedOnError(Exception)} disconnect of the connection.
|
||||||
|
*
|
||||||
|
* @author Florian Schmaus
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ThrowException extends ParsingExceptionCallback {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void messageParsingException(Exception e, UnparsedMessage message) throws Exception {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void iqParsingException(Exception e, UnparsedIQ iq) throws Exception {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void presenceParsingException(Exception e, UnparsedPresence presence) throws Exception {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
62
source/org/jivesoftware/smack/parsing/UnparsedIQ.java
Normal file
62
source/org/jivesoftware/smack/parsing/UnparsedIQ.java
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
/**
|
||||||
|
* $RCSfile$
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2013 Florian Schmaus.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smack.parsing;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Representation of an unparsed IQ stanza.
|
||||||
|
*
|
||||||
|
* @author Florian Schmaus
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class UnparsedIQ extends IQ {
|
||||||
|
private final String content;
|
||||||
|
private final Exception e;
|
||||||
|
|
||||||
|
public UnparsedIQ(final String content, final Exception e) {
|
||||||
|
this.content = content;
|
||||||
|
this.e = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return the exception that caused the parser to fail
|
||||||
|
*/
|
||||||
|
public Exception getException() {
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the raw stanza data
|
||||||
|
*
|
||||||
|
* @return the raw stanza data
|
||||||
|
*/
|
||||||
|
public String getContent() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getChildElementXML() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
57
source/org/jivesoftware/smack/parsing/UnparsedMessage.java
Normal file
57
source/org/jivesoftware/smack/parsing/UnparsedMessage.java
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
/**
|
||||||
|
* $RCSfile$
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2013 Florian Schmaus.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smack.parsing;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.Message;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Representation of an unparsed IQ stanza.
|
||||||
|
*
|
||||||
|
* @author Florian Schmaus
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class UnparsedMessage extends Message {
|
||||||
|
private final String content;
|
||||||
|
private final Exception e;
|
||||||
|
|
||||||
|
public UnparsedMessage(final String content, final Exception e) {
|
||||||
|
this.content = content;
|
||||||
|
this.e = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return the exception that caused the parser to fail
|
||||||
|
*/
|
||||||
|
public Exception getException() {
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the raw stanza data
|
||||||
|
*
|
||||||
|
* @return the raw stanza data
|
||||||
|
*/
|
||||||
|
public String getContent() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
61
source/org/jivesoftware/smack/parsing/UnparsedPresence.java
Normal file
61
source/org/jivesoftware/smack/parsing/UnparsedPresence.java
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/**
|
||||||
|
* $RCSfile$
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2013 Florian Schmaus.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smack.parsing;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.Presence;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Representation of an unparsed IQ stanza.
|
||||||
|
*
|
||||||
|
* @author Florian Schmaus
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class UnparsedPresence extends Presence {
|
||||||
|
private String content;
|
||||||
|
private Exception e;
|
||||||
|
|
||||||
|
public UnparsedPresence(Type type) {
|
||||||
|
super(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnparsedPresence(final String content, final Exception e) {
|
||||||
|
super(Presence.Type.error);
|
||||||
|
this.content = content;
|
||||||
|
this.e = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return the exception that caused the parser to fail
|
||||||
|
*/
|
||||||
|
public Exception getException() {
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the raw stanza data
|
||||||
|
*
|
||||||
|
* @return the raw stanza data
|
||||||
|
*/
|
||||||
|
public String getContent() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
}
|
|
@ -171,10 +171,13 @@ public class PacketParserUtils {
|
||||||
*/
|
*/
|
||||||
private static String parseContent(XmlPullParser parser)
|
private static String parseContent(XmlPullParser parser)
|
||||||
throws XmlPullParserException, IOException {
|
throws XmlPullParserException, IOException {
|
||||||
StringBuffer content = new StringBuffer();
|
|
||||||
int parserDepth = parser.getDepth();
|
int parserDepth = parser.getDepth();
|
||||||
while (!(parser.next() == XmlPullParser.END_TAG && parser
|
return parseContentDepth(parser, parserDepth);
|
||||||
.getDepth() == parserDepth)) {
|
}
|
||||||
|
|
||||||
|
public static String parseContentDepth(XmlPullParser parser, int depth) throws XmlPullParserException, IOException {
|
||||||
|
StringBuffer content = new StringBuffer();
|
||||||
|
while (!(parser.next() == XmlPullParser.END_TAG && parser.getDepth() == depth)) {
|
||||||
content.append(parser.getText());
|
content.append(parser.getText());
|
||||||
}
|
}
|
||||||
return content.toString();
|
return content.toString();
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
package org.jivesoftware.smack.parsing;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.TestUtils;
|
||||||
|
import org.jivesoftware.smack.XMPPException;
|
||||||
|
import org.jivesoftware.smack.packet.PacketExtension;
|
||||||
|
import org.jivesoftware.smack.provider.PacketExtensionProvider;
|
||||||
|
import org.jivesoftware.smack.provider.ProviderManager;
|
||||||
|
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
public class ParsingExceptionTest {
|
||||||
|
private final static ProviderManager PM = ProviderManager.getInstance();
|
||||||
|
|
||||||
|
private final static String EXTENSION2 =
|
||||||
|
"<extension2 xmlns='namespace'>" +
|
||||||
|
"<bar node='testNode'>" +
|
||||||
|
"<i id='testid1' >" +
|
||||||
|
"</i>" +
|
||||||
|
"</bar>" +
|
||||||
|
"</extension2>";
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void init() {
|
||||||
|
PM.addExtensionProvider(ThrowException.ELEMENT, ThrowException.NAMESPACE, new ThrowException());
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tini() {
|
||||||
|
PM.removeExtensionProvider(ThrowException.ELEMENT, ThrowException.NAMESPACE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void consumeUnparsedInput() throws Exception {
|
||||||
|
XmlPullParser parser = TestUtils.getMessageParser(
|
||||||
|
"<message from='user@server.example' to='francisco@denmark.lit' id='foo'>" +
|
||||||
|
"<" + ThrowException.ELEMENT + " xmlns='" + ThrowException.NAMESPACE + "'>" +
|
||||||
|
"<nothingInHere>" +
|
||||||
|
"</nothingInHere>" +
|
||||||
|
"</" + ThrowException.ELEMENT + ">" +
|
||||||
|
EXTENSION2 +
|
||||||
|
"</message>");
|
||||||
|
int parserDepth = parser.getDepth();
|
||||||
|
String content = null;
|
||||||
|
try {
|
||||||
|
PacketParserUtils.parseMessage(parser);
|
||||||
|
} catch (Exception e) {
|
||||||
|
content = PacketParserUtils.parseContentDepth(parser, parserDepth);
|
||||||
|
}
|
||||||
|
assertNotNull(content);
|
||||||
|
assertEquals(content, "<nothingInHere></nothingInHere>" + "</" + ThrowException.ELEMENT + ">" + EXTENSION2);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static class ThrowException implements PacketExtensionProvider {
|
||||||
|
public static final String ELEMENT = "exception";
|
||||||
|
public static final String NAMESPACE = "http://smack.jivesoftware.org/exception";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
|
||||||
|
throw new XMPPException("Test Exception");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue