Package net.timewalker.ffmq3.common.message.selector

Source Code of net.timewalker.ffmq3.common.message.selector.MessageSelectorTokenizer

/*
* This file is part of FFMQ.
*
* FFMQ is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* FFMQ is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with FFMQ; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/
package net.timewalker.ffmq3.common.message.selector;

import java.util.ArrayList;
import java.util.List;

import javax.jms.InvalidSelectorException;

/**
* <p>
*  Implementation of a JMS message selector expression tokenizer.
* </p>
*/
public final class MessageSelectorTokenizer
{
    private static final String[] SYMBOL_DELIMITERS = {
       "=", "<>", "<=", ">=", "<", ">",
       "+","-","/","*",
       "(",")",",",
    };
   
    // Attributes
    private List tokens = new ArrayList();
    private int tokenizerOffset;
   
    /**
     * Constructor
     */
    public MessageSelectorTokenizer( String messageSelector ) throws InvalidSelectorException
    {
        tokenize(messageSelector);
    }
   
    private String getSymbolDelimiter( String text , int offset )
    {
        for (int n = 0 ; n < SYMBOL_DELIMITERS.length ; n++)
            if (text.startsWith(SYMBOL_DELIMITERS[n],offset))
                return SYMBOL_DELIMITERS[n];
        return null;
    }
   
    private void tokenize( String text ) throws InvalidSelectorException
    {
        boolean inQuotes = false;
        int textLen = text.length();
        int pos = 0;
        String delimiter;
        StringBuffer buf = new StringBuffer();
       
        while (pos < textLen)
        {
            char c = text.charAt(pos);
            if (inQuotes)
            {
                if (c=='\'')
                {
                  buf.append('\'');
                 
                  if (pos < textLen-1 && text.charAt(pos+1) == '\'')
                  {
                    buf.append('\'');
                    pos++;
                  }
                  else
                    {
                    // Closing quote
                        inQuotes = false;
                        addAndCompress(buf.toString(),tokens);
                        buf.setLength(0);
                    }
                }
                else
                    buf.append(c);
                pos++;
            }
            else
            {
                if (c=='\'')
                {
                    buf.append('\'');
                    inQuotes = true;
                    pos++;
                }
                else
                    if (Character.isWhitespace(c))
                    {
                        if (buf.length() > 0)
                        {
                            addAndCompress(buf.toString(),tokens);
                            buf.setLength(0);
                        }
                        pos++;
                    }
                    else
                    if ((delimiter = getSymbolDelimiter(text,pos)) != null)
                    {
                        if (buf.length() > 0)
                        {
                            addAndCompress(buf.toString(),tokens);
                            buf.setLength(0);
                        }
                        addAndCompress(delimiter,tokens);
                        pos += delimiter.length();
                    }
                    else
                    {
                        buf.append(c);
                        pos++;
                    }
            }
        }
        if (inQuotes)
            throw new InvalidSelectorException("Expression contains an unclosed quote");
        if (buf.length() > 0)
        {           
            addAndCompress(buf.toString(),tokens);
            buf.setLength(0);
        }
    }
   
    private void addAndCompress( String token , List tokensList ) throws InvalidSelectorException
    {
        if (tokensList.isEmpty())
        {
            tokensList.add(token);
            return;
        }
       
        // Catches thoses special constructs and recompress them as one token:
        //   is true
        //   is false
        //   is not true
        //   is not false
        //   is null
        //   is not null
        //   not in
        //   not between
        //   not like
               
        String previous = (String)tokensList.get(tokensList.size()-1);
        if (previous.equalsIgnoreCase("is"))
        {
          if (token.equalsIgnoreCase("true") ||
                token.equalsIgnoreCase("false") ||
                token.equalsIgnoreCase("null") ||
                token.equalsIgnoreCase("not"))
          {
            tokensList.set(tokensList.size()-1, "is "+token);
          }
          else
            throw new InvalidSelectorException("Unexpected token after 'is' operator : "+token);
        }
        else
      if (previous.equalsIgnoreCase("is not"))
        {
        if (token.equalsIgnoreCase("true") ||
                token.equalsIgnoreCase("false") ||
                token.equalsIgnoreCase("null"))
          {
            tokensList.set(tokensList.size()-1, "is not "+token);
          }
          else
            throw new InvalidSelectorException("Unexpected token after 'is not' operator : "+token);
        }
      else
      if (previous.equalsIgnoreCase("not"))
        {
        if (token.equalsIgnoreCase("in") ||
              token.equalsIgnoreCase("between") ||
              token.equalsIgnoreCase("like") ||
              token.equalsIgnoreCase("true") ||
                token.equalsIgnoreCase("false"))
          {
                tokensList.set(tokensList.size()-1, "not "+token);
          }
        else
          tokensList.add(token);
            //throw new InvalidSelectorException("Unexpected token after 'not' operator : "+token);
        }
      else
        tokensList.add(token);
    }
   
    /**
     * Check if the tokenizer has more tokens
     */
    public boolean hasMoreTokens()
    {
        return tokenizerOffset < tokens.size();
    }
   
    /**
     * Get the next available token
     */
    public String nextToken()
    {
        if (hasMoreTokens())
            return (String)tokens.get(tokenizerOffset++);
        return null;
    }
}
TOP

Related Classes of net.timewalker.ffmq3.common.message.selector.MessageSelectorTokenizer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.