Ashish, thanks for posting the code. I will take this and go from here.
Ashish-24 wrote:
>
> Thanks Emmanuel!
>
> The pointer was helpful. Though I though about implementing somewhat
> in a different way.
>
> The decoder was implemented just to see the xml is complete and then
> pass-on the buffer to an abstract function, to be
> implemented by the user, picking an XML parser or Data binding
> Framework of his choice, convert it to the Object as expected by their
> Handler.
>
> Before I dump the code, few words
> 1. The code is not very clean and production ready. It just gives an
> idea of how to do it
> 2. The parsing doesn't handle all the XML specification conditions.
> 3. My limited knowledge of IoBuffer class has made code more cryptic
> than it should have been :-)
>
> Either ways, it shall server the purpose of that people can take it to
> next level, and will write a post on this on my blog
>
> I am inclined towards using regular expression for parsing and will
> post the code if I am able to do that.
>
> Thanks all!
>
> import org.apache.mina.common.IoBuffer;
> import org.apache.mina.common.IoSession;
> import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
> import org.apache.mina.filter.codec.ProtocolDecoderOutput;
> import org.slf4j.Logger;
> import org.slf4j.LoggerFactory;
>
>
> public abstract class XMLDecoder extends CumulativeProtocolDecoder {
>
> /*
> * As per XML specification 1.0, http://www.w3.org/TR/REC-xml
> */
> private static final char XML_START_TAG = '<';
> private static final char XML_END_TAG = '>';
> private static final char XML_PI_TAG = '?';
> private static final char XML_COMMENT_TAG = '!';
>
>
> protected static enum ParseState {ELEMENT_START, ELEMENT_END,
> COMMENTS, ENDELEMENT, PI, UNDEFINED};
>
> protected static final int ELEMENT_START = 1;
> protected static final int ELEMENT_END = 2;
>
> private static Logger logger =
> LoggerFactory.getLogger(XMLDecoder.class);
>
> @Override
> protected boolean doDecode(IoSession session, IoBuffer ioBuffer,
> ProtocolDecoderOutput decoderOutput) throws Exception {
>
> int startPosition = ioBuffer.position();
>
> if(!ioBuffer.hasRemaining()) {
> logger.debug("NO bytes to read keep waiting...");
> return false;
> }
>
> // Continue to read the bytes and keep parsing
> char currentChar = '0', previousChar = '0';
>
> boolean rootElementStarted = false;
> boolean rootElementPresent = false;
> boolean isBalanced = false;
>
> int rootStartPosition, rootEndPosition;
>
> ParseState parsingState = ParseState.UNDEFINED;
> logger.debug("Lets start decoding the XML");
>
> String root = null;
>
> boolean markedForEndElement = false;
>
> while(ioBuffer.hasRemaining()) {
> previousChar = currentChar;
> currentChar = (char)ioBuffer.get();
>
> switch (parsingState) {
> case ELEMENT_START:
> if(currentChar == XML_PI_TAG){
> logger.debug("Got PI Element");
> parsingState = ParseState.PI;
>
> } else if(currentChar ==
> XML_COMMENT_TAG) {
> logger.debug("Got Comment
> Element");
> parsingState =
> ParseState.COMMENTS;
> } else if((currentChar == ' ' ||
> currentChar == XML_END_TAG)
> &&
> rootElementStarted && !rootElementPresent) {
> rootEndPosition =
> ioBuffer.position();
> rootElementPresent = true;
>
> // Copy the Root Element
> int cPos = ioBuffer.position();
> int mPos = ioBuffer.markValue();
>
> char[] rootChar = new char[cPos
> - mPos];
> for(int i = mPos - 1, j =0; i <
> cPos - 1; i++) {
> rootChar[j++] =
> (char)ioBuffer.get(i);
> }
>
> root = new String(rootChar);
> logger.debug("Root Element = "+
> root);
> parsingState =
> ParseState.ELEMENT_END;
> logger.debug("Root Element
> detection completed "+rootEndPosition);
> } else if(currentChar == XML_END_TAG) {
> parsingState =
> ParseState.ELEMENT_END;
> } else if(!rootElementStarted &&
> !rootElementPresent) {
> rootStartPosition =
> ioBuffer.position();
> ioBuffer.mark();
> rootElementStarted = true;
> logger.debug("Got the root
> element at "+rootStartPosition);
> } else if (currentChar == '/') {
> // Change state
> if(previousChar ==
> XML_START_TAG) {
> parsingState =
> ParseState.ENDELEMENT;
> }
> }
> break;
>
> case ENDELEMENT:
> if(currentChar == XML_END_TAG) {
> parsingState =
> ParseState.ELEMENT_END;
>
> int cPos = ioBuffer.position();
> int mPos = ioBuffer.markValue();
>
> char[] el = new char[cPos -
> mPos];
> for(int i = mPos - 1, j =0; i <
> cPos - 1; i++) {
> el[j++] =
> (char)ioBuffer.get(i);
> }
> markedForEndElement = false;
> if(root.equalsIgnoreCase(new
> String(el))) {
> logger.debug("XML is
> balanced."+root);
> isBalanced = true;
> }
>
> break;
> } else if (currentChar == ' ') {
> continue;
> } else {
>
> // mark the position, we need
> to compare the it to see that if
> its the end element
> if(!markedForEndElement) {
> // logger.debug("Marking");
> ioBuffer.mark();
> markedForEndElement =
> true;
> }
> }
> break;
>
> case ELEMENT_END:
> if(currentChar == XML_START_TAG) {
> parsingState =
> ParseState.ELEMENT_START;
> }
> break;
>
> case UNDEFINED:
> if(currentChar == XML_START_TAG) {
> parsingState =
> ParseState.ELEMENT_START;
> }
> break;
>
> case COMMENTS:
> if (currentChar == '-') {
> previousChar = currentChar;
> } else if (previousChar == '-' &&
> currentChar == '>') {
> parsingState =
> ParseState.ELEMENT_END;
> }
> break;
>
> case PI:
> if (currentChar == '?') {
> previousChar = currentChar;
> } else if (previousChar == '?' &&
> currentChar == XML_END_TAG) {
> parsingState =
> ParseState.ELEMENT_END;
> }
> break;
>
> default:
> break;
> }
> }
>
> if(isBalanced) {
> decoderOutput.write(parserXML(ioBuffer));
> }
>
> if(isBalanced && !ioBuffer.hasRemaining()) {
> logger.debug("No more bytes to process");
> return true;
> }
>
> ioBuffer.position(startPosition);
> return false;
> }
>
> /**
> * Extending classes can implement their custom XML parsing to create
> Objects
> * from XML and use them appropriately in Handler
> *
> * @param xmlBuffer
> * @return
> */
> public abstract Object parserXML(IoBuffer xmlBuffer);
> }
>
>
> On Wed, Oct 22, 2008 at 10:25 PM, Emmanuel Lecharny <[EMAIL PROTECTED]>
> wrote:
>> Smith wrote:
>>>
>>> Hi , i'm following your discussion and i remember that the guys from
>>> JiveSoftware have created an XMPP server using mina , and the XMPP
>>> protocol
>>> use XML Stream. The software is under GPL so you can take a look a the
>>> source to see how they handle this problem :)
>>
>> There is also an Apache effort based on MINA and XMPP :
>> http://svn.apache.org/repos/asf/labs/vysper/
>>
>> The code is available, and is ASL 2.0, of course.
>>
>> --
>> --
>> cordialement, regards,
>> Emmanuel Lécharny
>> www.iktek.com
>> directory.apache.org
>
> --
> thanks
> ashish
>
> Blog: http://www.ashishpaliwal.com/blog
>
> My Photo Galleries: http://www.pbase.com/ashishpaliwal
>
>
--
View this message in context:
http://www.nabble.com/MINA---design-guidelines-tp20077627p20132388.html
Sent from the Apache MINA User Forum mailing list archive at Nabble.com.