Hi Arnaud, In the 0-10 Java Broker (whenever we start on that) I *definitely* expect that we will be having server-side selectors.
We are adding them client side so that we can have JMS compliance with brokers which do not implement server side selectors (e.g. our own C++ broker :-) ). As to XPath and XQuery mesage routing... I think this is a separate issue (and before we say "definitely" I think we should discuss on the list), and is a matter of custom exchanges. On that note I'll be putting a small patch into trunk soo which will allow custom exchange implementations to be specified in the config files... Cheers, Rob On 06/08/07, Arnaud Simon <[EMAIL PROTECTED]> wrote: > > Hi, > > Message selection will only happen at the client side. The reason is > that message selector is not supported by AMQP brokers. So, I don't > think that the 0.10 version of the broker should support message > selection. It will certainly support Xpath and Xquery message routing > though. > What I would suggest is that we keep the message selection code in > client for now. When implementing the 0.10 version of the broker we may > then decide to reuse this code and then move it into common. > What do you think? > > Arnaud > > > On Mon, 2007-08-06 at 11:40 +0100, Martin Ritchie wrote: > > Arnaud, If we are going to include the JMS Selector code in the client > > as well as the broker would it not make sense to move it to common? > > > > On 06/08/07, [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote: > > > Author: arnaudsimon > > > Date: Sun Aug 5 23:36:27 2007 > > > New Revision: 563043 > > > > > > URL: http://svn.apache.org/viewvc?view=rev&rev=563043 > > > Log: > > > JMS message selector grammar > > > > > > Added: > > > incubator/qpid/trunk/qpid/java/client/src/main/grammar/ > > > > incubator/qpid/trunk/qpid/java/client/src/main/grammar/SelectorParser.jj > > > > > > Added: > incubator/qpid/trunk/qpid/java/client/src/main/grammar/SelectorParser.jj > > > URL: > http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client/src/main/grammar/SelectorParser.jj?view=auto&rev=563043 > > > > ============================================================================== > > > --- > incubator/qpid/trunk/qpid/java/client/src/main/grammar/SelectorParser.jj > (added) > > > +++ > incubator/qpid/trunk/qpid/java/client/src/main/grammar/SelectorParser.jj Sun > Aug 5 23:36:27 2007 > > > @@ -0,0 +1,592 @@ > > > +/* > > > + * > > > + * 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. > > > + * > > > + */ > > > + > > > + // > > > + // Original File from r450141 of the Apache ActiveMQ project < > http://www.activemq.org/site/home.html> > > > + // > > > + > > > +// > ---------------------------------------------------------------------------- > > > +// OPTIONS > > > +// > ---------------------------------------------------------------------------- > > > +options { > > > + STATIC = false; > > > + UNICODE_INPUT = true; > > > + > > > + // some performance optimizations > > > + OPTIMIZE_TOKEN_MANAGER = true; > > > + ERROR_REPORTING = false; > > > +} > > > + > > > +// > ---------------------------------------------------------------------------- > > > +// PARSER > > > +// > ---------------------------------------------------------------------------- > > > + > > > +PARSER_BEGIN(SelectorParser) > > > +/* > > > + * > > > + * 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.qpid.nclient.jms.filter.selector; > > > + > > > +import java.io.StringReader; > > > +import java.util.ArrayList; > > > + > > > +import org.apache.qpidity.QpidException; > > > +import org.apache.qpid.nclient.jms.filter.ArithmeticExpression; > > > +import org.apache.qpid.nclient.jms.filter.BooleanExpression; > > > +import org.apache.qpid.nclient.jms.filter.ComparisonExpression; > > > +import org.apache.qpid.nclient.jms.filter.ConstantExpression; > > > +import org.apache.qpid.nclient.jms.filter.Expression; > > > +import org.apache.qpid.nclient.jms.filter.LogicExpression; > > > +import org.apache.qpid.nclient.jms.filter.PropertyExpression; > > > +import org.apache.qpid.nclient.jms.filter.UnaryExpression; > > > + > > > +/** > > > + * JMS Selector Parser generated by JavaCC > > > + * > > > + * Do not edit this .java file directly - it is autogenerated from > SelectorParser.jj > > > + */ > > > +public class SelectorParser { > > > + > > > + public SelectorParser() { > > > + this(new StringReader("")); > > > + } > > > + > > > + public BooleanExpression parse(String sql) throws QpidException { > > > + this.ReInit(new StringReader(sql)); > > > + > > > + try { > > > + return this.JmsSelector(); > > > + } > > > + catch (Throwable e) { > > > + throw new QpidException(sql,"filter error",e); > > > + } > > > + > > > + } > > > + > > > + private BooleanExpression asBooleanExpression(Expression value) > throws ParseException { > > > + if (value instanceof BooleanExpression) { > > > + return (BooleanExpression) value; > > > + } > > > + if (value instanceof PropertyExpression) { > > > + return UnaryExpression.createBooleanCast( value ); > > > + } > > > + throw new ParseException("Expression will not result in a > boolean value: " + value); > > > + } > > > + > > > + > > > +} > > > + > > > +PARSER_END(SelectorParser) > > > + > > > +// > ---------------------------------------------------------------------------- > > > +// Tokens > > > +// > ---------------------------------------------------------------------------- > > > + > > > +/* White Space */ > > > +SPECIAL_TOKEN : > > > +{ > > > + " " | "\t" | "\n" | "\r" | "\f" > > > +} > > > + > > > +/* Comments */ > > > +SKIP: > > > +{ > > > + <LINE_COMMENT: "--" (~["\n","\r"])* ("\n"|"\r"|"\r\n") > > > > +} > > > + > > > +SKIP: > > > +{ > > > + <BLOCK_COMMENT: "/*" (~["*"])* "*" ("*" | (~["*","/"] (~["*"])* > "*"))* "/"> > > > +} > > > + > > > +/* Reserved Words */ > > > +TOKEN [IGNORE_CASE] : > > > +{ > > > + < NOT : "NOT"> > > > + | < AND : "AND"> > > > + | < OR : "OR"> > > > + | < BETWEEN : "BETWEEN"> > > > + | < LIKE : "LIKE"> > > > + | < ESCAPE : "ESCAPE"> > > > + | < IN : "IN"> > > > + | < IS : "IS"> > > > + | < TRUE : "TRUE" > > > > + | < FALSE : "FALSE" > > > > + | < NULL : "NULL" > > > > +} > > > + > > > +/* Literals */ > > > +TOKEN [IGNORE_CASE] : > > > +{ > > > + > > > + < DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* (["l","L"])? > > > > + | < HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ > > > > + | < OCTAL_LITERAL: "0" (["0"-"7"])* > > > > + | < FLOATING_POINT_LITERAL: > > > + (["0"-"9"])+ "." (["0"-"9"])* (<EXPONENT>)? // matches: 5.5or > > > 5. or > 5.5E10 or 5.E10 > > > + | "." (["0"-"9"])+ (<EXPONENT>)? // matches: .5 > or .5E10 > > > + | (["0"-"9"])+ <EXPONENT> // matches: > 5E10 > > > + > > > > + | < #EXPONENT: "E" (["+","-"])? (["0"-"9"])+ > > > > + | < STRING_LITERAL: "'" ( ("''") | ~["'"] )* "'" > > > > +} > > > + > > > +TOKEN [IGNORE_CASE] : > > > +{ > > > + < ID : ["a"-"z", "_", "$"] (["a"-"z","0"-"9","_", "$"])* > > > > +} > > > + > > > +// > ---------------------------------------------------------------------------- > > > +// Grammer > > > +// > ---------------------------------------------------------------------------- > > > +BooleanExpression JmsSelector() : > > > +{ > > > + Expression left=null; > > > +} > > > +{ > > > + ( > > > + left = orExpression() > > > + ) > > > + { > > > + return asBooleanExpression(left); > > > + } > > > + > > > +} > > > + > > > +Expression orExpression() : > > > +{ > > > + Expression left; > > > + Expression right; > > > +} > > > +{ > > > + ( > > > + left = andExpression() > > > + ( > > > + <OR> right = andExpression() > > > + { > > > + left = > > > LogicExpression.createOR(asBooleanExpression(left), > asBooleanExpression(right)); > > > + } > > > + )* > > > + ) > > > + { > > > + return left; > > > + } > > > + > > > +} > > > + > > > + > > > +Expression andExpression() : > > > +{ > > > + Expression left; > > > + Expression right; > > > +} > > > +{ > > > + ( > > > + left = equalityExpression() > > > + ( > > > + <AND> right = equalityExpression() > > > + { > > > + left = > > > LogicExpression.createAND(asBooleanExpression(left), > asBooleanExpression(right)); > > > + } > > > + )* > > > + ) > > > + { > > > + return left; > > > + } > > > +} > > > + > > > +Expression equalityExpression() : > > > +{ > > > + Expression left; > > > + Expression right; > > > +} > > > +{ > > > + ( > > > + left = comparisonExpression() > > > + ( > > > + > > > + "=" right = comparisonExpression() > > > + { > > > + left = ComparisonExpression.createEqual(left, right); > > > + } > > > + | > > > + "<>" right = comparisonExpression() > > > + { > > > + left = ComparisonExpression.createNotEqual(left, > right); > > > + } > > > + | > > > + LOOKAHEAD(2) > > > + <IS> <NULL> > > > + { > > > + left = ComparisonExpression.createIsNull(left); > > > + } > > > + | > > > + <IS> <NOT> <NULL> > > > + { > > > + left = ComparisonExpression.createIsNotNull(left); > > > + } > > > + )* > > > + ) > > > + { > > > + return left; > > > + } > > > +} > > > + > > > +Expression comparisonExpression() : > > > +{ > > > + Expression left; > > > + Expression right; > > > + Expression low; > > > + Expression high; > > > + String t, u; > > > + boolean not; > > > + ArrayList list; > > > +} > > > +{ > > > + ( > > > + left = addExpression() > > > + ( > > > + > > > + ">" right = addExpression() > > > + { > > > + left = ComparisonExpression.createGreaterThan(left, > right); > > > + } > > > + | > > > + ">=" right = addExpression() > > > + { > > > + left = > ComparisonExpression.createGreaterThanEqual(left, right); > > > + } > > > + | > > > + "<" right = addExpression() > > > + { > > > + left = ComparisonExpression.createLessThan(left, > right); > > > + } > > > + | > > > + "<=" right = addExpression() > > > + { > > > + left = ComparisonExpression.createLessThanEqual(left, > right); > > > + } > > > + | > > > + { > > > + u=null; > > > + } > > > + <LIKE> t = stringLitteral() > > > + [ <ESCAPE> u = stringLitteral() ] > > > + { > > > + left = ComparisonExpression.createLike(left, t, > u); > > > + } > > > + | > > > + LOOKAHEAD(2) > > > + { > > > + u=null; > > > + } > > > + <NOT> <LIKE> t = stringLitteral() [ <ESCAPE> u > = stringLitteral() ] > > > + { > > > + left = ComparisonExpression.createNotLike(left, > t, u); > > > + } > > > + | > > > + <BETWEEN> low = addExpression() <AND> high = > addExpression() > > > + { > > > + left = > ComparisonExpression.createBetween(left, low, high); > > > + } > > > + | > > > + LOOKAHEAD(2) > > > + <NOT> <BETWEEN> low = addExpression() <AND> > high = addExpression() > > > + { > > > + left = > ComparisonExpression.createNotBetween(left, low, high); > > > + } > > > + | > > > + <IN> > > > + "(" > > > + t = stringLitteral() > > > + { > > > + list = new ArrayList(); > > > + list.add( t ); > > > + } > > > + ( > > > + "," > > > + t = stringLitteral() > > > + { > > > + list.add( t ); > > > + } > > > + > > > + )* > > > + ")" > > > + { > > > + left = > > > ComparisonExpression.createInFilter(left, > list); > > > + } > > > + | > > > + LOOKAHEAD(2) > > > + <NOT> <IN> > > > + "(" > > > + t = stringLitteral() > > > + { > > > + list = new ArrayList(); > > > + list.add( t ); > > > + } > > > + ( > > > + "," > > > + t = stringLitteral() > > > + { > > > + list.add( t ); > > > + } > > > + > > > + )* > > > + ")" > > > + { > > > + left = > ComparisonExpression.createNotInFilter(left, list); > > > + } > > > + > > > + )* > > > + ) > > > + { > > > + return left; > > > + } > > > +} > > > + > > > +Expression addExpression() : > > > +{ > > > + Expression left; > > > + Expression right; > > > +} > > > +{ > > > + left = multExpr() > > > + ( > > > + LOOKAHEAD( ("+"|"-") multExpr()) > > > + ( > > > + "+" right = multExpr() > > > + { > > > + left = ArithmeticExpression.createPlus(left, > right); > > > + } > > > + | > > > + "-" right = multExpr() > > > + { > > > + left = ArithmeticExpression.createMinus(left, > right); > > > + } > > > + ) > > > + > > > + )* > > > + { > > > + return left; > > > + } > > > +} > > > + > > > +Expression multExpr() : > > > +{ > > > + Expression left; > > > + Expression right; > > > +} > > > +{ > > > + left = unaryExpr() > > > + ( > > > + "*" right = unaryExpr() > > > + { > > > + left = ArithmeticExpression.createMultiply(left, > right); > > > + } > > > + | > > > + "/" right = unaryExpr() > > > + { > > > + left = ArithmeticExpression.createDivide(left, right); > > > + } > > > + | > > > + "%" right = unaryExpr() > > > + { > > > + left = ArithmeticExpression.createMod(left, right); > > > + } > > > + > > > + )* > > > + { > > > + return left; > > > + } > > > +} > > > + > > > + > > > +Expression unaryExpr() : > > > +{ > > > + String s=null; > > > + Expression left=null; > > > +} > > > +{ > > > + ( > > > + LOOKAHEAD( "+" unaryExpr() ) > > > + "+" left=unaryExpr() > > > + | > > > + "-" left=unaryExpr() > > > + { > > > + left = UnaryExpression.createNegate(left); > > > + } > > > + | > > > + <NOT> left=unaryExpr() > > > + { > > > + left = UnaryExpression.createNOT( > asBooleanExpression(left) ); > > > + } > > > + | > > > + left = primaryExpr() > > > + ) > > > + { > > > + return left; > > > + } > > > + > > > +} > > > + > > > +Expression primaryExpr() : > > > +{ > > > + Expression left=null; > > > +} > > > +{ > > > + ( > > > + left = literal() > > > + | > > > + left = variable() > > > + | > > > + "(" left = orExpression() ")" > > > + ) > > > + { > > > + return left; > > > + } > > > +} > > > + > > > + > > > + > > > +ConstantExpression literal() : > > > +{ > > > + Token t; > > > + String s; > > > + ConstantExpression left=null; > > > +} > > > +{ > > > + ( > > > + ( > > > + s = stringLitteral() > > > + { > > > + left = new ConstantExpression(s); > > > + } > > > + ) > > > + | > > > + ( > > > + t = <DECIMAL_LITERAL> > > > + { > > > + left = ConstantExpression.createFromDecimal(t.image); > > > + } > > > + ) > > > + | > > > + ( > > > + t = <HEX_LITERAL> > > > + { > > > + left = ConstantExpression.createFromHex(t.image); > > > + } > > > + ) > > > + | > > > + ( > > > + t = <OCTAL_LITERAL> > > > + { > > > + left = ConstantExpression.createFromOctal(t.image); > > > + } > > > + ) > > > + | > > > + ( > > > + t = <FLOATING_POINT_LITERAL> > > > + { > > > + left = ConstantExpression.createFloat(t.image); > > > + } > > > + ) > > > + | > > > + ( > > > + <TRUE> > > > + { > > > + left = ConstantExpression.TRUE; > > > + } > > > + ) > > > + | > > > + ( > > > + <FALSE> > > > + { > > > + left = ConstantExpression.FALSE; > > > + } > > > + ) > > > + | > > > + ( > > > + <NULL> > > > + { > > > + left = ConstantExpression.NULL; > > > + } > > > + ) > > > + ) > > > + { > > > + return left; > > > + } > > > +} > > > + > > > +String stringLitteral() : > > > +{ > > > + Token t; > > > + StringBuffer rc = new StringBuffer(); > > > + boolean first=true; > > > +} > > > +{ > > > + t = <STRING_LITERAL> > > > + { > > > + // Decode the sting value. > > > + String image = t.image; > > > + for( int i=1; i < image.length()-1; i++ ) { > > > + char c = image.charAt(i); > > > + if( c == '\'' ) > > > + i++; > > > + rc.append(c); > > > + } > > > + return rc.toString(); > > > + } > > > +} > > > + > > > +PropertyExpression variable() : > > > +{ > > > + Token t; > > > + PropertyExpression left=null; > > > +} > > > +{ > > > + ( > > > + t = <ID> > > > + { > > > + left = new PropertyExpression(t.image); > > > + } > > > + ) > > > + { > > > + return left; > > > + } > > > +} > > > > > > > > > > > > > > >
