提交 2dea109a authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 3d2cd051
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.api;
import java.sql.SQLException;
import java.util.EventListener;
/**
* A class that implements this interface can get notified about exceptions and other events.
* A database event listener can be registered when connecting to a database.
* Example database URL: jdbc:h2:test;DATABASE_EVENT_LISTENER='com.acme.DbListener' *
*/
public interface DatabaseEventListener extends EventListener {
int STATE_SCAN_FILE = 0, STATE_CREATE_INDEX = 1, STATE_RECOVER = 2;
/**
* This method is called just after creating the object.
* This is done when opening the database if the listener is specified in the database URL,
* but may be later if the listener is set at runtime with the SET SQL statement.
*
* @param url - the database URL
*/
void init(String url);
/**
* This method is called if the disk space is very low.
*
* @param stillAvailable the estimated space that is still available, in bytes
* @throws SQLException if the operation should be cancelled
*/
void diskSpaceIsLow(long stillAvailable) throws SQLException;
/**
* This method is called if an exception occured.
*
* @param e the exception
*/
void exceptionThrown(SQLException e);
/**
* This method is called for long running events, such as recovering, scanning a file or building an index.
*
* @param state - the state
* @param name - the object name
* @param x - the current position
* @param max - the highest value
*/
void setProgress(int state, String name, int x, int max);
/**
* This method is called before the database is closed normally.
*/
void closingDatabase();
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.api;
import java.sql.Connection;
import java.sql.SQLException;
/**
* A class that implements this interface can be used as a trigger.
*
* @author Thomas
*/
public interface Trigger {
/**
* This method is called by the database engine once when initializing the trigger.
*
* @param conn a connection to the database
* @param schemaName the name of the schema
* @param triggerName the name of the trigger used in the CREATE TRIGGER statement
* @param tableName the name of the table
*/
void init(Connection conn, String schemaName, String triggerName, String tableName) throws SQLException;
/**
* This method is called for each triggered action.
*
* @param conn a connection to the database
* @param oldRow the old row, or null if no old row is available (for INSERT)
* @param newRow the new row, or null if no new row is available (for DELETE)
* @throws SQLException if the operation must be undone
*/
void fire(Connection conn, Object[] oldRow, Object[] newRow) throws SQLException;
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.bnf;
import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Random;
import java.util.StringTokenizer;
import org.h2.server.web.DbContextRule;
import org.h2.tools.Csv;
import org.h2.util.Resources;
import org.h2.util.StringUtils;
public class Bnf {
static boolean COMBINE_KEYWORDS;
private static final String SEPARATORS = " [](){}|.,\r\n<>:-+*/=<\">!'";
private static final long MAX_PARSE_TIME = 100;
private Random random;
private HashMap ruleMap = new HashMap();
private String syntax;
private String currentToken;
private String[] tokens;
private char firstChar;
private int index;
private Rule lastRepeat;
private ArrayList statements;
private String currentTopic;
/**
* Create an instance using the grammar specified in the CSV file.
*
* @param csv if not specified, the help.csv is used
* @return a new instance
*/
public static Bnf getInstance(Reader csv) throws Exception {
Bnf bnf = new Bnf();
if(csv == null) {
byte[] data = Resources.get("/org/h2/res/help.csv");
csv = new InputStreamReader(new ByteArrayInputStream(data));
}
bnf.parse(csv);
return bnf;
}
Bnf() {
this.random = new Random();
random.setSeed(1);
}
void addFixedRule(String name, int fixedType) {
Rule rule = new RuleFixed(fixedType);
addRule(name, 0, "Fixed", rule);
}
RuleHead addRule(String topic, int id, String section, Rule rule) {
RuleHead head = new RuleHead(id, section, topic, rule);
if(ruleMap.get(StringUtils.toLowerEnglish(topic)) != null) {
throw new Error("already exists: " + topic);
}
ruleMap.put(StringUtils.toLowerEnglish(topic), head);
return head;
}
public Random getRandom() {
return random;
}
public HashMap getRuleMap() {
return ruleMap;
}
public void parse(Reader csv) throws Exception {
Rule functions = null;
statements = new ArrayList();
ResultSet rs = Csv.getInstance().read(csv, null);
for(int id=0; rs.next(); id++) {
String section = rs.getString("SECTION").trim();
if(section.startsWith("System")) {
continue;
}
String topic = StringUtils.toLowerEnglish(rs.getString("TOPIC").trim());
topic = StringUtils.replaceAll(topic, " ", "");
topic = StringUtils.replaceAll(topic, "_", "");
syntax = rs.getString("SYNTAX").trim();
currentTopic = section;
if(section.startsWith("Function")) {
int end = syntax.indexOf(':');
syntax = syntax.substring(0, end);
}
tokens = tokenize();
index = 0;
Rule rule = parseRule();
if(section.startsWith("Command")) {
rule = new RuleList(rule, new RuleElement(";\n\n", currentTopic), false);
}
RuleHead head = addRule(topic, id, section, rule);
if(section.startsWith("Function")) {
if(functions == null) {
functions = rule;
} else {
functions = new RuleList(rule, functions, true);
}
} else if(section.startsWith("Commands")) {
statements.add(head);
}
}
addRule("@func@", 0, "Function", functions);
addFixedRule("@ymd@", RuleFixed.YMD);
addFixedRule("@hms@", RuleFixed.HMS);
addFixedRule("@nanos@", RuleFixed.NANOS);
addFixedRule("anythingExceptSingleQuote", RuleFixed.ANY_EXCEPT_SINGLE_QUOTE);
addFixedRule("anythingExceptDoubleQuote", RuleFixed.ANY_EXCEPT_DOUBLE_QUOTE);
addFixedRule("anythingUntilEndOfLine", RuleFixed.ANY_UNTIL_EOL);
addFixedRule("anythingUntilEndComment", RuleFixed.ANY_UNTIL_END);
addFixedRule("anything", RuleFixed.ANY_WORD);
addFixedRule("@hexStart@", RuleFixed.HEXSTART);
addFixedRule("@concat@", RuleFixed.CONCAT);
addFixedRule("@az_@", RuleFixed.AZ_);
addFixedRule("@af@", RuleFixed.AF);
addFixedRule("@digit@", RuleFixed.DIGIT);
}
public String getSyntax(String rule, String syntax) {
StringTokenizer tokenizer = new StringTokenizer(syntax, SEPARATORS, true);
StringBuffer buff = new StringBuffer();
while(tokenizer.hasMoreTokens()) {
String s = tokenizer.nextToken();
if(s.length() == 1 || StringUtils.toUpperEnglish(s).equals(s)) {
buff.append(s);
continue;
}
String section = null;
int id = -1;
for(int i=0; i<s.length(); i++) {
String test = StringUtils.toLowerEnglish(s.substring(i));
RuleHead r = (RuleHead)ruleMap.get(test);
if(r != null) {
id = r.id;
section = r.section;
break;
}
}
if(id == -1) {
buff.append(s);
continue;
}
String page = "grammar.html";
if(section.startsWith("Data Types")) {
page = "datatypes.html";
} else if(section.startsWith("Functions")) {
page = "functions.html";
}
buff.append("<a href=\""+page+"#sql"+id+"\">");
buff.append(s);
buff.append("</a>");
}
return buff.toString();
}
private Rule parseRule() {
read();
Rule r= parseOr();
return r;
}
private Rule parseOr() {
Rule r = parseList();
if(firstChar == '|') {
read();
r = new RuleList(r, parseOr(), true);
}
lastRepeat = r;
return r;
}
private Rule parseList() {
Rule r = parseToken();
if(firstChar != '|' && firstChar != ']' && firstChar != '}' && firstChar != 0) {
r = new RuleList(r, parseList(), false);
}
lastRepeat = r;
return r;
}
private Rule parseToken() {
Rule r;
if((firstChar >= 'A' && firstChar <= 'Z') || (firstChar >= 'a' && firstChar <= 'z')) {
// r = new RuleElement(currentToken+ " syntax:" + syntax);
r = new RuleElement(currentToken, currentTopic);
} else if(firstChar == '[') {
read();
Rule r2 = parseOr();
boolean repeat = false;
if(r2.last() instanceof RuleRepeat) {
repeat = true;
}
r = new RuleOptional(r2, repeat);
if(firstChar != ']') {
throw new Error("expected ], got " + currentToken + " syntax:" + syntax);
}
} else if(firstChar == '{') {
read();
r = parseOr();
if(firstChar != '}') {
throw new Error("expected }, got " + currentToken+ " syntax:" + syntax);
}
} else if("@commadots@".equals(currentToken)) {
r = new RuleList(new RuleElement(",", currentTopic), lastRepeat, false);
r = new RuleRepeat(r);
} else if("@dots@".equals(currentToken)) {
r = new RuleRepeat(lastRepeat);
} else {
r = new RuleElement(currentToken, currentTopic);
}
lastRepeat = r;
read();
return r;
}
private void read() {
if(index < tokens.length) {
currentToken = tokens[index++];
firstChar = currentToken.charAt(0);
} else {
currentToken = "";
firstChar = 0;
}
}
private String[] tokenize() {
ArrayList list = new ArrayList();
syntax = StringUtils.replaceAll(syntax, "yyyy-MM-dd", "@ymd@");
syntax = StringUtils.replaceAll(syntax, "hh:mm:ss", "@hms@");
syntax = StringUtils.replaceAll(syntax, "nnnnnnnnn", "@nanos@");
syntax = StringUtils.replaceAll(syntax, "function", "@func@");
syntax = StringUtils.replaceAll(syntax, "0x", "@hexStart@");
syntax = StringUtils.replaceAll(syntax, ",...", "@commadots@");
syntax = StringUtils.replaceAll(syntax, "...", "@dots@");
syntax = StringUtils.replaceAll(syntax, "||", "@concat@");
syntax = StringUtils.replaceAll(syntax, "a-z|_", "@az_@");
syntax = StringUtils.replaceAll(syntax, "A-Z|_", "@az_@");
syntax = StringUtils.replaceAll(syntax, "a-f", "@af@");
syntax = StringUtils.replaceAll(syntax, "A-F", "@af@");
syntax = StringUtils.replaceAll(syntax, "0-9", "@digit@");
StringTokenizer tokenizer = new StringTokenizer(syntax, SEPARATORS, true);
while(tokenizer.hasMoreTokens()) {
String s = tokenizer.nextToken();
if(s.length() == 1) {
if(" \r\n".indexOf(s.charAt(0))>=0) {
continue;
}
}
list.add(s);
}
return (String[]) list.toArray(new String[0]);
}
public HashMap getNextTokenList(String query) {
HashMap next = new HashMap();
Sentence sentence = new Sentence();
sentence.next = next;
sentence.text = query;
for(int i=0; i<statements.size(); i++) {
RuleHead head = (RuleHead) statements.get(i);
if(!head.section.startsWith("Commands")) {
continue;
}
sentence.max = System.currentTimeMillis() + MAX_PARSE_TIME;
head.getRule().addNextTokenList(query, sentence);
}
return next;
}
public void linkStatements() {
HashMap ruleMap = getRuleMap();
for(Iterator it = ruleMap.keySet().iterator(); it.hasNext(); ) {
String key = (String)it.next();
RuleHead r = (RuleHead) ruleMap.get(key);
r.getRule().setLinks(ruleMap);
}
}
public void updateTopic(String topic, DbContextRule rule) {
topic = StringUtils.toLowerEnglish(topic);
RuleHead head = (RuleHead) ruleMap.get(topic);
if(head == null) {
head = new RuleHead(0, "db", topic, rule);
ruleMap.put(topic, head);
statements.add(head);
} else {
head.rule = rule;
}
}
public void updateTopic(String topic, String[] array) {
topic = StringUtils.toLowerEnglish(topic);
ArrayList list = new ArrayList();
for(int i=0; i<array.length; i++) {
list.add(new RuleElement(array[i], true, topic));
}
RuleList rule = new RuleList(list, true);
RuleHead head = (RuleHead) ruleMap.get(topic);
if(head == null) {
head = new RuleHead(0, "db", topic, rule);
ruleMap.put(topic, head);
statements.add(head);
} else {
head.rule = rule;
}
}
public ArrayList getStatements() {
return statements;
}
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.bnf;
import java.util.HashMap;
public interface Rule {
String name();
String random(Bnf config, int level);
Rule last();
void setLinks(HashMap ruleMap);
void addNextTokenList(String query, Sentence sentence);
/**
*
* @return null if not a match or a partial match, query.substring... if a full match
*/
String matchRemove(String query, Sentence sentence);
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.bnf;
import java.util.HashMap;
import org.h2.util.StringUtils;
public class RuleElement implements Rule {
private boolean keyword;
private String name;
private Rule link;
private int type;
private String topic;
public RuleElement(String name, boolean keyword, String topic) {
this.name = name;
this.topic = topic;
this.keyword = keyword;
this.type = Sentence.CONTEXT;
}
public RuleElement(String name, String topic) {
this.name = name;
this.topic = topic;
if(name.length()==1 || name.equals(StringUtils.toUpperEnglish(name))) {
keyword = true;
}
topic = StringUtils.toLowerEnglish(topic);
this.type = topic.startsWith("function") ? Sentence.FUNCTION : Sentence.KEYWORD;
}
public RuleElement merge(RuleElement rule) {
return new RuleElement(name + " " + rule.name, topic);
}
public String random(Bnf config, int level) {
if(keyword) {
return name.length() > 1 ? " " + name + " " : name;
}
if(link != null) {
return link.random(config, level+1);
}
throw new Error(">>>" + name + "<<<");
}
public String name() {
return name;
}
public Rule last() {
return this;
}
public void setLinks(HashMap ruleMap) {
if(link != null) {
link.setLinks(ruleMap);
}
if(keyword) {
return;
}
for(int i=0; i<name.length() && link == null; i++) {
String test = StringUtils.toLowerEnglish(name.substring(i));
RuleHead r = (RuleHead)ruleMap.get(test);
if(r != null) {
link = r.rule;
return;
}
}
if(link == null) {
throw new Error(">>>" + name + "<<<");
}
}
public String matchRemove(String query, Sentence sentence) {
if(sentence.stop()) {
return null;
}
if(query.length()==0) {
return null;
}
if(keyword) {
String up = StringUtils.toUpperEnglish(query);
if(up.startsWith(name)) {
query = query.substring(name.length());
while(!name.equals("_") && query.length()>0 && Character.isWhitespace(query.charAt(0))) {
query = query.substring(1);
}
return query;
}
return null;
} else {
query = link.matchRemove(query, sentence);
if(query != null && !name.startsWith("@") && (link.name() == null || !link.name().startsWith("@"))) {
while(query.length()>0 && Character.isWhitespace(query.charAt(0))) {
query = query.substring(1);
}
}
return query;
}
}
public void addNextTokenList(String query, Sentence sentence) {
if(sentence.stop()) {
return;
}
if(keyword) {
String q = query.trim();
String up = StringUtils.toUpperEnglish(q);
if(q.length() == 0 || name.startsWith(up)) {
if(q.length() < name.length()) {
sentence.add(name, name.substring(q.length()), type);
}
}
return;
}
link.addNextTokenList(query, sentence);
}
public boolean isKeyword() {
return keyword;
}
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.bnf;
import java.util.HashMap;
import java.util.Random;
import org.h2.util.StringUtils;
public class RuleFixed implements Rule {
public static final int YMD = 0, HMS =1, NANOS = 2;
public static final int ANY_EXCEPT_SINGLE_QUOTE = 3;
public static final int ANY_EXCEPT_DOUBLE_QUOTE = 4;
public static final int ANY_UNTIL_EOL = 5;
public static final int ANY_UNTIL_END = 6;
public static final int ANY_WORD = 7;
public static final int HEXSTART = 10, CONCAT = 11, AZ_ = 12, AF = 13, DIGIT = 14;
private int type;
public RuleFixed(int type) {
this.type = type;
}
public String random(Bnf config, int level) {
Random r = config.getRandom();
switch(type) {
case YMD:
return ""+(1800+r.nextInt(200))+"-"+(1+r.nextInt(12))+"-"+(1+r.nextInt(31));
case HMS:
return ""+(r.nextInt(24))+"-"+(r.nextInt(60))+"-"+(r.nextInt(60));
case NANOS:
return ""+(r.nextInt(100000)+r.nextInt(10000));
case ANY_UNTIL_EOL:
case ANY_EXCEPT_SINGLE_QUOTE:
case ANY_EXCEPT_DOUBLE_QUOTE:
case ANY_WORD:
case ANY_UNTIL_END: {
StringBuffer buff = new StringBuffer();
int len = r.nextInt(10);
for(int i=0; i<len; i++) {
buff.append((char)('A' + r.nextInt('Z'-'A')));
}
return buff.toString();
}
case HEXSTART:
return "0x";
case CONCAT:
return "||";
case AZ_:
return ""+(char)('A' + r.nextInt('Z'-'A'));
case AF:
return ""+(char)('A' + r.nextInt('F'-'A'));
case DIGIT:
return ""+(char)('0' + r.nextInt(10));
default:
throw new Error("type="+type);
}
}
public String name() {
return "type="+type;
}
public Rule last() {
return this;
}
public void setLinks(HashMap ruleMap) {
}
public String matchRemove(String query, Sentence sentence) {
if(sentence.stop()) {
return null;
}
if(query.length()==0) {
return null;
}
String s = query;
switch(type) {
case YMD:
while(s.length() > 0 && "0123456789- ".indexOf(s.charAt(0)) >= 0) {
s = s.substring(1);
}
break;
case HMS:
while(s.length() > 0 && "0123456789:. ".indexOf(s.charAt(0)) >= 0) {
s = s.substring(1);
}
break;
case NANOS:
while(s.length() > 0 && Character.isDigit(s.charAt(0))) {
s = s.substring(1);
}
break;
case ANY_WORD:
while(s.length() > 0 && Character.isWhitespace(s.charAt(0))) {
s = s.substring(1);
}
break;
case ANY_UNTIL_END:
while(s.length() > 1 && s.startsWith("*/")) {
s = s.substring(1);
}
break;
case ANY_UNTIL_EOL:
while(s.length() > 0 && s.charAt(0)!='\n') {
s = s.substring(1);
}
break;
case ANY_EXCEPT_SINGLE_QUOTE:
while(true) {
while(s.length() > 0 && s.charAt(0)!='\'') {
s = s.substring(1);
}
if(s.startsWith("''")) {
s = s.substring(2);
} else {
break;
}
}
break;
case ANY_EXCEPT_DOUBLE_QUOTE:
while(true) {
while(s.length() > 0 && s.charAt(0)!='\"') {
s = s.substring(1);
}
if(s.startsWith("\"\"")) {
s = s.substring(2);
} else {
break;
}
}
break;
case HEXSTART:
if(StringUtils.toUpperEnglish(s).startsWith("0X")) {
s = s.substring(2);
} else if(StringUtils.toUpperEnglish(s).startsWith("0")) {
s = s.substring(1);
}
break;
case CONCAT:
if(s.startsWith("||")) {
s = s.substring(2);
} else if(s.startsWith("|")) {
s = s.substring(1);
}
break;
case AZ_:
if(s.length() > 0 && (Character.isLetter(s.charAt(0)) || s.charAt(0)=='_')) {
s = s.substring(1);
}
break;
case AF:
if(s.length() > 0) {
char ch = Character.toUpperCase(s.charAt(0));
if(ch >= 'A' && ch <= 'F') {
s = s.substring(1);
}
}
break;
case DIGIT:
if(s.length() > 0 && Character.isDigit(s.charAt(0))) {
s = s.substring(1);
}
break;
default:
throw new Error("type="+type);
}
if(s == query) {
return null;
}
return s;
}
public void addNextTokenList(String query, Sentence sentence) {
if(sentence.stop()) {
return;
}
// String s = matchRemove(query, iteration);
switch(type) {
case YMD:
if(query.length() == 0) {
sentence.add("2006-01-01", "2006-01-01", Sentence.KEYWORD);
}
break;
case HMS:
if(query.length() == 0) {
sentence.add("12:00:00", "12:00:00", Sentence.KEYWORD);
}
break;
case NANOS:
if(query.length() == 0) {
sentence.add("nanoseconds", "0", Sentence.KEYWORD);
}
break;
case ANY_EXCEPT_SINGLE_QUOTE:
if(query.length() == 0) {
sentence.add("anything", "Hello World", Sentence.KEYWORD);
sentence.add("'", "'", Sentence.KEYWORD);
}
break;
case ANY_EXCEPT_DOUBLE_QUOTE:
if(query.length() == 0) {
sentence.add("anything", "identifier", Sentence.KEYWORD);
}
break;
case ANY_WORD:
break;
case HEXSTART:
if(query.length() == 0) {
sentence.add("0x", "0x", Sentence.KEYWORD);
} else if(query.equals("0")) {
sentence.add("0x", "x", Sentence.KEYWORD);
}
break;
case CONCAT:
if(query.length() == 0) {
sentence.add("||", "||", Sentence.KEYWORD);
} else if(query.equals("|")) {
sentence.add("||", "|", Sentence.KEYWORD);
}
break;
case AZ_:
if(query.length() == 0) {
sentence.add("character", "A", Sentence.KEYWORD);
}
break;
case AF:
if(query.length() == 0) {
sentence.add("hex character", "0A", Sentence.KEYWORD);
}
break;
case DIGIT:
if(query.length() == 0) {
sentence.add("digit", "1", Sentence.KEYWORD);
}
break;
default:
throw new Error("type="+type);
}
}
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.bnf;
public class RuleHead {
int id;
String section;
String topic;
Rule rule;
RuleHead(int id, String section, String topic, Rule rule) {
this.id = id;
this.section = section;
this.topic = topic;
this.rule = rule;
}
public String getTopic() {
return topic;
}
public Rule getRule() {
return rule;
}
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.bnf;
import java.util.ArrayList;
import java.util.HashMap;
public class RuleList implements Rule {
private boolean or;
private ArrayList list;
private boolean mapSet;
RuleList(ArrayList list, boolean or) {
this.or = or;
this.list = list;
}
RuleList(Rule first, Rule next, boolean or) {
list = new ArrayList();
if(first instanceof RuleList && ((RuleList)first).or == or) {
list.addAll(((RuleList)first).list);
} else {
list.add(first);
}
if(next instanceof RuleList && ((RuleList)next).or == or) {
list.addAll(((RuleList)next).list);
} else {
list.add(next);
}
if(!or && Bnf.COMBINE_KEYWORDS) {
for(int i=0; i<list.size()-1; i++) {
Rule r1 = (Rule) list.get(i);
Rule r2 = (Rule) list.get(i+1);
if(!(r1 instanceof RuleElement) || !(r2 instanceof RuleElement)) {
continue;
}
RuleElement re1 = (RuleElement) r1;
RuleElement re2 = (RuleElement) r2;
if(!re1.isKeyword() || !re2.isKeyword()) {
continue;
}
re1 = re1.merge(re2);
list.set(i, re1);
list.remove(i+1);
i--;
}
}
this.or = or;
}
public String random(Bnf config, int level) {
if(or) {
if(level > 10) {
if(level > 1000) {
// better than stack overflow
throw new Error();
}
return get(0).random(config, level);
}
int idx = config.getRandom().nextInt(list.size());
return get(idx).random(config, level+1);
} else {
StringBuffer buff = new StringBuffer();
for(int i=0; i<list.size(); i++) {
buff.append(get(i).random(config, level+1));
}
return buff.toString();
}
}
private Rule get(int idx) {
return ((Rule)list.get(idx));
}
public String name() {
return null;
}
public Rule last() {
return get(list.size()-1);
}
public void setLinks(HashMap ruleMap) {
if(!mapSet) {
for(int i=0; i<list.size(); i++) {
get(i).setLinks(ruleMap);
}
mapSet = true;
}
}
public String matchRemove(String query, Sentence sentence) {
if(query.length()==0) {
return null;
}
if(or) {
for(int i=0; i<list.size(); i++) {
String s = get(i).matchRemove(query, sentence);
if(s != null) {
return s;
}
}
return null;
} else {
for(int i=0; i<list.size(); i++) {
Rule r = get(i);
query = r.matchRemove(query, sentence);
if(query == null) {
return null;
}
}
return query;
}
}
public void addNextTokenList(String query, Sentence sentence) {
if(sentence.stop()) {
//
}
if(or) {
for(int i=0; i<list.size(); i++) {
get(i).addNextTokenList(query, sentence);
}
} else {
for(int i=0; i<list.size(); i++) {
Rule r = get(i);
r.addNextTokenList(query, sentence);
query = r.matchRemove(query, sentence);
if(query == null) {
break;
}
}
}
}
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.bnf;
import java.util.HashMap;
public class RuleOptional implements Rule {
private Rule rule;
private boolean mapSet;
RuleOptional(Rule rule, boolean repeat) {
this.rule = rule;
}
public String name() {
return null;
}
public String random(Bnf config, int level) {
if(level > 10 ? config.getRandom().nextInt(level) == 1 : config.getRandom().nextBoolean()) {
return rule.random(config, level+1);
} else {
return "";
}
}
public Rule last() {
return this;
}
public void setLinks(HashMap ruleMap) {
if(!mapSet) {
rule.setLinks(ruleMap);
mapSet = true;
}
}
public String matchRemove(String query, Sentence sentence) {
if(sentence.stop()) {
return null;
}
if(query.length()==0) {
return query;
}
String s = rule.matchRemove(query, sentence);
if(s == null) {
return query;
}
return s;
}
public void addNextTokenList(String query, Sentence sentence) {
if(sentence.stop()) {
return;
}
rule.addNextTokenList(query, sentence);
}
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.bnf;
import java.util.HashMap;
public class RuleRepeat implements Rule {
Rule rule;
RuleRepeat(Rule rule) {
this.rule = rule;
}
public String name() {
return rule.name();
}
public Rule last() {
return this;
}
public void setLinks(HashMap ruleMap) {
// rule.setLinks(ruleMap);
}
public String random(Bnf config, int level) {
return rule.random(config, level);
}
public String matchRemove(String query, Sentence sentence) {
if(sentence.stop()) {
return null;
}
if(query.length()==0) {
return null;
}
while(true) {
String s = rule.matchRemove(query, sentence);
if(s==null) {
return query;
} else if(s.length()==0) {
return s;
}
query = s;
}
}
public void addNextTokenList(String query, Sentence sentence) {
if(sentence.stop()) {
return;
}
while(true) {
rule.addNextTokenList(query, sentence);
String s = rule.matchRemove(query, sentence);
if(s == null || s==query) {
break;
}
query = s;
}
}
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.bnf;
import java.util.HashMap;
import java.util.HashSet;
import org.h2.server.web.DbTableOrView;
public class Sentence {
public static final int CONTEXT=0, KEYWORD=1;
public static final int FUNCTION = 2;
public String text;
HashMap next;
long max;
DbTableOrView lastTable;
private HashSet tables;
private HashMap aliases;
public boolean stop() {
return System.currentTimeMillis() > max;
}
public void add(String n, String string, int type) {
next.put(type+"#"+n, string);
}
public void addAlias(String alias, DbTableOrView table) {
if(aliases == null) {
aliases = new HashMap();
}
aliases.put(alias, table);
}
public void addTable(DbTableOrView table) {
lastTable = table;
if(tables==null) {
tables = new HashSet();
}
tables.add(table);
}
public HashSet getTables() {
return tables;
}
public HashMap getAliases() {
return aliases;
}
public DbTableOrView getLastTable() {
return lastTable;
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论