/* * 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. */ // This adds javacc generation support. configure(rootProject) { configurations { javacc } dependencies { javacc "net.java.dev.javacc:javacc:${scriptDepVersions['javacc']}" } task javacc() { description "Regenerate sources for corresponding javacc grammar files." group "generation" dependsOn ":lucene:queryparser:javaccParserClassic" dependsOn ":lucene:queryparser:javaccParserSurround" dependsOn ":lucene:queryparser:javaccParserFlexible" dependsOn ":solr:core:javaccSolrParser" } } // We always regenerate, no need to declare outputs. class JavaCCTask extends DefaultTask { @Input File javaccFile JavaCCTask() { dependsOn(project.rootProject.configurations.javacc) } @TaskAction def generate() { if (!javaccFile || !javaccFile.exists()) { throw new RuntimeException("JavaCC input file does not exist: ${javaccFile}") } // Remove previous files so we can regenerate them. javacc doesn't want to overwrite // locally modified files. def parentDir = javaccFile.parentFile def toDelete = project.fileTree(parentDir, { include "**/*.java" }).findAll { file -> file.getText("UTF-8").contains("Generated By:JavaCC") } project.delete(toDelete) logger.lifecycle("Regenerating JavaCC:\n from: ${javaccFile}\n to: ${parentDir}") def output = new ByteArrayOutputStream() def result = project.javaexec { classpath { project.rootProject.configurations.javacc } ignoreExitValue = true standardOutput = output errorOutput = output main = "org.javacc.parser.Main" args += [ "-OUTPUT_DIRECTORY=${parentDir}", javaccFile ] } // Unless we request verbose logging, don't emit javacc output. if (result.exitValue != 0) { throw new GradleException("JavaCC failed to compile ${javaccFile}, here is the compilation output:\n${output}") } // Cleanup common to more than one javacc invocation. // // This is a minor typo in a comment that nontheless people have hand-corrected in the past. ant.replace(file: "${parentDir}/CharStream.java", token: "implemetation", value: "implementation", encoding: "UTF-8") // StringBuffer -> StringBuilder ant.replace(token: "StringBuffer", value: "StringBuilder", encoding: "UTF-8") { ant.fileset(dir: parentDir, includes: '*.java') { ant.containsregexp(expression: "Generated By:JavaCC:") } } // Eliminates redundant cast message ant.replace(token: "int hiByte = (int)(curChar >> 8);", value: "int hiByte = curChar >> 8;", encoding: "UTF-8") { ant.fileset(dir: parentDir, includes: "*TokenManager.java") } // So precommit passes ant.replaceregexp(match: "/\\*\\* Debug output.*?Set debug output.*?ds; }", replace: '', flags: 's', encoding: 'UTF-8') { ant.fileset(dir: parentDir, includes: "*TokenManager.java") } // Correct line endings for Windows. project.ant.fixcrlf(srcDir: parentDir, includes: "*.java", encoding: "UTF-8", eol: "lf") { ant.containsregexp(expression: "Generated By:JavaCC:") } } } configure(project(":lucene:queryparser")) { task javaccParserClassic(type: JavaCCTask) { description "Regenerate classic query parser from lucene/queryparser/classic/QueryParser.jj" group "generation" javaccFile = file('src/java/org/apache/lucene/queryparser/classic/QueryParser.jj') def parentDir = javaccFile.parentFile // I'll need this later. doLast { // control visibility issues ant.replace(file: file("${parentDir}/QueryParser.java"), token: "public QueryParser(CharStream ", value: "protected QueryParser(CharStream ", encoding: 'UTF-8') ant.replace(file: file("${parentDir}/QueryParser.java"), token: "public QueryParser(QueryParserTokenManager ", value: "protected QueryParser(QueryParserTokenManager ", encoding: 'UTF-8') // Some redundant casts etc. in queryparser.java ant.replace(file: file("${parentDir}/QueryParser.java"), token: "new java.util.ArrayList", value: "new java.util.ArrayList<>", encoding: 'UTF-8') ant.replace(file: file("${parentDir}/QueryParser.java"), token: "new java.util.ArrayList", value: "new java.util.ArrayList<>", encoding: 'UTF-8') ant.replace(file: file("${parentDir}/QueryParser.java"), token: "(int)(curChar >> 8);", value: "curChar >> 8;", encoding: 'UTF-8') // Remove unnecessary imports def separator = System.getProperty('line.separator') [/import java\.io\.StringReader;/, /import java\.util\.ArrayList;/, /import java\.util\.Arrays;/, /import java\.util\.HashSet;/, /import java\.util\.List;/, /import java\.util\.Locale;/, /import java\.util\.Set;/, /import org\.apache\.lucene\.analysis\.Analyzer;/, /import org\.apache\.lucene\.document\.DateTools;/, /import org\.apache\.lucene\.search\.BooleanClause;/, /import org\.apache\.lucene\.search\.Query;/, /import org\.apache\.lucene\.search\.TermRangeQuery/, /import org\.apache\.lucene\.search\.TermRangeQuery;/ ].each { ant.replaceregexp(file: file("${parentDir}/QueryParserTokenManager.java"), match: "${it}\\s*${separator}", replace: "", encoding: "UTF-8") } } } } configure(project(":lucene:queryparser")) { task javaccParserSurround(type: JavaCCTask) { description "Regenerate surround query parser from lucene/queryparser/surround/parser/QueryParser.jj" group "generation" javaccFile = file('src/java/org/apache/lucene/queryparser/surround/parser/QueryParser.jj') def parentDir = javaccFile.parentFile doLast { def separator = System.getProperty('line.separator') // Remove unneeded import ant.replaceregexp(match: /import org\.apache\.lucene\.analysis\.TokenStream;\s*${separator}${separator}/, replace: "", encoding: "UTF-8") { ant.fileset(dir: parentDir, includes: "QueryParser.java") } // Eliminate compiler warning ant.replace(file: file("${parentDir}/QueryParser.java"), token: "new java.util.ArrayList", value: "new java.util.ArrayList<>", encoding: 'UTF-8') // There are a bunch of unused imports we need to remove to pass precommit [ /import java\.util\.ArrayList;/, /import java\.util\.List;/, /import java\.io\.StringReader;/, /import org\.apache\.lucene\.analysis\.TokenStream;/, /import org\.apache\.lucene\.queryparser\.surround\.query\.SrndQuery;/, /import org\.apache\.lucene\.queryparser\.surround\.query\.FieldsQuery;/, /import org\.apache\.lucene\.queryparser\.surround\.query\.OrQuery;/, /import org\.apache\.lucene\.queryparser\.surround\.query\.AndQuery;/, /import org\.apache\.lucene\.queryparser\.surround\.query\.NotQuery;/, /import org\.apache\.lucene\.queryparser\.surround\.query\.DistanceQuery;/, /import org\.apache\.lucene\.queryparser\.surround\.query\.SrndTermQuery;/, /import org\.apache\.lucene\.queryparser\.surround\.query\.SrndPrefixQuery;/, /import org\.apache\.lucene\.queryparser\.surround\.query\.SrndTruncQuery;/ ].each { ant.replaceregexp(file: file("${parentDir}/QueryParserTokenManager.java"), match: "${it}\\s*${separator}", replace: "", encoding: "UTF-8") } } } } configure(project(":lucene:queryparser")) { task javaccParserFlexible(type: JavaCCTask) { description "Regenerate Flexible query parser from queryparser/flexible/standard/parser/StandardSyntaxParser.jj" group "generation" javaccFile = file('src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParser.jj') def parentDir = javaccFile.parentFile doLast { def lineSeparator = System.lineSeparator() // extend the proper class ant.replaceregexp(file: "${parentDir}/ParseException.java", match: "public class ParseException extends Exception", replace: "public class ParseException extends QueryNodeParseException", flags: "g", byline: "false", encoding: 'UTF-8') // Import correct classes. ant.replaceregexp(file: "${parentDir}/ParseException.java", match: "package org.apache.lucene.queryparser.flexible.standard.parser;", replace: "package org.apache.lucene.queryparser.flexible.standard.parser;${lineSeparator} ${lineSeparator}" + " import org.apache.lucene.queryparser.flexible.messages.Message;${lineSeparator}" + " import org.apache.lucene.queryparser.flexible.messages.MessageImpl;${lineSeparator}" + " import org.apache.lucene.queryparser.flexible.core.*;${lineSeparator}" + " import org.apache.lucene.queryparser.flexible.core.messages.*;", flags: "g", byline: "false", encoding: 'UTF-8') // Fill in c'tor code ant.replaceregexp(file: "${parentDir}/ParseException.java", match: "^ public ParseException\\(Token currentTokenVal.*\$(\\s\\s[^}].*\\n)* \\}", replace: " public ParseException(Token currentTokenVal,${lineSeparator}" + " int[][] expectedTokenSequencesVal, String[] tokenImageVal) {${lineSeparator}" + " super(new MessageImpl(QueryParserMessages.INVALID_SYNTAX, initialise(${lineSeparator}" + " currentTokenVal, expectedTokenSequencesVal, tokenImageVal)));${lineSeparator}" + " this.currentToken = currentTokenVal;${lineSeparator}" + " this.expectedTokenSequences = expectedTokenSequencesVal;${lineSeparator}" + " this.tokenImage = tokenImageVal;${lineSeparator}" + " }", flags: "gm", byline: "false", encoding: 'UTF-8') // Invoke super, use proper c'tor ant.replaceregexp(file: "${parentDir}/ParseException.java", match: "^ public ParseException\\(String message.*\$(\\s\\s[^}].*\\n)* \\}", replace: " public ParseException(Message message) {${lineSeparator}" + " super(message);${lineSeparator}" + " }", flags: "gm", byline: "false", encoding: 'UTF-8') // Invoke super properly ant.replaceregexp(file: "${parentDir}/ParseException.java", match: "^ public ParseException\\(\\).*\$(\\s\\s[^}].*\\n)* \\}", replace: " public ParseException() {${lineSeparator}" + " super(new MessageImpl(QueryParserMessages.INVALID_SYNTAX, \"Error\"));${lineSeparator}" + " }", flags: "gm", byline: "false", encoding: 'UTF-8') // Redundant cast warning ant.replace(file: file("${parentDir}/StandardSyntaxParser.java"), token: "new java.util.ArrayList", value: "new java.util.ArrayList<>", encoding: 'UTF-8') // Remove unused imports. def separator = System.getProperty('line.separator') [ /import java.io.StringReader;/, /import java.util.Vector;/, /import java.util.Arrays;/, /import org.apache.lucene.queryparser.flexible.messages.Message;/, /import org.apache.lucene.queryparser.flexible.messages.MessageImpl;/, /import org.apache.lucene.queryparser.flexible.core.QueryNodeParseException;/, /import org.apache.lucene.queryparser.flexible.core.messages.QueryParserMessages;/, /import org.apache.lucene.queryparser.flexible.core.nodes.AndQueryNode;/, /import org.apache.lucene.queryparser.flexible.core.nodes.BooleanQueryNode;/, /import org.apache.lucene.queryparser.flexible.core.nodes.BoostQueryNode;/, /import org.apache.lucene.queryparser.flexible.core.nodes.FieldQueryNode;/, /import org.apache.lucene.queryparser.flexible.core.nodes.FuzzyQueryNode;/, /import org.apache.lucene.queryparser.flexible.core.nodes.ModifierQueryNode;/, /import org.apache.lucene.queryparser.flexible.core.nodes.GroupQueryNode;/, /import org.apache.lucene.queryparser.flexible.core.nodes.OrQueryNode;/, /import org.apache.lucene.queryparser.flexible.standard.nodes.RegexpQueryNode;/, /import org.apache.lucene.queryparser.flexible.core.nodes.SlopQueryNode;/, /import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode;/, /import org.apache.lucene.queryparser.flexible.core.nodes.QuotedFieldQueryNode;/, /import org.apache.lucene.queryparser.flexible.core.parser.SyntaxParser;/, /import org.apache.lucene.queryparser.flexible.standard.nodes.TermRangeQueryNode;/ ].each { ant.replaceregexp(file: file("${parentDir}/StandardSyntaxParserTokenManager.java"), match: "${it}\\s*${separator}", replace: "", encoding: "UTF-8") } } } } configure(project(":solr:core")) { task javaccSolrParser(type: JavaCCTask) { description "Regenerate Solr query parser from solr/parser/QueryParser.jj" group "generation" javaccFile = file('src/java/org/apache/solr/parser/QueryParser.jj') doLast { def separator = System.getProperty('line.separator') def parentDir = javaccFile.parentFile [/import java\.io\.StringReader;/, /import java\.util\.ArrayList;/, /import java\.util\.Arrays;/, /import java\.util\.HashSet;/, /import java\.util\.List;/, /import java\.util\.Set;/, /import org\.apache\.lucene\.analysis\.Analyzer;/, /import org\.apache\.lucene\.search\.BooleanClause;/, /import org\.apache\.lucene\.search\.Query;/, /import org\.apache\.solr\.search\.SyntaxError;/, /import org\.apache\.solr\.search\.QParser;/ ].each { ant.replaceregexp(file: file("${parentDir}/QueryParserTokenManager.java"), match: "${it}\\s*${separator}", replace: "", encoding: "UTF-8") } ant.replace(file: "${parentDir}/QueryParser.java", token: "public QueryParser(CharStream ", value: "protected QueryParser(CharStream ", encoding: "UTF-8") ant.replace(file: "${parentDir}/QueryParser.java", token: "public QueryParser(QueryParserTokenManager ", value: "protected QueryParser(QueryParserTokenManager ", encoding: "UTF-8") ant.replace(file: "${parentDir}/QueryParser.java", token: "final private LookaheadSuccess jj_ls =", value: "static final private LookaheadSuccess jj_ls =", encoding: "UTF-8") } } }