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.

Reply via email to