mirror of https://github.com/apache/lucene.git
fix eol-style
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1305339 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
f5770479e3
commit
a29a14698e
|
@ -1,10 +1,10 @@
|
||||||
<component name="libraryTable">
|
<component name="libraryTable">
|
||||||
<library name="ICU library">
|
<library name="ICU library">
|
||||||
<CLASSES>
|
<CLASSES>
|
||||||
<root url="file://$PROJECT_DIR$/modules/analysis/icu/lib" />
|
<root url="file://$PROJECT_DIR$/modules/analysis/icu/lib" />
|
||||||
</CLASSES>
|
</CLASSES>
|
||||||
<JAVADOC />
|
<JAVADOC />
|
||||||
<SOURCES />
|
<SOURCES />
|
||||||
<jarDirectory url="file://$PROJECT_DIR$/modules/analysis/icu/lib" recursive="false" />
|
<jarDirectory url="file://$PROJECT_DIR$/modules/analysis/icu/lib" recursive="false" />
|
||||||
</library>
|
</library>
|
||||||
</component>
|
</component>
|
|
@ -1,56 +1,56 @@
|
||||||
|
|
||||||
<project name="custom-tasks">
|
<project name="custom-tasks">
|
||||||
<description>
|
<description>
|
||||||
This file is designed for importing into a main build file, and not intended
|
This file is designed for importing into a main build file, and not intended
|
||||||
for standalone use.
|
for standalone use.
|
||||||
</description>
|
</description>
|
||||||
|
|
||||||
<macrodef name="license-check-macro">
|
<macrodef name="license-check-macro">
|
||||||
<attribute name="dir" />
|
<attribute name="dir" />
|
||||||
<element name="additional-excludes" optional="true" />
|
<element name="additional-excludes" optional="true" />
|
||||||
<element name="additional-filters" optional="true" />
|
<element name="additional-filters" optional="true" />
|
||||||
<sequential>
|
<sequential>
|
||||||
<!-- LICENSE and NOTICE verification macro. -->
|
<!-- LICENSE and NOTICE verification macro. -->
|
||||||
<dirname file="${ant.file.custom-tasks}" property="custom-tasks.dir"/>
|
<dirname file="${ant.file.custom-tasks}" property="custom-tasks.dir"/>
|
||||||
<taskdef resource="lucene-solr.antlib.xml">
|
<taskdef resource="lucene-solr.antlib.xml">
|
||||||
<classpath>
|
<classpath>
|
||||||
<pathelement location="${custom-tasks.dir}/../build/tools/classes/java" />
|
<pathelement location="${custom-tasks.dir}/../build/tools/classes/java" />
|
||||||
</classpath>
|
</classpath>
|
||||||
</taskdef>
|
</taskdef>
|
||||||
|
|
||||||
<echo>License check under: @{dir}</echo>
|
<echo>License check under: @{dir}</echo>
|
||||||
<licenses>
|
<licenses>
|
||||||
<fileset dir="@{dir}">
|
<fileset dir="@{dir}">
|
||||||
<include name="**/*.jar" />
|
<include name="**/*.jar" />
|
||||||
<!-- Speed up scanning a bit. -->
|
<!-- Speed up scanning a bit. -->
|
||||||
<exclude name="**/.git/**" />
|
<exclude name="**/.git/**" />
|
||||||
<exclude name="**/.svn/**" />
|
<exclude name="**/.svn/**" />
|
||||||
<exclude name="**/bin/**" />
|
<exclude name="**/bin/**" />
|
||||||
<exclude name="**/build/**" />
|
<exclude name="**/build/**" />
|
||||||
<exclude name="**/dist/**" />
|
<exclude name="**/dist/**" />
|
||||||
<exclude name="**/src/**" />
|
<exclude name="**/src/**" />
|
||||||
<additional-excludes />
|
<additional-excludes />
|
||||||
</fileset>
|
</fileset>
|
||||||
|
|
||||||
<licenseMapper>
|
<licenseMapper>
|
||||||
<filtermapper id="license-mapper-defaults">
|
<filtermapper id="license-mapper-defaults">
|
||||||
<!-- Normalize input paths. -->
|
<!-- Normalize input paths. -->
|
||||||
<replacestring from="\" to="/" />
|
<replacestring from="\" to="/" />
|
||||||
<replaceregex pattern="\.jar$" replace="" flags="gi" />
|
<replaceregex pattern="\.jar$" replace="" flags="gi" />
|
||||||
|
|
||||||
<!-- Some typical snapshot/minimalized JAR suffixes. -->
|
<!-- Some typical snapshot/minimalized JAR suffixes. -->
|
||||||
<replaceregex pattern="-min$" replace="" flags="gi" />
|
<replaceregex pattern="-min$" replace="" flags="gi" />
|
||||||
<replaceregex pattern="SNAPSHOT$" replace="" flags="gi" />
|
<replaceregex pattern="SNAPSHOT$" replace="" flags="gi" />
|
||||||
|
|
||||||
<!-- Non-typical version patterns. -->
|
<!-- Non-typical version patterns. -->
|
||||||
<additional-filters />
|
<additional-filters />
|
||||||
<replaceregex pattern="/xercesImpl([^/]+)$" replace="/xercesImpl" flags="gi" />
|
<replaceregex pattern="/xercesImpl([^/]+)$" replace="/xercesImpl" flags="gi" />
|
||||||
|
|
||||||
<!-- Typical version patterns. -->
|
<!-- Typical version patterns. -->
|
||||||
<replaceregex pattern="\-(r)?([0-9\-\_\.])+(b(eta)?([0-9\-\.])*)?$" replace="" flags="gi" />
|
<replaceregex pattern="\-(r)?([0-9\-\_\.])+(b(eta)?([0-9\-\.])*)?$" replace="" flags="gi" />
|
||||||
</filtermapper>
|
</filtermapper>
|
||||||
</licenseMapper>
|
</licenseMapper>
|
||||||
</licenses>
|
</licenses>
|
||||||
</sequential>
|
</sequential>
|
||||||
</macrodef>
|
</macrodef>
|
||||||
</project>
|
</project>
|
|
@ -1,110 +1,110 @@
|
||||||
package org.apache.lucene.analysis.icu;
|
package org.apache.lucene.analysis.icu;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
* this work for additional information regarding copyright ownership.
|
* this work for additional information regarding copyright ownership.
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
* 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 not use this file except in compliance with
|
||||||
* the License. You may obtain a copy of the License at
|
* the License. You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import com.ibm.icu.text.UnicodeSet;
|
import com.ibm.icu.text.UnicodeSet;
|
||||||
import com.ibm.icu.text.UnicodeSetIterator;
|
import com.ibm.icu.text.UnicodeSetIterator;
|
||||||
import com.ibm.icu.util.VersionInfo;
|
import com.ibm.icu.util.VersionInfo;
|
||||||
|
|
||||||
/** creates a macro to augment jflex's unicode support for > BMP */
|
/** creates a macro to augment jflex's unicode support for > BMP */
|
||||||
public class GenerateHTMLStripCharFilterSupplementaryMacros {
|
public class GenerateHTMLStripCharFilterSupplementaryMacros {
|
||||||
private static final UnicodeSet BMP = new UnicodeSet("[\u0000-\uFFFF]");
|
private static final UnicodeSet BMP = new UnicodeSet("[\u0000-\uFFFF]");
|
||||||
private static final String NL = System.getProperty("line.separator");
|
private static final String NL = System.getProperty("line.separator");
|
||||||
private static final DateFormat DATE_FORMAT = DateFormat.getDateTimeInstance
|
private static final DateFormat DATE_FORMAT = DateFormat.getDateTimeInstance
|
||||||
(DateFormat.FULL, DateFormat.FULL, Locale.US);
|
(DateFormat.FULL, DateFormat.FULL, Locale.US);
|
||||||
static {
|
static {
|
||||||
DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC"));
|
DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String APACHE_LICENSE
|
private static final String APACHE_LICENSE
|
||||||
= "/*" + NL
|
= "/*" + NL
|
||||||
+ " * Copyright 2010 The Apache Software Foundation." + NL
|
+ " * Copyright 2010 The Apache Software Foundation." + NL
|
||||||
+ " *" + NL
|
+ " *" + NL
|
||||||
+ " * Licensed under the Apache License, Version 2.0 (the \"License\");" + NL
|
+ " * Licensed under the Apache License, Version 2.0 (the \"License\");" + NL
|
||||||
+ " * you may not use this file except in compliance with the License." + NL
|
+ " * you may not use this file except in compliance with the License." + NL
|
||||||
+ " * You may obtain a copy of the License at" + NL
|
+ " * You may obtain a copy of the License at" + NL
|
||||||
+ " *" + NL
|
+ " *" + NL
|
||||||
+ " * http://www.apache.org/licenses/LICENSE-2.0" + NL
|
+ " * http://www.apache.org/licenses/LICENSE-2.0" + NL
|
||||||
+ " *" + NL
|
+ " *" + NL
|
||||||
+ " * Unless required by applicable law or agreed to in writing, software" + NL
|
+ " * Unless required by applicable law or agreed to in writing, software" + NL
|
||||||
+ " * distributed under the License is distributed on an \"AS IS\" BASIS," + NL
|
+ " * distributed under the License is distributed on an \"AS IS\" BASIS," + NL
|
||||||
+ " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied." + NL
|
+ " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied." + NL
|
||||||
+ " * See the License for the specific language governing permissions and" + NL
|
+ " * See the License for the specific language governing permissions and" + NL
|
||||||
+ " * limitations under the License." + NL
|
+ " * limitations under the License." + NL
|
||||||
+ " */" + NL + NL;
|
+ " */" + NL + NL;
|
||||||
|
|
||||||
|
|
||||||
public static void main(String args[]) throws Exception {
|
public static void main(String args[]) throws Exception {
|
||||||
outputHeader();
|
outputHeader();
|
||||||
outputMacro("ID_Start_Supp", "[:ID_Start:]");
|
outputMacro("ID_Start_Supp", "[:ID_Start:]");
|
||||||
outputMacro("ID_Continue_Supp", "[:ID_Continue:]");
|
outputMacro("ID_Continue_Supp", "[:ID_Continue:]");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void outputHeader() {
|
static void outputHeader() {
|
||||||
System.out.print(APACHE_LICENSE);
|
System.out.print(APACHE_LICENSE);
|
||||||
System.out.print("// Generated using ICU4J " + VersionInfo.ICU_VERSION.toString() + " on ");
|
System.out.print("// Generated using ICU4J " + VersionInfo.ICU_VERSION.toString() + " on ");
|
||||||
System.out.println(DATE_FORMAT.format(new Date()));
|
System.out.println(DATE_FORMAT.format(new Date()));
|
||||||
System.out.println("// by " + GenerateHTMLStripCharFilterSupplementaryMacros.class.getName());
|
System.out.println("// by " + GenerateHTMLStripCharFilterSupplementaryMacros.class.getName());
|
||||||
System.out.print(NL + NL);
|
System.out.print(NL + NL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// we have to carefully output the possibilities as compact utf-16
|
// we have to carefully output the possibilities as compact utf-16
|
||||||
// range expressions, or jflex will OOM!
|
// range expressions, or jflex will OOM!
|
||||||
static void outputMacro(String name, String pattern) {
|
static void outputMacro(String name, String pattern) {
|
||||||
UnicodeSet set = new UnicodeSet(pattern);
|
UnicodeSet set = new UnicodeSet(pattern);
|
||||||
set.removeAll(BMP);
|
set.removeAll(BMP);
|
||||||
System.out.println(name + " = (");
|
System.out.println(name + " = (");
|
||||||
// if the set is empty, we have to do this or jflex will barf
|
// if the set is empty, we have to do this or jflex will barf
|
||||||
if (set.isEmpty()) {
|
if (set.isEmpty()) {
|
||||||
System.out.println("\t []");
|
System.out.println("\t []");
|
||||||
}
|
}
|
||||||
|
|
||||||
HashMap<Character,UnicodeSet> utf16ByLead = new HashMap<Character,UnicodeSet>();
|
HashMap<Character,UnicodeSet> utf16ByLead = new HashMap<Character,UnicodeSet>();
|
||||||
for (UnicodeSetIterator it = new UnicodeSetIterator(set); it.next();) {
|
for (UnicodeSetIterator it = new UnicodeSetIterator(set); it.next();) {
|
||||||
char utf16[] = Character.toChars(it.codepoint);
|
char utf16[] = Character.toChars(it.codepoint);
|
||||||
UnicodeSet trails = utf16ByLead.get(utf16[0]);
|
UnicodeSet trails = utf16ByLead.get(utf16[0]);
|
||||||
if (trails == null) {
|
if (trails == null) {
|
||||||
trails = new UnicodeSet();
|
trails = new UnicodeSet();
|
||||||
utf16ByLead.put(utf16[0], trails);
|
utf16ByLead.put(utf16[0], trails);
|
||||||
}
|
}
|
||||||
trails.add(utf16[1]);
|
trails.add(utf16[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String,UnicodeSet> utf16ByTrail = new HashMap<String,UnicodeSet>();
|
Map<String,UnicodeSet> utf16ByTrail = new HashMap<String,UnicodeSet>();
|
||||||
for (Map.Entry<Character,UnicodeSet> entry : utf16ByLead.entrySet()) {
|
for (Map.Entry<Character,UnicodeSet> entry : utf16ByLead.entrySet()) {
|
||||||
String trail = entry.getValue().getRegexEquivalent();
|
String trail = entry.getValue().getRegexEquivalent();
|
||||||
UnicodeSet leads = utf16ByTrail.get(trail);
|
UnicodeSet leads = utf16ByTrail.get(trail);
|
||||||
if (leads == null) {
|
if (leads == null) {
|
||||||
leads = new UnicodeSet();
|
leads = new UnicodeSet();
|
||||||
utf16ByTrail.put(trail, leads);
|
utf16ByTrail.put(trail, leads);
|
||||||
}
|
}
|
||||||
leads.add(entry.getKey());
|
leads.add(entry.getKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isFirst = true;
|
boolean isFirst = true;
|
||||||
for (Map.Entry<String,UnicodeSet> entry : utf16ByTrail.entrySet()) {
|
for (Map.Entry<String,UnicodeSet> entry : utf16ByTrail.entrySet()) {
|
||||||
System.out.print( isFirst ? "\t " : "\t| ");
|
System.out.print( isFirst ? "\t " : "\t| ");
|
||||||
isFirst = false;
|
isFirst = false;
|
||||||
System.out.println(entry.getValue().getRegexEquivalent() + entry.getKey());
|
System.out.println(entry.getValue().getRegexEquivalent() + entry.getKey());
|
||||||
}
|
}
|
||||||
System.out.println(")");
|
System.out.println(")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,33 +1,33 @@
|
||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<project name="spatial" default="default">
|
<project name="spatial" default="default">
|
||||||
<description>
|
<description>
|
||||||
Lucene Spatial
|
Lucene Spatial
|
||||||
</description>
|
</description>
|
||||||
|
|
||||||
<property name="build.dir" location="build/" />
|
<property name="build.dir" location="build/" />
|
||||||
<property name="dist.dir" location="dist/" />
|
<property name="dist.dir" location="dist/" />
|
||||||
<property name="maven.dist.dir" location="../dist/maven" />
|
<property name="maven.dist.dir" location="../dist/maven" />
|
||||||
|
|
||||||
<path id="additional.dependencies">
|
<path id="additional.dependencies">
|
||||||
<fileset dir="lib" includes="*.jar"/>
|
<fileset dir="lib" includes="*.jar"/>
|
||||||
</path>
|
</path>
|
||||||
|
|
||||||
<pathconvert property="project.classpath"
|
<pathconvert property="project.classpath"
|
||||||
targetos="unix"
|
targetos="unix"
|
||||||
refid="additional.dependencies"
|
refid="additional.dependencies"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<import file="../../lucene/contrib/contrib-build.xml"/>
|
<import file="../../lucene/contrib/contrib-build.xml"/>
|
||||||
|
|
||||||
<path id="classpath">
|
<path id="classpath">
|
||||||
<path refid="base.classpath"/>
|
<path refid="base.classpath"/>
|
||||||
<pathelement path="${queries.jar}" />
|
<pathelement path="${queries.jar}" />
|
||||||
</path>
|
</path>
|
||||||
|
|
||||||
<path id="test.classpath">
|
<path id="test.classpath">
|
||||||
<path refid="test.base.classpath" />
|
<path refid="test.base.classpath" />
|
||||||
<pathelement path="src/test-files" />
|
<pathelement path="src/test-files" />
|
||||||
</path>
|
</path>
|
||||||
|
|
||||||
<target name="compile-core" depends="jar-queries,common.compile-core" />
|
<target name="compile-core" depends="jar-queries,common.compile-core" />
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
/*
|
/*
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
* this work for additional information regarding copyright ownership.
|
* this work for additional information regarding copyright ownership.
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
* 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 not use this file except in compliance with
|
||||||
* the License. You may obtain a copy of the License at
|
* the License. You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prefix Tree Strategy
|
* Prefix Tree Strategy
|
||||||
*/
|
*/
|
||||||
package org.apache.lucene.spatial.prefix;
|
package org.apache.lucene.spatial.prefix;
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
<!--
|
<!--
|
||||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
contributor license agreements. See the NOTICE file distributed with
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
this work for additional information regarding copyright ownership.
|
this work for additional information regarding copyright ownership.
|
||||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
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 not use this file except in compliance with
|
||||||
the License. You may obtain a copy of the License at
|
the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
Unless required by applicable law or agreed to in writing, software
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Apache Lucene Spatial Strategies</title>
|
<title>Apache Lucene Spatial Strategies</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -1,241 +1,241 @@
|
||||||
package org.apache.solr.handler.clustering.carrot2;
|
package org.apache.solr.handler.clustering.carrot2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
* this work for additional information regarding copyright ownership.
|
* this work for additional information regarding copyright ownership.
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
* 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 not use this file except in compliance with
|
||||||
* the License. You may obtain a copy of the License at
|
* the License. You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.nio.CharBuffer;
|
import java.nio.CharBuffer;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
import org.apache.lucene.analysis.ar.ArabicNormalizer;
|
import org.apache.lucene.analysis.ar.ArabicNormalizer;
|
||||||
import org.apache.lucene.analysis.ar.ArabicStemmer;
|
import org.apache.lucene.analysis.ar.ArabicStemmer;
|
||||||
import org.carrot2.core.LanguageCode;
|
import org.carrot2.core.LanguageCode;
|
||||||
import org.carrot2.text.linguistic.IStemmer;
|
import org.carrot2.text.linguistic.IStemmer;
|
||||||
import org.carrot2.text.linguistic.IStemmerFactory;
|
import org.carrot2.text.linguistic.IStemmerFactory;
|
||||||
import org.carrot2.util.ReflectionUtils;
|
import org.carrot2.util.ReflectionUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.tartarus.snowball.SnowballProgram;
|
import org.tartarus.snowball.SnowballProgram;
|
||||||
import org.tartarus.snowball.ext.DanishStemmer;
|
import org.tartarus.snowball.ext.DanishStemmer;
|
||||||
import org.tartarus.snowball.ext.DutchStemmer;
|
import org.tartarus.snowball.ext.DutchStemmer;
|
||||||
import org.tartarus.snowball.ext.EnglishStemmer;
|
import org.tartarus.snowball.ext.EnglishStemmer;
|
||||||
import org.tartarus.snowball.ext.FinnishStemmer;
|
import org.tartarus.snowball.ext.FinnishStemmer;
|
||||||
import org.tartarus.snowball.ext.FrenchStemmer;
|
import org.tartarus.snowball.ext.FrenchStemmer;
|
||||||
import org.tartarus.snowball.ext.GermanStemmer;
|
import org.tartarus.snowball.ext.GermanStemmer;
|
||||||
import org.tartarus.snowball.ext.HungarianStemmer;
|
import org.tartarus.snowball.ext.HungarianStemmer;
|
||||||
import org.tartarus.snowball.ext.ItalianStemmer;
|
import org.tartarus.snowball.ext.ItalianStemmer;
|
||||||
import org.tartarus.snowball.ext.NorwegianStemmer;
|
import org.tartarus.snowball.ext.NorwegianStemmer;
|
||||||
import org.tartarus.snowball.ext.PortugueseStemmer;
|
import org.tartarus.snowball.ext.PortugueseStemmer;
|
||||||
import org.tartarus.snowball.ext.RomanianStemmer;
|
import org.tartarus.snowball.ext.RomanianStemmer;
|
||||||
import org.tartarus.snowball.ext.RussianStemmer;
|
import org.tartarus.snowball.ext.RussianStemmer;
|
||||||
import org.tartarus.snowball.ext.SpanishStemmer;
|
import org.tartarus.snowball.ext.SpanishStemmer;
|
||||||
import org.tartarus.snowball.ext.SwedishStemmer;
|
import org.tartarus.snowball.ext.SwedishStemmer;
|
||||||
import org.tartarus.snowball.ext.TurkishStemmer;
|
import org.tartarus.snowball.ext.TurkishStemmer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An implementation of Carrot2's {@link IStemmerFactory} based on Lucene's
|
* An implementation of Carrot2's {@link IStemmerFactory} based on Lucene's
|
||||||
* APIs. Should the relevant Lucene APIs need to change, the changes can be made
|
* APIs. Should the relevant Lucene APIs need to change, the changes can be made
|
||||||
* in this class.
|
* in this class.
|
||||||
*/
|
*/
|
||||||
public class LuceneCarrot2StemmerFactory implements IStemmerFactory {
|
public class LuceneCarrot2StemmerFactory implements IStemmerFactory {
|
||||||
final static Logger logger = org.slf4j.LoggerFactory
|
final static Logger logger = org.slf4j.LoggerFactory
|
||||||
.getLogger(LuceneCarrot2StemmerFactory.class);
|
.getLogger(LuceneCarrot2StemmerFactory.class);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IStemmer getStemmer(LanguageCode language) {
|
public IStemmer getStemmer(LanguageCode language) {
|
||||||
switch (language) {
|
switch (language) {
|
||||||
case ARABIC:
|
case ARABIC:
|
||||||
return ArabicStemmerFactory.createStemmer();
|
return ArabicStemmerFactory.createStemmer();
|
||||||
|
|
||||||
case CHINESE_SIMPLIFIED:
|
case CHINESE_SIMPLIFIED:
|
||||||
return IdentityStemmer.INSTANCE;
|
return IdentityStemmer.INSTANCE;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/*
|
/*
|
||||||
* For other languages, try to use snowball's stemming.
|
* For other languages, try to use snowball's stemming.
|
||||||
*/
|
*/
|
||||||
return SnowballStemmerFactory.createStemmer(language);
|
return SnowballStemmerFactory.createStemmer(language);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory of {@link IStemmer} implementations from the <code>snowball</code>
|
* Factory of {@link IStemmer} implementations from the <code>snowball</code>
|
||||||
* project.
|
* project.
|
||||||
*/
|
*/
|
||||||
private final static class SnowballStemmerFactory {
|
private final static class SnowballStemmerFactory {
|
||||||
/**
|
/**
|
||||||
* Static hard mapping from language codes to stemmer classes in Snowball.
|
* Static hard mapping from language codes to stemmer classes in Snowball.
|
||||||
* This mapping is not dynamic because we want to keep the possibility to
|
* This mapping is not dynamic because we want to keep the possibility to
|
||||||
* obfuscate these classes.
|
* obfuscate these classes.
|
||||||
*/
|
*/
|
||||||
private static HashMap<LanguageCode, Class<? extends SnowballProgram>> snowballStemmerClasses;
|
private static HashMap<LanguageCode, Class<? extends SnowballProgram>> snowballStemmerClasses;
|
||||||
static {
|
static {
|
||||||
snowballStemmerClasses = new HashMap<LanguageCode, Class<? extends SnowballProgram>>();
|
snowballStemmerClasses = new HashMap<LanguageCode, Class<? extends SnowballProgram>>();
|
||||||
snowballStemmerClasses.put(LanguageCode.DANISH, DanishStemmer.class);
|
snowballStemmerClasses.put(LanguageCode.DANISH, DanishStemmer.class);
|
||||||
snowballStemmerClasses.put(LanguageCode.DUTCH, DutchStemmer.class);
|
snowballStemmerClasses.put(LanguageCode.DUTCH, DutchStemmer.class);
|
||||||
snowballStemmerClasses.put(LanguageCode.ENGLISH, EnglishStemmer.class);
|
snowballStemmerClasses.put(LanguageCode.ENGLISH, EnglishStemmer.class);
|
||||||
snowballStemmerClasses.put(LanguageCode.FINNISH, FinnishStemmer.class);
|
snowballStemmerClasses.put(LanguageCode.FINNISH, FinnishStemmer.class);
|
||||||
snowballStemmerClasses.put(LanguageCode.FRENCH, FrenchStemmer.class);
|
snowballStemmerClasses.put(LanguageCode.FRENCH, FrenchStemmer.class);
|
||||||
snowballStemmerClasses.put(LanguageCode.GERMAN, GermanStemmer.class);
|
snowballStemmerClasses.put(LanguageCode.GERMAN, GermanStemmer.class);
|
||||||
snowballStemmerClasses
|
snowballStemmerClasses
|
||||||
.put(LanguageCode.HUNGARIAN, HungarianStemmer.class);
|
.put(LanguageCode.HUNGARIAN, HungarianStemmer.class);
|
||||||
snowballStemmerClasses.put(LanguageCode.ITALIAN, ItalianStemmer.class);
|
snowballStemmerClasses.put(LanguageCode.ITALIAN, ItalianStemmer.class);
|
||||||
snowballStemmerClasses
|
snowballStemmerClasses
|
||||||
.put(LanguageCode.NORWEGIAN, NorwegianStemmer.class);
|
.put(LanguageCode.NORWEGIAN, NorwegianStemmer.class);
|
||||||
snowballStemmerClasses.put(LanguageCode.PORTUGUESE,
|
snowballStemmerClasses.put(LanguageCode.PORTUGUESE,
|
||||||
PortugueseStemmer.class);
|
PortugueseStemmer.class);
|
||||||
snowballStemmerClasses.put(LanguageCode.ROMANIAN, RomanianStemmer.class);
|
snowballStemmerClasses.put(LanguageCode.ROMANIAN, RomanianStemmer.class);
|
||||||
snowballStemmerClasses.put(LanguageCode.RUSSIAN, RussianStemmer.class);
|
snowballStemmerClasses.put(LanguageCode.RUSSIAN, RussianStemmer.class);
|
||||||
snowballStemmerClasses.put(LanguageCode.SPANISH, SpanishStemmer.class);
|
snowballStemmerClasses.put(LanguageCode.SPANISH, SpanishStemmer.class);
|
||||||
snowballStemmerClasses.put(LanguageCode.SWEDISH, SwedishStemmer.class);
|
snowballStemmerClasses.put(LanguageCode.SWEDISH, SwedishStemmer.class);
|
||||||
snowballStemmerClasses.put(LanguageCode.TURKISH, TurkishStemmer.class);
|
snowballStemmerClasses.put(LanguageCode.TURKISH, TurkishStemmer.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An adapter converting Snowball programs into {@link IStemmer} interface.
|
* An adapter converting Snowball programs into {@link IStemmer} interface.
|
||||||
*/
|
*/
|
||||||
private static class SnowballStemmerAdapter implements IStemmer {
|
private static class SnowballStemmerAdapter implements IStemmer {
|
||||||
private final SnowballProgram snowballStemmer;
|
private final SnowballProgram snowballStemmer;
|
||||||
|
|
||||||
public SnowballStemmerAdapter(SnowballProgram snowballStemmer) {
|
public SnowballStemmerAdapter(SnowballProgram snowballStemmer) {
|
||||||
this.snowballStemmer = snowballStemmer;
|
this.snowballStemmer = snowballStemmer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CharSequence stem(CharSequence word) {
|
public CharSequence stem(CharSequence word) {
|
||||||
snowballStemmer.setCurrent(word.toString());
|
snowballStemmer.setCurrent(word.toString());
|
||||||
if (snowballStemmer.stem()) {
|
if (snowballStemmer.stem()) {
|
||||||
return snowballStemmer.getCurrent();
|
return snowballStemmer.getCurrent();
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create and return an {@link IStemmer} adapter for a
|
* Create and return an {@link IStemmer} adapter for a
|
||||||
* {@link SnowballProgram} for a given language code. An identity stemmer is
|
* {@link SnowballProgram} for a given language code. An identity stemmer is
|
||||||
* returned for unknown languages.
|
* returned for unknown languages.
|
||||||
*/
|
*/
|
||||||
public static IStemmer createStemmer(LanguageCode language) {
|
public static IStemmer createStemmer(LanguageCode language) {
|
||||||
final Class<? extends SnowballProgram> stemmerClazz = snowballStemmerClasses
|
final Class<? extends SnowballProgram> stemmerClazz = snowballStemmerClasses
|
||||||
.get(language);
|
.get(language);
|
||||||
|
|
||||||
if (stemmerClazz == null) {
|
if (stemmerClazz == null) {
|
||||||
logger.warn("No Snowball stemmer class for: " + language.name()
|
logger.warn("No Snowball stemmer class for: " + language.name()
|
||||||
+ ". Quality of clustering may be degraded.");
|
+ ". Quality of clustering may be degraded.");
|
||||||
return IdentityStemmer.INSTANCE;
|
return IdentityStemmer.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return new SnowballStemmerAdapter(stemmerClazz.newInstance());
|
return new SnowballStemmerAdapter(stemmerClazz.newInstance());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.warn("Could not instantiate snowball stemmer"
|
logger.warn("Could not instantiate snowball stemmer"
|
||||||
+ " for language: " + language.name()
|
+ " for language: " + language.name()
|
||||||
+ ". Quality of clustering may be degraded.", e);
|
+ ". Quality of clustering may be degraded.", e);
|
||||||
|
|
||||||
return IdentityStemmer.INSTANCE;
|
return IdentityStemmer.INSTANCE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory of {@link IStemmer} implementations for the
|
* Factory of {@link IStemmer} implementations for the
|
||||||
* {@link LanguageCode#ARABIC} language. Requires <code>lucene-contrib</code>
|
* {@link LanguageCode#ARABIC} language. Requires <code>lucene-contrib</code>
|
||||||
* to be present in classpath, otherwise an empty (identity) stemmer is
|
* to be present in classpath, otherwise an empty (identity) stemmer is
|
||||||
* returned.
|
* returned.
|
||||||
*/
|
*/
|
||||||
private static class ArabicStemmerFactory {
|
private static class ArabicStemmerFactory {
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
ReflectionUtils.classForName(ArabicStemmer.class.getName(), false);
|
ReflectionUtils.classForName(ArabicStemmer.class.getName(), false);
|
||||||
ReflectionUtils.classForName(ArabicNormalizer.class.getName(), false);
|
ReflectionUtils.classForName(ArabicNormalizer.class.getName(), false);
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
logger
|
logger
|
||||||
.warn(
|
.warn(
|
||||||
"Could not instantiate Lucene stemmer for Arabic, clustering quality "
|
"Could not instantiate Lucene stemmer for Arabic, clustering quality "
|
||||||
+ "of Arabic content may be degraded. For best quality clusters, "
|
+ "of Arabic content may be degraded. For best quality clusters, "
|
||||||
+ "make sure Lucene's Arabic analyzer JAR is in the classpath",
|
+ "make sure Lucene's Arabic analyzer JAR is in the classpath",
|
||||||
e);
|
e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adapter to lucene-contrib Arabic analyzers.
|
* Adapter to lucene-contrib Arabic analyzers.
|
||||||
*/
|
*/
|
||||||
private static class LuceneStemmerAdapter implements IStemmer {
|
private static class LuceneStemmerAdapter implements IStemmer {
|
||||||
private final org.apache.lucene.analysis.ar.ArabicStemmer delegate;
|
private final org.apache.lucene.analysis.ar.ArabicStemmer delegate;
|
||||||
private final org.apache.lucene.analysis.ar.ArabicNormalizer normalizer;
|
private final org.apache.lucene.analysis.ar.ArabicNormalizer normalizer;
|
||||||
|
|
||||||
private char[] buffer = new char[0];
|
private char[] buffer = new char[0];
|
||||||
|
|
||||||
private LuceneStemmerAdapter() throws Exception {
|
private LuceneStemmerAdapter() throws Exception {
|
||||||
delegate = new org.apache.lucene.analysis.ar.ArabicStemmer();
|
delegate = new org.apache.lucene.analysis.ar.ArabicStemmer();
|
||||||
normalizer = new org.apache.lucene.analysis.ar.ArabicNormalizer();
|
normalizer = new org.apache.lucene.analysis.ar.ArabicNormalizer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public CharSequence stem(CharSequence word) {
|
public CharSequence stem(CharSequence word) {
|
||||||
if (word.length() > buffer.length) {
|
if (word.length() > buffer.length) {
|
||||||
buffer = new char[word.length()];
|
buffer = new char[word.length()];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < word.length(); i++) {
|
for (int i = 0; i < word.length(); i++) {
|
||||||
buffer[i] = word.charAt(i);
|
buffer[i] = word.charAt(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
int newLen = normalizer.normalize(buffer, word.length());
|
int newLen = normalizer.normalize(buffer, word.length());
|
||||||
newLen = delegate.stem(buffer, newLen);
|
newLen = delegate.stem(buffer, newLen);
|
||||||
|
|
||||||
if (newLen != word.length() || !equals(buffer, newLen, word)) {
|
if (newLen != word.length() || !equals(buffer, newLen, word)) {
|
||||||
return CharBuffer.wrap(buffer, 0, newLen);
|
return CharBuffer.wrap(buffer, 0, newLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Same-same.
|
// Same-same.
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean equals(char[] buffer, int len, CharSequence word) {
|
private boolean equals(char[] buffer, int len, CharSequence word) {
|
||||||
assert len == word.length();
|
assert len == word.length();
|
||||||
|
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
if (buffer[i] != word.charAt(i))
|
if (buffer[i] != word.charAt(i))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IStemmer createStemmer() {
|
public static IStemmer createStemmer() {
|
||||||
try {
|
try {
|
||||||
return new LuceneStemmerAdapter();
|
return new LuceneStemmerAdapter();
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
return IdentityStemmer.INSTANCE;
|
return IdentityStemmer.INSTANCE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An implementation of {@link IStemmer} that always returns <code>null</code>
|
* An implementation of {@link IStemmer} that always returns <code>null</code>
|
||||||
* which means no stemming.
|
* which means no stemming.
|
||||||
*/
|
*/
|
||||||
private static class IdentityStemmer implements IStemmer {
|
private static class IdentityStemmer implements IStemmer {
|
||||||
private final static IdentityStemmer INSTANCE = new IdentityStemmer();
|
private final static IdentityStemmer INSTANCE = new IdentityStemmer();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CharSequence stem(CharSequence word) {
|
public CharSequence stem(CharSequence word) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,156 +1,156 @@
|
||||||
package org.apache.solr.handler.clustering.carrot2;
|
package org.apache.solr.handler.clustering.carrot2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
* this work for additional information regarding copyright ownership.
|
* this work for additional information regarding copyright ownership.
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
* 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 not use this file except in compliance with
|
||||||
* the License. You may obtain a copy of the License at
|
* the License. You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.apache.lucene.analysis.TokenStream;
|
import org.apache.lucene.analysis.TokenStream;
|
||||||
import org.apache.lucene.analysis.Tokenizer;
|
import org.apache.lucene.analysis.Tokenizer;
|
||||||
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
|
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
|
||||||
import org.carrot2.core.LanguageCode;
|
import org.carrot2.core.LanguageCode;
|
||||||
import org.carrot2.text.analysis.ExtendedWhitespaceTokenizer;
|
import org.carrot2.text.analysis.ExtendedWhitespaceTokenizer;
|
||||||
import org.carrot2.text.analysis.ITokenizer;
|
import org.carrot2.text.analysis.ITokenizer;
|
||||||
import org.carrot2.text.linguistic.ITokenizerFactory;
|
import org.carrot2.text.linguistic.ITokenizerFactory;
|
||||||
import org.carrot2.text.util.MutableCharArray;
|
import org.carrot2.text.util.MutableCharArray;
|
||||||
import org.carrot2.util.ExceptionUtils;
|
import org.carrot2.util.ExceptionUtils;
|
||||||
import org.carrot2.util.ReflectionUtils;
|
import org.carrot2.util.ReflectionUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An implementation of Carrot2's {@link ITokenizerFactory} based on Lucene's
|
* An implementation of Carrot2's {@link ITokenizerFactory} based on Lucene's
|
||||||
* Smart Chinese tokenizer. If Smart Chinese tokenizer is not available in
|
* Smart Chinese tokenizer. If Smart Chinese tokenizer is not available in
|
||||||
* classpath at runtime, the default Carrot2's tokenizer is used. Should the
|
* classpath at runtime, the default Carrot2's tokenizer is used. Should the
|
||||||
* Lucene APIs need to change, the changes can be made in this class.
|
* Lucene APIs need to change, the changes can be made in this class.
|
||||||
*/
|
*/
|
||||||
public class LuceneCarrot2TokenizerFactory implements ITokenizerFactory {
|
public class LuceneCarrot2TokenizerFactory implements ITokenizerFactory {
|
||||||
final static Logger logger = org.slf4j.LoggerFactory
|
final static Logger logger = org.slf4j.LoggerFactory
|
||||||
.getLogger(LuceneCarrot2TokenizerFactory.class);
|
.getLogger(LuceneCarrot2TokenizerFactory.class);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ITokenizer getTokenizer(LanguageCode language) {
|
public ITokenizer getTokenizer(LanguageCode language) {
|
||||||
switch (language) {
|
switch (language) {
|
||||||
case CHINESE_SIMPLIFIED:
|
case CHINESE_SIMPLIFIED:
|
||||||
return ChineseTokenizerFactory.createTokenizer();
|
return ChineseTokenizerFactory.createTokenizer();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We use our own analyzer for Arabic. Lucene's version has special
|
* We use our own analyzer for Arabic. Lucene's version has special
|
||||||
* support for Nonspacing-Mark characters (see
|
* support for Nonspacing-Mark characters (see
|
||||||
* http://www.fileformat.info/info/unicode/category/Mn/index.htm), but we
|
* http://www.fileformat.info/info/unicode/category/Mn/index.htm), but we
|
||||||
* have them included as letters in the parser.
|
* have them included as letters in the parser.
|
||||||
*/
|
*/
|
||||||
case ARABIC:
|
case ARABIC:
|
||||||
// Intentional fall-through.
|
// Intentional fall-through.
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return new ExtendedWhitespaceTokenizer();
|
return new ExtendedWhitespaceTokenizer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates tokenizers that adapt Lucene's Smart Chinese Tokenizer to Carrot2's
|
* Creates tokenizers that adapt Lucene's Smart Chinese Tokenizer to Carrot2's
|
||||||
* {@link ITokenizer}. If Smart Chinese is not available in the classpath, the
|
* {@link ITokenizer}. If Smart Chinese is not available in the classpath, the
|
||||||
* factory will fall back to the default white space tokenizer.
|
* factory will fall back to the default white space tokenizer.
|
||||||
*/
|
*/
|
||||||
private static final class ChineseTokenizerFactory {
|
private static final class ChineseTokenizerFactory {
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
ReflectionUtils.classForName(
|
ReflectionUtils.classForName(
|
||||||
"org.apache.lucene.analysis.cn.smart.WordTokenFilter", false);
|
"org.apache.lucene.analysis.cn.smart.WordTokenFilter", false);
|
||||||
ReflectionUtils.classForName(
|
ReflectionUtils.classForName(
|
||||||
"org.apache.lucene.analysis.cn.smart.SentenceTokenizer", false);
|
"org.apache.lucene.analysis.cn.smart.SentenceTokenizer", false);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
logger
|
logger
|
||||||
.warn("Could not instantiate Smart Chinese Analyzer, clustering quality "
|
.warn("Could not instantiate Smart Chinese Analyzer, clustering quality "
|
||||||
+ "of Chinese content may be degraded. For best quality clusters, "
|
+ "of Chinese content may be degraded. For best quality clusters, "
|
||||||
+ "make sure Lucene's Smart Chinese Analyzer JAR is in the classpath");
|
+ "make sure Lucene's Smart Chinese Analyzer JAR is in the classpath");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static ITokenizer createTokenizer() {
|
static ITokenizer createTokenizer() {
|
||||||
try {
|
try {
|
||||||
return new ChineseTokenizer();
|
return new ChineseTokenizer();
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
return new ExtendedWhitespaceTokenizer();
|
return new ExtendedWhitespaceTokenizer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final static class ChineseTokenizer implements ITokenizer {
|
private final static class ChineseTokenizer implements ITokenizer {
|
||||||
private final static Pattern numeric = Pattern
|
private final static Pattern numeric = Pattern
|
||||||
.compile("[\\-+'$]?\\d+([:\\-/,.]?\\d+)*[%$]?");
|
.compile("[\\-+'$]?\\d+([:\\-/,.]?\\d+)*[%$]?");
|
||||||
|
|
||||||
private Tokenizer sentenceTokenizer;
|
private Tokenizer sentenceTokenizer;
|
||||||
private TokenStream wordTokenFilter;
|
private TokenStream wordTokenFilter;
|
||||||
private CharTermAttribute term = null;
|
private CharTermAttribute term = null;
|
||||||
|
|
||||||
private final MutableCharArray tempCharSequence;
|
private final MutableCharArray tempCharSequence;
|
||||||
private final Class<?> tokenFilterClass;
|
private final Class<?> tokenFilterClass;
|
||||||
|
|
||||||
private ChineseTokenizer() throws Exception {
|
private ChineseTokenizer() throws Exception {
|
||||||
this.tempCharSequence = new MutableCharArray(new char[0]);
|
this.tempCharSequence = new MutableCharArray(new char[0]);
|
||||||
|
|
||||||
// As Smart Chinese is not available during compile time,
|
// As Smart Chinese is not available during compile time,
|
||||||
// we need to resort to reflection.
|
// we need to resort to reflection.
|
||||||
final Class<?> tokenizerClass = ReflectionUtils.classForName(
|
final Class<?> tokenizerClass = ReflectionUtils.classForName(
|
||||||
"org.apache.lucene.analysis.cn.smart.SentenceTokenizer", false);
|
"org.apache.lucene.analysis.cn.smart.SentenceTokenizer", false);
|
||||||
this.sentenceTokenizer = (Tokenizer) tokenizerClass.getConstructor(
|
this.sentenceTokenizer = (Tokenizer) tokenizerClass.getConstructor(
|
||||||
Reader.class).newInstance((Reader) null);
|
Reader.class).newInstance((Reader) null);
|
||||||
this.tokenFilterClass = ReflectionUtils.classForName(
|
this.tokenFilterClass = ReflectionUtils.classForName(
|
||||||
"org.apache.lucene.analysis.cn.smart.WordTokenFilter", false);
|
"org.apache.lucene.analysis.cn.smart.WordTokenFilter", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public short nextToken() throws IOException {
|
public short nextToken() throws IOException {
|
||||||
final boolean hasNextToken = wordTokenFilter.incrementToken();
|
final boolean hasNextToken = wordTokenFilter.incrementToken();
|
||||||
if (hasNextToken) {
|
if (hasNextToken) {
|
||||||
short flags = 0;
|
short flags = 0;
|
||||||
final char[] image = term.buffer();
|
final char[] image = term.buffer();
|
||||||
final int length = term.length();
|
final int length = term.length();
|
||||||
tempCharSequence.reset(image, 0, length);
|
tempCharSequence.reset(image, 0, length);
|
||||||
if (length == 1 && image[0] == ',') {
|
if (length == 1 && image[0] == ',') {
|
||||||
// ChineseTokenizer seems to convert all punctuation to ','
|
// ChineseTokenizer seems to convert all punctuation to ','
|
||||||
// characters
|
// characters
|
||||||
flags = ITokenizer.TT_PUNCTUATION;
|
flags = ITokenizer.TT_PUNCTUATION;
|
||||||
} else if (numeric.matcher(tempCharSequence).matches()) {
|
} else if (numeric.matcher(tempCharSequence).matches()) {
|
||||||
flags = ITokenizer.TT_NUMERIC;
|
flags = ITokenizer.TT_NUMERIC;
|
||||||
} else {
|
} else {
|
||||||
flags = ITokenizer.TT_TERM;
|
flags = ITokenizer.TT_TERM;
|
||||||
}
|
}
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ITokenizer.TT_EOF;
|
return ITokenizer.TT_EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTermBuffer(MutableCharArray array) {
|
public void setTermBuffer(MutableCharArray array) {
|
||||||
array.reset(term.buffer(), 0, term.length());
|
array.reset(term.buffer(), 0, term.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reset(Reader input) throws IOException {
|
public void reset(Reader input) throws IOException {
|
||||||
try {
|
try {
|
||||||
sentenceTokenizer.reset(input);
|
sentenceTokenizer.reset(input);
|
||||||
wordTokenFilter = (TokenStream) tokenFilterClass.getConstructor(
|
wordTokenFilter = (TokenStream) tokenFilterClass.getConstructor(
|
||||||
TokenStream.class).newInstance(sentenceTokenizer);
|
TokenStream.class).newInstance(sentenceTokenizer);
|
||||||
term = wordTokenFilter.addAttribute(CharTermAttribute.class);
|
term = wordTokenFilter.addAttribute(CharTermAttribute.class);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw ExceptionUtils.wrapAsRuntimeException(e);
|
throw ExceptionUtils.wrapAsRuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,140 +1,140 @@
|
||||||
package org.apache.solr.handler.clustering.carrot2;
|
package org.apache.solr.handler.clustering.carrot2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
* this work for additional information regarding copyright ownership.
|
* this work for additional information regarding copyright ownership.
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
* 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 not use this file except in compliance with
|
||||||
* the License. You may obtain a copy of the License at
|
* the License. You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.apache.lucene.analysis.Analyzer;
|
import org.apache.lucene.analysis.Analyzer;
|
||||||
import org.apache.lucene.analysis.util.CharArraySet;
|
import org.apache.lucene.analysis.util.CharArraySet;
|
||||||
import org.apache.solr.analysis.CommonGramsFilterFactory;
|
import org.apache.solr.analysis.CommonGramsFilterFactory;
|
||||||
import org.apache.solr.analysis.StopFilterFactory;
|
import org.apache.solr.analysis.StopFilterFactory;
|
||||||
import org.apache.solr.analysis.TokenFilterFactory;
|
import org.apache.solr.analysis.TokenFilterFactory;
|
||||||
import org.apache.solr.analysis.TokenizerChain;
|
import org.apache.solr.analysis.TokenizerChain;
|
||||||
import org.apache.solr.schema.IndexSchema;
|
import org.apache.solr.schema.IndexSchema;
|
||||||
import org.carrot2.core.LanguageCode;
|
import org.carrot2.core.LanguageCode;
|
||||||
import org.carrot2.core.attribute.Init;
|
import org.carrot2.core.attribute.Init;
|
||||||
import org.carrot2.core.attribute.Processing;
|
import org.carrot2.core.attribute.Processing;
|
||||||
import org.carrot2.text.linguistic.DefaultLexicalDataFactory;
|
import org.carrot2.text.linguistic.DefaultLexicalDataFactory;
|
||||||
import org.carrot2.text.linguistic.ILexicalData;
|
import org.carrot2.text.linguistic.ILexicalData;
|
||||||
import org.carrot2.text.linguistic.ILexicalDataFactory;
|
import org.carrot2.text.linguistic.ILexicalDataFactory;
|
||||||
import org.carrot2.text.util.MutableCharArray;
|
import org.carrot2.text.util.MutableCharArray;
|
||||||
import org.carrot2.util.attribute.Attribute;
|
import org.carrot2.util.attribute.Attribute;
|
||||||
import org.carrot2.util.attribute.Bindable;
|
import org.carrot2.util.attribute.Bindable;
|
||||||
import org.carrot2.util.attribute.Input;
|
import org.carrot2.util.attribute.Input;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
import com.google.common.collect.HashMultimap;
|
import com.google.common.collect.HashMultimap;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An implementation of Carrot2's {@link ILexicalDataFactory} that adds stop
|
* An implementation of Carrot2's {@link ILexicalDataFactory} that adds stop
|
||||||
* words from a field's StopFilter to the default stop words used in Carrot2,
|
* words from a field's StopFilter to the default stop words used in Carrot2,
|
||||||
* for all languages Carrot2 supports. Completely replacing Carrot2 stop words
|
* for all languages Carrot2 supports. Completely replacing Carrot2 stop words
|
||||||
* with Solr's wouldn't make much sense because clustering needs more aggressive
|
* with Solr's wouldn't make much sense because clustering needs more aggressive
|
||||||
* stop words removal. In other words, if something is a stop word during
|
* stop words removal. In other words, if something is a stop word during
|
||||||
* indexing, then it should also be a stop word during clustering, but not the
|
* indexing, then it should also be a stop word during clustering, but not the
|
||||||
* other way round.
|
* other way round.
|
||||||
*/
|
*/
|
||||||
@Bindable
|
@Bindable
|
||||||
public class SolrStopwordsCarrot2LexicalDataFactory implements
|
public class SolrStopwordsCarrot2LexicalDataFactory implements
|
||||||
ILexicalDataFactory {
|
ILexicalDataFactory {
|
||||||
final static Logger logger = org.slf4j.LoggerFactory
|
final static Logger logger = org.slf4j.LoggerFactory
|
||||||
.getLogger(SolrStopwordsCarrot2LexicalDataFactory.class);
|
.getLogger(SolrStopwordsCarrot2LexicalDataFactory.class);
|
||||||
|
|
||||||
@Init
|
@Init
|
||||||
@Input
|
@Input
|
||||||
@Attribute(key = "solrIndexSchema")
|
@Attribute(key = "solrIndexSchema")
|
||||||
private IndexSchema schema;
|
private IndexSchema schema;
|
||||||
|
|
||||||
@Processing
|
@Processing
|
||||||
@Input
|
@Input
|
||||||
@Attribute(key = "solrFieldNames")
|
@Attribute(key = "solrFieldNames")
|
||||||
private Set<String> fieldNames;
|
private Set<String> fieldNames;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A lazily-built cache of stop words per field.
|
* A lazily-built cache of stop words per field.
|
||||||
*/
|
*/
|
||||||
private Multimap<String, CharArraySet> solrStopWords = HashMultimap.create();
|
private Multimap<String, CharArraySet> solrStopWords = HashMultimap.create();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Carrot2's default lexical resources to use in addition to Solr's stop
|
* Carrot2's default lexical resources to use in addition to Solr's stop
|
||||||
* words.
|
* words.
|
||||||
*/
|
*/
|
||||||
private DefaultLexicalDataFactory carrot2LexicalDataFactory = new DefaultLexicalDataFactory();
|
private DefaultLexicalDataFactory carrot2LexicalDataFactory = new DefaultLexicalDataFactory();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtains stop words for a field from the associated
|
* Obtains stop words for a field from the associated
|
||||||
* {@link StopFilterFactory}, if any.
|
* {@link StopFilterFactory}, if any.
|
||||||
*/
|
*/
|
||||||
private Collection<CharArraySet> getSolrStopWordsForField(String fieldName) {
|
private Collection<CharArraySet> getSolrStopWordsForField(String fieldName) {
|
||||||
// No need to synchronize here, Carrot2 ensures that instances
|
// No need to synchronize here, Carrot2 ensures that instances
|
||||||
// of this class are not used by multiple threads at a time.
|
// of this class are not used by multiple threads at a time.
|
||||||
if (!solrStopWords.containsKey(fieldName)) {
|
if (!solrStopWords.containsKey(fieldName)) {
|
||||||
final Analyzer fieldAnalyzer = schema.getFieldType(fieldName)
|
final Analyzer fieldAnalyzer = schema.getFieldType(fieldName)
|
||||||
.getAnalyzer();
|
.getAnalyzer();
|
||||||
if (fieldAnalyzer instanceof TokenizerChain) {
|
if (fieldAnalyzer instanceof TokenizerChain) {
|
||||||
final TokenFilterFactory[] filterFactories = ((TokenizerChain) fieldAnalyzer)
|
final TokenFilterFactory[] filterFactories = ((TokenizerChain) fieldAnalyzer)
|
||||||
.getTokenFilterFactories();
|
.getTokenFilterFactories();
|
||||||
for (TokenFilterFactory factory : filterFactories) {
|
for (TokenFilterFactory factory : filterFactories) {
|
||||||
if (factory instanceof StopFilterFactory) {
|
if (factory instanceof StopFilterFactory) {
|
||||||
// StopFilterFactory holds the stop words in a CharArraySet
|
// StopFilterFactory holds the stop words in a CharArraySet
|
||||||
solrStopWords.put(fieldName,
|
solrStopWords.put(fieldName,
|
||||||
((StopFilterFactory) factory).getStopWords());
|
((StopFilterFactory) factory).getStopWords());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (factory instanceof CommonGramsFilterFactory) {
|
if (factory instanceof CommonGramsFilterFactory) {
|
||||||
solrStopWords.put(fieldName,
|
solrStopWords.put(fieldName,
|
||||||
((CommonGramsFilterFactory) factory)
|
((CommonGramsFilterFactory) factory)
|
||||||
.getCommonWords());
|
.getCommonWords());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return solrStopWords.get(fieldName);
|
return solrStopWords.get(fieldName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ILexicalData getLexicalData(LanguageCode languageCode) {
|
public ILexicalData getLexicalData(LanguageCode languageCode) {
|
||||||
final ILexicalData carrot2LexicalData = carrot2LexicalDataFactory
|
final ILexicalData carrot2LexicalData = carrot2LexicalDataFactory
|
||||||
.getLexicalData(languageCode);
|
.getLexicalData(languageCode);
|
||||||
|
|
||||||
return new ILexicalData() {
|
return new ILexicalData() {
|
||||||
@Override
|
@Override
|
||||||
public boolean isStopLabel(CharSequence word) {
|
public boolean isStopLabel(CharSequence word) {
|
||||||
// Nothing in Solr maps to the concept of a stop label,
|
// Nothing in Solr maps to the concept of a stop label,
|
||||||
// so return Carrot2's default here.
|
// so return Carrot2's default here.
|
||||||
return carrot2LexicalData.isStopLabel(word);
|
return carrot2LexicalData.isStopLabel(word);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCommonWord(MutableCharArray word) {
|
public boolean isCommonWord(MutableCharArray word) {
|
||||||
// Loop over the fields involved in clustering first
|
// Loop over the fields involved in clustering first
|
||||||
for (String fieldName : fieldNames) {
|
for (String fieldName : fieldNames) {
|
||||||
for (CharArraySet stopWords : getSolrStopWordsForField(fieldName)) {
|
for (CharArraySet stopWords : getSolrStopWordsForField(fieldName)) {
|
||||||
if (stopWords.contains(word)) {
|
if (stopWords.contains(word)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Check default Carrot2 stop words too
|
// Check default Carrot2 stop words too
|
||||||
return carrot2LexicalData.isCommonWord(word);
|
return carrot2LexicalData.isCommonWord(word);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,78 +1,78 @@
|
||||||
package org.apache.solr.handler.clustering.carrot2;
|
package org.apache.solr.handler.clustering.carrot2;
|
||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
* this work for additional information regarding copyright ownership.
|
* this work for additional information regarding copyright ownership.
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
* 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 not use this file except in compliance with
|
||||||
* the License. You may obtain a copy of the License at
|
* the License. You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.carrot2.core.Cluster;
|
import org.carrot2.core.Cluster;
|
||||||
import org.carrot2.core.Document;
|
import org.carrot2.core.Document;
|
||||||
import org.carrot2.core.IClusteringAlgorithm;
|
import org.carrot2.core.IClusteringAlgorithm;
|
||||||
import org.carrot2.core.ProcessingComponentBase;
|
import org.carrot2.core.ProcessingComponentBase;
|
||||||
import org.carrot2.core.ProcessingException;
|
import org.carrot2.core.ProcessingException;
|
||||||
import org.carrot2.core.attribute.AttributeNames;
|
import org.carrot2.core.attribute.AttributeNames;
|
||||||
import org.carrot2.core.attribute.Processing;
|
import org.carrot2.core.attribute.Processing;
|
||||||
import org.carrot2.util.attribute.Attribute;
|
import org.carrot2.util.attribute.Attribute;
|
||||||
import org.carrot2.util.attribute.Bindable;
|
import org.carrot2.util.attribute.Bindable;
|
||||||
import org.carrot2.util.attribute.Input;
|
import org.carrot2.util.attribute.Input;
|
||||||
import org.carrot2.util.attribute.Output;
|
import org.carrot2.util.attribute.Output;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A mock Carrot2 clustering algorithm that outputs input documents as clusters.
|
* A mock Carrot2 clustering algorithm that outputs input documents as clusters.
|
||||||
* Useful only in tests.
|
* Useful only in tests.
|
||||||
*/
|
*/
|
||||||
@Bindable(prefix = "EchoClusteringAlgorithm")
|
@Bindable(prefix = "EchoClusteringAlgorithm")
|
||||||
public class EchoClusteringAlgorithm extends ProcessingComponentBase implements
|
public class EchoClusteringAlgorithm extends ProcessingComponentBase implements
|
||||||
IClusteringAlgorithm {
|
IClusteringAlgorithm {
|
||||||
@Input
|
@Input
|
||||||
@Processing
|
@Processing
|
||||||
@Attribute(key = AttributeNames.DOCUMENTS)
|
@Attribute(key = AttributeNames.DOCUMENTS)
|
||||||
private List<Document> documents;
|
private List<Document> documents;
|
||||||
|
|
||||||
@Output
|
@Output
|
||||||
@Processing
|
@Processing
|
||||||
@Attribute(key = AttributeNames.CLUSTERS)
|
@Attribute(key = AttributeNames.CLUSTERS)
|
||||||
private List<Cluster> clusters;
|
private List<Cluster> clusters;
|
||||||
|
|
||||||
@Input
|
@Input
|
||||||
@Processing
|
@Processing
|
||||||
@Attribute(key = "custom-fields")
|
@Attribute(key = "custom-fields")
|
||||||
private String customFields = "";
|
private String customFields = "";
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process() throws ProcessingException {
|
public void process() throws ProcessingException {
|
||||||
clusters = Lists.newArrayListWithCapacity(documents.size());
|
clusters = Lists.newArrayListWithCapacity(documents.size());
|
||||||
|
|
||||||
for (Document document : documents) {
|
for (Document document : documents) {
|
||||||
final Cluster cluster = new Cluster();
|
final Cluster cluster = new Cluster();
|
||||||
cluster.addPhrases(document.getTitle(), document.getSummary());
|
cluster.addPhrases(document.getTitle(), document.getSummary());
|
||||||
if (document.getLanguage() != null) {
|
if (document.getLanguage() != null) {
|
||||||
cluster.addPhrases(document.getLanguage().name());
|
cluster.addPhrases(document.getLanguage().name());
|
||||||
}
|
}
|
||||||
for (String field : customFields.split(",")) {
|
for (String field : customFields.split(",")) {
|
||||||
Object value = document.getField(field);
|
Object value = document.getField(field);
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
cluster.addPhrases(value.toString());
|
cluster.addPhrases(value.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cluster.addDocuments(document);
|
cluster.addDocuments(document);
|
||||||
clusters.add(cluster);
|
clusters.add(cluster);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,80 +1,80 @@
|
||||||
package org.apache.solr.handler.clustering.carrot2;
|
package org.apache.solr.handler.clustering.carrot2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
* this work for additional information regarding copyright ownership.
|
* this work for additional information regarding copyright ownership.
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
* 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 not use this file except in compliance with
|
||||||
* the License. You may obtain a copy of the License at
|
* the License. You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.carrot2.core.Cluster;
|
import org.carrot2.core.Cluster;
|
||||||
import org.carrot2.core.IClusteringAlgorithm;
|
import org.carrot2.core.IClusteringAlgorithm;
|
||||||
import org.carrot2.core.LanguageCode;
|
import org.carrot2.core.LanguageCode;
|
||||||
import org.carrot2.core.ProcessingComponentBase;
|
import org.carrot2.core.ProcessingComponentBase;
|
||||||
import org.carrot2.core.ProcessingException;
|
import org.carrot2.core.ProcessingException;
|
||||||
import org.carrot2.core.attribute.AttributeNames;
|
import org.carrot2.core.attribute.AttributeNames;
|
||||||
import org.carrot2.core.attribute.Processing;
|
import org.carrot2.core.attribute.Processing;
|
||||||
import org.carrot2.text.linguistic.ILexicalData;
|
import org.carrot2.text.linguistic.ILexicalData;
|
||||||
import org.carrot2.text.preprocessing.pipeline.BasicPreprocessingPipeline;
|
import org.carrot2.text.preprocessing.pipeline.BasicPreprocessingPipeline;
|
||||||
import org.carrot2.text.util.MutableCharArray;
|
import org.carrot2.text.util.MutableCharArray;
|
||||||
import org.carrot2.util.attribute.Attribute;
|
import org.carrot2.util.attribute.Attribute;
|
||||||
import org.carrot2.util.attribute.Bindable;
|
import org.carrot2.util.attribute.Bindable;
|
||||||
import org.carrot2.util.attribute.Input;
|
import org.carrot2.util.attribute.Input;
|
||||||
import org.carrot2.util.attribute.Output;
|
import org.carrot2.util.attribute.Output;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A mock implementation of Carrot2 clustering algorithm for testing whether the
|
* A mock implementation of Carrot2 clustering algorithm for testing whether the
|
||||||
* customized lexical resource lookup works correctly. This algorithm ignores
|
* customized lexical resource lookup works correctly. This algorithm ignores
|
||||||
* the input documents and instead for each word from {@link #wordsToCheck}, it
|
* the input documents and instead for each word from {@link #wordsToCheck}, it
|
||||||
* outputs a cluster labeled with the word only if the word is neither a stop
|
* outputs a cluster labeled with the word only if the word is neither a stop
|
||||||
* word nor a stop label.
|
* word nor a stop label.
|
||||||
*/
|
*/
|
||||||
@Bindable(prefix = "LexicalResourcesCheckClusteringAlgorithm")
|
@Bindable(prefix = "LexicalResourcesCheckClusteringAlgorithm")
|
||||||
public class LexicalResourcesCheckClusteringAlgorithm extends
|
public class LexicalResourcesCheckClusteringAlgorithm extends
|
||||||
ProcessingComponentBase implements IClusteringAlgorithm {
|
ProcessingComponentBase implements IClusteringAlgorithm {
|
||||||
|
|
||||||
@Output
|
@Output
|
||||||
@Processing
|
@Processing
|
||||||
@Attribute(key = AttributeNames.CLUSTERS)
|
@Attribute(key = AttributeNames.CLUSTERS)
|
||||||
private List<Cluster> clusters;
|
private List<Cluster> clusters;
|
||||||
|
|
||||||
@Input
|
@Input
|
||||||
@Processing
|
@Processing
|
||||||
@Attribute
|
@Attribute
|
||||||
private String wordsToCheck;
|
private String wordsToCheck;
|
||||||
|
|
||||||
private BasicPreprocessingPipeline preprocessing = new BasicPreprocessingPipeline();
|
private BasicPreprocessingPipeline preprocessing = new BasicPreprocessingPipeline();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process() throws ProcessingException {
|
public void process() throws ProcessingException {
|
||||||
clusters = Lists.newArrayList();
|
clusters = Lists.newArrayList();
|
||||||
if (wordsToCheck == null) {
|
if (wordsToCheck == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test with Maltese so that the English clustering performed in other tests
|
// Test with Maltese so that the English clustering performed in other tests
|
||||||
// is not affected by the test stopwords and stoplabels.
|
// is not affected by the test stopwords and stoplabels.
|
||||||
ILexicalData lexicalData = preprocessing.lexicalDataFactory
|
ILexicalData lexicalData = preprocessing.lexicalDataFactory
|
||||||
.getLexicalData(LanguageCode.MALTESE);
|
.getLexicalData(LanguageCode.MALTESE);
|
||||||
|
|
||||||
for (String word : wordsToCheck.split(",")) {
|
for (String word : wordsToCheck.split(",")) {
|
||||||
if (!lexicalData.isCommonWord(new MutableCharArray(word))
|
if (!lexicalData.isCommonWord(new MutableCharArray(word))
|
||||||
&& !lexicalData.isStopLabel(word)) {
|
&& !lexicalData.isStopLabel(word)) {
|
||||||
clusters.add(new Cluster(word));
|
clusters.add(new Cluster(word));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<html>
|
<html>
|
||||||
<body>
|
<body>
|
||||||
Apache Solr Search Server: Solr Language Identifier contrib
|
Apache Solr Search Server: Solr Language Identifier contrib
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<html>
|
<html>
|
||||||
<body>
|
<body>
|
||||||
Apache Solr Search Server: Velocity Response Writer contrib
|
Apache Solr Search Server: Velocity Response Writer contrib
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,184 +1,184 @@
|
||||||
package org.apache.solr.handler.component;
|
package org.apache.solr.handler.component;
|
||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
* this work for additional information regarding copyright ownership.
|
* this work for additional information regarding copyright ownership.
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
* 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 not use this file except in compliance with
|
||||||
* the License. You may obtain a copy of the License at
|
* the License. You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
|
import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
|
||||||
import org.apache.commons.httpclient.HttpClient;
|
import org.apache.commons.httpclient.HttpClient;
|
||||||
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
|
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
|
||||||
import org.apache.commons.httpclient.params.HttpMethodParams;
|
import org.apache.commons.httpclient.params.HttpMethodParams;
|
||||||
import org.apache.solr.client.solrj.impl.LBHttpSolrServer;
|
import org.apache.solr.client.solrj.impl.LBHttpSolrServer;
|
||||||
import org.apache.solr.common.SolrException;
|
import org.apache.solr.common.SolrException;
|
||||||
import org.apache.solr.common.util.NamedList;
|
import org.apache.solr.common.util.NamedList;
|
||||||
import org.apache.solr.core.PluginInfo;
|
import org.apache.solr.core.PluginInfo;
|
||||||
import org.apache.solr.util.DefaultSolrThreadFactory;
|
import org.apache.solr.util.DefaultSolrThreadFactory;
|
||||||
import org.apache.solr.util.plugin.PluginInfoInitialized;
|
import org.apache.solr.util.plugin.PluginInfoInitialized;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
public class HttpShardHandlerFactory extends ShardHandlerFactory implements PluginInfoInitialized {
|
public class HttpShardHandlerFactory extends ShardHandlerFactory implements PluginInfoInitialized {
|
||||||
protected static Logger log = LoggerFactory.getLogger(HttpShardHandlerFactory.class);
|
protected static Logger log = LoggerFactory.getLogger(HttpShardHandlerFactory.class);
|
||||||
|
|
||||||
// We want an executor that doesn't take up any resources if
|
// We want an executor that doesn't take up any resources if
|
||||||
// it's not used, so it could be created statically for
|
// it's not used, so it could be created statically for
|
||||||
// the distributed search component if desired.
|
// the distributed search component if desired.
|
||||||
//
|
//
|
||||||
// Consider CallerRuns policy and a lower max threads to throttle
|
// Consider CallerRuns policy and a lower max threads to throttle
|
||||||
// requests at some point (or should we simply return failure?)
|
// requests at some point (or should we simply return failure?)
|
||||||
ThreadPoolExecutor commExecutor = new ThreadPoolExecutor(
|
ThreadPoolExecutor commExecutor = new ThreadPoolExecutor(
|
||||||
0,
|
0,
|
||||||
Integer.MAX_VALUE,
|
Integer.MAX_VALUE,
|
||||||
5, TimeUnit.SECONDS, // terminate idle threads after 5 sec
|
5, TimeUnit.SECONDS, // terminate idle threads after 5 sec
|
||||||
new SynchronousQueue<Runnable>(), // directly hand off tasks
|
new SynchronousQueue<Runnable>(), // directly hand off tasks
|
||||||
new DefaultSolrThreadFactory("httpShardExecutor")
|
new DefaultSolrThreadFactory("httpShardExecutor")
|
||||||
);
|
);
|
||||||
|
|
||||||
HttpClient client;
|
HttpClient client;
|
||||||
Random r = new Random();
|
Random r = new Random();
|
||||||
LBHttpSolrServer loadbalancer;
|
LBHttpSolrServer loadbalancer;
|
||||||
int soTimeout = 0; //current default values
|
int soTimeout = 0; //current default values
|
||||||
int connectionTimeout = 0; //current default values
|
int connectionTimeout = 0; //current default values
|
||||||
int maxConnectionsPerHost = 20;
|
int maxConnectionsPerHost = 20;
|
||||||
int corePoolSize = 0;
|
int corePoolSize = 0;
|
||||||
int maximumPoolSize = 10;
|
int maximumPoolSize = 10;
|
||||||
int keepAliveTime = 5;
|
int keepAliveTime = 5;
|
||||||
int queueSize = 1;
|
int queueSize = 1;
|
||||||
boolean accessPolicy = true;
|
boolean accessPolicy = true;
|
||||||
|
|
||||||
public String scheme = "http://"; //current default values
|
public String scheme = "http://"; //current default values
|
||||||
|
|
||||||
private MultiThreadedHttpConnectionManager mgr;
|
private MultiThreadedHttpConnectionManager mgr;
|
||||||
// socket timeout measured in ms, closes a socket if read
|
// socket timeout measured in ms, closes a socket if read
|
||||||
// takes longer than x ms to complete. throws
|
// takes longer than x ms to complete. throws
|
||||||
// java.net.SocketTimeoutException: Read timed out exception
|
// java.net.SocketTimeoutException: Read timed out exception
|
||||||
static final String INIT_SO_TIMEOUT = "socketTimeout";
|
static final String INIT_SO_TIMEOUT = "socketTimeout";
|
||||||
|
|
||||||
// connection timeout measures in ms, closes a socket if connection
|
// connection timeout measures in ms, closes a socket if connection
|
||||||
// cannot be established within x ms. with a
|
// cannot be established within x ms. with a
|
||||||
// java.net.SocketTimeoutException: Connection timed out
|
// java.net.SocketTimeoutException: Connection timed out
|
||||||
static final String INIT_CONNECTION_TIMEOUT = "connTimeout";
|
static final String INIT_CONNECTION_TIMEOUT = "connTimeout";
|
||||||
|
|
||||||
// URL scheme to be used in distributed search.
|
// URL scheme to be used in distributed search.
|
||||||
static final String INIT_URL_SCHEME = "urlScheme";
|
static final String INIT_URL_SCHEME = "urlScheme";
|
||||||
|
|
||||||
// Maximum connections allowed per host
|
// Maximum connections allowed per host
|
||||||
static final String INIT_MAX_CONNECTION_PER_HOST = "maxConnectionsPerHost";
|
static final String INIT_MAX_CONNECTION_PER_HOST = "maxConnectionsPerHost";
|
||||||
|
|
||||||
// The core size of the threadpool servicing requests
|
// The core size of the threadpool servicing requests
|
||||||
static final String INIT_CORE_POOL_SIZE = "corePoolSize";
|
static final String INIT_CORE_POOL_SIZE = "corePoolSize";
|
||||||
|
|
||||||
// The maximum size of the threadpool servicing requests
|
// The maximum size of the threadpool servicing requests
|
||||||
static final String INIT_MAX_POOL_SIZE = "maximumPoolSize";
|
static final String INIT_MAX_POOL_SIZE = "maximumPoolSize";
|
||||||
|
|
||||||
// The amount of time idle threads persist for in the queue, before being killed
|
// The amount of time idle threads persist for in the queue, before being killed
|
||||||
static final String MAX_THREAD_IDLE_TIME = "maxThreadIdleTime";
|
static final String MAX_THREAD_IDLE_TIME = "maxThreadIdleTime";
|
||||||
|
|
||||||
// If the threadpool uses a backing queue, what is its maximum size (-1) to use direct handoff
|
// If the threadpool uses a backing queue, what is its maximum size (-1) to use direct handoff
|
||||||
static final String INIT_SIZE_OF_QUEUE = "sizeOfQueue";
|
static final String INIT_SIZE_OF_QUEUE = "sizeOfQueue";
|
||||||
|
|
||||||
// Configure if the threadpool favours fairness over throughput
|
// Configure if the threadpool favours fairness over throughput
|
||||||
static final String INIT_FAIRNESS_POLICY = "fairnessPolicy";
|
static final String INIT_FAIRNESS_POLICY = "fairnessPolicy";
|
||||||
|
|
||||||
public ShardHandler getShardHandler() {
|
public ShardHandler getShardHandler() {
|
||||||
return getShardHandler(null);
|
return getShardHandler(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ShardHandler getShardHandler(HttpClient httpClient) {
|
public ShardHandler getShardHandler(HttpClient httpClient) {
|
||||||
return new HttpShardHandler(this, httpClient);
|
return new HttpShardHandler(this, httpClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init(PluginInfo info) {
|
public void init(PluginInfo info) {
|
||||||
NamedList args = info.initArgs;
|
NamedList args = info.initArgs;
|
||||||
this.soTimeout = getParameter(args, INIT_SO_TIMEOUT, 0);
|
this.soTimeout = getParameter(args, INIT_SO_TIMEOUT, 0);
|
||||||
|
|
||||||
this.scheme = getParameter(args, INIT_URL_SCHEME, "http://");
|
this.scheme = getParameter(args, INIT_URL_SCHEME, "http://");
|
||||||
this.scheme = (this.scheme.endsWith("://")) ? this.scheme : this.scheme + "://";
|
this.scheme = (this.scheme.endsWith("://")) ? this.scheme : this.scheme + "://";
|
||||||
this.connectionTimeout = getParameter(args, INIT_CONNECTION_TIMEOUT, 0);
|
this.connectionTimeout = getParameter(args, INIT_CONNECTION_TIMEOUT, 0);
|
||||||
this.maxConnectionsPerHost = getParameter(args, INIT_MAX_CONNECTION_PER_HOST, 20);
|
this.maxConnectionsPerHost = getParameter(args, INIT_MAX_CONNECTION_PER_HOST, 20);
|
||||||
this.corePoolSize = getParameter(args, INIT_CORE_POOL_SIZE, 0);
|
this.corePoolSize = getParameter(args, INIT_CORE_POOL_SIZE, 0);
|
||||||
this.maximumPoolSize = getParameter(args, INIT_MAX_POOL_SIZE, Integer.MAX_VALUE);
|
this.maximumPoolSize = getParameter(args, INIT_MAX_POOL_SIZE, Integer.MAX_VALUE);
|
||||||
this.keepAliveTime = getParameter(args, MAX_THREAD_IDLE_TIME, 5);
|
this.keepAliveTime = getParameter(args, MAX_THREAD_IDLE_TIME, 5);
|
||||||
this.queueSize = getParameter(args, INIT_SIZE_OF_QUEUE, -1);
|
this.queueSize = getParameter(args, INIT_SIZE_OF_QUEUE, -1);
|
||||||
this.accessPolicy = getParameter(args, INIT_FAIRNESS_POLICY, false);
|
this.accessPolicy = getParameter(args, INIT_FAIRNESS_POLICY, false);
|
||||||
|
|
||||||
BlockingQueue<Runnable> blockingQueue = (this.queueSize == -1) ?
|
BlockingQueue<Runnable> blockingQueue = (this.queueSize == -1) ?
|
||||||
new SynchronousQueue<Runnable>(this.accessPolicy) :
|
new SynchronousQueue<Runnable>(this.accessPolicy) :
|
||||||
new ArrayBlockingQueue<Runnable>(this.queueSize, this.accessPolicy);
|
new ArrayBlockingQueue<Runnable>(this.queueSize, this.accessPolicy);
|
||||||
|
|
||||||
this.commExecutor = new ThreadPoolExecutor(
|
this.commExecutor = new ThreadPoolExecutor(
|
||||||
this.corePoolSize,
|
this.corePoolSize,
|
||||||
this.maximumPoolSize,
|
this.maximumPoolSize,
|
||||||
this.keepAliveTime, TimeUnit.SECONDS,
|
this.keepAliveTime, TimeUnit.SECONDS,
|
||||||
blockingQueue,
|
blockingQueue,
|
||||||
new DefaultSolrThreadFactory("httpShardExecutor")
|
new DefaultSolrThreadFactory("httpShardExecutor")
|
||||||
);
|
);
|
||||||
|
|
||||||
mgr = new MultiThreadedHttpConnectionManager();
|
mgr = new MultiThreadedHttpConnectionManager();
|
||||||
mgr.getParams().setDefaultMaxConnectionsPerHost(this.maxConnectionsPerHost);
|
mgr.getParams().setDefaultMaxConnectionsPerHost(this.maxConnectionsPerHost);
|
||||||
mgr.getParams().setMaxTotalConnections(10000);
|
mgr.getParams().setMaxTotalConnections(10000);
|
||||||
mgr.getParams().setConnectionTimeout(this.connectionTimeout);
|
mgr.getParams().setConnectionTimeout(this.connectionTimeout);
|
||||||
mgr.getParams().setSoTimeout(this.soTimeout);
|
mgr.getParams().setSoTimeout(this.soTimeout);
|
||||||
// mgr.getParams().setStaleCheckingEnabled(false);
|
// mgr.getParams().setStaleCheckingEnabled(false);
|
||||||
|
|
||||||
client = new HttpClient(mgr);
|
client = new HttpClient(mgr);
|
||||||
|
|
||||||
// prevent retries (note: this didn't work when set on mgr.. needed to be set on client)
|
// prevent retries (note: this didn't work when set on mgr.. needed to be set on client)
|
||||||
DefaultHttpMethodRetryHandler retryhandler = new DefaultHttpMethodRetryHandler(0, false);
|
DefaultHttpMethodRetryHandler retryhandler = new DefaultHttpMethodRetryHandler(0, false);
|
||||||
client.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, retryhandler);
|
client.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, retryhandler);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
loadbalancer = new LBHttpSolrServer(client);
|
loadbalancer = new LBHttpSolrServer(client);
|
||||||
} catch (MalformedURLException e) {
|
} catch (MalformedURLException e) {
|
||||||
// should be impossible since we're not passing any URLs here
|
// should be impossible since we're not passing any URLs here
|
||||||
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, e);
|
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> T getParameter(NamedList initArgs, String configKey, T defaultValue) {
|
private <T> T getParameter(NamedList initArgs, String configKey, T defaultValue) {
|
||||||
T toReturn = defaultValue;
|
T toReturn = defaultValue;
|
||||||
if (initArgs != null) {
|
if (initArgs != null) {
|
||||||
T temp = (T) initArgs.get(configKey);
|
T temp = (T) initArgs.get(configKey);
|
||||||
toReturn = (temp != null) ? temp : defaultValue;
|
toReturn = (temp != null) ? temp : defaultValue;
|
||||||
}
|
}
|
||||||
log.info("Setting {} to: {}", configKey, soTimeout);
|
log.info("Setting {} to: {}", configKey, soTimeout);
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
try {
|
try {
|
||||||
mgr.shutdown();
|
mgr.shutdown();
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
SolrException.log(log, e);
|
SolrException.log(log, e);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
loadbalancer.shutdown();
|
loadbalancer.shutdown();
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
SolrException.log(log, e);
|
SolrException.log(log, e);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
commExecutor.shutdownNow();
|
commExecutor.shutdownNow();
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
SolrException.log(log, e);
|
SolrException.log(log, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,28 +1,28 @@
|
||||||
package org.apache.solr.handler.component;
|
package org.apache.solr.handler.component;
|
||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
* this work for additional information regarding copyright ownership.
|
* this work for additional information regarding copyright ownership.
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
* 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 not use this file except in compliance with
|
||||||
* the License. You may obtain a copy of the License at
|
* the License. You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
import org.apache.solr.common.params.ModifiableSolrParams;
|
import org.apache.solr.common.params.ModifiableSolrParams;
|
||||||
|
|
||||||
public abstract class ShardHandler {
|
public abstract class ShardHandler {
|
||||||
public abstract void checkDistributed(ResponseBuilder rb);
|
public abstract void checkDistributed(ResponseBuilder rb);
|
||||||
public abstract void submit(ShardRequest sreq, String shard, ModifiableSolrParams params) ;
|
public abstract void submit(ShardRequest sreq, String shard, ModifiableSolrParams params) ;
|
||||||
public abstract ShardResponse takeCompletedIncludingErrors();
|
public abstract ShardResponse takeCompletedIncludingErrors();
|
||||||
public abstract ShardResponse takeCompletedOrError();
|
public abstract ShardResponse takeCompletedOrError();
|
||||||
public abstract void cancelAll();
|
public abstract void cancelAll();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +1,25 @@
|
||||||
package org.apache.solr.handler.component;
|
package org.apache.solr.handler.component;
|
||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
* this work for additional information regarding copyright ownership.
|
* this work for additional information regarding copyright ownership.
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
* 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 not use this file except in compliance with
|
||||||
* the License. You may obtain a copy of the License at
|
* the License. You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
public abstract class ShardHandlerFactory {
|
public abstract class ShardHandlerFactory {
|
||||||
|
|
||||||
public abstract ShardHandler getShardHandler();
|
public abstract ShardHandler getShardHandler();
|
||||||
|
|
||||||
public abstract void close();
|
public abstract void close();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,96 +1,96 @@
|
||||||
package org.apache.solr.search;
|
package org.apache.solr.search;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
* this work for additional information regarding copyright ownership.
|
* this work for additional information regarding copyright ownership.
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
* 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 not use this file except in compliance with
|
||||||
* the License. You may obtain a copy of the License at
|
* the License. You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import org.apache.lucene.index.IndexReader;
|
import org.apache.lucene.index.IndexReader;
|
||||||
import org.apache.lucene.index.AtomicReaderContext;
|
import org.apache.lucene.index.AtomicReaderContext;
|
||||||
import org.apache.lucene.search.Collector;
|
import org.apache.lucene.search.Collector;
|
||||||
import org.apache.lucene.search.Scorer;
|
import org.apache.lucene.search.Scorer;
|
||||||
import org.apache.lucene.util.OpenBitSet;
|
import org.apache.lucene.util.OpenBitSet;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class DocSetCollector extends Collector {
|
public class DocSetCollector extends Collector {
|
||||||
int pos=0;
|
int pos=0;
|
||||||
OpenBitSet bits;
|
OpenBitSet bits;
|
||||||
final int maxDoc;
|
final int maxDoc;
|
||||||
final int smallSetSize;
|
final int smallSetSize;
|
||||||
int base;
|
int base;
|
||||||
|
|
||||||
// in case there aren't that many hits, we may not want a very sparse
|
// in case there aren't that many hits, we may not want a very sparse
|
||||||
// bit array. Optimistically collect the first few docs in an array
|
// bit array. Optimistically collect the first few docs in an array
|
||||||
// in case there are only a few.
|
// in case there are only a few.
|
||||||
final int[] scratch;
|
final int[] scratch;
|
||||||
|
|
||||||
public DocSetCollector(int smallSetSize, int maxDoc) {
|
public DocSetCollector(int smallSetSize, int maxDoc) {
|
||||||
this.smallSetSize = smallSetSize;
|
this.smallSetSize = smallSetSize;
|
||||||
this.maxDoc = maxDoc;
|
this.maxDoc = maxDoc;
|
||||||
this.scratch = new int[smallSetSize];
|
this.scratch = new int[smallSetSize];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void collect(int doc) throws IOException {
|
public void collect(int doc) throws IOException {
|
||||||
doc += base;
|
doc += base;
|
||||||
// optimistically collect the first docs in an array
|
// optimistically collect the first docs in an array
|
||||||
// in case the total number will be small enough to represent
|
// in case the total number will be small enough to represent
|
||||||
// as a small set like SortedIntDocSet instead...
|
// as a small set like SortedIntDocSet instead...
|
||||||
// Storing in this array will be quicker to convert
|
// Storing in this array will be quicker to convert
|
||||||
// than scanning through a potentially huge bit vector.
|
// than scanning through a potentially huge bit vector.
|
||||||
// FUTURE: when search methods all start returning docs in order, maybe
|
// FUTURE: when search methods all start returning docs in order, maybe
|
||||||
// we could have a ListDocSet() and use the collected array directly.
|
// we could have a ListDocSet() and use the collected array directly.
|
||||||
if (pos < scratch.length) {
|
if (pos < scratch.length) {
|
||||||
scratch[pos]=doc;
|
scratch[pos]=doc;
|
||||||
} else {
|
} else {
|
||||||
// this conditional could be removed if BitSet was preallocated, but that
|
// this conditional could be removed if BitSet was preallocated, but that
|
||||||
// would take up more memory, and add more GC time...
|
// would take up more memory, and add more GC time...
|
||||||
if (bits==null) bits = new OpenBitSet(maxDoc);
|
if (bits==null) bits = new OpenBitSet(maxDoc);
|
||||||
bits.fastSet(doc);
|
bits.fastSet(doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
pos++;
|
pos++;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DocSet getDocSet() {
|
public DocSet getDocSet() {
|
||||||
if (pos<=scratch.length) {
|
if (pos<=scratch.length) {
|
||||||
// assumes docs were collected in sorted order!
|
// assumes docs were collected in sorted order!
|
||||||
return new SortedIntDocSet(scratch, pos);
|
return new SortedIntDocSet(scratch, pos);
|
||||||
} else {
|
} else {
|
||||||
// set the bits for ids that were collected in the array
|
// set the bits for ids that were collected in the array
|
||||||
for (int i=0; i<scratch.length; i++) bits.fastSet(scratch[i]);
|
for (int i=0; i<scratch.length; i++) bits.fastSet(scratch[i]);
|
||||||
return new BitDocSet(bits,pos);
|
return new BitDocSet(bits,pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setScorer(Scorer scorer) throws IOException {
|
public void setScorer(Scorer scorer) throws IOException {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setNextReader(AtomicReaderContext context) throws IOException {
|
public void setNextReader(AtomicReaderContext context) throws IOException {
|
||||||
this.base = context.docBase;
|
this.base = context.docBase;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean acceptsDocsOutOfOrder() {
|
public boolean acceptsDocsOutOfOrder() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,85 +1,85 @@
|
||||||
package org.apache.solr.search;
|
package org.apache.solr.search;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
* this work for additional information regarding copyright ownership.
|
* this work for additional information regarding copyright ownership.
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
* 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 not use this file except in compliance with
|
||||||
* the License. You may obtain a copy of the License at
|
* the License. You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import org.apache.lucene.index.IndexReader;
|
import org.apache.lucene.index.IndexReader;
|
||||||
import org.apache.lucene.index.AtomicReaderContext;
|
import org.apache.lucene.index.AtomicReaderContext;
|
||||||
import org.apache.lucene.search.Collector;
|
import org.apache.lucene.search.Collector;
|
||||||
import org.apache.lucene.search.Scorer;
|
import org.apache.lucene.search.Scorer;
|
||||||
import org.apache.lucene.util.OpenBitSet;
|
import org.apache.lucene.util.OpenBitSet;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class DocSetDelegateCollector extends DocSetCollector {
|
public class DocSetDelegateCollector extends DocSetCollector {
|
||||||
final Collector collector;
|
final Collector collector;
|
||||||
|
|
||||||
public DocSetDelegateCollector(int smallSetSize, int maxDoc, Collector collector) {
|
public DocSetDelegateCollector(int smallSetSize, int maxDoc, Collector collector) {
|
||||||
super(smallSetSize, maxDoc);
|
super(smallSetSize, maxDoc);
|
||||||
this.collector = collector;
|
this.collector = collector;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void collect(int doc) throws IOException {
|
public void collect(int doc) throws IOException {
|
||||||
collector.collect(doc);
|
collector.collect(doc);
|
||||||
|
|
||||||
doc += base;
|
doc += base;
|
||||||
// optimistically collect the first docs in an array
|
// optimistically collect the first docs in an array
|
||||||
// in case the total number will be small enough to represent
|
// in case the total number will be small enough to represent
|
||||||
// as a small set like SortedIntDocSet instead...
|
// as a small set like SortedIntDocSet instead...
|
||||||
// Storing in this array will be quicker to convert
|
// Storing in this array will be quicker to convert
|
||||||
// than scanning through a potentially huge bit vector.
|
// than scanning through a potentially huge bit vector.
|
||||||
// FUTURE: when search methods all start returning docs in order, maybe
|
// FUTURE: when search methods all start returning docs in order, maybe
|
||||||
// we could have a ListDocSet() and use the collected array directly.
|
// we could have a ListDocSet() and use the collected array directly.
|
||||||
if (pos < scratch.length) {
|
if (pos < scratch.length) {
|
||||||
scratch[pos]=doc;
|
scratch[pos]=doc;
|
||||||
} else {
|
} else {
|
||||||
// this conditional could be removed if BitSet was preallocated, but that
|
// this conditional could be removed if BitSet was preallocated, but that
|
||||||
// would take up more memory, and add more GC time...
|
// would take up more memory, and add more GC time...
|
||||||
if (bits==null) bits = new OpenBitSet(maxDoc);
|
if (bits==null) bits = new OpenBitSet(maxDoc);
|
||||||
bits.fastSet(doc);
|
bits.fastSet(doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
pos++;
|
pos++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DocSet getDocSet() {
|
public DocSet getDocSet() {
|
||||||
if (pos<=scratch.length) {
|
if (pos<=scratch.length) {
|
||||||
// assumes docs were collected in sorted order!
|
// assumes docs were collected in sorted order!
|
||||||
return new SortedIntDocSet(scratch, pos);
|
return new SortedIntDocSet(scratch, pos);
|
||||||
} else {
|
} else {
|
||||||
// set the bits for ids that were collected in the array
|
// set the bits for ids that were collected in the array
|
||||||
for (int i=0; i<scratch.length; i++) bits.fastSet(scratch[i]);
|
for (int i=0; i<scratch.length; i++) bits.fastSet(scratch[i]);
|
||||||
return new BitDocSet(bits,pos);
|
return new BitDocSet(bits,pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setScorer(Scorer scorer) throws IOException {
|
public void setScorer(Scorer scorer) throws IOException {
|
||||||
collector.setScorer(scorer);
|
collector.setScorer(scorer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setNextReader(AtomicReaderContext context) throws IOException {
|
public void setNextReader(AtomicReaderContext context) throws IOException {
|
||||||
collector.setNextReader(context);
|
collector.setNextReader(context);
|
||||||
this.base = context.docBase;
|
this.base = context.docBase;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,70 +1,70 @@
|
||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
* this work for additional information regarding copyright ownership.
|
* this work for additional information regarding copyright ownership.
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
* 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 not use this file except in compliance with
|
||||||
* the License. You may obtain a copy of the License at
|
* the License. You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.apache.solr.search;
|
package org.apache.solr.search;
|
||||||
|
|
||||||
import org.apache.lucene.index.AtomicReaderContext;
|
import org.apache.lucene.index.AtomicReaderContext;
|
||||||
import org.apache.lucene.index.IndexReader;
|
import org.apache.lucene.index.IndexReader;
|
||||||
import org.apache.lucene.queries.function.FunctionValues;
|
import org.apache.lucene.queries.function.FunctionValues;
|
||||||
import org.apache.lucene.queries.function.ValueSource;
|
import org.apache.lucene.queries.function.ValueSource;
|
||||||
import org.apache.lucene.queries.function.ValueSourceScorer;
|
import org.apache.lucene.queries.function.ValueSourceScorer;
|
||||||
import org.apache.lucene.search.IndexSearcher;
|
import org.apache.lucene.search.IndexSearcher;
|
||||||
import org.apache.solr.search.function.ValueSourceRangeFilter;
|
import org.apache.solr.search.function.ValueSourceRangeFilter;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
// This class works as either a normal constant score query, or as a PostFilter using a collector
|
// This class works as either a normal constant score query, or as a PostFilter using a collector
|
||||||
public class FunctionRangeQuery extends SolrConstantScoreQuery implements PostFilter {
|
public class FunctionRangeQuery extends SolrConstantScoreQuery implements PostFilter {
|
||||||
final ValueSourceRangeFilter rangeFilt;
|
final ValueSourceRangeFilter rangeFilt;
|
||||||
|
|
||||||
public FunctionRangeQuery(ValueSourceRangeFilter filter) {
|
public FunctionRangeQuery(ValueSourceRangeFilter filter) {
|
||||||
super(filter);
|
super(filter);
|
||||||
this.rangeFilt = filter;
|
this.rangeFilt = filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DelegatingCollector getFilterCollector(IndexSearcher searcher) {
|
public DelegatingCollector getFilterCollector(IndexSearcher searcher) {
|
||||||
Map fcontext = ValueSource.newContext(searcher);
|
Map fcontext = ValueSource.newContext(searcher);
|
||||||
return new FunctionRangeCollector(fcontext);
|
return new FunctionRangeCollector(fcontext);
|
||||||
}
|
}
|
||||||
|
|
||||||
class FunctionRangeCollector extends DelegatingCollector {
|
class FunctionRangeCollector extends DelegatingCollector {
|
||||||
final Map fcontext;
|
final Map fcontext;
|
||||||
ValueSourceScorer scorer;
|
ValueSourceScorer scorer;
|
||||||
int maxdoc;
|
int maxdoc;
|
||||||
|
|
||||||
public FunctionRangeCollector(Map fcontext) {
|
public FunctionRangeCollector(Map fcontext) {
|
||||||
this.fcontext = fcontext;
|
this.fcontext = fcontext;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void collect(int doc) throws IOException {
|
public void collect(int doc) throws IOException {
|
||||||
if (doc<maxdoc && scorer.matches(doc)) {
|
if (doc<maxdoc && scorer.matches(doc)) {
|
||||||
delegate.collect(doc);
|
delegate.collect(doc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setNextReader(AtomicReaderContext context) throws IOException {
|
public void setNextReader(AtomicReaderContext context) throws IOException {
|
||||||
maxdoc = context.reader().maxDoc();
|
maxdoc = context.reader().maxDoc();
|
||||||
FunctionValues dv = rangeFilt.getValueSource().getValues(fcontext, context);
|
FunctionValues dv = rangeFilt.getValueSource().getValues(fcontext, context);
|
||||||
scorer = dv.getRangeScorer(context.reader(), rangeFilt.getLowerVal(), rangeFilt.getUpperVal(), rangeFilt.isIncludeLower(), rangeFilt.isIncludeUpper());
|
scorer = dv.getRangeScorer(context.reader(), rangeFilt.getLowerVal(), rangeFilt.getUpperVal(), rangeFilt.isIncludeLower(), rangeFilt.isIncludeUpper());
|
||||||
super.setNextReader(context);
|
super.setNextReader(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,76 +1,76 @@
|
||||||
package org.apache.solr.search.grouping.collector;
|
package org.apache.solr.search.grouping.collector;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
* this work for additional information regarding copyright ownership.
|
* this work for additional information regarding copyright ownership.
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
* 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 not use this file except in compliance with
|
||||||
* the License. You may obtain a copy of the License at
|
* the License. You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import org.apache.lucene.index.AtomicReaderContext;
|
import org.apache.lucene.index.AtomicReaderContext;
|
||||||
import org.apache.lucene.search.Collector;
|
import org.apache.lucene.search.Collector;
|
||||||
import org.apache.lucene.search.Scorer;
|
import org.apache.lucene.search.Scorer;
|
||||||
import org.apache.solr.search.DocSet;
|
import org.apache.solr.search.DocSet;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A collector that filters incoming doc ids that are not in the filter.
|
* A collector that filters incoming doc ids that are not in the filter.
|
||||||
*
|
*
|
||||||
* @lucene.experimental
|
* @lucene.experimental
|
||||||
*/
|
*/
|
||||||
public class FilterCollector extends Collector {
|
public class FilterCollector extends Collector {
|
||||||
|
|
||||||
private final DocSet filter;
|
private final DocSet filter;
|
||||||
private final Collector delegate;
|
private final Collector delegate;
|
||||||
private int docBase;
|
private int docBase;
|
||||||
private int matches;
|
private int matches;
|
||||||
|
|
||||||
public FilterCollector(DocSet filter, Collector delegate) throws IOException {
|
public FilterCollector(DocSet filter, Collector delegate) throws IOException {
|
||||||
this.filter = filter;
|
this.filter = filter;
|
||||||
this.delegate = delegate;
|
this.delegate = delegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setScorer(Scorer scorer) throws IOException {
|
public void setScorer(Scorer scorer) throws IOException {
|
||||||
delegate.setScorer(scorer);
|
delegate.setScorer(scorer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void collect(int doc) throws IOException {
|
public void collect(int doc) throws IOException {
|
||||||
matches++;
|
matches++;
|
||||||
if (filter.exists(doc + docBase)) {
|
if (filter.exists(doc + docBase)) {
|
||||||
delegate.collect(doc);
|
delegate.collect(doc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNextReader(AtomicReaderContext context) throws IOException {
|
public void setNextReader(AtomicReaderContext context) throws IOException {
|
||||||
this.docBase = context.docBase;
|
this.docBase = context.docBase;
|
||||||
delegate.setNextReader(context);
|
delegate.setNextReader(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean acceptsDocsOutOfOrder() {
|
public boolean acceptsDocsOutOfOrder() {
|
||||||
return delegate.acceptsDocsOutOfOrder();
|
return delegate.acceptsDocsOutOfOrder();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMatches() {
|
public int getMatches() {
|
||||||
return matches;
|
return matches;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the delegate collector
|
* Returns the delegate collector
|
||||||
*
|
*
|
||||||
* @return the delegate collector
|
* @return the delegate collector
|
||||||
*/
|
*/
|
||||||
public Collector getDelegate() {
|
public Collector getDelegate() {
|
||||||
return delegate;
|
return delegate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,82 +1,82 @@
|
||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
* this work for additional information regarding copyright ownership.
|
* this work for additional information regarding copyright ownership.
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
* 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 not use this file except in compliance with
|
||||||
* the License. You may obtain a copy of the License at
|
* the License. You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.apache.solr.servlet;
|
package org.apache.solr.servlet;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServlet;
|
import javax.servlet.http.HttpServlet;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.commons.lang.StringEscapeUtils;
|
import org.apache.commons.lang.StringEscapeUtils;
|
||||||
import org.apache.solr.core.CoreContainer;
|
import org.apache.solr.core.CoreContainer;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple servlet to load the Solr Admin UI
|
* A simple servlet to load the Solr Admin UI
|
||||||
*
|
*
|
||||||
* @since solr 4.0
|
* @since solr 4.0
|
||||||
*/
|
*/
|
||||||
public final class LoadAdminUiServlet extends HttpServlet {
|
public final class LoadAdminUiServlet extends HttpServlet {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doGet(HttpServletRequest request,
|
public void doGet(HttpServletRequest request,
|
||||||
HttpServletResponse response)
|
HttpServletResponse response)
|
||||||
throws IOException, ServletException {
|
throws IOException, ServletException {
|
||||||
response.setCharacterEncoding("UTF-8");
|
response.setCharacterEncoding("UTF-8");
|
||||||
response.setContentType("text/html");
|
response.setContentType("text/html");
|
||||||
|
|
||||||
PrintWriter out = response.getWriter();
|
PrintWriter out = response.getWriter();
|
||||||
InputStream in = getServletContext().getResourceAsStream("/admin.html");
|
InputStream in = getServletContext().getResourceAsStream("/admin.html");
|
||||||
if(in != null) {
|
if(in != null) {
|
||||||
try {
|
try {
|
||||||
// This attribute is set by the SolrDispatchFilter
|
// This attribute is set by the SolrDispatchFilter
|
||||||
CoreContainer cores = (CoreContainer) request.getAttribute("org.apache.solr.CoreContainer");
|
CoreContainer cores = (CoreContainer) request.getAttribute("org.apache.solr.CoreContainer");
|
||||||
|
|
||||||
String html = IOUtils.toString(in, "UTF-8");
|
String html = IOUtils.toString(in, "UTF-8");
|
||||||
|
|
||||||
String[] search = new String[] {
|
String[] search = new String[] {
|
||||||
"${contextPath}",
|
"${contextPath}",
|
||||||
"${adminPath}"
|
"${adminPath}"
|
||||||
};
|
};
|
||||||
String[] replace = new String[] {
|
String[] replace = new String[] {
|
||||||
StringEscapeUtils.escapeJavaScript(request.getContextPath()),
|
StringEscapeUtils.escapeJavaScript(request.getContextPath()),
|
||||||
StringEscapeUtils.escapeJavaScript(cores.getAdminPath())
|
StringEscapeUtils.escapeJavaScript(cores.getAdminPath())
|
||||||
};
|
};
|
||||||
|
|
||||||
out.println( StringUtils.replaceEach(html, search, replace) );
|
out.println( StringUtils.replaceEach(html, search, replace) );
|
||||||
} finally {
|
} finally {
|
||||||
IOUtils.closeQuietly(in);
|
IOUtils.closeQuietly(in);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
out.println("solr");
|
out.println("solr");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request,
|
public void doPost(HttpServletRequest request,
|
||||||
HttpServletResponse response)
|
HttpServletResponse response)
|
||||||
throws IOException, ServletException {
|
throws IOException, ServletException {
|
||||||
doGet(request, response);
|
doGet(request, response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,409 +1,409 @@
|
||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
* this work for additional information regarding copyright ownership.
|
* this work for additional information regarding copyright ownership.
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
* 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 not use this file except in compliance with
|
||||||
* the License. You may obtain a copy of the License at
|
* the License. You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.apache.solr.servlet;
|
package org.apache.solr.servlet;
|
||||||
|
|
||||||
import org.apache.lucene.util.BytesRef;
|
import org.apache.lucene.util.BytesRef;
|
||||||
import org.apache.noggit.CharArr;
|
import org.apache.noggit.CharArr;
|
||||||
import org.apache.noggit.JSONWriter;
|
import org.apache.noggit.JSONWriter;
|
||||||
import org.apache.solr.cloud.ZkController;
|
import org.apache.solr.cloud.ZkController;
|
||||||
import org.apache.solr.common.cloud.SolrZkClient;
|
import org.apache.solr.common.cloud.SolrZkClient;
|
||||||
import org.apache.solr.core.CoreContainer;
|
import org.apache.solr.core.CoreContainer;
|
||||||
import org.apache.zookeeper.KeeperException;
|
import org.apache.zookeeper.KeeperException;
|
||||||
import org.apache.zookeeper.data.Stat;
|
import org.apache.zookeeper.data.Stat;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServlet;
|
import javax.servlet.http.HttpServlet;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Zookeeper Info
|
* Zookeeper Info
|
||||||
*
|
*
|
||||||
* @since solr 4.0
|
* @since solr 4.0
|
||||||
*/
|
*/
|
||||||
public final class ZookeeperInfoServlet extends HttpServlet {
|
public final class ZookeeperInfoServlet extends HttpServlet {
|
||||||
static final Logger log = LoggerFactory.getLogger(ZookeeperInfoServlet.class);
|
static final Logger log = LoggerFactory.getLogger(ZookeeperInfoServlet.class);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init() throws ServletException {
|
public void init() throws ServletException {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doGet(HttpServletRequest request,
|
public void doGet(HttpServletRequest request,
|
||||||
HttpServletResponse response)
|
HttpServletResponse response)
|
||||||
throws IOException, ServletException {
|
throws IOException, ServletException {
|
||||||
response.setCharacterEncoding("UTF-8");
|
response.setCharacterEncoding("UTF-8");
|
||||||
response.setContentType("application/json");
|
response.setContentType("application/json");
|
||||||
|
|
||||||
// This attribute is set by the SolrDispatchFilter
|
// This attribute is set by the SolrDispatchFilter
|
||||||
CoreContainer cores = (CoreContainer) request.getAttribute("org.apache.solr.CoreContainer");
|
CoreContainer cores = (CoreContainer) request.getAttribute("org.apache.solr.CoreContainer");
|
||||||
|
|
||||||
String path = request.getParameter("path");
|
String path = request.getParameter("path");
|
||||||
String addr = request.getParameter("addr");
|
String addr = request.getParameter("addr");
|
||||||
|
|
||||||
if (addr != null && addr.length() == 0) {
|
if (addr != null && addr.length() == 0) {
|
||||||
addr = null;
|
addr = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
String detailS = request.getParameter("detail");
|
String detailS = request.getParameter("detail");
|
||||||
boolean detail = detailS != null && detailS.equals("true");
|
boolean detail = detailS != null && detailS.equals("true");
|
||||||
|
|
||||||
String dumpS = request.getParameter("dump");
|
String dumpS = request.getParameter("dump");
|
||||||
boolean dump = dumpS != null && dumpS.equals("true");
|
boolean dump = dumpS != null && dumpS.equals("true");
|
||||||
|
|
||||||
PrintWriter out = response.getWriter();
|
PrintWriter out = response.getWriter();
|
||||||
|
|
||||||
|
|
||||||
ZKPrinter printer = new ZKPrinter(response, out, cores.getZkController(), addr);
|
ZKPrinter printer = new ZKPrinter(response, out, cores.getZkController(), addr);
|
||||||
printer.detail = detail;
|
printer.detail = detail;
|
||||||
printer.dump = dump;
|
printer.dump = dump;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
printer.print(path);
|
printer.print(path);
|
||||||
} finally {
|
} finally {
|
||||||
printer.close();
|
printer.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request,
|
public void doPost(HttpServletRequest request,
|
||||||
HttpServletResponse response)
|
HttpServletResponse response)
|
||||||
throws IOException, ServletException {
|
throws IOException, ServletException {
|
||||||
doGet(request, response);
|
doGet(request, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
static class ZKPrinter {
|
static class ZKPrinter {
|
||||||
static boolean FULLPATH_DEFAULT = false;
|
static boolean FULLPATH_DEFAULT = false;
|
||||||
|
|
||||||
boolean indent = true;
|
boolean indent = true;
|
||||||
boolean fullpath = FULLPATH_DEFAULT;
|
boolean fullpath = FULLPATH_DEFAULT;
|
||||||
boolean detail = false;
|
boolean detail = false;
|
||||||
boolean dump = false;
|
boolean dump = false;
|
||||||
|
|
||||||
String addr; // the address passed to us
|
String addr; // the address passed to us
|
||||||
String keeperAddr; // the address we're connected to
|
String keeperAddr; // the address we're connected to
|
||||||
|
|
||||||
boolean doClose; // close the client after done if we opened it
|
boolean doClose; // close the client after done if we opened it
|
||||||
|
|
||||||
final HttpServletResponse response;
|
final HttpServletResponse response;
|
||||||
final PrintWriter out;
|
final PrintWriter out;
|
||||||
SolrZkClient zkClient;
|
SolrZkClient zkClient;
|
||||||
|
|
||||||
int level;
|
int level;
|
||||||
int maxData = 95;
|
int maxData = 95;
|
||||||
|
|
||||||
public ZKPrinter(HttpServletResponse response, PrintWriter out, ZkController controller, String addr) throws IOException {
|
public ZKPrinter(HttpServletResponse response, PrintWriter out, ZkController controller, String addr) throws IOException {
|
||||||
this.response = response;
|
this.response = response;
|
||||||
this.out = out;
|
this.out = out;
|
||||||
this.addr = addr;
|
this.addr = addr;
|
||||||
|
|
||||||
if (addr == null) {
|
if (addr == null) {
|
||||||
if (controller != null) {
|
if (controller != null) {
|
||||||
// this core is zk enabled
|
// this core is zk enabled
|
||||||
keeperAddr = controller.getZkServerAddress();
|
keeperAddr = controller.getZkServerAddress();
|
||||||
zkClient = controller.getZkClient();
|
zkClient = controller.getZkClient();
|
||||||
if (zkClient != null && zkClient.isConnected()) {
|
if (zkClient != null && zkClient.isConnected()) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
// try a different client with this address
|
// try a different client with this address
|
||||||
addr = keeperAddr;
|
addr = keeperAddr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
keeperAddr = addr;
|
keeperAddr = addr;
|
||||||
if (addr == null) {
|
if (addr == null) {
|
||||||
writeError(404, "Zookeeper is not configured for this Solr Core. Please try connecting to an alternate zookeeper address.");
|
writeError(404, "Zookeeper is not configured for this Solr Core. Please try connecting to an alternate zookeeper address.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
zkClient = new SolrZkClient(addr, 10000);
|
zkClient = new SolrZkClient(addr, 10000);
|
||||||
doClose = true;
|
doClose = true;
|
||||||
} catch (TimeoutException e) {
|
} catch (TimeoutException e) {
|
||||||
writeError(503, "Could not connect to zookeeper at '" + addr + "'\"");
|
writeError(503, "Could not connect to zookeeper at '" + addr + "'\"");
|
||||||
zkClient = null;
|
zkClient = null;
|
||||||
return;
|
return;
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
// Restore the interrupted status
|
// Restore the interrupted status
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
writeError(503, "Could not connect to zookeeper at '" + addr + "'\"");
|
writeError(503, "Could not connect to zookeeper at '" + addr + "'\"");
|
||||||
zkClient = null;
|
zkClient = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() {
|
public void close() {
|
||||||
try {
|
try {
|
||||||
if (doClose) {
|
if (doClose) {
|
||||||
zkClient.close();
|
zkClient.close();
|
||||||
}
|
}
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
// ignore exception on close
|
// ignore exception on close
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// main entry point
|
// main entry point
|
||||||
void print(String path) throws IOException {
|
void print(String path) throws IOException {
|
||||||
if (zkClient == null) {
|
if (zkClient == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// normalize path
|
// normalize path
|
||||||
if (path == null) {
|
if (path == null) {
|
||||||
path = "/";
|
path = "/";
|
||||||
} else {
|
} else {
|
||||||
path.trim();
|
path.trim();
|
||||||
if (path.length() == 0) {
|
if (path.length() == 0) {
|
||||||
path = "/";
|
path = "/";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path.endsWith("/") && path.length() > 1) {
|
if (path.endsWith("/") && path.length() > 1) {
|
||||||
path = path.substring(0, path.length() - 1);
|
path = path.substring(0, path.length() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int idx = path.lastIndexOf('/');
|
int idx = path.lastIndexOf('/');
|
||||||
String parent = idx >= 0 ? path.substring(0, idx) : path;
|
String parent = idx >= 0 ? path.substring(0, idx) : path;
|
||||||
if (parent.length() == 0) {
|
if (parent.length() == 0) {
|
||||||
parent = "/";
|
parent = "/";
|
||||||
}
|
}
|
||||||
|
|
||||||
CharArr chars = new CharArr();
|
CharArr chars = new CharArr();
|
||||||
JSONWriter json = new JSONWriter(chars, 2);
|
JSONWriter json = new JSONWriter(chars, 2);
|
||||||
json.startObject();
|
json.startObject();
|
||||||
|
|
||||||
if (detail) {
|
if (detail) {
|
||||||
if (!printZnode(json, path)) {
|
if (!printZnode(json, path)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
json.writeValueSeparator();
|
json.writeValueSeparator();
|
||||||
}
|
}
|
||||||
|
|
||||||
json.writeString("tree");
|
json.writeString("tree");
|
||||||
json.writeNameSeparator();
|
json.writeNameSeparator();
|
||||||
json.startArray();
|
json.startArray();
|
||||||
if (!printTree(json, path)) {
|
if (!printTree(json, path)) {
|
||||||
return; // there was an error
|
return; // there was an error
|
||||||
}
|
}
|
||||||
json.endArray();
|
json.endArray();
|
||||||
json.endObject();
|
json.endObject();
|
||||||
out.println(chars.toString());
|
out.println(chars.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeError(int code, String msg) {
|
void writeError(int code, String msg) {
|
||||||
response.setStatus(code);
|
response.setStatus(code);
|
||||||
|
|
||||||
CharArr chars = new CharArr();
|
CharArr chars = new CharArr();
|
||||||
JSONWriter w = new JSONWriter(chars, 2);
|
JSONWriter w = new JSONWriter(chars, 2);
|
||||||
w.startObject();
|
w.startObject();
|
||||||
w.indent();
|
w.indent();
|
||||||
w.writeString("status");
|
w.writeString("status");
|
||||||
w.writeNameSeparator();
|
w.writeNameSeparator();
|
||||||
w.write(code);
|
w.write(code);
|
||||||
w.writeValueSeparator();
|
w.writeValueSeparator();
|
||||||
w.indent();
|
w.indent();
|
||||||
w.writeString("error");
|
w.writeString("error");
|
||||||
w.writeNameSeparator();
|
w.writeNameSeparator();
|
||||||
w.writeString(msg);
|
w.writeString(msg);
|
||||||
w.endObject();
|
w.endObject();
|
||||||
|
|
||||||
out.println(chars.toString());
|
out.println(chars.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
boolean printTree(JSONWriter json, String path) throws IOException {
|
boolean printTree(JSONWriter json, String path) throws IOException {
|
||||||
String label = path;
|
String label = path;
|
||||||
if (!fullpath) {
|
if (!fullpath) {
|
||||||
int idx = path.lastIndexOf('/');
|
int idx = path.lastIndexOf('/');
|
||||||
label = idx > 0 ? path.substring(idx + 1) : path;
|
label = idx > 0 ? path.substring(idx + 1) : path;
|
||||||
}
|
}
|
||||||
json.startObject();
|
json.startObject();
|
||||||
//writeKeyValue(json, "data", label, true );
|
//writeKeyValue(json, "data", label, true );
|
||||||
json.writeString("data");
|
json.writeString("data");
|
||||||
json.writeNameSeparator();
|
json.writeNameSeparator();
|
||||||
|
|
||||||
json.startObject();
|
json.startObject();
|
||||||
writeKeyValue(json, "title", label, true);
|
writeKeyValue(json, "title", label, true);
|
||||||
json.writeValueSeparator();
|
json.writeValueSeparator();
|
||||||
json.writeString("attr");
|
json.writeString("attr");
|
||||||
json.writeNameSeparator();
|
json.writeNameSeparator();
|
||||||
json.startObject();
|
json.startObject();
|
||||||
writeKeyValue(json, "href", "zookeeper?detail=true&path=" + URLEncoder.encode(path, "UTF-8"), true);
|
writeKeyValue(json, "href", "zookeeper?detail=true&path=" + URLEncoder.encode(path, "UTF-8"), true);
|
||||||
json.endObject();
|
json.endObject();
|
||||||
json.endObject();
|
json.endObject();
|
||||||
|
|
||||||
Stat stat = new Stat();
|
Stat stat = new Stat();
|
||||||
try {
|
try {
|
||||||
// Trickily, the call to zkClient.getData fills in the stat variable
|
// Trickily, the call to zkClient.getData fills in the stat variable
|
||||||
byte[] data = zkClient.getData(path, null, stat, true);
|
byte[] data = zkClient.getData(path, null, stat, true);
|
||||||
|
|
||||||
if (stat.getEphemeralOwner() != 0) {
|
if (stat.getEphemeralOwner() != 0) {
|
||||||
writeKeyValue(json, "ephemeral", true, false);
|
writeKeyValue(json, "ephemeral", true, false);
|
||||||
writeKeyValue(json, "version", stat.getVersion(), false);
|
writeKeyValue(json, "version", stat.getVersion(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dump) {
|
if (dump) {
|
||||||
json.writeValueSeparator();
|
json.writeValueSeparator();
|
||||||
printZnode(json, path);
|
printZnode(json, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (stat.getNumChildren() != 0)
|
if (stat.getNumChildren() != 0)
|
||||||
{
|
{
|
||||||
writeKeyValue(json, "children_count", stat.getNumChildren(), false );
|
writeKeyValue(json, "children_count", stat.getNumChildren(), false );
|
||||||
out.println(", \"children_count\" : \"" + stat.getNumChildren() + "\"");
|
out.println(", \"children_count\" : \"" + stat.getNumChildren() + "\"");
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//if (stat.getDataLength() != 0)
|
//if (stat.getDataLength() != 0)
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
String str = new BytesRef(data).utf8ToString();
|
String str = new BytesRef(data).utf8ToString();
|
||||||
//?? writeKeyValue(json, "content", str, false );
|
//?? writeKeyValue(json, "content", str, false );
|
||||||
// Does nothing now, but on the assumption this will be used later we'll leave it in. If it comes out
|
// Does nothing now, but on the assumption this will be used later we'll leave it in. If it comes out
|
||||||
// the catches below need to be restructured.
|
// the catches below need to be restructured.
|
||||||
}
|
}
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
// path doesn't exist (must have been removed)
|
// path doesn't exist (must have been removed)
|
||||||
writeKeyValue(json, "warning", "(path gone)", false);
|
writeKeyValue(json, "warning", "(path gone)", false);
|
||||||
} catch (KeeperException e) {
|
} catch (KeeperException e) {
|
||||||
writeKeyValue(json, "warning", e.toString(), false);
|
writeKeyValue(json, "warning", e.toString(), false);
|
||||||
log.warn("Keeper Exception", e);
|
log.warn("Keeper Exception", e);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
writeKeyValue(json, "warning", e.toString(), false);
|
writeKeyValue(json, "warning", e.toString(), false);
|
||||||
log.warn("InterruptedException", e);
|
log.warn("InterruptedException", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stat.getNumChildren() > 0) {
|
if (stat.getNumChildren() > 0) {
|
||||||
json.writeValueSeparator();
|
json.writeValueSeparator();
|
||||||
if (indent) {
|
if (indent) {
|
||||||
json.indent();
|
json.indent();
|
||||||
}
|
}
|
||||||
json.writeString("children");
|
json.writeString("children");
|
||||||
json.writeNameSeparator();
|
json.writeNameSeparator();
|
||||||
json.startArray();
|
json.startArray();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
List<String> children = zkClient.getChildren(path, null, true);
|
List<String> children = zkClient.getChildren(path, null, true);
|
||||||
java.util.Collections.sort(children);
|
java.util.Collections.sort(children);
|
||||||
|
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
for (String child : children) {
|
for (String child : children) {
|
||||||
if (!first) {
|
if (!first) {
|
||||||
json.writeValueSeparator();
|
json.writeValueSeparator();
|
||||||
}
|
}
|
||||||
|
|
||||||
String childPath = path + (path.endsWith("/") ? "" : "/") + child;
|
String childPath = path + (path.endsWith("/") ? "" : "/") + child;
|
||||||
if (!printTree(json, childPath)) {
|
if (!printTree(json, childPath)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
} catch (KeeperException e) {
|
} catch (KeeperException e) {
|
||||||
writeError(500, e.toString());
|
writeError(500, e.toString());
|
||||||
return false;
|
return false;
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
writeError(500, e.toString());
|
writeError(500, e.toString());
|
||||||
return false;
|
return false;
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
// path doesn't exist (must have been removed)
|
// path doesn't exist (must have been removed)
|
||||||
json.writeString("(children gone)");
|
json.writeString("(children gone)");
|
||||||
}
|
}
|
||||||
|
|
||||||
json.endArray();
|
json.endArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
json.endObject();
|
json.endObject();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
String time(long ms) {
|
String time(long ms) {
|
||||||
return (new Date(ms)).toString() + " (" + ms + ")";
|
return (new Date(ms)).toString() + " (" + ms + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeKeyValue(JSONWriter json, String k, Object v, boolean isFirst) {
|
public void writeKeyValue(JSONWriter json, String k, Object v, boolean isFirst) {
|
||||||
if (!isFirst) {
|
if (!isFirst) {
|
||||||
json.writeValueSeparator();
|
json.writeValueSeparator();
|
||||||
}
|
}
|
||||||
if (indent) {
|
if (indent) {
|
||||||
json.indent();
|
json.indent();
|
||||||
}
|
}
|
||||||
json.writeString(k);
|
json.writeString(k);
|
||||||
json.writeNameSeparator();
|
json.writeNameSeparator();
|
||||||
json.write(v);
|
json.write(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean printZnode(JSONWriter json, String path) throws IOException {
|
boolean printZnode(JSONWriter json, String path) throws IOException {
|
||||||
try {
|
try {
|
||||||
Stat stat = new Stat();
|
Stat stat = new Stat();
|
||||||
// Trickily, the call to zkClient.getData fills in the stat variable
|
// Trickily, the call to zkClient.getData fills in the stat variable
|
||||||
byte[] data = zkClient.getData(path, null, stat, true);
|
byte[] data = zkClient.getData(path, null, stat, true);
|
||||||
|
|
||||||
json.writeString("znode");
|
json.writeString("znode");
|
||||||
json.writeNameSeparator();
|
json.writeNameSeparator();
|
||||||
json.startObject();
|
json.startObject();
|
||||||
|
|
||||||
writeKeyValue(json, "path", path, true);
|
writeKeyValue(json, "path", path, true);
|
||||||
|
|
||||||
json.writeValueSeparator();
|
json.writeValueSeparator();
|
||||||
json.writeString("prop");
|
json.writeString("prop");
|
||||||
json.writeNameSeparator();
|
json.writeNameSeparator();
|
||||||
json.startObject();
|
json.startObject();
|
||||||
writeKeyValue(json, "version", stat.getVersion(), true);
|
writeKeyValue(json, "version", stat.getVersion(), true);
|
||||||
writeKeyValue(json, "aversion", stat.getAversion(), false);
|
writeKeyValue(json, "aversion", stat.getAversion(), false);
|
||||||
writeKeyValue(json, "children_count", stat.getNumChildren(), false);
|
writeKeyValue(json, "children_count", stat.getNumChildren(), false);
|
||||||
writeKeyValue(json, "ctime", time(stat.getCtime()), false);
|
writeKeyValue(json, "ctime", time(stat.getCtime()), false);
|
||||||
writeKeyValue(json, "cversion", stat.getCversion(), false);
|
writeKeyValue(json, "cversion", stat.getCversion(), false);
|
||||||
writeKeyValue(json, "czxid", stat.getCzxid(), false);
|
writeKeyValue(json, "czxid", stat.getCzxid(), false);
|
||||||
writeKeyValue(json, "dataLength", stat.getDataLength(), false);
|
writeKeyValue(json, "dataLength", stat.getDataLength(), false);
|
||||||
writeKeyValue(json, "ephemeralOwner", stat.getEphemeralOwner(), false);
|
writeKeyValue(json, "ephemeralOwner", stat.getEphemeralOwner(), false);
|
||||||
writeKeyValue(json, "mtime", time(stat.getMtime()), false);
|
writeKeyValue(json, "mtime", time(stat.getMtime()), false);
|
||||||
writeKeyValue(json, "mzxid", stat.getMzxid(), false);
|
writeKeyValue(json, "mzxid", stat.getMzxid(), false);
|
||||||
writeKeyValue(json, "pzxid", stat.getPzxid(), false);
|
writeKeyValue(json, "pzxid", stat.getPzxid(), false);
|
||||||
json.endObject();
|
json.endObject();
|
||||||
|
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
writeKeyValue(json, "data", new BytesRef(data).utf8ToString(), false);
|
writeKeyValue(json, "data", new BytesRef(data).utf8ToString(), false);
|
||||||
}
|
}
|
||||||
json.endObject();
|
json.endObject();
|
||||||
} catch (KeeperException e) {
|
} catch (KeeperException e) {
|
||||||
writeError(500, e.toString());
|
writeError(500, e.toString());
|
||||||
return false;
|
return false;
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
writeError(500, e.toString());
|
writeError(500, e.toString());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,456 +1,456 @@
|
||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
* this work for additional information regarding copyright ownership.
|
* this work for additional information regarding copyright ownership.
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
* 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 not use this file except in compliance with
|
||||||
* the License. You may obtain a copy of the License at
|
* the License. You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.apache.solr.search;
|
package org.apache.solr.search;
|
||||||
|
|
||||||
import org.apache.solr.SolrTestCaseJ4;
|
import org.apache.solr.SolrTestCaseJ4;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
public class TestPseudoReturnFields extends SolrTestCaseJ4 {
|
public class TestPseudoReturnFields extends SolrTestCaseJ4 {
|
||||||
|
|
||||||
// :TODO: datatypes produced by the functions used may change
|
// :TODO: datatypes produced by the functions used may change
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* values of the fl param that mean all real fields
|
* values of the fl param that mean all real fields
|
||||||
*/
|
*/
|
||||||
private static String[] ALL_REAL_FIELDS = new String[] { "", "*" };
|
private static String[] ALL_REAL_FIELDS = new String[] { "", "*" };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* values of the fl param that mean all real fields and score
|
* values of the fl param that mean all real fields and score
|
||||||
*/
|
*/
|
||||||
private static String[] SCORE_AND_REAL_FIELDS = new String[] {
|
private static String[] SCORE_AND_REAL_FIELDS = new String[] {
|
||||||
"score,*", "*,score"
|
"score,*", "*,score"
|
||||||
};
|
};
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void beforeTests() throws Exception {
|
public static void beforeTests() throws Exception {
|
||||||
initCore("solrconfig.xml","schema12.xml");
|
initCore("solrconfig.xml","schema12.xml");
|
||||||
|
|
||||||
|
|
||||||
assertU(adoc("id", "42", "val_i", "1", "ssto", "X", "subject", "aaa"));
|
assertU(adoc("id", "42", "val_i", "1", "ssto", "X", "subject", "aaa"));
|
||||||
assertU(adoc("id", "43", "val_i", "9", "ssto", "X", "subject", "bbb"));
|
assertU(adoc("id", "43", "val_i", "9", "ssto", "X", "subject", "bbb"));
|
||||||
assertU(adoc("id", "44", "val_i", "4", "ssto", "X", "subject", "aaa"));
|
assertU(adoc("id", "44", "val_i", "4", "ssto", "X", "subject", "aaa"));
|
||||||
assertU(adoc("id", "45", "val_i", "6", "ssto", "X", "subject", "aaa"));
|
assertU(adoc("id", "45", "val_i", "6", "ssto", "X", "subject", "aaa"));
|
||||||
assertU(adoc("id", "46", "val_i", "3", "ssto", "X", "subject", "ggg"));
|
assertU(adoc("id", "46", "val_i", "3", "ssto", "X", "subject", "ggg"));
|
||||||
assertU(commit());
|
assertU(commit());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAllRealFields() throws Exception {
|
public void testAllRealFields() throws Exception {
|
||||||
|
|
||||||
for (String fl : ALL_REAL_FIELDS) {
|
for (String fl : ALL_REAL_FIELDS) {
|
||||||
assertQ("fl="+fl+" ... all real fields",
|
assertQ("fl="+fl+" ... all real fields",
|
||||||
req("q","*:*", "rows", "1", "fl",fl)
|
req("q","*:*", "rows", "1", "fl",fl)
|
||||||
,"//result[@numFound='5']"
|
,"//result[@numFound='5']"
|
||||||
,"//result/doc/str[@name='id']"
|
,"//result/doc/str[@name='id']"
|
||||||
,"//result/doc/int[@name='val_i']"
|
,"//result/doc/int[@name='val_i']"
|
||||||
,"//result/doc/str[@name='ssto']"
|
,"//result/doc/str[@name='ssto']"
|
||||||
,"//result/doc/str[@name='subject']"
|
,"//result/doc/str[@name='subject']"
|
||||||
|
|
||||||
,"//result/doc[count(*)=4]"
|
,"//result/doc[count(*)=4]"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testScoreAndAllRealFields() throws Exception {
|
public void testScoreAndAllRealFields() throws Exception {
|
||||||
|
|
||||||
for (String fl : SCORE_AND_REAL_FIELDS) {
|
for (String fl : SCORE_AND_REAL_FIELDS) {
|
||||||
assertQ("fl="+fl+" ... score and real fields",
|
assertQ("fl="+fl+" ... score and real fields",
|
||||||
req("q","*:*", "rows", "1", "fl",fl)
|
req("q","*:*", "rows", "1", "fl",fl)
|
||||||
,"//result[@numFound='5']"
|
,"//result[@numFound='5']"
|
||||||
,"//result/doc/str[@name='id']"
|
,"//result/doc/str[@name='id']"
|
||||||
,"//result/doc/int[@name='val_i']"
|
,"//result/doc/int[@name='val_i']"
|
||||||
,"//result/doc/str[@name='ssto']"
|
,"//result/doc/str[@name='ssto']"
|
||||||
,"//result/doc/str[@name='subject']"
|
,"//result/doc/str[@name='subject']"
|
||||||
,"//result/doc/float[@name='score']"
|
,"//result/doc/float[@name='score']"
|
||||||
|
|
||||||
,"//result/doc[count(*)=5]"
|
,"//result/doc[count(*)=5]"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testScoreAndExplicitRealFields() throws Exception {
|
public void testScoreAndExplicitRealFields() throws Exception {
|
||||||
|
|
||||||
assertQ("fl=score,val_i",
|
assertQ("fl=score,val_i",
|
||||||
req("q","*:*", "rows", "1", "fl","score,val_i")
|
req("q","*:*", "rows", "1", "fl","score,val_i")
|
||||||
,"//result[@numFound='5']"
|
,"//result[@numFound='5']"
|
||||||
,"//result/doc/int[@name='val_i']"
|
,"//result/doc/int[@name='val_i']"
|
||||||
,"//result/doc/float[@name='score']"
|
,"//result/doc/float[@name='score']"
|
||||||
|
|
||||||
,"//result/doc[count(*)=2]"
|
,"//result/doc[count(*)=2]"
|
||||||
);
|
);
|
||||||
assertQ("fl=score&fl=val_i",
|
assertQ("fl=score&fl=val_i",
|
||||||
req("q","*:*", "rows", "1", "fl","score","fl","val_i")
|
req("q","*:*", "rows", "1", "fl","score","fl","val_i")
|
||||||
,"//result[@numFound='5']"
|
,"//result[@numFound='5']"
|
||||||
,"//result/doc/int[@name='val_i']"
|
,"//result/doc/int[@name='val_i']"
|
||||||
,"//result/doc/float[@name='score']"
|
,"//result/doc/float[@name='score']"
|
||||||
|
|
||||||
,"//result/doc[count(*)=2]"
|
,"//result/doc[count(*)=2]"
|
||||||
);
|
);
|
||||||
|
|
||||||
assertQ("fl=val_i",
|
assertQ("fl=val_i",
|
||||||
req("q","*:*", "rows", "1", "fl","val_i")
|
req("q","*:*", "rows", "1", "fl","val_i")
|
||||||
,"//result[@numFound='5']"
|
,"//result[@numFound='5']"
|
||||||
,"//result/doc/int[@name='val_i']"
|
,"//result/doc/int[@name='val_i']"
|
||||||
|
|
||||||
,"//result/doc[count(*)=1]"
|
,"//result/doc[count(*)=1]"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFunctions() throws Exception {
|
public void testFunctions() throws Exception {
|
||||||
assertQ("fl=log(val_i)",
|
assertQ("fl=log(val_i)",
|
||||||
req("q","*:*", "rows", "1", "fl","log(val_i)")
|
req("q","*:*", "rows", "1", "fl","log(val_i)")
|
||||||
,"//result[@numFound='5']"
|
,"//result[@numFound='5']"
|
||||||
,"//result/doc/double[@name='log(val_i)']"
|
,"//result/doc/double[@name='log(val_i)']"
|
||||||
|
|
||||||
,"//result/doc[count(*)=1]"
|
,"//result/doc[count(*)=1]"
|
||||||
);
|
);
|
||||||
|
|
||||||
assertQ("fl=log(val_i),abs(val_i)",
|
assertQ("fl=log(val_i),abs(val_i)",
|
||||||
req("q","*:*", "rows", "1", "fl","log(val_i),abs(val_i)")
|
req("q","*:*", "rows", "1", "fl","log(val_i),abs(val_i)")
|
||||||
,"//result[@numFound='5']"
|
,"//result[@numFound='5']"
|
||||||
,"//result/doc/double[@name='log(val_i)']"
|
,"//result/doc/double[@name='log(val_i)']"
|
||||||
,"//result/doc/float[@name='abs(val_i)']"
|
,"//result/doc/float[@name='abs(val_i)']"
|
||||||
|
|
||||||
,"//result/doc[count(*)=2]"
|
,"//result/doc[count(*)=2]"
|
||||||
);
|
);
|
||||||
assertQ("fl=log(val_i)&fl=abs(val_i)",
|
assertQ("fl=log(val_i)&fl=abs(val_i)",
|
||||||
req("q","*:*", "rows", "1", "fl","log(val_i)","fl","abs(val_i)")
|
req("q","*:*", "rows", "1", "fl","log(val_i)","fl","abs(val_i)")
|
||||||
,"//result[@numFound='5']"
|
,"//result[@numFound='5']"
|
||||||
,"//result/doc/double[@name='log(val_i)']"
|
,"//result/doc/double[@name='log(val_i)']"
|
||||||
,"//result/doc/float[@name='abs(val_i)']"
|
,"//result/doc/float[@name='abs(val_i)']"
|
||||||
|
|
||||||
,"//result/doc[count(*)=2]"
|
,"//result/doc[count(*)=2]"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFunctionsAndExplicit() throws Exception {
|
public void testFunctionsAndExplicit() throws Exception {
|
||||||
assertQ("fl=log(val_i),val_i",
|
assertQ("fl=log(val_i),val_i",
|
||||||
req("q","*:*", "rows", "1", "fl","log(val_i),val_i")
|
req("q","*:*", "rows", "1", "fl","log(val_i),val_i")
|
||||||
,"//result[@numFound='5']"
|
,"//result[@numFound='5']"
|
||||||
,"//result/doc/double[@name='log(val_i)']"
|
,"//result/doc/double[@name='log(val_i)']"
|
||||||
,"//result/doc/int[@name='val_i']"
|
,"//result/doc/int[@name='val_i']"
|
||||||
|
|
||||||
,"//result/doc[count(*)=2]"
|
,"//result/doc[count(*)=2]"
|
||||||
);
|
);
|
||||||
|
|
||||||
assertQ("fl=log(val_i)&fl=val_i",
|
assertQ("fl=log(val_i)&fl=val_i",
|
||||||
req("q","*:*", "rows", "1", "fl","log(val_i)","fl","val_i")
|
req("q","*:*", "rows", "1", "fl","log(val_i)","fl","val_i")
|
||||||
,"//result[@numFound='5']"
|
,"//result[@numFound='5']"
|
||||||
,"//result/doc/double[@name='log(val_i)']"
|
,"//result/doc/double[@name='log(val_i)']"
|
||||||
,"//result/doc/int[@name='val_i']"
|
,"//result/doc/int[@name='val_i']"
|
||||||
|
|
||||||
,"//result/doc[count(*)=2]"
|
,"//result/doc[count(*)=2]"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFunctionsAndScore() throws Exception {
|
public void testFunctionsAndScore() throws Exception {
|
||||||
|
|
||||||
assertQ("fl=log(val_i),score",
|
assertQ("fl=log(val_i),score",
|
||||||
req("q","*:*", "rows", "1", "fl","log(val_i),score")
|
req("q","*:*", "rows", "1", "fl","log(val_i),score")
|
||||||
,"//result[@numFound='5']"
|
,"//result[@numFound='5']"
|
||||||
,"//result/doc/float[@name='score']"
|
,"//result/doc/float[@name='score']"
|
||||||
,"//result/doc/double[@name='log(val_i)']"
|
,"//result/doc/double[@name='log(val_i)']"
|
||||||
|
|
||||||
,"//result/doc[count(*)=2]"
|
,"//result/doc[count(*)=2]"
|
||||||
);
|
);
|
||||||
assertQ("fl=log(val_i)&fl=score",
|
assertQ("fl=log(val_i)&fl=score",
|
||||||
req("q","*:*", "rows", "1", "fl","log(val_i)","fl","score")
|
req("q","*:*", "rows", "1", "fl","log(val_i)","fl","score")
|
||||||
,"//result[@numFound='5']"
|
,"//result[@numFound='5']"
|
||||||
,"//result/doc/float[@name='score']"
|
,"//result/doc/float[@name='score']"
|
||||||
,"//result/doc/double[@name='log(val_i)']"
|
,"//result/doc/double[@name='log(val_i)']"
|
||||||
|
|
||||||
,"//result/doc[count(*)=2]"
|
,"//result/doc[count(*)=2]"
|
||||||
);
|
);
|
||||||
|
|
||||||
assertQ("fl=score,log(val_i),abs(val_i)",
|
assertQ("fl=score,log(val_i),abs(val_i)",
|
||||||
req("q","*:*", "rows", "1",
|
req("q","*:*", "rows", "1",
|
||||||
"fl","score,log(val_i),abs(val_i)")
|
"fl","score,log(val_i),abs(val_i)")
|
||||||
,"//result[@numFound='5']"
|
,"//result[@numFound='5']"
|
||||||
,"//result/doc/float[@name='score']"
|
,"//result/doc/float[@name='score']"
|
||||||
,"//result/doc/double[@name='log(val_i)']"
|
,"//result/doc/double[@name='log(val_i)']"
|
||||||
,"//result/doc/float[@name='abs(val_i)']"
|
,"//result/doc/float[@name='abs(val_i)']"
|
||||||
|
|
||||||
,"//result/doc[count(*)=3]"
|
,"//result/doc[count(*)=3]"
|
||||||
);
|
);
|
||||||
assertQ("fl=score&fl=log(val_i)&fl=abs(val_i)",
|
assertQ("fl=score&fl=log(val_i)&fl=abs(val_i)",
|
||||||
req("q","*:*", "rows", "1",
|
req("q","*:*", "rows", "1",
|
||||||
"fl","score","fl","log(val_i)","fl","abs(val_i)")
|
"fl","score","fl","log(val_i)","fl","abs(val_i)")
|
||||||
,"//result[@numFound='5']"
|
,"//result[@numFound='5']"
|
||||||
,"//result/doc/float[@name='score']"
|
,"//result/doc/float[@name='score']"
|
||||||
,"//result/doc/double[@name='log(val_i)']"
|
,"//result/doc/double[@name='log(val_i)']"
|
||||||
,"//result/doc/float[@name='abs(val_i)']"
|
,"//result/doc/float[@name='abs(val_i)']"
|
||||||
|
|
||||||
,"//result/doc[count(*)=3]"
|
,"//result/doc[count(*)=3]"
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGlobs() throws Exception {
|
public void testGlobs() throws Exception {
|
||||||
assertQ("fl=val_*",
|
assertQ("fl=val_*",
|
||||||
req("q","*:*", "rows", "1", "fl","val_*")
|
req("q","*:*", "rows", "1", "fl","val_*")
|
||||||
,"//result[@numFound='5']"
|
,"//result[@numFound='5']"
|
||||||
,"//result/doc/int[@name='val_i']"
|
,"//result/doc/int[@name='val_i']"
|
||||||
|
|
||||||
,"//result/doc[count(*)=1]"
|
,"//result/doc[count(*)=1]"
|
||||||
);
|
);
|
||||||
|
|
||||||
assertQ("fl=val_*,subj*",
|
assertQ("fl=val_*,subj*",
|
||||||
req("q","*:*", "rows", "1", "fl","val_*,subj*")
|
req("q","*:*", "rows", "1", "fl","val_*,subj*")
|
||||||
,"//result[@numFound='5']"
|
,"//result[@numFound='5']"
|
||||||
,"//result/doc/int[@name='val_i']"
|
,"//result/doc/int[@name='val_i']"
|
||||||
,"//result/doc/str[@name='subject']"
|
,"//result/doc/str[@name='subject']"
|
||||||
|
|
||||||
,"//result/doc[count(*)=2]"
|
,"//result/doc[count(*)=2]"
|
||||||
);
|
);
|
||||||
assertQ("fl=val_*&fl=subj*",
|
assertQ("fl=val_*&fl=subj*",
|
||||||
req("q","*:*", "rows", "1", "fl","val_*","fl","subj*")
|
req("q","*:*", "rows", "1", "fl","val_*","fl","subj*")
|
||||||
,"//result[@numFound='5']"
|
,"//result[@numFound='5']"
|
||||||
,"//result/doc/int[@name='val_i']"
|
,"//result/doc/int[@name='val_i']"
|
||||||
,"//result/doc/str[@name='subject']"
|
,"//result/doc/str[@name='subject']"
|
||||||
|
|
||||||
,"//result/doc[count(*)=2]"
|
,"//result/doc[count(*)=2]"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGlobsAndExplicit() throws Exception {
|
public void testGlobsAndExplicit() throws Exception {
|
||||||
assertQ("fl=val_*,id",
|
assertQ("fl=val_*,id",
|
||||||
req("q","*:*", "rows", "1", "fl","val_*,id")
|
req("q","*:*", "rows", "1", "fl","val_*,id")
|
||||||
,"//result[@numFound='5']"
|
,"//result[@numFound='5']"
|
||||||
,"//result/doc/int[@name='val_i']"
|
,"//result/doc/int[@name='val_i']"
|
||||||
,"//result/doc/str[@name='id']"
|
,"//result/doc/str[@name='id']"
|
||||||
|
|
||||||
,"//result/doc[count(*)=2]"
|
,"//result/doc[count(*)=2]"
|
||||||
);
|
);
|
||||||
|
|
||||||
assertQ("fl=val_*,subj*,id",
|
assertQ("fl=val_*,subj*,id",
|
||||||
req("q","*:*", "rows", "1", "fl","val_*,subj*,id")
|
req("q","*:*", "rows", "1", "fl","val_*,subj*,id")
|
||||||
,"//result[@numFound='5']"
|
,"//result[@numFound='5']"
|
||||||
,"//result/doc/int[@name='val_i']"
|
,"//result/doc/int[@name='val_i']"
|
||||||
,"//result/doc/str[@name='subject']"
|
,"//result/doc/str[@name='subject']"
|
||||||
,"//result/doc/str[@name='id']"
|
,"//result/doc/str[@name='id']"
|
||||||
|
|
||||||
,"//result/doc[count(*)=3]"
|
,"//result/doc[count(*)=3]"
|
||||||
);
|
);
|
||||||
assertQ("fl=val_*&fl=subj*&fl=id",
|
assertQ("fl=val_*&fl=subj*&fl=id",
|
||||||
req("q","*:*", "rows", "1", "fl","val_*","fl","subj*","fl","id")
|
req("q","*:*", "rows", "1", "fl","val_*","fl","subj*","fl","id")
|
||||||
,"//result[@numFound='5']"
|
,"//result[@numFound='5']"
|
||||||
,"//result/doc/int[@name='val_i']"
|
,"//result/doc/int[@name='val_i']"
|
||||||
,"//result/doc/str[@name='subject']"
|
,"//result/doc/str[@name='subject']"
|
||||||
,"//result/doc/str[@name='id']"
|
,"//result/doc/str[@name='id']"
|
||||||
|
|
||||||
,"//result/doc[count(*)=3]"
|
,"//result/doc[count(*)=3]"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGlobsAndScore() throws Exception {
|
public void testGlobsAndScore() throws Exception {
|
||||||
assertQ("fl=val_*,score",
|
assertQ("fl=val_*,score",
|
||||||
req("q","*:*", "rows", "1", "fl","val_*,score", "indent", "true")
|
req("q","*:*", "rows", "1", "fl","val_*,score", "indent", "true")
|
||||||
,"//result[@numFound='5']"
|
,"//result[@numFound='5']"
|
||||||
,"//result/doc/float[@name='score']"
|
,"//result/doc/float[@name='score']"
|
||||||
,"//result/doc/int[@name='val_i']"
|
,"//result/doc/int[@name='val_i']"
|
||||||
|
|
||||||
,"//result/doc[count(*)=2]"
|
,"//result/doc[count(*)=2]"
|
||||||
);
|
);
|
||||||
|
|
||||||
assertQ("fl=val_*,subj*,score",
|
assertQ("fl=val_*,subj*,score",
|
||||||
req("q","*:*", "rows", "1", "fl","val_*,subj*,score")
|
req("q","*:*", "rows", "1", "fl","val_*,subj*,score")
|
||||||
,"//result[@numFound='5']"
|
,"//result[@numFound='5']"
|
||||||
,"//result/doc/float[@name='score']"
|
,"//result/doc/float[@name='score']"
|
||||||
,"//result/doc/int[@name='val_i']"
|
,"//result/doc/int[@name='val_i']"
|
||||||
,"//result/doc/str[@name='subject']"
|
,"//result/doc/str[@name='subject']"
|
||||||
|
|
||||||
,"//result/doc[count(*)=3]"
|
,"//result/doc[count(*)=3]"
|
||||||
);
|
);
|
||||||
assertQ("fl=val_*&fl=subj*&fl=score",
|
assertQ("fl=val_*&fl=subj*&fl=score",
|
||||||
req("q","*:*", "rows", "1",
|
req("q","*:*", "rows", "1",
|
||||||
"fl","val_*","fl","subj*","fl","score")
|
"fl","val_*","fl","subj*","fl","score")
|
||||||
,"//result[@numFound='5']"
|
,"//result[@numFound='5']"
|
||||||
,"//result/doc/float[@name='score']"
|
,"//result/doc/float[@name='score']"
|
||||||
,"//result/doc/int[@name='val_i']"
|
,"//result/doc/int[@name='val_i']"
|
||||||
,"//result/doc/str[@name='subject']"
|
,"//result/doc/str[@name='subject']"
|
||||||
|
|
||||||
,"//result/doc[count(*)=3]"
|
,"//result/doc[count(*)=3]"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAugmenters() throws Exception {
|
public void testAugmenters() throws Exception {
|
||||||
assertQ("fl=[docid]",
|
assertQ("fl=[docid]",
|
||||||
req("q","*:*", "rows", "1", "fl","[docid]")
|
req("q","*:*", "rows", "1", "fl","[docid]")
|
||||||
,"//result[@numFound='5']"
|
,"//result[@numFound='5']"
|
||||||
,"//result/doc/int[@name='[docid]']"
|
,"//result/doc/int[@name='[docid]']"
|
||||||
|
|
||||||
,"//result/doc[count(*)=1]"
|
,"//result/doc[count(*)=1]"
|
||||||
);
|
);
|
||||||
|
|
||||||
assertQ("fl=[docid],[explain]",
|
assertQ("fl=[docid],[explain]",
|
||||||
req("q","*:*", "rows", "1", "fl","[docid],[explain]")
|
req("q","*:*", "rows", "1", "fl","[docid],[explain]")
|
||||||
,"//result[@numFound='5']"
|
,"//result[@numFound='5']"
|
||||||
,"//result/doc/int[@name='[docid]']"
|
,"//result/doc/int[@name='[docid]']"
|
||||||
,"//result/doc/str[@name='[explain]']"
|
,"//result/doc/str[@name='[explain]']"
|
||||||
|
|
||||||
,"//result/doc[count(*)=2]"
|
,"//result/doc[count(*)=2]"
|
||||||
);
|
);
|
||||||
assertQ("fl=[docid]&fl=[explain]",
|
assertQ("fl=[docid]&fl=[explain]",
|
||||||
req("q","*:*", "rows", "1", "fl","[docid]","fl","[explain]")
|
req("q","*:*", "rows", "1", "fl","[docid]","fl","[explain]")
|
||||||
,"//result[@numFound='5']"
|
,"//result[@numFound='5']"
|
||||||
,"//result/doc/int[@name='[docid]']"
|
,"//result/doc/int[@name='[docid]']"
|
||||||
,"//result/doc/str[@name='[explain]']"
|
,"//result/doc/str[@name='[explain]']"
|
||||||
|
|
||||||
,"//result/doc[count(*)=2]"
|
,"//result/doc[count(*)=2]"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAugmentersAndExplicit() throws Exception {
|
public void testAugmentersAndExplicit() throws Exception {
|
||||||
assertQ("fl=[docid],id",
|
assertQ("fl=[docid],id",
|
||||||
req("q","*:*", "rows", "1",
|
req("q","*:*", "rows", "1",
|
||||||
"fl","[docid],id")
|
"fl","[docid],id")
|
||||||
,"//result[@numFound='5']"
|
,"//result[@numFound='5']"
|
||||||
,"//result/doc/int[@name='[docid]']"
|
,"//result/doc/int[@name='[docid]']"
|
||||||
,"//result/doc/str[@name='id']"
|
,"//result/doc/str[@name='id']"
|
||||||
|
|
||||||
,"//result/doc[count(*)=2]"
|
,"//result/doc[count(*)=2]"
|
||||||
);
|
);
|
||||||
|
|
||||||
assertQ("fl=[docid],[explain],id",
|
assertQ("fl=[docid],[explain],id",
|
||||||
req("q","*:*", "rows", "1",
|
req("q","*:*", "rows", "1",
|
||||||
"fl","[docid],[explain],id")
|
"fl","[docid],[explain],id")
|
||||||
,"//result[@numFound='5']"
|
,"//result[@numFound='5']"
|
||||||
,"//result/doc/int[@name='[docid]']"
|
,"//result/doc/int[@name='[docid]']"
|
||||||
,"//result/doc/str[@name='[explain]']"
|
,"//result/doc/str[@name='[explain]']"
|
||||||
,"//result/doc/str[@name='id']"
|
,"//result/doc/str[@name='id']"
|
||||||
|
|
||||||
,"//result/doc[count(*)=3]"
|
,"//result/doc[count(*)=3]"
|
||||||
);
|
);
|
||||||
assertQ("fl=[docid]&fl=[explain]&fl=id",
|
assertQ("fl=[docid]&fl=[explain]&fl=id",
|
||||||
req("q","*:*", "rows", "1",
|
req("q","*:*", "rows", "1",
|
||||||
"fl","[docid]","fl","[explain]","fl","id")
|
"fl","[docid]","fl","[explain]","fl","id")
|
||||||
,"//result[@numFound='5']"
|
,"//result[@numFound='5']"
|
||||||
,"//result/doc/int[@name='[docid]']"
|
,"//result/doc/int[@name='[docid]']"
|
||||||
,"//result/doc/str[@name='[explain]']"
|
,"//result/doc/str[@name='[explain]']"
|
||||||
,"//result/doc/str[@name='id']"
|
,"//result/doc/str[@name='id']"
|
||||||
|
|
||||||
,"//result/doc[count(*)=3]"
|
,"//result/doc[count(*)=3]"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAugmentersAndScore() throws Exception {
|
public void testAugmentersAndScore() throws Exception {
|
||||||
assertQ("fl=[docid],score",
|
assertQ("fl=[docid],score",
|
||||||
req("q","*:*", "rows", "1",
|
req("q","*:*", "rows", "1",
|
||||||
"fl","[docid],score")
|
"fl","[docid],score")
|
||||||
,"//result[@numFound='5']"
|
,"//result[@numFound='5']"
|
||||||
,"//result/doc/float[@name='score']"
|
,"//result/doc/float[@name='score']"
|
||||||
,"//result/doc/int[@name='[docid]']"
|
,"//result/doc/int[@name='[docid]']"
|
||||||
|
|
||||||
,"//result/doc[count(*)=2]"
|
,"//result/doc[count(*)=2]"
|
||||||
);
|
);
|
||||||
|
|
||||||
assertQ("fl=[docid],[explain],score",
|
assertQ("fl=[docid],[explain],score",
|
||||||
req("q","*:*", "rows", "1",
|
req("q","*:*", "rows", "1",
|
||||||
"fl","[docid],[explain],score")
|
"fl","[docid],[explain],score")
|
||||||
,"//result[@numFound='5']"
|
,"//result[@numFound='5']"
|
||||||
,"//result/doc/float[@name='score']"
|
,"//result/doc/float[@name='score']"
|
||||||
,"//result/doc/int[@name='[docid]']"
|
,"//result/doc/int[@name='[docid]']"
|
||||||
,"//result/doc/str[@name='[explain]']"
|
,"//result/doc/str[@name='[explain]']"
|
||||||
|
|
||||||
,"//result/doc[count(*)=3]"
|
,"//result/doc[count(*)=3]"
|
||||||
);
|
);
|
||||||
assertQ("fl=[docid]&fl=[explain]&fl=score",
|
assertQ("fl=[docid]&fl=[explain]&fl=score",
|
||||||
req("q","*:*", "rows", "1",
|
req("q","*:*", "rows", "1",
|
||||||
"fl","[docid]","fl","[explain]","fl","score")
|
"fl","[docid]","fl","[explain]","fl","score")
|
||||||
,"//result[@numFound='5']"
|
,"//result[@numFound='5']"
|
||||||
,"//result/doc/float[@name='score']"
|
,"//result/doc/float[@name='score']"
|
||||||
,"//result/doc/int[@name='[docid]']"
|
,"//result/doc/int[@name='[docid]']"
|
||||||
,"//result/doc/str[@name='[explain]']"
|
,"//result/doc/str[@name='[explain]']"
|
||||||
|
|
||||||
,"//result/doc[count(*)=3]"
|
,"//result/doc[count(*)=3]"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAugmentersGlobsExplicitAndScoreOhMy() throws Exception {
|
public void testAugmentersGlobsExplicitAndScoreOhMy() throws Exception {
|
||||||
|
|
||||||
// NOTE: 'ssto' is the missing one
|
// NOTE: 'ssto' is the missing one
|
||||||
final List<String> fl = Arrays.asList
|
final List<String> fl = Arrays.asList
|
||||||
("id","[docid]","[explain]","score","val_*","subj*");
|
("id","[docid]","[explain]","score","val_*","subj*");
|
||||||
|
|
||||||
final int iters = atLeast(random, 10);
|
final int iters = atLeast(random, 10);
|
||||||
for (int i = 0; i< iters; i++) {
|
for (int i = 0; i< iters; i++) {
|
||||||
|
|
||||||
Collections.shuffle(fl, random);
|
Collections.shuffle(fl, random);
|
||||||
|
|
||||||
final String singleFl = StringUtils.join(fl.toArray(),',');
|
final String singleFl = StringUtils.join(fl.toArray(),',');
|
||||||
assertQ("fl=" + singleFl,
|
assertQ("fl=" + singleFl,
|
||||||
req("q","*:*", "rows", "1","fl",singleFl)
|
req("q","*:*", "rows", "1","fl",singleFl)
|
||||||
,"//result[@numFound='5']"
|
,"//result[@numFound='5']"
|
||||||
,"//result/doc/str[@name='id']"
|
,"//result/doc/str[@name='id']"
|
||||||
,"//result/doc/float[@name='score']"
|
,"//result/doc/float[@name='score']"
|
||||||
,"//result/doc/str[@name='subject']"
|
,"//result/doc/str[@name='subject']"
|
||||||
,"//result/doc/int[@name='val_i']"
|
,"//result/doc/int[@name='val_i']"
|
||||||
,"//result/doc/int[@name='[docid]']"
|
,"//result/doc/int[@name='[docid]']"
|
||||||
,"//result/doc/str[@name='[explain]']"
|
,"//result/doc/str[@name='[explain]']"
|
||||||
|
|
||||||
,"//result/doc[count(*)=6]"
|
,"//result/doc[count(*)=6]"
|
||||||
);
|
);
|
||||||
|
|
||||||
final List<String> params = new ArrayList<String>((fl.size()*2) + 4);
|
final List<String> params = new ArrayList<String>((fl.size()*2) + 4);
|
||||||
final StringBuilder info = new StringBuilder();
|
final StringBuilder info = new StringBuilder();
|
||||||
params.addAll(Arrays.asList("q","*:*", "rows", "1"));
|
params.addAll(Arrays.asList("q","*:*", "rows", "1"));
|
||||||
for (String item : fl) {
|
for (String item : fl) {
|
||||||
params.add("fl");
|
params.add("fl");
|
||||||
params.add(item);
|
params.add(item);
|
||||||
info.append("&fl=").append(item);
|
info.append("&fl=").append(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
assertQ(info.toString(),
|
assertQ(info.toString(),
|
||||||
req((String[])params.toArray(new String[0]))
|
req((String[])params.toArray(new String[0]))
|
||||||
,"//result[@numFound='5']"
|
,"//result[@numFound='5']"
|
||||||
,"//result/doc/str[@name='id']"
|
,"//result/doc/str[@name='id']"
|
||||||
,"//result/doc/float[@name='score']"
|
,"//result/doc/float[@name='score']"
|
||||||
,"//result/doc/str[@name='subject']"
|
,"//result/doc/str[@name='subject']"
|
||||||
,"//result/doc/int[@name='val_i']"
|
,"//result/doc/int[@name='val_i']"
|
||||||
,"//result/doc/int[@name='[docid]']"
|
,"//result/doc/int[@name='[docid]']"
|
||||||
,"//result/doc/str[@name='[explain]']"
|
,"//result/doc/str[@name='[explain]']"
|
||||||
|
|
||||||
,"//result/doc[count(*)=6]"
|
,"//result/doc[count(*)=6]"
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,56 +1,56 @@
|
||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
* this work for additional information regarding copyright ownership.
|
* this work for additional information regarding copyright ownership.
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
* 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 not use this file except in compliance with
|
||||||
* the License. You may obtain a copy of the License at
|
* the License. You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.apache.solr.util;
|
package org.apache.solr.util;
|
||||||
|
|
||||||
|
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
import javax.xml.xpath.XPath;
|
import javax.xml.xpath.XPath;
|
||||||
import javax.xml.xpath.XPathConstants;
|
import javax.xml.xpath.XPathConstants;
|
||||||
import javax.xml.xpath.XPathFactory;
|
import javax.xml.xpath.XPathFactory;
|
||||||
|
|
||||||
import org.apache.lucene.util.LuceneTestCase;
|
import org.apache.lucene.util.LuceneTestCase;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
import org.xml.sax.InputSource;
|
import org.xml.sax.InputSource;
|
||||||
|
|
||||||
public abstract class DOMUtilTestBase extends LuceneTestCase {
|
public abstract class DOMUtilTestBase extends LuceneTestCase {
|
||||||
|
|
||||||
private DocumentBuilder builder;
|
private DocumentBuilder builder;
|
||||||
private static final XPathFactory xpathFactory = XPathFactory.newInstance();
|
private static final XPathFactory xpathFactory = XPathFactory.newInstance();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
super.setUp();
|
super.setUp();
|
||||||
builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Node getNode( String xml, String path ) throws Exception {
|
public Node getNode( String xml, String path ) throws Exception {
|
||||||
return getNode( getDocument(xml), path );
|
return getNode( getDocument(xml), path );
|
||||||
}
|
}
|
||||||
|
|
||||||
public Node getNode( Document doc, String path ) throws Exception {
|
public Node getNode( Document doc, String path ) throws Exception {
|
||||||
XPath xpath = xpathFactory.newXPath();
|
XPath xpath = xpathFactory.newXPath();
|
||||||
return (Node)xpath.evaluate(path, doc, XPathConstants.NODE);
|
return (Node)xpath.evaluate(path, doc, XPathConstants.NODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Document getDocument( String xml ) throws Exception {
|
public Document getDocument( String xml ) throws Exception {
|
||||||
return builder.parse(new InputSource(new StringReader(xml)));
|
return builder.parse(new InputSource(new StringReader(xml)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue