You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by ng...@apache.org on 2009/12/07 17:59:17 UTC
svn commit: r888001 - in /mina/sandbox/vysper/trunk/nbxml/src:
main/java/org/apache/vysper/xmpp/xmldecoder/ParticleDecoder.java
test/java/org/apache/vysper/xmpp/xmldecoder/ParticleDecoderTestCase.java
Author: ngn
Date: Mon Dec 7 16:59:17 2009
New Revision: 888001
URL: http://svn.apache.org/viewvc?rev=888001&view=rev
Log:
Adding a simple statemachine when parsing XML as to handle some odd cases
Added:
mina/sandbox/vysper/trunk/nbxml/src/test/java/org/apache/vysper/xmpp/xmldecoder/ParticleDecoderTestCase.java
Modified:
mina/sandbox/vysper/trunk/nbxml/src/main/java/org/apache/vysper/xmpp/xmldecoder/ParticleDecoder.java
Modified: mina/sandbox/vysper/trunk/nbxml/src/main/java/org/apache/vysper/xmpp/xmldecoder/ParticleDecoder.java
URL: http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/nbxml/src/main/java/org/apache/vysper/xmpp/xmldecoder/ParticleDecoder.java?rev=888001&r1=888000&r2=888001&view=diff
==============================================================================
--- mina/sandbox/vysper/trunk/nbxml/src/main/java/org/apache/vysper/xmpp/xmldecoder/ParticleDecoder.java (original)
+++ mina/sandbox/vysper/trunk/nbxml/src/main/java/org/apache/vysper/xmpp/xmldecoder/ParticleDecoder.java Mon Dec 7 16:59:17 2009
@@ -29,6 +29,19 @@
* @author The Apache MINA Project (dev@mina.apache.org)
*/
public class ParticleDecoder {
+
+ private enum State {
+ START, IN_TEXT, IN_TAG, IN_DOUBLE_ATTRIBUTE, IN_SINGLE_ATTRIBUTE, END, END_TEXT;
+
+ public static boolean inAttribute(State state) {
+ return state == IN_DOUBLE_ATTRIBUTE || state == IN_SINGLE_ATTRIBUTE;
+ }
+
+ public static boolean atEnd(State state) {
+ return state == END || state == END_TEXT;
+ }
+}
+
/**
* split in String, either in those parts enclosed by brackets or those who are not
* @param byteBuffer
@@ -39,24 +52,42 @@
public static XMLParticle decodeParticle(ByteBuffer byteBuffer, CharsetDecoder charsetDecoder) throws Exception {
int startPosition = byteBuffer.position();
- //String DEBUG_VORDERBAND = byteBuffer.duplicate().getString(charsetDecoder);
+ State state = State.START;
if (!byteBuffer.hasRemaining()) return null;
// count opening and closing braces
char firstChar = (char)byteBuffer.get();
- boolean plainText = firstChar != '<';
+ if(firstChar == '<') {
+ state = State.IN_TAG;
+ } else {
+ state = State.IN_TEXT;
+ }
- boolean endReached = false;
while (byteBuffer.remaining() > 0) {
char aChar = (char)byteBuffer.get();
- if (plainText && aChar == '<') endReached = true;
- if (!plainText && aChar == '>') endReached = true;
-
- if (endReached) {
+ if (state != State.IN_TEXT && state != State.IN_SINGLE_ATTRIBUTE && aChar == '"') {
+ if (state == State.IN_DOUBLE_ATTRIBUTE) {
+ state = State.IN_TAG;
+ } else {
+ state = State.IN_DOUBLE_ATTRIBUTE;
+ }
+ }
+ if (state != State.IN_TEXT && state != State.IN_DOUBLE_ATTRIBUTE && aChar == '\'') {
+ if (state == State.IN_SINGLE_ATTRIBUTE) {
+ state = State.IN_TAG;
+ } else {
+ state = State.IN_SINGLE_ATTRIBUTE;
+ }
+ }
+
+ if (state == State.IN_TEXT && aChar == '<') state = State.END_TEXT;
+ if (state != State.IN_TEXT && !State.inAttribute(state) && aChar == '>') state = State.END;
+
+ if (State.atEnd(state)) {
int endPosition = byteBuffer.position();
- if (plainText) endPosition--;
+ if (state == State.END_TEXT) endPosition--;
int limit = byteBuffer.limit();
ByteBuffer stanzaBuffer = null;
try {
@@ -69,8 +100,7 @@
byteBuffer.position(endPosition);
byteBuffer.limit(limit);
}
- //String DEBUG_HINTERBAND = stanzaBuffer.duplicate().getString(charsetDecoder);
- //String DEBUG_REMAINS = byteBuffer.duplicate().getString(charsetDecoder);
+
String content = stanzaBuffer.getString(charsetDecoder);
return new XMLParticle(content);
}
Added: mina/sandbox/vysper/trunk/nbxml/src/test/java/org/apache/vysper/xmpp/xmldecoder/ParticleDecoderTestCase.java
URL: http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/nbxml/src/test/java/org/apache/vysper/xmpp/xmldecoder/ParticleDecoderTestCase.java?rev=888001&view=auto
==============================================================================
--- mina/sandbox/vysper/trunk/nbxml/src/test/java/org/apache/vysper/xmpp/xmldecoder/ParticleDecoderTestCase.java (added)
+++ mina/sandbox/vysper/trunk/nbxml/src/test/java/org/apache/vysper/xmpp/xmldecoder/ParticleDecoderTestCase.java Mon Dec 7 16:59:17 2009
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.vysper.xmpp.xmldecoder;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.apache.mina.common.ByteBuffer;
+import org.apache.vysper.charset.CharsetUtil;
+
+/**
+ */
+public class ParticleDecoderTestCase extends TestCase {
+
+ public void testSimple() throws Exception {
+ List<XMLParticle> particles = decodeAll("<root>text</root>");
+ XMLParticle opening = particles.get(0);
+ XMLParticle text = particles.get(1);
+ XMLParticle closing = particles.get(2);
+
+ assertTrue(opening.isOpeningElement());
+ assertEquals("root", opening.getElementName());
+
+ assertTrue(text.isText());
+ assertEquals("text", text.getContent());
+
+ assertTrue(closing.isClosingElement());
+ assertEquals("root", closing.getElementName());
+ }
+
+ public void testParseDoubleQuoteAttributes() throws Exception {
+ String xml = "<root att=\"foo\">";
+ XMLParticle opening = decode(xml);
+
+ assertTrue(opening.isOpeningElement());
+ assertEquals("root", opening.getElementName());
+ assertEquals(xml, opening.getContent());
+ }
+
+ public void testParseSingleQuoteAttributes() throws Exception {
+ String xml = "<root att='f\"oo'>";
+ XMLParticle opening = decode(xml);
+
+ assertTrue(opening.isOpeningElement());
+ assertEquals("root", opening.getElementName());
+ assertEquals(xml, opening.getContent());
+ }
+
+ public void testParseAttributeWithLt() throws Exception {
+ // TODO This is not supported as per the XML spec, we might want to fail already in ParticleDecoder
+ String xml = "<root att='<'>";
+ XMLParticle opening = decode(xml);
+
+ assertTrue(opening.isOpeningElement());
+ assertEquals("root", opening.getElementName());
+ assertEquals(xml, opening.getContent());
+ }
+
+ public void testParseAttributeWithGt() throws Exception {
+ String xml = "<root att='>'>";
+ XMLParticle opening = decode(xml);
+ assertTrue(opening.isOpeningElement());
+ assertEquals("root", opening.getElementName());
+ assertEquals(xml, opening.getContent());
+ }
+
+ public void testParseComment() throws Exception {
+ XMLParticle opening = decode("<!-- comment -->");
+
+ assertTrue(opening.isOpeningElement());
+ // TODO activate when XMLParticle supports comments
+ // assertNull(opening.getElementName());
+ assertEquals("<!-- comment -->", opening.getContent());
+ }
+
+ public void testParsePI() throws Exception {
+ String xml = "<?pi att=\"foo\" ?>";
+ XMLParticle opening = decode(xml);
+
+ assertTrue(opening.isOpeningElement());
+ assertEquals("pi", opening.getElementName());
+ assertEquals(xml, opening.getContent());
+ }
+
+
+ private ByteBuffer wrap(String xml) throws Exception {
+ return ByteBuffer.wrap(xml.getBytes("UTF-8"));
+ }
+
+ private XMLParticle decode(String xml) throws Exception {
+ return decode(wrap(xml));
+ }
+
+ private XMLParticle decode(ByteBuffer bb) throws Exception {
+ return ParticleDecoder.decodeParticle(bb, CharsetUtil.UTF8_DECODER);
+ }
+
+ private List<XMLParticle> decodeAll(String xml) throws Exception {
+ ByteBuffer bb = wrap(xml);
+ List<XMLParticle> particles = new ArrayList<XMLParticle>();
+
+ XMLParticle particle = decode(bb);
+ while(particle != null) {
+ particles.add(particle);
+
+ particle = decode(bb);
+ }
+ return particles;
+ }
+
+}