/*
* JBoss, Home of Professional Open Source
* Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This 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.1 of
* the License, or (at your option) any later version.
*
* This software 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 this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.messaging.jms.client;
import java.util.ArrayList;
import java.util.List;
/**
*
* This class converts a JMS selector expression into a JBM core filter expression.
*
* JMS selector and JBM filters use the same syntax but have different identifiers.
*
* We basically just need to replace the JMS header and property Identifier names
* with the corresponding JBM field and header Identifier names.
*
* We must be careful not to substitute any literals, or identifers whose name contains the name
* of one we want to substitute.
*
* This makes it less trivial than a simple search and replace.
*
* @author <a href="mailto:tim.fox@jboss.com">Tim Fox</a>
*
*/
public class SelectorTranslator
{
public static String convertToJBMFilterString(final String selectorString)
{
if (selectorString == null)
{
return null;
}
//First convert any JMS header identifiers
String filterString = parse(selectorString, "JMSDeliveryMode", "JBMDurable");
filterString = parse(filterString, "'PERSISTENT'", "'DURABLE'");
filterString = parse(filterString, "'NON_PERSISTENT'", "'NON_DURABLE'");
filterString = parse(filterString, "JMSPriority", "JBMPriority");
filterString = parse(filterString, "JMSTimestamp", "JBMTimestamp");
return filterString;
}
private static String parse(final String input, final String match, final String replace)
{
final char quote = '\'';
boolean inQuote = false;
int matchPos = 0;
List<Integer> positions = new ArrayList<Integer>();
boolean replaceInQuotes = match.charAt(0) == quote;
for (int i = 0; i < input.length(); i++)
{
char c = input.charAt(i);
if (c == quote)
{
inQuote = !inQuote;
}
if ((!inQuote || replaceInQuotes) && c == match.charAt(matchPos))
{
matchPos++;
if (matchPos == match.length())
{
boolean matched = true;
//Check that name is not part of another identifier name
//Check character after match
if (i < input.length() -1 && Character.isJavaIdentifierPart(input.charAt(i + 1)))
{
matched = false;
}
//Check character before match
int posBeforeStart = i - match.length();
if (posBeforeStart >= 0 && Character.isJavaIdentifierPart(input.charAt(posBeforeStart)))
{
matched = false;
}
if (matched)
{
positions.add(i - match.length() + 1);
}
//check previous character too
matchPos = 0;
}
}
else
{
matchPos = 0;
}
}
if (!positions.isEmpty())
{
StringBuffer buff = new StringBuffer();
int startPos = 0;
for (int pos: positions)
{
String substr = input.substring(startPos, pos);
buff.append(substr);
buff.append(replace);
startPos = pos + match.length();
}
if (startPos < input.length())
{
buff.append(input.substring(startPos, input.length()));
}
return buff.toString();
}
else
{
return input;
}
}
}