diff options
Diffstat (limited to 'qpid/java/common/src/main/java/org/apache/qpid/messaging')
11 files changed, 1264 insertions, 0 deletions
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/messaging/Address.java b/qpid/java/common/src/main/java/org/apache/qpid/messaging/Address.java new file mode 100644 index 0000000000..2c7fe7b8ed --- /dev/null +++ b/qpid/java/common/src/main/java/org/apache/qpid/messaging/Address.java @@ -0,0 +1,75 @@ +/* + * + * 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.messaging; + +import java.util.Map; + +import org.apache.qpid.messaging.util.AddressParser; + +import static org.apache.qpid.messaging.util.PyPrint.pprint; + + +/** + * Address + * + */ + +public class Address +{ + + public static Address parse(String address) + { + return new AddressParser(address).parse(); + } + + private String name; + private String subject; + private Map options; + + public Address(String name, String subject, Map options) + { + this.name = name; + this.subject = subject; + this.options = options; + } + + public String getName() + { + return name; + } + + public String getSubject() + { + return subject; + } + + public Map getOptions() + { + return options; + } + + public String toString() + { + return String.format("%s/%s; %s", pprint(name), pprint(subject), + pprint(options)); + } + +} diff --git a/qpid/java/common/src/main/java/org/apache/qpid/messaging/util/AddressParser.java b/qpid/java/common/src/main/java/org/apache/qpid/messaging/util/AddressParser.java new file mode 100644 index 0000000000..7b31436ba0 --- /dev/null +++ b/qpid/java/common/src/main/java/org/apache/qpid/messaging/util/AddressParser.java @@ -0,0 +1,380 @@ +/* + * + * 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.messaging.util; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.qpid.messaging.Address; + + +/** + * AddressParser + * + */ + +public class AddressParser extends Parser +{ + + private static Lexicon lxi = new Lexicon(); + + private static Token.Type LBRACE = lxi.define("LBRACE", "\\{"); + private static Token.Type RBRACE = lxi.define("RBRACE", "\\}"); + private static Token.Type LBRACK = lxi.define("LBRACK", "\\["); + private static Token.Type RBRACK = lxi.define("RBRACK", "\\]"); + private static Token.Type COLON = lxi.define("COLON", ":"); + private static Token.Type SEMI = lxi.define("SEMI", ";"); + private static Token.Type SLASH = lxi.define("SLASH", "/"); + private static Token.Type COMMA = lxi.define("COMMA", ","); + private static Token.Type NUMBER = lxi.define("NUMBER", "[+-]?[0-9]*\\.?[0-9]+"); + private static Token.Type TRUE = lxi.define("TRUE", "True"); + private static Token.Type FALSE = lxi.define("FALSE", "False"); + private static Token.Type ID = lxi.define("ID", "[a-zA-Z_](?:[a-zA-Z0-9_-]*[a-zA-Z0-9_])?"); + private static Token.Type STRING = lxi.define("STRING", "\"(?:[^\\\"]|\\.)*\"|'(?:[^\\']|\\.)*'"); + private static Token.Type ESC = lxi.define("ESC", "\\\\[^ux]|\\\\x[0-9a-fA-F][0-9a-fA-F]|\\\\u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]"); + private static Token.Type SYM = lxi.define("SYM", "[.#*%@$^!+-]"); + private static Token.Type WSPACE = lxi.define("WSPACE", "[\\s]+"); + private static Token.Type EOF = lxi.eof("EOF"); + + private static Lexer LEXER = lxi.compile(); + + public static List<Token> lex(String input) + { + return LEXER.lex(input); + } + + static List<Token> wlex(String input) + { + List<Token> tokens = new ArrayList<Token>(); + for (Token t : lex(input)) + { + if (t.getType() != WSPACE) + { + tokens.add(t); + } + } + return tokens; + } + + static String unquote(String st, Token tok) + { + StringBuilder result = new StringBuilder(); + for (int i = 1; i < st.length() - 1; i++) + { + char ch = st.charAt(i); + if (ch == '\\') + { + char code = st.charAt(i+1); + switch (code) + { + case '\n': + break; + case '\\': + result.append('\\'); + break; + case '\'': + result.append('\''); + break; + case '"': + result.append('"'); + break; + case 'a': + result.append((char) 0x07); + break; + case 'b': + result.append((char) 0x08); + break; + case 'f': + result.append('\f'); + break; + case 'n': + result.append('\n'); + break; + case 'r': + result.append('\r'); + break; + case 't': + result.append('\t'); + break; + case 'u': + result.append(decode(st.substring(i+2, i+6))); + i += 4; + break; + case 'v': + result.append((char) 0x0b); + break; + case 'o': + result.append(decode(st.substring(i+2, i+4), 8)); + i += 2; + break; + case 'x': + result.append(decode(st.substring(i+2, i+4))); + i += 2; + break; + default: + throw new ParseError(tok); + } + i += 1; + } + else + { + result.append(ch); + } + } + + return result.toString(); + } + + static char[] decode(String hex) + { + return decode(hex, 16); + } + + static char[] decode(String code, int radix) + { + return Character.toChars(Integer.parseInt(code, radix)); + } + + static String tok2str(Token tok) + { + Token.Type type = tok.getType(); + String value = tok.getValue(); + + if (type == STRING) + { + return unquote(value, tok); + } + else if (type == ESC) + { + if (value.charAt(1) == 'x' || value.charAt(1) == 'u') + { + return new String(decode(value.substring(2))); + } + else + { + return value.substring(1); + } + } + else + { + return value; + } + } + + static Object tok2obj(Token tok) + { + Token.Type type = tok.getType(); + String value = tok.getValue(); + if (type == STRING) + { + return unquote(value, tok); + } + else if (type == NUMBER) + { + if (value.indexOf('.') >= 0) + { + return Double.valueOf(value); + } + else + { + return Integer.decode(value); + } + } + else if (type == TRUE) + { + return true; + } + else if (type == FALSE) + { + return false; + } + else + { + return value; + } + } + + static String toks2str(List<Token> toks) + { + if (toks.size() > 0) + { + StringBuilder result = new StringBuilder(); + for (Token t : toks) + { + result.append(tok2str(t)); + } + return result.toString(); + } + else + { + return null; + } + } + + public AddressParser(String input) + { + super(wlex(input)); + } + + public Address parse() + { + Address result = address(); + eat(EOF); + return result; + } + + public Address address() + { + String name = toks2str(eat_until(SLASH, SEMI, EOF)); + + if (name == null) + { + throw new ParseError(next()); + } + + String subject; + if (matches(SLASH)) + { + eat(SLASH); + subject = toks2str(eat_until(SEMI, EOF)); + } + else + { + subject = null; + } + + Map options; + if (matches(SEMI)) + { + eat(SEMI); + options = map(); + } + else + { + options = null; + } + + return new Address(name, subject, options); + } + + public Map<Object,Object> map() + { + eat(LBRACE); + + Map<Object,Object> result = new HashMap<Object,Object>(); + while (true) + { + if (matches(NUMBER, STRING, ID, LBRACE, LBRACK)) + { + keyval(result); + if (matches(COMMA)) + { + eat(COMMA); + } + else if (matches(RBRACE)) + { + break; + } + else + { + throw new ParseError(next(), COMMA, RBRACE); + } + } + else if (matches(RBRACE)) + { + break; + } + else + { + throw new ParseError(next(), NUMBER, STRING, ID, LBRACE, LBRACK, + RBRACE); + } + } + + eat(RBRACE); + return result; + } + + void keyval(Map<Object,Object> map) + { + Object key = value(); + eat(COLON); + Object val = value(); + map.put(key, val); + } + + Object value() + { + if (matches(NUMBER, STRING, ID, TRUE, FALSE)) + { + return tok2obj(eat()); + } + else if (matches(LBRACE)) + { + return map(); + } + else if (matches(LBRACK)) + { + return list(); + } + else + { + throw new ParseError(next(), NUMBER, STRING, ID, LBRACE, LBRACK); + } + } + + List<Object> list() + { + eat(LBRACK); + + List<Object> result = new ArrayList<Object>(); + + while (true) + { + if (matches(RBRACK)) + { + break; + } + else + { + result.add(value()); + if (matches(COMMA)) + { + eat(COMMA); + } + else if (matches(RBRACK)) + { + break; + } + else + { + throw new ParseError(next(), COMMA, RBRACK); + } + } + } + + eat(RBRACK); + return result; + } + +} diff --git a/qpid/java/common/src/main/java/org/apache/qpid/messaging/util/JAddr.java b/qpid/java/common/src/main/java/org/apache/qpid/messaging/util/JAddr.java new file mode 100644 index 0000000000..93df052af1 --- /dev/null +++ b/qpid/java/common/src/main/java/org/apache/qpid/messaging/util/JAddr.java @@ -0,0 +1,97 @@ +/* + * + * 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.messaging.util; + +import java.io.InputStreamReader; + +import java.util.List; + +import org.apache.qpid.messaging.Address; +import org.apache.qpid.messaging.util.ParseError; +import org.apache.qpid.messaging.util.Token; + +import static org.apache.qpid.messaging.util.PyPrint.pprint; + + +/** + * JAddr + * + */ + +public class JAddr +{ + + public static final void main(String[] args) throws Exception + { + StringBuilder addr = new StringBuilder(); + InputStreamReader reader = new InputStreamReader(System.in); + + char[] buf = new char[1024]; + while (true) + { + int n = reader.read(buf, 0, buf.length); + if (n < 0) + { + break; + } + addr.append(buf, 0, n); + } + + if ("parse".equals(args[0])) + { + try + { + Address address = Address.parse(addr.toString()); + System.out.println(pprint_address(address)); + } + catch (ParseError e) + { + System.out.println(String.format("ERROR: %s", e.getMessage())); + } + } + else + { + List<Token> tokens = AddressParser.lex(addr.toString()); + for (Token t : tokens) + { + String value = t.getValue(); + if (value != null) + { + value = value.replace("\\", "\\\\").replace("\n", "\\n"); + System.out.println(String.format("%s:%s:%s", t.getType(), t.getPosition(), value)); + } + else + { + System.out.println(String.format("%s:%s", t.getType(), t.getPosition())); + } + } + } + } + + private static String pprint_address(Address addr) + { + return String.format("NAME: %s\nSUBJECT: %s\nOPTIONS: %s", + pprint(addr.getName()), + pprint(addr.getSubject()), + pprint(addr.getOptions())); + } + +} diff --git a/qpid/java/common/src/main/java/org/apache/qpid/messaging/util/LexError.java b/qpid/java/common/src/main/java/org/apache/qpid/messaging/util/LexError.java new file mode 100644 index 0000000000..b8d346dca4 --- /dev/null +++ b/qpid/java/common/src/main/java/org/apache/qpid/messaging/util/LexError.java @@ -0,0 +1,37 @@ +/* + * + * 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.messaging.util; + + +/** + * LexError + * + */ + +public class LexError extends RuntimeException +{ + + public LexError(String msg) + { + super(msg); + } + +} diff --git a/qpid/java/common/src/main/java/org/apache/qpid/messaging/util/Lexer.java b/qpid/java/common/src/main/java/org/apache/qpid/messaging/util/Lexer.java new file mode 100644 index 0000000000..8226cc77cb --- /dev/null +++ b/qpid/java/common/src/main/java/org/apache/qpid/messaging/util/Lexer.java @@ -0,0 +1,84 @@ +/* + * + * 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.messaging.util; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +/** + * Lexer + * + */ + +public class Lexer +{ + + private List<Token.Type> types; + private Token.Type eof; + private Pattern rexp; + + public Lexer(List<Token.Type> types, Token.Type eof, Pattern rexp) + { + this.types = types; + this.eof = eof; + this.rexp = rexp; + } + + public List<Token> lex(final String st) + { + List<Token> tokens = new ArrayList<Token>(); + + int position = 0; + Matcher m = rexp.matcher(st); + OUTER: while (position < st.length()) + { + m.region(position, st.length()); + if (m.lookingAt()) + { + for (int i = 1; i <= m.groupCount(); i++) + { + String value = m.group(i); + if (value != null) + { + tokens.add(new Token(types.get(i-1), value, st, m.start(i))); + position = m.end(i); + continue OUTER; + } + } + throw new RuntimeException("no group matched"); + } + else + { + throw new LexError("unrecognized characters line:" + LineInfo.get(st, position)); + } + } + + tokens.add(new Token(eof, null, st, position)); + + return tokens; + } + +} diff --git a/qpid/java/common/src/main/java/org/apache/qpid/messaging/util/Lexicon.java b/qpid/java/common/src/main/java/org/apache/qpid/messaging/util/Lexicon.java new file mode 100644 index 0000000000..9ab610f37a --- /dev/null +++ b/qpid/java/common/src/main/java/org/apache/qpid/messaging/util/Lexicon.java @@ -0,0 +1,103 @@ +/* + * + * 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.messaging.util; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; + + +/** + * Lexicon + * + */ + +public class Lexicon +{ + + private List<Token.Type> types; + private Token.Type eof; + + public Lexicon() + { + this.types = new ArrayList<Token.Type>(); + this.eof = null; + } + + public Token.Type define(String name, String pattern) + { + Token.Type t = new Token.Type(name, pattern); + types.add(t); + return t; + } + + public Token.Type eof(String name) + { + Token.Type t = new Token.Type(name, null); + eof = t; + return t; + } + + public Lexer compile() + { + StringBuilder joined = new StringBuilder(); + for (Token.Type t : types) + { + if (joined.length() > 0) + { + joined.append('|'); + } + joined.append('(').append(t.getPattern()).append(')'); + } + Pattern rexp = Pattern.compile(joined.toString()); + return new Lexer(new ArrayList<Token.Type>(types), eof, rexp); + } + + public static final void main(String[] args) + { + StringBuilder input = new StringBuilder(); + for (String a : args) + { + if (input.length() > 0) + { + input.append(" "); + } + + input.append(a); + } + + Lexicon lxi = new Lexicon(); + lxi.define("FOR", "for"); + lxi.define("IF", "if"); + lxi.define("LPAREN", "\\("); + lxi.define("RPAREN", "\\)"); + lxi.define("ID", "[\\S]+"); + lxi.define("WSPACE", "[\\s]+"); + lxi.eof("EOF"); + Lexer lx = lxi.compile(); + + for (Token t : lx.lex(input.toString())) + { + System.out.println(t); + } + } + +} diff --git a/qpid/java/common/src/main/java/org/apache/qpid/messaging/util/LineInfo.java b/qpid/java/common/src/main/java/org/apache/qpid/messaging/util/LineInfo.java new file mode 100644 index 0000000000..4952fc38a3 --- /dev/null +++ b/qpid/java/common/src/main/java/org/apache/qpid/messaging/util/LineInfo.java @@ -0,0 +1,93 @@ +/* + * + * 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.messaging.util; + + +/** + * LineInfo + * + */ + +public class LineInfo +{ + + public static LineInfo get(String st, int position) + { + int idx = 0; + int line = 1; + int column = 0; + int line_pos = 0; + while (idx < position) + { + if (st.charAt(idx) == '\n') + { + line += 1; + column = 0; + line_pos = idx; + } + + column += 1; + idx += 1; + } + + int end = st.indexOf('\n', line_pos); + if (end < 0) + { + end = st.length(); + } + + String text = st.substring(line_pos, end); + + return new LineInfo(line, column, text); + } + + private int line; + private int column; + private String text; + + public LineInfo(int line, int column, String text) + { + this.line = line; + this.column = column; + this.text = text; + } + + public int getLine() + { + return line; + } + + public int getColumn() + { + return column; + } + + public String getText() + { + return text; + } + + public String toString() + { + return String.format("%s,%s:%s", line, column, text); + } + +} diff --git a/qpid/java/common/src/main/java/org/apache/qpid/messaging/util/ParseError.java b/qpid/java/common/src/main/java/org/apache/qpid/messaging/util/ParseError.java new file mode 100644 index 0000000000..ce758e15fa --- /dev/null +++ b/qpid/java/common/src/main/java/org/apache/qpid/messaging/util/ParseError.java @@ -0,0 +1,58 @@ +/* + * + * 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.messaging.util; + +import org.apache.qpid.util.Strings; + + +/** + * ParseError + * + */ + +public class ParseError extends RuntimeException +{ + + private static String msg(Token token, Token.Type ... expected) + { + LineInfo li = token.getLineInfo(); + String exp = Strings.join(", ", expected); + if (expected.length > 1) + { + exp = String.format("(%s)", exp); + } + + if (expected.length > 0) + { + return String.format("expecting %s, got %s line:%s", exp, token, li); + } + else + { + return String.format("unexpected token %s line:%s", token, li); + } + } + + public ParseError(Token token, Token.Type ... expected) + { + super(msg(token, expected)); + } + +} diff --git a/qpid/java/common/src/main/java/org/apache/qpid/messaging/util/Parser.java b/qpid/java/common/src/main/java/org/apache/qpid/messaging/util/Parser.java new file mode 100644 index 0000000000..2e983f5165 --- /dev/null +++ b/qpid/java/common/src/main/java/org/apache/qpid/messaging/util/Parser.java @@ -0,0 +1,85 @@ +/* + * + * 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.messaging.util; + +import java.util.ArrayList; +import java.util.List; + + +/** + * Parser + * + */ + +class Parser +{ + + private List<Token> tokens; + private int idx = 0; + + Parser(List<Token> tokens) + { + this.tokens = tokens; + this.idx = 0; + } + + Token next() + { + return tokens.get(idx); + } + + boolean matches(Token.Type ... types) + { + for (Token.Type t : types) + { + if (next().getType() == t) + { + return true; + } + } + return false; + } + + Token eat(Token.Type ... types) + { + if (types.length > 0 && !matches(types)) + { + throw new ParseError(next(), types); + } + else + { + Token t = next(); + idx += 1; + return t; + } + } + + List<Token> eat_until(Token.Type ... types) + { + List<Token> result = new ArrayList(); + while (!matches(types)) + { + result.add(eat()); + } + return result; + } + +} diff --git a/qpid/java/common/src/main/java/org/apache/qpid/messaging/util/PyPrint.java b/qpid/java/common/src/main/java/org/apache/qpid/messaging/util/PyPrint.java new file mode 100644 index 0000000000..ef6c724371 --- /dev/null +++ b/qpid/java/common/src/main/java/org/apache/qpid/messaging/util/PyPrint.java @@ -0,0 +1,146 @@ +/* + * + * 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.messaging.util; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + + +/** + * PyPrint + * + */ + +public class PyPrint +{ + + public static String pprint(Object obj) + { + if (obj instanceof Map) + { + return pprint_map((Map) obj); + } + else if (obj instanceof List) + { + return pprint_list((List) obj); + } + else if (obj instanceof String) + { + return pprint_string((String) obj); + } + else if (obj instanceof Boolean) + { + return ((Boolean) obj).booleanValue() ? "True" : "False"; + } + else if (obj == null) + { + return "None"; + } + else + { + return obj.toString(); + } + } + + private static String indent(String st) + { + return " " + st.replace("\n", "\n "); + } + + private static String pprint_map(Map<Object,Object> map) + { + List<String> items = new ArrayList<String>(); + for (Map.Entry me : map.entrySet()) + { + items.add(String.format("%s: %s", pprint(me.getKey()), + pprint(me.getValue()))); + } + Collections.sort(items); + return pprint_items("{", items, "}"); + } + + private static String pprint_list(List list) + { + List<String> items = new ArrayList<String>(); + for (Object o : list) + { + items.add(pprint(o)); + } + return pprint_items("[", items, "]"); + } + + private static String pprint_items(String start, List<String> items, + String end) + { + StringBuilder result = new StringBuilder(); + for (String item : items) + { + if (result.length() > 0) + { + result.append(",\n"); + } + result.append(indent(item)); + } + + if (result.length() > 0) + { + return String.format("%s\n%s\n%s", start, result, end); + } + else + { + return String.format("%s%s", start, end); + } + } + + private static String pprint_string(String st) + { + StringBuilder result = new StringBuilder(); + result.append('\''); + for (int i = 0; i < st.length(); i++) + { + char c = st.charAt(i); + switch (c) + { + case '\'': + result.append("\\'"); + break; + case '\n': + result.append("\\n"); + break; + default: + if (c >= 0x80) + { + result.append(String.format("\\u%04x", (int)c)); + } + else + { + result.append(c); + } + break; + } + } + result.append('\''); + return result.toString(); + } + +} diff --git a/qpid/java/common/src/main/java/org/apache/qpid/messaging/util/Token.java b/qpid/java/common/src/main/java/org/apache/qpid/messaging/util/Token.java new file mode 100644 index 0000000000..b9458d7997 --- /dev/null +++ b/qpid/java/common/src/main/java/org/apache/qpid/messaging/util/Token.java @@ -0,0 +1,106 @@ +/* + * + * 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.messaging.util; + + +/** + * Token + * + */ + +public class Token +{ + + public static class Type + { + + private String name; + private String pattern; + + Type(String name, String pattern) + { + this.name = name; + this.pattern = pattern; + } + + public String getName() + { + return name; + } + + public String getPattern() + { + return pattern; + } + + public String toString() + { + return name; + } + + } + + private Type type; + private String value; + private String input; + private int position; + + Token(Type type, String value, String input, int position) + { + this.type = type; + this.value = value; + this.input = input; + this.position = position; + } + + public Type getType() + { + return type; + } + + public String getValue() + { + return value; + } + + public int getPosition() + { + return position; + } + + public LineInfo getLineInfo() + { + return LineInfo.get(input, position); + } + + public String toString() + { + if (value == null) + { + return type.toString(); + } + else + { + return String.format("%s(%s)", type, value); + } + } + +} |