From fd8a71b213828306cd8f7363a0614c890ba6e831 Mon Sep 17 00:00:00 2001 From: Steven Rowe Date: Thu, 14 Nov 2013 19:13:03 +0000 Subject: [PATCH 001/223] Allow trailing colons in CHANGES.txt section names git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1542027 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/CHANGES.txt | 2 +- lucene/site/changes/changes2html.pl | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index f655d14247b..1aafbf7050a 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -216,7 +216,7 @@ Bug Fixes deleted at a later point in time. This could cause short-term disk pollution or OOM if in-memory directories are used. (Simon Willnauer) -API Changes: +API Changes * LUCENE-5222: Add SortField.needsScores(). Previously it was not possible for a custom Sort that makes use of the relevance score to work correctly diff --git a/lucene/site/changes/changes2html.pl b/lucene/site/changes/changes2html.pl index fd94f4a13bb..61ac1c11e63 100755 --- a/lucene/site/changes/changes2html.pl +++ b/lucene/site/changes/changes2html.pl @@ -113,10 +113,13 @@ for (my $line_num = 0 ; $line_num <= $#lines ; ++$line_num) { } # Section heading: no leading whitespace, initial word capitalized, - # five words or less, and no trailing punctuation - if ( /^([A-Z]\S*(?:\s+\S+){0,4})(? Date: Thu, 14 Nov 2013 21:07:07 +0000 Subject: [PATCH 002/223] SOLR-5399: fix windows test issue git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1542080 13f79535-47bb-0310-9956-ffa450edef68 --- .../handler/component/DistributedDebugComponentTest.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/solr/core/src/test/org/apache/solr/handler/component/DistributedDebugComponentTest.java b/solr/core/src/test/org/apache/solr/handler/component/DistributedDebugComponentTest.java index 381e6859c92..06df11be9a0 100644 --- a/solr/core/src/test/org/apache/solr/handler/component/DistributedDebugComponentTest.java +++ b/solr/core/src/test/org/apache/solr/handler/component/DistributedDebugComponentTest.java @@ -62,8 +62,7 @@ public class DistributedDebugComponentTest extends SolrJettyTestBase { } private static File createSolrHome() throws Exception { - File workDir = new File(System.getProperty("tempDir", System.getProperty("java.io.tmpdir"))); - workDir = new File(workDir, DistributedDebugComponentTest.class.getName()); + File workDir = new File(TEMP_DIR, DistributedDebugComponentTest.class.getName()); setupJettyTestHome(workDir, "collection1"); FileUtils.copyDirectory(new File(workDir, "collection1"), new File(workDir, "collection2")); return workDir; @@ -71,6 +70,10 @@ public class DistributedDebugComponentTest extends SolrJettyTestBase { @AfterClass public static void afterTest() throws Exception { + collection1.shutdown(); + collection2.shutdown(); + jetty.stop(); + jetty=null; cleanUpJettyHome(solrHome); } From 7b608c2e1ff10555f7d3a3af0b5af81aa2fd14f9 Mon Sep 17 00:00:00 2001 From: Erick Erickson Date: Fri, 15 Nov 2013 00:48:08 +0000 Subject: [PATCH 003/223] SOLR-5441: the null-pointer patch addition git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1542142 13f79535-47bb-0310-9956-ffa450edef68 --- .../java/org/apache/solr/update/DirectUpdateHandler2.java | 6 ++++-- .../src/java/org/apache/solr/update/TransactionLog.java | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java b/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java index 5d1a67ccae4..ea9ea298353 100644 --- a/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java +++ b/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java @@ -842,8 +842,10 @@ public class DirectUpdateHandler2 extends UpdateHandler implements SolrCoreState lst.add("cumulative_deletesById", deleteByIdCommandsCumulative.get()); lst.add("cumulative_deletesByQuery", deleteByQueryCommandsCumulative.get()); lst.add("cumulative_errors", numErrorsCumulative.get()); - lst.add("transaction_logs_total_size", ulog.getTotalLogsSize()); - lst.add("transaction_logs_total_number", ulog.getTotalLogsNumber()); + if (this.ulog != null) { + lst.add("transaction_logs_total_size", ulog.getTotalLogsSize()); + lst.add("transaction_logs_total_number", ulog.getTotalLogsNumber()); + } return lst; } diff --git a/solr/core/src/java/org/apache/solr/update/TransactionLog.java b/solr/core/src/java/org/apache/solr/update/TransactionLog.java index ac13dd172d9..a9cefc657aa 100644 --- a/solr/core/src/java/org/apache/solr/update/TransactionLog.java +++ b/solr/core/src/java/org/apache/solr/update/TransactionLog.java @@ -564,7 +564,10 @@ public class TransactionLog { } public long getLogSize() { - return tlogFile.length(); + if (tlogFile != null) { + return tlogFile.length(); + } + return 0; } /** Returns a reader that can be used while a log is still in use. @@ -579,7 +582,6 @@ public class TransactionLog { return new FSReverseReader(); } - public class LogReader { private ChannelFastInputStream fis; private LogCodec codec = new LogCodec(resolver); From a917f0fd3e5b064912016d08ef7c0e206b0e6fd3 Mon Sep 17 00:00:00 2001 From: Shalin Shekhar Mangar Date: Fri, 15 Nov 2013 05:44:14 +0000 Subject: [PATCH 004/223] SOLR-5421: Remove double set of distrib.from param in processAdd method of DistributedUpdateProcessor git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1542177 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 3 +++ .../solr/update/processor/DistributedUpdateProcessor.java | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index f46c6d20eae..92188b0e279 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -90,6 +90,9 @@ Other Changes * SOLR-5399: Add distributed request tracking information to DebugComponent (Tomás Fernández Löbbe via Ryan Ernst) +* SOLR-5421: Remove double set of distrib.from param in processAdd method of + DistributedUpdateProcessor. (Anshum Gupta via shalin) + ================== 4.6.0 ================== diff --git a/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java b/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java index 345b3fd827b..a138200588c 100644 --- a/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java +++ b/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java @@ -593,8 +593,6 @@ public class DistributedUpdateProcessor extends UpdateRequestProcessor { zkController.getBaseUrl(), req.getCore().getName())); } - params.set("distrib.from", ZkCoreNodeProps.getCoreUrl( - zkController.getBaseUrl(), req.getCore().getName())); cmdDistrib.distribAdd(cmd, nodes, params); } From 8c02d253b2aa38ddba9dce17ea007359f7afd01a Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Fri, 15 Nov 2013 08:37:00 +0000 Subject: [PATCH 005/223] LUCENE-5283: allow top-level testcase filters. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1542198 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 5 +---- extra-targets.xml | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/build.xml b/build.xml index 6cf53b99698..01467634853 100644 --- a/build.xml +++ b/build.xml @@ -36,10 +36,7 @@ depends="check-svn-working-copy,validate,documentation-lint"/> - - - - + diff --git a/extra-targets.xml b/extra-targets.xml index 9ac1e058dcc..214c17d911e 100644 --- a/extra-targets.xml +++ b/extra-targets.xml @@ -25,6 +25,27 @@ + + + + + + + + + + + + + + + + diff --git a/solr/core/src/test-files/solr/collection1/conf/solrconfig.xml b/solr/core/src/test-files/solr/collection1/conf/solrconfig.xml index 1750afe51ba..3c4f454439a 100644 --- a/solr/core/src/test-files/solr/collection1/conf/solrconfig.xml +++ b/solr/core/src/test-files/solr/collection1/conf/solrconfig.xml @@ -234,6 +234,12 @@ + + + bogus.txt + + + diff --git a/solr/core/src/test/org/apache/solr/cloud/TestModifyConfFiles.java b/solr/core/src/test/org/apache/solr/cloud/TestModifyConfFiles.java new file mode 100644 index 00000000000..56eaf5833fa --- /dev/null +++ b/solr/core/src/test/org/apache/solr/cloud/TestModifyConfFiles.java @@ -0,0 +1,96 @@ +package org.apache.solr.cloud; +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.apache.solr.client.solrj.impl.HttpSolrServer; +import org.apache.solr.client.solrj.request.QueryRequest; +import org.apache.solr.common.cloud.SolrZkClient; +import org.apache.solr.common.params.ModifiableSolrParams; + +public class TestModifyConfFiles extends AbstractFullDistribZkTestBase { + + public TestModifyConfFiles() { + super(); + } + + @Override + public void doTest() throws Exception { + int which = r.nextInt(clients.size()); + HttpSolrServer client = (HttpSolrServer) clients.get(which); + + ModifiableSolrParams params = new ModifiableSolrParams(); + params.set("op", "write"); + params.set("file", "schema.xml"); + QueryRequest request = new QueryRequest(params); + request.setPath("/admin/file"); + try { + client.request(request); + fail("Should have caught exception"); + } catch (Exception e) { + assertEquals(e.getMessage(), "Input stream list was null for admin file write operation."); + } + + params.remove("file"); + params.set("stream.body", "Testing rewrite of schema.xml file."); + request = new QueryRequest(params); + request.setPath("/admin/file"); + try { + client.request(request); + fail("Should have caught exception"); + } catch (Exception e) { + assertEquals(e.getMessage(), "No file name specified for write operation."); + } + + params.set("file", "bogus.txt"); + request = new QueryRequest(params); + request.setPath("/admin/file"); + try { + client.request(request); + fail("Should have caught exception"); + } catch (Exception e) { + assertEquals(e.getMessage(), "Can not access: bogus.txt"); + } + + params.set("file", "schema.xml"); + request = new QueryRequest(params); + request.setPath("/admin/file"); + + client.request(request); + + SolrZkClient zkClient = cloudClient.getZkStateReader().getZkClient(); + String contents = new String(zkClient.getData("/configs/conf1/schema.xml", null, null, true), "UTF-8"); + + //String schema = getFileContentFromZooKeeper("schema.xml"); + + assertTrue("Schema contents should have changed!", "Testing rewrite of schema.xml file.".equals(contents)); + + // Create a velocity/whatever node. Put a bit of data in it. See if you can change it. + zkClient.makePath("/configs/conf1/velocity/test.vm", false, true); + + params.set("stream.body", "Some bogus stuff for a test."); + params.set("file", "velocity/test.vm"); + request = new QueryRequest(params); + request.setPath("/admin/file"); + + client.request(request); + + contents = new String(zkClient.getData("/configs/conf1/velocity/test.vm", null, null, true), "UTF-8"); + assertTrue("Should have found new content in a velocity/test.vm.", + contents.indexOf("Some bogus stuff for a test.") != -1); + } + +} diff --git a/solr/core/src/test/org/apache/solr/schema/ModifyConfFileTest.java b/solr/core/src/test/org/apache/solr/schema/ModifyConfFileTest.java new file mode 100644 index 00000000000..9ce47685160 --- /dev/null +++ b/solr/core/src/test/org/apache/solr/schema/ModifyConfFileTest.java @@ -0,0 +1,122 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.schema; + +import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule; +import org.apache.commons.codec.Charsets; +import org.apache.commons.io.FileUtils; +import org.apache.solr.SolrTestCaseJ4; +import org.apache.solr.common.params.ModifiableSolrParams; +import org.apache.solr.common.util.ContentStream; +import org.apache.solr.common.util.ContentStreamBase; +import org.apache.solr.core.CoreContainer; +import org.apache.solr.core.SolrCore; +import org.apache.solr.request.LocalSolrQueryRequest; +import org.apache.solr.request.SolrRequestHandler; +import org.apache.solr.response.SolrQueryResponse; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.RuleChain; +import org.junit.rules.TestRule; + +import java.io.File; +import java.util.ArrayList; + +public class ModifyConfFileTest extends SolrTestCaseJ4 { + private File solrHomeDirectory = new File(TEMP_DIR, this.getClass().getName()); + @Rule + public TestRule solrTestRules = RuleChain.outerRule(new SystemPropertiesRestoreRule()); + + private CoreContainer init() throws Exception { + System.setProperty("solr.test.sys.prop1", "propone"); + System.setProperty("solr.test.sys.prop2", "proptwo"); + + if (solrHomeDirectory.exists()) { + FileUtils.deleteDirectory(solrHomeDirectory); + } + assertTrue("Failed to mkdirs workDir", solrHomeDirectory.mkdirs()); + + copySolrHomeToTemp(solrHomeDirectory, "core1", true); + FileUtils.write(new File(new File(solrHomeDirectory, "core1"), "core.properties"), "", Charsets.UTF_8.toString()); + final CoreContainer cores = new CoreContainer(solrHomeDirectory.getAbsolutePath()); + cores.load(); + return cores; + } + + @Test + public void testConfigWrite() throws Exception { + + final CoreContainer cc = init(); + try { + //final CoreAdminHandler admin = new CoreAdminHandler(cc); + + SolrCore core = cc.getCore("core1"); + SolrQueryResponse rsp = new SolrQueryResponse(); + SolrRequestHandler handler = core.getRequestHandler("/admin/file"); + + ModifiableSolrParams params = params("file","schema.xml", "op","write"); + core.execute(handler, new LocalSolrQueryRequest(core, params), rsp); + assertEquals(rsp.getException().getMessage(), "Input stream list was null for admin file write operation."); + + params = params("op", "write", "stream.body", "Testing rewrite of schema.xml file."); + core.execute(handler, new LocalSolrQueryRequest(core, params), rsp); + assertEquals(rsp.getException().getMessage(), "No file name specified for write operation."); + + + params = params("op", "write", "file", "bogus.txt"); + core.execute(handler, new LocalSolrQueryRequest(core, params), rsp); + assertEquals(rsp.getException().getMessage(), "Can not access: bogus.txt"); + + ArrayList streams = new ArrayList( 2 ); + streams.add( new ContentStreamBase.StringStream( "Testing rewrite of schema.xml file." ) ); + //streams.add( new ContentStreamBase.StringStream( "there" ) ); + + params = params("op", "write", "file", "schema.xml", "stream.body", "Testing rewrite of schema.xml file."); + LocalSolrQueryRequest locReq = new LocalSolrQueryRequest(core, params); + locReq.setContentStreams(streams); + core.execute(handler, locReq, rsp); + + String contents = FileUtils.readFileToString(new File(core.getCoreDescriptor().getInstanceDir(), "conf/schema.xml")); + assertEquals("Schema contents should have changed!", "Testing rewrite of schema.xml file.", contents); + + streams.add(new ContentStreamBase.StringStream("This should barf")); + locReq = new LocalSolrQueryRequest(core, params); + locReq.setContentStreams(streams); + core.execute(handler, locReq, rsp); + assertEquals(rsp.getException().getMessage(), "More than one input stream was found for admin file write operation."); + + streams.clear(); + streams.add(new ContentStreamBase.StringStream("Some bogus stuff for a test.")); + params = params("op", "write", "file", "velocity/test.vm"); + locReq = new LocalSolrQueryRequest(core, params); + locReq.setContentStreams(streams); + core.execute(handler, locReq, rsp); + contents = FileUtils.readFileToString(new File(core.getCoreDescriptor().getInstanceDir(), + "conf/velocity/test.vm")); + assertEquals("Schema contents should have changed!", "Some bogus stuff for a test.", contents); + + core.close(); + } finally { + cc.shutdown(); + if (solrHomeDirectory.exists()) { + FileUtils.deleteDirectory(solrHomeDirectory); + } + } + + } +} diff --git a/solr/example/solr/collection1/conf/solrconfig.xml b/solr/example/solr/collection1/conf/solrconfig.xml index f908392acc7..54f8af36a63 100755 --- a/solr/example/solr/collection1/conf/solrconfig.xml +++ b/solr/example/solr/collection1/conf/solrconfig.xml @@ -1116,7 +1116,9 @@ --> diff --git a/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java b/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java index 3e4c0736cf4..a719845aefd 100644 --- a/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java +++ b/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java @@ -1662,11 +1662,18 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase { // the stock files in there. Seems to be indicated for some tests when we remove the default, hard-coded // solr.xml from being automatically synthesized from SolrConfigXmlOld.DEFAULT_SOLR_XML. public static void copySolrHomeToTemp(File dstRoot, String collection) throws IOException { + copySolrHomeToTemp(dstRoot, collection, false); + } + public static void copySolrHomeToTemp(File dstRoot, String collection, boolean newStyle) throws IOException { if (!dstRoot.exists()) { assertTrue("Failed to make subdirectory ", dstRoot.mkdirs()); } - FileUtils.copyFile(new File(SolrTestCaseJ4.TEST_HOME(), "solr.xml"), new File(dstRoot, "solr.xml")); + if (newStyle) { + FileUtils.copyFile(new File(SolrTestCaseJ4.TEST_HOME(), "solr-no-core.xml"), new File(dstRoot, "solr.xml")); + } else { + FileUtils.copyFile(new File(SolrTestCaseJ4.TEST_HOME(), "solr.xml"), new File(dstRoot, "solr.xml")); + } File subHome = new File(dstRoot, collection + File.separator + "conf"); String top = SolrTestCaseJ4.TEST_HOME() + "/collection1/conf"; From a40ee0f5bcdc9a9c2245c8641c63b245576c6fb4 Mon Sep 17 00:00:00 2001 From: Erick Erickson Date: Sat, 16 Nov 2013 00:53:41 +0000 Subject: [PATCH 013/223] SOLR-5448: ShowFileRequestHandler treats everything as Directory, when in Cloud-Mode git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1542436 13f79535-47bb-0310-9956-ffa450edef68 --- .../handler/admin/ShowFileRequestHandler.java | 2 +- .../solr/cloud/TestModifyConfFiles.java | 18 +++++++++++++++++ .../solr/schema/ModifyConfFileTest.java | 20 +++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/solr/core/src/java/org/apache/solr/handler/admin/ShowFileRequestHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/ShowFileRequestHandler.java index 2c5a361b613..224723904b5 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/ShowFileRequestHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/ShowFileRequestHandler.java @@ -297,7 +297,7 @@ public class ShowFileRequestHandler extends RequestHandlerBase SimpleOrderedMap fileInfo = new SimpleOrderedMap(); files.add(f, fileInfo); - List fchildren = zkClient.getChildren(adminFile, null, true); + List fchildren = zkClient.getChildren(adminFile + "/" + f, null, true); if (fchildren.size() > 0) { fileInfo.add("directory", true); } else { diff --git a/solr/core/src/test/org/apache/solr/cloud/TestModifyConfFiles.java b/solr/core/src/test/org/apache/solr/cloud/TestModifyConfFiles.java index 56eaf5833fa..f633b77ee7c 100644 --- a/solr/core/src/test/org/apache/solr/cloud/TestModifyConfFiles.java +++ b/solr/core/src/test/org/apache/solr/cloud/TestModifyConfFiles.java @@ -20,6 +20,8 @@ import org.apache.solr.client.solrj.impl.HttpSolrServer; import org.apache.solr.client.solrj.request.QueryRequest; import org.apache.solr.common.cloud.SolrZkClient; import org.apache.solr.common.params.ModifiableSolrParams; +import org.apache.solr.common.util.NamedList; +import org.apache.solr.common.util.SimpleOrderedMap; public class TestModifyConfFiles extends AbstractFullDistribZkTestBase { @@ -91,6 +93,22 @@ public class TestModifyConfFiles extends AbstractFullDistribZkTestBase { contents = new String(zkClient.getData("/configs/conf1/velocity/test.vm", null, null, true), "UTF-8"); assertTrue("Should have found new content in a velocity/test.vm.", contents.indexOf("Some bogus stuff for a test.") != -1); + + params = new ModifiableSolrParams(); + request = new QueryRequest(params); + request.setPath("/admin/file"); + NamedList res = client.request(request); + + NamedList files = (NamedList)res.get("files"); + assertNotNull("Should have gotten files back", files); + SimpleOrderedMap schema = (SimpleOrderedMap)files.get("schema.xml"); + assertNotNull("Should have a schema returned", schema); + assertNull("Schema.xml should not be a directory", schema.get("directory")); + + SimpleOrderedMap velocity = (SimpleOrderedMap)files.get("velocity"); + assertNotNull("Should have velocity dir returned", velocity); + + assertTrue("Velocity should be a directory", (boolean)velocity.get("directory")); } } diff --git a/solr/core/src/test/org/apache/solr/schema/ModifyConfFileTest.java b/solr/core/src/test/org/apache/solr/schema/ModifyConfFileTest.java index 9ce47685160..60420887dbb 100644 --- a/solr/core/src/test/org/apache/solr/schema/ModifyConfFileTest.java +++ b/solr/core/src/test/org/apache/solr/schema/ModifyConfFileTest.java @@ -24,6 +24,8 @@ import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.util.ContentStream; import org.apache.solr.common.util.ContentStreamBase; +import org.apache.solr.common.util.NamedList; +import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.core.CoreContainer; import org.apache.solr.core.SolrCore; import org.apache.solr.request.LocalSolrQueryRequest; @@ -110,6 +112,24 @@ public class ModifyConfFileTest extends SolrTestCaseJ4 { "conf/velocity/test.vm")); assertEquals("Schema contents should have changed!", "Some bogus stuff for a test.", contents); + streams.clear(); + params = params(); + locReq = new LocalSolrQueryRequest(core, params); + core.execute(handler, locReq, rsp); + + NamedList res = rsp.getValues(); + + NamedList files = (NamedList)res.get("files"); + assertNotNull("Should have gotten files back", files); + SimpleOrderedMap schema = (SimpleOrderedMap)files.get("schema.xml"); + assertNotNull("Should have a schema returned", schema); + assertNull("Schema.xml should not be a directory", schema.get("directory")); + + SimpleOrderedMap velocity = (SimpleOrderedMap)files.get("velocity"); + assertNotNull("Should have velocity dir returned", velocity); + + assertTrue("Velocity should be a directory", (boolean)velocity.get("directory")); + core.close(); } finally { cc.shutdown(); From d34549874cdb6118cc26a2a855711029f31813f7 Mon Sep 17 00:00:00 2001 From: Shalin Shekhar Mangar Date: Sat, 16 Nov 2013 09:16:57 +0000 Subject: [PATCH 014/223] SOLR-5447: Add a QParserPlugin for Lucene's SimpleQueryParser git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1542486 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 3 + .../org/apache/solr/search/QParserPlugin.java | 3 +- .../solr/search/SimpleQParserPlugin.java | 173 +++++++++++++++ .../conf/schema-simpleqpplugin.xml | 51 +++++ .../solr/search/TestSimpleQParserPlugin.java | 208 ++++++++++++++++++ .../solr/common/params/SimpleParams.java | 29 +++ 6 files changed, 466 insertions(+), 1 deletion(-) create mode 100644 solr/core/src/java/org/apache/solr/search/SimpleQParserPlugin.java create mode 100644 solr/core/src/test-files/solr/collection1/conf/schema-simpleqpplugin.xml create mode 100644 solr/core/src/test/org/apache/solr/search/TestSimpleQParserPlugin.java create mode 100644 solr/solrj/src/java/org/apache/solr/common/params/SimpleParams.java diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index eedba58ca73..97eea1c638c 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -84,6 +84,9 @@ New Features * SOLR-5287: You can edit files in the conf directory from the admin UI (Erick Erickson, Stefan Matheis) +* SOLR-5447: Add a QParserPlugin for Lucene's SimpleQueryParser. + (Jack Conradson via shalin) + Bug Fixes ---------------------- diff --git a/solr/core/src/java/org/apache/solr/search/QParserPlugin.java b/solr/core/src/java/org/apache/solr/search/QParserPlugin.java index 4cbe8b38dfc..a0f572d2a86 100644 --- a/solr/core/src/java/org/apache/solr/search/QParserPlugin.java +++ b/solr/core/src/java/org/apache/solr/search/QParserPlugin.java @@ -52,7 +52,8 @@ public abstract class QParserPlugin implements NamedListInitializedPlugin, SolrI MaxScoreQParserPlugin.NAME, MaxScoreQParserPlugin.class, BlockJoinParentQParserPlugin.NAME, BlockJoinParentQParserPlugin.class, BlockJoinChildQParserPlugin.NAME, BlockJoinChildQParserPlugin.class, - CollapsingQParserPlugin.NAME, CollapsingQParserPlugin.class + CollapsingQParserPlugin.NAME, CollapsingQParserPlugin.class, + SimpleQParserPlugin.NAME, SimpleQParserPlugin.class }; /** return a {@link QParser} */ diff --git a/solr/core/src/java/org/apache/solr/search/SimpleQParserPlugin.java b/solr/core/src/java/org/apache/solr/search/SimpleQParserPlugin.java new file mode 100644 index 00000000000..5e5c6e837ad --- /dev/null +++ b/solr/core/src/java/org/apache/solr/search/SimpleQParserPlugin.java @@ -0,0 +1,173 @@ +package org.apache.solr.search; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.apache.lucene.queryparser.simple.SimpleQueryParser; +import org.apache.lucene.search.BooleanClause; +import org.apache.lucene.search.Query; +import org.apache.solr.common.params.CommonParams; +import org.apache.solr.common.params.SimpleParams; +import org.apache.solr.common.params.SolrParams; +import org.apache.solr.common.util.NamedList; +import org.apache.solr.parser.QueryParser; +import org.apache.solr.request.SolrQueryRequest; +import org.apache.solr.util.SolrPluginUtils; + +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +/** + * Create a query from the input value that will be parsed by Lucene's SimpleQueryParser. + * See {@link org.apache.lucene.queryparser.simple.SimpleQueryParser} for details on the exact syntax allowed + * to be used for queries. + *
+ * The following options may be applied for parsing the query. + *
    + *
  • + * q.operations - Used to enable specific operations for parsing. The operations that can be enabled are + * and, not, or, prefix, phrase, precedence, escape, and whitespace. By default all operations + * are enabled. All operations can be disabled by passing in an empty string to this parameter. + *
  • + *
  • + * q.op - Used to specify the operator to be used if whitespace is a delimiter. Either 'AND' or 'OR' + * can be specified for this parameter. Any other string will cause an exception to be thrown. + * If this parameter is not specified 'OR' will be used by default. + *
  • + *
  • + * qf - The list of query fields and boosts to use when building the simple query. The format is the following: + * fieldA^1.0 fieldB^2.2. A field can also be specified without a boost by simply listing the + * field as fieldA fieldB. Any field without a boost will default to use a boost of 1.0. + *
  • + *
  • + * df - An override for the default field specified in the schema or a default field if one is not specified + * in the schema. If qf is not specified the default field will be used as the field to run the query + * against. + *
  • + *
+ */ +public class SimpleQParserPlugin extends QParserPlugin { + /** The name that can be used to specify this plugin should be used to parse the query. */ + public static String NAME = "simple"; + + /** Enables {@code AND} operator (+) */ + private static final String AND_OPERATOR = "AND"; + /** Enables {@code NOT} operator (-) */ + private static final String NOT_OPERATOR = "NOT"; + /** Enables {@code OR} operator (|) */ + private static final String OR_OPERATOR = "OR"; + /** Enables {@code PREFIX} operator (*) */ + private static final String PREFIX_OPERATOR = "PREFIX"; + /** Enables {@code PHRASE} operator (") */ + private static final String PHRASE_OPERATOR = "PHRASE"; + /** Enables {@code PRECEDENCE} operators: {@code (} and {@code )} */ + private static final String PRECEDENCE_OPERATORS = "PRECEDENCE"; + /** Enables {@code ESCAPE} operator (\) */ + private static final String ESCAPE_OPERATOR = "ESCAPE"; + /** Enables {@code WHITESPACE} operators: ' ' '\n' '\r' '\t' */ + private static final String WHITESPACE_OPERATOR = "WHITESPACE"; + + /** Map of string operators to their int counterparts in SimpleQueryParser. */ + private static final Map OPERATORS = new HashMap(); + + /* Setup the map of possible operators. */ + static { + OPERATORS.put(AND_OPERATOR, SimpleQueryParser.AND_OPERATOR); + OPERATORS.put(NOT_OPERATOR, SimpleQueryParser.NOT_OPERATOR); + OPERATORS.put(OR_OPERATOR, SimpleQueryParser.OR_OPERATOR); + OPERATORS.put(PREFIX_OPERATOR, SimpleQueryParser.PREFIX_OPERATOR); + OPERATORS.put(PHRASE_OPERATOR, SimpleQueryParser.PHRASE_OPERATOR); + OPERATORS.put(PRECEDENCE_OPERATORS, SimpleQueryParser.PRECEDENCE_OPERATORS); + OPERATORS.put(ESCAPE_OPERATOR, SimpleQueryParser.ESCAPE_OPERATOR); + OPERATORS.put(WHITESPACE_OPERATOR, SimpleQueryParser.WHITESPACE_OPERATOR); + } + + /** No initialization is necessary so this method is empty. */ + @Override + public void init(NamedList args) { + } + + /** Returns a QParser that will create a query by using Lucene's SimpleQueryParser. */ + @Override + public QParser createParser(String qstr, SolrParams localParams, SolrParams params, SolrQueryRequest req) { + // Some of the parameters may come in through localParams, so combine them with params. + SolrParams defaultParams = SolrParams.wrapDefaults(localParams, params); + + // This will be used to specify what fields and boosts will be used by SimpleQueryParser. + Map queryFields = SolrPluginUtils.parseFieldBoosts(defaultParams.get(SimpleParams.QF)); + + if (queryFields.isEmpty()) { + // It qf is not specified setup up the queryFields map to use the defaultField. + String defaultField = QueryParsing.getDefaultField(req.getSchema(), defaultParams.get(CommonParams.DF)); + + if (defaultField == null) { + // A query cannot be run without having a field or set of fields to run against. + throw new IllegalStateException("Neither " + SimpleParams.QF + ", " + CommonParams.DF + + ", nor the default search field are present."); + } + + queryFields.put(defaultField, 1.0F); + } + else { + for (Map.Entry queryField : queryFields.entrySet()) { + if (queryField.getValue() == null) { + // Some fields may be specified without a boost, so default the boost to 1.0 since a null value + // will not be accepted by SimpleQueryParser. + queryField.setValue(1.0F); + } + } + } + + // Setup the operations that are enabled for the query. + int enabledOps = 0; + String opParam = defaultParams.get(SimpleParams.QO); + + if (opParam == null) { + // All operations will be enabled. + enabledOps = -1; + } else { + // Parse the specified enabled operations to be used by the query. + String[] operations = opParam.split(","); + + for (String operation : operations) { + Integer enabledOp = OPERATORS.get(operation.trim().toUpperCase(Locale.getDefault())); + + if (enabledOp != null) { + enabledOps |= enabledOp; + } + } + } + + // Create a SimpleQueryParser using the analyzer from the schema. + final SimpleQueryParser parser = new SimpleQueryParser(req.getSchema().getAnalyzer(), queryFields, enabledOps); + + // Set the default operator to be either 'AND' or 'OR' for the query. + QueryParser.Operator defaultOp = QueryParsing.getQueryParserDefaultOperator(req.getSchema(), defaultParams.get(QueryParsing.OP)); + + if (defaultOp == QueryParser.Operator.AND) { + parser.setDefaultOperator(BooleanClause.Occur.MUST); + } + + // Return a QParser that wraps a SimpleQueryParser. + return new QParser(qstr, localParams, params, req) { + public Query parse() throws SyntaxError { + return parser.parse(qstr); + } + }; + } +} diff --git a/solr/core/src/test-files/solr/collection1/conf/schema-simpleqpplugin.xml b/solr/core/src/test-files/solr/collection1/conf/schema-simpleqpplugin.xml new file mode 100644 index 00000000000..e6724421c91 --- /dev/null +++ b/solr/core/src/test-files/solr/collection1/conf/schema-simpleqpplugin.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text0 + id + diff --git a/solr/core/src/test/org/apache/solr/search/TestSimpleQParserPlugin.java b/solr/core/src/test/org/apache/solr/search/TestSimpleQParserPlugin.java new file mode 100644 index 00000000000..0e2a0a502e3 --- /dev/null +++ b/solr/core/src/test/org/apache/solr/search/TestSimpleQParserPlugin.java @@ -0,0 +1,208 @@ +package org.apache.solr.search; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.apache.solr.SolrTestCaseJ4; +import org.junit.BeforeClass; +import org.junit.Test; + +/** Simple tests for SimpleQParserPlugin. */ +public class TestSimpleQParserPlugin extends SolrTestCaseJ4 { + @BeforeClass + public static void beforeClass() throws Exception { + initCore("solrconfig-basic.xml","schema-simpleqpplugin.xml"); + index(); + } + + public static void index() throws Exception { + assertU(adoc("id", "42", "text0", "t0 t0 t0", "text1", "t0 t1 t2", "text-keyword0", "kw0 kw0 kw0")); + assertU(adoc("id", "43", "text0", "t0 t1 t2", "text1", "t3 t4 t5", "text-keyword0", "kw0 kw1 kw2")); + assertU(adoc("id", "44", "text0", "t0 t1 t1", "text1", "t6 t7 t8", "text-keyword0", "kw3 kw4 kw5")); + assertU(adoc("id", "45", "text0", "t0 t0 t1", "text1", "t9 t10 t11", "text-keyword0", "kw6 kw7 kw8")); + assertU(adoc("id", "46", "text0", "t1 t1 t1", "text1", "t12 t13 t14", "text-keyword0", "kw9 kw10 kw11")); + assertU(adoc("id", "47", "text0", "and", "text1", "+", "text-keyword0", "+")); + assertU(adoc("id", "48", "text0", "not", "text1", "-", "text-keyword0", "-")); + assertU(adoc("id", "49", "text0", "or", "text1", "|", "text-keyword0", "|")); + assertU(adoc("id", "50", "text0", "prefix", "text1", "t*", "text-keyword0", "kw*")); + assertU(adoc("id", "51", "text0", "phrase", "text1", "\"", "text-keyword0", "\"")); + assertU(adoc("id", "52", "text0", "open", "text1", "(", "text-keyword0", "(")); + assertU(adoc("id", "53", "text0", "close", "text1", ")", "text-keyword0", ")")); + assertU(adoc("id", "54", "text0", "escape", "text1", "\\", "text-keyword0", "\\")); + assertU(adoc("id", "55", "text0", "whitespace", "text1", "whitespace", "text-keyword0", " ")); + assertU(adoc("id", "55", "text0", "whitespace", "text1", "whitespace", "text-keyword0", "\n")); + assertU(commit()); + } + + @Test + public void testQueryFields() throws Exception { + assertJQ(req("defType", "simple", "qf", "text0^2 text1 text-keyword0", "q", "t3"), "/response/numFound==1"); + assertJQ(req("defType", "simple", "qf", "text0^3 text1^4 text-keyword0^0.55", "q", "t0"), "/response/numFound==4"); + assertJQ(req("defType", "simple", "qf", "text-keyword0^9.2", "q", "\"kw9 kw10 kw11\""), "/response/numFound==1"); + assertJQ(req("defType", "simple", "qf", "text-keyword0", "q", "kw9 kw10 kw11"), "/response/numFound==0"); + assertJQ(req("defType", "simple", "qf", "text1 text-keyword0", "q", "kw9"), "/response/numFound==0"); + assertJQ(req("defType", "simple", "qf", "text0", "q", "t2"), "/response/numFound==1"); + assertJQ(req("defType", "simple", "qf", "text0^1.1 text1^0.9", "q", "t2 t9 t12"), "/response/numFound==4"); + } + + @Test + public void testDefaultField() throws Exception { + assertJQ(req("defType", "simple", "q", "t2 t9 t12"), "/response/numFound==1"); + assertJQ(req("defType", "simple", "q", "t3"), "/response/numFound==0"); + assertJQ(req("defType", "simple", "df", "text1", "q", "t2 t9 t12"), "/response/numFound==3"); + assertJQ(req("defType", "simple", "df", "text1", "q", "t3"), "/response/numFound==1"); + assertJQ(req("defType", "simple", "df", "text-keyword0", "q", "\"kw9 kw10 kw11\""), "/response/numFound==1"); + assertJQ(req("defType", "simple", "df", "text-keyword0", "q", "kw9 kw10 kw11"), "/response/numFound==0"); + } + + @Test + public void testQueryFieldPriority() throws Exception { + assertJQ(req("defType", "simple", "qf", "text0^2 text1 text-keyword0", "df", "text0", "q", "t3"), "/response/numFound==1"); + } + + @Test + public void testOnlyAndOperatorEnabledDisabled() throws Exception { + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", "+", + "q.operators", "NOT, OR, PHRASE, PREFIX, PRECEDENCE, ESCAPE, WHITESPACE"), "/response/numFound==1"); + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", "-", + "q.operators", "NOT, OR, PHRASE, PREFIX, PRECEDENCE, ESCAPE, WHITESPACE"), "/response/numFound==0"); + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", "+", + "q.operators", "AND"), "/response/numFound==0"); + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", "-", + "q.operators", "AND"), "/response/numFound==1"); + } + + @Test + public void testOnlyNotOperatorEnabledDisabled() throws Exception { + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", "-", + "q.operators", "AND, OR, PHRASE, PREFIX, PRECEDENCE, ESCAPE, WHITESPACE"), "/response/numFound==1"); + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", "|", + "q.operators", "AND, OR, PHRASE, PREFIX, PRECEDENCE, ESCAPE, WHITESPACE"), "/response/numFound==0"); + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", "-", + "q.operators", "NOT"), "/response/numFound==0"); + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", "|", + "q.operators", "NOT"), "/response/numFound==1"); + } + + @Test + public void testOnlyOrOperatorEnabledDisabled() throws Exception { + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", "|", + "q.operators", "AND, NOT, PHRASE, PREFIX, PRECEDENCE, ESCAPE, WHITESPACE"), "/response/numFound==1"); + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", "\"", + "q.operators", "AND, NOT, PHRASE, PREFIX, PRECEDENCE, ESCAPE, WHITESPACE"), "/response/numFound==0"); + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", "|", + "q.operators", "OR"), "/response/numFound==0"); + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", "\"", + "q.operators", "OR"), "/response/numFound==1"); + } + + @Test + public void testOnlyPhraseOperatorEnabledDisabled() throws Exception { + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", "\"", + "q.operators", "AND, NOT, OR, PREFIX, PRECEDENCE, ESCAPE, WHITESPACE"), "/response/numFound==1"); + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", "|", + "q.operators", "AND, NOT, OR, PREFIX, PRECEDENCE, ESCAPE, WHITESPACE"), "/response/numFound==0"); + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", "\"", + "q.operators", "PHRASE"), "/response/numFound==0"); + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", "|", + "q.operators", "PHRASE"), "/response/numFound==1"); + } + + @Test + public void testOnlyPrefixOperatorEnabledDisabled() throws Exception { + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", "t*", + "q.operators", "AND, NOT, OR, PHRASE, PRECEDENCE, ESCAPE, WHITESPACE"), "/response/numFound==1"); + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", "(", + "q.operators", "AND, NOT, OR, PHRASE, PRECEDENCE, ESCAPE, WHITESPACE"), "/response/numFound==0"); + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", "t*", + "q.operators", "PREFIX"), "/response/numFound==6"); + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", "(", + "q.operators", "PREFIX"), "/response/numFound==1"); + } + + @Test + public void testOnlyPrecedenceOperatorEnabledDisabled() throws Exception { + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", "(", + "q.operators", "AND, NOT, OR, PHRASE, PREFIX, ESCAPE, WHITESPACE"), "/response/numFound==1"); + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", "\\", + "q.operators", "AND, NOT, OR, PHRASE, PREFIX, ESCAPE, WHITESPACE"), "/response/numFound==0"); + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", "(", + "q.operators", "PRECEDENCE"), "/response/numFound==0"); + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", "\\", + "q.operators", "PRECEDENCE"), "/response/numFound==1"); + + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", ")", + "q.operators", "AND, NOT, OR, PHRASE, PREFIX, ESCAPE, WHITESPACE"), "/response/numFound==1"); + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", "\\", + "q.operators", "AND, NOT, OR, PHRASE, PREFIX, ESCAPE, WHITESPACE"), "/response/numFound==0"); + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", ")", + "q.operators", "PRECEDENCE"), "/response/numFound==0"); + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", "\\", + "q.operators", "PRECEDENCE"), "/response/numFound==1"); + } + + @Test + public void testOnlyEscapeOperatorEnabledDisabled() throws Exception { + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", "\\", + "q.operators", "AND, NOT, OR, PHRASE, PREFIX, PRECEDENCE, WHITESPACE"), "/response/numFound==1"); + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", "\n", + "q.operators", "AND, NOT, OR, PHRASE, PREFIX, PRECEDENCE, WHITESPACE"), "/response/numFound==0"); + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", "\\", + "q.operators", "ESCAPE"), "/response/numFound==0"); + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", "\n", + "q.operators", "ESCAPE"), "/response/numFound==1"); + } + + @Test + public void testOnlyWhitespaceOperatorEnabledDisabled() throws Exception { + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", "\n", + "q.operators", "AND, NOT, OR, PHRASE, PREFIX, PRECEDENCE, ESCAPE"), "/response/numFound==1"); + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", "\\", + "q.operators", "AND, NOT, OR, PHRASE, PREFIX, PRECEDENCE, ESCAPE"), "/response/numFound==0"); + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", "\n", + "q.operators", "WHITESPACE"), "/response/numFound==0"); + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", "\\", + "q.operators", "WHITESPACE"), "/response/numFound==1"); + } + + @Test + public void testArbitraryOperatorsEnabledDisabled() throws Exception { + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", "kw0+kw1+kw2| \\ ", + "q.operators", "AND, NOT, OR, PHRASE"), "/response/numFound==1"); + assertJQ(req("defType", "simple", "qf", "text0 text1 text-keyword0", "q", "t1 + t2 \\", + "q.operators", "AND, WHITESPACE"), "/response/numFound==3"); + assertJQ(req("defType", "simple", "qf", "text0 text-keyword0", "q", "t0 + (-t1 -t2) |", + "q.operators", "AND, NOT, PRECEDENCE, WHITESPACE"), "/response/numFound==4"); + } + + @Test + public void testNoOperators() throws Exception { + assertJQ(req("defType", "simple", "qf", "text1 text-keyword0", "q", "kw0 kw1 kw2", + "q.operators", ""), "/response/numFound==1"); + assertJQ(req("defType", "simple", "qf", "text1", "q", "t1 t2 t3", + "q.operators", ""), "/response/numFound==2"); + } + + @Test + public void testDefaultOperator() throws Exception { + assertJQ(req("defType", "simple", "qf", "text1 text-keyword0", "q", "t2 t3", + "q.op", "AND"), "/response/numFound==0"); + assertJQ(req("defType", "simple", "qf", "text0 text-keyword0", "q", "t0 t2", + "q.op", "AND"), "/response/numFound==1"); + assertJQ(req("defType", "simple", "qf", "text1", "q", "t2 t3"), "/response/numFound==2"); + } +} diff --git a/solr/solrj/src/java/org/apache/solr/common/params/SimpleParams.java b/solr/solrj/src/java/org/apache/solr/common/params/SimpleParams.java new file mode 100644 index 00000000000..1fd89030f30 --- /dev/null +++ b/solr/solrj/src/java/org/apache/solr/common/params/SimpleParams.java @@ -0,0 +1,29 @@ +package org.apache.solr.common.params; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Parameters used by the SimpleQParser. + */ +public interface SimpleParams { + /** Query fields and boosts. */ + public static String QF = "qf"; + + /** Override the currently enabled/disabled query operators. */ + public static String QO = "q.operators"; +} From 653297153bf4a2da858ea7247e29ae3a7fee4f3e Mon Sep 17 00:00:00 2001 From: Shalin Shekhar Mangar Date: Sat, 16 Nov 2013 13:20:54 +0000 Subject: [PATCH 015/223] SOLR-5447: Added a test for simple query parser in QueryEqualityTest git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1542507 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/solr/search/QueryEqualityTest.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/solr/core/src/test/org/apache/solr/search/QueryEqualityTest.java b/solr/core/src/test/org/apache/solr/search/QueryEqualityTest.java index 626999910eb..d1f5e0fc767 100644 --- a/solr/core/src/test/org/apache/solr/search/QueryEqualityTest.java +++ b/solr/core/src/test/org/apache/solr/search/QueryEqualityTest.java @@ -744,6 +744,17 @@ public class QueryEqualityTest extends SolrTestCaseJ4 { doAssertParserCoverage = true; } + public void testQuerySimple() throws Exception { + SolrQueryRequest req = req("myField","foo_s"); + try { + assertQueryEquals("simple", req, + "{!simple f=$myField}asdf", + "{!simple f=$myField v=asdf}", + "{!simple f=foo_s}asdf"); + } finally { + req.close(); + } + } /** * NOTE: defType is not only used to pick the parser, but also to record From a30b4ef94db2edd67a51bdb2748e4405de828a66 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Sat, 16 Nov 2013 17:25:28 +0000 Subject: [PATCH 016/223] SOLR-5439: raise so timeout for this client to 60s from 30s - also remove sync idiom that I see failing under contention git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1542536 13f79535-47bb-0310-9956-ffa450edef68 --- .../solr/cloud/AbstractFullDistribZkTestBase.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java b/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java index 19905abe35a..35f3b292386 100644 --- a/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java +++ b/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java @@ -257,7 +257,7 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes server.getLbServer().getHttpClient().getParams() .setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 5000); server.getLbServer().getHttpClient().getParams() - .setParameter(CoreConnectionPNames.SO_TIMEOUT, 30000); + .setParameter(CoreConnectionPNames.SO_TIMEOUT, 60000); return server; } @@ -1732,12 +1732,14 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes } } - volatile CloudSolrServer commondCloudSolrServer; + private CloudSolrServer commondCloudSolrServer; + protected CloudSolrServer getCommonCloudSolrServer() { - if (commondCloudSolrServer == null) { - synchronized(this) { + synchronized (this) { + if (commondCloudSolrServer == null) { try { - commondCloudSolrServer = new CloudSolrServer(zkServer.getZkAddress(), random().nextBoolean()); + commondCloudSolrServer = new CloudSolrServer(zkServer.getZkAddress(), + random().nextBoolean()); commondCloudSolrServer.setParallelUpdates(random().nextBoolean()); commondCloudSolrServer.setDefaultCollection(DEFAULT_COLLECTION); commondCloudSolrServer.connect(); From dc651394b117b4d5a2aa439bd6b4ee4a4a45592c Mon Sep 17 00:00:00 2001 From: Stefan Matheis Date: Sat, 16 Nov 2013 18:54:15 +0000 Subject: [PATCH 017/223] SOLR-4612: Admin UI - Analysis Screen contains empty table-columns git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1542547 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 2 ++ solr/webapp/web/js/scripts/analysis.js | 32 ++++++++------------------ 2 files changed, 11 insertions(+), 23 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 97eea1c638c..a1a18abf7bf 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -99,6 +99,8 @@ Bug Fixes * SOLR-5445: Proxied responses should propagate all headers rather than the first one for each key. (Patrick Hunt, Mark Miller) +* SOLR-4612: Admin UI - Analysis Screen contains empty table-columns (steffkes) + Other Changes --------------------- diff --git a/solr/webapp/web/js/scripts/analysis.js b/solr/webapp/web/js/scripts/analysis.js index 8aee1299be6..2fc6e9a5fa1 100644 --- a/solr/webapp/web/js/scripts/analysis.js +++ b/solr/webapp/web/js/scripts/analysis.js @@ -355,32 +355,18 @@ sammy.get if( 0 !== type_length ) { var global_elements_count = 0; - for( var i = 0; i < analysis_data[type].length; i += 2 ) + if( 'string' === typeof analysis_data[type][1] ) { - if( 'string' === typeof analysis_data[type][i+1] ) - { - analysis_data[type][i+1] = [{ 'text': analysis_data[type][i+1] }] - } - - var tmp = {}; - var cols = analysis_data[type][i+1].filter - ( - function( obj ) - { - var obj_position = obj.position || 0; - if( !tmp[obj_position] ) - { - tmp[obj_position] = true; - return true; - } - - return false; - } - ); - - global_elements_count = Math.max( global_elements_count, cols.length ); + analysis_data[type][1] = [{ 'text': analysis_data[type][1] }] } + var c = analysis_data[type][1].length; + for( var i = 0; i < c; i++ ) + { + global_elements_count = Math.max( analysis_data[type][1][i].position || 0, global_elements_count ); + } + + var content = '
' + "\n"; content += '' + "\n"; From f43a661898ecbe936c22e66eef5a396de17d727a Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Sat, 16 Nov 2013 22:30:04 +0000 Subject: [PATCH 018/223] SOLR-5451: SyncStrategy closes it's http connection manager before the executor that uses it in it's close method. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1542604 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 3 +++ solr/core/src/java/org/apache/solr/cloud/SyncStrategy.java | 6 ++++-- .../src/java/org/apache/solr/common/util/ExecutorUtil.java | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index a1a18abf7bf..b2bb52a48a0 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -101,6 +101,9 @@ Bug Fixes * SOLR-4612: Admin UI - Analysis Screen contains empty table-columns (steffkes) +* SOLR-5451: SyncStrategy closes it's http connection manager before the + executor that uses it in it's close method. (Mark Miller) + Other Changes --------------------- diff --git a/solr/core/src/java/org/apache/solr/cloud/SyncStrategy.java b/solr/core/src/java/org/apache/solr/cloud/SyncStrategy.java index 8249d2732e8..7ab219ec38a 100644 --- a/solr/core/src/java/org/apache/solr/cloud/SyncStrategy.java +++ b/solr/core/src/java/org/apache/solr/cloud/SyncStrategy.java @@ -258,12 +258,14 @@ public class SyncStrategy { public void close() { this.isClosed = true; try { - client.getConnectionManager().shutdown(); + ExecutorUtil.shutdownAndAwaitTermination(recoveryCmdExecutor); } catch (Throwable e) { SolrException.log(log, e); } + + // we must close connection manager *after* shutting down executor try { - ExecutorUtil.shutdownNowAndAwaitTermination(recoveryCmdExecutor); + client.getConnectionManager().shutdown(); } catch (Throwable e) { SolrException.log(log, e); } diff --git a/solr/solrj/src/java/org/apache/solr/common/util/ExecutorUtil.java b/solr/solrj/src/java/org/apache/solr/common/util/ExecutorUtil.java index 777e32353ba..0c058c94af4 100644 --- a/solr/solrj/src/java/org/apache/solr/common/util/ExecutorUtil.java +++ b/solr/solrj/src/java/org/apache/solr/common/util/ExecutorUtil.java @@ -51,7 +51,7 @@ public class ExecutorUtil { while (!shutdown) { try { // Wait a while for existing tasks to terminate - shutdown = pool.awaitTermination(30, TimeUnit.SECONDS); + shutdown = pool.awaitTermination(60, TimeUnit.SECONDS); } catch (InterruptedException ie) { // Preserve interrupt status Thread.currentThread().interrupt(); From add510e6a9c027f7b435228ad9a5d47bc743724e Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Sun, 17 Nov 2013 00:38:59 +0000 Subject: [PATCH 019/223] SOLR-5453: Raise recovery socket read timeouts. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1542620 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 2 ++ .../java/org/apache/solr/cloud/RecoveryStrategy.java | 4 +--- .../src/java/org/apache/solr/cloud/SyncStrategy.java | 7 +++---- .../core/src/java/org/apache/solr/update/PeerSync.java | 10 +++------- .../org/apache/solr/update/StreamingSolrServers.java | 1 + .../src/test/org/apache/solr/cloud/SyncSliceTest.java | 2 +- 6 files changed, 11 insertions(+), 15 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index b2bb52a48a0..d63ea8bb02c 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -104,6 +104,8 @@ Bug Fixes * SOLR-5451: SyncStrategy closes it's http connection manager before the executor that uses it in it's close method. (Mark Miller) +* SOLR-5453: Raise recovery socket read timeouts. (Mark Miller) + Other Changes --------------------- diff --git a/solr/core/src/java/org/apache/solr/cloud/RecoveryStrategy.java b/solr/core/src/java/org/apache/solr/cloud/RecoveryStrategy.java index 6ad73c8ba62..596027b0f04 100644 --- a/solr/core/src/java/org/apache/solr/cloud/RecoveryStrategy.java +++ b/solr/core/src/java/org/apache/solr/cloud/RecoveryStrategy.java @@ -186,7 +186,6 @@ public class RecoveryStrategy extends Thread implements ClosableThread { HttpSolrServer server = new HttpSolrServer(leaderUrl); try { server.setConnectionTimeout(30000); - server.setSoTimeout(60000); UpdateRequest ureq = new UpdateRequest(); ureq.setParams(new ModifiableSolrParams()); ureq.getParams().set(DistributedUpdateProcessor.COMMIT_END_POINT, true); @@ -202,8 +201,7 @@ public class RecoveryStrategy extends Thread implements ClosableThread { throws SolrServerException, IOException { HttpSolrServer server = new HttpSolrServer(leaderBaseUrl); try { - server.setConnectionTimeout(45000); - server.setSoTimeout(120000); + server.setConnectionTimeout(30000); WaitForState prepCmd = new WaitForState(); prepCmd.setCoreName(leaderCoreName); prepCmd.setNodeName(zkController.getNodeName()); diff --git a/solr/core/src/java/org/apache/solr/cloud/SyncStrategy.java b/solr/core/src/java/org/apache/solr/cloud/SyncStrategy.java index 7ab219ec38a..274528552e7 100644 --- a/solr/core/src/java/org/apache/solr/cloud/SyncStrategy.java +++ b/solr/core/src/java/org/apache/solr/cloud/SyncStrategy.java @@ -67,8 +67,7 @@ public class SyncStrategy { ModifiableSolrParams params = new ModifiableSolrParams(); params.set(HttpClientUtil.PROP_MAX_CONNECTIONS, 10000); params.set(HttpClientUtil.PROP_MAX_CONNECTIONS_PER_HOST, 20); - params.set(HttpClientUtil.PROP_CONNECTION_TIMEOUT, 15000); - params.set(HttpClientUtil.PROP_SO_TIMEOUT, 60000); + params.set(HttpClientUtil.PROP_CONNECTION_TIMEOUT, 30000); params.set(HttpClientUtil.PROP_USE_RETRY, false); client = HttpClientUtil.createClient(params); } @@ -284,8 +283,8 @@ public class SyncStrategy { HttpSolrServer server = new HttpSolrServer(baseUrl, client); try { - server.setConnectionTimeout(15000); - server.setSoTimeout(60000); + server.setConnectionTimeout(30000); + server.setSoTimeout(120000); server.request(recoverRequestCmd); } catch (Throwable t) { SolrException.log(log, ZkCoreNodeProps.getCoreUrl(leaderProps) + ": Could not tell a replica to recover", t); diff --git a/solr/core/src/java/org/apache/solr/update/PeerSync.java b/solr/core/src/java/org/apache/solr/update/PeerSync.java index fe57116bbc1..e4507d5aebe 100644 --- a/solr/core/src/java/org/apache/solr/update/PeerSync.java +++ b/solr/core/src/java/org/apache/solr/update/PeerSync.java @@ -17,6 +17,9 @@ package org.apache.solr.update; +import static org.apache.solr.update.processor.DistributedUpdateProcessor.DistribPhase.FROMLEADER; +import static org.apache.solr.update.processor.DistributingUpdateProcessorFactory.DISTRIB_UPDATE_PARAM; + import java.io.IOException; import java.net.ConnectException; import java.net.SocketException; @@ -37,7 +40,6 @@ import org.apache.solr.cloud.ZkController; import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrInputDocument; import org.apache.solr.common.params.ModifiableSolrParams; -import org.apache.solr.common.util.NamedList; import org.apache.solr.common.util.StrUtils; import org.apache.solr.core.SolrCore; import org.apache.solr.handler.component.HttpShardHandlerFactory; @@ -48,16 +50,11 @@ import org.apache.solr.handler.component.ShardResponse; import org.apache.solr.request.LocalSolrQueryRequest; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; -import org.apache.solr.update.processor.DistributedUpdateProcessorFactory; -import org.apache.solr.update.processor.RunUpdateProcessorFactory; import org.apache.solr.update.processor.UpdateRequestProcessor; import org.apache.solr.update.processor.UpdateRequestProcessorChain; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import static org.apache.solr.update.processor.DistributingUpdateProcessorFactory.DISTRIB_UPDATE_PARAM; -import static org.apache.solr.update.processor.DistributedUpdateProcessor.DistribPhase.FROMLEADER; - /** @lucene.experimental */ public class PeerSync { public static Logger log = LoggerFactory.getLogger(PeerSync.class); @@ -88,7 +85,6 @@ public class PeerSync { params.set(HttpClientUtil.PROP_MAX_CONNECTIONS_PER_HOST, 20); params.set(HttpClientUtil.PROP_MAX_CONNECTIONS, 10000); params.set(HttpClientUtil.PROP_CONNECTION_TIMEOUT, 30000); - params.set(HttpClientUtil.PROP_SO_TIMEOUT, 30000); params.set(HttpClientUtil.PROP_USE_RETRY, false); client = HttpClientUtil.createClient(params); } diff --git a/solr/core/src/java/org/apache/solr/update/StreamingSolrServers.java b/solr/core/src/java/org/apache/solr/update/StreamingSolrServers.java index 02ec08939e6..3af7c328b8a 100644 --- a/solr/core/src/java/org/apache/solr/update/StreamingSolrServers.java +++ b/solr/core/src/java/org/apache/solr/update/StreamingSolrServers.java @@ -45,6 +45,7 @@ public class StreamingSolrServers { params.set(HttpClientUtil.PROP_MAX_CONNECTIONS, 128); params.set(HttpClientUtil.PROP_MAX_CONNECTIONS_PER_HOST, 32); params.set(HttpClientUtil.PROP_FOLLOW_REDIRECTS, false); + params.set(HttpClientUtil.PROP_CONNECTION_TIMEOUT, 30000); httpClient = HttpClientUtil.createClient(params); } diff --git a/solr/core/src/test/org/apache/solr/cloud/SyncSliceTest.java b/solr/core/src/test/org/apache/solr/cloud/SyncSliceTest.java index ad49dc1ba99..65ad0e8b851 100644 --- a/solr/core/src/test/org/apache/solr/cloud/SyncSliceTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/SyncSliceTest.java @@ -134,8 +134,8 @@ public class SyncSliceTest extends AbstractFullDistribZkTestBase { baseUrl = baseUrl.substring(0, baseUrl.length() - "collection1".length()); HttpSolrServer baseServer = new HttpSolrServer(baseUrl); + // we only set the connect timeout, not so timeout baseServer.setConnectionTimeout(15000); - baseServer.setSoTimeout(60000); baseServer.request(request); waitForThingsToLevelOut(15); From 7f478c999975321a30237a48384bb8abed055f3a Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Sun, 17 Nov 2013 01:00:16 +0000 Subject: [PATCH 020/223] tests: null out a couple statics git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1542625 13f79535-47bb-0310-9956-ffa450edef68 --- .../solr/handler/component/DistributedDebugComponentTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/solr/core/src/test/org/apache/solr/handler/component/DistributedDebugComponentTest.java b/solr/core/src/test/org/apache/solr/handler/component/DistributedDebugComponentTest.java index 06df11be9a0..62cdfd41249 100644 --- a/solr/core/src/test/org/apache/solr/handler/component/DistributedDebugComponentTest.java +++ b/solr/core/src/test/org/apache/solr/handler/component/DistributedDebugComponentTest.java @@ -72,6 +72,8 @@ public class DistributedDebugComponentTest extends SolrJettyTestBase { public static void afterTest() throws Exception { collection1.shutdown(); collection2.shutdown(); + collection1 = null; + collection2 = null; jetty.stop(); jetty=null; cleanUpJettyHome(solrHome); From 496f27ad6699405a953ef1a443aef2c9a635f229 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Sun, 17 Nov 2013 02:44:59 +0000 Subject: [PATCH 021/223] tests: add useful commented out logging options for solrcloud debug to log4j test config file git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1542634 13f79535-47bb-0310-9956-ffa450edef68 --- solr/core/src/test-files/log4j.properties | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/solr/core/src/test-files/log4j.properties b/solr/core/src/test-files/log4j.properties index 9b74a5f22b2..74a5d358eb4 100644 --- a/solr/core/src/test-files/log4j.properties +++ b/solr/core/src/test-files/log4j.properties @@ -8,3 +8,17 @@ log4j.appender.CONSOLE.layout.ConversionPattern=%-5p - %d{yyyy-MM-dd HH:mm:ss.SS log4j.logger.org.apache.zookeeper=WARN log4j.logger.org.apache.hadoop=WARN + +#log4j.logger.org.apache.solr.update.processor.LogUpdateProcessor=DEBUG +#log4j.logger.org.apache.solr.update.processor.DistributedUpdateProcessor=DEBUG +#log4j.logger.org.apache.solr.update.PeerSync=DEBUG +#log4j.logger.org.apache.solr.core.CoreContainer=DEBUG +#log4j.logger.org.apache.solr.cloud.RecoveryStrategy=DEBUG +#log4j.logger.org.apache.solr.cloud.SyncStrategy=DEBUG +#log4j.logger.org.apache.solr.handler.admin.CoreAdminHandler=DEBUG +#log4j.logger.org.apache.solr.cloud.ZkController=DEBUG +#log4j.logger.org.apache.solr.update.DefaultSolrCoreState=DEBUG +#log4j.logger.org.apache.solr.common.cloud.ConnectionManager=DEBUG +#log4j.logger.org.apache.solr.update.UpdateLog.level=FINE +#log4j.logger.org.apache.solr.cloud.ChaosMonkey=DEBUG +#log4j.logger.org.apache.solr.update.TransactionLog=DEBUG \ No newline at end of file From 2aec8731a47bbc973beb8a0360e626e053da1385 Mon Sep 17 00:00:00 2001 From: Stefan Matheis Date: Sun, 17 Nov 2013 13:23:23 +0000 Subject: [PATCH 022/223] SOLR-5446: Admin UI - Allow changing Schema and Config git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1542720 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 2 + solr/webapp/web/admin.html | 1 + solr/webapp/web/css/styles/cloud.css | 6 - solr/webapp/web/css/styles/common.css | 6 + solr/webapp/web/css/styles/files.css | 102 +++++++ solr/webapp/web/css/styles/menu.css | 1 + solr/webapp/web/img/ico/drive-upload.png | Bin 0 -> 746 bytes .../web/js/lib/jquery.ajaxfileupload.js | 2 + solr/webapp/web/js/main.js | 1 + solr/webapp/web/js/require.js | 3 +- solr/webapp/web/js/scripts/app.js | 1 + solr/webapp/web/js/scripts/files.js | 254 ++++++++++++++++++ solr/webapp/web/tpl/files.html | 50 ++++ 13 files changed, 422 insertions(+), 7 deletions(-) create mode 100644 solr/webapp/web/css/styles/files.css create mode 100644 solr/webapp/web/img/ico/drive-upload.png create mode 100644 solr/webapp/web/js/scripts/files.js create mode 100644 solr/webapp/web/tpl/files.html diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index d63ea8bb02c..c1244373ce4 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -87,6 +87,8 @@ New Features * SOLR-5447: Add a QParserPlugin for Lucene's SimpleQueryParser. (Jack Conradson via shalin) +* SOLR-5446: Admin UI - Allow changing Schema and Config (steffkes) + Bug Fixes ---------------------- diff --git a/solr/webapp/web/admin.html b/solr/webapp/web/admin.html index 13ee241b093..1180658a16f 100644 --- a/solr/webapp/web/admin.html +++ b/solr/webapp/web/admin.html @@ -30,6 +30,7 @@ limitations under the License. + diff --git a/solr/webapp/web/css/styles/cloud.css b/solr/webapp/web/css/styles/cloud.css index 912143214eb..ac275298b38 100644 --- a/solr/webapp/web/css/styles/cloud.css +++ b/solr/webapp/web/css/styles/cloud.css @@ -244,12 +244,6 @@ limitations under the License. /* tree */ -#content #cloud .tree a.active -{ - background-color: #f0f0f0; - color: #00f; -} - #content #cloud #legend { border: 1px solid #f0f0f0; diff --git a/solr/webapp/web/css/styles/common.css b/solr/webapp/web/css/styles/common.css index 8e671caf706..8dcfeb2dd2c 100644 --- a/solr/webapp/web/css/styles/common.css +++ b/solr/webapp/web/css/styles/common.css @@ -606,6 +606,12 @@ pre.syntax .tex .formula background:#beebff; border:1px solid #99defd; padding:0 2px 0 1px; } +#content .tree a.active +{ + background-color: #f0f0f0; + color: #00f; +} + #content .tree a .jstree-icon { background-image: url( ../../img/ico/folder.png ); diff --git a/solr/webapp/web/css/styles/files.css b/solr/webapp/web/css/styles/files.css new file mode 100644 index 00000000000..8e11588fd7d --- /dev/null +++ b/solr/webapp/web/css/styles/files.css @@ -0,0 +1,102 @@ +/* + +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*/ + +#content #files #tree +{ + float: left; + width: 20%; +} + +#content #files .show #tree +{ + overflow: hidden; +} + +#content #files #file-content +{ + display: none; + float: right; + position: relative; + width: 78%; + min-height: 100px +} + +#content #files .show #file-content +{ + display: block; +} + +#content #files #file-content .close +{ + background-image: url( ../../img/ico/cross-0.png ); + background-position: 50% 50%; + display: block; + height: 20px; + position: absolute; + right: 0; + top: 0; + width: 20px; +} + +#content #files #file-content .close:hover +{ + background-image: url( ../../img/ico/cross-1.png ); +} + +#content #files #file-content .close span +{ + display: none; +} + +#content #files #file-content form .buttons button +{ + float: right; +} + +#content #files #file-content textarea +{ + display: block; + height: 500px; + margin-bottom: 10px; + width: 99%; +} + +#content #files #file-content button span +{ + background-image: url( ../../img/ico/disk-black.png ); +} + +#content #files #file-content form.upload +{ + border-top: 1px solid #c0c0c0; + margin-top: 20px; + padding-top: 20px; + padding-bottom: 20px; +} + +#content #files #file-content .upload input +{ + border: 0; + float: left; +} + +#content #files #file-content .upload button span +{ + background-image: url( ../../img/ico/drive-upload.png ); +} \ No newline at end of file diff --git a/solr/webapp/web/css/styles/menu.css b/solr/webapp/web/css/styles/menu.css index 5e8057024c9..4fba2e86974 100644 --- a/solr/webapp/web/css/styles/menu.css +++ b/solr/webapp/web/css/styles/menu.css @@ -275,6 +275,7 @@ limitations under the License. #core-menu .config a { background-image: url( ../../img/ico/gear.png ); } #core-menu .analysis a { background-image: url( ../../img/ico/funnel.png ); } #core-menu .documents a { background-image: url( ../../img/ico/documents-stack.png ); } +#core-menu .files a { background-image: url( ../../img/ico/folder.png ); } #core-menu .schema-browser a { background-image: url( ../../img/ico/book-open-text.png ); } #core-menu .replication a { background-image: url( ../../img/ico/node.png ); } #core-menu .distribution a { background-image: url( ../../img/ico/node-select.png ); } diff --git a/solr/webapp/web/img/ico/drive-upload.png b/solr/webapp/web/img/ico/drive-upload.png new file mode 100644 index 0000000000000000000000000000000000000000..93589e4da36620cdb65ac61873c97c76dd5fd355 GIT binary patch literal 746 zcmV1&W>84^hl#VOYFJ#X2yELbG1 z^bY$=b1=4x;W@7N`a{Idj-!jj3j*Zs?iL^#&4A-_;ZzVjacz5%0W4id)AwQS6k(8r z;rq`aCHh-5o`)ETKoEos4dw1-hSbzh_rUt*;l&^b%D(S^_FR{EL3oBem`6uZGh^F! z?#|6&wNf!rE*qGh>{rvhiaCk`7%?r!G1>Nq}h-9WXvOWMbkbF#{Moen1Z>xU$>;B3m~Do+`) zpb7BD!I^`6n~X-+AP&(Bqh4oQTf3Yr?8*WIY|{H67LTLX{SL*fgh7UYzJrxk7(^cw zMI3Rbu!2dpRjlx_y}f7v+cdwi4b@yiPjCRw^Fo&=UV#-Gm<(31?5b;8AeMCj@NBy_ zB^A)a9d(X_%Vx7}2MT@vTeMX0?`qI}cufu(p@X&+`n^3nJNq;qkEbllglQTii|qRB zIV6b`fngY13kxsE7hZ*cYPE_)BEiNI5$0j*w8H|vk(4Ot!!N2x}} zy1Keeu#wTx3!w|!cK&i;zV)&8wYXic*Q2FUsgLEsIz6NTa&SqKq|5k^a$R?w9DJf> c^``&>09jXAhv@$a5&!@I07*qoM6N<$g4fw%X8-^I literal 0 HcmV?d00001 diff --git a/solr/webapp/web/js/lib/jquery.ajaxfileupload.js b/solr/webapp/web/js/lib/jquery.ajaxfileupload.js index eb538534fe2..0488bf97a0c 100644 --- a/solr/webapp/web/js/lib/jquery.ajaxfileupload.js +++ b/solr/webapp/web/js/lib/jquery.ajaxfileupload.js @@ -149,6 +149,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI // with uninit() later, to allow updating that settings if ($element.data('ajaxUploader-setup') === true) return; + /* $element.change(function () { // since a new image was selected, reset the marker uploading_file = false; @@ -159,6 +160,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI upload_file(); } }); + //*/ if (settings.submit_button == null) { // do nothing diff --git a/solr/webapp/web/js/main.js b/solr/webapp/web/js/main.js index 792a185851b..c9b09952450 100644 --- a/solr/webapp/web/js/main.js +++ b/solr/webapp/web/js/main.js @@ -41,6 +41,7 @@ require 'lib/order!scripts/dataimport', 'lib/order!scripts/dashboard', 'lib/order!scripts/file', + 'lib/order!scripts/files', 'lib/order!scripts/index', 'lib/order!scripts/java-properties', 'lib/order!scripts/logging', diff --git a/solr/webapp/web/js/require.js b/solr/webapp/web/js/require.js index 8ee0051c79a..9ddc7c314f9 100644 --- a/solr/webapp/web/js/require.js +++ b/solr/webapp/web/js/require.js @@ -9388,7 +9388,8 @@ jQuery.extend({ return this; }, - url : s.url + url : s.url, + data : s.data }; // Callback for when everything is done diff --git a/solr/webapp/web/js/scripts/app.js b/solr/webapp/web/js/scripts/app.js index 1d797aa2759..2ea303d98b6 100644 --- a/solr/webapp/web/js/scripts/app.js +++ b/solr/webapp/web/js/scripts/app.js @@ -367,6 +367,7 @@ var solr_admin = function( app_config ) '
  • Config
  • ' + "\n" + '
  • Dataimport
  • ' + "\n" + '
  • Documents
  • ' + "\n" + + '
  • Files
  • ' + "\n" + '
  • Ping
  • ' + "\n" + '
  • Plugins / Stats
  • ' + "\n" + '
  • Query
  • ' + "\n" + diff --git a/solr/webapp/web/js/scripts/files.js b/solr/webapp/web/js/scripts/files.js new file mode 100644 index 00000000000..02f2a945ffb --- /dev/null +++ b/solr/webapp/web/js/scripts/files.js @@ -0,0 +1,254 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// #/:core/files +sammy.get +( + new RegExp( app.core_regex_base + '\\/(files)$' ), + function( context ) + { + core_basepath = this.active_core.attr( 'data-basepath' ); + current_core = context.params.splat[0]; + + var content_element = $( '#content' ); + + var file_endpoint = core_basepath + '/admin/file'; + + var path = context.path.split( '?' ); + var selected_file = null; + if( path && path[1] ) + { + selected_file = path[1].split( '=' ).pop(); + } + + $.get + ( + 'tpl/files.html', + function( template ) + { + content_element + .html( template ); + + var frame_element = $( '#frame', content_element ); + + var tree_callback = function( event, data ) + { + $( 'li[data-file].jstree-closed', event.currentTarget ) + .filter + ( + function( index, element ) + { + return selected_file && 0 === selected_file.indexOf( $( element ).data( 'file' ) ); + } + ) + .each + ( + function( index, element ) + { + data.inst.open_node( element ); + } + ); + + if( selected_file ) + { + $( 'li[data-file="' + selected_file.replace( /\/$/, '' ) + '"] > a', event.currentTarget ) + .addClass( 'active' ); + } + }; + + $( '#tree', frame_element ) + .jstree + ( + { + plugins : [ 'json_data', 'sort' ], + json_data : { + ajax: { + url : file_endpoint + '?wt=json', + data : function( n ) + { + if( -1 === n ) + return null; + + return { + file : n.attr( 'data-file' ) + }; + }, + success : function( response, status, xhr ) + { + var files = []; + + for( var file in response.files ) + { + var is_directory = response.files[file].directory; + var prefix = xhr.data ? xhr.data.file + '/' : '' + + var item = { + data: { + title : file, + attr : { + href : '#/' + current_core + '/files?file=' + prefix + file + } + }, + attr : { + 'data-file' : prefix + file + } + }; + + if( is_directory ) + { + item.state = 'closed'; + item.data.attr.href += '/'; + } + + files.push( item ); + } + + return files; + } + }, + progressive_render : true + }, + core : { + animation : 0 + } + } + ) + .on + ( + 'loaded.jstree', + tree_callback + ) + .on + ( + 'open_node.jstree', + tree_callback + ); + + if( selected_file && '/' !== selected_file.substr( -1 ) ) + { + frame_element + .addClass( 'show' ); + + var endpoint = file_endpoint + '?file=' + selected_file; + var public_url = window.location.protocol + '//' + window.location.host + endpoint; + + $( '#url', frame_element ) + .text( public_url ) + .attr( 'href', public_url ); + + var form = $( 'form.modify', frame_element ); + + form + .attr( 'action', file_endpoint + '?wt=json&op=write&file=' + selected_file ) + .ajaxForm + ( + { + context : form, + beforeSubmit: function( arr, form, options ) + { + $( 'button span', form ) + .addClass( 'loader' ); + }, + success : function( response, status, xhr ) + { + $( 'button span', this ) + .removeClass( 'loader' ); + + var button = $( 'button', this ); + + button + .addClass( 'success' ); + + window.setTimeout + ( + function() + { + button + .removeClass( 'success' ); + }, + 1000 + ); + } + } + ); + + var load_file = function() + { + $( 'form textarea', frame_element ) + .load( endpoint ); + } + load_file(); + + $( 'form.upload', frame_element ) + .on + ( + 'submit', + function( event ) + { + $( 'form input', frame_element ) + .ajaxfileupload + ( + { + action: endpoint + '&op=write&wt=json', + validate_extensions: false, + upload_now: true, + onStart: function () + { + $( 'form.upload button span', frame_element ) + .addClass( 'loader' ); + }, + onCancel: function () + { + $( 'form.upload button span', frame_element ) + .removeClass( 'loader' ); + }, + onComplete: function( response ) + { + $( 'form.upload button span', frame_element ) + .removeClass( 'loader' ); + + var button = $( 'form.upload button', frame_element ); + + button + .addClass( 'success' ); + + load_file(); + + $( 'body' ) + .animate( { scrollTop: 0 }, 500 ); + + window.setTimeout + ( + function() + { + button + .removeClass( 'success' ); + }, + 1000 + ); + } + } + ); + + return false; + } + ); + } + } + ); + } +); \ No newline at end of file diff --git a/solr/webapp/web/tpl/files.html b/solr/webapp/web/tpl/files.html new file mode 100644 index 00000000000..6d0f63bf50b --- /dev/null +++ b/solr/webapp/web/tpl/files.html @@ -0,0 +1,50 @@ + +
    + +
    + +
    #tree
    +
    + + + +
    + + + +
    + +
    + + + +
    + + + +
    + +
    + + + +
    + +
    + +
    \ No newline at end of file From da585d78edf8367d8faf1f4f133edd7074eb8366 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Sun, 17 Nov 2013 14:20:10 +0000 Subject: [PATCH 023/223] tests: tweak timeouts git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1542730 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/solr/cloud/AbstractFullDistribZkTestBase.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java b/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java index 35f3b292386..9a360e211af 100644 --- a/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java +++ b/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java @@ -255,9 +255,7 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes server.setParallelUpdates(random().nextBoolean()); if (defaultCollection != null) server.setDefaultCollection(defaultCollection); server.getLbServer().getHttpClient().getParams() - .setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 5000); - server.getLbServer().getHttpClient().getParams() - .setParameter(CoreConnectionPNames.SO_TIMEOUT, 60000); + .setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 15000); return server; } From bb3a18444ab2a79c2fc0e43ab6d71aba41695675 Mon Sep 17 00:00:00 2001 From: Erick Erickson Date: Sun, 17 Nov 2013 16:49:37 +0000 Subject: [PATCH 024/223] Added native EOL git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1542760 13f79535-47bb-0310-9956-ffa450edef68 From 194238944c6582639de9e3666cebeb7b8e2fe889 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Sun, 17 Nov 2013 18:29:53 +0000 Subject: [PATCH 025/223] tests: improve example test debug logging git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1542784 13f79535-47bb-0310-9956-ffa450edef68 --- solr/core/src/test-files/log4j.properties | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/solr/core/src/test-files/log4j.properties b/solr/core/src/test-files/log4j.properties index 74a5d358eb4..4562e3fd80a 100644 --- a/solr/core/src/test-files/log4j.properties +++ b/solr/core/src/test-files/log4j.properties @@ -19,6 +19,8 @@ log4j.logger.org.apache.hadoop=WARN #log4j.logger.org.apache.solr.cloud.ZkController=DEBUG #log4j.logger.org.apache.solr.update.DefaultSolrCoreState=DEBUG #log4j.logger.org.apache.solr.common.cloud.ConnectionManager=DEBUG -#log4j.logger.org.apache.solr.update.UpdateLog.level=FINE +#log4j.logger.org.apache.solr.update.UpdateLog=DEBUG #log4j.logger.org.apache.solr.cloud.ChaosMonkey=DEBUG -#log4j.logger.org.apache.solr.update.TransactionLog=DEBUG \ No newline at end of file +#log4j.logger.org.apache.solr.update.TransactionLog=DEBUG +#log4j.logger.org.apache.solr.handler.ReplicationHandler=DEBUG +#log4j.logger.org.apache.solr.handler.SnapPuller=DEBUG \ No newline at end of file From 6e78f9a497a3c442a2d91b13da0e58f70d077b5f Mon Sep 17 00:00:00 2001 From: Erick Erickson Date: Sun, 17 Nov 2013 22:59:42 +0000 Subject: [PATCH 026/223] SOLR-5455: add managed schema name to the files the admin UI cannot edit git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1542859 13f79535-47bb-0310-9956-ffa450edef68 --- .../handler/admin/ShowFileRequestHandler.java | 55 ++++++---- .../solr/schema/TestCloudManagedSchema.java | 103 ++++++------------ 2 files changed, 69 insertions(+), 89 deletions(-) diff --git a/solr/core/src/java/org/apache/solr/handler/admin/ShowFileRequestHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/ShowFileRequestHandler.java index 224723904b5..aaa5b9b6d32 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/ShowFileRequestHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/ShowFileRequestHandler.java @@ -36,6 +36,8 @@ import org.apache.solr.handler.RequestHandlerBase; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.RawResponseWriter; import org.apache.solr.response.SolrQueryResponse; +import org.apache.solr.schema.IndexSchema; +import org.apache.solr.schema.ManagedIndexSchema; import org.apache.zookeeper.KeeperException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -170,13 +172,11 @@ public class ShowFileRequestHandler extends RequestHandlerBase if (fname == null) { rsp.setException(new SolrException(ErrorCode.BAD_REQUEST, "No file name specified for write operation.")); } else { - if (coreContainer.isZooKeeperAware()) { - if (isHiddenFile(rsp, fname) == false) { + fname = fname.replace('\\', '/'); + if (isHiddenFile(req, rsp, fname, true) == false) { + if (coreContainer.isZooKeeperAware()) { writeToZooKeeper(req, rsp, coreContainer); - } - } else { - fname = fname.replace('\\', '/'); // normalize slashes. Should be done above too? - if (isHiddenFile(rsp, fname) == false) { + } else { writeToFileSystem(req, rsp); } } @@ -186,21 +186,38 @@ public class ShowFileRequestHandler extends RequestHandlerBase // See if we should deal with this file - private boolean isHiddenFile(SolrQueryResponse rsp, String fnameIn) { + private boolean isHiddenFile(SolrQueryRequest req, SolrQueryResponse rsp, String fnameIn, boolean reportError) { String fname = fnameIn.toUpperCase(Locale.ROOT); if (hiddenFiles.contains(fname) || hiddenFiles.contains("*")) { - log.error("Cannot access " + fname); - rsp.setException(new SolrException(ErrorCode.FORBIDDEN, "Can not access: " + fnameIn)); + if (reportError) { + log.error("Cannot access " + fname); + rsp.setException(new SolrException(ErrorCode.FORBIDDEN, "Can not access: " + fnameIn)); + } return true; } // This is slightly off, a valid path is something like ./schema.xml. I don't think it's worth the effort though // to fix it to handle all possibilities though. if (fname.indexOf("..") >= 0 || fname.startsWith(".")) { - log.error("Invalid path: " + fname); - rsp.setException(new SolrException(ErrorCode.FORBIDDEN, "Invalid path: " + fnameIn)); + if (reportError) { + log.error("Invalid path: " + fname); + rsp.setException(new SolrException(ErrorCode.FORBIDDEN, "Invalid path: " + fnameIn)); + } return true; } + + // Make sure that if the schema is managed, we don't allow editing. Don't really want to put + // this in the init since we're not entirely sure when the managed schema will get initialized relative to this + // handler. + SolrCore core = req.getCore(); + IndexSchema schema = core.getLatestSchema(); + if (schema instanceof ManagedIndexSchema) { + String managed = schema.getResourceName(); + + if (fname.equalsIgnoreCase(managed)) { + return true; + } + } return false; } @@ -223,7 +240,7 @@ public class ShowFileRequestHandler extends RequestHandlerBase adminFile = confPath; } else { fname = fname.replace('\\', '/'); // normalize slashes - if (isHiddenFile(rsp, fname)) { + if (isHiddenFile(req, rsp, fname, true)) { return null; } if (fname.startsWith("/")) { // Only files relative to conf are valid @@ -291,7 +308,7 @@ public class ShowFileRequestHandler extends RequestHandlerBase NamedList> files = new SimpleOrderedMap>(); for (String f : children) { - if (isHiddenFile(rsp, f)) { + if (isHiddenFile(req, rsp, f, false)) { continue; } @@ -452,13 +469,11 @@ public class ShowFileRequestHandler extends RequestHandlerBase for( File f : adminFile.listFiles() ) { String path = f.getAbsolutePath().substring( basePath ); path = path.replace( '\\', '/' ); // normalize slashes - if( hiddenFiles.contains( path.toUpperCase(Locale.ROOT) ) ) { - continue; // don't show 'hidden' files + + if (isHiddenFile(req, rsp, f.getName().replace('\\', '/'), false)) { + continue; } - if( f.isHidden() || f.getName().startsWith( "." ) ) { - continue; // skip hidden system files... - } - + SimpleOrderedMap fileInfo = new SimpleOrderedMap(); files.add( path, fileInfo ); if( f.isDirectory() ) { @@ -480,7 +495,7 @@ public class ShowFileRequestHandler extends RequestHandlerBase req.setParams(params); ContentStreamBase content = new ContentStreamBase.FileStream( adminFile ); - content.setContentType( req.getParams().get( USE_CONTENT_TYPE ) ); + content.setContentType(req.getParams().get(USE_CONTENT_TYPE)); rsp.add(RawResponseWriter.CONTENT, content); } diff --git a/solr/core/src/test/org/apache/solr/schema/TestCloudManagedSchema.java b/solr/core/src/test/org/apache/solr/schema/TestCloudManagedSchema.java index f1cc4904d36..6deaa45b526 100644 --- a/solr/core/src/test/org/apache/solr/schema/TestCloudManagedSchema.java +++ b/solr/core/src/test/org/apache/solr/schema/TestCloudManagedSchema.java @@ -16,23 +16,20 @@ package org.apache.solr.schema; * limitations under the License. */ -import org.apache.commons.io.IOUtils; -import org.apache.solr.client.solrj.ResponseParser; -import org.apache.solr.client.solrj.SolrServer; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.impl.HttpSolrServer; import org.apache.solr.client.solrj.request.QueryRequest; import org.apache.solr.cloud.AbstractFullDistribZkTestBase; import org.apache.solr.common.SolrException; +import org.apache.solr.common.cloud.SolrZkClient; import org.apache.solr.common.params.CoreAdminParams; import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.util.NamedList; +import org.apache.zookeeper.KeeperException; import org.junit.BeforeClass; import java.io.IOException; -import java.io.InputStream; -import java.io.Reader; -import java.util.regex.Pattern; +import java.util.List; public class TestCloudManagedSchema extends AbstractFullDistribZkTestBase { @@ -69,72 +66,40 @@ public class TestCloudManagedSchema extends AbstractFullDistribZkTestBase { String collectionSchema = (String)collectionStatus.get(CoreAdminParams.SCHEMA); // Make sure the upgrade to managed schema happened assertEquals("Schema resource name differs from expected name", "managed-schema", collectionSchema); - - // Make sure "DO NOT EDIT" is in the content of the managed schema - String fileContent = getFileContentFromZooKeeper("managed-schema"); - assertTrue("Managed schema is missing", fileContent.contains("DO NOT EDIT")); - - // Make sure the original non-managed schema is no longer in ZooKeeper - assertFileNotInZooKeeper("schema.xml"); - // Make sure the renamed non-managed schema is present in ZooKeeper - fileContent = getFileContentFromZooKeeper("schema.xml.bak"); - assertTrue("schema file doesn't contain ' processResponse(InputStream body, String encoding) { - try { - rawFileContent = IOUtils.toString(body, encoding); - } catch (Exception e) { - throw new RuntimeException(e); - } - return null; - } - @Override - public NamedList processResponse(Reader reader) { - throw new UnsupportedOperationException("TODO unimplemented");//TODO - } - } - - protected final void assertFileNotInZooKeeper(String fileName) throws Exception { - // Stolen from AbstractBadConfigTestBase - String errString = "Not Found"; - ignoreException(Pattern.quote(errString)); - String rawContent = null; + SolrZkClient zkClient = new SolrZkClient(zkServer.getZkHost(), 30000); try { - rawContent = getFileContentFromZooKeeper(fileName); - } catch (Exception e) { - // short circuit out if we found what we expected - if (-1 != e.getMessage().indexOf(errString)) return; - // otherwise, rethrow it, possibly completely unrelated - throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, - "Unexpected error, expected error matching: " + errString, e); + // Make sure "DO NOT EDIT" is in the content of the managed schema + String fileContent = getFileContentFromZooKeeper(zkClient, "/solr/configs/conf1/managed-schema"); + assertTrue("Managed schema is missing", fileContent.contains("DO NOT EDIT")); + + // Make sure the original non-managed schema is no longer in ZooKeeper + assertFileNotInZooKeeper(zkClient, "/solr/configs/conf1", "schema.xml"); + + // Make sure the renamed non-managed schema is present in ZooKeeper + fileContent = getFileContentFromZooKeeper(zkClient, "/solr/configs/conf1/schema.xml.bak"); + assertTrue("schema file doesn't contain ' kids = zkClient.getChildren(parent, null, true); + for (String kid : kids) { + if (kid.equalsIgnoreCase(fileName)) { + String rawContent = new String(zkClient.getData(fileName, null, null, true), "UTF-8"); + fail("File '" + fileName + "' was unexpectedly found in ZooKeeper. Content starts with '" + + rawContent.substring(0, 100) + " [...]'"); + } } - fail("File '" + fileName + "' was unexpectedly found in ZooKeeper. Content starts with '" - + rawContent.substring(0, 100) + " [...]'"); } } From e8fbefc83dacb7562a8c57aebd7f6946d33b015b Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Mon, 18 Nov 2013 04:00:56 +0000 Subject: [PATCH 027/223] SOLR-5397: Replication can fail silently in some cases. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1542884 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 2 + .../apache/solr/cloud/RecoveryStrategy.java | 10 +- .../org/apache/solr/handler/SnapPuller.java | 157 ++++++++++-------- .../processor/DistributedUpdateProcessor.java | 48 ++---- 4 files changed, 114 insertions(+), 103 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index c1244373ce4..889ebbefd40 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -226,6 +226,8 @@ Bug Fixes unloaded results in a " Too many close [count:-1]" error. (Olivier Soyez via Erick Erickson) +* SOLR-5397: Replication can fail silently in some cases. (Mark Miller) + Optimizations ---------------------- diff --git a/solr/core/src/java/org/apache/solr/cloud/RecoveryStrategy.java b/solr/core/src/java/org/apache/solr/cloud/RecoveryStrategy.java index 596027b0f04..7955bd6756f 100644 --- a/solr/core/src/java/org/apache/solr/cloud/RecoveryStrategy.java +++ b/solr/core/src/java/org/apache/solr/cloud/RecoveryStrategy.java @@ -19,12 +19,14 @@ package org.apache.solr.cloud; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import org.apache.lucene.search.MatchAllDocsQuery; +import org.apache.lucene.store.Directory; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.impl.HttpSolrServer; import org.apache.solr.client.solrj.request.AbstractUpdateRequest; @@ -41,6 +43,7 @@ import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.params.UpdateParams; import org.apache.solr.core.CoreContainer; import org.apache.solr.core.CoreDescriptor; +import org.apache.solr.core.DirectoryFactory.DirContext; import org.apache.solr.core.RequestHandlers.LazyRequestHandlerWrapper; import org.apache.solr.core.SolrCore; import org.apache.solr.handler.ReplicationHandler; @@ -161,6 +164,7 @@ public class RecoveryStrategy extends Thread implements ClosableThread { RefCounted searchHolder = core .getNewestSearcher(false); SolrIndexSearcher searcher = searchHolder.get(); + Directory dir = core.getDirectoryFactory().get(core.getIndexDir(), DirContext.META_DATA, null); try { log.debug(core.getCoreDescriptor().getCoreContainer() .getZkController().getNodeName() @@ -170,8 +174,12 @@ public class RecoveryStrategy extends Thread implements ClosableThread { + leaderUrl + " gen:" + core.getDeletionPolicy().getLatestCommit().getGeneration() - + " data:" + core.getDataDir()); + + " data:" + core.getDataDir() + + " index:" + core.getIndexDir() + + " newIndex:" + core.getNewIndexDir() + + " files:" + Arrays.asList(dir.listAll())); } finally { + core.getDirectoryFactory().release(dir); searchHolder.decref(); } } catch (Exception e) { diff --git a/solr/core/src/java/org/apache/solr/handler/SnapPuller.java b/solr/core/src/java/org/apache/solr/handler/SnapPuller.java index 2ed2ff481ac..343aff62fe5 100644 --- a/solr/core/src/java/org/apache/solr/handler/SnapPuller.java +++ b/solr/core/src/java/org/apache/solr/handler/SnapPuller.java @@ -16,6 +16,7 @@ */ package org.apache.solr.handler; +import static org.apache.lucene.util.IOUtils.CHARSET_UTF_8; import static org.apache.solr.handler.ReplicationHandler.ALIAS; import static org.apache.solr.handler.ReplicationHandler.CHECKSUM; import static org.apache.solr.handler.ReplicationHandler.CMD_DETAILS; @@ -47,6 +48,7 @@ import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Date; @@ -75,9 +77,6 @@ import org.apache.lucene.index.IndexWriter; import org.apache.lucene.store.Directory; import org.apache.lucene.store.IndexInput; import org.apache.lucene.store.IndexOutput; - -import static org.apache.lucene.util.IOUtils.CHARSET_UTF_8; - import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.impl.HttpClientUtil; import org.apache.solr.client.solrj.impl.HttpSolrServer; @@ -104,6 +103,7 @@ import org.apache.solr.util.FileUtils; import org.apache.solr.util.PropertiesInputStream; import org.apache.solr.util.PropertiesOutputStream; import org.apache.solr.util.RefCounted; +import org.eclipse.jetty.util.log.Log; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -388,8 +388,8 @@ public class SnapPuller { fsyncService = Executors.newSingleThreadExecutor(new DefaultSolrThreadFactory("fsyncService")); // use a synchronized list because the list is read by other threads (to show details) filesDownloaded = Collections.synchronizedList(new ArrayList>()); - // if the generateion of master is older than that of the slave , it means they are not compatible to be copied - // then a new index direcory to be created and all the files need to be copied + // if the generation of master is older than that of the slave , it means they are not compatible to be copied + // then a new index directory to be created and all the files need to be copied boolean isFullCopyNeeded = IndexDeletionPolicyWrapper .getCommitTimestamp(commit) >= latestVersion || commit.getGeneration() >= latestGeneration || forceReplication; @@ -408,57 +408,66 @@ public class SnapPuller { if (isIndexStale(indexDir)) { isFullCopyNeeded = true; } - LOG.info("Starting download to " + tmpIndexDir + " fullCopy=" + isFullCopyNeeded); - successfulInstall = false; - downloadIndexFiles(isFullCopyNeeded, tmpIndexDir, latestGeneration); - LOG.info("Total time taken for download : " + ((System.currentTimeMillis() - replicationStartTime) / 1000) + " secs"); - Collection> modifiedConfFiles = getModifiedConfFiles(confFilesToDownload); - if (!modifiedConfFiles.isEmpty()) { - downloadConfFiles(confFilesToDownload, latestGeneration); - if (isFullCopyNeeded) { - successfulInstall = modifyIndexProps(tmpIdxDirName); - deleteTmpIdxDir = false; - } else { - solrCore.getUpdateHandler().getSolrCoreState() - .closeIndexWriter(core, true); - try { - successfulInstall = moveIndexFiles(tmpIndexDir, indexDir); - } finally { - solrCore.getUpdateHandler().getSolrCoreState() - .openIndexWriter(core); - } - } - if (successfulInstall) { + if (!isFullCopyNeeded) { + // rollback - and do it before we download any files + // so we don't remove files we thought we didn't need + // to download later + solrCore.getUpdateHandler().getSolrCoreState() + .closeIndexWriter(core, true); + } + try { + LOG.info("Starting download to " + tmpIndexDir + " fullCopy=" + + isFullCopyNeeded); + successfulInstall = false; + + downloadIndexFiles(isFullCopyNeeded, indexDir, tmpIndexDir, + latestGeneration); + LOG.info("Total time taken for download : " + + ((System.currentTimeMillis() - replicationStartTime) / 1000) + + " secs"); + Collection> modifiedConfFiles = getModifiedConfFiles(confFilesToDownload); + if (!modifiedConfFiles.isEmpty()) { + downloadConfFiles(confFilesToDownload, latestGeneration); if (isFullCopyNeeded) { - // let the system know we are changing dir's and the old one - // may be closed - if (indexDir != null) { - LOG.info("removing old index directory " + indexDir); - core.getDirectoryFactory().doneWithDirectory(indexDir); - core.getDirectoryFactory().remove(indexDir); - } - } - - LOG.info("Configuration files are modified, core will be reloaded"); - logReplicationTimeAndConfFiles(modifiedConfFiles, successfulInstall);//write to a file time of replication and conf files. - reloadCore(); - } - } else { - terminateAndWaitFsyncService(); - if (isFullCopyNeeded) { - successfulInstall = modifyIndexProps(tmpIdxDirName); - deleteTmpIdxDir = false; - } else { - solrCore.getUpdateHandler().getSolrCoreState().closeIndexWriter(core, true); - try { + successfulInstall = modifyIndexProps(tmpIdxDirName); + deleteTmpIdxDir = false; + } else { successfulInstall = moveIndexFiles(tmpIndexDir, indexDir); - } finally { - solrCore.getUpdateHandler().getSolrCoreState().openIndexWriter(core); + } + if (successfulInstall) { + if (isFullCopyNeeded) { + // let the system know we are changing dir's and the old one + // may be closed + if (indexDir != null) { + LOG.info("removing old index directory " + indexDir); + core.getDirectoryFactory().doneWithDirectory(indexDir); + core.getDirectoryFactory().remove(indexDir); + } + } + + LOG.info("Configuration files are modified, core will be reloaded"); + logReplicationTimeAndConfFiles(modifiedConfFiles, + successfulInstall);// write to a file time of replication and + // conf files. + reloadCore(); + } + } else { + terminateAndWaitFsyncService(); + if (isFullCopyNeeded) { + successfulInstall = modifyIndexProps(tmpIdxDirName); + deleteTmpIdxDir = false; + } else { + successfulInstall = moveIndexFiles(tmpIndexDir, indexDir); + } + if (successfulInstall) { + logReplicationTimeAndConfFiles(modifiedConfFiles, + successfulInstall); } } - if (successfulInstall) { - logReplicationTimeAndConfFiles(modifiedConfFiles, successfulInstall); + } finally { + if (!isFullCopyNeeded) { + solrCore.getUpdateHandler().getSolrCoreState().openIndexWriter(core); } } @@ -732,29 +741,28 @@ public class SnapPuller { * Download the index files. If a new index is needed, download all the files. * * @param downloadCompleteIndex is it a fresh index copy - * @param tmpIndexDir the directory to which files need to be downloadeed to + * @param tmpIndexDir the directory to which files need to be downloadeed to + * @param indexDir the indexDir to be merged to * @param latestGeneration the version number */ private void downloadIndexFiles(boolean downloadCompleteIndex, - Directory tmpIndexDir, long latestGeneration) throws Exception { - String indexDir = solrCore.getIndexDir(); - - // it's okay to use null for lock factory since we know this dir will exist - Directory dir = solrCore.getDirectoryFactory().get(indexDir, DirContext.DEFAULT, solrCore.getSolrConfig().indexConfig.lockType); - try { - for (Map file : filesToDownload) { - if (!dir.fileExists((String) file.get(NAME)) || downloadCompleteIndex) { - dirFileFetcher = new DirectoryFileFetcher(tmpIndexDir, file, - (String) file.get(NAME), false, latestGeneration); - currentFile = file; - dirFileFetcher.fetchFile(); - filesDownloaded.add(new HashMap(file)); - } else { - LOG.info("Skipping download for " + file.get(NAME) + " because it already exists"); - } + Directory indexDir, Directory tmpIndexDir, long latestGeneration) + throws Exception { + if (LOG.isDebugEnabled()) { + LOG.debug("Download files to dir: " + Arrays.asList(indexDir.listAll())); + } + for (Map file : filesToDownload) { + if (!indexDir.fileExists((String) file.get(NAME)) + || downloadCompleteIndex) { + dirFileFetcher = new DirectoryFileFetcher(tmpIndexDir, file, + (String) file.get(NAME), false, latestGeneration); + currentFile = file; + dirFileFetcher.fetchFile(); + filesDownloaded.add(new HashMap(file)); + } else { + LOG.info("Skipping download for " + file.get(NAME) + + " because it already exists"); } - } finally { - solrCore.getDirectoryFactory().release(dir); } } @@ -782,6 +790,7 @@ public class SnapPuller { *

    */ private boolean moveAFile(Directory tmpIdxDir, Directory indexDir, String fname, List copiedfiles) { + LOG.debug("Moving file: {}", fname); boolean success = false; try { if (indexDir.fileExists(fname)) { @@ -805,6 +814,14 @@ public class SnapPuller { * Copy all index files from the temp index dir to the actual index. The segments_N file is copied last. */ private boolean moveIndexFiles(Directory tmpIdxDir, Directory indexDir) { + if (LOG.isDebugEnabled()) { + try { + LOG.info("From dir files:" + Arrays.asList(tmpIdxDir.listAll())); + LOG.info("To dir files:" + Arrays.asList(indexDir.listAll())); + } catch (IOException e) { + throw new RuntimeException(e); + } + } String segmentsFile = null; List movedfiles = new ArrayList(); for (Map f : filesDownloaded) { diff --git a/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java b/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java index a138200588c..78429964100 100644 --- a/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java +++ b/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java @@ -17,10 +17,24 @@ package org.apache.solr.update.processor; * limitations under the License. */ -import org.apache.http.client.HttpClient; +import static org.apache.solr.update.processor.DistributingUpdateProcessorFactory.DISTRIB_UPDATE_PARAM; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.ReentrantLock; + import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.CharsRef; -import org.apache.solr.client.solrj.impl.HttpClientUtil; import org.apache.solr.client.solrj.impl.HttpSolrServer; import org.apache.solr.client.solrj.request.CoreAdminRequest.RequestRecovery; import org.apache.solr.cloud.CloudDescriptor; @@ -51,10 +65,7 @@ import org.apache.solr.common.params.UpdateParams; import org.apache.solr.common.util.Hash; import org.apache.solr.common.util.NamedList; import org.apache.solr.core.CoreDescriptor; -import org.apache.solr.core.SolrCore; -import org.apache.solr.handler.component.HttpShardHandlerFactory; import org.apache.solr.handler.component.RealTimeGetComponent; -import org.apache.solr.handler.component.ShardHandler; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.request.SolrRequestInfo; import org.apache.solr.response.SolrQueryResponse; @@ -78,22 +89,6 @@ import org.apache.zookeeper.KeeperException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.locks.ReentrantLock; - -import static org.apache.solr.update.processor.DistributingUpdateProcessorFactory.DISTRIB_UPDATE_PARAM; - // NOT mt-safe... create a new processor for each add thread // TODO: we really should not wait for distrib after local? unless a certain replication factor is asked for public class DistributedUpdateProcessor extends UpdateRequestProcessor { @@ -122,17 +117,6 @@ public class DistributedUpdateProcessor extends UpdateRequestProcessor { } } } - - private final HttpClient client; - { - ModifiableSolrParams params = new ModifiableSolrParams(); - params.set(HttpClientUtil.PROP_MAX_CONNECTIONS, 10000); - params.set(HttpClientUtil.PROP_MAX_CONNECTIONS_PER_HOST, 20); - params.set(HttpClientUtil.PROP_CONNECTION_TIMEOUT, 15000); - params.set(HttpClientUtil.PROP_SO_TIMEOUT, 60000); - params.set(HttpClientUtil.PROP_USE_RETRY, false); - client = HttpClientUtil.createClient(params); - } public static final String COMMIT_END_POINT = "commit_end_point"; public static final String LOG_REPLAY = "log_replay"; From c13e4aaa380f865b308c7c7b13bdd1bd35ec3347 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Mon, 18 Nov 2013 04:23:40 +0000 Subject: [PATCH 028/223] SOLR-5453: Move CHANGES entry to 4.6 git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1542888 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 889ebbefd40..473fffed42d 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -106,8 +106,6 @@ Bug Fixes * SOLR-5451: SyncStrategy closes it's http connection manager before the executor that uses it in it's close method. (Mark Miller) -* SOLR-5453: Raise recovery socket read timeouts. (Mark Miller) - Other Changes --------------------- @@ -226,6 +224,8 @@ Bug Fixes unloaded results in a " Too many close [count:-1]" error. (Olivier Soyez via Erick Erickson) +* SOLR-5453: Raise recovery socket read timeouts. (Mark Miller) + * SOLR-5397: Replication can fail silently in some cases. (Mark Miller) Optimizations From bdbf771ef88e14557948f0ec464f90f94c082f86 Mon Sep 17 00:00:00 2001 From: Stefan Matheis Date: Mon, 18 Nov 2013 10:30:54 +0000 Subject: [PATCH 029/223] SOLR-5456: Admin UI - Allow creating new Files git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1542967 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 2 + solr/webapp/web/css/styles/files.css | 68 +++++---- solr/webapp/web/js/scripts/files.js | 208 +++++++++++++++++++-------- solr/webapp/web/tpl/files.html | 28 +++- 4 files changed, 219 insertions(+), 87 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 473fffed42d..a13187ec850 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -89,6 +89,8 @@ New Features * SOLR-5446: Admin UI - Allow changing Schema and Config (steffkes) +* SOLR-5456: Admin UI - Allow creating new Files (steffkes) + Bug Fixes ---------------------- diff --git a/solr/webapp/web/css/styles/files.css b/solr/webapp/web/css/styles/files.css index 8e11588fd7d..dcd0d88f8ef 100644 --- a/solr/webapp/web/css/styles/files.css +++ b/solr/webapp/web/css/styles/files.css @@ -17,15 +17,47 @@ limitations under the License. */ -#content #files #tree +#content #files #tree-holder { float: left; width: 20%; } -#content #files .show #tree +#content #files #new-file-holder { - overflow: hidden; + margin-top: 20px; + padding-bottom: 10px; +} + +#content #files #new-file-holder button span +{ + background-image: url( ../../img/ico/plus-button.png ); +} + +#content #files #new-file-holder form +{ + box-shadow: 5px 5px 10px #c0c0c0; + -moz-box-shadow: 5px 5px 10px #c0c0c0; + -webkit-box-shadow: 5px 5px 10px #c0c0c0; + display: none; + padding: 10px; +} + +#content #files #new-file-holder form input +{ + margin-bottom: 3px; + width: 98%; +} + +#content #files #new-file-holder .note +{ + color: #c0c0c0; + margin-bottom: 5px; +} + +#content #files form .buttons button +{ + float: right; } #content #files #file-content @@ -42,31 +74,15 @@ limitations under the License. display: block; } -#content #files #file-content .close -{ - background-image: url( ../../img/ico/cross-0.png ); - background-position: 50% 50%; - display: block; - height: 20px; - position: absolute; - right: 0; - top: 0; - width: 20px; -} - -#content #files #file-content .close:hover -{ - background-image: url( ../../img/ico/cross-1.png ); -} - -#content #files #file-content .close span +#content #files #new-file-note { + background-color: #ffa662; + background-image: url( ../../img/ico/exclamation-button.png ); + background-position: 10px 50%; display: none; -} - -#content #files #file-content form .buttons button -{ - float: right; + margin-bottom: 10px; + padding: 10px; + padding-left: 31px; } #content #files #file-content textarea diff --git a/solr/webapp/web/js/scripts/files.js b/solr/webapp/web/js/scripts/files.js index 02f2a945ffb..9f2ef63617d 100644 --- a/solr/webapp/web/js/scripts/files.js +++ b/solr/webapp/web/js/scripts/files.js @@ -27,6 +27,7 @@ sammy.get var content_element = $( '#content' ); var file_endpoint = core_basepath + '/admin/file'; + var file_exists = null; var path = context.path.split( '?' ); var selected_file = null; @@ -70,74 +71,118 @@ sammy.get } }; - $( '#tree', frame_element ) - .jstree - ( - { - plugins : [ 'json_data', 'sort' ], - json_data : { - ajax: { - url : file_endpoint + '?wt=json', - data : function( n ) - { - if( -1 === n ) - return null; - - return { - file : n.attr( 'data-file' ) - }; - }, - success : function( response, status, xhr ) - { - var files = []; - - for( var file in response.files ) + var load_tree = function() + { + $( '#tree', frame_element ) + .empty() + .jstree + ( + { + plugins : [ 'json_data', 'sort' ], + json_data : { + ajax: { + url : file_endpoint + '?wt=json', + data : function( n ) { - var is_directory = response.files[file].directory; - var prefix = xhr.data ? xhr.data.file + '/' : '' + if( -1 === n ) + return null; - var item = { - data: { - title : file, - attr : { - href : '#/' + current_core + '/files?file=' + prefix + file - } - }, - attr : { - 'data-file' : prefix + file - } + return { + file : n.attr( 'data-file' ) }; + }, + success : function( response, status, xhr ) + { + var files = []; - if( is_directory ) + for( var file in response.files ) { - item.state = 'closed'; - item.data.attr.href += '/'; + var is_directory = response.files[file].directory; + var prefix = xhr.data ? xhr.data.file + '/' : '' + + var item = { + data: { + title : file, + attr : { + href : '#/' + current_core + '/files?file=' + prefix + file + } + }, + attr : { + 'data-file' : prefix + file + } + }; + + if( is_directory ) + { + item.state = 'closed'; + item.data.attr.href += '/'; + } + + files.push( item ); } - files.push( item ); + return files; } - - return files; - } + }, + progressive_render : true }, - progressive_render : true - }, - core : { - animation : 0 + core : { + animation : 0 + } } + ) + .on + ( + 'loaded.jstree', + tree_callback + ) + .on + ( + 'open_node.jstree', + tree_callback + ); + }; + load_tree(); + + var new_file_form = $( '#new-file-holder form' ); + + $( '#new-file-holder > button' ) + .on + ( + 'click', + function( event ) + { + new_file_form.toggle(); + return false; } - ) - .on - ( - 'loaded.jstree', - tree_callback - ) - .on - ( - 'open_node.jstree', - tree_callback ); + new_file_form + .on + ( + 'submit', + function( event ) + { + $( 'body' ) + .animate( { scrollTop: 0 }, 500 ); + + window.location.href = '#/' + current_core + '/files?file=' + $( 'input', this ).val(); + + return false; + } + ); + + if( selected_file ) + { + $( '#new-file-holder input' ) + .val + ( + '/' !== selected_file.substr( -1 ) + ? selected_file.replace( /[^\/]+$/, '' ) + : selected_file + ); + } + if( selected_file && '/' !== selected_file.substr( -1 ) ) { frame_element @@ -173,6 +218,8 @@ sammy.get button .addClass( 'success' ); + load_file( !file_exists ); + window.setTimeout ( function() @@ -186,10 +233,53 @@ sammy.get } ); - var load_file = function() + var change_button_label = function( form, label ) { - $( 'form textarea', frame_element ) - .load( endpoint ); + $( 'span[data-' + label + ']', form ) + .each + ( + function( index, element ) + { + var self = $( this ); + self.text( self.data( label ) ); + } + ); + } + + var load_file = function( load_tree ) + { + if( load_tree ) + { + load_tree(); + } + + $.ajax + ( + { + url : endpoint, + context : $( 'form', frame_element ), + beforeSend : function( xhr, settings ) + { + }, + success : function( response, text_status, xhr ) + { + change_button_label( this, 'existing-title' ); + + $( 'textarea', this ) + .val( xhr.responseText ); + }, + error : function( xhr, text_status, error_thrown) + { + change_button_label( this, 'new-title' ); + }, + complete : function( xhr, text_status ) + { + file_exists = 200 === xhr.status; + $( '#new-file-note' ) + .toggle( !file_exists ); + } + } + ); } load_file(); @@ -226,7 +316,7 @@ sammy.get button .addClass( 'success' ); - load_file(); + load_file( !file_exists ); $( 'body' ) .animate( { scrollTop: 0 }, 500 ); diff --git a/solr/webapp/web/tpl/files.html b/solr/webapp/web/tpl/files.html index 6d0f63bf50b..dba9bf0d0e8 100644 --- a/solr/webapp/web/tpl/files.html +++ b/solr/webapp/web/tpl/files.html @@ -18,11 +18,35 @@ limitations under the License.

    -
    #tree
    +
    + +
    #tree
    + +
    + + + +
    + +

    Enter filename, on the next page you can input content or upload a file.

    + + + +
    + +
    + + + +
    + +
    +

    The requested file does (not yet) exist. Save file or Upload new file will create it.

    +
    @@ -38,7 +62,7 @@ limitations under the License.
    - +
    From ca9f50fde526395f04013c786cf9fb6f37a3b084 Mon Sep 17 00:00:00 2001 From: Simon Willnauer Date: Mon, 18 Nov 2013 10:53:58 +0000 Subject: [PATCH 030/223] Added missing Lucene 4.5.1 secion and ported already released changes to that secion. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1542971 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/CHANGES.txt | 64 ++++++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index ce7c0741b16..027f70a106a 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -171,39 +171,9 @@ New Features Bug Fixes -* LUCENE-4998: Fixed a few places to pass IOContext.READONCE instead - of IOContext.READ (Shikhar Bhushan via Mike McCandless) - -* LUCENE-5242: DirectoryTaxonomyWriter.replaceTaxonomy did not fully reset - its state, which could result in exceptions being thrown, as well as - incorrect ordinals returned from getParent. (Shai Erera) - -* LUCENE-5254: Fixed bounded memory leak, where objects like live - docs bitset were not freed from an starting reader after reopening - to a new reader and closing the original one. (Shai Erera, Mike - McCandless) - -* LUCENE-5262: Fixed file handle leaks when multiple attempts to open an - NRT reader hit exceptions. (Shai Erera) - -* LUCENE-5263: Transient IOExceptions, e.g. due to disk full or file - descriptor exhaustion, hit at unlucky times inside IndexWriter could - lead to silently losing deletions. (Shai Erera, Mike McCandless) - -* LUCENE-5264: CommonTermsQuery ignored minMustMatch if only high-frequent - terms were present in the query and the high-frequent operator was set - to SHOULD. (Simon Willnauer) - -* LUCENE-5269: Fix bug in NGramTokenFilter where it would sometimes count - unicode characters incorrectly. (Mike McCandless, Robert Muir) - * LUCENE-5272: OpenBitSet.ensureCapacity did not modify numBits, causing false assertion errors in fastSet. (Shai Erera) -* LUCENE-5289: IndexWriter.hasUncommittedChanges was returning false - when there were buffered delete-by-Term. (Shalin Shekhar Mangar, - Mike McCandless) - * LUCENE-5303: OrdinalsCache did not use coreCacheKey, resulting in over caching across multiple threads. (Mike McCandless, Shai Erera) @@ -313,6 +283,40 @@ Tests is either a "word" character or not), but now it gives a general longest-match behavior. (Nik Everett via Robert Muir) +======================= Lucene 4.5.1 ======================= + +Bug Fixes + +* LUCENE-4998: Fixed a few places to pass IOContext.READONCE instead + of IOContext.READ (Shikhar Bhushan via Mike McCandless) + +* LUCENE-5242: DirectoryTaxonomyWriter.replaceTaxonomy did not fully reset + its state, which could result in exceptions being thrown, as well as + incorrect ordinals returned from getParent. (Shai Erera) + +* LUCENE-5254: Fixed bounded memory leak, where objects like live + docs bitset were not freed from an starting reader after reopening + to a new reader and closing the original one. (Shai Erera, Mike + McCandless) + +* LUCENE-5262: Fixed file handle leaks when multiple attempts to open an + NRT reader hit exceptions. (Shai Erera) + +* LUCENE-5263: Transient IOExceptions, e.g. due to disk full or file + descriptor exhaustion, hit at unlucky times inside IndexWriter could + lead to silently losing deletions. (Shai Erera, Mike McCandless) + +* LUCENE-5264: CommonTermsQuery ignored minMustMatch if only high-frequent + terms were present in the query and the high-frequent operator was set + to SHOULD. (Simon Willnauer) + +* LUCENE-5269: Fix bug in NGramTokenFilter where it would sometimes count + unicode characters incorrectly. (Mike McCandless, Robert Muir) + +* LUCENE-5289: IndexWriter.hasUncommittedChanges was returning false + when there were buffered delete-by-Term. (Shalin Shekhar Mangar, + Mike McCandless) + ======================= Lucene 4.5.0 ======================= New features From d9e8a31a15eaf1aef0d3513093cc7ab88dde1ef8 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Mon, 18 Nov 2013 13:25:26 +0000 Subject: [PATCH 031/223] tests: try running this tests again to see how it goes... git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1543022 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java b/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java index 36cd3ab6cb3..0e161120638 100644 --- a/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java @@ -37,7 +37,6 @@ import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; -import org.junit.Ignore; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -45,7 +44,6 @@ import com.carrotsearch.randomizedtesting.annotations.ThreadLeakLingering; @Slow @ThreadLeakLingering(linger = 60000) -@Ignore public class ChaosMonkeyNothingIsSafeTest extends AbstractFullDistribZkTestBase { public static Logger log = LoggerFactory.getLogger(ChaosMonkeyNothingIsSafeTest.class); From 4f1a857977a50f09ad7bd8a08b9f77d5e048e011 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Mon, 18 Nov 2013 14:31:18 +0000 Subject: [PATCH 032/223] SOLR-5452: Do not attempt to proxy internal update requests. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1543037 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 2 + .../solr/servlet/SolrDispatchFilter.java | 5 +- .../processor/DistributedUpdateProcessor.java | 48 ++++++++++--------- 3 files changed, 32 insertions(+), 23 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index a13187ec850..e3a1bc4098f 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -108,6 +108,8 @@ Bug Fixes * SOLR-5451: SyncStrategy closes it's http connection manager before the executor that uses it in it's close method. (Mark Miller) +* SOLR-5452: Do not attempt to proxy internal update requests. (Mark Miller) + Other Changes --------------------- diff --git a/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java b/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java index 0374ca01c3f..57213215f67 100644 --- a/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java +++ b/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java @@ -52,6 +52,7 @@ import org.apache.solr.response.QueryResponseWriter; import org.apache.solr.response.SolrQueryResponse; import org.apache.solr.servlet.cache.HttpCacheHeaderUtil; import org.apache.solr.servlet.cache.Method; +import org.apache.solr.update.processor.DistributingUpdateProcessorFactory; import org.apache.solr.util.FastWriter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -313,7 +314,9 @@ public class SolrDispatchFilter implements Filter // if we couldn't find it locally, look on other nodes if (core == null && idx > 0) { String coreUrl = getRemotCoreUrl(cores, corename, origCorename); - if (coreUrl != null) { + Map params = req.getParameterMap(); + // don't proxy for internal update requests + if (coreUrl != null && (params == null || !params.containsKey(DistributingUpdateProcessorFactory.DISTRIB_UPDATE_PARAM))) { path = path.substring( idx ); remoteQuery(coreUrl + path, req, solrReq, resp); return; diff --git a/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java b/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java index 78429964100..6120337e1cf 100644 --- a/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java +++ b/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java @@ -92,6 +92,10 @@ import org.slf4j.LoggerFactory; // NOT mt-safe... create a new processor for each add thread // TODO: we really should not wait for distrib after local? unless a certain replication factor is asked for public class DistributedUpdateProcessor extends UpdateRequestProcessor { + public static final String DISTRIB_FROM_SHARD = "distrib.from.shard"; + public static final String DISTRIB_FROM_COLLECTION = "distrib.from.collection"; + public static final String DISTRIB_FROM_PARENT = "distrib.from.parent"; + public static final String DISTRIB_FROM = "distrib.from"; private static final String TEST_DISTRIB_SKIP_SERVERS = "test.distrib.skip.servers"; public final static Logger log = LoggerFactory.getLogger(DistributedUpdateProcessor.class); @@ -252,7 +256,7 @@ public class DistributedUpdateProcessor extends UpdateRequestProcessor { // if request is coming from another collection then we want it to be sent to all replicas // even if it's phase is FROMLEADER - String fromCollection = updateCommand.getReq().getParams().get("distrib.from.collection"); + String fromCollection = updateCommand.getReq().getParams().get(DISTRIB_FROM_COLLECTION); if (DistribPhase.FROMLEADER == phase && !isSubShardLeader && fromCollection == null) { // we are coming from the leader, just go local - add no urls @@ -443,13 +447,13 @@ public class DistributedUpdateProcessor extends UpdateRequestProcessor { boolean isReplayOrPeersync = (updateCommand.getFlags() & (UpdateCommand.REPLAY | UpdateCommand.PEER_SYNC)) != 0; if (isReplayOrPeersync) return; - String from = req.getParams().get("distrib.from"); + String from = req.getParams().get(DISTRIB_FROM); ClusterState clusterState = zkController.getClusterState(); CloudDescriptor cloudDescriptor = req.getCore().getCoreDescriptor().getCloudDescriptor(); Slice mySlice = clusterState.getSlice(collection, cloudDescriptor.getShardId()); boolean localIsLeader = cloudDescriptor.isLeader(); if (DistribPhase.FROMLEADER == phase && localIsLeader && from != null) { // from will be null on log replay - String fromShard = req.getParams().get("distrib.from.parent"); + String fromShard = req.getParams().get(DISTRIB_FROM_PARENT); if (fromShard != null) { if (Slice.ACTIVE.equals(mySlice.getState())) { throw new SolrException(ErrorCode.SERVICE_UNAVAILABLE, @@ -464,7 +468,7 @@ public class DistributedUpdateProcessor extends UpdateRequestProcessor { "Request says it is coming from parent shard leader but parent hash range is not superset of my range"); } } else { - String fromCollection = req.getParams().get("distrib.from.collection"); // is it because of a routing rule? + String fromCollection = req.getParams().get(DISTRIB_FROM_COLLECTION); // is it because of a routing rule? if (fromCollection == null) { log.error("Request says it is coming from leader, but we are the leader: " + req.getParamString()); throw new SolrException(ErrorCode.SERVICE_UNAVAILABLE, "Request says it is coming from leader, but we are the leader"); @@ -543,9 +547,9 @@ public class DistributedUpdateProcessor extends UpdateRequestProcessor { if (subShardLeaders != null && !subShardLeaders.isEmpty()) { ModifiableSolrParams params = new ModifiableSolrParams(filterParams(req.getParams())); params.set(DISTRIB_UPDATE_PARAM, DistribPhase.FROMLEADER.toString()); - params.set("distrib.from", ZkCoreNodeProps.getCoreUrl( + params.set(DISTRIB_FROM, ZkCoreNodeProps.getCoreUrl( zkController.getBaseUrl(), req.getCore().getName())); - params.set("distrib.from.parent", req.getCore().getCoreDescriptor().getCloudDescriptor().getShardId()); + params.set(DISTRIB_FROM_PARENT, req.getCore().getCoreDescriptor().getCloudDescriptor().getShardId()); for (Node subShardLeader : subShardLeaders) { cmdDistrib.distribAdd(cmd, Collections.singletonList(subShardLeader), params, true); } @@ -554,10 +558,10 @@ public class DistributedUpdateProcessor extends UpdateRequestProcessor { if (nodesByRoutingRules != null && !nodesByRoutingRules.isEmpty()) { ModifiableSolrParams params = new ModifiableSolrParams(filterParams(req.getParams())); params.set(DISTRIB_UPDATE_PARAM, DistribPhase.FROMLEADER.toString()); - params.set("distrib.from", ZkCoreNodeProps.getCoreUrl( + params.set(DISTRIB_FROM, ZkCoreNodeProps.getCoreUrl( zkController.getBaseUrl(), req.getCore().getName())); - params.set("distrib.from.collection", req.getCore().getCoreDescriptor().getCloudDescriptor().getCollectionName()); - params.set("distrib.from.shard", req.getCore().getCoreDescriptor().getCloudDescriptor().getShardId()); + params.set(DISTRIB_FROM_COLLECTION, req.getCore().getCoreDescriptor().getCloudDescriptor().getCollectionName()); + params.set(DISTRIB_FROM_SHARD, req.getCore().getCoreDescriptor().getCloudDescriptor().getShardId()); for (Node nodesByRoutingRule : nodesByRoutingRules) { cmdDistrib.distribAdd(cmd, Collections.singletonList(nodesByRoutingRule), params, true); } @@ -573,7 +577,7 @@ public class DistributedUpdateProcessor extends UpdateRequestProcessor { DistribPhase.FROMLEADER.toString() : DistribPhase.TOLEADER.toString())); if (isLeader || isSubShardLeader) { - params.set("distrib.from", ZkCoreNodeProps.getCoreUrl( + params.set(DISTRIB_FROM, ZkCoreNodeProps.getCoreUrl( zkController.getBaseUrl(), req.getCore().getName())); } @@ -727,7 +731,7 @@ public class DistributedUpdateProcessor extends UpdateRequestProcessor { boolean isReplayOrPeersync = (cmd.getFlags() & (UpdateCommand.REPLAY | UpdateCommand.PEER_SYNC)) != 0; boolean leaderLogic = isLeader && !isReplayOrPeersync; - boolean forwardedFromCollection = cmd.getReq().getParams().get("distrib.from.collection") != null; + boolean forwardedFromCollection = cmd.getReq().getParams().get(DISTRIB_FROM_COLLECTION) != null; VersionBucket bucket = vinfo.bucket(bucketHash); @@ -972,9 +976,9 @@ public class DistributedUpdateProcessor extends UpdateRequestProcessor { if (subShardLeaders != null && !subShardLeaders.isEmpty()) { ModifiableSolrParams params = new ModifiableSolrParams(filterParams(req.getParams())); params.set(DISTRIB_UPDATE_PARAM, DistribPhase.FROMLEADER.toString()); - params.set("distrib.from", ZkCoreNodeProps.getCoreUrl( + params.set(DISTRIB_FROM, ZkCoreNodeProps.getCoreUrl( zkController.getBaseUrl(), req.getCore().getName())); - params.set("distrib.from.parent", cloudDesc.getShardId()); + params.set(DISTRIB_FROM_PARENT, cloudDesc.getShardId()); cmdDistrib.distribDelete(cmd, subShardLeaders, params, true); } @@ -982,10 +986,10 @@ public class DistributedUpdateProcessor extends UpdateRequestProcessor { if (nodesByRoutingRules != null && !nodesByRoutingRules.isEmpty()) { ModifiableSolrParams params = new ModifiableSolrParams(filterParams(req.getParams())); params.set(DISTRIB_UPDATE_PARAM, DistribPhase.FROMLEADER.toString()); - params.set("distrib.from", ZkCoreNodeProps.getCoreUrl( + params.set(DISTRIB_FROM, ZkCoreNodeProps.getCoreUrl( zkController.getBaseUrl(), req.getCore().getName())); - params.set("distrib.from.collection", req.getCore().getCoreDescriptor().getCloudDescriptor().getCollectionName()); - params.set("distrib.from.shard", req.getCore().getCoreDescriptor().getCloudDescriptor().getShardId()); + params.set(DISTRIB_FROM_COLLECTION, req.getCore().getCoreDescriptor().getCloudDescriptor().getCollectionName()); + params.set(DISTRIB_FROM_SHARD, req.getCore().getCoreDescriptor().getCloudDescriptor().getShardId()); for (Node nodesByRoutingRule : nodesByRoutingRules) { cmdDistrib.distribDelete(cmd, Collections.singletonList(nodesByRoutingRule), params, true); } @@ -1002,7 +1006,7 @@ public class DistributedUpdateProcessor extends UpdateRequestProcessor { DistribPhase.FROMLEADER.toString() : DistribPhase.TOLEADER.toString())); if (isLeader || isSubShardLeader) { - params.set("distrib.from", ZkCoreNodeProps.getCoreUrl( + params.set(DISTRIB_FROM, ZkCoreNodeProps.getCoreUrl( zkController.getBaseUrl(), req.getCore().getName())); } cmdDistrib.distribDelete(cmd, nodes, params); @@ -1180,7 +1184,7 @@ public class DistributedUpdateProcessor extends UpdateRequestProcessor { ModifiableSolrParams params = new ModifiableSolrParams(filterParams(req.getParams())); params.set(VERSION_FIELD, Long.toString(cmd.getVersion())); params.set(DISTRIB_UPDATE_PARAM, DistribPhase.FROMLEADER.toString()); - params.set("update.from", ZkCoreNodeProps.getCoreUrl( + params.set(DISTRIB_FROM, ZkCoreNodeProps.getCoreUrl( zkController.getBaseUrl(), req.getCore().getName())); boolean someReplicas = false; @@ -1217,10 +1221,10 @@ public class DistributedUpdateProcessor extends UpdateRequestProcessor { if (nodesByRoutingRules != null && !nodesByRoutingRules.isEmpty()) { params = new ModifiableSolrParams(filterParams(req.getParams())); params.set(DISTRIB_UPDATE_PARAM, DistribPhase.FROMLEADER.toString()); - params.set("distrib.from", ZkCoreNodeProps.getCoreUrl( + params.set(DISTRIB_FROM, ZkCoreNodeProps.getCoreUrl( zkController.getBaseUrl(), req.getCore().getName())); - params.set("distrib.from.collection", req.getCore().getCoreDescriptor().getCloudDescriptor().getCollectionName()); - params.set("distrib.from.shard", req.getCore().getCoreDescriptor().getCloudDescriptor().getShardId()); + params.set(DISTRIB_FROM_COLLECTION, req.getCore().getCoreDescriptor().getCloudDescriptor().getCollectionName()); + params.set(DISTRIB_FROM_SHARD, req.getCore().getCoreDescriptor().getCloudDescriptor().getShardId()); cmdDistrib.distribDelete(cmd, nodesByRoutingRules, params, true); } if (replicas != null) { @@ -1315,7 +1319,7 @@ public class DistributedUpdateProcessor extends UpdateRequestProcessor { boolean isReplayOrPeersync = (cmd.getFlags() & (UpdateCommand.REPLAY | UpdateCommand.PEER_SYNC)) != 0; boolean leaderLogic = isLeader && !isReplayOrPeersync; - boolean forwardedFromCollection = cmd.getReq().getParams().get("distrib.from.collection") != null; + boolean forwardedFromCollection = cmd.getReq().getParams().get(DISTRIB_FROM_COLLECTION) != null; if (!leaderLogic && versionOnUpdate==0) { throw new SolrException(ErrorCode.BAD_REQUEST, "missing _version_ on update from leader"); From d88ee060b5625066397027b464181d3353c818b7 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Mon, 18 Nov 2013 16:47:02 +0000 Subject: [PATCH 033/223] SOLR-5460: SolrDispatchFilter#sendError can get a SolrCore that it does not close. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1543078 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 3 +++ .../java/org/apache/solr/servlet/SolrDispatchFilter.java | 9 ++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index e3a1bc4098f..ae44a74325a 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -110,6 +110,9 @@ Bug Fixes * SOLR-5452: Do not attempt to proxy internal update requests. (Mark Miller) +* SOLR-5460: SolrDispatchFilter#sendError can get a SolrCore that it does not + close. (Mark Miller) + Other Changes --------------------- diff --git a/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java b/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java index 57213215f67..505f5ee2d29 100644 --- a/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java +++ b/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java @@ -722,6 +722,7 @@ public class SolrDispatchFilter implements Filter ServletRequest request, HttpServletResponse response, Throwable ex) throws IOException { + SolrCore localCore = null; try { SolrQueryResponse solrResp = new SolrQueryResponse(); if(ex instanceof Exception) { @@ -731,7 +732,9 @@ public class SolrDispatchFilter implements Filter solrResp.setException(new RuntimeException(ex)); } if(core==null) { - core = cores.getCore(""); // default core + localCore = cores.getCore(""); // default core + } else { + localCore = core; } if(req==null) { final SolrParams solrParams; @@ -751,6 +754,10 @@ public class SolrDispatchFilter implements Filter SimpleOrderedMap info = new SimpleOrderedMap(); int code = ResponseUtils.getErrorInfo(ex, info, log); response.sendError( code, info.toString() ); + } finally { + if (core == null && localCore != null) { + localCore.close(); + } } } From 74deac93f81961aa89b73c2f3f8dad7b5ac3b76b Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Mon, 18 Nov 2013 17:18:37 +0000 Subject: [PATCH 034/223] SOLR-5461: Request proxying should only set con.setDoOutput(true) if the request is a post. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1543088 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 3 +++ .../java/org/apache/solr/servlet/SolrDispatchFilter.java | 8 ++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index ae44a74325a..39c89762219 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -113,6 +113,9 @@ Bug Fixes * SOLR-5460: SolrDispatchFilter#sendError can get a SolrCore that it does not close. (Mark Miller) +* SOLR-5461: Request proxying should only set con.setDoOutput(true) if the + request is a post. (Mark Miller) + Other Changes --------------------- diff --git a/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java b/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java index 505f5ee2d29..80c3fd3f2f9 100644 --- a/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java +++ b/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java @@ -500,7 +500,11 @@ public class SolrDispatchFilter implements Filter con.setRequestMethod(req.getMethod()); con.setUseCaches(false); - con.setDoOutput(true); + boolean isPostRequest = "POST".equals(req.getMethod()); + + if (isPostRequest) { + con.setDoOutput(true); + } con.setDoInput(true); for (Enumeration e = req.getHeaderNames(); e.hasMoreElements();) { String headerName = e.nextElement(); @@ -511,7 +515,7 @@ public class SolrDispatchFilter implements Filter InputStream is; OutputStream os; - if ("POST".equals(req.getMethod())) { + if (isPostRequest) { is = req.getInputStream(); os = con.getOutputStream(); // side effect: method is switched to POST try { From b10061bf1117c3262fcbfbec43d724fbfba02d9a Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Mon, 18 Nov 2013 18:19:26 +0000 Subject: [PATCH 035/223] SOLR-5452: Parse params correctly. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1543097 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/solr/servlet/SolrDispatchFilter.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java b/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java index 80c3fd3f2f9..4d1277c6ef9 100644 --- a/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java +++ b/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java @@ -314,9 +314,9 @@ public class SolrDispatchFilter implements Filter // if we couldn't find it locally, look on other nodes if (core == null && idx > 0) { String coreUrl = getRemotCoreUrl(cores, corename, origCorename); - Map params = req.getParameterMap(); // don't proxy for internal update requests - if (coreUrl != null && (params == null || !params.containsKey(DistributingUpdateProcessorFactory.DISTRIB_UPDATE_PARAM))) { + solrReq = SolrRequestParsers.DEFAULT.parse(null,path, req); + if (coreUrl != null && solrReq.getParams().get(DistributingUpdateProcessorFactory.DISTRIB_UPDATE_PARAM) == null) { path = path.substring( idx ); remoteQuery(coreUrl + path, req, solrReq, resp); return; @@ -500,9 +500,9 @@ public class SolrDispatchFilter implements Filter con.setRequestMethod(req.getMethod()); con.setUseCaches(false); - boolean isPostRequest = "POST".equals(req.getMethod()); + boolean isPostOrPutRequest = "POST".equals(req.getMethod()) || "PUT".equals(req.getMethod()); - if (isPostRequest) { + if (isPostOrPutRequest) { con.setDoOutput(true); } con.setDoInput(true); @@ -515,7 +515,7 @@ public class SolrDispatchFilter implements Filter InputStream is; OutputStream os; - if (isPostRequest) { + if (isPostOrPutRequest) { is = req.getInputStream(); os = con.getOutputStream(); // side effect: method is switched to POST try { From 2115c05de906540d18996db5a42ebae598513420 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Mon, 18 Nov 2013 18:52:01 +0000 Subject: [PATCH 036/223] SOLR-5452: Back this out for a bit git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1543108 13f79535-47bb-0310-9956-ffa450edef68 --- .../src/java/org/apache/solr/servlet/SolrDispatchFilter.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java b/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java index 4d1277c6ef9..41c1916ac37 100644 --- a/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java +++ b/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java @@ -315,8 +315,9 @@ public class SolrDispatchFilter implements Filter if (core == null && idx > 0) { String coreUrl = getRemotCoreUrl(cores, corename, origCorename); // don't proxy for internal update requests - solrReq = SolrRequestParsers.DEFAULT.parse(null,path, req); - if (coreUrl != null && solrReq.getParams().get(DistributingUpdateProcessorFactory.DISTRIB_UPDATE_PARAM) == null) { + //solrReq = SolrRequestParsers.DEFAULT.parse(null,path, req); + //if (coreUrl != null && solrReq.getParams().get(DistributingUpdateProcessorFactory.DISTRIB_UPDATE_PARAM) == null) { + if (coreUrl != null) { path = path.substring( idx ); remoteQuery(coreUrl + path, req, solrReq, resp); return; From d6e11140022eb1ff4befc4a1b04bdc6519a8c881 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Mon, 18 Nov 2013 22:33:25 +0000 Subject: [PATCH 037/223] tests: set request info on SyncStrategy for better logging git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1543205 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/solr/cloud/SyncStrategy.java | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/solr/core/src/java/org/apache/solr/cloud/SyncStrategy.java b/solr/core/src/java/org/apache/solr/cloud/SyncStrategy.java index 274528552e7..839c1c34da9 100644 --- a/solr/core/src/java/org/apache/solr/cloud/SyncStrategy.java +++ b/solr/core/src/java/org/apache/solr/cloud/SyncStrategy.java @@ -43,6 +43,10 @@ import org.apache.solr.handler.component.HttpShardHandlerFactory; import org.apache.solr.handler.component.ShardHandler; import org.apache.solr.handler.component.ShardRequest; import org.apache.solr.handler.component.ShardResponse; +import org.apache.solr.request.LocalSolrQueryRequest; +import org.apache.solr.request.SolrQueryRequest; +import org.apache.solr.request.SolrRequestInfo; +import org.apache.solr.response.SolrQueryResponse; import org.apache.solr.update.PeerSync; import org.apache.solr.util.DefaultSolrThreadFactory; import org.slf4j.Logger; @@ -86,17 +90,25 @@ public class SyncStrategy { if (SKIP_AUTO_RECOVERY) { return true; } - if (isClosed) { - log.warn("Closed, skipping sync up."); - return false; + boolean success; + SolrQueryRequest req = new LocalSolrQueryRequest(core, new ModifiableSolrParams()); + SolrQueryResponse rsp = new SolrQueryResponse(); + SolrRequestInfo.setRequestInfo(new SolrRequestInfo(req, rsp)); + try { + if (isClosed) { + log.warn("Closed, skipping sync up."); + return false; + } + log.info("Sync replicas to " + ZkCoreNodeProps.getCoreUrl(leaderProps)); + + if (core.getUpdateHandler().getUpdateLog() == null) { + log.error("No UpdateLog found - cannot sync"); + return false; + } + success = syncReplicas(zkController, core, leaderProps); + } finally { + SolrRequestInfo.clearRequestInfo(); } - log.info("Sync replicas to " + ZkCoreNodeProps.getCoreUrl(leaderProps)); - - if (core.getUpdateHandler().getUpdateLog() == null) { - log.error("No UpdateLog found - cannot sync"); - return false; - } - boolean success = syncReplicas(zkController, core, leaderProps); return success; } From 882263204861ba43353d7654b86128444a2a8f7f Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Tue, 19 Nov 2013 03:13:33 +0000 Subject: [PATCH 038/223] SOLR-5465: SolrCmdDistributor retry logic has a concurrency race bug. SOLR-5464: ConcurrentSolrServer does not stream pure delete by id requests. SOLR-5452: Do not attempt to proxy internal update requests. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1543299 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 10 ++++- .../solr/servlet/SolrDispatchFilter.java | 11 +++-- .../solr/update/SolrCmdDistributor.java | 10 +++-- .../solr/update/StreamingSolrServers.java | 10 ++++- .../impl/ConcurrentUpdateSolrServer.java | 41 ++++++++++++++++-- .../client/solrj/impl/HttpSolrServer.java | 43 +++++++++++++++---- .../client/solrj/impl/LBHttpSolrServer.java | 17 ++++++++ 7 files changed, 120 insertions(+), 22 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 39c89762219..a8251665b8e 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -108,14 +108,20 @@ Bug Fixes * SOLR-5451: SyncStrategy closes it's http connection manager before the executor that uses it in it's close method. (Mark Miller) -* SOLR-5452: Do not attempt to proxy internal update requests. (Mark Miller) - * SOLR-5460: SolrDispatchFilter#sendError can get a SolrCore that it does not close. (Mark Miller) * SOLR-5461: Request proxying should only set con.setDoOutput(true) if the request is a post. (Mark Miller) +* SOLR-5465: SolrCmdDistributor retry logic has a concurrency race bug. + (Mark Miller) + +* SOLR-5464: ConcurrentSolrServer does not stream pure delete by id requests. + (Mark Miller) + +* SOLR-5452: Do not attempt to proxy internal update requests. (Mark Miller) + Other Changes --------------------- diff --git a/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java b/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java index 41c1916ac37..3437245cd8c 100644 --- a/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java +++ b/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java @@ -52,6 +52,7 @@ import org.apache.solr.response.QueryResponseWriter; import org.apache.solr.response.SolrQueryResponse; import org.apache.solr.servlet.cache.HttpCacheHeaderUtil; import org.apache.solr.servlet.cache.Method; +import org.apache.solr.update.processor.DistributedUpdateProcessor; import org.apache.solr.update.processor.DistributingUpdateProcessorFactory; import org.apache.solr.util.FastWriter; import org.slf4j.Logger; @@ -315,10 +316,12 @@ public class SolrDispatchFilter implements Filter if (core == null && idx > 0) { String coreUrl = getRemotCoreUrl(cores, corename, origCorename); // don't proxy for internal update requests - //solrReq = SolrRequestParsers.DEFAULT.parse(null,path, req); - //if (coreUrl != null && solrReq.getParams().get(DistributingUpdateProcessorFactory.DISTRIB_UPDATE_PARAM) == null) { - if (coreUrl != null) { - path = path.substring( idx ); + SolrParams queryParams = SolrRequestParsers.parseQueryString(req.getQueryString()); + if (coreUrl != null + && queryParams + .get(DistributingUpdateProcessorFactory.DISTRIB_UPDATE_PARAM) == null + && queryParams.get(DistributedUpdateProcessor.DISTRIB_FROM) == null) { + path = path.substring(idx); remoteQuery(coreUrl + path, req, solrReq, resp); return; } else { diff --git a/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java b/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java index 0e4d9fbfaa9..f77a774ea39 100644 --- a/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java +++ b/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java @@ -69,8 +69,8 @@ public class SolrCmdDistributor { List errors = new ArrayList(this.errors); errors.addAll(servers.getErrors()); + List resubmitList = new ArrayList(); - boolean blockUntilFinishedAgain = false; for (Error err : errors) { String oldNodeUrl = err.req.node.getUrl(); @@ -108,8 +108,7 @@ public class SolrCmdDistributor { log.warn(null, e); } - submit(err.req); - blockUntilFinishedAgain = true; + resubmitList.add(err); } else { allErrors.add(err); } @@ -120,8 +119,11 @@ public class SolrCmdDistributor { servers.clearErrors(); this.errors.clear(); + for (Error err : resubmitList) { + submit(err.req); + } - if (blockUntilFinishedAgain) { + if (resubmitList.size() > 0) { servers.blockUntilFinished(); doRetriesIfNeeded(); } diff --git a/solr/core/src/java/org/apache/solr/update/StreamingSolrServers.java b/solr/core/src/java/org/apache/solr/update/StreamingSolrServers.java index 3af7c328b8a..4d460ef4c0e 100644 --- a/solr/core/src/java/org/apache/solr/update/StreamingSolrServers.java +++ b/solr/core/src/java/org/apache/solr/update/StreamingSolrServers.java @@ -20,8 +20,10 @@ package org.apache.solr.update; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.concurrent.ExecutorService; import org.apache.http.client.HttpClient; @@ -33,6 +35,8 @@ import org.apache.solr.client.solrj.impl.HttpClientUtil; import org.apache.solr.common.SolrException; import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.update.SolrCmdDistributor.Error; +import org.apache.solr.update.processor.DistributedUpdateProcessor; +import org.apache.solr.update.processor.DistributingUpdateProcessorFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -70,7 +74,7 @@ public class StreamingSolrServers { String url = getFullUrl(req.node.getUrl()); ConcurrentUpdateSolrServer server = solrServers.get(url); if (server == null) { - server = new ConcurrentUpdateSolrServer(url, httpClient, 100, 1, updateExecutor) { + server = new ConcurrentUpdateSolrServer(url, httpClient, 100, 1, updateExecutor, true) { @Override public void handleError(Throwable ex) { log.error("error", ex); @@ -86,6 +90,10 @@ public class StreamingSolrServers { server.setParser(new BinaryResponseParser()); server.setRequestWriter(new BinaryRequestWriter()); server.setPollQueueTime(0); + Set queryParams = new HashSet(2); + queryParams.add(DistributedUpdateProcessor.DISTRIB_FROM); + queryParams.add(DistributingUpdateProcessorFactory.DISTRIB_UPDATE_PARAM); + server.setQueryParams(queryParams); solrServers.put(url, server); } diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ConcurrentUpdateSolrServer.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ConcurrentUpdateSolrServer.java index 24e46566a26..34cf01e729b 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ConcurrentUpdateSolrServer.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ConcurrentUpdateSolrServer.java @@ -22,6 +22,7 @@ import java.io.OutputStream; import java.util.LinkedList; import java.util.Locale; import java.util.Queue; +import java.util.Set; import java.util.concurrent.BlockingQueue; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; @@ -80,6 +81,7 @@ public class ConcurrentUpdateSolrServer extends SolrServer { final int threadCount; boolean shutdownExecutor = false; int pollQueueTime = 250; + private final boolean streamDeletes; /** * Uses an internally managed HttpClient instance. @@ -109,14 +111,35 @@ public class ConcurrentUpdateSolrServer extends SolrServer { */ public ConcurrentUpdateSolrServer(String solrServerUrl, HttpClient client, int queueSize, int threadCount, ExecutorService es) { + this(solrServerUrl, client, queueSize, threadCount, es, false); + } + + /** + * Uses the supplied HttpClient to send documents to the Solr server. + */ + public ConcurrentUpdateSolrServer(String solrServerUrl, + HttpClient client, int queueSize, int threadCount, ExecutorService es, boolean streamDeletes) { this.server = new HttpSolrServer(solrServerUrl, client); this.server.setFollowRedirects(false); queue = new LinkedBlockingQueue(queueSize); this.threadCount = threadCount; runners = new LinkedList(); scheduler = es; + this.streamDeletes = streamDeletes; } + public Set getQueryParams() { + return this.server.getQueryParams(); + } + + /** + * Expert Method. + * @param queryParams set of param keys to only send via the query string + */ + public void setQueryParams(Set queryParams) { + this.server.setQueryParams(queryParams); + } + /** * Opens a connection and sends everything... */ @@ -261,11 +284,23 @@ public class ConcurrentUpdateSolrServer extends SolrServer { UpdateRequest req = (UpdateRequest) request; // this happens for commit... - if (req.getDocuments() == null || req.getDocuments().isEmpty()) { - blockUntilFinished(); - return server.request(request); + if (streamDeletes) { + if ((req.getDocuments() == null || req.getDocuments().isEmpty()) + && (req.getDeleteById() == null || req.getDeleteById().isEmpty()) + && (req.getDeleteByIdMap() == null || req.getDeleteByIdMap().isEmpty())) { + blockUntilFinished(); + if (req.getDeleteQuery() == null) { + return server.request(request); + } + } + } else { + if ((req.getDocuments() == null || req.getDocuments().isEmpty())) { + blockUntilFinished(); + return server.request(request); + } } + SolrParams params = req.getParams(); if (params != null) { // check if it is waiting for the searcher diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrServer.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrServer.java index 7401bb82af1..ff4a5aa429a 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrServer.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrServer.java @@ -22,9 +22,11 @@ import java.net.ConnectException; import java.net.SocketTimeoutException; import java.nio.charset.Charset; import java.util.Collection; +import java.util.Collections; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.Set; import org.apache.commons.io.IOUtils; import org.apache.http.Header; @@ -71,6 +73,7 @@ public class HttpSolrServer extends SolrServer { private static final String UTF_8 = "UTF-8"; private static final String DEFAULT_PATH = "/select"; private static final long serialVersionUID = -946812319974801896L; + /** * User-Agent String. */ @@ -117,7 +120,8 @@ public class HttpSolrServer extends SolrServer { private boolean useMultiPartPost; private final boolean internalClient; - + private Set queryParams = Collections.emptySet(); + /** * @param baseURL * The URL of the Solr server. For example, " @@ -158,6 +162,18 @@ public class HttpSolrServer extends SolrServer { this.parser = parser; } + public Set getQueryParams() { + return queryParams; + } + + /** + * Expert Method. + * @param queryParams set of param keys to only send via the query string + */ + public void setQueryParams(Set queryParams) { + this.queryParams = queryParams; + } + /** * Process the request. If * {@link org.apache.solr.client.solrj.SolrRequest#getResponseParser()} is @@ -207,7 +223,6 @@ public class HttpSolrServer extends SolrServer { if (invariantParams != null) { wparams.add(invariantParams); } - params = wparams; int tries = maxRetries + 1; try { @@ -221,7 +236,7 @@ public class HttpSolrServer extends SolrServer { if( streams != null ) { throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "GET can't send streams!" ); } - method = new HttpGet( baseUrl + path + ClientUtils.toQueryString( params, false ) ); + method = new HttpGet( baseUrl + path + ClientUtils.toQueryString( wparams, false ) ); } else if( SolrRequest.METHOD.POST == request.getMethod() ) { @@ -236,10 +251,22 @@ public class HttpSolrServer extends SolrServer { } } boolean isMultipart = (this.useMultiPartPost || ( streams != null && streams.size() > 1 )) && !hasNullStreamName; - + + // only send this list of params as query string params + ModifiableSolrParams queryParams = new ModifiableSolrParams(); + for (String param : this.queryParams) { + String[] value = wparams.getParams(param) ; + if (value != null) { + for (String v : value) { + queryParams.add(param, v); + } + wparams.remove(param); + } + } + LinkedList postParams = new LinkedList(); if (streams == null || isMultipart) { - HttpPost post = new HttpPost(url); + HttpPost post = new HttpPost(url + ClientUtils.toQueryString( queryParams, false )); post.setHeader("Content-Charset", "UTF-8"); if (!isMultipart) { post.addHeader("Content-Type", @@ -247,10 +274,10 @@ public class HttpSolrServer extends SolrServer { } List parts = new LinkedList(); - Iterator iter = params.getParameterNamesIterator(); + Iterator iter = wparams.getParameterNamesIterator(); while (iter.hasNext()) { String p = iter.next(); - String[] vals = params.getParams(p); + String[] vals = wparams.getParams(p); if (vals != null) { for (String v : vals) { if (isMultipart) { @@ -295,7 +322,7 @@ public class HttpSolrServer extends SolrServer { } // It is has one stream, it is the post body, put the params in the URL else { - String pstr = ClientUtils.toQueryString(params, false); + String pstr = ClientUtils.toQueryString(wparams, false); HttpPost post = new HttpPost(url + pstr); // Single stream as body diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBHttpSolrServer.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBHttpSolrServer.java index c68662ee2f9..830b79e5dcb 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBHttpSolrServer.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBHttpSolrServer.java @@ -97,6 +97,8 @@ public class LBHttpSolrServer extends SolrServer { private volatile ResponseParser parser; private volatile RequestWriter requestWriter; + private Set queryParams; + static { solrQuery.setRows(0); } @@ -213,6 +215,18 @@ public class LBHttpSolrServer extends SolrServer { } updateAliveList(); } + + public Set getQueryParams() { + return queryParams; + } + + /** + * Expert Method. + * @param queryParams set of param keys to only send via the query string + */ + public void setQueryParams(Set queryParams) { + this.queryParams = queryParams; + } public static String normalize(String server) { if (server.endsWith("/")) @@ -225,6 +239,9 @@ public class LBHttpSolrServer extends SolrServer { if (requestWriter != null) { s.setRequestWriter(requestWriter); } + if (queryParams != null) { + s.setQueryParams(queryParams); + } return s; } From d744fb54dc0f47fae72003dd35b9b954e225ab7e Mon Sep 17 00:00:00 2001 From: Stefan Matheis Date: Tue, 19 Nov 2013 10:21:02 +0000 Subject: [PATCH 039/223] SOLR-5458: Admin UI - Remove separated Pages for Config & Schema git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1543368 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 5 ++ solr/webapp/web/css/styles/files.css | 47 ++++++++++++++++- solr/webapp/web/css/styles/menu.css | 2 - solr/webapp/web/img/ico/pencil.png | Bin 0 -> 1529 bytes solr/webapp/web/js/main.js | 1 - solr/webapp/web/js/scripts/app.js | 2 - solr/webapp/web/js/scripts/file.js | 73 --------------------------- solr/webapp/web/js/scripts/files.js | 68 ++++++++++++++++++++++++- solr/webapp/web/tpl/file.html | 23 --------- solr/webapp/web/tpl/files.html | 49 +++++++++++++----- 10 files changed, 152 insertions(+), 118 deletions(-) create mode 100644 solr/webapp/web/img/ico/pencil.png delete mode 100644 solr/webapp/web/js/scripts/file.js delete mode 100755 solr/webapp/web/tpl/file.html diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index a8251665b8e..41fb2b1654c 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -122,6 +122,11 @@ Bug Fixes * SOLR-5452: Do not attempt to proxy internal update requests. (Mark Miller) +Optimizations +---------------------- + +* SOLR-5458: Admin UI - Remove separated Pages for Config & Schema (steffkes) + Other Changes --------------------- diff --git a/solr/webapp/web/css/styles/files.css b/solr/webapp/web/css/styles/files.css index dcd0d88f8ef..74e14bdfc8d 100644 --- a/solr/webapp/web/css/styles/files.css +++ b/solr/webapp/web/css/styles/files.css @@ -60,6 +60,17 @@ limitations under the License. float: right; } +#content #files .modify-file, +#content #files .modify-file .view-file +{ + display: none; +} + +#content #files .modify-file .modify-file +{ + display: block; +} + #content #files #file-content { display: none; @@ -69,6 +80,33 @@ limitations under the License. min-height: 100px } +#content #files .top #url +{ + float: left; + width: 80%; +} + +#content #files .top .buttons +{ + float: right; + width: 15%; +} + +#content #files .top .buttons button +{ + float: right; +} + +#content #files .top .buttons button.view-file span +{ + background-image: url( ../../img/ico/pencil.png ); +} + +#content #files .top .buttons button.modify-file span +{ + background-image: url( ../../img/ico/document-text.png ); +} + #content #files .show #file-content { display: block; @@ -85,15 +123,22 @@ limitations under the License. padding-left: 31px; } +#content #files #file-content .response +{ + border: 1px solid transparent; + padding: 2px; +} + #content #files #file-content textarea { display: block; + font-family: monospace; height: 500px; margin-bottom: 10px; width: 99%; } -#content #files #file-content button span +#content #files #file-content form button span { background-image: url( ../../img/ico/disk-black.png ); } diff --git a/solr/webapp/web/css/styles/menu.css b/solr/webapp/web/css/styles/menu.css index 4fba2e86974..334acdc89c5 100644 --- a/solr/webapp/web/css/styles/menu.css +++ b/solr/webapp/web/css/styles/menu.css @@ -271,8 +271,6 @@ limitations under the License. #core-menu .overview a { background-image: url( ../../img/ico/home.png ); } #core-menu .query a { background-image: url( ../../img/ico/magnifier.png ); } -#core-menu .schema a { background-image: url( ../../img/ico/table.png ); } -#core-menu .config a { background-image: url( ../../img/ico/gear.png ); } #core-menu .analysis a { background-image: url( ../../img/ico/funnel.png ); } #core-menu .documents a { background-image: url( ../../img/ico/documents-stack.png ); } #core-menu .files a { background-image: url( ../../img/ico/folder.png ); } diff --git a/solr/webapp/web/img/ico/pencil.png b/solr/webapp/web/img/ico/pencil.png new file mode 100644 index 0000000000000000000000000000000000000000..3ef2fa63e268971a0bc18951278218e279429ac1 GIT binary patch literal 1529 zcmaJ>dr;GM9FHP`2n^XkM5kHQox9N{Y5I&Uu1Q)cv#6yLl#MgAfktf7CFxoiK2UGq zr01prhj%`vo6l3`L_Kxj1H`f0M4jAJ#+>Iib|z|m^5HNX2n3V?OvwvHFlsOu!Wt@-LPjXW5>BFn3Qn9ls6a8IOJIEx%X45@ zkuKo=U|IGk~k#Ji37=!(*_4=AB-vySm?)u;~Qkz?Js9|y+deGaxgEP z|6hI4S>j`02P5)+!6jF*aOyBqFEdrGw2d&%;Z+=;3`JnT>%tEa&C}Vz^GSS7ARHf&GYaTLs<=_NNSIhgtXgWz%L7 zwW=(73{$DilodtIWkW8Z89NZouLG7}hU?TXGYIr$gN@FNW?9!^!Cu8SuJZ!R!8s7p{SuT-d=v4K(%F@os1Qavz(M7VncLRk=4T}n9 z>^#!(b&dY}&=|WV;(TJ#rci5RNn@v}>p+sO_+Z48?y|DJ8-^Q!CNX+RY+i)<{9E9m ztNH)jef-QGdHQkOy|TzwR&noi)3)UWhm0NVn}58pQ>DvMwgTJ#=eqcu6K_{%p7E&9c3w@n+IYNV|?(r@ky|ue*=7ZAu>RW|>h3*4ybT;pv`K0IEj@WhQR^6O!ha=0M zbVt|K-O@W7DMgwMTCgBFVOtr>b*)}*xio!6n@5qGAbeL?o3QL@Z)559yt!=?4{YM1 zx`q7-Ytr&V@s_wrclMaZ^3^{rxp#e0>W1Feo73CZoLQM~9d|jiqoyYG@7VnOtra_7 zLwZ}Vy=RY2n0ku7k+OQmrz;9ir=+$RmD~Ki*RZTKY&n@|NZ0)FNt?U1IjU)W!>H_Uob*rTty zsxMD;*JgcIel513Epkq`<>>rz<1=eNs5?@8JQ41EWyEOUT72}!oP!Jh(gB+#i#kXw GUiBZ;`8Zkt literal 0 HcmV?d00001 diff --git a/solr/webapp/web/js/main.js b/solr/webapp/web/js/main.js index c9b09952450..aa5dec67b05 100644 --- a/solr/webapp/web/js/main.js +++ b/solr/webapp/web/js/main.js @@ -40,7 +40,6 @@ require 'lib/order!scripts/documents', 'lib/order!scripts/dataimport', 'lib/order!scripts/dashboard', - 'lib/order!scripts/file', 'lib/order!scripts/files', 'lib/order!scripts/index', 'lib/order!scripts/java-properties', diff --git a/solr/webapp/web/js/scripts/app.js b/solr/webapp/web/js/scripts/app.js index 2ea303d98b6..1267e7cb4c4 100644 --- a/solr/webapp/web/js/scripts/app.js +++ b/solr/webapp/web/js/scripts/app.js @@ -364,7 +364,6 @@ var solr_admin = function( app_config ) //Keep this in alphabetical order after the overview '
  • Overview
  • ' + "\n" + '
  • Analysis
  • ' + "\n" + - '
  • Config
  • ' + "\n" + '
  • Dataimport
  • ' + "\n" + '
  • Documents
  • ' + "\n" + '
  • Files
  • ' + "\n" + @@ -372,7 +371,6 @@ var solr_admin = function( app_config ) '
  • Plugins / Stats
  • ' + "\n" + '
  • Query
  • ' + "\n" + '
  • Replication
  • ' + "\n" + - '
  • Schema
  • ' + "\n" + '
  • Schema Browser
  • ' ) .show(); diff --git a/solr/webapp/web/js/scripts/file.js b/solr/webapp/web/js/scripts/file.js deleted file mode 100644 index 95d201feba1..00000000000 --- a/solr/webapp/web/js/scripts/file.js +++ /dev/null @@ -1,73 +0,0 @@ -/* - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -// #/:core/schema, #/:core/config -sammy.get -( - new RegExp( app.core_regex_base + '\\/(schema|config)$' ), - function( context ) - { - var core_basepath = this.active_core.attr( 'data-basepath' ); - var content_element = $( '#content' ); - - var url = window.location.protocol + '//' + window.location.host + core_basepath + '/admin/file' - + '?file=' + this.active_core.attr( context.params.splat[1] ) - + '&contentType=text/xml;charset=utf-8'; - - $.get - ( - 'tpl/file.html', - function( template ) - { - content_element - .html( template ); - - $( '#url', content_element ) - .text( url ) - .attr( 'href', url ); - - $.ajax - ( - { - url : url, - dataType : 'xml', - context : $( '#response' ,content_element ), - beforeSend : function( xhr, settings ) - { - this - .html( '
    Loading ...
    ' ); - }, - complete : function( xhr, text_status ) - { - var code = $( - '
    ' +
    -                xhr.responseText.esc() +
    -                '
    ' - ); - this.html( code ); - - if( 'success' === text_status ) - { - hljs.highlightBlock( code.get(0) ); - } - } - } - ); - } - ); - } -); \ No newline at end of file diff --git a/solr/webapp/web/js/scripts/files.js b/solr/webapp/web/js/scripts/files.js index 9f2ef63617d..401bb0484a1 100644 --- a/solr/webapp/web/js/scripts/files.js +++ b/solr/webapp/web/js/scripts/files.js @@ -189,6 +189,11 @@ sammy.get .addClass( 'show' ); var endpoint = file_endpoint + '?file=' + selected_file; + + var content_type_map = { xml : 'text/xml', html : 'text/html', js : 'text/javascript' }; + var file_ext = selected_file.match( /\.(\w+)$/ ); + endpoint += '&contentType=' + ( content_type_map[ file_ext[1] || '' ] || 'text/plain' ) + ';charset=utf-8'; + var public_url = window.location.protocol + '//' + window.location.host + endpoint; $( '#url', frame_element ) @@ -257,15 +262,50 @@ sammy.get ( { url : endpoint, - context : $( 'form', frame_element ), + context : frame_element, beforeSend : function( xhr, settings ) { + var block = $( '.view-file .response', this ); + + if( !block.data( 'placeholder' ) ) + { + block.data( 'placeholder', block.text() ); + } + + block + .text( block.data( 'placeholder' ) ); }, success : function( response, text_status, xhr ) { change_button_label( this, 'existing-title' ); - $( 'textarea', this ) + var content_type = xhr.getResponseHeader( 'Content-Type' ) || ''; + var highlight = null; + + if( 0 === content_type.indexOf( 'text/xml' ) || 0 === xhr.responseText.indexOf( '' + + xhr.responseText.esc() + + '' + ); + $( '.view-file .response', this ) + .html( code ); + + if( highlight ) + { + hljs.highlightBlock( code.get( 0 ) ); + } + + $( 'form textarea', this ) .val( xhr.responseText ); }, error : function( xhr, text_status, error_thrown) @@ -283,6 +323,19 @@ sammy.get } load_file(); + $( '.top button', frame_element ) + .on + ( + 'click', + function( event ) + { + $( '#file-content', frame_element ) + .toggleClass( 'modify-file' ); + + return false; + } + ); + $( 'form.upload', frame_element ) .on ( @@ -341,4 +394,15 @@ sammy.get } ); } +); + +// legacy redirect for 'config' & 'schema' pages +// #/:core/schema, #/:core/config +sammy.get +( + new RegExp( app.core_regex_base + '\\/(schema|config)$' ), + function( context ) + { + context.redirect( '#/' + context.params.splat[0] + '/files?file=' + this.active_core.attr( context.params.splat[1] ) ); + } ); \ No newline at end of file diff --git a/solr/webapp/web/tpl/file.html b/solr/webapp/web/tpl/file.html deleted file mode 100755 index 25fa03dcf87..00000000000 --- a/solr/webapp/web/tpl/file.html +++ /dev/null @@ -1,23 +0,0 @@ - -
    - - - -
    - -
    \ No newline at end of file diff --git a/solr/webapp/web/tpl/files.html b/solr/webapp/web/tpl/files.html index dba9bf0d0e8..93ffca897ca 100644 --- a/solr/webapp/web/tpl/files.html +++ b/solr/webapp/web/tpl/files.html @@ -43,29 +43,50 @@ limitations under the License.
    - +
    -

    The requested file does (not yet) exist. Save file or Upload new file will create it.

    + -
    - - +
    + + + -
    -
    - +
    -
    +
    - +
    Loading …
    -
    - -
    +
    - +
    + +

    The requested file does (not yet) exist. Save file or Upload new file will create it.

    + +
    + + + +
    + +
    + + + +
    + + + +
    + +
    + + + +
    From 94fe5db45ca9733a9466a238488262abc6ec2d92 Mon Sep 17 00:00:00 2001 From: Shalin Shekhar Mangar Date: Tue, 19 Nov 2013 13:25:12 +0000 Subject: [PATCH 040/223] Reformatted code according to lucene/solr standards git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1543422 13f79535-47bb-0310-9956-ffa450edef68 --- .../cloud/TriLevelCompositeIdRoutingTest.java | 15 ++++--- .../solr/common/cloud/CompositeIdRouter.java | 39 ++++++++++--------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/solr/core/src/test/org/apache/solr/cloud/TriLevelCompositeIdRoutingTest.java b/solr/core/src/test/org/apache/solr/cloud/TriLevelCompositeIdRoutingTest.java index 07a61bcb98c..024cc016e0f 100644 --- a/solr/core/src/test/org/apache/solr/cloud/TriLevelCompositeIdRoutingTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/TriLevelCompositeIdRoutingTest.java @@ -23,7 +23,6 @@ import org.junit.BeforeClass; import java.util.HashMap; import java.util.HashSet; -import java.util.Random; import java.util.Set; @@ -80,7 +79,7 @@ public class TriLevelCompositeIdRoutingTest extends ShardRoutingTest { // for now, we know how ranges will be distributed to shards. // may have to look it up in clusterstate if that assumption changes. - for (int i=0;i < NUM_DOCS;i++) { + for (int i = 0; i < NUM_DOCS; i++) { int appId = r.nextInt(NUM_APPS) + 1; int userId = r.nextInt(NUM_USERS) + 1; @@ -93,10 +92,10 @@ public class TriLevelCompositeIdRoutingTest extends ShardRoutingTest { HashMap idMap = new HashMap(); - for(int i=1;i<=sliceCount;i++) { + for (int i = 1; i <= sliceCount; i++) { Set ids = doQueryGetUniqueIdKeys("q", "*:*", "shards", "shard" + i); - for(String id:ids) { + for (String id : ids) { assertFalse("Found the same route key [" + id + "] in 2 shards.", idMap.containsKey(id)); idMap.put(getKey(id), i); } @@ -111,7 +110,7 @@ public class TriLevelCompositeIdRoutingTest extends ShardRoutingTest { // may have to look it up in clusterstate if that assumption changes. del("*:*"); - for (int i=0;i < NUM_DOCS;i++) { + for (int i = 0; i < NUM_DOCS; i++) { int appId = r.nextInt(NUM_APPS) + 1; int userId = r.nextInt(NUM_USERS) + 1; int bitMask = r.nextInt(16) + 1; @@ -125,10 +124,10 @@ public class TriLevelCompositeIdRoutingTest extends ShardRoutingTest { HashMap idMap = new HashMap(); - for(int i=1;i<=sliceCount;i++) { + for (int i = 1; i <= sliceCount; i++) { Set ids = doQueryGetUniqueIdKeys("q", "*:*", "shards", "shard" + i); - for(String id:ids) { + for (String id : ids) { assertFalse("Found the same route key [" + id + "] in 2 shards.", idMap.containsKey(id)); idMap.put(getKey(id), i); } @@ -137,7 +136,7 @@ public class TriLevelCompositeIdRoutingTest extends ShardRoutingTest { } void doAddDoc(String id) throws Exception { - index("id",id); + index("id", id); // todo - target diff servers and use cloud clients as well as non-cloud clients } diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/CompositeIdRouter.java b/solr/solrj/src/java/org/apache/solr/common/cloud/CompositeIdRouter.java index 05c1ab7b10a..862e41759a4 100644 --- a/solr/solrj/src/java/org/apache/solr/common/cloud/CompositeIdRouter.java +++ b/solr/solrj/src/java/org/apache/solr/common/cloud/CompositeIdRouter.java @@ -48,7 +48,7 @@ public class CompositeIdRouter extends HashBasedRouter { if (shardFieldName != null && doc != null) { Object o = doc.getFieldValue(shardFieldName); if (o == null) - throw new SolrException (SolrException.ErrorCode.BAD_REQUEST, "No value for :"+shardFieldName + ". Unable to identify shard"); + throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "No value for :" + shardFieldName + ". Unable to identify shard"); id = o.toString(); } if (id.indexOf(SEPARATOR) < 0) { @@ -61,6 +61,7 @@ public class CompositeIdRouter extends HashBasedRouter { /** * Get Range for a given CompositeId based route key + * * @param routeKey to return Range for * @return Range for given routeKey */ @@ -112,10 +113,10 @@ public class CompositeIdRouter extends HashBasedRouter { result.add(new Range(range.min, keyRange.min - 1)); result.add(keyRange); result.add((new Range(keyRange.max + 1, range.max))); - } else if (range.includes(keyRange.max)) { + } else if (range.includes(keyRange.max)) { result.add(new Range(range.min, keyRange.max)); result.add(new Range(keyRange.max + 1, range.max)); - } else { + } else { result.add(new Range(range.min, keyRange.min - 1)); result.add(new Range(keyRange.min, range.max)); } @@ -129,7 +130,7 @@ public class CompositeIdRouter extends HashBasedRouter { assert max >= min; if (partitions == 0) return Collections.EMPTY_LIST; - long rangeSize = (long)max - (long)min; + long rangeSize = (long) max - (long) min; long rangeStep = Math.max(1, rangeSize / partitions); List ranges = new ArrayList(partitions); @@ -145,7 +146,7 @@ public class CompositeIdRouter extends HashBasedRouter { // With default bits==16, one would need to create more than 4000 shards before this // becomes false by default. int mask = 0x0000ffff; - boolean round = rangeStep >= (1<= (1 << bits) * 16; while (end < max) { targetEnd = targetStart + rangeStep; @@ -154,7 +155,7 @@ public class CompositeIdRouter extends HashBasedRouter { if (round && ((end & mask) != mask)) { // round up or down? int increment = 1 << bits; // 0x00010000 - long roundDown = (end | mask) - increment ; + long roundDown = (end | mask) - increment; long roundUp = (end | mask) + increment; if (end - roundDown < roundUp - end && roundDown > start) { end = roundDown; @@ -167,7 +168,7 @@ public class CompositeIdRouter extends HashBasedRouter { if (ranges.size() == partitions - 1) { end = max; } - ranges.add(new Range((int)start, (int)end)); + ranges.add(new Range((int) start, (int) end)); start = end + 1L; targetStart = targetEnd + 1L; } @@ -192,9 +193,9 @@ public class CompositeIdRouter extends HashBasedRouter { pieces = parts.length; hashes = new int[pieces]; numBits = new int[2]; - if(key.endsWith("!")) + if (key.endsWith("!")) pieces++; - if(pieces == 3) { + if (pieces == 3) { numBits[0] = 8; numBits[1] = 8; triLevel = true; @@ -204,10 +205,10 @@ public class CompositeIdRouter extends HashBasedRouter { } - for(int i=0;i 0) { + if (commaIdx > 0) { numBits[i] = getNumBits(parts[i], commaIdx); parts[i] = parts[i].substring(0, commaIdx); } @@ -220,7 +221,7 @@ public class CompositeIdRouter extends HashBasedRouter { int lowerBound; int upperBound; - if(triLevel) { + if (triLevel) { lowerBound = hashes[0] & masks[0] | hashes[1] & masks[1]; upperBound = lowerBound | masks[2]; } else { @@ -245,7 +246,7 @@ public class CompositeIdRouter extends HashBasedRouter { */ private int[] getMasks() { int[] masks; - if(triLevel) + if (triLevel) masks = getBitMasks(numBits[0], numBits[1]); else masks = getBitMasks(numBits[0]); @@ -256,8 +257,8 @@ public class CompositeIdRouter extends HashBasedRouter { private int[] getBitMasks(int firstBits, int secondBits) { // java can't shift 32 bits int[] masks = new int[3]; - masks[0] = firstBits==0 ? 0 : (-1 << (32-firstBits)); - masks[1] = (firstBits + secondBits)==0 ? 0 : (-1 << (32 - firstBits - secondBits)); + masks[0] = firstBits == 0 ? 0 : (-1 << (32 - firstBits)); + masks[1] = (firstBits + secondBits) == 0 ? 0 : (-1 << (32 - firstBits - secondBits)); masks[1] = masks[0] ^ masks[1]; masks[2] = (firstBits + secondBits) == 32 ? 0 : ~(masks[0] | masks[1]); return masks; @@ -265,7 +266,7 @@ public class CompositeIdRouter extends HashBasedRouter { private int getNumBits(String firstPart, int commaIdx) { int v = 0; - for (int idx = commaIdx + 1; idx '9') return -1; v = v * 10 + (ch - '0'); @@ -277,15 +278,15 @@ public class CompositeIdRouter extends HashBasedRouter { // java can't shift 32 bits int[] masks; masks = new int[2]; - masks[0] = firstBits==0 ? 0 : (-1 << (32-firstBits)); - masks[1] = firstBits==32 ? 0 : (-1 >>> firstBits); + masks[0] = firstBits == 0 ? 0 : (-1 << (32 - firstBits)); + masks[1] = firstBits == 32 ? 0 : (-1 >>> firstBits); return masks; } int getHash() { int result = hashes[0] & masks[0]; - for(int i=1;i Date: Tue, 19 Nov 2013 15:20:51 +0000 Subject: [PATCH 041/223] SOLR-5464,SOLR-5465,SOLR-5452: Fix CHANGES entries - move to 4.6 git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1543450 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 41fb2b1654c..cc62372d7df 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -114,14 +114,6 @@ Bug Fixes * SOLR-5461: Request proxying should only set con.setDoOutput(true) if the request is a post. (Mark Miller) -* SOLR-5465: SolrCmdDistributor retry logic has a concurrency race bug. - (Mark Miller) - -* SOLR-5464: ConcurrentSolrServer does not stream pure delete by id requests. - (Mark Miller) - -* SOLR-5452: Do not attempt to proxy internal update requests. (Mark Miller) - Optimizations ---------------------- @@ -209,6 +201,9 @@ New Features * SOLR-5084: new field type EnumField. (Elran Dvir via Erick Erickson) +* SOLR-5464: Add option to ConcurrentSolrServer to stream pure delete + requests. (Mark Miller) + Bug Fixes ---------------------- @@ -249,6 +244,11 @@ Bug Fixes * SOLR-5397: Replication can fail silently in some cases. (Mark Miller) +* SOLR-5465: SolrCmdDistributor retry logic has a concurrency race bug. + (Mark Miller) + +* SOLR-5452: Do not attempt to proxy internal update requests. (Mark Miller) + Optimizations ---------------------- From 6b67d485dc27874bd39f2f9429b51c30c78715c4 Mon Sep 17 00:00:00 2001 From: Shawn Heisey Date: Tue, 19 Nov 2013 19:39:53 +0000 Subject: [PATCH 042/223] fix typo in jmx log message git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1543545 13f79535-47bb-0310-9956-ffa450edef68 --- solr/core/src/java/org/apache/solr/core/JmxMonitoredMap.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solr/core/src/java/org/apache/solr/core/JmxMonitoredMap.java b/solr/core/src/java/org/apache/solr/core/JmxMonitoredMap.java index 45b1e358750..384fe0896da 100644 --- a/solr/core/src/java/org/apache/solr/core/JmxMonitoredMap.java +++ b/solr/core/src/java/org/apache/solr/core/JmxMonitoredMap.java @@ -320,7 +320,7 @@ public class JmxMonitoredMap extends try { list.add(new Attribute(attribute, getAttribute(attribute))); } catch (Exception e) { - LOG.warn("Could not get attibute " + attribute); + LOG.warn("Could not get attribute " + attribute); } } From 122171155f418a6b7a69720d43770d8297c7c39a Mon Sep 17 00:00:00 2001 From: Erick Erickson Date: Tue, 19 Nov 2013 23:45:31 +0000 Subject: [PATCH 043/223] SOLR-5302 Analytics component. Checking in to trunk, we'll let it back then port to 4x git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1543651 13f79535-47bb-0310-9956-ffa450edef68 --- .../accumulator/BasicAccumulator.java | 163 +++ .../accumulator/FacetingAccumulator.java | 722 ++++++++++ .../accumulator/ValueAccumulator.java | 59 + .../facet/FacetValueAccumulator.java | 36 + .../facet/FieldFacetAccumulator.java | 143 ++ .../facet/QueryFacetAccumulator.java | 69 + .../facet/RangeFacetAccumulator.java | 50 + .../analytics/accumulator/facet/package.html | 27 + .../solr/analytics/accumulator/package.html | 27 + .../analytics/expression/BaseExpression.java | 86 ++ .../expression/DualDelegateExpression.java | 100 ++ .../solr/analytics/expression/Expression.java | 44 + .../expression/ExpressionFactory.java | 185 +++ .../expression/MultiDelegateExpression.java | 132 ++ .../expression/SingleDelegateExpression.java | 89 ++ .../solr/analytics/expression/package.html | 27 + .../plugin/AnalyticsStatisticsCollector.java | 114 ++ .../apache/solr/analytics/plugin/package.html | 27 + .../request/AbstractFieldFacetRequest.java | 43 + .../request/AnalyticsContentHandler.java | 315 +++++ .../analytics/request/AnalyticsRequest.java | 115 ++ .../request/AnalyticsRequestFactory.java | 309 +++++ .../analytics/request/AnalyticsStats.java | 132 ++ .../analytics/request/ExpressionRequest.java | 73 + .../solr/analytics/request/FacetRequest.java | 27 + .../analytics/request/FieldFacetRequest.java | 173 +++ .../analytics/request/QueryFacetRequest.java | 75 ++ .../analytics/request/RangeFacetRequest.java | 130 ++ .../solr/analytics/request/package.html | 27 + .../AbstractDelegatingStatsCollector.java | 75 ++ .../statistics/MedianStatsCollector.java | 76 ++ .../statistics/MinMaxStatsCollector.java | 113 ++ .../statistics/NumericStatsCollector.java | 68 + .../statistics/PercentileStatsCollector.java | 80 ++ .../analytics/statistics/StatsCollector.java | 70 + .../StatsCollectorSupplierFactory.java | 649 +++++++++ .../statistics/UniqueStatsCollector.java | 53 + .../solr/analytics/statistics/package.html | 27 + .../solr/analytics/util/AnalyticsParams.java | 114 ++ .../solr/analytics/util/AnalyticsParsers.java | 200 +++ .../solr/analytics/util/MedianCalculator.java | 128 ++ .../analytics/util/PercentileCalculator.java | 177 +++ .../util/RangeEndpointCalculator.java | 358 +++++ .../apache/solr/analytics/util/package.html | 27 + .../AbsoluteValueDoubleFunction.java | 59 + .../util/valuesource/AddDoubleFunction.java | 48 + .../valuesource/ConcatStringFunction.java | 53 + .../util/valuesource/ConstDateSource.java | 114 ++ .../util/valuesource/ConstDoubleSource.java | 106 ++ .../util/valuesource/ConstStringSource.java | 51 + .../util/valuesource/DateFieldSource.java | 127 ++ .../util/valuesource/DateMathFunction.java | 71 + .../util/valuesource/DivDoubleFunction.java | 47 + .../util/valuesource/DualDoubleFunction.java | 95 ++ .../util/valuesource/FilterFieldSource.java | 156 +++ .../util/valuesource/LogDoubleFunction.java | 42 + .../util/valuesource/MultiDateFunction.java | 134 ++ .../util/valuesource/MultiDoubleFunction.java | 120 ++ .../util/valuesource/MultiStringFunction.java | 149 ++ .../valuesource/MultiplyDoubleFunction.java | 48 + .../valuesource/NegateDoubleFunction.java | 54 + .../util/valuesource/PowDoubleFunction.java | 47 + .../valuesource/ReverseStringFunction.java | 44 + .../valuesource/SingleDoubleFunction.java | 80 ++ .../valuesource/SingleStringFunction.java | 120 ++ .../analytics/util/valuesource/package.html | 27 + .../java/org/apache/solr/core/SolrCore.java | 70 +- .../handler/component/AnalyticsComponent.java | 97 ++ .../solr/handler/component/SearchHandler.java | 11 +- .../analytics/requestFiles/expressions.txt | 70 + .../requestFiles/fieldFacetExtras.txt | 66 + .../analytics/requestFiles/fieldFacets.txt | 132 ++ .../analytics/requestFiles/functions.txt | 62 + .../analytics/requestFiles/noFacets.txt | 74 + .../analytics/requestFiles/queryFacets.txt | 45 + .../analytics/requestFiles/rangeFacets.txt | 170 +++ .../analytics/requestXMLFiles/expressions.xml | 285 ++++ .../requestXMLFiles/fieldFacetExtras.xml | 101 ++ .../analytics/requestXMLFiles/fieldFacets.xml | 496 +++++++ .../analytics/requestXMLFiles/functions.xml | 246 ++++ .../analytics/requestXMLFiles/noFacets.xml | 310 +++++ .../analytics/requestXMLFiles/queryFacets.xml | 94 ++ .../analytics/requestXMLFiles/rangeFacets.xml | 319 +++++ .../collection1/conf/schema-analytics.xml | 94 ++ .../analytics/AbstractAnalyticsStatsTest.java | 156 +++ .../apache/solr/analytics/NoFacetTest.java | 483 +++++++ .../analytics/expression/ExpressionTest.java | 270 ++++ .../facet/AbstractAnalyticsFacetTest.java | 257 ++++ .../analytics/facet/FieldFacetExtrasTest.java | 190 +++ .../solr/analytics/facet/FieldFacetTest.java | 1196 +++++++++++++++++ .../solr/analytics/facet/QueryFacetTest.java | 131 ++ .../solr/analytics/facet/RangeFacetTest.java | 467 +++++++ .../util/valuesource/FunctionTest.java | 231 ++++ 93 files changed, 13610 insertions(+), 39 deletions(-) create mode 100644 solr/core/src/java/org/apache/solr/analytics/accumulator/BasicAccumulator.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/accumulator/FacetingAccumulator.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/accumulator/ValueAccumulator.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/accumulator/facet/FacetValueAccumulator.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/accumulator/facet/FieldFacetAccumulator.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/accumulator/facet/QueryFacetAccumulator.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/accumulator/facet/RangeFacetAccumulator.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/accumulator/facet/package.html create mode 100644 solr/core/src/java/org/apache/solr/analytics/accumulator/package.html create mode 100644 solr/core/src/java/org/apache/solr/analytics/expression/BaseExpression.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/expression/DualDelegateExpression.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/expression/Expression.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/expression/ExpressionFactory.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/expression/MultiDelegateExpression.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/expression/SingleDelegateExpression.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/expression/package.html create mode 100644 solr/core/src/java/org/apache/solr/analytics/plugin/AnalyticsStatisticsCollector.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/plugin/package.html create mode 100644 solr/core/src/java/org/apache/solr/analytics/request/AbstractFieldFacetRequest.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/request/AnalyticsContentHandler.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/request/AnalyticsRequest.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/request/AnalyticsRequestFactory.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/request/AnalyticsStats.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/request/ExpressionRequest.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/request/FacetRequest.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/request/FieldFacetRequest.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/request/QueryFacetRequest.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/request/RangeFacetRequest.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/request/package.html create mode 100644 solr/core/src/java/org/apache/solr/analytics/statistics/AbstractDelegatingStatsCollector.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/statistics/MedianStatsCollector.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/statistics/MinMaxStatsCollector.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/statistics/NumericStatsCollector.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/statistics/PercentileStatsCollector.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/statistics/StatsCollector.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/statistics/StatsCollectorSupplierFactory.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/statistics/UniqueStatsCollector.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/statistics/package.html create mode 100644 solr/core/src/java/org/apache/solr/analytics/util/AnalyticsParams.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/util/AnalyticsParsers.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/util/MedianCalculator.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/util/PercentileCalculator.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/util/RangeEndpointCalculator.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/util/package.html create mode 100644 solr/core/src/java/org/apache/solr/analytics/util/valuesource/AbsoluteValueDoubleFunction.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/util/valuesource/AddDoubleFunction.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/util/valuesource/ConcatStringFunction.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/util/valuesource/ConstDateSource.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/util/valuesource/ConstDoubleSource.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/util/valuesource/ConstStringSource.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/util/valuesource/DateFieldSource.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/util/valuesource/DateMathFunction.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/util/valuesource/DivDoubleFunction.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/util/valuesource/DualDoubleFunction.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/util/valuesource/FilterFieldSource.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/util/valuesource/LogDoubleFunction.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/util/valuesource/MultiDateFunction.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/util/valuesource/MultiDoubleFunction.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/util/valuesource/MultiStringFunction.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/util/valuesource/MultiplyDoubleFunction.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/util/valuesource/NegateDoubleFunction.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/util/valuesource/PowDoubleFunction.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/util/valuesource/ReverseStringFunction.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/util/valuesource/SingleDoubleFunction.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/util/valuesource/SingleStringFunction.java create mode 100644 solr/core/src/java/org/apache/solr/analytics/util/valuesource/package.html create mode 100644 solr/core/src/java/org/apache/solr/handler/component/AnalyticsComponent.java create mode 100644 solr/core/src/test-files/analytics/requestFiles/expressions.txt create mode 100644 solr/core/src/test-files/analytics/requestFiles/fieldFacetExtras.txt create mode 100644 solr/core/src/test-files/analytics/requestFiles/fieldFacets.txt create mode 100644 solr/core/src/test-files/analytics/requestFiles/functions.txt create mode 100644 solr/core/src/test-files/analytics/requestFiles/noFacets.txt create mode 100644 solr/core/src/test-files/analytics/requestFiles/queryFacets.txt create mode 100644 solr/core/src/test-files/analytics/requestFiles/rangeFacets.txt create mode 100644 solr/core/src/test-files/analytics/requestXMLFiles/expressions.xml create mode 100644 solr/core/src/test-files/analytics/requestXMLFiles/fieldFacetExtras.xml create mode 100644 solr/core/src/test-files/analytics/requestXMLFiles/fieldFacets.xml create mode 100644 solr/core/src/test-files/analytics/requestXMLFiles/functions.xml create mode 100644 solr/core/src/test-files/analytics/requestXMLFiles/noFacets.xml create mode 100644 solr/core/src/test-files/analytics/requestXMLFiles/queryFacets.xml create mode 100644 solr/core/src/test-files/analytics/requestXMLFiles/rangeFacets.xml create mode 100644 solr/core/src/test-files/solr/collection1/conf/schema-analytics.xml create mode 100644 solr/core/src/test/org/apache/solr/analytics/AbstractAnalyticsStatsTest.java create mode 100644 solr/core/src/test/org/apache/solr/analytics/NoFacetTest.java create mode 100644 solr/core/src/test/org/apache/solr/analytics/expression/ExpressionTest.java create mode 100644 solr/core/src/test/org/apache/solr/analytics/facet/AbstractAnalyticsFacetTest.java create mode 100644 solr/core/src/test/org/apache/solr/analytics/facet/FieldFacetExtrasTest.java create mode 100644 solr/core/src/test/org/apache/solr/analytics/facet/FieldFacetTest.java create mode 100644 solr/core/src/test/org/apache/solr/analytics/facet/QueryFacetTest.java create mode 100644 solr/core/src/test/org/apache/solr/analytics/facet/RangeFacetTest.java create mode 100644 solr/core/src/test/org/apache/solr/analytics/util/valuesource/FunctionTest.java diff --git a/solr/core/src/java/org/apache/solr/analytics/accumulator/BasicAccumulator.java b/solr/core/src/java/org/apache/solr/analytics/accumulator/BasicAccumulator.java new file mode 100644 index 00000000000..6a9232f9db5 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/accumulator/BasicAccumulator.java @@ -0,0 +1,163 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.accumulator; + +import java.io.IOException; +import java.util.Collections; +import java.util.Date; +import java.util.Set; + +import org.apache.lucene.index.AtomicReaderContext; +import org.apache.solr.analytics.expression.Expression; +import org.apache.solr.analytics.expression.ExpressionFactory; +import org.apache.solr.analytics.request.AnalyticsRequest; +import org.apache.solr.analytics.request.ExpressionRequest; +import org.apache.solr.analytics.statistics.StatsCollector; +import org.apache.solr.analytics.statistics.StatsCollectorSupplierFactory; +import org.apache.solr.common.SolrException; +import org.apache.solr.common.SolrException.ErrorCode; +import org.apache.solr.common.util.NamedList; +import org.apache.solr.schema.TrieDateField; +import org.apache.solr.search.DocSet; +import org.apache.solr.search.SolrIndexSearcher; + +import com.google.common.base.Supplier; + +/** + * A BasicAccumulator manages the ValueCounters and Expressions without regard to Facets. + */ +public class BasicAccumulator extends ValueAccumulator { + protected final SolrIndexSearcher searcher; + protected final AnalyticsRequest request; + protected final DocSet docs; + protected final Supplier statsCollectorArraySupplier; + protected final StatsCollector[] statsCollectors; + protected final Expression[] expressions; + protected final String[] expressionNames; + protected final String[] expressionStrings; + protected final Set hiddenExpressions; + protected AtomicReaderContext context = null; + + public BasicAccumulator(SolrIndexSearcher searcher, DocSet docs, AnalyticsRequest request) throws IOException { + this.searcher = searcher; + this.docs = docs; + this.request = request; + statsCollectorArraySupplier = StatsCollectorSupplierFactory.create(searcher.getSchema(), request); + statsCollectors = statsCollectorArraySupplier.get(); + int size = request.getExpressions().size(); + expressionNames = new String[size]; + expressionStrings = new String[size]; + int count = 0; + Collections.sort(request.getExpressions()); + for (ExpressionRequest expRequest : request.getExpressions()) { + expressionNames[count] = expRequest.getName(); + expressionStrings[count++] = expRequest.getExpressionString(); + } + expressions = makeExpressions(statsCollectors); + hiddenExpressions = request.getHiddenExpressions(); + } + + @Override + public void setNextReader(AtomicReaderContext context) throws IOException { + this.context = context; + for (StatsCollector counter : statsCollectors) { + counter.setNextReader(context); + } + } + + public static BasicAccumulator create(SolrIndexSearcher searcher, DocSet docs, AnalyticsRequest request) throws IOException { + return new BasicAccumulator(searcher,docs,request); + } + + /** + * Passes the documents on to the {@link StatsCollector}s to be collected. + * @param doc Document to collect from + */ + @Override + public void collect(int doc) throws IOException { + for (StatsCollector statsCollector : statsCollectors) { + statsCollector.collect(doc); + } + } + + @Override + public void compute() { + for (StatsCollector statsCollector : statsCollectors) { + statsCollector.compute(); + } + } + + public NamedList export(){ + NamedList base = new NamedList(); + for (int count = 0; count < expressions.length; count++) { + if (!hiddenExpressions.contains(expressionNames[count])) { + base.add(expressionNames[count], expressions[count].getValue()); + } + } + return base; + } + + /** + * Builds an array of Expressions with the given list of counters + * @param statsCollectors the stats collectors + * @return The array of Expressions + */ + public Expression[] makeExpressions(StatsCollector[] statsCollectors) { + Expression[] expressions = new Expression[expressionStrings.length]; + for (int count = 0; count < expressionStrings.length; count++) { + expressions[count] = ExpressionFactory.create(expressionStrings[count], statsCollectors); + } + return expressions; + } + + /** + * Returns the value of an expression to use in a field or query facet. + * @param expressionName the name of the expression + * @return String String representation of pivot value + */ + @SuppressWarnings({ "deprecation", "rawtypes" }) + public String getResult(String expressionName) { + for (int count = 0; count < expressionNames.length; count++) { + if (expressionName.equals(expressionNames[count])) { + Comparable value = expressions[count].getValue(); + if (value.getClass().equals(Date.class)) { + return TrieDateField.formatExternal((Date)value); + } else { + return value.toString(); + } + } + } + throw new SolrException(ErrorCode.BAD_REQUEST, "Pivot expression "+expressionName+" not found."); + } + + /** + * Used for JMX stats collecting. Counts the number of stats requests + * @return number of unique stats collectors + */ + public long getNumStatsCollectors() { + return statsCollectors.length; + } + + /** + * Used for JMX stats collecting. Counts the number of queries in all query facets + * @return number of queries requested in all query facets. + */ + public long getNumQueries() { + return 0l; + } +} diff --git a/solr/core/src/java/org/apache/solr/analytics/accumulator/FacetingAccumulator.java b/solr/core/src/java/org/apache/solr/analytics/accumulator/FacetingAccumulator.java new file mode 100644 index 00000000000..f22c345e424 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/accumulator/FacetingAccumulator.java @@ -0,0 +1,722 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.accumulator; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.apache.lucene.index.AtomicReaderContext; +import org.apache.lucene.search.Filter; +import org.apache.lucene.search.Query; +import org.apache.solr.analytics.accumulator.facet.FacetValueAccumulator; +import org.apache.solr.analytics.accumulator.facet.FieldFacetAccumulator; +import org.apache.solr.analytics.accumulator.facet.QueryFacetAccumulator; +import org.apache.solr.analytics.accumulator.facet.RangeFacetAccumulator; +import org.apache.solr.analytics.expression.Expression; +import org.apache.solr.analytics.expression.ExpressionFactory; +import org.apache.solr.analytics.request.AnalyticsContentHandler; +import org.apache.solr.analytics.request.AnalyticsRequest; +import org.apache.solr.analytics.request.FieldFacetRequest; +import org.apache.solr.analytics.request.FieldFacetRequest.FacetSortSpecification; +import org.apache.solr.analytics.request.QueryFacetRequest; +import org.apache.solr.analytics.request.RangeFacetRequest; +import org.apache.solr.analytics.statistics.StatsCollector; +import org.apache.solr.analytics.util.AnalyticsParams; +import org.apache.solr.analytics.util.RangeEndpointCalculator; +import org.apache.solr.analytics.util.RangeEndpointCalculator.FacetRange; +import org.apache.solr.common.SolrException; +import org.apache.solr.common.SolrException.ErrorCode; +import org.apache.solr.common.util.NamedList; +import org.apache.solr.request.SolrQueryRequest; +import org.apache.solr.schema.SchemaField; +import org.apache.solr.schema.TrieDateField; +import org.apache.solr.search.DocSet; +import org.apache.solr.search.QParser; +import org.apache.solr.search.SolrIndexSearcher; +import org.apache.solr.search.SyntaxError; + +import com.google.common.collect.Iterables; + +/** + * A FacetingAccumulator manages the StatsCollectors and Expressions for facets. + */ +public class FacetingAccumulator extends BasicAccumulator implements FacetValueAccumulator { + public static final String MISSING_VALUE = "(MISSING)"; + protected boolean basicsAndFieldFacetsComputed; + protected int leafNum; + protected AtomicReaderContext leaf; + protected final AnalyticsRequest analyticsRequest; + protected final Map> fieldFacetExpressions; + protected final Map> rangeFacetExpressions; + protected final Map> queryFacetExpressions; + protected final Map> fieldFacetCollectors; + protected final Map> rangeFacetCollectors; + protected final Map> queryFacetCollectors; + protected final List facetAccumulators; + protected final Set hiddenFieldFacets; + /** the current value of this stat field */ + protected final SolrQueryRequest queryRequest; + + protected List rangeFacets = null; + protected List queryFacets = null; + + protected long queryCount; + + public FacetingAccumulator(SolrIndexSearcher searcher, DocSet docs, AnalyticsRequest request, SolrQueryRequest queryRequest) throws IOException { + // The parent Basic Accumulator keeps track of overall stats while + // the Faceting Accumulator only manages the facet stats + super(searcher, docs, request); + this.analyticsRequest = request; + this.queryRequest = queryRequest; + basicsAndFieldFacetsComputed = false; + List fieldFreqs = request.getFieldFacets(); + List rangeFreqs = request.getRangeFacets(); + List queryFreqs = request.getQueryFacets(); + + this.fieldFacetExpressions = new LinkedHashMap>(fieldFreqs.size()); + this.rangeFacetExpressions = new LinkedHashMap>(rangeFreqs.size()); + this.queryFacetExpressions = new LinkedHashMap>(queryFreqs.size()); + this.fieldFacetCollectors = new LinkedHashMap>(fieldFreqs.size()); + this.rangeFacetCollectors = new LinkedHashMap>(rangeFreqs.size()); + this.queryFacetCollectors = new LinkedHashMap>(queryFreqs.size()); + this.facetAccumulators = new ArrayList(); + this.hiddenFieldFacets = new HashSet(); + + /** + * For each field facet request add a bucket to the {@link Expression} map and {@link StatsCollector} map. + * Field facets are computed during the initial collection of documents, therefore + * the FieldFacetAccumulators are created initially. + */ + for( FieldFacetRequest freq : fieldFreqs ){ + final FieldFacetRequest fr = (FieldFacetRequest) freq; + if (fr.isHidden()) { + hiddenFieldFacets.add(fr.getName()); + } + final SchemaField ff = fr.getField(); + final FieldFacetAccumulator facc = FieldFacetAccumulator.create(searcher, this, ff); + facetAccumulators.add(facc); + fieldFacetExpressions.put(freq.getName(), new LinkedHashMap() ); + fieldFacetCollectors.put(freq.getName(), new LinkedHashMap()); + } + /** + * For each range and query facet request add a bucket to the corresponding + * {@link Expression} map and {@link StatsCollector} map. + * Range and Query Facets are computed in the post processing, so the accumulators + * are not created initially. + */ + for( RangeFacetRequest freq : rangeFreqs ){ + if( rangeFacets == null ) rangeFacets = new ArrayList(); + rangeFacets.add(freq); + rangeFacetExpressions.put(freq.getName(), new LinkedHashMap() ); + rangeFacetCollectors.put(freq.getName(), new LinkedHashMap()); + } + for( QueryFacetRequest freq : queryFreqs ){ + if( queryFacets == null ) queryFacets = new ArrayList(); + queryFacets.add(freq); + queryFacetExpressions.put(freq.getName(), new LinkedHashMap() ); + queryFacetCollectors.put(freq.getName(), new LinkedHashMap()); + } + this.queryCount = 0l; + } + + public static FacetingAccumulator create(SolrIndexSearcher searcher, DocSet docs, AnalyticsRequest request, SolrQueryRequest queryRequest) throws IOException { + return new FacetingAccumulator(searcher,docs,request,queryRequest); + } + + /** + * Update the readers for the {@link BasicAccumulator}, field facets and field facet {@link StatsCollector}s. + * @param context The context to read documents from. + * @throws IOException if there is an error setting the next reader + */ + @Override + public void setNextReader(AtomicReaderContext context) throws IOException { + super.setNextReader(context); + for( Map valueList : fieldFacetCollectors.values() ){ + for (StatsCollector[] statsCollectorList : valueList.values()) { + for (StatsCollector statsCollector : statsCollectorList) { + statsCollector.setNextReader(context); + } + } + } + for (FieldFacetAccumulator fa : facetAccumulators) { + fa.setNextReader(context); + } + } + + /** + * Updates the reader for all of the range facet {@link StatsCollector}s. + * @param context The context to read documents from. + * @throws IOException if there is an error setting the next reader + */ + public void setRangeStatsCollectorReaders(AtomicReaderContext context) throws IOException { + super.setNextReader(context); + for( Map rangeList : rangeFacetCollectors.values() ){ + for (StatsCollector[] statsCollectorList : rangeList.values()) { + for (StatsCollector statsCollector : statsCollectorList) { + statsCollector.setNextReader(context); + } + } + } + } + + + /** + * Updates the reader for all of the query facet {@link StatsCollector}s. + * @param context The context to read documents from. + * @throws IOException if there is an error setting the next reader + */ + public void setQueryStatsCollectorReaders(AtomicReaderContext context) throws IOException { + super.setNextReader(context); + for( Map queryList : queryFacetCollectors.values() ){ + for (StatsCollector[] statsCollectorList : queryList.values()) { + for (StatsCollector statsCollector : statsCollectorList) { + statsCollector.setNextReader(context); + } + } + } + } + + /** + * Called from Analytics stats, adds documents to the field + * facets and the super {@link BasicAccumulator}. + */ + @Override + public void collect(int doc) throws IOException { + for( FieldFacetAccumulator fa : facetAccumulators ){ + fa.collect(doc); + } + super.collect(doc); + } + + /** + * Given a document, fieldFacet field and facetValue, adds the document to the + * {@link StatsCollector}s held in the bucket corresponding to the fieldFacet field and facetValue. + * Called during initial document collection. + */ + @Override + public void collectField(int doc, String facetField, String facetValue) throws IOException { + Map map = fieldFacetCollectors.get(facetField); + StatsCollector[] statsCollectors = map.get(facetValue); + // If the facetValue has not been seen yet, a StatsCollector array is + // created and associated with that bucket. + if( statsCollectors == null ){ + statsCollectors = statsCollectorArraySupplier.get(); + map.put(facetValue,statsCollectors); + fieldFacetExpressions.get(facetField).put(facetValue,makeExpressions(statsCollectors)); + for (StatsCollector statsCollector : statsCollectors) { + statsCollector.setNextReader(context); + } + } + for (StatsCollector statsCollector : statsCollectors) { + statsCollector.collect(doc); + } + } + + /** + * Given a document, rangeFacet field and range, adds the document to the + * {@link StatsCollector}s held in the bucket corresponding to the rangeFacet field and range. + * Called during post processing. + */ + @Override + public void collectRange(int doc, String facetField, String range) throws IOException { + Map map = rangeFacetCollectors.get(facetField); + StatsCollector[] statsCollectors = map.get(range); + // If the range has not been seen yet, a StatsCollector array is + // created and associated with that bucket. + if( statsCollectors == null ){ + statsCollectors = statsCollectorArraySupplier.get(); + map.put(range,statsCollectors); + rangeFacetExpressions.get(facetField).put(range,makeExpressions(statsCollectors)); + for (StatsCollector statsCollector : statsCollectors) { + statsCollector.setNextReader(context); + } + } + for (StatsCollector statsCollector : statsCollectors) { + statsCollector.collect(doc); + } + } + + /** + * Given a document, queryFacet name and query, adds the document to the + * {@link StatsCollector}s held in the bucket corresponding to the queryFacet name and query. + * Called during post processing. + */ + @Override + public void collectQuery(int doc, String facetName, String query) throws IOException { + Map map = queryFacetCollectors.get(facetName); + StatsCollector[] statsCollectors = map.get(query); + // If the query has not been seen yet, a StatsCollector array is + // created and associated with that bucket. + if( statsCollectors == null ){ + statsCollectors = statsCollectorArraySupplier.get(); + map.put(query,statsCollectors); + queryFacetExpressions.get(facetName).put(query,makeExpressions(statsCollectors)); + for (StatsCollector statsCollector : statsCollectors) { + statsCollector.setNextReader(context); + } + } + for (StatsCollector statsCollector : statsCollectors) { + statsCollector.collect(doc); + } + } + + /** + * A comparator to compare expression values for field facet sorting. + */ + public static class EntryComparator implements Comparator> { + private final Comparator comp; + private final int comparatorExpressionPlace; + + public EntryComparator(Comparator comp, int comparatorExpressionPlace) { + this.comp = comp; + this.comparatorExpressionPlace = comparatorExpressionPlace; + } + + @Override + public int compare(Entry o1, Entry o2) { + return comp.compare(o1.getValue()[comparatorExpressionPlace], o2.getValue()[comparatorExpressionPlace]); + } + } + + /** + * Finalizes the statistics within the each facet bucket before exporting; + */ + @Override + public void compute() { + if (!basicsAndFieldFacetsComputed) { + super.compute(); + for( Map f : fieldFacetCollectors.values() ){ + for( StatsCollector[] arr : f.values() ){ + for( StatsCollector b : arr ){ + b.compute(); + } + } + } + basicsAndFieldFacetsComputed = true; + } + } + + /** + * Finalizes the statistics within the a specific query facet before exporting; + */ + public void computeQueryFacet(String facet) { + Map f = queryFacetCollectors.get(facet); + for( StatsCollector[] arr : f.values() ){ + for( StatsCollector b : arr ){ + b.compute(); + } + } + } + + /** + * Finalizes the statistics within the a specific range facet before exporting; + */ + public void computeRangeFacet(String facet) { + Map f = rangeFacetCollectors.get(facet); + for( StatsCollector[] arr : f.values() ){ + for( StatsCollector b : arr ){ + b.compute(); + } + } + } + + /** + * Returns the value of an expression to use in a range or query facet. + * @param expressionName the name of the expression + * @param fieldFacet the facet field + * @param facetValue the facet value + * @return String String representation of pivot value + */ + @SuppressWarnings({ "deprecation", "rawtypes" }) + public String getResult(String expressionName, String fieldFacet, String facetValue) { + if (facetValue.contains(AnalyticsParams.RESULT) && !facetValue.contains(AnalyticsParams.QUERY_RESULT)) { + try { + String[] pivotStr = ExpressionFactory.getArguments(facetValue.substring(facetValue.indexOf('(')+1,facetValue.lastIndexOf(')')).trim()); + if (pivotStr.length==1) { + facetValue = getResult(pivotStr[0]); + } else if (pivotStr.length==3) { + facetValue = getResult(pivotStr[0],pivotStr[1],pivotStr[2]); + } else { + throw new SolrException(ErrorCode.BAD_REQUEST, "Result request "+facetValue+" has an invalid amount of arguments."); + } + } catch (IndexOutOfBoundsException e) { + throw new SolrException(ErrorCode.BAD_REQUEST, "Result request "+facetValue+" is invalid. Lacks parentheses.",e); + } + } + if (fieldFacetExpressions.get(fieldFacet)!=null) { + Expression[] facetExpressions = fieldFacetExpressions.get(fieldFacet).get(facetValue); + for (int count = 0; count < expressionNames.length; count++) { + if (expressionName.equals(expressionNames[count])) { + Comparable value = facetExpressions[count].getValue(); + if (value.getClass().equals(Date.class)) { + return TrieDateField.formatExternal((Date)value); + } else { + return value.toString(); + } + } + } + } + throw new SolrException(ErrorCode.BAD_REQUEST,"Field Facet Pivot expression "+expressionName+" not found."); + } + + /** + * Returns the value of an expression to use in a range or query facet. + * @param currentFacet the name of the current facet + * @param expressionName the name of the expression + * @param queryFacet the facet query + * @param facetValue the field value + * @return String String representation of pivot value + */ + @SuppressWarnings({ "deprecation", "rawtypes" }) + public String getQueryResult(String currentFacet, String expressionName, String queryFacet, String facetValue) { + if (facetValue.contains(AnalyticsParams.RESULT) && !facetValue.contains(AnalyticsParams.QUERY_RESULT)) { + try { + String[] pivotStr = ExpressionFactory.getArguments(facetValue.substring(facetValue.indexOf('(')+1,facetValue.lastIndexOf(')')).trim()); + if (pivotStr.length==1) { + facetValue = getResult(pivotStr[0]); + } else if (pivotStr.length==3) { + facetValue = getResult(pivotStr[0],pivotStr[1],pivotStr[2]); + } else { + throw new SolrException(ErrorCode.BAD_REQUEST, "Result request "+facetValue+" has an invalid amount of arguments."); + } + } catch (IndexOutOfBoundsException e) { + throw new SolrException(ErrorCode.BAD_REQUEST,"Result request "+facetValue+" is invalid. Lacks parentheses.",e); + } + } + if (facetValue.contains(AnalyticsParams.QUERY_RESULT)) { + try { + String[] pivotStr = ExpressionFactory.getArguments(facetValue.substring(facetValue.indexOf('(')+1,facetValue.lastIndexOf(')')).trim()); + if (pivotStr.length==1) { + facetValue = getResult(pivotStr[0]); + } else if (pivotStr.length==3) { + facetValue = getQueryResult(currentFacet,pivotStr[0],pivotStr[1],pivotStr[2]); + } else { + throw new SolrException(ErrorCode.BAD_REQUEST,"Result request "+facetValue+" has an invalid amount of arguments."); + } + } catch (IndexOutOfBoundsException e) { + throw new SolrException(ErrorCode.BAD_REQUEST,"Result request "+facetValue+" is invalid. Lacks parentheses.",e); + } + } + if (queryFacetExpressions.get(queryFacet)!=null) { + Expression[] facetExpressions = queryFacetExpressions.get(queryFacet).get(facetValue); + for (int count = 0; count < expressionNames.length; count++) { + if (expressionName.equals(expressionNames[count])) { + Comparable value = facetExpressions[count].getValue(); + if (value.getClass().equals(Date.class)) { + return TrieDateField.formatExternal((Date)value); + } else { + return value.toString(); + } + } + } + } + throw new SolrException(ErrorCode.BAD_REQUEST,"Field Facet Pivot expression "+expressionName+" not found."); + } + + @Override + @SuppressWarnings("unchecked") + public NamedList export() { + final NamedList base = (NamedList)super.export(); + NamedList> facetList = new NamedList>(); + + // Add the field facet buckets to the output + base.add("fieldFacets",facetList); + for( FieldFacetRequest freq : request.getFieldFacets() ){ + final String name = freq.getName(); + if (hiddenFieldFacets.contains(name)) { + continue; + } + final Map buckets = fieldFacetExpressions.get(name); + final NamedList bucketBase = new NamedList(); + + Iterable> iter = buckets.entrySet(); + + final FieldFacetRequest fr = (FieldFacetRequest) freq; + + final FacetSortSpecification sort = fr.getSort(); + final int limit = fr.getLimit(); + final int offset = fr.getOffset(); + final boolean showMissing = fr.showsMissing(); + if (!showMissing) { + buckets.remove(MISSING_VALUE); + } + // Sorting the buckets if a sort specification is provided + if( sort != null && buckets.values().iterator().hasNext()){ + int sortPlace = Arrays.binarySearch(expressionNames, sort.getStatistic()); + final Expression first = buckets.values().iterator().next()[sortPlace]; + final Comparator comp = (Comparator) first.comparator(sort.getDirection()); + + final List> sorted = new ArrayList>(buckets.size()); + Iterables.addAll(sorted, iter); + Collections.sort(sorted, new EntryComparator(comp,sortPlace)); + iter = sorted; + } + // apply the limit + if( limit > AnalyticsContentHandler.DEFAULT_FACET_LIMIT ){ + if( offset > 0 ){ + iter = Iterables.skip(iter, offset); + } + iter = Iterables.limit(iter, limit); + } + + // Export each expression in the bucket. + for( Entry bucket : iter ){ + bucketBase.add(bucket.getKey(),export(bucket.getValue())); + } + + facetList.add(name, bucketBase); + } + + // Add the range facet buckets to the output + facetList = new NamedList>(); + base.add("rangeFacets",facetList); + for( RangeFacetRequest freq : request.getRangeFacets() ){ + final String name = freq.getName(); + final Map buckets = rangeFacetExpressions.get(name); + final NamedList bucketBase = new NamedList(); + + Iterable> iter = buckets.entrySet(); + + for( Entry bucket : iter ){ + bucketBase.add(bucket.getKey(),export(bucket.getValue())); + } + + facetList.add(name, bucketBase); + } + + // Add the query facet buckets to the output + facetList = new NamedList>(); + base.add("queryFacets",facetList); + for( QueryFacetRequest freq : request.getQueryFacets() ){ + final String name = freq.getName(); + final Map buckets = queryFacetExpressions.get(name); + final NamedList bucketBase = new NamedList(); + + Iterable> iter = buckets.entrySet(); + + for( Entry bucket : iter ){ + bucketBase.add(bucket.getKey(),export(bucket.getValue())); + } + + facetList.add(name, bucketBase); + } + + return base; + } + + /** + * Exports a list of expressions as a NamedList + * @param expressionArr an array of expressions + * @return named list of expressions + */ + public NamedList export(Expression[] expressionArr) { + NamedList base = new NamedList(); + for (int count = 0; count < expressionArr.length; count++) { + if (!hiddenExpressions.contains(expressionNames[count])) { + base.add(expressionNames[count], expressionArr[count].getValue()); + } + } + return base; + } + + /** + * Processes the query and range facets. + * Must be called if range and/or query facets are supported. + */ + @Override + public void postProcess() throws IOException { + super.compute(); + for( Map f : fieldFacetCollectors.values() ){ + for( StatsCollector[] arr : f.values() ){ + for( StatsCollector b : arr ){ + b.compute(); + } + } + } + basicsAndFieldFacetsComputed = true; + final Filter filter = docs.getTopFilter(); + if( rangeFacets != null ){ + processRangeFacets(filter); + } + if( queryFacets != null ){ + processQueryFacets(filter); + } + } + + /** + * Initiates the collecting of query facets + * @param filter the base filter to work against + * @throws IOException if searching failed + */ + public void processQueryFacets(final Filter filter) throws IOException { + for( QueryFacetRequest qfr : queryFacets ){ + for( String query : qfr.getQueries() ){ + if (query.contains(AnalyticsParams.RESULT) && !query.contains(AnalyticsParams.QUERY_RESULT)) { + try { + String[] pivotStr = ExpressionFactory.getArguments(query.substring(query.indexOf('(')+1,query.lastIndexOf(')')).trim()); + if (pivotStr.length==1) { + query = getResult(pivotStr[0]); + } else if (pivotStr.length==3) { + query = getResult(pivotStr[0],pivotStr[1],pivotStr[2]); + } else { + throw new SolrException(ErrorCode.BAD_REQUEST,"Result request "+query+" has an invalid amount of arguments."); + } + } catch (IndexOutOfBoundsException e) { + throw new SolrException(ErrorCode.BAD_REQUEST,"Result request "+query+" is invalid. Lacks parentheses.",e); + } + } else if (query.contains(AnalyticsParams.QUERY_RESULT)) { + try { + String[] pivotStr = ExpressionFactory.getArguments(query.substring(query.indexOf('(')+1,query.lastIndexOf(')')).trim()); + if (pivotStr.length==3) { + query = getQueryResult(qfr.getName(),pivotStr[0],pivotStr[1],pivotStr[2]); + } else { + throw new SolrException(ErrorCode.BAD_REQUEST,"Result request "+query+" has an invalid amount of arguments."); + } + } catch (IndexOutOfBoundsException e) { + throw new SolrException(ErrorCode.BAD_REQUEST,"Result request "+query+" is invalid. Lacks parentheses.",e); + } + } + QueryFacetAccumulator qAcc = new QueryFacetAccumulator(this,qfr.getName(),query); + final Query q; + try { + q = QParser.getParser(query, null, queryRequest).getQuery(); + } catch( SyntaxError e ){ + throw new SolrException(ErrorCode.BAD_REQUEST,"Invalid query '"+query+"'",e); + } + // The searcher sends docIds to the QueryFacetAccumulator which forwards + // them to collectQuery() in this class for collection. + searcher.search(q, filter, qAcc); + computeQueryFacet(qfr.getName()); + queryCount++; + } + } + } + + @Override + public long getNumQueries() { + return queryCount; + } + + /** + * Initiates the collecting of range facets + * @param filter the base filter to use + * @throws IOException if searching fails + */ + public void processRangeFacets(final Filter filter) throws IOException { + for( RangeFacetRequest rfr : rangeFacets ){ + String[] pivotStr; + String start = rfr.getStart(); + if (start.contains(AnalyticsParams.QUERY_RESULT)) { + throw new SolrException(ErrorCode.BAD_REQUEST,"Query result requests can not be used in Range Facets"); + } else if (start.contains(AnalyticsParams.RESULT)) { + try { + pivotStr = ExpressionFactory.getArguments(start.substring(start.indexOf('(')+1,start.indexOf(')')).trim()); + if (pivotStr.length==1) { + rfr.setStart(getResult(pivotStr[0])); + } else if (pivotStr.length==3) { + rfr.setStart(getResult(pivotStr[0],pivotStr[1],pivotStr[2])); + } else { + throw new SolrException(ErrorCode.BAD_REQUEST, "Result request "+start+" has an invalid amount of arguments."); + } + } catch (IndexOutOfBoundsException e) { + throw new SolrException(ErrorCode.BAD_REQUEST, "Result request "+start+" is invalid. Lacks parentheses.",e); + } + } + String end = rfr.getEnd(); + if (end.contains(AnalyticsParams.QUERY_RESULT)) { + throw new SolrException(ErrorCode.BAD_REQUEST, "Query result requests can not be used in Range Facets"); + } else if (end.contains(AnalyticsParams.RESULT)) { + try { + pivotStr = ExpressionFactory.getArguments(end.substring(end.indexOf('(')+1,end.indexOf(')')).trim()); + if (pivotStr.length==1) { + rfr.setEnd(getResult(pivotStr[0])); + } else if (pivotStr.length==3) { + rfr.setEnd(getResult(pivotStr[0],pivotStr[1],pivotStr[2])); + } else { + throw new SolrException(ErrorCode.BAD_REQUEST, "Result request "+end+" has an invalid amount of arguments."); + } + } catch (IndexOutOfBoundsException e) { + throw new SolrException(ErrorCode.BAD_REQUEST, "Result request "+end+" is invalid. Lacks parentheses.",e); + } + } + String[] gaps = rfr.getGaps(); + for (int count = 0; count> rec = RangeEndpointCalculator.create(rfr); + final SchemaField sf = rfr.getField(); + + // Create a rangeFacetAccumulator for each range and + // collect the documents for that range. + for( FacetRange range : rec.getRanges() ){ + final String upper; + final String lower; + String facetValue = ""; + if( range.lower == null ){ + facetValue = "(*"; + lower = null; + } else { + lower = range.lower; + facetValue = ((range.includeLower)?"[":"(") + range.lower; + } + facetValue+=" TO "; + if( range.upper == null ){ + upper = null; + facetValue += "*)"; + } else { + upper = range.upper; + facetValue += range.upper + ((range.includeUpper)?"]":")"); + } + + Query q = sf.getType().getRangeQuery(null, sf, lower, upper, range.includeLower,range.includeUpper); + RangeFacetAccumulator rAcc = new RangeFacetAccumulator(this,rfr.getName(),facetValue); + // The searcher sends docIds to the RangeFacetAccumulator which forwards + // them to collectRange() in this class for collection. + searcher.search(q, filter, rAcc); + computeRangeFacet(sf.getName()); + } + } + } +} diff --git a/solr/core/src/java/org/apache/solr/analytics/accumulator/ValueAccumulator.java b/solr/core/src/java/org/apache/solr/analytics/accumulator/ValueAccumulator.java new file mode 100644 index 00000000000..ecc74ef01d5 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/accumulator/ValueAccumulator.java @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.accumulator; + +import java.io.IOException; + +import org.apache.lucene.index.AtomicReaderContext; +import org.apache.lucene.search.Collector; +import org.apache.lucene.search.Scorer; +import org.apache.solr.common.util.NamedList; + +/** + * Abstract Collector that manages all StatsCollectors, Expressions and Facets. + */ +public abstract class ValueAccumulator extends Collector { + + /** + * @param context The context to read documents from. + * @throws IOException if setting next reader fails + */ + public abstract void setNextReader(AtomicReaderContext context) throws IOException; + + /** + * Finalizes the statistics within each StatsCollector. + * Must be called before export(). + */ + public abstract void compute(); + public abstract NamedList export(); + + public void postProcess() throws IOException { + // NOP + } + + @Override + public boolean acceptsDocsOutOfOrder() { + return true; + } + + @Override + public void setScorer(Scorer scorer) throws IOException { + // NOP + } + +} diff --git a/solr/core/src/java/org/apache/solr/analytics/accumulator/facet/FacetValueAccumulator.java b/solr/core/src/java/org/apache/solr/analytics/accumulator/facet/FacetValueAccumulator.java new file mode 100644 index 00000000000..856f45f5ba1 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/accumulator/facet/FacetValueAccumulator.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.accumulator.facet; + +import java.io.IOException; + +import org.apache.lucene.index.AtomicReaderContext; + +/** + * Interface that describes the methods needed for an Accumulator to be able to handle + * fieldFacets, rangeFacets and queryFacets. + */ +public interface FacetValueAccumulator { + + void collectField(int doc, String facetName, String facetValue) throws IOException; + void collectQuery(int doc, String facetName, String facetValue) throws IOException; + void collectRange(int doc, String facetName, String facetValue) throws IOException; + void setQueryStatsCollectorReaders(AtomicReaderContext context) throws IOException; + void setRangeStatsCollectorReaders(AtomicReaderContext context) throws IOException; + +} diff --git a/solr/core/src/java/org/apache/solr/analytics/accumulator/facet/FieldFacetAccumulator.java b/solr/core/src/java/org/apache/solr/analytics/accumulator/facet/FieldFacetAccumulator.java new file mode 100644 index 00000000000..a4649237d2e --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/accumulator/facet/FieldFacetAccumulator.java @@ -0,0 +1,143 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.accumulator.facet; + +import java.io.IOException; + +import org.apache.lucene.index.AtomicReaderContext; +import org.apache.lucene.index.NumericDocValues; +import org.apache.lucene.index.SortedDocValues; +import org.apache.lucene.index.SortedSetDocValues; +import org.apache.lucene.util.Bits; +import org.apache.lucene.util.BytesRef; +import org.apache.solr.analytics.accumulator.FacetingAccumulator; +import org.apache.solr.analytics.accumulator.ValueAccumulator; +import org.apache.solr.analytics.util.AnalyticsParsers; +import org.apache.solr.analytics.util.AnalyticsParsers.NumericParser; +import org.apache.solr.analytics.util.AnalyticsParsers.Parser; +import org.apache.solr.common.SolrException; +import org.apache.solr.common.SolrException.ErrorCode; +import org.apache.solr.common.util.NamedList; +import org.apache.solr.schema.SchemaField; +import org.apache.solr.schema.TrieDateField; +import org.apache.solr.search.SolrIndexSearcher; + +/** + * An Accumulator that manages the faceting for fieldFacets. + * Collects the field facet values. + */ +public class FieldFacetAccumulator extends ValueAccumulator { + protected final Parser parser; + protected final FacetValueAccumulator parent; + protected final String name; + protected final SolrIndexSearcher searcher; + protected final SchemaField schemaField; + protected final boolean multiValued; + protected final boolean numField; + protected final boolean dateField; + protected final BytesRef value; + protected SortedSetDocValues setValues; + protected SortedDocValues sortValues; + protected NumericDocValues numValues; + protected Bits numValuesBits; + + public FieldFacetAccumulator(SolrIndexSearcher searcher, FacetValueAccumulator parent, SchemaField schemaField) throws IOException { + if( !schemaField.hasDocValues() ){ + throw new SolrException(ErrorCode.BAD_REQUEST, "Field '"+schemaField.getName()+"' does not have docValues"); + } + this.searcher = searcher; + this.schemaField = schemaField; + this.name = schemaField.getName(); + if (!schemaField.hasDocValues()) { + throw new IOException(name+" does not have docValues and therefore cannot be faceted over."); + } + this.multiValued = schemaField.multiValued(); + this.numField = schemaField.getType().getNumericType()!=null; + this.dateField = schemaField.getType().getClass().equals(TrieDateField.class); + this.parent = parent; + this.value = new BytesRef(); + this.parser = AnalyticsParsers.getParser(schemaField.getType().getClass()); + } + + public static FieldFacetAccumulator create(SolrIndexSearcher searcher, FacetValueAccumulator parent, SchemaField facetField) throws IOException{ + return new FieldFacetAccumulator(searcher,parent,facetField); + } + + /** + * Move to the next set of documents to add to the field facet. + */ + @Override + public void setNextReader(AtomicReaderContext context) throws IOException { + if (multiValued) { + setValues = context.reader().getSortedSetDocValues(name); + } else { + if (numField) { + numValues = context.reader().getNumericDocValues(name); + numValuesBits = context.reader().getDocsWithField(name); + } else { + sortValues = context.reader().getSortedDocValues(name); + } + } + } + + /** + * Tell the FacetingAccumulator to collect the doc with the + * given fieldFacet and value(s). + */ + @Override + public void collect(int doc) throws IOException { + if (multiValued) { + boolean exists = false; + if (setValues!=null) { + setValues.setDocument(doc); + int term; + while ((term = (int)setValues.nextOrd()) != SortedSetDocValues.NO_MORE_ORDS) { + exists = true; + setValues.lookupOrd(term, value); + parent.collectField(doc, name, parser.parse(value) ); + } + } + if (!exists) { + parent.collectField(doc, name, FacetingAccumulator.MISSING_VALUE ); + } + } else { + if(numField){ + long v = numValues.get(doc); + if( v != 0 || numValuesBits.get(doc) ){ + parent.collectField(doc, name, ((NumericParser)parser).parseNum(numValues.get(doc))); + } else { + parent.collectField(doc, name, FacetingAccumulator.MISSING_VALUE ); + } + } else { + sortValues.get(doc,value); + if( BytesRef.EMPTY_BYTES == value.bytes ){ + parent.collectField(doc, name, FacetingAccumulator.MISSING_VALUE ); + } else { + parent.collectField(doc, name, parser.parse(value) ); + } + } + } + } + + @Override + public void compute() {} + + @Override + public NamedList export() { return null; } + +} diff --git a/solr/core/src/java/org/apache/solr/analytics/accumulator/facet/QueryFacetAccumulator.java b/solr/core/src/java/org/apache/solr/analytics/accumulator/facet/QueryFacetAccumulator.java new file mode 100644 index 00000000000..f0d6b4aa516 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/accumulator/facet/QueryFacetAccumulator.java @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.accumulator.facet; + +import java.io.IOException; + +import org.apache.lucene.index.AtomicReaderContext; +import org.apache.solr.analytics.accumulator.ValueAccumulator; +import org.apache.solr.analytics.statistics.StatsCollector; +import org.apache.solr.common.util.NamedList; + +/** + * An Accumulator that manages a certain query of a given query facet. + */ +public class QueryFacetAccumulator extends ValueAccumulator { + protected final FacetValueAccumulator parent; + protected final String facetName; + protected final String facetValue; + + public QueryFacetAccumulator(FacetValueAccumulator parent, String facetName, String facetValue) { + this.parent = parent; + this.facetName = facetName; + this.facetValue = facetValue; + } + + /** + * Tell the FacetingAccumulator to collect the doc with the + * given queryFacet and query. + */ + @Override + public void collect(int doc) throws IOException { + parent.collectQuery(doc, facetName, facetValue); + } + + /** + * Update the readers of the queryFacet {@link StatsCollector}s in FacetingAccumulator + */ + @Override + public void setNextReader(AtomicReaderContext context) throws IOException { + parent.setQueryStatsCollectorReaders(context); + } + + @Override + public void compute() { + // NOP + } + + @Override + public NamedList export() { + // NOP + return null; + } + +} diff --git a/solr/core/src/java/org/apache/solr/analytics/accumulator/facet/RangeFacetAccumulator.java b/solr/core/src/java/org/apache/solr/analytics/accumulator/facet/RangeFacetAccumulator.java new file mode 100644 index 00000000000..dd29c1c414b --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/accumulator/facet/RangeFacetAccumulator.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.accumulator.facet; + +import java.io.IOException; + +import org.apache.lucene.index.AtomicReaderContext; +import org.apache.solr.analytics.statistics.StatsCollector; + +/** + * An Accumulator that manages a certain range of a given range facet. + */ +public class RangeFacetAccumulator extends QueryFacetAccumulator { + public RangeFacetAccumulator(FacetValueAccumulator parent, String facetName, String facetValue) { + super(parent, facetName, facetValue); + } + + /** + * Tell the FacetingAccumulator to collect the doc with the + * given rangeFacet and range. + */ + @Override + public void collect(int doc) throws IOException { + parent.collectRange(doc, facetName, facetValue); + } + + /** + * Update the readers of the rangeFacet {@link StatsCollector}s in FacetingAccumulator + */ + @Override + public void setNextReader(AtomicReaderContext context) throws IOException { + parent.setRangeStatsCollectorReaders(context); + } + +} diff --git a/solr/core/src/java/org/apache/solr/analytics/accumulator/facet/package.html b/solr/core/src/java/org/apache/solr/analytics/accumulator/facet/package.html new file mode 100644 index 00000000000..8737a008740 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/accumulator/facet/package.html @@ -0,0 +1,27 @@ + + + + + + + +

    +Accumulators for accumulating over differnt types of facets +

    + + diff --git a/solr/core/src/java/org/apache/solr/analytics/accumulator/package.html b/solr/core/src/java/org/apache/solr/analytics/accumulator/package.html new file mode 100644 index 00000000000..b2cb8c2d121 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/accumulator/package.html @@ -0,0 +1,27 @@ + + + + + + + +

    +Accumulators accumulate values over different types of strucuture (eg result, facet, etc..) +

    + + diff --git a/solr/core/src/java/org/apache/solr/analytics/expression/BaseExpression.java b/solr/core/src/java/org/apache/solr/analytics/expression/BaseExpression.java new file mode 100644 index 00000000000..3e56c89c665 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/expression/BaseExpression.java @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.expression; + +import java.util.Date; + +import org.apache.solr.analytics.statistics.StatsCollector; + + +/** + * BaseExpression returns the value returned by the {@link StatsCollector} for the specified stat. + */ +public class BaseExpression extends Expression { + protected final StatsCollector statsCollector; + protected final String stat; + + public BaseExpression(StatsCollector statsCollector, String stat) { + this.statsCollector = statsCollector; + this.stat = stat; + } + + public Comparable getValue() { + return statsCollector.getStat(stat); + } +} +/** + * ConstantStringExpression returns the specified constant double. + */ +class ConstantNumberExpression extends Expression { + protected final Double constant; + + public ConstantNumberExpression(double d) { + constant = new Double(d); + } + + public Comparable getValue() { + return constant; + } +} +/** + * ConstantStringExpression returns the specified constant date. + */ +class ConstantDateExpression extends Expression { + protected final Date constant; + + public ConstantDateExpression(Date date) { + constant = date; + } + + public ConstantDateExpression(Long date) { + constant = new Date(date); + } + + public Comparable getValue() { + return constant; + } +} +/** + * ConstantStringExpression returns the specified constant string. + */ +class ConstantStringExpression extends Expression { + protected final String constant; + + public ConstantStringExpression(String str) { + constant = str; + } + + public Comparable getValue() { + return constant; + } +} diff --git a/solr/core/src/java/org/apache/solr/analytics/expression/DualDelegateExpression.java b/solr/core/src/java/org/apache/solr/analytics/expression/DualDelegateExpression.java new file mode 100644 index 00000000000..f8579bf2d61 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/expression/DualDelegateExpression.java @@ -0,0 +1,100 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.expression; + +/** + * Abstraction of an expression that applies a function to two delegate expressions. + */ +public abstract class DualDelegateExpression extends Expression { + protected Expression a; + protected Expression b; + public DualDelegateExpression(Expression a, Expression b) { + this.a = a; + this.b = b; + } +} +/** + * DivideExpression returns the quotient of 'a' and 'b'. + */ +class DivideExpression extends DualDelegateExpression { + + /** + * @param a numerator + * @param b divisor + */ + public DivideExpression(Expression a, Expression b) { + super(a,b); + } + + @Override + public Comparable getValue() { + Comparable aComp = a.getValue(); + Comparable bComp = b.getValue(); + if (aComp==null || bComp==null) { + return null; + } + double div = ((Number)aComp).doubleValue(); + div = div / ((Number)bComp).doubleValue(); + return new Double(div); + } +} +/** + * PowerExpression returns 'a' to the power of 'b'. + */ +class PowerExpression extends DualDelegateExpression { + + /** + * @param a base + * @param b exponent + */ + public PowerExpression(Expression a, Expression b) { + super(a,b); + } + + @Override + public Comparable getValue() { + Comparable aComp = a.getValue(); + Comparable bComp = b.getValue(); + if (aComp==null || bComp==null) { + return null; + } + return new Double(Math.pow(((Number)aComp).doubleValue(),((Number)bComp).doubleValue())); + } +} +/** + * LogExpression returns the log of the delegate's value given a base number. + */ +class LogExpression extends DualDelegateExpression { + /** + * @param a number + * @param b base + */ + public LogExpression(Expression a, Expression b) { + super(a,b); + } + + @Override + public Comparable getValue() { + Comparable aComp = a.getValue(); + Comparable bComp = b.getValue(); + if (aComp==null || bComp==null) { + return null; + } + return Math.log(((Number)aComp).doubleValue())/Math.log(((Number)bComp).doubleValue()); + } +} diff --git a/solr/core/src/java/org/apache/solr/analytics/expression/Expression.java b/solr/core/src/java/org/apache/solr/analytics/expression/Expression.java new file mode 100644 index 00000000000..add097682e7 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/expression/Expression.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.expression; + +import java.util.Comparator; + +import org.apache.solr.analytics.request.FieldFacetRequest.FacetSortDirection; + +/** + * Expressions map either zero, one, two or many inputs to a single value. + * They can be defined recursively to compute complex math. + */ +public abstract class Expression { + public abstract Comparable getValue(); + + public Comparator comparator(final FacetSortDirection direction) { + return new Comparator(){ + @SuppressWarnings("unchecked") + @Override + public int compare(Expression a, Expression b) { + if( direction == FacetSortDirection.ASCENDING ){ + return a.getValue().compareTo(b.getValue()); + } else { + return b.getValue().compareTo(a.getValue()); + } + } + }; + } +} diff --git a/solr/core/src/java/org/apache/solr/analytics/expression/ExpressionFactory.java b/solr/core/src/java/org/apache/solr/analytics/expression/ExpressionFactory.java new file mode 100644 index 00000000000..9dc78d4b031 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/expression/ExpressionFactory.java @@ -0,0 +1,185 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.expression; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.List; + +import org.apache.solr.analytics.statistics.StatsCollector; +import org.apache.solr.analytics.util.AnalyticsParams; +import org.apache.solr.common.SolrException; +import org.apache.solr.common.SolrException.ErrorCode; +import org.apache.solr.schema.TrieDateField; + +public class ExpressionFactory { + + /** + * Creates a single expression that contains delegate expressions and/or + * a StatsCollector. + * StatsCollectors are given as input and not created within the method so that + * expressions can share the same StatsCollectors, minimizing computation. + * + * @param expression String representation of the desired expression + * @param statsCollectors List of StatsCollectors to build the expression with. + * @return the expression + */ + @SuppressWarnings("deprecation") + public static Expression create(String expression, StatsCollector[] statsCollectors) { + int paren = expression.indexOf('('); + if (paren<=0) { + throw new SolrException(ErrorCode.BAD_REQUEST, "The expression ["+expression+"] has no arguments and is not supported."); + } + String topOperation = expression.substring(0,paren).trim(); + String operands; + try { + operands = expression.substring(paren+1, expression.lastIndexOf(')')).trim(); + } catch (Exception e) { + throw new SolrException(ErrorCode.BAD_REQUEST,"Missing closing parenthesis in ["+expression+"]",e); + } + + // Builds a statistic, constant or recursively builds an expression tree + + // Statistic + if (AnalyticsParams.ALL_STAT_SET.contains(topOperation)) { + if (topOperation.equals(AnalyticsParams.STAT_PERCENTILE)) { + operands = expression.substring(expression.indexOf(',')+1, expression.lastIndexOf(')')).trim(); + topOperation = topOperation+"_"+expression.substring(expression.indexOf('(')+1, expression.indexOf(',')).trim(); + } + StatsCollector collector = null; + // Finds the desired counter and builds an expression around it and the desired statistic. + for (StatsCollector c : statsCollectors) { + if (c.valueSourceString().equals(operands)) { + collector = c; + break; + } + } + if (collector == null) { + throw new SolrException(ErrorCode.BAD_REQUEST, "ValueSource ["+operands+"] in Expression ["+expression+"] not found."); + } + return new BaseExpression(collector, topOperation); + } + // Constant + if (topOperation.equals(AnalyticsParams.CONSTANT_NUMBER)) { + try { + return new ConstantNumberExpression(Double.parseDouble(operands)); + } catch (NumberFormatException e) { + throw new SolrException(ErrorCode.BAD_REQUEST, "The constant "+operands+" cannot be converted into a number.",e); + } + } else if (topOperation.equals(AnalyticsParams.CONSTANT_DATE)) { + try { + return new ConstantDateExpression(TrieDateField.parseDate(operands)); + } catch (ParseException e) { + throw new SolrException(ErrorCode.BAD_REQUEST, "The constant "+operands+" cannot be converted into a date.",e); + } + } else if (topOperation.equals(AnalyticsParams.CONSTANT_STRING)) { + operands = expression.substring(paren+1, expression.lastIndexOf(')')); + return new ConstantStringExpression(operands); + } + + // Complex Delegating Expressions + String[] arguments = getArguments(operands); + Expression[] expArgs = new Expression[arguments.length]; + for (int count = 0; count < arguments.length; count++) { + // Recursively builds delegate expressions + expArgs[count] = create(arguments[count], statsCollectors); + } + + // Single Delegate Expressions + if (expArgs.length==1) { + // Numeric Expression + if (topOperation.equals(AnalyticsParams.NEGATE)) { + return new NegateExpression(expArgs[0]); + } + if (topOperation.equals(AnalyticsParams.ABSOLUTE_VALUE)) { + return new AbsoluteValueExpression(expArgs[0]); + } + // String Expression + else if (topOperation.equals(AnalyticsParams.REVERSE)) { + return new ReverseExpression(expArgs[0]); + } + throw new SolrException(ErrorCode.BAD_REQUEST, topOperation+" does not have the correct number of arguments."); + } else { + // Multi Delegate Expressions + // Numeric Expression + if (topOperation.equals(AnalyticsParams.ADD)) { + return new AddExpression(expArgs); + } else if (topOperation.equals(AnalyticsParams.MULTIPLY)) { + return new MultiplyExpression(expArgs); + } + // Date Expression + else if (topOperation.equals(AnalyticsParams.DATE_MATH)) { + return new DateMathExpression(expArgs); + } + // String Expression + else if (topOperation.equals(AnalyticsParams.CONCATENATE)) { + return new ConcatenateExpression(expArgs); + } + // Dual Delegate Expressions + else if (expArgs.length==2 && (topOperation.equals(AnalyticsParams.DIVIDE) || topOperation.equals(AnalyticsParams.POWER) + || topOperation.equals(AnalyticsParams.LOG))) { + // Numeric Expression + if (topOperation.equals(AnalyticsParams.DIVIDE)) { + return new DivideExpression(expArgs[0], expArgs[1]); + } else if (topOperation.equals(AnalyticsParams.POWER)) { + return new PowerExpression(expArgs[0], expArgs[1]); + } else if (topOperation.equals(AnalyticsParams.LOG)) { + return new LogExpression(expArgs[0], expArgs[1]); + } + return null; + } + throw new SolrException(ErrorCode.BAD_REQUEST, topOperation+" does not have the correct number of arguments or is unsupported."); + } + + } + + /** + * Splits up an Expression's arguments. + * + * @param expression Current expression string + * @return List The list of arguments + */ + public static String[] getArguments(String expression) { + String[] strings = new String[1]; + int stack = 0; + int start = 0; + List arguments = new ArrayList(); + char[] chars = expression.toCharArray(); + boolean escapedCharacter = false; + for (int count = 0; count < expression.length(); count++) { + char c = chars[count]; + if (c==',' && stack == 0 && !escapedCharacter) { + arguments.add(expression.substring(start, count).replace("\\(","(").replace("\\)",")").replace("\\,",",").trim()); + start = count+1; + } else if (c == '(' && !escapedCharacter) { + stack ++; + } else if (c == ')' && !escapedCharacter) { + stack --; + } else if (c == '\\') { + escapedCharacter=true; + } + if (escapedCharacter) { + escapedCharacter=false; + } + } + if (stack==0) { + arguments.add(expression.substring(start).trim()); + } + return arguments.toArray(strings); + } +} diff --git a/solr/core/src/java/org/apache/solr/analytics/expression/MultiDelegateExpression.java b/solr/core/src/java/org/apache/solr/analytics/expression/MultiDelegateExpression.java new file mode 100644 index 00000000000..4ea4825f7d7 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/expression/MultiDelegateExpression.java @@ -0,0 +1,132 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.expression; + +import java.text.ParseException; +import java.util.Date; + +import org.apache.solr.util.DateMathParser; + +/** + * Abstraction of an expression that applies a function to an array of delegate expressions. + */ +public abstract class MultiDelegateExpression extends Expression { + protected final Expression[] delegates; + + public MultiDelegateExpression(Expression[] delegates) { + this.delegates = delegates; + } +} +/** + * AddExpression returns the sum of it's components' values. + */ +class AddExpression extends MultiDelegateExpression { + public AddExpression(Expression[] delegates) { + super(delegates); + } + + @Override + public Comparable getValue() { + double sum = 0; + for (Expression delegate : delegates) { + Comparable dComp = delegate.getValue(); + if (dComp==null) { + return null; + } else if (dComp.getClass().equals(Date.class)) { + dComp = new Long(((Date)dComp).getTime()); + } + sum += ((Number)dComp).doubleValue(); + } + return new Double(sum); + } +} +/** + * MultiplyExpression returns the product of it's delegates' values. + */ +class MultiplyExpression extends MultiDelegateExpression { + public MultiplyExpression(Expression[] delegates) { + super(delegates); + } + + @Override + public Comparable getValue() { + double prod = 1; + for (Expression delegate : delegates) { + Comparable dComp = delegate.getValue(); + if (dComp==null) { + return null; + } + prod *= ((Number)dComp).doubleValue(); + } + return new Double(prod); + } +} +/** + * DateMathExpression returns the start date modified by the DateMath operations + */ +class DateMathExpression extends MultiDelegateExpression { + /** + * @param delegates A list of Expressions. The first element in the list + * should be a numeric Expression which represents the starting date. + * The rest of the field should be string Expression objects which contain + * the DateMath operations to perform on the start date. + */ + public DateMathExpression(Expression[] delegates) { + super(delegates); + } + + @Override + public Comparable getValue() { + DateMathParser parser = new DateMathParser(); + parser.setNow((Date)delegates[0].getValue()); + try { + for (int count = 1; countConcatenateExpression returns the concatenation of it's delegates' values in the order given. + */ +class ConcatenateExpression extends MultiDelegateExpression { + public ConcatenateExpression(Expression[] delegates) { + super(delegates); + } + + @Override + public Comparable getValue() { + StringBuilder builder = new StringBuilder(); + for (Expression delegate : delegates) { + Comparable dComp = delegate.getValue(); + if (dComp==null) { + return null; + } + builder.append(dComp.toString()); + } + return builder.toString(); + } +} diff --git a/solr/core/src/java/org/apache/solr/analytics/expression/SingleDelegateExpression.java b/solr/core/src/java/org/apache/solr/analytics/expression/SingleDelegateExpression.java new file mode 100644 index 00000000000..c6ab60ed3d2 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/expression/SingleDelegateExpression.java @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.expression; + +import java.util.Date; + +/** + * Abstraction of an expression that applies a function to one delegate expression. + */ +public abstract class SingleDelegateExpression extends Expression { + protected Expression delegate; + + public SingleDelegateExpression(Expression delegate) { + this.delegate = delegate; + } +} +/** + * NegateExpression returns the negation of the delegate's value. + */ +class NegateExpression extends SingleDelegateExpression { + public NegateExpression(Expression delegate) { + super(delegate); + } + + @Override + public Comparable getValue() { + Comparable nComp = delegate.getValue(); + if (nComp==null) { + return null; + } else if (nComp.getClass().equals(Date.class)) { + nComp = new Long(((Date)nComp).getTime()); + } + return new Double(((Number)nComp).doubleValue()*-1); + } +} +/** + * AbsoluteValueExpression returns the negation of the delegate's value. + */ +class AbsoluteValueExpression extends SingleDelegateExpression { + public AbsoluteValueExpression(Expression delegate) { + super(delegate); + } + + @Override + public Comparable getValue() { + Comparable nComp = delegate.getValue(); + if (nComp==null) { + return null; + } + double d = ((Number)nComp).doubleValue(); + if (d<0) { + return new Double(d*-1); + } else { + return new Double(d); + } + } +} +/** + * StringExpression returns the reverse of the delegate's string value. + */ +class ReverseExpression extends SingleDelegateExpression { + public ReverseExpression(Expression delegate) { + super(delegate); + } + + @Override + public Comparable getValue() { + Comparable rComp = delegate.getValue(); + if (rComp==null) { + return null; + } + return new StringBuilder(rComp.toString()).reverse().toString(); + } +} diff --git a/solr/core/src/java/org/apache/solr/analytics/expression/package.html b/solr/core/src/java/org/apache/solr/analytics/expression/package.html new file mode 100644 index 00000000000..434f7103fa9 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/expression/package.html @@ -0,0 +1,27 @@ + + + + + + + +

    +Expressions map either zero, one, two or many inputs to a single value. They can be defined recursively to compute complex math. +

    + + diff --git a/solr/core/src/java/org/apache/solr/analytics/plugin/AnalyticsStatisticsCollector.java b/solr/core/src/java/org/apache/solr/analytics/plugin/AnalyticsStatisticsCollector.java new file mode 100644 index 00000000000..74db91dfa94 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/plugin/AnalyticsStatisticsCollector.java @@ -0,0 +1,114 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.plugin; + +import java.util.concurrent.atomic.AtomicLong; + +import org.apache.solr.common.util.NamedList; +import org.apache.solr.common.util.SimpleOrderedMap; +import org.apache.solr.util.stats.Snapshot; +import org.apache.solr.util.stats.Timer; +import org.apache.solr.util.stats.TimerContext; + +public class AnalyticsStatisticsCollector { + private final AtomicLong numRequests; + private final AtomicLong numAnalyticsRequests; + private final AtomicLong numStatsRequests; + private final AtomicLong numCollectedStats; + private final AtomicLong numFieldFacets; + private final AtomicLong numRangeFacets; + private final AtomicLong numQueryFacets; + private final AtomicLong numQueries; + private final Timer requestTimes; + + public TimerContext currentTimer; + + public AnalyticsStatisticsCollector() { + numRequests = new AtomicLong(); + numAnalyticsRequests = new AtomicLong(); + numStatsRequests = new AtomicLong(); + numCollectedStats = new AtomicLong(); + numFieldFacets = new AtomicLong(); + numRangeFacets = new AtomicLong(); + numQueryFacets = new AtomicLong(); + numQueries = new AtomicLong(); + requestTimes = new Timer(); + } + + public void startRequest() { + numRequests.incrementAndGet(); + currentTimer = requestTimes.time(); + } + + public void addRequests(long num) { + numAnalyticsRequests.addAndGet(num); + } + + public void addStatsRequests(long num) { + numStatsRequests.addAndGet(num); + } + + public void addStatsCollected(long num) { + numCollectedStats.addAndGet(num); + } + + public void addFieldFacets(long num) { + numFieldFacets.addAndGet(num); + } + + public void addRangeFacets(long num) { + numRangeFacets.addAndGet(num); + } + + public void addQueryFacets(long num) { + numQueryFacets.addAndGet(num); + } + + public void addQueries(long num) { + numQueries.addAndGet(num); + } + + public void endRequest() { + currentTimer.stop(); + } + + public NamedList getStatistics() { + NamedList lst = new SimpleOrderedMap(); + Snapshot snapshot = requestTimes.getSnapshot(); + lst.add("requests", numRequests.longValue()); + lst.add("analyticsRequests", numAnalyticsRequests.longValue()); + lst.add("statsRequests", numStatsRequests.longValue()); + lst.add("statsCollected", numCollectedStats.longValue()); + lst.add("fieldFacets", numFieldFacets.longValue()); + lst.add("rangeFacets", numRangeFacets.longValue()); + lst.add("queryFacets", numQueryFacets.longValue()); + lst.add("queriesInQueryFacets", numQueries.longValue()); + lst.add("totalTime", requestTimes.getSum()); + lst.add("avgRequestsPerSecond", requestTimes.getMeanRate()); + lst.add("5minRateReqsPerSecond", requestTimes.getFiveMinuteRate()); + lst.add("15minRateReqsPerSecond", requestTimes.getFifteenMinuteRate()); + lst.add("avgTimePerRequest", requestTimes.getMean()); + lst.add("medianRequestTime", snapshot.getMedian()); + lst.add("75thPcRequestTime", snapshot.get75thPercentile()); + lst.add("95thPcRequestTime", snapshot.get95thPercentile()); + lst.add("99thPcRequestTime", snapshot.get99thPercentile()); + lst.add("999thPcRequestTime", snapshot.get999thPercentile()); + return lst; + } + +} diff --git a/solr/core/src/java/org/apache/solr/analytics/plugin/package.html b/solr/core/src/java/org/apache/solr/analytics/plugin/package.html new file mode 100644 index 00000000000..7555251cb85 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/plugin/package.html @@ -0,0 +1,27 @@ + + + + + + + +

    +MBean plugins for stats collection +

    + + diff --git a/solr/core/src/java/org/apache/solr/analytics/request/AbstractFieldFacetRequest.java b/solr/core/src/java/org/apache/solr/analytics/request/AbstractFieldFacetRequest.java new file mode 100644 index 00000000000..6f85cf0dba3 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/request/AbstractFieldFacetRequest.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.request; + +import org.apache.solr.schema.SchemaField; + +/** + * An abstract request for a facet over a single field, such as a field or range facet. + */ +public abstract class AbstractFieldFacetRequest implements FacetRequest { + protected SchemaField field = null; + + public AbstractFieldFacetRequest(SchemaField field) { + this.field = field; + } + + public SchemaField getField() { + return field; + } + + public void setField(SchemaField field) { + this.field = field; + } + + public String getName() { + return field.getName(); + } +} diff --git a/solr/core/src/java/org/apache/solr/analytics/request/AnalyticsContentHandler.java b/solr/core/src/java/org/apache/solr/analytics/request/AnalyticsContentHandler.java new file mode 100644 index 00000000000..1f038bae37b --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/request/AnalyticsContentHandler.java @@ -0,0 +1,315 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.request; + +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; + +import org.apache.solr.analytics.request.FieldFacetRequest.FacetSortDirection; +import org.apache.solr.analytics.request.FieldFacetRequest.FacetSortSpecification; +import org.apache.solr.common.params.FacetParams.FacetRangeInclude; +import org.apache.solr.common.params.FacetParams.FacetRangeOther; +import org.apache.solr.schema.IndexSchema; +import org.xml.sax.Attributes; +import org.xml.sax.ContentHandler; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; + +/** + * Handles the parsing of the AnalysisRequestEnvelope elements if passed in through XML. + */ +public class AnalyticsContentHandler implements ContentHandler { + // XML Element/Attribute Name Constants + public final String ANALYTICS_REQUEST_ENVELOPE="analyticsRequestEnvelope"; + + public final String ANALYTICS_REQUEST="analyticsRequest"; + public final String NAME="name"; + + public final String STATISTIC="statistic"; + public final String EXPRESSION="expression"; + + public final String FIELD_FACET="fieldFacet"; + public final String FIELD="field"; + public final String SHOW_MISSING="showMissing"; + public final String LIMIT="limit"; + public final String MIN_COUNT="minCount"; + + public final String SORT_SPECIFICATION="sortSpecification"; + public final String STAT_NAME="statName"; + public final String DIRECTION="direction"; + + public final String RANGE_FACET="rangeFacet"; + public final String START="start"; + public final String END="end"; + public final String GAP="gap"; + public final String INCLUDE_BOUNDARY="includeBoundary"; + public final String OTHER_RANGE="otherRange"; + public final String HARD_END="hardend"; + + public final String QUERY_FACET="queryFacet"; + public final String QUERY="query"; + + // Default Values + public static final int DEFAULT_FACET_LIMIT = -1; + public static final boolean DEFAULT_FACET_HARDEND = false; + public static final int DEFAULT_FACET_MINCOUNT = 0; + public static final boolean DEFAULT_FACET_FIELD_SHOW_MISSING = false; + + boolean inEnvelope = false; + boolean inRequest = false; + boolean inStatistic = false; + boolean inFieldFacet = false; + boolean inSortSpecification = false; + boolean inQueryFacet = false; + boolean inRangeFacet = false; + + private final IndexSchema schema; + + // Objects to use while building the Analytics Requests + + String currentElementText; + + List requests; + + AnalyticsRequest analyticsRequest; + List expressionList; + List fieldFacetList; + List rangeFacetList; + List queryFacetList; + + ExpressionRequest expression; + + FieldFacetRequest fieldFacet; + int limit; + int minCount; + boolean showMissing; + FacetSortSpecification sortSpecification; + + RangeFacetRequest rangeFacet; + boolean hardend; + List gaps; + EnumSet includeBoundaries; + EnumSet otherRanges; + + String queryName; + List queries; + + public AnalyticsContentHandler(IndexSchema schema) { + this.schema = schema; + } + + @Override + public void setDocumentLocator(Locator locator) { } + + @Override + public void startDocument() throws SAXException { } + + @Override + public void endDocument() throws SAXException { } + + @Override + public void startPrefixMapping(String prefix, String uri) throws SAXException { } + + @Override + public void endPrefixMapping(String prefix) throws SAXException { } + + @Override + public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException { + currentElementText = ""; + if (inEnvelope) { + if (inRequest) { + if (localName.equals(STATISTIC)) { + // Start a Statistic Request + inStatistic = true; + } else if (inFieldFacet) { + if (localName.equals(SORT_SPECIFICATION)) { + // Start a Sort Specification + inSortSpecification = true; + sortSpecification = new FacetSortSpecification(); + } + } else if (localName.equals(FIELD_FACET)) { + // Start a Field Facet Request + // Get attributes (limit, minCount, showMissing) + String att = atts.getValue(uri,LIMIT); + if (att!=null) { + limit = Integer.parseInt(att); + } else { + limit = DEFAULT_FACET_LIMIT; + } + att = atts.getValue(uri,MIN_COUNT); + if (att!=null) { + minCount = Integer.parseInt(att); + } else { + minCount = DEFAULT_FACET_MINCOUNT; + } + att = atts.getValue(uri,SHOW_MISSING); + if (att!=null) { + showMissing = Boolean.parseBoolean(att); + } else { + showMissing = DEFAULT_FACET_FIELD_SHOW_MISSING; + } + + inFieldFacet = true; + } else if (localName.equals(RANGE_FACET)) { + // Start a Range Facet Request + // Get attributes (hardEnd) + String att = atts.getValue(uri,HARD_END); + if (att!=null) { + hardend = Boolean.parseBoolean(att); + } else { + hardend = false; + } + + // Initiate Range Facet classes + gaps = new ArrayList(); + includeBoundaries = EnumSet.noneOf(FacetRangeInclude.class); + otherRanges = EnumSet.noneOf(FacetRangeOther.class); + inRangeFacet = true; + } else if (localName.equals(QUERY_FACET)) { + // Start a Query Facet Request + queries = new ArrayList(); + inQueryFacet = true; + } + } else if (localName.equals(ANALYTICS_REQUEST)){ + // Start an Analytics Request + + // Renew each list. + fieldFacetList = new ArrayList(); + rangeFacetList = new ArrayList(); + queryFacetList = new ArrayList(); + expressionList = new ArrayList(); + inRequest = true; + } + } else if (localName.equals(ANALYTICS_REQUEST_ENVELOPE)){ + //Begin the parsing of the Analytics Requests + requests = new ArrayList(); + inEnvelope = true; + } + } + + @Override + public void endElement(String uri, String localName, String qName) throws SAXException { + if (inEnvelope) { + if (inRequest) { + if (inStatistic) { + if (localName.equals(EXPRESSION)) { + expression = new ExpressionRequest(currentElementText,currentElementText); + } else if (localName.equals(NAME)) { + expression.setName(currentElementText); + } else if (localName.equals(STATISTIC)) { + // Finished Parsing the Statistic Request + expressionList.add(expression); + inStatistic = false; + } + } else if (inFieldFacet) { + if (inSortSpecification) { + if (localName.equals(STAT_NAME)) { + sortSpecification.setStatistic(currentElementText); + } else if (localName.equals(DIRECTION)) { + sortSpecification.setDirection(FacetSortDirection.fromExternal(currentElementText)); + } else if (localName.equals(SORT_SPECIFICATION)) { + // Finished Parsing the Sort Specification + fieldFacet.setSort(sortSpecification); + inSortSpecification = false; + } + } else if (localName.equals(FIELD)) { + fieldFacet = new FieldFacetRequest(schema.getField(currentElementText)); + } else if (localName.equals(FIELD_FACET)) { + // Finished Parsing the Field Facet Request + fieldFacet.setLimit(limit); + fieldFacet.showMissing(showMissing); + fieldFacetList.add(fieldFacet); + inFieldFacet = false; + } + } else if (inRangeFacet) { + if (localName.equals(FIELD)) { + rangeFacet = new RangeFacetRequest(schema.getField(currentElementText), "", "", new String[1]); + } else if (localName.equals(START)) { + rangeFacet.setStart(currentElementText); + } else if (localName.equals(END)) { + rangeFacet.setEnd(currentElementText); + } else if (localName.equals(GAP)) { + gaps.add(currentElementText); + } else if (localName.equals(INCLUDE_BOUNDARY)) { + includeBoundaries.add(FacetRangeInclude.get(currentElementText)); + } else if (localName.equals(OTHER_RANGE)) { + otherRanges.add(FacetRangeOther.get(currentElementText)); + } else if (localName.equals(RANGE_FACET)) { + // Finished Parsing the Range Facet Request + rangeFacet.setHardEnd(hardend); + rangeFacet.setGaps(gaps.toArray(new String[1])); + rangeFacet.setInclude(includeBoundaries); + rangeFacet.setOthers(otherRanges); + inRangeFacet = false; + rangeFacetList.add(rangeFacet); + } + } else if (inQueryFacet) { + if (localName.equals(NAME)) { + queryName = currentElementText; + } else if (localName.equals(QUERY)) { + queries.add(currentElementText); + } else if (localName.equals(QUERY_FACET)) { + // Finished Parsing the Query Facet Request + QueryFacetRequest temp = new QueryFacetRequest(queryName); + temp.setQueries(queries); + queryFacetList.add(temp); + inQueryFacet = false; + } + } else if (localName.equals(NAME)) { + analyticsRequest = new AnalyticsRequest(currentElementText); + } else if (localName.equals(ANALYTICS_REQUEST)){ + // Finished Parsing the Analytics Request + analyticsRequest.setExpressions(expressionList); + analyticsRequest.setFieldFacets(fieldFacetList); + analyticsRequest.setRangeFacets(rangeFacetList); + analyticsRequest.setQueryFacets(queryFacetList); + requests.add(analyticsRequest); + inRequest = false; + } + } else if (localName.equals(ANALYTICS_REQUEST_ENVELOPE)){ + // Finished Parsing + inEnvelope = false; + } + } + } + + @Override + public void characters(char[] ch, int start, int length) throws SAXException { + currentElementText += new String(ch,start,length); + } + + @Override + public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException { } + + @Override + public void processingInstruction(String target, String data) throws SAXException { } + + @Override + public void skippedEntity(String name) throws SAXException { } + + /** + * Returns the list of Analytics Requests built during parsing. + * + * @return List of {@link AnalyticsRequest} objects specified by the given XML file + */ + public List getAnalyticsRequests() { + return requests; + } + +} diff --git a/solr/core/src/java/org/apache/solr/analytics/request/AnalyticsRequest.java b/solr/core/src/java/org/apache/solr/analytics/request/AnalyticsRequest.java new file mode 100644 index 00000000000..8e8282c58e6 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/request/AnalyticsRequest.java @@ -0,0 +1,115 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.request; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Contains the specifications of an Analytics Request, specifically a name, + * a list of Expressions, a list of field facets, a list of range facets, a list of query facets + * and the list of expressions and their results calculated in previous AnalyticsRequests. + */ +public class AnalyticsRequest { + + private String name; + private List expressions; + private Set hiddenExpressions; + private List fieldFacets; + private List rangeFacets; + private List queryFacets; + + public AnalyticsRequest(String name) { + this.name = name; + expressions = new ArrayList(); + hiddenExpressions = new HashSet(); + fieldFacets = new ArrayList(); + rangeFacets = new ArrayList(); + queryFacets = new ArrayList(); + } + + public String getName() { + return name; + } + + public void setExpressions(List expressions) { + this.expressions = expressions; + } + + public void addExpression(ExpressionRequest expressionRequest) { + expressions.add(expressionRequest); + } + + public List getExpressions() { + return expressions; + } + + public void addHiddenExpression(ExpressionRequest expressionRequest) { + expressions.add(expressionRequest); + hiddenExpressions.add(expressionRequest.getName()); + } + + public Set getHiddenExpressions() { + return hiddenExpressions; + } + + public void setFieldFacets(List fieldFacets) { + this.fieldFacets = fieldFacets; + } + + public List getFieldFacets() { + return fieldFacets; + } + + public void setRangeFacets(List rangeFacets) { + this.rangeFacets = rangeFacets; + } + + public List getRangeFacets() { + return rangeFacets; + } + + public void setQueryFacets(List queryFacets) { + this.queryFacets = queryFacets; + } + + public List getQueryFacets() { + return queryFacets; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(""); + for (ExpressionRequest exp : expressions) { + builder.append(exp.toString()); + } + for (FieldFacetRequest facet : fieldFacets) { + builder.append(facet.toString()); + } + for (RangeFacetRequest facet : rangeFacets) { + builder.append(facet.toString()); + } + for (QueryFacetRequest facet : queryFacets) { + builder.append(facet.toString()); + } + builder.append(""); + return builder.toString(); + } +} diff --git a/solr/core/src/java/org/apache/solr/analytics/request/AnalyticsRequestFactory.java b/solr/core/src/java/org/apache/solr/analytics/request/AnalyticsRequestFactory.java new file mode 100644 index 00000000000..1c8142a97c0 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/request/AnalyticsRequestFactory.java @@ -0,0 +1,309 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.request; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.solr.analytics.request.FieldFacetRequest.FacetSortSpecification; +import org.apache.solr.analytics.util.AnalyticsParams; +import org.apache.solr.common.SolrException; +import org.apache.solr.common.SolrException.ErrorCode; +import org.apache.solr.common.params.FacetParams.FacetRangeInclude; +import org.apache.solr.common.params.FacetParams.FacetRangeOther; +import org.apache.solr.common.params.SolrParams; +import org.apache.solr.schema.IndexSchema; + +/** + * Parses the SolrParams to create a list of analytics requests. + */ +public class AnalyticsRequestFactory implements AnalyticsParams { + + public static final Pattern statPattern = Pattern.compile("^o(?:lap)?\\.([^\\.]+)\\.(?:"+EXPRESSION+")\\.([^\\.]+)$", Pattern.CASE_INSENSITIVE); + public static final Pattern hiddenStatPattern = Pattern.compile("^o(?:lap)?\\.([^\\.]+)\\.(?:"+HIDDEN_EXPRESSION+")\\.([^\\.]+)$", Pattern.CASE_INSENSITIVE); + public static final Pattern fieldFacetPattern = Pattern.compile("^o(?:lap)?\\.([^\\.]+)\\.(?:"+FIELD_FACET+")$", Pattern.CASE_INSENSITIVE); + public static final Pattern fieldFacetParamPattern = Pattern.compile("^o(?:lap)?\\.([^\\.]+)\\.(?:"+FIELD_FACET+")\\.([^\\.]+)\\.("+LIMIT+"|"+OFFSET+"|"+HIDDEN+"|"+SHOW_MISSING+"|"+SORT_STATISTIC+"|"+SORT_DIRECTION+")$", Pattern.CASE_INSENSITIVE); + public static final Pattern rangeFacetPattern = Pattern.compile("^o(?:lap)?\\.([^\\.]+)\\.(?:"+RANGE_FACET+")$", Pattern.CASE_INSENSITIVE); + public static final Pattern rangeFacetParamPattern = Pattern.compile("^o(?:lap)?\\.([^\\.]+)\\.(?:"+RANGE_FACET+")\\.([^\\.]+)\\.("+START+"|"+END+"|"+GAP+"|"+HARDEND+"|"+INCLUDE_BOUNDARY+"|"+OTHER_RANGE+")$", Pattern.CASE_INSENSITIVE); + public static final Pattern queryFacetPattern = Pattern.compile("^o(?:lap)?\\.([^\\.]+)\\.(?:"+QUERY_FACET+")$", Pattern.CASE_INSENSITIVE); + public static final Pattern queryFacetParamPattern = Pattern.compile("^o(?:lap)?\\.([^\\.]+)\\.(?:"+QUERY_FACET+")\\.([^\\.]+)\\.("+QUERY+"|"+DEPENDENCY+")$", Pattern.CASE_INSENSITIVE); + + public static List parse(IndexSchema schema, SolrParams params) { + Map requestMap = new HashMap(); + Map> fieldFacetMap = new HashMap>(); + Map> fieldFacetSet = new HashMap>(); + Map> rangeFacetMap = new HashMap>(); + Map> rangeFacetSet = new HashMap>(); + Map> queryFacetMap = new HashMap>(); + Map> queryFacetSet = new HashMap>(); + List requestList = new ArrayList(); + + Iterator paramsIterator = params.getParameterNamesIterator(); + while (paramsIterator.hasNext()) { + String param = paramsIterator.next(); + CharSequence paramSequence = param.subSequence(0, param.length()); + + // Check if stat + Matcher m = statPattern.matcher(paramSequence); + if (m.matches()) { + makeExpression(requestMap,m.group(1),m.group(2),params.get(param)); + } else { + // Check if hidden stat + m = hiddenStatPattern.matcher(paramSequence); + if (m.matches()) { + makeHiddenExpression(requestMap,m.group(1),m.group(2),params.get(param)); + } else { + // Check if field facet + m = fieldFacetPattern.matcher(paramSequence); + if (m.matches()) { + makeFieldFacet(schema,fieldFacetMap,fieldFacetSet,m.group(1),params.getParams(param)); + } else { + // Check if field facet parameter + m = fieldFacetParamPattern.matcher(paramSequence); + if (m.matches()) { + setFieldFacetParam(schema,fieldFacetMap,m.group(1),m.group(2),m.group(3),params.getParams(param)); + } else { + // Check if range facet + m = rangeFacetPattern.matcher(paramSequence); + if (m.matches()) { + makeRangeFacet(schema,rangeFacetSet,m.group(1),params.getParams(param)); + } else { + // Check if range facet parameter + m = rangeFacetParamPattern.matcher(paramSequence); + if (m.matches()) { + setRangeFacetParam(schema,rangeFacetMap,m.group(1),m.group(2),m.group(3),params.getParams(param)); + } else { + // Check if query facet + m = queryFacetPattern.matcher(paramSequence); + if (m.matches()) { + makeQueryFacet(schema,queryFacetSet,m.group(1),params.getParams(param)); + } else { + // Check if query + m = queryFacetParamPattern.matcher(paramSequence); + if (m.matches()) { + setQueryFacetParam(schema,queryFacetMap,m.group(1),m.group(2),m.group(3),params.getParams(param)); + } + } + } + } + } + } + } + } + } + for (String reqName : requestMap.keySet()) { + AnalyticsRequest ar = requestMap.get(reqName); + List ffrs = new ArrayList(); + if (fieldFacetSet.get(reqName)!=null) { + for (String field : fieldFacetSet.get(reqName)) { + ffrs.add(fieldFacetMap.get(reqName).get(field)); + } + } + ar.setFieldFacets(ffrs); + + List rfrs = new ArrayList(); + if (rangeFacetSet.get(reqName)!=null) { + for (String field : rangeFacetSet.get(reqName)) { + RangeFacetRequest rfr = rangeFacetMap.get(reqName).get(field); + if (rfr != null) { + rfrs.add(rfr); + } + } + } + ar.setRangeFacets(rfrs); + + List qfrs = new ArrayList(); + if (queryFacetSet.get(reqName)!=null) { + for (String name : queryFacetSet.get(reqName)) { + QueryFacetRequest qfr = queryFacetMap.get(reqName).get(name); + if (qfr != null) { + addQueryFacet(qfrs,qfr); + } + } + } + for (QueryFacetRequest qfr : qfrs) { + if (qfr.getDependencies().size()>0) { + throw new SolrException(ErrorCode.BAD_REQUEST,"The query facet dependencies "+qfr.getDependencies().toString()+" either do not exist or are defined in a dependency looop."); + } + } + ar.setQueryFacets(qfrs); + requestList.add(ar); + } + return requestList; + } + + private static void makeFieldFacet(IndexSchema schema, Map> fieldFacetMap, Map> fieldFacetSet, String requestName, String[] fields) { + Map facetMap = fieldFacetMap.get(requestName); + if (facetMap == null) { + facetMap = new HashMap(); + fieldFacetMap.put(requestName, facetMap); + } + Set set = fieldFacetSet.get(requestName); + if (set == null) { + set = new HashSet(); + fieldFacetSet.put(requestName, set); + } + for (String field : fields) { + if (facetMap.get(field) == null) { + facetMap.put(field,new FieldFacetRequest(schema.getField(field))); + } + set.add(field); + } + } + + private static void setFieldFacetParam(IndexSchema schema, Map> fieldFacetMap, String requestName, String field, String paramType, String[] params) { + Map facetMap = fieldFacetMap.get(requestName); + if (facetMap == null) { + facetMap = new HashMap(); + fieldFacetMap.put(requestName, facetMap); + } + FieldFacetRequest fr = facetMap.get(field); + if (fr == null) { + fr = new FieldFacetRequest(schema.getField(field)); + facetMap.put(field,fr); + } + if (paramType.equals("limit")||paramType.equals("l")) { + fr.setLimit(Integer.parseInt(params[0])); + } else if (paramType.equals("offset")||paramType.equals("off")) { + fr.setOffset(Integer.parseInt(params[0])); + } else if (paramType.equals("hidden")||paramType.equals("h")) { + fr.setHidden(Boolean.parseBoolean(params[0])); + } else if (paramType.equals("showmissing")||paramType.equals("sm")) { + fr.showMissing(Boolean.parseBoolean(params[0])); + } else if (paramType.equals("sortstatistic")||paramType.equals("sortstat")||paramType.equals("ss")) { + fr.setSort(new FacetSortSpecification(params[0],fr.getDirection())); + } else if (paramType.equals("sortdirection")||paramType.equals("sd")) { + fr.setDirection(params[0]); + } + } + + private static void makeRangeFacet(IndexSchema schema, Map> rangeFacetSet, String requestName, String[] fields) { + Set set = rangeFacetSet.get(requestName); + if (set == null) { + set = new HashSet(); + rangeFacetSet.put(requestName, set); + } + for (String field : fields) { + set.add(field); + } + } + + private static void setRangeFacetParam(IndexSchema schema, Map> rangeFacetMap, String requestName, String field, String paramType, String[] params) { + Map facetMap = rangeFacetMap.get(requestName); + if (facetMap == null) { + facetMap = new HashMap(); + rangeFacetMap.put(requestName, facetMap); + } + RangeFacetRequest rr = facetMap.get(field); + if (rr == null) { + rr = new RangeFacetRequest(schema.getField(field)); + facetMap.put(field,rr); + } + if (paramType.equals("start")||paramType.equals("st")) { + rr.setStart(params[0]); + } else if (paramType.equals("end")||paramType.equals("e")) { + rr.setEnd(params[0]); + } else if (paramType.equals("gap")||paramType.equals("g")) { + rr.setGaps(params[0].split(",")); + } else if (paramType.equals("hardend")||paramType.equals("he")) { + rr.setHardEnd(Boolean.parseBoolean(params[0])); + } else if (paramType.equals("includebound")||paramType.equals("ib")) { + for (String param : params) { + rr.addInclude(FacetRangeInclude.get(param)); + } + } else if (paramType.equals("otherrange")||paramType.equals("or")) { + for (String param : params) { + rr.addOther(FacetRangeOther.get(param)); + } + } + } + + private static void makeQueryFacet(IndexSchema schema,Map> queryFacetSet, String requestName, String[] names) { + Set set = queryFacetSet.get(requestName); + if (set == null) { + set = new HashSet(); + queryFacetSet.put(requestName, set); + } + for (String name : names) { + set.add(name); + } + } + + private static void setQueryFacetParam(IndexSchema schema, Map> queryFacetMap, String requestName, String name, String paramType, String[] params) { + Map facetMap = queryFacetMap.get(requestName); + if (facetMap == null) { + facetMap = new HashMap(); + queryFacetMap.put(requestName, facetMap); + } + QueryFacetRequest qr = facetMap.get(name); + if (qr == null) { + qr = new QueryFacetRequest(name); + facetMap.put(name,qr); + } + if (paramType.equals("query")||paramType.equals("q")) { + for (String query : params) { + qr.addQuery(query); + } + } else if (paramType.equals("dependency")||paramType.equals("d")) { + for (String depend : params) { + qr.addDependency(depend); + } + } + } + + private static void makeHiddenExpression(Map requestMap, String requestName, String expressionName, String expression) { + AnalyticsRequest req = requestMap.get(requestName); + if (req == null) { + req = new AnalyticsRequest(requestName); + requestMap.put(requestName, req); + } + req.addHiddenExpression(new ExpressionRequest(expressionName,expression)); + } + + private static void makeExpression(Map requestMap, String requestName, String expressionName, String expression) { + AnalyticsRequest req = requestMap.get(requestName); + if (req == null) { + req = new AnalyticsRequest(requestName); + requestMap.put(requestName, req); + } + req.addExpression(new ExpressionRequest(expressionName,expression)); + } + + private static void addQueryFacet(List currentList, QueryFacetRequest queryFacet) { + Set depends = queryFacet.getDependencies(); + int place = 0; + for (QueryFacetRequest qfr : currentList) { + if (qfr.getDependencies().remove(queryFacet)) { + break; + } + place++; + depends.remove(qfr.getName()); + } + currentList.add(place,queryFacet); + for (int count = place+1; count < currentList.size(); count++) { + currentList.get(count).getDependencies().remove(queryFacet.getName()); + } + } +} diff --git a/solr/core/src/java/org/apache/solr/analytics/request/AnalyticsStats.java b/solr/core/src/java/org/apache/solr/analytics/request/AnalyticsStats.java new file mode 100644 index 00000000000..a740fadfd5c --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/request/AnalyticsStats.java @@ -0,0 +1,132 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.request; + +import java.io.IOException; +import java.util.List; + +import org.apache.lucene.index.AtomicReaderContext; +import org.apache.lucene.search.DocIdSet; +import org.apache.lucene.search.DocIdSetIterator; +import org.apache.lucene.search.Filter; +import org.apache.solr.analytics.accumulator.BasicAccumulator; +import org.apache.solr.analytics.accumulator.FacetingAccumulator; +import org.apache.solr.analytics.accumulator.ValueAccumulator; +import org.apache.solr.analytics.plugin.AnalyticsStatisticsCollector; +import org.apache.solr.common.params.SolrParams; +import org.apache.solr.common.util.NamedList; +import org.apache.solr.request.SolrQueryRequest; +import org.apache.solr.search.DocSet; +import org.apache.solr.search.SolrIndexSearcher; + +/** + * Class which computes the set of {@link AnalyticsRequest}s. + */ +public class AnalyticsStats { + protected DocSet docs; + protected SolrParams params; + protected SolrIndexSearcher searcher; + protected SolrQueryRequest req; + protected AnalyticsStatisticsCollector statsCollector; + + public AnalyticsStats(SolrQueryRequest req, DocSet docs, SolrParams params, AnalyticsStatisticsCollector statsCollector) { + this.req = req; + this.searcher = req.getSearcher(); + this.docs = docs; + this.params = params; + this.statsCollector = statsCollector; + } + + /** + * Calculates the analytics requested in the Parameters. + * + * @return List of results formated to mirror the input XML. + * @throws IOException if execution fails + */ + public NamedList execute() throws IOException { + statsCollector.startRequest(); + NamedList res = new NamedList(); + List requests; + + requests = AnalyticsRequestFactory.parse(searcher.getSchema(), params); + + if(requests == null || requests.size()==0){ + return res; + } + statsCollector.addRequests(requests.size()); + // Computing each Analytics Request Seperately + for( AnalyticsRequest areq : requests ){ + // The Accumulator which will control the statistics generation + // for the entire analytics request + ValueAccumulator accumulator; + + // The number of total facet requests + int facets = areq.getFieldFacets().size()+areq.getRangeFacets().size()+areq.getQueryFacets().size(); + try { + if( facets== 0 ){ + accumulator = BasicAccumulator.create(searcher, docs, areq); + } else { + accumulator = FacetingAccumulator.create(searcher, docs, areq, req); + } + } catch (IOException e) { + System.err.println(e.getMessage()); + continue; + } + + statsCollector.addStatsCollected(((BasicAccumulator)accumulator).getNumStatsCollectors()); + statsCollector.addStatsRequests(areq.getExpressions().size()); + statsCollector.addFieldFacets(areq.getFieldFacets().size()); + statsCollector.addRangeFacets(areq.getRangeFacets().size()); + statsCollector.addQueryFacets(areq.getQueryFacets().size()); + statsCollector.addQueries(((BasicAccumulator)accumulator).getNumQueries()); + + // Loop through the documents returned by the query and add to accumulator + Filter filter = docs.getTopFilter(); + List contexts = searcher.getTopReaderContext().leaves(); + for (int leafNum = 0; leafNum < contexts.size(); leafNum++) { + AtomicReaderContext context = contexts.get(leafNum); + DocIdSet dis = filter.getDocIdSet(context, null); // solr docsets already exclude any deleted docs + DocIdSetIterator disi = null; + if (dis != null) { + disi = dis.iterator(); + } + + if (disi != null) { + accumulator.setNextReader(context); + int doc = disi.nextDoc(); + while( doc != DocIdSetIterator.NO_MORE_DOCS){ + // Add a document to the statistics being generated + accumulator.collect(doc); + doc = disi.nextDoc(); + } + } + } + + // do some post-processing + accumulator.postProcess(); + + // compute the stats + accumulator.compute(); + + res.add(areq.getName(),accumulator.export()); + } + + statsCollector.endRequest(); + return res; + } +} diff --git a/solr/core/src/java/org/apache/solr/analytics/request/ExpressionRequest.java b/solr/core/src/java/org/apache/solr/analytics/request/ExpressionRequest.java new file mode 100644 index 00000000000..1549cdfb8a6 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/request/ExpressionRequest.java @@ -0,0 +1,73 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.request; + +import org.apache.solr.analytics.expression.Expression; + +/** + * Contains name and string representation of an expression. + */ +public class ExpressionRequest implements Comparable { + private String name; + private String expressionString; + private Expression expression; + + /** + * @param name The name of the Expression. + * @param expressionString The string representation of the desired Expression. + */ + public ExpressionRequest(String name, String expressionString) { + this.name = name; + this.expressionString = expressionString; + } + + public void setExpressionString(String expressionString) { + this.expressionString = expressionString; + } + + public String getExpressionString() { + return expressionString; + } + + public void setExpression(Expression expression) { + this.expression = expression; + } + + public Expression getExpression() { + return expression; + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + @Override + public int compareTo(ExpressionRequest o) { + return name.compareTo(o.getName()); + } + + @Override + public String toString() { + return ""; + } + +} diff --git a/solr/core/src/java/org/apache/solr/analytics/request/FacetRequest.java b/solr/core/src/java/org/apache/solr/analytics/request/FacetRequest.java new file mode 100644 index 00000000000..6cca99d6f3d --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/request/FacetRequest.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.request; + +public interface FacetRequest { + + /** + * Get the name of this facet (commonly the field name) + * @return the name + */ + String getName(); +} diff --git a/solr/core/src/java/org/apache/solr/analytics/request/FieldFacetRequest.java b/solr/core/src/java/org/apache/solr/analytics/request/FieldFacetRequest.java new file mode 100644 index 00000000000..7884476d577 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/request/FieldFacetRequest.java @@ -0,0 +1,173 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.request; + +import org.apache.solr.analytics.util.AnalyticsParams; +import org.apache.solr.schema.SchemaField; + +import java.util.Locale; + + +/** + * Contains all of the specifications for a field facet. + */ +public class FieldFacetRequest extends AbstractFieldFacetRequest { + + private FacetSortSpecification sort = null; + private FacetSortDirection dir = null; + private int limit; + private int offset; + private boolean missing; + private boolean hidden; + + + public static enum FacetSortDirection { + ASCENDING , + DESCENDING; + + public static FacetSortDirection fromExternal(String value){ + final String sort = value.toLowerCase(Locale.ROOT); + if( "asc".equals(sort) ) return ASCENDING; + if( "ascending".equals(sort) ) return ASCENDING; + if( "desc".equals(sort) ) return DESCENDING; + if( "descending".equals(sort) ) return DESCENDING; + return Enum.valueOf(FacetSortDirection.class, value); + } + } + + /** + * Specifies how to sort the buckets of a field facet. + * + */ + public static class FacetSortSpecification { + private String statistic; + private FacetSortDirection direction = FacetSortDirection.DESCENDING; + + public FacetSortSpecification(){} + + /** + * @param statistic The name of a statistic specified in the {@link AnalyticsRequest} + * which is wrapping the {@link FieldFacetRequest} being sorted. + */ + public FacetSortSpecification(String statistic) { + this.statistic = statistic; + } + + public FacetSortSpecification(String statistic, FacetSortDirection direction) { + this(statistic); + this.direction = direction; + } + + public String getStatistic() { + return statistic; + } + public void setStatistic(String statistic) { + this.statistic = statistic; + } + public FacetSortDirection getDirection() { + return direction; + } + public void setDirection(FacetSortDirection direction) { + this.direction = direction; + } + + public static FacetSortSpecification fromExternal(String spec){ + String[] parts = spec.split(" ",2); + if( parts.length == 1 ){ + return new FacetSortSpecification(parts[0]); + } else { + return new FacetSortSpecification(parts[0], FacetSortDirection.fromExternal(parts[1])); + } + } + + @Override + public String toString() { + return ""; + } + } + + public FieldFacetRequest(SchemaField field) { + super(field); + this.limit = AnalyticsParams.DEFAULT_LIMIT; + this.hidden = AnalyticsParams.DEFAULT_HIDDEN; + } + + public FacetSortDirection getDirection() { + return dir; + } + + public void setDirection(String dir) { + this.dir = FacetSortDirection.fromExternal(dir); + if (sort!=null) { + sort.setDirection(this.dir); + } + } + + public FacetSortSpecification getSort() { + return sort; + } + + public void setSort(FacetSortSpecification sort) { + this.sort = sort; + } + + public boolean showsMissing() { + return missing; + } + + /** + * If there are missing values in the facet field, include the bucket + * for the missing facet values in the facet response. + * @param missing true/false if we calculate missing + */ + public void showMissing(boolean missing) { + this.missing = missing; + } + + public int getLimit() { + return limit; + } + + public void setLimit(int limit) { + this.limit = limit; + } + + public int getOffset() { + return offset; + } + + public void setOffset(int offset) { + this.offset = offset; + } + + public boolean isHidden() { + return hidden; + } + + public void setHidden(boolean hidden) { + this.hidden = hidden; + } + + @Override + public String toString() { + return ""; + } + + + +} diff --git a/solr/core/src/java/org/apache/solr/analytics/request/QueryFacetRequest.java b/solr/core/src/java/org/apache/solr/analytics/request/QueryFacetRequest.java new file mode 100644 index 00000000000..6d36d58cb8b --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/request/QueryFacetRequest.java @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.request; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Contains all of the specifications for a query facet. + */ +public class QueryFacetRequest implements FacetRequest { + private String name; + private List queries; + private Set dependencies; + + public QueryFacetRequest() { + dependencies = new HashSet(); + } + + public QueryFacetRequest(String name) { + this.name = name; + this.queries = new ArrayList(); + dependencies = new HashSet(); + } + + public List getQueries() { + return queries; + } + + public void setQueries(List queries) { + this.queries = queries; + } + + public void addQuery(String query) { + queries.add(query); + } + + public Set getDependencies() { + return dependencies; + } + + public void setDependencies(Set dependencies) { + this.dependencies = dependencies; + } + + public void addDependency(String dependency) { + dependencies.add(dependency); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/solr/core/src/java/org/apache/solr/analytics/request/RangeFacetRequest.java b/solr/core/src/java/org/apache/solr/analytics/request/RangeFacetRequest.java new file mode 100644 index 00000000000..8c70b98fa01 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/request/RangeFacetRequest.java @@ -0,0 +1,130 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.request; + +import java.util.Arrays; +import java.util.EnumSet; + +import org.apache.solr.analytics.util.AnalyticsParams; +import org.apache.solr.common.params.FacetParams.FacetRangeInclude; +import org.apache.solr.common.params.FacetParams.FacetRangeOther; +import org.apache.solr.schema.SchemaField; + +/** + * Contains all of the specifications for a range facet. + */ +public class RangeFacetRequest extends AbstractFieldFacetRequest { + protected String start; + protected String end; + protected String[] gaps; + protected boolean hardEnd = false; + protected EnumSet include; + protected boolean includeCalled = false; + protected EnumSet others; + protected boolean othersCalled = false; + + public RangeFacetRequest(SchemaField field) { + super(field); + include = EnumSet.of(AnalyticsParams.DEFAULT_INCLUDE); + others = EnumSet.of(AnalyticsParams.DEFAULT_OTHER); + } + + public RangeFacetRequest(SchemaField field, String start, String end, String[] gaps) { + super(field); + this.start = start; + this.end = end; + this.gaps = gaps; + } + + public String getStart() { + return start; + } + + public void setStart(String start) { + this.start = start; + } + + public String getEnd() { + return end; + } + + public void setEnd(String end) { + this.end = end; + } + + public EnumSet getInclude() { + return include; + } + + public void setInclude(EnumSet include) { + includeCalled = true; + this.include = include; + } + + public void addInclude(FacetRangeInclude include) { + if (includeCalled) { + this.include.add(include); + } else { + includeCalled = true; + this.include = EnumSet.of(include); + } + } + + public String[] getGaps() { + return gaps; + } + + public void setGaps(String[] gaps) { + this.gaps = gaps; + } + + public boolean isHardEnd() { + return hardEnd; + } + + public void setHardEnd(boolean hardEnd) { + this.hardEnd = hardEnd; + } + + public EnumSet getOthers() { + return others; + } + + public void setOthers(EnumSet others) { + othersCalled = true; + this.others = others; + } + + public void addOther(FacetRangeOther other) { + if (othersCalled) { + this.others.add(other); + } else { + othersCalled = true; + this.others = EnumSet.of(other); + } + } + + @Override + public String toString() { + return ""; + } + + + +} diff --git a/solr/core/src/java/org/apache/solr/analytics/request/package.html b/solr/core/src/java/org/apache/solr/analytics/request/package.html new file mode 100644 index 00000000000..08822a9df7f --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/request/package.html @@ -0,0 +1,27 @@ + + + + + + + +

    +Request objects for creating Analytics requests +

    + + diff --git a/solr/core/src/java/org/apache/solr/analytics/statistics/AbstractDelegatingStatsCollector.java b/solr/core/src/java/org/apache/solr/analytics/statistics/AbstractDelegatingStatsCollector.java new file mode 100644 index 00000000000..093ab29f03c --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/statistics/AbstractDelegatingStatsCollector.java @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.statistics; + +import java.io.IOException; +import java.util.Set; + +import org.apache.lucene.index.AtomicReaderContext; +import org.apache.lucene.queries.function.FunctionValues; +import org.apache.lucene.util.mutable.MutableValue; + +/** + * AbstractDelegationStatsCollector objects wrap other StatsCollectors. + * While they compute their own statistics they pass along all inputs and requests + * to the delegates as well. + */ +public abstract class AbstractDelegatingStatsCollector implements StatsCollector{ + protected final StatsCollector delegate; + protected final Set statsList; + MutableValue value; + FunctionValues function; + + /** + * @param delegate The delegate computing statistics on the same set of values. + */ + public AbstractDelegatingStatsCollector(StatsCollector delegate) { + this.delegate = delegate; + this.statsList = delegate.getStatsList(); + } + + public void setNextReader(AtomicReaderContext context) throws IOException { + delegate.setNextReader(context); + value = getValue(); + function = getFunction(); + } + + public StatsCollector delegate(){ + return delegate; + } + + public Set getStatsList(){ + return statsList; + } + + public MutableValue getValue() { + return delegate.getValue(); + } + + public FunctionValues getFunction() { + return delegate.getFunction(); + } + + public void collect(int doc) { + delegate.collect(doc); + } + + public String valueSourceString() { + return delegate.valueSourceString(); + } +} diff --git a/solr/core/src/java/org/apache/solr/analytics/statistics/MedianStatsCollector.java b/solr/core/src/java/org/apache/solr/analytics/statistics/MedianStatsCollector.java new file mode 100644 index 00000000000..c8f9ee064bc --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/statistics/MedianStatsCollector.java @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.statistics; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import org.apache.solr.analytics.util.MedianCalculator; + +/** + * MedianStatsCollector computes the median. + */ +public class MedianStatsCollector extends AbstractDelegatingStatsCollector{ + + private final List values = new ArrayList(); + protected double median; + + public MedianStatsCollector(StatsCollector delegate) { + super(delegate); + } + + public Double getMedian() { + return new Double(MedianCalculator.getMedian(values)); + } + + @Override + public Comparable getStat(String stat) { + if (stat.equals("median")) { + return new Double(median); + } + return delegate.getStat(stat); + } + + public void compute(){ + delegate.compute(); + median = getMedian(); + } + + @Override + public void collect(int doc) { + super.collect(doc); + if (value.exists) { + values.add(function.doubleVal(doc)); + } + } +} +class DateMedianStatsCollector extends MedianStatsCollector{ + + public DateMedianStatsCollector(StatsCollector delegate) { + super(delegate); + } + + @Override + public Comparable getStat(String stat) { + if (stat.equals("median")) { + return new Date((long)median); + } + return delegate.getStat(stat); + } +} diff --git a/solr/core/src/java/org/apache/solr/analytics/statistics/MinMaxStatsCollector.java b/solr/core/src/java/org/apache/solr/analytics/statistics/MinMaxStatsCollector.java new file mode 100644 index 00000000000..08608861789 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/statistics/MinMaxStatsCollector.java @@ -0,0 +1,113 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.statistics; + +import java.io.IOException; +import java.util.Locale; +import java.util.Set; + +import org.apache.lucene.index.AtomicReaderContext; +import org.apache.lucene.queries.function.FunctionValues; +import org.apache.lucene.queries.function.FunctionValues.ValueFiller; +import org.apache.lucene.queries.function.ValueSource; +import org.apache.lucene.util.mutable.MutableValue; + +/** + * MinMaxStatsCollector computes the min, max, number of values and number of missing values. + */ +public class MinMaxStatsCollector implements StatsCollector{ + protected long missingCount = 0; + protected long valueCount = 0; + protected MutableValue max; + protected MutableValue min; + protected MutableValue value; + protected final Set statsList; + protected final ValueSource source; + protected FunctionValues function; + protected ValueFiller valueFiller; + + public MinMaxStatsCollector(ValueSource source, Set statsList) { + this.source = source; + this.statsList = statsList; + } + + public void setNextReader(AtomicReaderContext context) throws IOException { + function = source.getValues(null, context); + valueFiller = function.getValueFiller(); + value = valueFiller.getValue(); + } + + public void collect(int doc) { + valueFiller.fillValue(doc); + if( value.exists ){ + valueCount += 1; + if ( max==null ) max = value.duplicate(); + else if( !max.exists || value.compareTo(max) > 0 ) max.copy(value); + if ( min==null ) min = value.duplicate(); + else if( !min.exists || value.compareTo(min) < 0 ) min.copy(value); + } else { + missingCount += 1; + } + } + + @Override + public String toString() { + return String.format(Locale.ROOT, "", min, max, valueCount, missingCount ); + } + + public Comparable getStat(String stat){ + if (stat.equals("min")&&min!=null) { + return (Comparable)min.toObject(); + } + if (stat.equals("max")&&min!=null) { + return (Comparable)max.toObject(); + } + if (stat.equals("count")) { + return new Long(valueCount); + } + if (stat.equals("missing")) { + return new Long(missingCount); + } + return null; + } + + public Set getStatsList() { + return statsList; + } + + @Override + public void compute() { } + + @Override + public MutableValue getValue() { + return value; + } + + @Override + public FunctionValues getFunction() { + return function; + } + + public String valueSourceString() { + return source.toString(); + } + + public String statString(String stat) { + return stat+"("+valueSourceString()+")"; + } +} diff --git a/solr/core/src/java/org/apache/solr/analytics/statistics/NumericStatsCollector.java b/solr/core/src/java/org/apache/solr/analytics/statistics/NumericStatsCollector.java new file mode 100644 index 00000000000..ef3de5dc02b --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/statistics/NumericStatsCollector.java @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.statistics; + +import java.util.Set; + +import org.apache.lucene.queries.function.ValueSource; + +/** + * NumericStatsCollector computes the sum, sum of squares, mean and standard deviation. + */ +public class NumericStatsCollector extends MinMaxStatsCollector { + protected double sum = 0; + protected double sumOfSquares = 0; + protected double mean = 0; + protected double stddev = 0; + + public NumericStatsCollector(ValueSource source, Set statsList) { + super(source, statsList); + } + + public void collect(int doc) { + super.collect(doc); + double value = function.doubleVal(doc); + sum += value; + sumOfSquares += (value * value); + } + + @Override + public Comparable getStat(String stat) { + if (stat.equals("sum")) { + return new Double(sum); + } + if (stat.equals("sumofsquares")) { + return new Double(sumOfSquares); + } + if (stat.equals("mean")) { + return new Double(mean); + } + if (stat.equals("stddev")) { + return new Double(stddev); + } + return super.getStat(stat); + } + + @Override + public void compute(){ + super.compute(); + mean = (valueCount==0)? 0:sum / valueCount; + stddev = (valueCount <= 1) ? 0.0D : Math.sqrt((sumOfSquares/valueCount) - (mean*mean)); + } + +} diff --git a/solr/core/src/java/org/apache/solr/analytics/statistics/PercentileStatsCollector.java b/solr/core/src/java/org/apache/solr/analytics/statistics/PercentileStatsCollector.java new file mode 100644 index 00000000000..88e1c748d31 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/statistics/PercentileStatsCollector.java @@ -0,0 +1,80 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.statistics; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; + +import org.apache.solr.analytics.util.PercentileCalculator; + +import com.google.common.collect.Iterables; + +/** + * PercentileStatsCollector computes a given list of percentiles. + */ +@SuppressWarnings("rawtypes") +public class PercentileStatsCollector extends AbstractDelegatingStatsCollector{ + public final List values = new ArrayList(); + public static final Pattern PERCENTILE_PATTERN = Pattern.compile("perc(?:entile)?_(\\d+)",Pattern.CASE_INSENSITIVE); + protected final double[] percentiles; + protected final String[] percentileNames; + protected Comparable[] results; + + public PercentileStatsCollector(StatsCollector delegate, double[] percentiles, String[] percentileNames) { + super(delegate); + this.percentiles = percentiles; + this.percentileNames = percentileNames; + } + + @Override + public Comparable getStat(String stat) { + for( int i=0; i < percentiles.length; i++ ){ + if (stat.equals(percentileNames[i])) { + if (results!=null) { + return results[i]; + } else { + return null; + } + } + } + return delegate.getStat(stat); + } + + public void compute(){ + delegate.compute(); + if (values.size()>0) { + results = Iterables.toArray(getPercentiles(),Comparable.class); + } else { + results = null; + } + } + + @SuppressWarnings({ "unchecked"}) + protected List getPercentiles() { + return PercentileCalculator.getPercentiles(values, percentiles); + } + + public void collect(int doc) { + super.collect(doc); + if (value.exists) { + values.add((Comparable)value.toObject()); + } + } + +} diff --git a/solr/core/src/java/org/apache/solr/analytics/statistics/StatsCollector.java b/solr/core/src/java/org/apache/solr/analytics/statistics/StatsCollector.java new file mode 100644 index 00000000000..b3f173de949 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/statistics/StatsCollector.java @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.statistics; + +import java.io.IOException; +import java.util.Set; + +import org.apache.lucene.index.AtomicReaderContext; +import org.apache.lucene.queries.function.FunctionValues; +import org.apache.lucene.util.mutable.MutableValue; + +/** + * StatsCollector implementations reduce a list of Objects to a single value. + * Most implementations reduce a list to a statistic on that list. + */ +public interface StatsCollector { + + /** + * Collect values from the value source and add to statistics. + * @param doc Document to collect from + */ + void collect(int doc); + + /** + * @param context The context to read documents from. + * @throws IOException if setting next reader fails + */ + void setNextReader(AtomicReaderContext context) throws IOException; + + MutableValue getValue(); + FunctionValues getFunction(); + + /** + * @return The set of statistics being computed by the stats collector. + */ + Set getStatsList(); + + /** + * Return the value of the given statistic. + * @param stat the stat + * @return a comparable + */ + Comparable getStat(String stat); + + /** + * After all documents have been collected, this method should be + * called to finalize the calculations of each statistic. + */ + void compute(); + + /** + * @return The string representation of the value source. + */ + String valueSourceString(); +} diff --git a/solr/core/src/java/org/apache/solr/analytics/statistics/StatsCollectorSupplierFactory.java b/solr/core/src/java/org/apache/solr/analytics/statistics/StatsCollectorSupplierFactory.java new file mode 100644 index 00000000000..20d92d470a4 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/statistics/StatsCollectorSupplierFactory.java @@ -0,0 +1,649 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.statistics; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.lucene.queries.function.ValueSource; +import org.apache.lucene.queries.function.valuesource.BytesRefFieldSource; +import org.apache.lucene.queries.function.valuesource.DoubleFieldSource; +import org.apache.lucene.queries.function.valuesource.FloatFieldSource; +import org.apache.lucene.queries.function.valuesource.IntFieldSource; +import org.apache.lucene.queries.function.valuesource.LongFieldSource; +import org.apache.lucene.search.FieldCache; +import org.apache.solr.analytics.expression.ExpressionFactory; +import org.apache.solr.analytics.request.AnalyticsRequest; +import org.apache.solr.analytics.request.ExpressionRequest; +import org.apache.solr.analytics.util.AnalyticsParams; +import org.apache.solr.analytics.util.AnalyticsParsers; +import org.apache.solr.analytics.util.valuesource.AbsoluteValueDoubleFunction; +import org.apache.solr.analytics.util.valuesource.AddDoubleFunction; +import org.apache.solr.analytics.util.valuesource.ConcatStringFunction; +import org.apache.solr.analytics.util.valuesource.ConstDateSource; +import org.apache.solr.analytics.util.valuesource.ConstDoubleSource; +import org.apache.solr.analytics.util.valuesource.ConstStringSource; +import org.apache.solr.analytics.util.valuesource.DateFieldSource; +import org.apache.solr.analytics.util.valuesource.DateMathFunction; +import org.apache.solr.analytics.util.valuesource.DivDoubleFunction; +import org.apache.solr.analytics.util.valuesource.DualDoubleFunction; +import org.apache.solr.analytics.util.valuesource.FilterFieldSource; +import org.apache.solr.analytics.util.valuesource.LogDoubleFunction; +import org.apache.solr.analytics.util.valuesource.MultiDateFunction; +import org.apache.solr.analytics.util.valuesource.MultiDoubleFunction; +import org.apache.solr.analytics.util.valuesource.MultiplyDoubleFunction; +import org.apache.solr.analytics.util.valuesource.NegateDoubleFunction; +import org.apache.solr.analytics.util.valuesource.PowDoubleFunction; +import org.apache.solr.analytics.util.valuesource.ReverseStringFunction; +import org.apache.solr.analytics.util.valuesource.SingleDoubleFunction; +import org.apache.solr.common.SolrException; +import org.apache.solr.common.SolrException.ErrorCode; +import org.apache.solr.schema.FieldType; +import org.apache.solr.schema.IndexSchema; +import org.apache.solr.schema.SchemaField; +import org.apache.solr.schema.StrField; +import org.apache.solr.schema.TrieDateField; +import org.apache.solr.schema.TrieDoubleField; +import org.apache.solr.schema.TrieFloatField; +import org.apache.solr.schema.TrieIntField; +import org.apache.solr.schema.TrieLongField; + +import com.google.common.base.Supplier; + +public class StatsCollectorSupplierFactory { + + // FunctionTypes + final static int NUMBER_TYPE = 0; + final static int DATE_TYPE = 1; + final static int STRING_TYPE = 2; + final static int FIELD_TYPE = 3; + final static int FILTER_TYPE = 4; + + /** + * Builds a Supplier that will generate identical arrays of new StatsCollectors. + * + * @param schema The Schema being used. + * @param request The AnalyticsRequest to generate a StatsCollector[] from. + * @return A Supplier that will return an array of new StatsCollector. + */ + @SuppressWarnings("unchecked") + public static Supplier create(IndexSchema schema, AnalyticsRequest request) { + final Map> collectorStats = new HashMap>(); + final Map> collectorPercs = new HashMap>(); + final Map collectorSources = new HashMap(); + + // Iterate through all expression request to make a list of ValueSource strings + // and statistics that need to be calculated on those ValueSources. + for (ExpressionRequest expRequest : request.getExpressions()) { + String statExpression = expRequest.getExpressionString(); + Set statistics = getStatistics(statExpression); + if (statistics == null) { + continue; + } + for (String statExp : statistics) { + String stat; + String operands; + try { + stat = statExp.substring(0, statExp.indexOf('(')).trim(); + operands = statExp.substring(statExp.indexOf('(')+1, statExp.lastIndexOf(')')).trim(); + } catch (Exception e) { + throw new SolrException(ErrorCode.BAD_REQUEST,"Unable to parse statistic: ["+statExpression+"]",e); + } + String[] arguments = ExpressionFactory.getArguments(operands); + String source = arguments[0]; + if (stat.equals(AnalyticsParams.STAT_PERCENTILE)) { + // The statistic is a percentile, extra parsing is required + if (arguments.length<2) { + throw new SolrException(ErrorCode.BAD_REQUEST,"Too few arguments given for "+stat+"() in ["+statExp+"]."); + } else if (arguments.length>2) { + throw new SolrException(ErrorCode.BAD_REQUEST,"Too many arguments given for "+stat+"() in ["+statExp+"]."); + } + source = arguments[1]; + Set percs = collectorPercs.get(source); + if (percs == null) { + percs = new HashSet(); + collectorPercs.put(source, percs); + } + try { + int perc = Integer.parseInt(arguments[0]); + if (perc>0 && perc<100) { + percs.add(perc); + } else { + throw new SolrException(ErrorCode.BAD_REQUEST,"The percentile in ["+statExp+"] is not between 0 and 100, exculsive."); + } + } catch (NumberFormatException e) { + throw new SolrException(ErrorCode.BAD_REQUEST,"\""+arguments[0]+"\" cannot be converted into a percentile.",e); + } + } else if (arguments.length>1) { + throw new SolrException(ErrorCode.BAD_REQUEST,"Too many arguments given for "+stat+"() in ["+statExp+"]."); + } else if (arguments.length==0) { + throw new SolrException(ErrorCode.BAD_REQUEST,"No arguments given for "+stat+"() in ["+statExp+"]."); + } + // Only unique ValueSources will be made; therefore statistics must be accumulated for + // each ValueSource, even across different expression requests + Set stats = collectorStats.get(source); + if (stats == null) { + stats = new HashSet(); + collectorStats.put(source, stats); + } + stats.add(stat); + } + } + String[] keys = collectorStats.keySet().toArray(new String[0]); + for (String sourceStr : keys) { + // Build one ValueSource for each unique value source string + ValueSource source = buildSourceTree(schema, sourceStr); + if (source == null) { + throw new SolrException(ErrorCode.BAD_REQUEST,"The statistic ["+sourceStr+"] could not be parsed."); + } + String builtString = source.toString(); + collectorSources.put(builtString,source); + // Replace the user given string with the correctly built string + if (!builtString.equals(sourceStr)) { + Set stats = collectorStats.remove(sourceStr); + if (stats!=null) { + collectorStats.put(builtString, stats); + } + Set percs = collectorPercs.remove(sourceStr); + if (percs!=null) { + collectorPercs.put(builtString, percs); + } + for (ExpressionRequest er : request.getExpressions()) { + er.setExpressionString(er.getExpressionString().replace(sourceStr, builtString)); + } + } + } + if (collectorSources.size()==0) { + return new Supplier() { + @Override + public StatsCollector[] get() { + return new StatsCollector[0]; + } + }; + } + + // All information is stored in final arrays so that nothing + // has to be computed when the Supplier's get() method is called. + final Set[] statsArr = collectorStats.values().toArray(new Set[0]); + final ValueSource[] sourceArr = collectorSources.values().toArray(new ValueSource[0]); + final boolean[] uniqueBools = new boolean[statsArr.length]; + final boolean[] medianBools = new boolean[statsArr.length]; + final boolean[] numericBools = new boolean[statsArr.length]; + final boolean[] dateBools = new boolean[statsArr.length]; + final double[][] percsArr = new double[statsArr.length][]; + final String[][] percsNames = new String[statsArr.length][]; + for (int count = 0; count < sourceArr.length; count++) { + uniqueBools[count] = statsArr[count].contains(AnalyticsParams.STAT_UNIQUE); + medianBools[count] = statsArr[count].contains(AnalyticsParams.STAT_MEDIAN); + numericBools[count] = statsArr[count].contains(AnalyticsParams.STAT_SUM)||statsArr[count].contains(AnalyticsParams.STAT_SUM_OF_SQUARES)||statsArr[count].contains(AnalyticsParams.STAT_MEAN)||statsArr[count].contains(AnalyticsParams.STAT_STANDARD_DEVIATION); + dateBools[count] = (sourceArr[count] instanceof DateFieldSource) | (sourceArr[count] instanceof MultiDateFunction) | (sourceArr[count] instanceof ConstDateSource); + Set ps = collectorPercs.get(sourceArr[count].toString()); + if (ps!=null) { + percsArr[count] = new double[ps.size()]; + percsNames[count] = new String[ps.size()]; + int percCount = 0; + for (int p : ps) { + percsArr[count][percCount] = p/100.0; + percsNames[count][percCount++] = AnalyticsParams.STAT_PERCENTILE+"_"+p; + } + } + } + // Making the Supplier + return new Supplier() { + public StatsCollector[] get() { + StatsCollector[] collectors = new StatsCollector[statsArr.length]; + for (int count = 0; count < statsArr.length; count++) { + if(numericBools[count]){ + StatsCollector sc = new NumericStatsCollector(sourceArr[count], statsArr[count]); + if(uniqueBools[count]) sc = new UniqueStatsCollector(sc); + if(medianBools[count]) sc = new MedianStatsCollector(sc); + if(percsArr[count]!=null) sc = new PercentileStatsCollector(sc,percsArr[count],percsNames[count]); + collectors[count]=sc; + } else if (dateBools[count]) { + StatsCollector sc = new MinMaxStatsCollector(sourceArr[count], statsArr[count]); + if(uniqueBools[count]) sc = new UniqueStatsCollector(sc); + if(medianBools[count]) sc = new DateMedianStatsCollector(sc); + if(percsArr[count]!=null) sc = new PercentileStatsCollector(sc,percsArr[count],percsNames[count]); + collectors[count]=sc; + } else { + StatsCollector sc = new MinMaxStatsCollector(sourceArr[count], statsArr[count]); + if(uniqueBools[count]) sc = new UniqueStatsCollector(sc); + if(medianBools[count]) sc = new MedianStatsCollector(sc); + if(percsArr[count]!=null) sc = new PercentileStatsCollector(sc,percsArr[count],percsNames[count]); + collectors[count]=sc; + } + } + return collectors; + } + }; + } + + /** + * Finds the set of statistics that must be computed for the expression. + * @param expression The string representation of an expression + * @return The set of statistics (sum, mean, median, etc.) found in the expression + */ + public static Set getStatistics(String expression) { + HashSet set = new HashSet(); + int firstParen = expression.indexOf('('); + if (firstParen>0) { + String topOperation = expression.substring(0,firstParen).trim(); + if (AnalyticsParams.ALL_STAT_SET.contains(topOperation)) { + set.add(expression); + } else if (!(topOperation.equals(AnalyticsParams.CONSTANT_NUMBER)||topOperation.equals(AnalyticsParams.CONSTANT_DATE)||topOperation.equals(AnalyticsParams.CONSTANT_STRING))) { + String operands = expression.substring(firstParen+1, expression.lastIndexOf(')')).trim(); + String[] arguments = ExpressionFactory.getArguments(operands); + for (String argument : arguments) { + Set more = getStatistics(argument); + if (more!=null) { + set.addAll(more); + } + } + } + } + if (set.size()==0) { + return null; + } + return set; + } + + /** + * Builds a Value Source from a given string + * + * @param schema The schema being used. + * @param expression The string to be turned into an expression. + * @return The completed ValueSource + */ + private static ValueSource buildSourceTree(IndexSchema schema, String expression) { + return buildSourceTree(schema,expression,FIELD_TYPE); + } + + /** + * Builds a Value Source from a given string and a given source type + * + * @param schema The schema being used. + * @param expression The string to be turned into an expression. + * @param sourceType The type of source that must be returned. + * @return The completed ValueSource + */ + private static ValueSource buildSourceTree(IndexSchema schema, String expression, int sourceType) { + int expressionType = getSourceType(expression); + if (sourceType != FIELD_TYPE && expressionType != FIELD_TYPE && + expressionType != FILTER_TYPE && expressionType != sourceType) { + return null; + } + switch (expressionType) { + case NUMBER_TYPE : return buildNumericSource(schema, expression); + case DATE_TYPE : return buildDateSource(schema, expression); + case STRING_TYPE : return buildStringSource(schema, expression); + case FIELD_TYPE : return buildFieldSource(schema, expression, sourceType); + case FILTER_TYPE : return buildFilterSource(schema, expression.substring(expression.indexOf('(')+1,expression.lastIndexOf(')')), sourceType); + default : throw new SolrException(ErrorCode.BAD_REQUEST,expression+" is not a valid operation."); + } + } + + /** + * Determines what type of value source the expression represents. + * + * @param expression The expression representing the desired ValueSource + * @return NUMBER_TYPE, DATE_TYPE, STRING_TYPE or -1 + */ + private static int getSourceType(String expression) { + int paren = expression.indexOf('('); + if (paren<0) { + return FIELD_TYPE; + } + String operation = expression.substring(0,paren).trim(); + + if (AnalyticsParams.NUMERIC_OPERATION_SET.contains(operation)) { + return NUMBER_TYPE; + } else if (AnalyticsParams.DATE_OPERATION_SET.contains(operation)) { + return DATE_TYPE; + } else if (AnalyticsParams.STRING_OPERATION_SET.contains(operation)) { + return STRING_TYPE; + } else if (operation.equals(AnalyticsParams.FILTER)) { + return FILTER_TYPE; + } + throw new SolrException(ErrorCode.BAD_REQUEST,"The operation \""+operation+"\" in ["+expression+"] is not supported."); + } + + /** + * Builds a value source for a given field, making sure that the field fits a given source type. + * @param schema the schema + * @param expressionString The name of the field to build a Field Source from. + * @param sourceType FIELD_TYPE for any type of field, NUMBER_TYPE for numeric fields, + * DATE_TYPE for date fields and STRING_TYPE for string fields. + * @return a value source + */ + private static ValueSource buildFieldSource(IndexSchema schema, String expressionString, int sourceType) { + SchemaField sf; + try { + sf = schema.getField(expressionString); + } catch (SolrException e) { + throw new SolrException(ErrorCode.BAD_REQUEST,"The field "+expressionString+" does not exist.",e); + } + FieldType type = sf.getType(); + if ( type instanceof TrieIntField) { + if (sourceType!=NUMBER_TYPE&&sourceType!=FIELD_TYPE) { + return null; + } + return new IntFieldSource(expressionString, FieldCache.NUMERIC_UTILS_INT_PARSER) { + public String description() { + return field; + } + }; + } else if (type instanceof TrieLongField) { + if (sourceType!=NUMBER_TYPE&&sourceType!=FIELD_TYPE) { + return null; + } + return new LongFieldSource(expressionString, FieldCache.NUMERIC_UTILS_LONG_PARSER) { + public String description() { + return field; + } + }; + } else if (type instanceof TrieFloatField) { + if (sourceType!=NUMBER_TYPE&&sourceType!=FIELD_TYPE) { + return null; + } + return new FloatFieldSource(expressionString, FieldCache.NUMERIC_UTILS_FLOAT_PARSER) { + public String description() { + return field; + } + }; + } else if (type instanceof TrieDoubleField) { + if (sourceType!=NUMBER_TYPE&&sourceType!=FIELD_TYPE) { + return null; + } + return new DoubleFieldSource(expressionString, FieldCache.NUMERIC_UTILS_DOUBLE_PARSER) { + public String description() { + return field; + } + }; + } else if (type instanceof TrieDateField) { + if (sourceType!=DATE_TYPE&&sourceType!=FIELD_TYPE) { + return null; + } + return new DateFieldSource(expressionString, AnalyticsParsers.DEFAULT_DATE_PARSER) { + public String description() { + return field; + } + }; + } else if (type instanceof StrField) { + if (sourceType!=STRING_TYPE&&sourceType!=FIELD_TYPE) { + return null; + } + return new BytesRefFieldSource(expressionString) { + public String description() { + return field; + } + }; + } + throw new SolrException(ErrorCode.BAD_REQUEST, type.toString()+" is not a supported field type in Solr Analytics."); + } + + /** + * Builds a default is missing source that wraps a given source. A missing value is required for all + * non-field value sources. + * @param schema the schema + * @param expressionString The name of the field to build a Field Source from. + * @param sourceType FIELD_TYPE for any type of field, NUMBER_TYPE for numeric fields, + * DATE_TYPE for date fields and STRING_TYPE for string fields. + * @return a value source + */ + @SuppressWarnings("deprecation") + private static ValueSource buildFilterSource(IndexSchema schema, String expressionString, int sourceType) { + String[] arguments = ExpressionFactory.getArguments(expressionString); + if (arguments.length!=2) { + throw new SolrException(ErrorCode.BAD_REQUEST,"Invalid arguments were given for \""+AnalyticsParams.FILTER+"\"."); + } + ValueSource delegateSource = buildSourceTree(schema, arguments[0], sourceType); + if (delegateSource==null) { + return null; + } + Object defaultObject; + Class type = delegateSource.getClass(); + ValueSource src = delegateSource; + if (delegateSource instanceof FilterFieldSource) { + src = ((FilterFieldSource)delegateSource).getRootSource(); + } + if ( src instanceof IntFieldSource) { + try { + defaultObject = new Integer(arguments[1]); + } catch (NumberFormatException e) { + throw new SolrException(ErrorCode.BAD_REQUEST,"The filter value "+arguments[1]+" cannot be converted into an integer.",e); + } + } else if ( src instanceof LongFieldSource ) { + try { + defaultObject = new Long(arguments[1]); + } catch (NumberFormatException e) { + throw new SolrException(ErrorCode.BAD_REQUEST,"The filter value "+arguments[1]+" cannot be converted into a long.",e); + } + } else if ( src instanceof FloatFieldSource ) { + try { + defaultObject = new Float(arguments[1]); + } catch (NumberFormatException e) { + throw new SolrException(ErrorCode.BAD_REQUEST,"The filter value "+arguments[1]+" cannot be converted into a float.",e); + } + } else if ( src instanceof DoubleFieldSource || src instanceof SingleDoubleFunction || + src instanceof DualDoubleFunction|| src instanceof MultiDoubleFunction) { + try { + defaultObject = new Double(arguments[1]); + } catch (NumberFormatException e) { + throw new SolrException(ErrorCode.BAD_REQUEST,"The filter value "+arguments[1]+" cannot be converted into a double.",e); + } + } else if ( src instanceof DateFieldSource || src instanceof MultiDateFunction) { + try { + defaultObject = TrieDateField.parseDate(arguments[1]); + } catch (ParseException e) { + throw new SolrException(ErrorCode.BAD_REQUEST,"The filter value "+arguments[1]+" cannot be converted into a date.",e); + } + } else { + defaultObject = arguments[1]; + } + return new FilterFieldSource(delegateSource,defaultObject); + } + + /** + * Recursively parses and breaks down the expression string to build a numeric ValueSource. + * + * @param schema The schema to pull fields from. + * @param expressionString The expression string to build a ValueSource from. + * @return The value source represented by the given expressionString + */ + private static ValueSource buildNumericSource(IndexSchema schema, String expressionString) { + int paren = expressionString.indexOf('('); + String[] arguments; + String operands; + if (paren<0) { + return buildFieldSource(schema,expressionString,NUMBER_TYPE); + } else { + try { + operands = expressionString.substring(paren+1, expressionString.lastIndexOf(')')).trim(); + } catch (Exception e) { + throw new SolrException(ErrorCode.BAD_REQUEST,"Missing closing parenthesis in ["+expressionString+"]"); + } + arguments = ExpressionFactory.getArguments(operands); + } + String operation = expressionString.substring(0, paren).trim(); + if (operation.equals(AnalyticsParams.CONSTANT_NUMBER)) { + if (arguments.length!=1) { + throw new SolrException(ErrorCode.BAD_REQUEST,"The constant number declaration ["+expressionString+"] does not have exactly 1 argument."); + } + return new ConstDoubleSource(Double.parseDouble(arguments[0])); + } else if (operation.equals(AnalyticsParams.NEGATE)) { + if (arguments.length!=1) { + throw new SolrException(ErrorCode.BAD_REQUEST,"The negate operation ["+expressionString+"] does not have exactly 1 argument."); + } + ValueSource argSource = buildNumericSource(schema, arguments[0]); + if (argSource==null) { + throw new SolrException(ErrorCode.BAD_REQUEST,"The operation \""+AnalyticsParams.NEGATE+"\" requires a numeric field or operation as argument. \""+arguments[0]+"\" is not a numeric field or operation."); + } + return new NegateDoubleFunction(argSource); + } else if (operation.equals(AnalyticsParams.ABSOLUTE_VALUE)) { + if (arguments.length!=1) { + throw new SolrException(ErrorCode.BAD_REQUEST,"The absolute value operation ["+expressionString+"] does not have exactly 1 argument."); + } + ValueSource argSource = buildNumericSource(schema, arguments[0]); + if (argSource==null) { + throw new SolrException(ErrorCode.BAD_REQUEST,"The operation \""+AnalyticsParams.NEGATE+"\" requires a numeric field or operation as argument. \""+arguments[0]+"\" is not a numeric field or operation."); + } + return new AbsoluteValueDoubleFunction(argSource); + } else if (operation.equals(AnalyticsParams.FILTER)) { + return buildFilterSource(schema, operands, NUMBER_TYPE); + } + List subExpressions = new ArrayList(); + for (String argument : arguments) { + ValueSource argSource = buildNumericSource(schema, argument); + if (argSource == null) { + throw new SolrException(ErrorCode.BAD_REQUEST,"The operation \""+operation+"\" requires numeric fields or operations as arguments. \""+argument+"\" is not a numeric field or operation."); + } + subExpressions.add(argSource); + } + if (operation.equals(AnalyticsParams.ADD)) { + return new AddDoubleFunction(subExpressions.toArray(new ValueSource[0])); + } else if (operation.equals(AnalyticsParams.MULTIPLY)) { + return new MultiplyDoubleFunction(subExpressions.toArray(new ValueSource[0])); + } else if (operation.equals(AnalyticsParams.DIVIDE)) { + if (subExpressions.size()!=2) { + throw new SolrException(ErrorCode.BAD_REQUEST,"The divide operation ["+expressionString+"] does not have exactly 2 arguments."); + } + return new DivDoubleFunction(subExpressions.get(0),subExpressions.get(1)); + } else if (operation.equals(AnalyticsParams.POWER)) { + if (subExpressions.size()!=2) { + throw new SolrException(ErrorCode.BAD_REQUEST,"The power operation ["+expressionString+"] does not have exactly 2 arguments."); + } + return new PowDoubleFunction(subExpressions.get(0),subExpressions.get(1)); + } else if (operation.equals(AnalyticsParams.LOG)) { + if (subExpressions.size()!=2) { + throw new SolrException(ErrorCode.BAD_REQUEST,"The log operation ["+expressionString+"] does not have exactly 2 arguments."); + } + return new LogDoubleFunction(subExpressions.get(0), subExpressions.get(1)); + } + if (AnalyticsParams.DATE_OPERATION_SET.contains(operation)||AnalyticsParams.STRING_OPERATION_SET.contains(operation)) { + return null; + } + throw new SolrException(ErrorCode.BAD_REQUEST,"The operation ["+expressionString+"] is not supported."); + } + + + /** + * Recursively parses and breaks down the expression string to build a date ValueSource. + * + * @param schema The schema to pull fields from. + * @param expressionString The expression string to build a ValueSource from. + * @return The value source represented by the given expressionString + */ + @SuppressWarnings("deprecation") + private static ValueSource buildDateSource(IndexSchema schema, String expressionString) { + int paren = expressionString.indexOf('('); + String[] arguments; + if (paren<0) { + return buildFieldSource(schema, expressionString, DATE_TYPE); + } else { + arguments = ExpressionFactory.getArguments(expressionString.substring(paren+1, expressionString.lastIndexOf(')')).trim()); + } + String operands = arguments[0]; + String operation = expressionString.substring(0, paren).trim(); + if (operation.equals(AnalyticsParams.CONSTANT_DATE)) { + if (arguments.length!=1) { + throw new SolrException(ErrorCode.BAD_REQUEST,"The constant date declaration ["+expressionString+"] does not have exactly 1 argument."); + } + try { + return new ConstDateSource(TrieDateField.parseDate(operands)); + } catch (ParseException e) { + throw new SolrException(ErrorCode.BAD_REQUEST,"The constant "+operands+" cannot be converted into a date.",e); + } + } else if (operation.equals(AnalyticsParams.FILTER)) { + return buildFilterSource(schema, operands, DATE_TYPE); + } + if (operation.equals(AnalyticsParams.DATE_MATH)) { + List subExpressions = new ArrayList(); + boolean first = true; + for (String argument : arguments) { + ValueSource argSource; + if (first) { + first = false; + argSource = buildDateSource(schema, argument); + if (argSource == null) { + throw new SolrException(ErrorCode.BAD_REQUEST,"\""+AnalyticsParams.DATE_MATH+"\" requires the first argument be a date operation or field. ["+argument+"] is not a date operation or field."); + } + } else { + argSource = buildStringSource(schema, argument); + if (argSource == null) { + throw new SolrException(ErrorCode.BAD_REQUEST,"\""+AnalyticsParams.DATE_MATH+"\" requires that all arguments except the first be string operations. ["+argument+"] is not a string operation."); + } + } + subExpressions.add(argSource); + } + return new DateMathFunction(subExpressions.toArray(new ValueSource[0])); + } + if (AnalyticsParams.NUMERIC_OPERATION_SET.contains(operation)||AnalyticsParams.STRING_OPERATION_SET.contains(operation)) { + return null; + } + throw new SolrException(ErrorCode.BAD_REQUEST,"The operation ["+expressionString+"] is not supported."); + } + + + /** + * Recursively parses and breaks down the expression string to build a string ValueSource. + * + * @param schema The schema to pull fields from. + * @param expressionString The expression string to build a ValueSource from. + * @return The value source represented by the given expressionString + */ + private static ValueSource buildStringSource(IndexSchema schema, String expressionString) { + int paren = expressionString.indexOf('('); + String[] arguments; + if (paren<0) { + return buildFieldSource(schema, expressionString, FIELD_TYPE); + } else { + arguments = ExpressionFactory.getArguments(expressionString.substring(paren+1, expressionString.lastIndexOf(')')).trim()); + } + String operands = arguments[0]; + String operation = expressionString.substring(0, paren).trim(); + if (operation.equals(AnalyticsParams.CONSTANT_STRING)) { + operands = expressionString.substring(paren+1, expressionString.lastIndexOf(')')); + return new ConstStringSource(operands); + } else if (operation.equals(AnalyticsParams.FILTER)) { + return buildFilterSource(schema,operands,FIELD_TYPE); + } else if (operation.equals(AnalyticsParams.REVERSE)) { + if (arguments.length!=1) { + throw new SolrException(ErrorCode.BAD_REQUEST,"\""+AnalyticsParams.REVERSE+"\" requires exactly one argument. The number of arguments in "+expressionString+" is not 1."); + } + return new ReverseStringFunction(buildStringSource(schema, operands)); + } + List subExpressions = new ArrayList(); + for (String argument : arguments) { + subExpressions.add(buildSourceTree(schema, argument)); + } + if (operation.equals(AnalyticsParams.CONCATENATE)) { + return new ConcatStringFunction(subExpressions.toArray(new ValueSource[0])); + } + if (AnalyticsParams.NUMERIC_OPERATION_SET.contains(operation)) { + return buildNumericSource(schema, expressionString); + } else if (AnalyticsParams.DATE_OPERATION_SET.contains(operation)) { + return buildDateSource(schema, expressionString); + } + throw new SolrException(ErrorCode.BAD_REQUEST,"The operation ["+expressionString+"] is not supported."); + } +} diff --git a/solr/core/src/java/org/apache/solr/analytics/statistics/UniqueStatsCollector.java b/solr/core/src/java/org/apache/solr/analytics/statistics/UniqueStatsCollector.java new file mode 100644 index 00000000000..ca8d2ab47fb --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/statistics/UniqueStatsCollector.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.statistics; + +import java.util.HashSet; +import java.util.Set; + +/** + * UniqueValueCounter computes the number of unique values. + */ +public class UniqueStatsCollector extends AbstractDelegatingStatsCollector{ + private final Set uniqueValues = new HashSet(); + + public UniqueStatsCollector(StatsCollector delegate) { + super(delegate); + } + + @Override + public void collect(int doc) { + super.collect(doc); + if (value.exists) { + uniqueValues.add(value.toObject()); + } + } + + @Override + public Comparable getStat(String stat) { + if (stat.equals("unique")) { + return new Long(uniqueValues.size()); + } + return delegate.getStat(stat); + } + + @Override + public void compute() { + delegate.compute(); + } +} diff --git a/solr/core/src/java/org/apache/solr/analytics/statistics/package.html b/solr/core/src/java/org/apache/solr/analytics/statistics/package.html new file mode 100644 index 00000000000..99539fc28ed --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/statistics/package.html @@ -0,0 +1,27 @@ + + + + + + + +

    +Statistics collectors reduce a list of Objects to a single value. Most implementations reduce a list to a statistic on that list. +

    + + diff --git a/solr/core/src/java/org/apache/solr/analytics/util/AnalyticsParams.java b/solr/core/src/java/org/apache/solr/analytics/util/AnalyticsParams.java new file mode 100644 index 00000000000..d7f220a22b8 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/util/AnalyticsParams.java @@ -0,0 +1,114 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.util; + +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import org.apache.solr.common.params.FacetParams.FacetRangeInclude; +import org.apache.solr.common.params.FacetParams.FacetRangeOther; + +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; + +public interface AnalyticsParams { + // Full length Analytics Params + public static final String ANALYTICS = "olap"; + + public static final String REQUEST = "o|olap"; + + public static final String EXPRESSION = "s|stat|statistic"; + public static final String HIDDEN_EXPRESSION = "hs|hiddenstat|hiddenstatistic"; + + public static final String FIELD_FACET = "ff|fieldfacet"; + public static final String LIMIT = "l|limit"; + public static final String OFFSET = "off|offset"; + public static final String HIDDEN = "h|hidden"; + public static final String SHOW_MISSING = "sm|showmissing"; + public static final String SORT_STATISTIC ="ss|sortstat|sortstatistic"; + public static final String SORT_DIRECTION ="sd|sortdirection"; + + public static final String RANGE_FACET = "rf|rangefacet"; + public static final String START = "st|start"; + public static final String END = "e|end"; + public static final String GAP = "g|gap"; + public static final String HARDEND = "he|hardend"; + public static final String INCLUDE_BOUNDARY = "ib|includebound"; + public static final String OTHER_RANGE = "or|otherrange"; + + public static final String QUERY_FACET = "qf|queryfacet"; + public static final String DEPENDENCY = "d|dependecy"; + public static final String QUERY = "q|query"; + + //Defaults + public static final boolean DEFAULT_ABBREVIATE_PREFIX = true; + public static final String DEFAULT_SORT_DIRECTION = "ascending"; + public static final int DEFAULT_LIMIT = -1; + public static final boolean DEFAULT_HIDDEN = false; + public static final boolean DEFAULT_HARDEND = false; + public static final boolean DEFAULT_SHOW_MISSING = false; + public static final FacetRangeInclude DEFAULT_INCLUDE = FacetRangeInclude.LOWER; + public static final FacetRangeOther DEFAULT_OTHER = FacetRangeOther.NONE; + + // Statistic Function Names (Cannot share names with ValueSource & Expression Functions) + public static final String STAT_COUNT = "count"; + public static final String STAT_MISSING = "missing"; + public static final String STAT_SUM = "sum"; + public static final String STAT_SUM_OF_SQUARES = "sumofsquares"; + public static final String STAT_STANDARD_DEVIATION = "stddev"; + public static final String STAT_MEAN = "mean"; + public static final String STAT_UNIQUE = "unique"; + public static final String STAT_MEDIAN = "median"; + public static final String STAT_PERCENTILE = "percentile"; + public static final String STAT_MIN = "min"; + public static final String STAT_MAX = "max"; + + public static final List ALL_STAT_LIST = Collections.unmodifiableList(Lists.newArrayList(STAT_COUNT, STAT_MISSING, STAT_SUM, STAT_SUM_OF_SQUARES, STAT_STANDARD_DEVIATION, STAT_MEAN, STAT_UNIQUE, STAT_MEDIAN, STAT_PERCENTILE,STAT_MIN,STAT_MAX)); + public static final Set ALL_STAT_SET = Collections.unmodifiableSet(Sets.newLinkedHashSet(ALL_STAT_LIST)); + + // ValueSource & Expression Function Names (Cannot share names with Statistic Functions) + // No specific type + final static String FILTER = "filter"; + final static String RESULT = "result"; + final static String QUERY_RESULT = "qresult"; + + // Numbers + final static String CONSTANT_NUMBER = "const_num"; + final static String NEGATE = "neg"; + final static String ABSOLUTE_VALUE = "abs"; + final static String LOG = "log"; + final static String ADD = "add"; + final static String MULTIPLY = "mult"; + final static String DIVIDE = "div"; + final static String POWER = "pow"; + public static final Set NUMERIC_OPERATION_SET = Collections.unmodifiableSet(Sets.newLinkedHashSet(Lists.newArrayList(CONSTANT_NUMBER,NEGATE,ABSOLUTE_VALUE,LOG,ADD,MULTIPLY,DIVIDE,POWER))); + + // Dates + final static String CONSTANT_DATE = "const_date"; + final static String DATE_MATH = "date_math"; + public static final Set DATE_OPERATION_SET = Collections.unmodifiableSet(Sets.newLinkedHashSet(Lists.newArrayList(CONSTANT_DATE,DATE_MATH))); + + //Strings + final static String CONSTANT_STRING = "const_str"; + final static String REVERSE = "rev"; + final static String CONCATENATE = "concat"; + public static final Set STRING_OPERATION_SET = Collections.unmodifiableSet(Sets.newLinkedHashSet(Lists.newArrayList(CONSTANT_STRING,REVERSE,CONCATENATE))); + + // Field Source Wrappers +} diff --git a/solr/core/src/java/org/apache/solr/analytics/util/AnalyticsParsers.java b/solr/core/src/java/org/apache/solr/analytics/util/AnalyticsParsers.java new file mode 100644 index 00000000000..b27fe702585 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/util/AnalyticsParsers.java @@ -0,0 +1,200 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.util; + +import java.io.IOException; +import java.text.ParseException; +import java.util.Arrays; +import java.util.Date; + +import org.apache.lucene.index.Terms; +import org.apache.lucene.index.TermsEnum; +import org.apache.lucene.search.FieldCache; +import org.apache.lucene.search.FieldCache.LongParser; +import org.apache.lucene.util.BytesRef; +import org.apache.lucene.util.NumericUtils; +import org.apache.solr.schema.FieldType; +import org.apache.solr.schema.TrieDateField; +import org.apache.solr.schema.TrieDoubleField; +import org.apache.solr.schema.TrieFloatField; +import org.apache.solr.schema.TrieIntField; +import org.apache.solr.schema.TrieLongField; + +/** + * Class to hold the parsers used for Solr Analytics. + */ +public class AnalyticsParsers { + + /** + * Returns a parser that will translate a BytesRef or long from DocValues into + * a String that correctly represents the value. + * @param class1 class of the FieldType of the field being faceted on. + * @return A Parser + */ + public static Parser getParser(Class class1) { + if (class1.equals(TrieIntField.class)) { + return AnalyticsParsers.INT_DOC_VALUES_PARSER; + } else if (class1.equals(TrieLongField.class)) { + return AnalyticsParsers.LONG_DOC_VALUES_PARSER; + } else if (class1.equals(TrieFloatField.class)) { + return AnalyticsParsers.FLOAT_DOC_VALUES_PARSER; + } else if (class1.equals(TrieDoubleField.class)) { + return AnalyticsParsers.DOUBLE_DOC_VALUES_PARSER; + } else if (class1.equals(TrieDateField.class)) { + return AnalyticsParsers.DATE_DOC_VALUES_PARSER; + } else { + return AnalyticsParsers.STRING_PARSER; + } + } + + /** Long Parser that takes in String representations of dates and + * converts them into longs + */ + public final static LongParser DEFAULT_DATE_PARSER = new LongParser() { + @SuppressWarnings("deprecation") + @Override + public long parseLong(BytesRef term) { + try { + return TrieDateField.parseDate(term.utf8ToString()).getTime(); + } catch (ParseException e) { + System.err.println("Cannot parse date "+term.utf8ToString()); + return 0; + } + } + @Override + public String toString() { + return FieldCache.class.getName()+".DEFAULT_DATE_PARSER"; + } + @Override + public TermsEnum termsEnum(Terms terms) throws IOException { + return terms.iterator(null); + } + }; + + /** + * For use in classes that grab values by docValue. + * Converts a BytesRef object into the correct readable text. + */ + public static interface Parser { + String parse(BytesRef bytes) throws IOException; + } + + /** + * Converts the long returned by NumericDocValues into the + * correct number and return it as a string. + */ + public static interface NumericParser extends Parser { + String parseNum(long l); + } + + /** + * Converts the BytesRef or long to the correct int string. + */ + public static final NumericParser INT_DOC_VALUES_PARSER = new NumericParser() { + public String parse(BytesRef bytes) throws IOException { + try { + return ""+NumericUtils.prefixCodedToInt(bytes); + } catch (NumberFormatException e) { + throw new IOException("The byte array "+Arrays.toString(bytes.bytes)+" cannot be converted to an int."); + } + } + @Override + public String parseNum(long l) { + return ""+(int)l; + } + }; + + /** + * Converts the BytesRef or long to the correct long string. + */ + public static final NumericParser LONG_DOC_VALUES_PARSER = new NumericParser() { + public String parse(BytesRef bytes) throws IOException { + try { + return ""+NumericUtils.prefixCodedToLong(bytes); + } catch (NumberFormatException e) { + throw new IOException("The byte array "+Arrays.toString(bytes.bytes)+" cannot be converted to a long."); + } + } + @Override + public String parseNum(long l) { + return ""+l; + } + }; + + /** + * Converts the BytesRef or long to the correct float string. + */ + public static final NumericParser FLOAT_DOC_VALUES_PARSER = new NumericParser() { + public String parse(BytesRef bytes) throws IOException { + try { + return ""+NumericUtils.sortableIntToFloat(NumericUtils.prefixCodedToInt(bytes)); + } catch (NumberFormatException e) { + throw new IOException("The byte array "+Arrays.toString(bytes.bytes)+" cannot be converted to a float."); + } + } + @Override + public String parseNum(long l) { + return ""+NumericUtils.sortableIntToFloat((int)l); + } + }; + + /** + * Converts the BytesRef or long to the correct double string. + */ + public static final NumericParser DOUBLE_DOC_VALUES_PARSER = new NumericParser() { + public String parse(BytesRef bytes) throws IOException { + try { + return ""+NumericUtils.sortableLongToDouble(NumericUtils.prefixCodedToLong(bytes)); + } catch (NumberFormatException e) { + throw new IOException("The byte array "+Arrays.toString(bytes.bytes)+" cannot be converted to a double."); + } + } + @Override + public String parseNum(long l) { + return ""+NumericUtils.sortableLongToDouble(l); + } + }; + + /** + * Converts the BytesRef or long to the correct date string. + */ + public static final NumericParser DATE_DOC_VALUES_PARSER = new NumericParser() { + @SuppressWarnings("deprecation") + public String parse(BytesRef bytes) throws IOException { + try { + return TrieDateField.formatExternal(new Date(NumericUtils.prefixCodedToLong(bytes))); + } catch (NumberFormatException e) { + throw new IOException("The byte array "+Arrays.toString(bytes.bytes)+" cannot be converted to a date."); + } + } + @SuppressWarnings("deprecation") + @Override + public String parseNum(long l) { + return ""+TrieDateField.formatExternal(new Date(l)); + } + }; + + /** + * Converts the BytesRef to the correct string. + */ + public static final Parser STRING_PARSER = new Parser() { + public String parse(BytesRef bytes) { + return bytes.utf8ToString(); + } + }; +} diff --git a/solr/core/src/java/org/apache/solr/analytics/util/MedianCalculator.java b/solr/core/src/java/org/apache/solr/analytics/util/MedianCalculator.java new file mode 100644 index 00000000000..48575977939 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/util/MedianCalculator.java @@ -0,0 +1,128 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.util; + +import java.util.List; + +public class MedianCalculator { + + /** + * Calculates the median of the given list of numbers. + * + * @param list A list of {@link Comparable} {@link Number} objects + * @return The median of the given list as a double. + */ + public static > double getMedian(List list) { + int size = list.size() - 1; + if (size == -1) { + return 0; + } + + select(list, .5 * size, 0, size); + + int firstIdx = (int) (Math.floor(.5 * size)); + int secondIdx = (firstIdx <= size && size % 2 == 1) ? firstIdx + 1 : firstIdx; + double result = list.get(firstIdx).doubleValue() * .5 + list.get(secondIdx).doubleValue() * .5; + + return result; + } + + private static > void select(List list, double place, int begin, int end) { + T split; + if (end - begin < 10) { + split = list.get((int) (Math.random() * (end - begin + 1)) + begin); + } else { + split = split(list, begin, end); + } + + Point result = partition(list, begin, end, split); + + if (place < result.low) { + select(list, place, begin, result.low); + } else if (place > result.high) { + select(list, place, result.high, end); + } else { + if (result.low == (int) (Math.floor(place)) && result.low > begin) { + select(list, result.low, begin, result.low); + } + if (result.high == (int) (Math.ceil(place)) && result.high < end) { + select(list, result.high, result.high, end); + } + } + } + + private static > T split(List list, int begin, int end) { + T temp; + int num = (end - begin + 1); + int recursiveSize = (int) Math.sqrt((double) num); + int step = num / recursiveSize; + for (int i = 1; i < recursiveSize; i++) { + int swapFrom = i * step + begin; + int swapTo = i + begin; + temp = list.get(swapFrom); + list.set(swapFrom, list.get(swapTo)); + list.set(swapTo, temp); + } + recursiveSize--; + select(list, recursiveSize / 2 + begin, begin, recursiveSize + begin); + return list.get(recursiveSize / 2 + begin); + } + + private static > Point partition(List list, int begin, int end, T indexElement) { + T temp; + int left, right; + for (left = begin, right = end; left < right; left++, right--) { + while (list.get(left).compareTo(indexElement) < 0) { + left++; + } + while (right != begin - 1 && list.get(right).compareTo(indexElement) >= 0) { + right--; + } + if (right <= left) { + left--; + right++; + break; + } + temp = list.get(left); + list.set(left, list.get(right)); + list.set(right, temp); + } + while (left != begin - 1 && list.get(left).compareTo(indexElement) >= 0) { + left--; + } + while (right != end + 1 && list.get(right).compareTo(indexElement) <= 0) { + right++; + } + int rightMove = right + 1; + while (rightMove < end + 1) { + if (list.get(rightMove).equals(indexElement)) { + temp = list.get(rightMove); + list.set(rightMove, list.get(right)); + list.set(right, temp); + do { + right++; + } while (list.get(right).equals(indexElement)); + if (rightMove <= right) { + rightMove = right; + } + } + rightMove++; + } + return new Point(left, right); + } +} diff --git a/solr/core/src/java/org/apache/solr/analytics/util/PercentileCalculator.java b/solr/core/src/java/org/apache/solr/analytics/util/PercentileCalculator.java new file mode 100644 index 00000000000..a98ed0c4d8e --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/util/PercentileCalculator.java @@ -0,0 +1,177 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.util; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class PercentileCalculator { + /** + * Calculates a list of percentile values for a given list of objects and percentiles. + * + * @param list The list of {@link Comparable} objects to calculate the percentiles of. + * @param percents The array of percentiles (.01 to .99) to calculate. + * @return a list of comparables + */ + public static > List getPercentiles(List list, double[] percents) { + int size = list.size(); + if (size == 0) { + return null; + } + + int[] percs = new int[percents.length]; + for (int i = 0; i < percs.length; i++) { + percs[i] = (int) Math.round(percents[i] * size - .5); + } + int[] percentiles = Arrays.copyOf(percs, percs.length); + Arrays.sort(percentiles); + + if (percentiles[0] < 0 || percentiles[percentiles.length - 1] > size - 1) { + throw new IllegalArgumentException(); + } + + List results = new ArrayList(percs.length); + + distributeAndFind(list, percentiles, 0, percentiles.length - 1); + + for (int i = 0; i < percs.length; i++) { + results.add(list.get(percs[i])); + } + return results; + } + + private static > void distributeAndFind(List list, int[] percentiles, int beginIdx, int endIdx) { + if (endIdx < beginIdx) { + return; + } + int middleIdxb = beginIdx; + int middleIdxe = beginIdx; + int begin = (beginIdx == 0) ? -1 : percentiles[beginIdx - 1]; + int end = (endIdx == percentiles.length - 1) ? list.size() : percentiles[endIdx + 1]; + double middle = (begin + end) / 2.0; + for (int i = beginIdx; i <= endIdx; i++) { + double value = Math.abs(percentiles[i] - middle) - Math.abs(percentiles[middleIdxb] - middle); + if (percentiles[i] == percentiles[middleIdxb]) { + middleIdxe = i; + } else if (value < 0) { + middleIdxb = i; + do { + middleIdxe = i; + i++; + } while (i <= endIdx && percentiles[middleIdxb] == percentiles[i]); + break; + } + } + + int middlePlace = percentiles[middleIdxb]; + int beginPlace = begin + 1; + int endPlace = end - 1; + + select(list, middlePlace, beginPlace, endPlace); + distributeAndFind(list, percentiles, beginIdx, middleIdxb - 1); + distributeAndFind(list, percentiles, middleIdxe + 1, endIdx); + } + + private static > void select(List list, int place, int begin, int end) { + T split; + if (end - begin < 10) { + split = list.get((int) (Math.random() * (end - begin + 1)) + begin); + } else { + split = split(list, begin, end); + } + + Point result = partition(list, begin, end, split); + + if (place <= result.low) { + select(list, place, begin, result.low); + } else if (place >= result.high) { + select(list, place, result.high, end); + } + } + + private static > T split(List list, int begin, int end) { + T temp; + int num = (end - begin + 1); + int recursiveSize = (int) Math.sqrt((double) num); + int step = num / recursiveSize; + for (int i = 1; i < recursiveSize; i++) { + int swapFrom = i * step + begin; + int swapTo = i + begin; + temp = list.get(swapFrom); + list.set(swapFrom, list.get(swapTo)); + list.set(swapTo, temp); + } + recursiveSize--; + select(list, recursiveSize / 2 + begin, begin, recursiveSize + begin); + return list.get(recursiveSize / 2 + begin); + } + + private static > Point partition(List list, int begin, int end, T indexElement) { + T temp; + int left, right; + for (left = begin, right = end; left <= right; left++, right--) { + while (list.get(left).compareTo(indexElement) < 0) { + left++; + } + while (right != begin - 1 && list.get(right).compareTo(indexElement) >= 0) { + right--; + } + if (right <= left) { + left--; + right++; + break; + } + temp = list.get(left); + list.set(left, list.get(right)); + list.set(right, temp); + } + while (left > begin - 1 && list.get(left).compareTo(indexElement) >= 0) { + left--; + } + while (right < end + 1 && list.get(right).compareTo(indexElement) <= 0) { + right++; + } + int rightMove = right + 1; + while (rightMove < end + 1) { + if (list.get(rightMove).equals(indexElement)) { + temp = list.get(rightMove); + list.set(rightMove, list.get(right)); + list.set(right, temp); + do { + right++; + } while (list.get(right).equals(indexElement)); + if (rightMove <= right) { + rightMove = right; + } + } + rightMove++; + } + return new Point(left, right); + } +} + +class Point { + public int low; + public int high; + + public Point(int low, int high) { + this.low = low; + this.high = high; + } +} diff --git a/solr/core/src/java/org/apache/solr/analytics/util/RangeEndpointCalculator.java b/solr/core/src/java/org/apache/solr/analytics/util/RangeEndpointCalculator.java new file mode 100644 index 00000000000..50e45c0ce81 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/util/RangeEndpointCalculator.java @@ -0,0 +1,358 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.util; + +import java.util.ArrayList; +import java.util.Date; +import java.util.EnumSet; +import java.util.List; +import java.util.Set; + +import org.apache.solr.analytics.request.RangeFacetRequest; +import org.apache.solr.common.SolrException; +import org.apache.solr.common.params.FacetParams.FacetRangeInclude; +import org.apache.solr.common.params.FacetParams.FacetRangeOther; +import org.apache.solr.schema.DateField; +import org.apache.solr.schema.FieldType; +import org.apache.solr.schema.SchemaField; +import org.apache.solr.schema.TrieField; +import org.apache.solr.util.DateMathParser; + + +@SuppressWarnings("deprecation") +public abstract class RangeEndpointCalculator> { + protected final SchemaField field; + protected final RangeFacetRequest request; + + public RangeEndpointCalculator(final RangeFacetRequest request) { + this.field = request.getField(); + this.request = request; + } + + /** + * Formats a Range endpoint for use as a range label name in the response. + * Default Impl just uses toString() + */ + public String formatValue(final T val) { + return val.toString(); + } + + /** + * Parses a String param into an Range endpoint value throwing + * a useful exception if not possible + */ + public final T getValue(final String rawval) { + try { + return parseVal(rawval); + } catch (Exception e) { + throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Can't parse value "+rawval+" for field: " + field.getName(), e); + } + } + + /** + * Parses a String param into an Range endpoint. + * Can throw a low level format exception as needed. + */ + protected abstract T parseVal(final String rawval) throws java.text.ParseException; + + /** + * Parses a String param into a value that represents the gap and + * can be included in the response, throwing + * a useful exception if not possible. + * + * Note: uses Object as the return type instead of T for things like + * Date where gap is just a DateMathParser string + */ + public final Object getGap(final String gap) { + try { + return parseGap(gap); + } catch (Exception e) { + throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Can't parse gap "+gap+" for field: " + field.getName(), e); + } + } + + /** + * Parses a String param into a value that represents the gap and + * can be included in the response. + * Can throw a low level format exception as needed. + * + * Default Impl calls parseVal + */ + protected Object parseGap(final String rawval) throws java.text.ParseException { + return parseVal(rawval); + } + + /** + * Adds the String gap param to a low Range endpoint value to determine + * the corrisponding high Range endpoint value, throwing + * a useful exception if not possible. + */ + public final T addGap(T value, String gap) { + try { + return parseAndAddGap(value, gap); + } catch (Exception e) { + throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Can't add gap "+gap+" to value " + value + " for field: " + field.getName(), e); + } + } + + /** + * Adds the String gap param to a low Range endpoint value to determine + * the corrisponding high Range endpoint value. + * Can throw a low level format exception as needed. + */ + protected abstract T parseAndAddGap(T value, String gap) throws java.text.ParseException; + + public static class FacetRange { + public final String name; + public final String lower; + public final String upper; + public final boolean includeLower; + public final boolean includeUpper; + + public FacetRange(String name, String lower, String upper, boolean includeLower, boolean includeUpper) { + this.name = name; + this.lower = lower; + this.upper = upper; + this.includeLower = includeLower; + this.includeUpper = includeUpper; + } + } + + public List getRanges(){ + + final T start = getValue(request.getStart()); + T end = getValue(request.getEnd()); // not final, hardend may change this + + if( end.compareTo(start) < 0 ){ + throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "range facet 'end' comes before 'start': "+end+" < "+start); + } + + // explicitly return the gap. compute this early so we are more + // likely to catch parse errors before attempting math + final String[] gaps = request.getGaps(); + String gap = gaps[0]; + + final EnumSet include = request.getInclude(); + + T low = start; + + List ranges = new ArrayList(); + + int gapCounter = 0; + + while (low.compareTo(end) < 0) { + if (gapCounter> create(RangeFacetRequest request){ + final SchemaField sf = request.getField(); + final FieldType ft = sf.getType(); + final RangeEndpointCalculator calc; + if (ft instanceof TrieField) { + final TrieField trie = (TrieField)ft; + switch (trie.getType()) { + case FLOAT: + calc = new FloatRangeEndpointCalculator(request); + break; + case DOUBLE: + calc = new DoubleRangeEndpointCalculator(request); + break; + case INTEGER: + calc = new IntegerRangeEndpointCalculator(request); + break; + case LONG: + calc = new LongRangeEndpointCalculator(request); + break; + default: + throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Unable to range facet on tried field of unexpected type:" + sf.getName()); + } + } else if (ft instanceof DateField) { + calc = new DateRangeEndpointCalculator(request, null); + } else { + throw new SolrException (SolrException.ErrorCode.BAD_REQUEST, "Unable to range facet on field:" + sf); + } + return calc; + } + + public static class FloatRangeEndpointCalculator extends RangeEndpointCalculator { + + public FloatRangeEndpointCalculator(final RangeFacetRequest request) { super(request); } + + @Override + protected Float parseVal(String rawval) { + return Float.valueOf(rawval); + } + + @Override + public Float parseAndAddGap(Float value, String gap) { + return new Float(value.floatValue() + Float.valueOf(gap).floatValue()); + } + + } + + public static class DoubleRangeEndpointCalculator extends RangeEndpointCalculator { + + public DoubleRangeEndpointCalculator(final RangeFacetRequest request) { super(request); } + + @Override + protected Double parseVal(String rawval) { + return Double.valueOf(rawval); + } + + @Override + public Double parseAndAddGap(Double value, String gap) { + return new Double(value.doubleValue() + Double.valueOf(gap).doubleValue()); + } + + } + + public static class IntegerRangeEndpointCalculator extends RangeEndpointCalculator { + + public IntegerRangeEndpointCalculator(final RangeFacetRequest request) { super(request); } + + @Override + protected Integer parseVal(String rawval) { + return Integer.valueOf(rawval); + } + + @Override + public Integer parseAndAddGap(Integer value, String gap) { + return new Integer(value.intValue() + Integer.valueOf(gap).intValue()); + } + + } + + public static class LongRangeEndpointCalculator extends RangeEndpointCalculator { + + public LongRangeEndpointCalculator(final RangeFacetRequest request) { super(request); } + + @Override + protected Long parseVal(String rawval) { + return Long.valueOf(rawval); + } + + @Override + public Long parseAndAddGap(Long value, String gap) { + return new Long(value.longValue() + Long.valueOf(gap).longValue()); + } + + } + + public static class DateRangeEndpointCalculator extends RangeEndpointCalculator { + private final Date now; + public DateRangeEndpointCalculator(final RangeFacetRequest request, final Date now) { + super(request); + this.now = now; + if (! (field.getType() instanceof DateField) ) { + throw new IllegalArgumentException("SchemaField must use filed type extending DateField"); + } + } + + @Override + @SuppressWarnings("deprecation") + public String formatValue(Date val) { + return ((DateField)field.getType()).toExternal(val); + } + + @Override + @SuppressWarnings("deprecation") + protected Date parseVal(String rawval) { + return ((DateField)field.getType()).parseMath(now, rawval); + } + + @Override + protected Object parseGap(final String rawval) { + return rawval; + } + + @Override + public Date parseAndAddGap(Date value, String gap) throws java.text.ParseException { + final DateMathParser dmp = new DateMathParser(); + dmp.setNow(value); + return dmp.parseMath(gap); + } + + } +} diff --git a/solr/core/src/java/org/apache/solr/analytics/util/package.html b/solr/core/src/java/org/apache/solr/analytics/util/package.html new file mode 100644 index 00000000000..3cc6e4a335a --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/util/package.html @@ -0,0 +1,27 @@ + + + + + + + +

    +Utilities used by analytics component +

    + + diff --git a/solr/core/src/java/org/apache/solr/analytics/util/valuesource/AbsoluteValueDoubleFunction.java b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/AbsoluteValueDoubleFunction.java new file mode 100644 index 00000000000..f42924875d6 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/AbsoluteValueDoubleFunction.java @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.util.valuesource; + +import org.apache.lucene.queries.function.FunctionValues; +import org.apache.lucene.queries.function.ValueSource; +import org.apache.solr.analytics.util.AnalyticsParams; + +/** + * AbsoluteValueDoubleFunction takes the absolute value of the double value of the source it contains. + */ +public class AbsoluteValueDoubleFunction extends SingleDoubleFunction { + public final static String NAME = AnalyticsParams.ABSOLUTE_VALUE; + + public AbsoluteValueDoubleFunction(ValueSource source) { + super(source); + } + + protected String name() { + return NAME; + } + + @Override + public String description() { + return name()+"("+source.description()+")"; + } + + protected double func(int doc, FunctionValues vals) { + double d = vals.doubleVal(doc); + if (d<0) { + return d*-1; + } else { + return d; + } + } + + @Override + public boolean equals(Object o) { + if (getClass() != o.getClass()) return false; + AbsoluteValueDoubleFunction other = (AbsoluteValueDoubleFunction)o; + return this.source.equals(other.source); + } + +} diff --git a/solr/core/src/java/org/apache/solr/analytics/util/valuesource/AddDoubleFunction.java b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/AddDoubleFunction.java new file mode 100644 index 00000000000..7784febd053 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/AddDoubleFunction.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.util.valuesource; + +import org.apache.lucene.queries.function.FunctionValues; +import org.apache.lucene.queries.function.ValueSource; +import org.apache.solr.analytics.util.AnalyticsParams; + +/** + * AddDoubleFunction returns the sum of it's components. + */ +public class AddDoubleFunction extends MultiDoubleFunction { + public final static String NAME = AnalyticsParams.ADD; + + public AddDoubleFunction(ValueSource[] sources) { + super(sources); + } + + @Override + protected String name() { + return NAME; + } + + @Override + protected double func(int doc, FunctionValues[] valsArr) { + double sum = 0d; + for (FunctionValues val : valsArr) { + sum += val.doubleVal(doc); + } + return sum; + } + +} diff --git a/solr/core/src/java/org/apache/solr/analytics/util/valuesource/ConcatStringFunction.java b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/ConcatStringFunction.java new file mode 100644 index 00000000000..97537a7619e --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/ConcatStringFunction.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.util.valuesource; + +import org.apache.lucene.queries.function.FunctionValues; +import org.apache.lucene.queries.function.ValueSource; +import org.apache.solr.analytics.util.AnalyticsParams; + +/** + * ConcatStringFunction concatenates the string values of its + * components in the order given. + */ +public class ConcatStringFunction extends MultiStringFunction { + public final static String NAME = AnalyticsParams.CONCATENATE; + + public ConcatStringFunction(ValueSource[] sources) { + super(sources); + } + + protected String name() { + return NAME; + } + + @Override + protected String func(int doc, FunctionValues[] valsArr) { + StringBuilder sb = new StringBuilder(); + for (FunctionValues val : valsArr) { + String v = val.strVal(doc); + if(v == null){ + return null; + } else { + sb.append(v); + } + } + return sb.toString(); + } + +} diff --git a/solr/core/src/java/org/apache/solr/analytics/util/valuesource/ConstDateSource.java b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/ConstDateSource.java new file mode 100644 index 00000000000..1ed8ca77705 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/ConstDateSource.java @@ -0,0 +1,114 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.util.valuesource; + +import java.io.IOException; +import java.text.ParseException; +import java.util.Date; +import java.util.Map; + +import org.apache.lucene.index.AtomicReaderContext; +import org.apache.lucene.queries.function.FunctionValues; +import org.apache.lucene.queries.function.docvalues.FloatDocValues; +import org.apache.lucene.util.mutable.MutableValue; +import org.apache.lucene.util.mutable.MutableValueDate; +import org.apache.solr.analytics.util.AnalyticsParams; +import org.apache.solr.schema.TrieDateField; + +/** + * ConstDateSource returns a constant date for all documents + */ +public class ConstDateSource extends ConstDoubleSource { + public final static String NAME = AnalyticsParams.CONSTANT_DATE; + + public ConstDateSource(Date constant) throws ParseException { + super(constant.getTime()); + } + + public ConstDateSource(Long constant) { + super(constant); + } + + @SuppressWarnings("deprecation") + @Override + public String description() { + return name()+"(" + TrieDateField.formatExternal(new Date(getLong())) + ")"; + } + + protected String name() { + return NAME; + } + + @Override + public FunctionValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { + return new FloatDocValues(this) { + @Override + public float floatVal(int doc) { + return getFloat(); + } + @Override + public int intVal(int doc) { + return getInt(); + } + @Override + public long longVal(int doc) { + return getLong(); + } + @Override + public double doubleVal(int doc) { + return getDouble(); + } + @Override + public String toString(int doc) { + return description(); + } + @Override + public Object objectVal(int doc) { + return new Date(longVal(doc)); + } + @SuppressWarnings("deprecation") + @Override + public String strVal(int doc) { + return TrieDateField.formatExternal(new Date(longVal(doc))); + } + @Override + public boolean boolVal(int doc) { + return getFloat() != 0.0f; + } + + @Override + public ValueFiller getValueFiller() { + return new ValueFiller() { + private final MutableValueDate mval = new MutableValueDate(); + + @Override + public MutableValue getValue() { + return mval; + } + + @Override + public void fillValue(int doc) { + mval.value = longVal(doc); + mval.exists = true; + } + }; + } + }; + } + +} diff --git a/solr/core/src/java/org/apache/solr/analytics/util/valuesource/ConstDoubleSource.java b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/ConstDoubleSource.java new file mode 100644 index 00000000000..63110867b85 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/ConstDoubleSource.java @@ -0,0 +1,106 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.util.valuesource; + +import java.io.IOException; +import java.util.Map; + +import org.apache.lucene.index.AtomicReaderContext; +import org.apache.lucene.queries.function.FunctionValues; +import org.apache.lucene.queries.function.docvalues.DoubleDocValues; +import org.apache.lucene.queries.function.valuesource.ConstNumberSource; +import org.apache.lucene.queries.function.valuesource.ConstValueSource; +import org.apache.solr.analytics.util.AnalyticsParams; + +/** + * ConstDoubleSource returns a constant double for all documents + */ +public class ConstDoubleSource extends ConstNumberSource { + public final static String NAME = AnalyticsParams.CONSTANT_NUMBER; + final double constant; + + public ConstDoubleSource(double constant) { + this.constant = constant; + } + + @Override + public String description() { + return name()+"(" + getFloat() + ")"; + } + + protected String name() { + return NAME; + } + + @Override + public FunctionValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { + return new DoubleDocValues(this) { + @Override + public double doubleVal(int doc) { + return constant; + } + @Override + public boolean exists(int doc) { + return true; + } + }; + } + + @Override + public int hashCode() { + return (int)Double.doubleToLongBits(constant) * 31; + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof ConstValueSource)) return false; + ConstDoubleSource other = (ConstDoubleSource)o; + return this.constant == other.constant; + } + + @Override + public int getInt() { + return (int)constant; + } + + @Override + public long getLong() { + return (long)constant; + } + + @Override + public float getFloat() { + return (float)constant; + } + + @Override + public double getDouble() { + return constant; + } + + @Override + public Number getNumber() { + return new Double(constant); + } + + @Override + public boolean getBool() { + return constant != 0.0f; + } + +} diff --git a/solr/core/src/java/org/apache/solr/analytics/util/valuesource/ConstStringSource.java b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/ConstStringSource.java new file mode 100644 index 00000000000..c2c9af78e7f --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/ConstStringSource.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.util.valuesource; + +import org.apache.lucene.queries.function.valuesource.LiteralValueSource; +import org.apache.solr.analytics.util.AnalyticsParams; + +/** + * ConstStringSource returns a constant string for all documents + */ +public class ConstStringSource extends LiteralValueSource { + public final static String NAME = AnalyticsParams.CONSTANT_STRING; + + public ConstStringSource(String string) { + super(string); + } + + @Override + public String description() { + return name()+"(" + string + ")"; + } + + protected String name() { + return NAME; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof ConstStringSource)) return false; + ConstStringSource that = (ConstStringSource) o; + + return getValue().equals(that.getValue()); + } + +} diff --git a/solr/core/src/java/org/apache/solr/analytics/util/valuesource/DateFieldSource.java b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/DateFieldSource.java new file mode 100644 index 00000000000..2b0dbae72e4 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/DateFieldSource.java @@ -0,0 +1,127 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.util.valuesource; + +import java.io.IOException; +import java.text.ParseException; +import java.util.Date; +import java.util.Map; + +import org.apache.lucene.index.AtomicReaderContext; +import org.apache.lucene.queries.function.FunctionValues; +import org.apache.lucene.queries.function.docvalues.LongDocValues; +import org.apache.lucene.queries.function.valuesource.LongFieldSource; +import org.apache.lucene.search.FieldCache; +import org.apache.lucene.util.Bits; +import org.apache.lucene.util.BytesRef; +import org.apache.lucene.util.mutable.MutableValue; +import org.apache.lucene.util.mutable.MutableValueDate; +import org.apache.solr.schema.TrieDateField; + +/** + * Extends {@link LongFieldSource} to have a field source that takes in + * and returns {@link Date} values while working with long values internally. + */ +public class DateFieldSource extends LongFieldSource { + + public DateFieldSource(String field) throws ParseException { + super(field, null); + } + + public DateFieldSource(String field, FieldCache.LongParser parser) { + super(field, parser); + } + + public long externalToLong(String extVal) { + return parser.parseLong(new BytesRef(extVal)); + } + + public Object longToObject(long val) { + return new Date(val); + } + + @SuppressWarnings("deprecation") + public String longToString(long val) { + return TrieDateField.formatExternal((Date)longToObject(val)); + } + + @Override + public FunctionValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { + final FieldCache.Longs arr = cache.getLongs(readerContext.reader(), field, parser, true); + final Bits valid = cache.getDocsWithField(readerContext.reader(), field); + return new LongDocValues(this) { + @Override + public long longVal(int doc) { + return arr.get(doc); + } + + @Override + public boolean exists(int doc) { + return valid.get(doc); + } + + @Override + public Object objectVal(int doc) { + return exists(doc) ? longToObject(arr.get(doc)) : null; + } + + @Override + public String strVal(int doc) { + return exists(doc) ? longToString(arr.get(doc)) : null; + } + + @Override + public ValueFiller getValueFiller() { + return new ValueFiller() { + private final MutableValueDate mval = new MutableValueDate(); + + @Override + public MutableValue getValue() { + return mval; + } + + @Override + public void fillValue(int doc) { + mval.value = arr.get(doc); + mval.exists = exists(doc); + } + }; + } + + }; + } + + @Override + public boolean equals(Object o) { + if (o.getClass() != this.getClass()) return false; + DateFieldSource other = (DateFieldSource) o; + if (parser==null) { + return field.equals(other.field); + } else { + return field.equals(other.field) && parser.equals(other.parser); + } + } + + @Override + public int hashCode() { + int h = parser == null ? this.getClass().hashCode() : parser.getClass().hashCode(); + h += super.hashCode(); + return h; + } + +} diff --git a/solr/core/src/java/org/apache/solr/analytics/util/valuesource/DateMathFunction.java b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/DateMathFunction.java new file mode 100644 index 00000000000..f2d4c4a858a --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/DateMathFunction.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.util.valuesource; + +import java.text.ParseException; +import java.util.Date; + +import org.apache.lucene.queries.function.FunctionValues; +import org.apache.lucene.queries.function.ValueSource; +import org.apache.lucene.queries.function.valuesource.BytesRefFieldSource; +import org.apache.solr.analytics.util.AnalyticsParams; +import org.apache.solr.util.DateMathParser; + +/** + * DateMathFunction returns a start date modified by a list of DateMath operations. + */ +public class DateMathFunction extends MultiDateFunction { + public final static String NAME = AnalyticsParams.DATE_MATH; + final private DateMathParser parser; + + /** + * @param sources A list of ValueSource objects. The first element in the list + * should be a {@link DateFieldSource} or {@link ConstDateSource} object which + * represents the starting date. The rest of the field should be {@link BytesRefFieldSource} + * or {@link ConstStringSource} objects which contain the DateMath operations to perform on + * the start date. + */ + public DateMathFunction(ValueSource[] sources) { + super(sources); + parser = new DateMathParser(); + } + + @Override + protected String name() { + return NAME; + } + + @Override + protected long func(int doc, FunctionValues[] valsArr) { + long time = 0; + Date date = (Date)valsArr[0].objectVal(doc); + try { + parser.setNow(date); + for (int count = 1; count < valsArr.length; count++) { + date = parser.parseMath(valsArr[count].strVal(doc)); + parser.setNow(date); + } + time = parser.getNow().getTime(); + } catch (ParseException e) { + e.printStackTrace(); + time = date.getTime(); + } + return time; + } + +} diff --git a/solr/core/src/java/org/apache/solr/analytics/util/valuesource/DivDoubleFunction.java b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/DivDoubleFunction.java new file mode 100644 index 00000000000..f029d79a351 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/DivDoubleFunction.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.util.valuesource; + +import org.apache.lucene.queries.function.FunctionValues; +import org.apache.lucene.queries.function.ValueSource; +import org.apache.solr.analytics.util.AnalyticsParams; + +/** + * DivDoubleFunction returns the quotient of 'a' and 'b'. + */ +public class DivDoubleFunction extends DualDoubleFunction { + public final static String NAME = AnalyticsParams.DIVIDE; + + /** + * @param a the numerator. + * @param b the denominator. + */ + public DivDoubleFunction(ValueSource a, ValueSource b) { + super(a, b); + } + + protected String name() { + return NAME; + } + + @Override + protected double func(int doc, FunctionValues aVals, FunctionValues bVals) { + return aVals.doubleVal(doc)/bVals.doubleVal(doc); + } + +} diff --git a/solr/core/src/java/org/apache/solr/analytics/util/valuesource/DualDoubleFunction.java b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/DualDoubleFunction.java new file mode 100644 index 00000000000..21f5edab710 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/DualDoubleFunction.java @@ -0,0 +1,95 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.util.valuesource; + +import java.io.IOException; +import java.util.Map; + +import org.apache.lucene.index.AtomicReaderContext; +import org.apache.lucene.queries.function.FunctionValues; +import org.apache.lucene.queries.function.ValueSource; +import org.apache.lucene.queries.function.docvalues.DoubleDocValues; +import org.apache.lucene.search.IndexSearcher; + +/** + * Abstract {@link ValueSource} implementation which wraps two ValueSources + * and applies an extendible double function to their values. + **/ +public abstract class DualDoubleFunction extends ValueSource { + protected final ValueSource a; + protected final ValueSource b; + + public DualDoubleFunction(ValueSource a, ValueSource b) { + this.a = a; + this.b = b; + } + + protected abstract String name(); + protected abstract double func(int doc, FunctionValues aVals, FunctionValues bVals); + + @Override + public String description() { + return name() + "(" + a.description() + "," + b.description() + ")"; + } + + @Override + public FunctionValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { + final FunctionValues aVals = a.getValues(context, readerContext); + final FunctionValues bVals = b.getValues(context, readerContext); + return new DoubleDocValues(this) { + @Override + public double doubleVal(int doc) { + return func(doc, aVals, bVals); + } + + @Override + public boolean exists(int doc) { + return aVals.exists(doc) & bVals.exists(doc); + } + + @Override + public String toString(int doc) { + return name() + '(' + aVals.toString(doc) + ',' + bVals.toString(doc) + ')'; + } + }; + } + + @Override + public void createWeight(Map context, IndexSearcher searcher) throws IOException { + a.createWeight(context,searcher); + b.createWeight(context,searcher); + } + + @Override + public boolean equals(Object o) { + if (getClass() != o.getClass()) return false; + DualDoubleFunction other = (DualDoubleFunction)o; + return this.a.equals(other.a) + && this.b.equals(other.b); + } + + @Override + public int hashCode() { + int h = a.hashCode(); + h ^= (h << 13) | (h >>> 20); + h += b.hashCode(); + h ^= (h << 23) | (h >>> 10); + h += name().hashCode(); + return h; + } +} diff --git a/solr/core/src/java/org/apache/solr/analytics/util/valuesource/FilterFieldSource.java b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/FilterFieldSource.java new file mode 100644 index 00000000000..33a9995845f --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/FilterFieldSource.java @@ -0,0 +1,156 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.util.valuesource; + +import java.io.IOException; +import java.util.Date; +import java.util.Map; + +import org.apache.lucene.index.AtomicReaderContext; +import org.apache.lucene.queries.function.FunctionValues; +import org.apache.lucene.queries.function.ValueSource; +import org.apache.lucene.util.mutable.MutableValue; +import org.apache.solr.analytics.util.AnalyticsParams; +import org.apache.solr.schema.TrieDateField; + +/** + * DefaultIsMissingFieldSource wraps a field source to return missing values + * if the value is equal to the default value. + */ +public class FilterFieldSource extends ValueSource { + public final static String NAME = AnalyticsParams.FILTER; + public final Object missValue; + protected final ValueSource source; + + public FilterFieldSource(ValueSource source, Object missValue) { + this.source = source; + this.missValue = missValue; + } + + protected String name() { + return NAME; + } + + @SuppressWarnings("deprecation") + @Override + public String description() { + if (missValue.getClass().equals(Date.class)) { + return name()+"("+source.description()+","+TrieDateField.formatExternal((Date)missValue)+")"; + } else { + return name()+"("+source.description()+","+missValue.toString()+")"; + } + } + + @Override + public FunctionValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { + final FunctionValues vals = source.getValues(context, readerContext); + return new FunctionValues() { + + @Override + public byte byteVal(int doc) { + return vals.byteVal(doc); + } + + @Override + public short shortVal(int doc) { + return vals.shortVal(doc); + } + + @Override + public float floatVal(int doc) { + return vals.floatVal(doc); + } + + @Override + public int intVal(int doc) { + return vals.intVal(doc); + } + + @Override + public long longVal(int doc) { + return vals.longVal(doc); + } + + @Override + public double doubleVal(int doc) { + return vals.doubleVal(doc); + } + + @Override + public String strVal(int doc) { + return vals.strVal(doc); + } + + @Override + public Object objectVal(int doc) { + return exists(doc)? vals.objectVal(doc) : null; + } + + @Override + public boolean exists(int doc) { + Object other = vals.objectVal(doc); + return other!=null&&!missValue.equals(other); + } + + @Override + public String toString(int doc) { + return NAME + '(' + vals.toString(doc) + ')'; + } + + @Override + public ValueFiller getValueFiller() { + return new ValueFiller() { + private final ValueFiller delegateFiller = vals.getValueFiller(); + private final MutableValue mval = delegateFiller.getValue(); + + @Override + public MutableValue getValue() { + return mval; + } + + @Override + public void fillValue(int doc) { + delegateFiller.fillValue(doc); + mval.exists = exists(doc); + } + }; + } + }; + } + + public ValueSource getRootSource() { + if (source instanceof FilterFieldSource) { + return ((FilterFieldSource)source).getRootSource(); + } else { + return source; + } + } + + @Override + public boolean equals(Object o) { + if (getClass() != o.getClass()) return false; + FilterFieldSource other = (FilterFieldSource)o; + return this.source.equals(other.source) && this.missValue.equals(other.missValue); + } + + @Override + public int hashCode() { + return source.hashCode()+name().hashCode(); + } + +} diff --git a/solr/core/src/java/org/apache/solr/analytics/util/valuesource/LogDoubleFunction.java b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/LogDoubleFunction.java new file mode 100644 index 00000000000..c4729a31ad8 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/LogDoubleFunction.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.util.valuesource; + +import org.apache.lucene.queries.function.FunctionValues; +import org.apache.lucene.queries.function.ValueSource; +import org.apache.solr.analytics.util.AnalyticsParams; + +/** + * LogDoubleFunction returns the log of a double value with a given base. + */ +public class LogDoubleFunction extends DualDoubleFunction { + public final static String NAME = AnalyticsParams.LOG; + + public LogDoubleFunction(ValueSource a, ValueSource b) { + super(a,b); + } + + protected String name() { + return NAME; + } + + @Override + protected double func(int doc, FunctionValues aVals, FunctionValues bVals) { + return Math.log(aVals.doubleVal(doc))/Math.log(bVals.doubleVal(doc)); + } +} diff --git a/solr/core/src/java/org/apache/solr/analytics/util/valuesource/MultiDateFunction.java b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/MultiDateFunction.java new file mode 100644 index 00000000000..1b51f6dbb38 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/MultiDateFunction.java @@ -0,0 +1,134 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.util.valuesource; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Map; + +import org.apache.lucene.index.AtomicReaderContext; +import org.apache.lucene.queries.function.FunctionValues; +import org.apache.lucene.queries.function.ValueSource; +import org.apache.lucene.queries.function.docvalues.LongDocValues; +import org.apache.lucene.util.mutable.MutableValue; +import org.apache.lucene.util.mutable.MutableValueDate; + +/** + * Abstract {@link ValueSource} implementation which wraps multiple ValueSources + * and applies an extendible date function to their values. + **/ +public abstract class MultiDateFunction extends ValueSource { + protected final ValueSource[] sources; + + public MultiDateFunction(ValueSource[] sources) { + this.sources = sources; + } + + abstract protected String name(); + abstract protected long func(int doc, FunctionValues[] valsArr); + + @Override + public String description() { + StringBuilder sb = new StringBuilder(); + sb.append(name()).append('('); + boolean firstTime=true; + for (ValueSource source : sources) { + if (firstTime) { + firstTime=false; + } else { + sb.append(','); + } + sb.append(source); + } + sb.append(')'); + return sb.toString(); + } + + @Override + public FunctionValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { + final FunctionValues[] valsArr = new FunctionValues[sources.length]; + for (int i=0; iMultiplyDoubleFunction returns the product of it's components. + */ +public class MultiplyDoubleFunction extends MultiDoubleFunction { + public final static String NAME = AnalyticsParams.MULTIPLY; + + public MultiplyDoubleFunction(ValueSource[] sources) { + super(sources); + } + + @Override + protected String name() { + return NAME; + } + + @Override + protected double func(int doc, FunctionValues[] valsArr) { + double product = 1d; + for (FunctionValues val : valsArr) { + product *= val.doubleVal(doc); + } + return product; + } + +} diff --git a/solr/core/src/java/org/apache/solr/analytics/util/valuesource/NegateDoubleFunction.java b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/NegateDoubleFunction.java new file mode 100644 index 00000000000..4bff8d0845e --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/NegateDoubleFunction.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.util.valuesource; + +import org.apache.lucene.queries.function.FunctionValues; +import org.apache.lucene.queries.function.ValueSource; +import org.apache.solr.analytics.util.AnalyticsParams; + +/** + * NegateDoubleFunction negates the double value of the source it contains. + */ +public class NegateDoubleFunction extends SingleDoubleFunction { + public final static String NAME = AnalyticsParams.NEGATE; + + public NegateDoubleFunction(ValueSource source) { + super(source); + } + + protected String name() { + return NAME; + } + + @Override + public String description() { + return name()+"("+source.description()+")"; + } + + protected double func(int doc, FunctionValues vals) { + return vals.doubleVal(doc)*-1; + } + + @Override + public boolean equals(Object o) { + if (getClass() != o.getClass()) return false; + NegateDoubleFunction other = (NegateDoubleFunction)o; + return this.source.equals(other.source); + } + +} diff --git a/solr/core/src/java/org/apache/solr/analytics/util/valuesource/PowDoubleFunction.java b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/PowDoubleFunction.java new file mode 100644 index 00000000000..1b4348b0118 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/PowDoubleFunction.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.util.valuesource; + +import org.apache.lucene.queries.function.FunctionValues; +import org.apache.lucene.queries.function.ValueSource; +import org.apache.solr.analytics.util.AnalyticsParams; + +/** + * PowDoubleFunction returns 'a' raised to the power of 'b'. + */ +public class PowDoubleFunction extends DualDoubleFunction { + public final static String NAME = AnalyticsParams.POWER; + + /** + * @param a the base. + * @param b the exponent. + */ + public PowDoubleFunction(ValueSource a, ValueSource b) { + super(a, b); + } + + @Override + protected String name() { + return NAME; + } + + @Override + protected double func(int doc, FunctionValues aVals, FunctionValues bVals) { + return Math.pow(aVals.doubleVal(doc), bVals.doubleVal(doc)); + } +} diff --git a/solr/core/src/java/org/apache/solr/analytics/util/valuesource/ReverseStringFunction.java b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/ReverseStringFunction.java new file mode 100644 index 00000000000..568f94e1821 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/ReverseStringFunction.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.util.valuesource; + +import org.apache.commons.lang.StringUtils; +import org.apache.lucene.queries.function.FunctionValues; +import org.apache.lucene.queries.function.ValueSource; +import org.apache.solr.analytics.util.AnalyticsParams; + +/** + * ReverseStringFunction reverses the string value of the source it contains. + */ +public class ReverseStringFunction extends SingleStringFunction { + public final static String NAME = AnalyticsParams.REVERSE; + + public ReverseStringFunction(ValueSource source) { + super(source); + } + + protected String name() { + return NAME; + } + + protected CharSequence func(int doc, FunctionValues vals) { + String val = vals.strVal(doc); + return val != null ? StringUtils.reverse(val) : null; + } + +} diff --git a/solr/core/src/java/org/apache/solr/analytics/util/valuesource/SingleDoubleFunction.java b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/SingleDoubleFunction.java new file mode 100644 index 00000000000..45fc4caf989 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/SingleDoubleFunction.java @@ -0,0 +1,80 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.util.valuesource; + +import java.io.IOException; +import java.util.Map; + +import org.apache.lucene.index.AtomicReaderContext; +import org.apache.lucene.queries.function.FunctionValues; +import org.apache.lucene.queries.function.ValueSource; +import org.apache.lucene.queries.function.docvalues.DoubleDocValues; + +/** + * Abstract {@link ValueSource} implementation which wraps one ValueSource + * and applies an extendible double function to its values. + */ +public abstract class SingleDoubleFunction extends ValueSource { + protected final ValueSource source; + + public SingleDoubleFunction(ValueSource source) { + this.source = source; + } + + @Override + public String description() { + return name()+"("+source.description()+")"; + } + + abstract String name(); + abstract double func(int doc, FunctionValues vals); + + @Override + public FunctionValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { + final FunctionValues vals = source.getValues(context, readerContext); + return new DoubleDocValues(this) { + @Override + public double doubleVal(int doc) { + return func(doc, vals); + } + + @Override + public boolean exists(int doc) { + return vals.exists(doc); + } + + @Override + public String toString(int doc) { + return name() + '(' + vals.toString(doc) + ')'; + } + }; + } + + @Override + public boolean equals(Object o) { + if (getClass() != o.getClass()) return false; + SingleDoubleFunction other = (SingleDoubleFunction)o; + return this.source.equals(other.source); + } + + @Override + public int hashCode() { + return source.hashCode()+name().hashCode(); + } + +} diff --git a/solr/core/src/java/org/apache/solr/analytics/util/valuesource/SingleStringFunction.java b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/SingleStringFunction.java new file mode 100644 index 00000000000..c5178b9d1b7 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/SingleStringFunction.java @@ -0,0 +1,120 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.util.valuesource; + +import java.io.IOException; +import java.util.Map; + +import org.apache.lucene.index.AtomicReaderContext; +import org.apache.lucene.queries.function.FunctionValues; +import org.apache.lucene.queries.function.ValueSource; +import org.apache.lucene.queries.function.docvalues.StrDocValues; +import org.apache.lucene.util.BytesRef; +import org.apache.lucene.util.mutable.MutableValue; +import org.apache.lucene.util.mutable.MutableValueStr; + +/** + * Abstract {@link ValueSource} implementation which wraps one ValueSource + * and applies an extendible string function to its values. + */ +public abstract class SingleStringFunction extends ValueSource { + protected final ValueSource source; + + public SingleStringFunction(ValueSource source) { + this.source = source; + } + + @Override + public String description() { + return name()+"("+source.description()+")"; + } + + abstract String name(); + abstract CharSequence func(int doc, FunctionValues vals); + + @Override + public FunctionValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { + final FunctionValues vals = source.getValues(context, readerContext); + return new StrDocValues(this) { + @Override + public String strVal(int doc) { + CharSequence cs = func(doc, vals); + return cs != null ? cs.toString() : null; + } + + @Override + public boolean bytesVal(int doc, BytesRef bytes) { + CharSequence cs = func(doc, vals); + if( cs != null ){ + bytes.copyChars(func(doc,vals)); + return true; + } else { + bytes.bytes = BytesRef.EMPTY_BYTES; + bytes.length = 0; + bytes.offset = 0; + return false; + } + } + + @Override + public Object objectVal(int doc) { + return strVal(doc); + } + + @Override + public boolean exists(int doc) { + return vals.exists(doc); + } + + @Override + public String toString(int doc) { + return name() + '(' + strVal(doc) + ')'; + } + + @Override + public ValueFiller getValueFiller() { + return new ValueFiller() { + private final MutableValueStr mval = new MutableValueStr(); + + @Override + public MutableValue getValue() { + return mval; + } + + @Override + public void fillValue(int doc) { + mval.exists = bytesVal(doc, mval.value); + } + }; + } + }; + } + + @Override + public boolean equals(Object o) { + if (getClass() != o.getClass()) return false; + SingleStringFunction other = (SingleStringFunction)o; + return this.source.equals(other.source); + } + + @Override + public int hashCode() { + return source.hashCode()+name().hashCode(); + } + +} diff --git a/solr/core/src/java/org/apache/solr/analytics/util/valuesource/package.html b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/package.html new file mode 100644 index 00000000000..c5059c1920e --- /dev/null +++ b/solr/core/src/java/org/apache/solr/analytics/util/valuesource/package.html @@ -0,0 +1,27 @@ + + + + + + + +

    +ValueSource function/sources used by analytics component +

    + + diff --git a/solr/core/src/java/org/apache/solr/core/SolrCore.java b/solr/core/src/java/org/apache/solr/core/SolrCore.java index 1b8f433b432..3ebd68edb16 100644 --- a/solr/core/src/java/org/apache/solr/core/SolrCore.java +++ b/solr/core/src/java/org/apache/solr/core/SolrCore.java @@ -17,9 +17,42 @@ package org.apache.solr.core; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Writer; +import java.lang.reflect.Constructor; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.IdentityHashMap; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.StringTokenizer; +import java.util.concurrent.Callable; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.locks.ReentrantLock; + +import javax.xml.parsers.ParserConfigurationException; + import org.apache.commons.io.IOUtils; import org.apache.lucene.codecs.Codec; -import org.apache.lucene.index.AtomicReaderContext; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.IndexDeletionPolicy; import org.apache.lucene.index.IndexWriter; @@ -40,6 +73,7 @@ import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.core.DirectoryFactory.DirContext; import org.apache.solr.handler.SnapPuller; import org.apache.solr.handler.admin.ShowFileRequestHandler; +import org.apache.solr.handler.component.AnalyticsComponent; import org.apache.solr.handler.component.DebugComponent; import org.apache.solr.handler.component.FacetComponent; import org.apache.solr.handler.component.HighlightComponent; @@ -93,39 +127,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xml.sax.SAXException; -import javax.xml.parsers.ParserConfigurationException; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Writer; -import java.lang.reflect.Constructor; -import java.net.URL; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.IdentityHashMap; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.StringTokenizer; -import java.util.concurrent.Callable; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.locks.ReentrantLock; - /** * @@ -1197,6 +1198,7 @@ public final class SolrCore implements SolrInfoMBean { addIfNotPresent(components,StatsComponent.COMPONENT_NAME,StatsComponent.class); addIfNotPresent(components,DebugComponent.COMPONENT_NAME,DebugComponent.class); addIfNotPresent(components,RealTimeGetComponent.COMPONENT_NAME,RealTimeGetComponent.class); + addIfNotPresent(components,AnalyticsComponent.COMPONENT_NAME,AnalyticsComponent.class); return components; } private void addIfNotPresent(Map registry, String name, Class c){ diff --git a/solr/core/src/java/org/apache/solr/handler/component/AnalyticsComponent.java b/solr/core/src/java/org/apache/solr/handler/component/AnalyticsComponent.java new file mode 100644 index 00000000000..ed51a6f7c41 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/handler/component/AnalyticsComponent.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.handler.component; + +import java.io.IOException; + +import org.apache.solr.analytics.plugin.AnalyticsStatisticsCollector; +import org.apache.solr.analytics.request.AnalyticsStats; +import org.apache.solr.analytics.util.AnalyticsParams; +import org.apache.solr.common.params.SolrParams; +import org.apache.solr.common.util.NamedList; + +public class AnalyticsComponent extends SearchComponent { + public static final String COMPONENT_NAME = "analytics"; + private final AnalyticsStatisticsCollector analyticsCollector = new AnalyticsStatisticsCollector();; + + @Override + public void prepare(ResponseBuilder rb) throws IOException { + if (rb.req.getParams().getBool(AnalyticsParams.ANALYTICS,false)) { + rb.setNeedDocSet( true ); + } + } + + @Override + public void process(ResponseBuilder rb) throws IOException { + if (rb.req.getParams().getBool(AnalyticsParams.ANALYTICS,false)) { + SolrParams params = rb.req.getParams(); + AnalyticsStats s = new AnalyticsStats(rb.req, rb.getResults().docSet, params, analyticsCollector); + rb.rsp.add( "stats", s.execute() ); + } + } + + /* + @Override + public int distributedProcess(ResponseBuilder rb) throws IOException { + return ResponseBuilder.STAGE_DONE; + } + + @Override + public void modifyRequest(ResponseBuilder rb, SearchComponent who, ShardRequest sreq) { + // TODO Auto-generated method stub + super.modifyRequest(rb, who, sreq); + } + + @Override + public void handleResponses(ResponseBuilder rb, ShardRequest sreq) { + // TODO Auto-generated method stub + super.handleResponses(rb, sreq); + } + + @Override + public void finishStage(ResponseBuilder rb) { + // TODO Auto-generated method stub + super.finishStage(rb); + } + */ + + @Override + public String getName() { + return COMPONENT_NAME; + } + + @Override + public String getDescription() { + return "Perform analytics"; + } + + @Override + public String getSource() { + return "$URL$"; + } + + @Override + public String getVersion() { + return getClass().getPackage().getSpecificationVersion(); + } + + @Override + public NamedList getStatistics() { + return analyticsCollector.getStatistics(); + } +} diff --git a/solr/core/src/java/org/apache/solr/handler/component/SearchHandler.java b/solr/core/src/java/org/apache/solr/handler/component/SearchHandler.java index 713574450cb..2f49229ed10 100644 --- a/solr/core/src/java/org/apache/solr/handler/component/SearchHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/component/SearchHandler.java @@ -17,27 +17,27 @@ package org.apache.solr.handler.component; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + import org.apache.solr.common.SolrException; import org.apache.solr.common.params.CommonParams; import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.params.ShardParams; -import org.apache.solr.util.RTimer; import org.apache.solr.core.CloseHook; import org.apache.solr.core.PluginInfo; import org.apache.solr.core.SolrCore; import org.apache.solr.handler.RequestHandlerBase; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; +import org.apache.solr.util.RTimer; import org.apache.solr.util.SolrPluginUtils; import org.apache.solr.util.plugin.PluginInfoInitialized; import org.apache.solr.util.plugin.SolrCoreAware; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; - /** * @@ -69,6 +69,7 @@ public class SearchHandler extends RequestHandlerBase implements SolrCoreAware , names.add( HighlightComponent.COMPONENT_NAME ); names.add( StatsComponent.COMPONENT_NAME ); names.add( DebugComponent.COMPONENT_NAME ); + names.add( AnalyticsComponent.COMPONENT_NAME ); return names; } diff --git a/solr/core/src/test-files/analytics/requestFiles/expressions.txt b/solr/core/src/test-files/analytics/requestFiles/expressions.txt new file mode 100644 index 00000000000..329d32db0e2 --- /dev/null +++ b/solr/core/src/test-files/analytics/requestFiles/expressions.txt @@ -0,0 +1,70 @@ +o.ar.s.sum=sum(int_id) +o.ar.s.unique=unique(long_ld) +o.ar.s.su=add(sum(int_id),unique(long_ld)) +o.ar.s.mean=mean(int_id) +o.ar.s.count=count(long_ld) +o.ar.s.median=median(int_id) +o.ar.s.mcm=add(mean(int_id),count(long_ld),median(int_id)) + +o.mr.s.sum=sum(int_id) +o.mr.s.unique=unique(long_ld) +o.mr.s.su=mult(sum(int_id),unique(long_ld)) +o.mr.s.mean=mean(int_id) +o.mr.s.count=count(long_ld) +o.mr.s.median=median(int_id) +o.mr.s.mcm=mult(mean(int_id),count(long_ld),median(int_id)) + +o.dr.s.sum=sum(int_id) +o.dr.s.unique=unique(long_ld) +o.dr.s.su=div(sum(int_id),unique(long_ld)) +o.dr.s.mean=mean(int_id) +o.dr.s.count=count(long_ld) +o.dr.s.mc=div(mean(int_id),count(long_ld)) + +o.pr.s.sum=sum(int_id) +o.pr.s.unique=unique(long_ld) +o.pr.s.su=pow(sum(int_id),unique(long_ld)) +o.pr.s.mean=mean(int_id) +o.pr.s.count=count(long_ld) +o.pr.s.mc=pow(mean(int_id),count(long_ld)) + +o.nr.s.sum=sum(int_id) +o.nr.s.s=neg(sum(int_id)) +o.nr.s.count=count(long_ld) +o.nr.s.c=neg(count(long_ld)) + +o.avr.s.sum=sum(int_id) +o.avr.s.s=abs(neg(sum(int_id))) +o.avr.s.count=count(long_ld) +o.avr.s.c=abs(neg(count(long_ld))) + +o.cnr.s.c8=const_num(8) +o.cnr.s.c10=const_num(10) + +o.dmr.s.median=median(date_dtd) +o.dmr.s.cme=const_str(+2YEARS) +o.dmr.s.dmme=date_math(median(date_dtd),const_str(+2YEARS)) +o.dmr.s.max=max(date_dtd) +o.dmr.s.cma=const_str(+2MONTHS) +o.dmr.s.dmma=date_math(max(date_dtd),const_str(+2MONTHS)) + +o.cdr.s.cd1=const_date(1800-12-31T23:59:59Z) +o.cdr.s.cs1=const_str(1800-12-31T23:59:59Z) +o.cdr.s.cd2=const_date(1804-06-30T23:59:59Z) +o.cdr.s.cs2=const_str(1804-06-30T23:59:59Z) + +o.csr.s.cs1=const_str(this is the first) +o.csr.s.cs2=const_str(this is the second) +o.csr.s.cs3=const_str(this is the third) + +o.cr.s.csmin=const_str(this is the first) +o.cr.s.min=min(string_sd) +o.cr.s.ccmin=concat(const_str(this is the first),min(string_sd)) +o.cr.s.csmax=const_str(this is the second) +o.cr.s.max=max(string_sd) +o.cr.s.ccmax=concat(const_str(this is the second),max(string_sd)) + +o.rr.s.min=min(string_sd) +o.rr.s.rmin=rev(min(string_sd)) +o.rr.s.max=max(string_sd) +o.rr.s.rmax=rev(max(string_sd)) diff --git a/solr/core/src/test-files/analytics/requestFiles/fieldFacetExtras.txt b/solr/core/src/test-files/analytics/requestFiles/fieldFacetExtras.txt new file mode 100644 index 00000000000..3979f57bd95 --- /dev/null +++ b/solr/core/src/test-files/analytics/requestFiles/fieldFacetExtras.txt @@ -0,0 +1,66 @@ +o.sr.s.mean=mean(int_id) +o.sr.s.median=median(int_id) +o.sr.s.count=count(int_id) +o.sr.s.percentile_20=percentile(20,int_id) +o.sr.ff=long_ld +o.sr.ff.long_ld.ss=mean +o.sr.ff.long_ld.sd=asc +o.sr.ff=float_fd +o.sr.ff.float_fd.ss=median +o.sr.ff.float_fd.sd=desc +o.sr.ff=double_dd +o.sr.ff.double_dd.ss=count +o.sr.ff.double_dd.sd=asc +o.sr.ff=string_sd +o.sr.ff.string_sd.ss=percentile_20 +o.sr.ff.string_sd.sd=desc + +o.lr.s.mean=mean(int_id) +o.lr.s.median=median(int_id) +o.lr.s.count=count(int_id) +o.lr.s.percentile_20=percentile(20,int_id) +o.lr.ff=long_ld +o.lr.ff.long_ld.ss=mean +o.lr.ff.long_ld.sd=asc +o.lr.ff.long_ld.limit=5 +o.lr.ff=float_fd +o.lr.ff.float_fd.ss=median +o.lr.ff.float_fd.sd=desc +o.lr.ff.float_fd.limit=3 +o.lr.ff=double_dd +o.lr.ff.double_dd.ss=count +o.lr.ff.double_dd.sd=asc +o.lr.ff.double_dd.limit=7 +o.lr.ff=string_sd +o.lr.ff.string_sd.ss=percentile_20 +o.lr.ff.string_sd.sd=desc +o.lr.ff.string_sd.limit=1 + + + +o.offAll.s.mean=mean(int_id) +o.offAll.ff=long_ld +o.offAll.ff.long_ld.ss=mean +o.offAll.ff.long_ld.sd=asc +o.offAll.ff.long_ld.limit=7 + +o.off0.s.mean=mean(int_id) +o.off0.ff=long_ld +o.off0.ff.long_ld.ss=mean +o.off0.ff.long_ld.sd=asc +o.off0.ff.long_ld.limit=2 +o.off0.ff.long_ld.offset=0 + +o.off1.s.mean=mean(int_id) +o.off1.ff=long_ld +o.off1.ff.long_ld.ss=mean +o.off1.ff.long_ld.sd=asc +o.off1.ff.long_ld.limit=2 +o.off1.ff.long_ld.offset=2 + +o.off2.s.mean=mean(int_id) +o.off2.ff=long_ld +o.off2.ff.long_ld.ss=mean +o.off2.ff.long_ld.sd=asc +o.off2.ff.long_ld.limit=3 +o.off2.ff.long_ld.offset=4 diff --git a/solr/core/src/test-files/analytics/requestFiles/fieldFacets.txt b/solr/core/src/test-files/analytics/requestFiles/fieldFacets.txt new file mode 100644 index 00000000000..5ba5953a0c8 --- /dev/null +++ b/solr/core/src/test-files/analytics/requestFiles/fieldFacets.txt @@ -0,0 +1,132 @@ +o.sum.s.int=sum(int_id) +o.sum.s.long=sum(long_ld) +o.sum.s.float=sum(float_fd) +o.sum.s.double=sum(double_dd) +o.sum.ff=string_sd +o.sum.ff=date_dtd + +o.mean.s.int=mean(int_id) +o.mean.s.long=mean(long_ld) +o.mean.s.float=mean(float_fd) +o.mean.s.double=mean(double_dd) +o.mean.ff=string_sd +o.mean.ff=date_dtd + +o.sumOfSquares.s.int=sumofsquares(int_id) +o.sumOfSquares.s.long=sumofsquares(long_ld) +o.sumOfSquares.s.float=sumofsquares(float_fd) +o.sumOfSquares.s.double=sumofsquares(double_dd) +o.sumOfSquares.ff=string_sd +o.sumOfSquares.ff=date_dtd + +o.stddev.s.int=stddev(int_id) +o.stddev.s.long=stddev(long_ld) +o.stddev.s.float=stddev(float_fd) +o.stddev.s.double=stddev(double_dd) +o.stddev.ff=string_sd +o.stddev.ff=date_dtd + +o.median.s.int=median(int_id) +o.median.s.long=median(long_ld) +o.median.s.float=median(float_fd) +o.median.s.double=median(double_dd) +o.median.ff=string_sd +o.median.ff=date_dtd + +o.percentile_20n.s.int=percentile(20,int_id) +o.percentile_20n.s.long=percentile(20,long_ld) +o.percentile_20n.s.float=percentile(20,float_fd) +o.percentile_20n.s.double=percentile(20,double_dd) +o.percentile_20n.ff=string_sd +o.percentile_20n.ff=date_dtd + +o.percentile_20.s.str=percentile(20,string_sd) +o.percentile_20.s.date=percentile(20,date_dtd) +o.percentile_20.ff=int_id +o.percentile_20.ff=long_ld + +o.percentile_60n.s.int=percentile(60,int_id) +o.percentile_60n.s.long=percentile(60,long_ld) +o.percentile_60n.s.float=percentile(60,float_fd) +o.percentile_60n.s.double=percentile(60,double_dd) +o.percentile_60n.ff=string_sd +o.percentile_60n.ff=date_dtd + +o.percentile_60.s.str=percentile(60,string_sd) +o.percentile_60.s.date=percentile(60,date_dtd) +o.percentile_60.ff=int_id +o.percentile_60.ff=long_ld + +o.minn.s.int=min(int_id) +o.minn.s.long=min(long_ld) +o.minn.s.float=min(float_fd) +o.minn.s.double=min(double_dd) +o.minn.ff=string_sd +o.minn.ff=date_dtd + +o.min.s.str=min(string_sd) +o.min.s.date=min(date_dtd) +o.min.ff=int_id +o.min.ff=long_ld + +o.maxn.s.int=max(int_id) +o.maxn.s.long=max(long_ld) +o.maxn.s.float=max(float_fd) +o.maxn.s.double=max(double_dd) +o.maxn.ff=string_sd +o.maxn.ff=date_dtd + +o.max.s.str=max(string_sd) +o.max.s.date=max(date_dtd) +o.max.ff=int_id +o.max.ff=long_ld + +o.countn.s.int=count(int_id) +o.countn.s.long=count(long_ld) +o.countn.s.float=count(float_fd) +o.countn.s.double=count(double_dd) +o.countn.ff=string_sd +o.countn.ff=date_dtd + +o.count.s.str=count(string_sd) +o.count.s.date=count(date_dtd) +o.count.ff=int_id +o.count.ff=long_ld + +o.uniquen.s.int=unique(int_id) +o.uniquen.s.long=unique(long_ld) +o.uniquen.s.float=unique(float_fd) +o.uniquen.s.double=unique(double_dd) +o.uniquen.ff=string_sd +o.uniquen.ff=date_dtd + +o.unique.s.str=unique(string_sd) +o.unique.s.date=unique(date_dtd) +o.unique.ff=int_id +o.unique.ff=long_ld + +o.missingn.s.int=missing(int_id) +o.missingn.s.long=missing(long_ld) +o.missingn.s.float=missing(float_fd) +o.missingn.s.double=missing(double_dd) +o.missingn.ff=string_sd +o.missingn.ff=date_dtd + +o.missing.s.str=missing(string_sd) +o.missing.s.date=missing(date_dtd) +o.missing.ff=int_id +o.missing.ff=long_ld + +o.multivalued.s.mean=mean(int_id) +o.multivalued.ff=long_ldm +o.multivalued.ff=string_sdm +o.multivalued.ff=date_dtdm + +o.missingf.s.mean=mean(int_id) +o.missingf.ff=date_dtd +o.missingf.ff.date_dtd.dim=true +o.missingf.ff=string_sd +o.missingf.ff.string_sd.dim=true +o.missingf.ff.string_sd.sm=true +o.missingf.ff=date_dtdm +o.missingf.ff.date_dtdm.sm=true diff --git a/solr/core/src/test-files/analytics/requestFiles/functions.txt b/solr/core/src/test-files/analytics/requestFiles/functions.txt new file mode 100644 index 00000000000..93f4ba56f15 --- /dev/null +++ b/solr/core/src/test-files/analytics/requestFiles/functions.txt @@ -0,0 +1,62 @@ +o.ar.s.sum=sum(add(int_id,float_fd)) +o.ar.s.sumc=sum(add_if_dd) +o.ar.s.mean=mean(add(long_ld,double_dd,float_fd)) +o.ar.s.meanc=mean(add_ldf_dd) + +o.mr.s.sum=sum(mult(int_id,float_fd)) +o.mr.s.sumc=sum(mult_if_dd) +o.mr.s.mean=mean(mult(long_ld,double_dd,float_fd)) +o.mr.s.meanc=mean(mult_ldf_dd) + +o.dr.s.sum=sum(div(int_id,float_fd)) +o.dr.s.sumc=sum(div_if_dd) +o.dr.s.mean=mean(div(long_ld,double_dd)) +o.dr.s.meanc=mean(div_ld_dd) + +o.pr.s.sum=sum(pow(int_id,float_fd)) +o.pr.s.sumc=sum(pow_if_dd) +o.pr.s.mean=mean(pow(long_ld,double_dd)) +o.pr.s.meanc=mean(pow_ld_dd) + +o.nr.s.sum=sum(neg(int_id)) +o.nr.s.sumc=sum(neg_i_dd) +o.nr.s.mean=mean(neg(long_ld)) +o.nr.s.meanc=mean(neg_l_dd) + +o.nr.s.sum=sum(abs(neg(int_id))) +o.nr.s.sumc=sum(int_id) +o.nr.s.mean=mean(abs(neg(long_ld))) +o.nr.s.meanc=mean(int_id) + +o.cnr.s.sum=sum(const_num(8)) +o.cnr.s.sumc=sum(const_8_dd) +o.cnr.s.mean=mean(const_num(10)) +o.cnr.s.meanc=mean(const_10_dd) + +o.dmr.s.median=median(date_math(date_dtd,const_str(+2YEARS))) +o.dmr.s.medianc=median(dm_2y_dtd) +o.dmr.s.max=max(date_math(date_dtd,const_str(+2MONTHS))) +o.dmr.s.maxc=max(dm_2m_dtd) + +o.cdr.s.median=median(const_date(1800-06-30T23:59:59Z)) +o.cdr.s.medianc=median(const_00_dtd) +o.cdr.s.max=max(const_date(1804-06-30T23:59:59Z)) +o.cdr.s.maxc=max(const_04_dtd) + +o.csr.s.min=min(const_str(this is the first)) +o.csr.s.minc=min(const_first_sd) +o.csr.s.max=max(const_str(this is the second)) +o.csr.s.maxc=max(const_second_sd) + +o.cr.s.min=min(concat(const_str(this is the first),string_sd)) +o.cr.s.minc=min(concat_first_sd) +o.cr.s.max=max(concat(const_str(this is the second),string_sd)) +o.cr.s.maxc=max(concat_second_sd) + +o.rr.s.min=min(rev(string_sd)) +o.rr.s.minc=min(rev_sd) +o.rr.s.max=max(rev(string_sd)) +o.rr.s.maxc=max(rev_sd) + +o.ms.s.min=min(miss_dd) +o.ms.s.max=max(miss_dd) diff --git a/solr/core/src/test-files/analytics/requestFiles/noFacets.txt b/solr/core/src/test-files/analytics/requestFiles/noFacets.txt new file mode 100644 index 00000000000..e69b4fe58f2 --- /dev/null +++ b/solr/core/src/test-files/analytics/requestFiles/noFacets.txt @@ -0,0 +1,74 @@ +o.sr.s.int_id=sum(int_i) +o.sr.s.long_ld=sum(long_l) +o.sr.s.float_fd=sum(float_f) +o.sr.s.double_dd=sum(double_d) + +o.sosr.s.int_id=sumofsquares(int_id) +o.sosr.s.long_ld=sumofsquares(long_ld) +o.sosr.s.float_fd=sumofsquares(float_fd) +o.sosr.s.double_dd=sumofsquares(double_dd) + +o.mr.s.int_id=mean(int_id) +o.mr.s.long_ld=mean(long_ld) +o.mr.s.float_fd=mean(float_fd) +o.mr.s.double_dd=mean(double_dd) + +o.str.s.int_id=stddev(int_id) +o.str.s.long_ld=stddev(long_ld) +o.st.s.float_fd=stddev(float_fd) +o.str.s.double_dd=stddev(double_dd) + +o.medr.s.int_id=median(int_id) +o.medr.s.long_ld=median(long_ld) +o.medr.s.float_fd=median(float_fd) +o.medr.s.double_dd=median(double_dd) +o.medr.s.date_dtd=median(date_dtd) + +o.p2r.s.int_id=percentile(20,int_id) +o.p2r.s.long_ld=percentile(20,long_ld) +o.p2r.s.float_fd=percentile(20,float_fd) +o.p2r.s.double_dd=percentile(20,double_dd) +o.p2r.s.date_dtd=percentile(20,date_dtd) +o.p2r.s.string_sd=percentile(20,string_sd) + +o.p6r.s.int_id=percentile(60,int_id) +o.p6r.s.long_ld=percentile(60,long_ld) +o.p6r.s.float_fd=percentile(60,float_fd) +o.p6r.s.double_dd=percentile(60,double_dd) +o.p6r.s.date_dtd=percentile(60,date_dtd) +o.p6r.s.string_sd=percentile(60,string_sd) + +o.mir.s.int_id=min(int_id) +o.mir.s.long_ld=min(long_ld) +o.mir.s.float_fd=min(float_fd) +o.mir.s.double_dd=min(double_dd) +o.mir.s.date_dtd=min(date_dtd) +o.mir.s.string_sd=min(string_sd) + +o.mar.s.int_id=max(int_id) +o.mar.s.long_ld=max(long_ld) +o.mar.s.float_fd=max(float_fd) +o.mar.s.double_dd=max(double_dd) +o.mar.s.date_dtd=max(date_dtd) +o.mar.s.string_sd=max(string_sd) + +o.cr.s.int_id=count(int_id) +o.cr.s.long_ld=count(long_ld) +o.cr.s.float_fd=count(float_fd) +o.cr.s.double_dd=count(double_dd) +o.cr.s.date_dtd=count(date_dtd) +o.cr.s.string_sd=count(string_sd) + +o.ur.s.int_id=unique(int_id) +o.ur.s.long_ld=unique(long_ld) +o.ur.s.float_fd=unique(float_fd) +o.ur.s.double_dd=unique(double_dd) +o.ur.s.date_dtd=unique(date_dtd) +o.ur.s.string_sd=unique(string_sd) + +o.misr.s.int_id=missing(int_id) +o.misr.s.long_ld=missing(long_ld) +o.misr.s.float_fd=missing(float_fd) +o.misr.s.double_dd=missing(double_dd) +o.misr.s.date_dtd=missing(date_dtd) +o.misr.s.string_sd=missing(string_sd) diff --git a/solr/core/src/test-files/analytics/requestFiles/queryFacets.txt b/solr/core/src/test-files/analytics/requestFiles/queryFacets.txt new file mode 100644 index 00000000000..6be4a4e1a60 --- /dev/null +++ b/solr/core/src/test-files/analytics/requestFiles/queryFacets.txt @@ -0,0 +1,45 @@ +o.ir.s.sum=sum(int_id) +o.ir.s.mean=mean(int_id) +o.ir.s.median=median(int_id) +o.ir.s.percentile_8=percentile(8,int_id) +o.ir.ff=string_sd +o.ir.ff.string_sd.h=true +o.ir.qf=float1 +o.ir.qf.float1.q=float_fd:[* TO 50] +o.ir.qf=float2 +o.ir.qf.float2.q=float_fd:[* TO 30] + +o.pr.s.sum=sum(int_id) +o.pr.s.mean=mean(int_id) +o.pr.s.median=median(int_id) +o.pr.s.q1=concat(const_str(float_fd:[), percentile(10,int_id), const_str( TO ), median(int_id), const_str(])) +o.pr.hs.q2=concat(const_str(float_fd:[), percentile(30,int_id), const_str( TO ), median(int_id), const_str(])) +o.pr.hs.q3=concat(const_str(float_fd:[), percentile(40,int_id), const_str( TO ), median(int_id), const_str(])) +o.pr.s.percentile_8=percentile(8,int_id) +o.pr.ff=string_sd +o.pr.ff.string_sd.h=true +o.pr.qf=float3 +o.pr.qf.float3.q=result(q1) +o.pr.qf.float3.q=result(q2) +o.pr.qf.float3.q=result(q3) +o.pr.qf.float3.q=result(q1,string_sd,abc2) +o.pr.qf=float4 +o.pr.qf.float4.d=float3 +o.pr.qf.float4.q=qresult(q1,float3,result(q1)) + +o.lr.s.sum=sum(long_ld) +o.lr.s.mean=mean(long_ld) +o.lr.s.median=median(long_ld) +o.lr.s.percentile_8=percentile(8,long_ld) +o.lr.qf=string +o.lr.qf.string.q=string_sd:abc1 +o.lr.qf.string.q=string_sd:abc2 + +o.fr.s.sum=sum(float_fd) +o.fr.s.mean=mean(float_fd) +o.fr.s.median=median(float_fd) +o.fr.s.percentile_8=percentile(8,float_fd) +o.fr.qf=lad +o.fr.qf.lad.q=long_ld:[20 TO *] +o.fr.qf.lad.q=long_ld:[30 TO *] +o.fr.qf.lad.q=double_dd:[* TO 50] diff --git a/solr/core/src/test-files/analytics/requestFiles/rangeFacets.txt b/solr/core/src/test-files/analytics/requestFiles/rangeFacets.txt new file mode 100644 index 00000000000..cbfe052a250 --- /dev/null +++ b/solr/core/src/test-files/analytics/requestFiles/rangeFacets.txt @@ -0,0 +1,170 @@ +o.ri.s.sum=sum(int_id) +o.ri.s.mean=mean(int_id) +o.ri.s.median=median(int_id) +o.ri.s.count=count(int_id) +o.ri.s.sumOfSquares=sumofsquares(int_id) +o.ri.rf=long_ld +o.ri.rf.long_ld.st=5 +o.ri.rf.long_ld.e=30 +o.ri.rf.long_ld.g=5 +o.ri.rf.long_ld.ib=lower +o.ri.rf.long_ld.or=all +o.ri.rf=double_dd +o.ri.rf.double_dd.st=3 +o.ri.rf.double_dd.e=39 +o.ri.rf.double_dd.g=7 +o.ri.rf.double_dd.ib=upper +o.ri.rf.double_dd.ib=outer +o.ri.rf.double_dd.or=all +o.ri.rf=date_dtd +o.ri.rf.date_dtd.st=1007-01-01T23:59:59Z +o.ri.rf.date_dtd.e=1044-01-01T23:59:59Z +o.ri.rf.date_dtd.g=+7YEARS +o.ri.rf.date_dtd.ib=lower +o.ri.rf.date_dtd.ib=edge +o.ri.rf.date_dtd.ib=outer +o.ri.rf.date_dtd.or=all + +o.rf.s.sum=sum(float_fd) +o.rf.s.mean=mean(float_fd) +o.rf.s.median=median(float_fd) +o.rf.s.count=count(float_fd) +o.rf.s.sumOfSquares=sumofsquares(float_fd) +o.rf.rf=long_ld +o.rf.rf.long_ld.st=0 +o.rf.rf.long_ld.e=29 +o.rf.rf.long_ld.g=4 +o.rf.rf.long_ld.ib=all +o.rf.rf.long_ld.or=all +o.rf.rf=double_dd +o.rf.rf.double_dd.st=4 +o.rf.rf.double_dd.e=47 +o.rf.rf.double_dd.g=11 +o.rf.rf.double_dd.ib=edge +o.rf.rf.double_dd.or=all +o.rf.rf=date_dtd +o.rf.rf.date_dtd.st=1004-01-01T23:59:59Z +o.rf.rf.date_dtd.e=1046-01-01T23:59:59Z +o.rf.rf.date_dtd.g=+5YEARS +o.rf.rf.date_dtd.ib=upper +o.rf.rf.date_dtd.ib=edge +o.rf.rf.date_dtd.or=all + +o.hi.s.sum=sum(int_id) +o.hi.s.mean=mean(int_id) +o.hi.s.median=median(int_id) +o.hi.s.count=count(int_id) +o.hi.s.sumOfSquares=sumofsquares(int_id) +o.hi.rf=long_ld +o.hi.rf.long_ld.st=5 +o.hi.rf.long_ld.e=30 +o.hi.rf.long_ld.g=5 +o.hi.rf.long_ld.he=true +o.hi.rf.long_ld.ib=lower +o.hi.rf.long_ld.or=all +o.hi.rf=double_dd +o.hi.rf.double_dd.st=3 +o.hi.rf.double_dd.e=39 +o.hi.rf.double_dd.g=7 +o.hi.rf.double_dd.he=true +o.hi.rf.double_dd.ib=upper +o.hi.rf.double_dd.ib=outer +o.hi.rf.double_dd.or=all +o.hi.rf=date_dtd +o.hi.rf.date_dtd.st=1007-01-01T23:59:59Z +o.hi.rf.date_dtd.e=1044-01-01T23:59:59Z +o.hi.rf.date_dtd.g=+7YEARS +o.hi.rf.date_dtd.he=true +o.hi.rf.date_dtd.ib=lower +o.hi.rf.date_dtd.ib=edge +o.hi.rf.date_dtd.ib=outer +o.hi.rf.date_dtd.or=all + +o.hf.s.sum=sum(float_fd) +o.hf.s.mean=mean(float_fd) +o.hf.s.median=median(float_fd) +o.hf.s.count=count(float_fd) +o.hf.s.sumOfSquares=sumofsquares(float_fd) +o.hf.rf=long_ld +o.hf.rf.long_ld.st=0 +o.hf.rf.long_ld.e=29 +o.hf.rf.long_ld.g=4 +o.hf.rf.long_ld.he=true +o.hf.rf.long_ld.ib=all +o.hf.rf.long_ld.or=all +o.hf.rf=double_dd +o.hf.rf.double_dd.st=4 +o.hf.rf.double_dd.e=47 +o.hf.rf.double_dd.g=11 +o.hf.rf.double_dd.he=true +o.hf.rf.double_dd.ib=edge +o.hf.rf.double_dd.or=all +o.hf.rf=date_dtd +o.hf.rf.date_dtd.st=1004-01-01T23:59:59Z +o.hf.rf.date_dtd.e=1046-01-01T23:59:59Z +o.hf.rf.date_dtd.g=+5YEARS +o.hf.rf.date_dtd.he=true +o.hf.rf.date_dtd.ib=upper +o.hf.rf.date_dtd.ib=edge +o.hf.rf.date_dtd.or=all + +o.mi.s.sum=sum(int_id) +o.mi.s.mean=mean(int_id) +o.mi.s.median=median(int_id) +o.mi.s.count=count(int_id) +o.mi.s.sumOfSquares=sumofsquares(int_id) +o.mi.rf=long_ld +o.mi.rf.long_ld.st=5 +o.mi.rf.long_ld.e=30 +o.mi.rf.long_ld.g=4,2,6,3 +o.mi.rf.long_ld.ib=lower +o.mi.rf.long_ld.or=all +o.mi.rf=double_dd +o.mi.rf.double_dd.st=3 +o.mi.rf.double_dd.e=39 +o.mi.rf.double_dd.g=3,1,7 +o.mi.rf.double_dd.ib=upper +o.mi.rf.double_dd.ib=outer +o.mi.rf.double_dd.or=all +o.mi.rf=date_dtd +o.mi.rf.date_dtd.st=1007-01-01T23:59:59Z +o.mi.rf.date_dtd.e=1044-01-01T23:59:59Z +o.mi.rf.date_dtd.g=+2YEARS,+7YEARS +o.mi.rf.date_dtd.ib=lower +o.mi.rf.date_dtd.ib=edge +o.mi.rf.date_dtd.ib=outer +o.mi.rf.date_dtd.or=all + +o.mf.s.sum=sum(float_fd) +o.mf.s.mean=mean(float_fd) +o.mf.s.median=median(float_fd) +o.mf.s.count=count(float_fd) +o.mf.s.sumOfSquares=sumofsquares(float_fd) +o.mf.rf=long_ld +o.mf.rf.long_ld.st=0 +o.mf.rf.long_ld.e=29 +o.mf.rf.long_ld.g=1,4 +o.mf.rf.long_ld.ib=all +o.mf.rf.long_ld.or=all +o.mf.rf=double_dd +o.mf.rf.double_dd.st=4 +o.mf.rf.double_dd.e=47 +o.mf.rf.double_dd.g=2,3,11 +o.mf.rf.double_dd.ib=edge +o.mf.rf.double_dd.or=all +o.mf.rf=date_dtd +o.mf.rf.date_dtd.st=1004-01-01T23:59:59Z +o.mf.rf.date_dtd.e=1046-01-01T23:59:59Z +o.mf.rf.date_dtd.g=+4YEARS,+5YEARS +o.mf.rf.date_dtd.ib=upper +o.mf.rf.date_dtd.ib=edge +o.mf.rf.date_dtd.or=all + +o.pf.s.mean=mean(float_fd) +o.pf.hs.min=min(date_dtd) +o.pf.hs.max=max(date_dtd) +o.pf.hs.gap=const_str(+5YEARS) +o.pf.rf=date_dtd +o.pf.rf.date_dtd.st=result(min) +o.pf.rf.date_dtd.e=result(max) +o.pf.rf.date_dtd.g=result(gap) diff --git a/solr/core/src/test-files/analytics/requestXMLFiles/expressions.xml b/solr/core/src/test-files/analytics/requestXMLFiles/expressions.xml new file mode 100644 index 00000000000..511805de935 --- /dev/null +++ b/solr/core/src/test-files/analytics/requestXMLFiles/expressions.xml @@ -0,0 +1,285 @@ + + + + Add Request + + + sum(int(int_id)) + sum + + + unique(long(long_ld)) + unique + + + add(sum(int(int_id)),unique(long(long_ld))) + add sum and unique + + + + mean(int(int_id)) + mean + + + count(long(long_ld)) + count + + + median(int(int_id)) + median + + + add(mean(int(int_id)),count(long(long_ld)),median(int(int_id))) + add mean and count and median + + + + + Multiply Request + + + sum(int(int_id)) + sum + + + unique(long(long_ld)) + unique + + + mult(sum(int(int_id)),unique(long(long_ld))) + multiply sum and unique + + + + mean(int(int_id)) + mean + + + count(long(long_ld)) + count + + + median(int(int_id)) + median + + + mult(mean(int(int_id)),count(long(long_ld)),median(int(int_id))) + multiply mean and count and median + + + + + Divide Request + + + sum(int(int_id)) + sum + + + unique(long(long_ld)) + unique + + + div(sum(int(int_id)),unique(long(long_ld))) + divide sum by unique + + + + mean(int(int_id)) + mean + + + count(long(long_ld)) + count + + + div(mean(int(int_id)),count(long(long_ld))) + divide mean by count + + + + + Power Request + + + sum(int(int_id)) + sum + + + unique(long(long_ld)) + unique + + + pow(sum(int(int_id)),unique(long(long_ld))) + power sum by unique + + + + mean(int(int_id)) + mean + + + count(long(long_ld)) + count + + + pow(mean(int(int_id)),count(long(long_ld))) + power mean by count + + + + + Negate Request + + + sum(int(int_id)) + sum + + + neg(sum(int(int_id))) + negate of sum + + + + count(long(long_ld)) + count + + + neg(count(long(long_ld))) + negate of count + + + + + Const Num Request + + + const_num(8) + constant 8 + + + const_num(10) + constant 10 + + + + + Date Math Request + + + median(date(date_dtd)) + median + + + const_str(+2YEARS) + constant str median + + + date_math(median(date(date_dtd)),const_str(+2YEARS)) + date math median + + + + max(date(date_dtd)) + max + + + const_str(+2MONTHS) + constant str max + + + date_math(max(date(date_dtd)),const_str(+2MONTHS)) + date math max + + + + + Constant Date Request + + + const_str(1800-12-31T23:59:59Z) + const str 1 + + + const_date(1800-12-31T23:59:59Z) + const date 1 + + + const_str(1804-06-30T23:59:59Z) + const str 2 + + + const_date(1804-06-30T23:59:59Z) + const date 2 + + + + + Constant String Request + + + const_str(this is the first) + const str 1 + + + const_str(this is the second) + const str 2 + + + const_str(this is the third) + const str 3 + + + + + Concatenate Request + + + const_str(this is the first) + const str min + + + min(str(string_sd)) + min + + + concat(const_str(this is the first),min(str(string_sd))) + concat const and min + + + + const_str(this is the second) + const str max + + + max(str(string_sd)) + max + + + concat(const_str(this is the second),max(str(string_sd))) + concat const and max + + + + + Reverse Request + + + min(str(string_sd)) + min + + + rev(min(str(string_sd))) + reverse min + + + + max(str(string_sd)) + max + + + rev(max(str(string_sd))) + reverse max + + + diff --git a/solr/core/src/test-files/analytics/requestXMLFiles/fieldFacetExtras.xml b/solr/core/src/test-files/analytics/requestXMLFiles/fieldFacetExtras.xml new file mode 100644 index 00000000000..5d7bf074e3a --- /dev/null +++ b/solr/core/src/test-files/analytics/requestXMLFiles/fieldFacetExtras.xml @@ -0,0 +1,101 @@ + + + + sort request + + + mean(int(int_id)) + mean + + + median(int(int_id)) + median + + + count(int(int_id)) + count + + + perc(20,int(int_id)) + perc_20 + + + + long_ld + + mean + asc + + + + float_fd + + median + desc + + + + double_dd + + count + asc + + + + string_sd + + perc_20 + desc + + + + + limit request + + + mean(int(int_id)) + mean + + + median(int(int_id)) + median + + + count(int(int_id)) + count + + + perc(20,int(int_id)) + perc_20 + + + + long_ld + + mean + asc + + + + float_fd + + median + desc + + + + double_dd + + count + asc + + + + string_sd + + perc_20 + desc + + + + diff --git a/solr/core/src/test-files/analytics/requestXMLFiles/fieldFacets.xml b/solr/core/src/test-files/analytics/requestXMLFiles/fieldFacets.xml new file mode 100644 index 00000000000..53dd2d3ed89 --- /dev/null +++ b/solr/core/src/test-files/analytics/requestXMLFiles/fieldFacets.xml @@ -0,0 +1,496 @@ + + + + sum + + + sum(int(int_id)) + int + + + sum(long(long_ld)) + long + + + sum(float(float_fd)) + float + + + sum(double(double_dd)) + double + + + + string_sd + + + date_dtd + + + + mean + + + mean(int(int_id)) + int + + + mean(long(long_ld)) + long + + + mean(float(float_fd)) + float + + + mean(double(double_dd)) + double + + + + string_sd + + + date_dtd + + + + sumOfSquares + + + sumofsquares(int(int_id)) + int + + + sumofsquares(long(long_ld)) + long + + + sumofsquares(float(float_fd)) + float + + + sumofsquares(double(double_dd)) + double + + + + string_sd + + + date_dtd + + + + stddev + + + stddev(int(int_id)) + int + + + stddev(long(long_ld)) + long + + + stddev(float(float_fd)) + float + + + stddev(double(double_dd)) + double + + + + string_sd + + + date_dtd + + + + median + + + median(int(int_id)) + int + + + median(long(long_ld)) + long + + + median(float(float_fd)) + float + + + median(double(double_dd)) + double + + + + string_sd + + + date_dtd + + + + perc_20 numeric + + + perc(20,int(int_id)) + int + + + perc(20,long(long_ld)) + long + + + perc(20,float(float_fd)) + float + + + perc(20,double(double_dd)) + double + + + + string_sd + + + date_dtd + + + + perc_20 + + + perc(20,str(string_sd)) + str + + + perc(20,date(date_dtd)) + date + + + + int_id + + + long_ld + + + + perc_60 numeric + + + perc(60,int(int_id)) + int + + + perc(60,long(long_ld)) + long + + + perc(60,float(float_fd)) + float + + + perc(60,double(double_dd)) + double + + + + string_sd + + + date_dtd + + + + perc_60 + + + perc(60,str(string_sd)) + str + + + perc(60,date(date_dtd)) + date + + + + int_id + + + long_ld + + + + min numeric + + + min(int(int_id)) + int + + + min(long(long_ld)) + long + + + min(float(float_fd)) + float + + + min(double(double_dd)) + double + + + + string_sd + + + date_dtd + + + + min + + + min(str(string_sd)) + str + + + min(date(date_dtd)) + date + + + + int_id + + + long_ld + + + + max numeric + + + max(int(int_id)) + int + + + max(long(long_ld)) + long + + + max(float(float_fd)) + float + + + max(double(double_dd)) + double + + + + string_sd + + + date_dtd + + + + max + + + max(str(string_sd)) + str + + + max(date(date_dtd)) + date + + + + int_id + + + long_ld + + + + count numeric + + + count(int(int_id)) + int + + + count(long(long_ld)) + long + + + count(float(float_fd)) + float + + + count(double(double_dd)) + double + + + + string_sd + + + date_dtd + + + + count + + + count(str(string_sd)) + str + + + count(date(date_dtd)) + date + + + + int_id + + + long_ld + + + + unique numeric + + + unique(int(int_id)) + int + + + unique(long(long_ld)) + long + + + unique(float(float_fd)) + float + + + unique(double(double_dd)) + double + + + + string_sd + + + date_dtd + + + + unique + + + unique(str(string_sd)) + str + + + unique(date(date_dtd)) + date + + + + int_id + + + long_ld + + + + missing numeric + + + missing(int{int_id}) + int + + + missing(long{long_ld}) + long + + + missing(float{float_fd}) + float + + + missing(double{double_dd}) + double + + + + string_sd + + + date_dtd + + + + missing + + + missing(str{string_sd}) + str + + + missing(date{date_dtd}) + date + + + + int_id + + + long_ld + + + + multivalued + + + mean(int(int_id)) + mean + + + + long_ldm + + + string_sdm + + + date_dtdm + + + + missing facet + + + mean(int(int_id)) + mean + + + + date_dtd + + + string_sd + + + date_dtdm + + + diff --git a/solr/core/src/test-files/analytics/requestXMLFiles/functions.xml b/solr/core/src/test-files/analytics/requestXMLFiles/functions.xml new file mode 100644 index 00000000000..40f5adad239 --- /dev/null +++ b/solr/core/src/test-files/analytics/requestXMLFiles/functions.xml @@ -0,0 +1,246 @@ + + + + Add Request + + + sum(add(int(int_id),float(float_fd))) + sum + + + sum(double(add_if_dd)) + sum calced + + + + mean(add(long(long_ld),double(double_dd),float(float_fd))) + mean + + + mean(double(add_ldf_dd)) + mean calced + + + + + Multiply Request + + + sum(mult(int(int_id),float(float_fd))) + sum + + + sum(double(mult_if_dd)) + sum calced + + + + mean(mult(long(long_ld),double(double_dd),float(float_fd))) + mean + + + mean(double(mult_ldf_dd)) + mean calced + + + + + Divide Request + + + sum(div(int(int_id),float(float_fd))) + sum + + + sum(double(div_if_dd)) + sum calced + + + + mean(div(long(long_ld),double(double_dd))) + mean + + + + mean(double(div_ld_dd)) + mean calced + + + + + Power Request + + + sum(pow(int(int_id),float(float_fd)) + sum + + + sum(double(pow_if_dd)) + sum calced + + + + mean(pow(long(long_ld),double(double_dd))) + mean + + + + mean(double(pow_ld_dd)) + mean calced + + + + + Negate Request + + + sum(neg(int(int_id))) + sum + + + sum(double(neg_i_dd)) + sum calced + + + + mean(neg(long(long_ld))) + mean + + + mean(double(neg_l_dd)) + mean calced + + + + + Const Num Request + + + sum(const_num(8)) + sum + + + sum(double(const_8_dd)) + sum calced + + + + mean(const_num(10)) + mean + + + mean(double(const_10_dd)) + mean calced + + + + + Date Math Request + + + median(date_math(date(date_dtd),const_str(+2YEARS))) + median + + + median(date(dm_2y_dtd)) + median calced + + + + max(date_math(date(date_dtd),const_str(+2MONTHS))) + max + + + max(date(dm_2m_dtd)) + max calced + + + + + Constant Date Request + + + median(const_date(1800-06-30T23:59:59Z)) + median + + + median(date(const_00_dtd)) + median calced + + + + max(const_date(1804-06-30T23:59:59Z)) + max + + + max(date(const_04_dtd)) + max calced + + + + + Constant String Request + + + min(const_str(this is the first)) + min + + + min(str(const_first_sd)) + min calced + + + + max(const_str(this is the second)) + max + + + max(str(const_second_sd)) + max calced + + + + + Concatenate Request + + + min(concat(const_str(this is the first),str(string_sd))) + min + + + min(str(concat_first_sd)) + min calced + + + + max(concat(const_str(this is the second),str(string_sd))) + max + + + max(str(concat_second_sd)) + max calced + + + + + Reverse Request + + + min(rev(str(string_sd))) + min + + + min(str(rev_sd)) + min calced + + + + max(rev(str(string_sd))) + max + + + max(str(rev_sd)) + max calced + + + diff --git a/solr/core/src/test-files/analytics/requestXMLFiles/noFacets.xml b/solr/core/src/test-files/analytics/requestXMLFiles/noFacets.xml new file mode 100644 index 00000000000..ce00d3840ac --- /dev/null +++ b/solr/core/src/test-files/analytics/requestXMLFiles/noFacets.xml @@ -0,0 +1,310 @@ + + + + Sum Request + + + sum(int(int_id)) + int_id + + + sum(long(long_ld)) + long_ld + + + sum(float(float_fd)) + float_fd + + + sum(double(double_dd)) + double_dd + + + + + SumOfSquares Request + + + sumofsquares(int(int_id)) + int_id + + + sumofsquares(long(long_ld)) + long_ld + + + sumofsquares(float(float_fd)) + float_fd + + + sumofsquares(double(double_dd)) + double_dd + + + + + Mean Request + + + mean(int(int_id)) + int_id + + + mean(long(long_ld)) + long_ld + + + mean(float(float_fd)) + float_fd + + + mean(double(double_dd)) + double_dd + + + + + Stddev Request + + + stddev(int(int_id)) + int_id + + + stddev(long(long_ld)) + long_ld + + + stddev(float(float_fd)) + float_fd + + + stddev(double(double_dd)) + double_dd + + + + + Median Request + + + median(int(int_id)) + int_id + + + median(long(long_ld)) + long_ld + + + median(float(float_fd)) + float_fd + + + median(double(double_dd)) + double_dd + + + + + Perc 20 Request + + + perc(20,int(int_id)) + int_id + + + perc(20,long(long_ld)) + long_ld + + + perc(20,float(float_fd)) + float_fd + + + perc(20,double(double_dd)) + double_dd + + + perc(20,date(date_dtd)) + date_dtd + + + perc(20,str(string_sd)) + string_sd + + + + + Perc 60 Request + + + perc(60,int(int_id)) + int_id + + + perc(60,long(long_ld)) + long_ld + + + perc(60,float(float_fd)) + float_fd + + + perc(60,double(double_dd)) + double_dd + + + perc(60,date(date_dtd)) + date_dtd + + + perc(60,str(string_sd)) + string_sd + + + + + Min Request + + + min(int(int_id)) + int_id + + + min(long(long_ld)) + long_ld + + + min(float(float_fd)) + float_fd + + + min(double(double_dd)) + double_dd + + + min(date(date_dtd)) + date_dtd + + + min(str(string_sd)) + string_sd + + + + + Max Request + + + max(int(int_id)) + int_id + + + max(long(long_ld)) + long_ld + + + max(float(float_fd)) + float_fd + + + max(double(double_dd)) + double_dd + + + max(date(date_dtd)) + date_dtd + + + max(str(string_sd)) + string_sd + + + + + Unique Request + + + unique(int(int_id)) + int_id + + + unique(long(long_ld)) + long_ld + + + unique(float(float_fd)) + float_fd + + + unique(double(double_dd)) + double_dd + + + unique(date(date_dtd)) + date_dtd + + + unique(str(string_sd)) + string_sd + + + + + Count Request + + + count(int(int_id)) + int_id + + + count(long(long_ld)) + long_ld + + + count(float(float_fd)) + float_fd + + + count(double(double_dd)) + double_dd + + + count(date(date_dtd)) + date_dtd + + + count(str(string_sd)) + string_sd + + + + + Missing Request + + + missing(int{int_id}) + int_id + + + missing(long{long_ld}) + long_ld + + + missing(float{float_fd}) + float_fd + + + missing(double{double_dd}) + double_dd + + + missing(date{date_dtd}) + date_dtd + + + missing(str{string_sd}) + string_sd + + + diff --git a/solr/core/src/test-files/analytics/requestXMLFiles/queryFacets.xml b/solr/core/src/test-files/analytics/requestXMLFiles/queryFacets.xml new file mode 100644 index 00000000000..73f615b2b25 --- /dev/null +++ b/solr/core/src/test-files/analytics/requestXMLFiles/queryFacets.xml @@ -0,0 +1,94 @@ + + + + int request + + + sum(int(int_id)) + sum + + + + mean(int(int_id)) + mean + + + + median(int(int_id)) + median + + + + perc(8,int(int_id)) + perc_8 + + + + float1 + float_fd:[* TO 50] + + + float2 + float_fd:[* TO 30] + + + + long request + + + sum(long(long_ld)) + sum + + + + mean(long(long_ld)) + mean + + + + median(long(long_ld)) + median + + + + perc(8,long(long_ld)) + perc_8 + + + + string + string_sd:abc1 + string_sd:abc2 + + + + float request + + + sum(float(float_fd)) + sum + + + + mean(float(float_fd)) + mean + + + + median(float(float_fd)) + median + + + + perc(8,float(float_fd)) + perc_8 + + + + long and double + long_ld:[20 TO *] + long_ld:[30 TO *] + double_dd:[* TO 50] + + + diff --git a/solr/core/src/test-files/analytics/requestXMLFiles/rangeFacets.xml b/solr/core/src/test-files/analytics/requestXMLFiles/rangeFacets.xml new file mode 100644 index 00000000000..3434d2e0220 --- /dev/null +++ b/solr/core/src/test-files/analytics/requestXMLFiles/rangeFacets.xml @@ -0,0 +1,319 @@ + + + + regular int + + + mean(int(int_id)) + mean + + + sum(int(int_id)) + sum + + + median(int(int_id)) + median + + + count(int(int_id)) + count + + + sumofsquares(int(int_id)) + sumOfSquares + + + + long_ld + 5 + 30 + 5 + lower + all + + + double_dd + 3 + 39 + 7 + upper + outer + all + + + date_dtd + 1007-01-01T23:59:59Z + 1044-01-01T23:59:59Z + +7YEARS + lower + edge + outer + all + + + + regular float + + + mean(float(float_fd)) + mean + + + sum(float(float_fd)) + sum + + + median(float(float_fd)) + median + + + count(float(float_fd)) + count + + + sumofsquares(float(float_fd)) + sumOfSquares + + + + long_ld + 0 + 29 + 4 + all + all + + + double_dd + 4 + 47 + 11 + edge + all + + + date_dtd + 1004-01-01T23:59:59Z + 1046-01-01T23:59:59Z + +5YEARS + upper + edge + all + + + + hardend int + + + mean(int(int_id)) + mean + + + sum(int(int_id)) + sum + + + median(int(int_id)) + median + + + count(int(int_id)) + count + + + sumofsquares(int(int_id)) + sumOfSquares + + + + long_ld + 5 + 30 + 5 + lower + all + + + double_dd + 3 + 39 + 7 + upper + outer + all + + + date_dtd + 1007-01-01T23:59:59Z + 1044-01-01T23:59:59Z + +7YEARS + lower + edge + outer + all + + + + hardend float + + + mean(float(float_fd)) + mean + + + sum(float(float_fd)) + sum + + + median(float(float_fd)) + median + + + count(float(float_fd)) + count + + + sumofsquares(float(float_fd)) + sumOfSquares + + + + long_ld + 0 + 29 + 4 + all + all + + + double_dd + 4 + 47 + 11 + edge + all + + + date_dtd + 1004-01-01T23:59:59Z + 1046-01-01T23:59:59Z + +5YEARS + upper + edge + all + + + + multigap int + + + mean(int(int_id)) + mean + + + sum(int(int_id)) + sum + + + median(int(int_id)) + median + + + count(int(int_id)) + count + + + sumofsquares(int(int_id)) + sumOfSquares + + + + long_ld + 5 + 30 + 4 + 2 + 6 + 3 + lower + all + + + double_dd + 3 + 39 + 3 + 1 + 7 + upper + outer + all + + + date_dtd + 1007-01-01T23:59:59Z + 1044-01-01T23:59:59Z + +2YEARS + +7YEARS + lower + edge + outer + all + + + + multigap float + + + mean(float(float_fd)) + mean + + + sum(float(float_fd)) + sum + + + median(float(float_fd)) + median + + + count(float(float_fd)) + count + + + sumofsquares(float(float_fd)) + sumOfSquares + + + + long_ld + 0 + 29 + 1 + 4 + all + all + + + double_dd + 4 + 47 + 2 + 3 + 11 + edge + all + + + date_dtd + 1004-01-01T23:59:59Z + 1046-01-01T23:59:59Z + +4YEARS + +5YEARS + upper + edge + all + + + diff --git a/solr/core/src/test-files/solr/collection1/conf/schema-analytics.xml b/solr/core/src/test-files/solr/collection1/conf/schema-analytics.xml new file mode 100644 index 00000000000..3c5713d929b --- /dev/null +++ b/solr/core/src/test-files/solr/collection1/conf/schema-analytics.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id + + diff --git a/solr/core/src/test/org/apache/solr/analytics/AbstractAnalyticsStatsTest.java b/solr/core/src/test/org/apache/solr/analytics/AbstractAnalyticsStatsTest.java new file mode 100644 index 00000000000..f5e008bd423 --- /dev/null +++ b/solr/core/src/test/org/apache/solr/analytics/AbstractAnalyticsStatsTest.java @@ -0,0 +1,156 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics; + +import java.io.File; +import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Scanner; + +import org.apache.commons.lang.StringUtils; +import org.apache.lucene.util.LuceneTestCase.SuppressCodecs; +import org.apache.solr.SolrTestCaseJ4; +import org.apache.solr.analytics.util.MedianCalculator; +import org.apache.solr.analytics.util.PercentileCalculator; +import org.apache.solr.request.SolrQueryRequest; + +import com.google.common.collect.ObjectArrays; +import org.apache.solr.util.ExternalPaths; + +@SuppressCodecs({"Lucene3x","Lucene40","Lucene41","Lucene42","Appending","Asserting"}) +public class AbstractAnalyticsStatsTest extends SolrTestCaseJ4 { + + protected static final String[] BASEPARMS = new String[]{ "q", "*:*", "indent", "true", "olap", "true", "rows", "0" }; + protected static final HashMap defaults = new HashMap(); + + public Object getStatResult(String response, String request, String type, String name) { + String cat = "\n "; + String begin = "<"+type+" name=\""+name+"\">"; + String end = ""; + int beginInt = response.indexOf(begin, response.indexOf(cat))+begin.length(); + int endInt = response.indexOf(end, beginInt); + String resultStr = response.substring(beginInt, endInt); + if (type.equals("double")) { + return Double.parseDouble(resultStr); + } else if (type.equals("int")) { + return Integer.parseInt(resultStr); + } else if (type.equals("long")) { + return Long.parseLong(resultStr); + } else if (type.equals("float")) { + return Float.parseFloat(resultStr); + } else { + return resultStr; + } + } + + public > Double calculateNumberStat(ArrayList list, String stat) { + Double result; + if (stat.equals("median")) { + result = MedianCalculator.getMedian(list); + } else if (stat.equals("mean")) { + double d = 0; + for (T element : list) { + d += element.doubleValue(); + } + result = Double.valueOf(d/list.size()); + } else if (stat.equals("sum")) { + double d = 0; + for (T element : list) { + d += element.doubleValue(); + } + result = Double.valueOf(d); + } else if (stat.equals("sumOfSquares")) { + double d = 0; + for (T element : list) { + d += element.doubleValue()*element.doubleValue(); + } + result = Double.valueOf(d); + } else if (stat.equals("stddev")) { + double sum = 0; + double sumSquares = 0; + for (T element : list) { + sum += element.doubleValue(); + sumSquares += element.doubleValue()*element.doubleValue(); + } + result = Math.sqrt(sumSquares/list.size()-sum*sum/(list.size()*list.size())); + } else { + throw new IllegalArgumentException(); + } + return result; + } + + public > Object calculateStat(ArrayList list, String stat) { + Object result; + if (stat.contains("perc_")) { + double[] perc = new double[]{Double.parseDouble(stat.substring(5))/100}; + result = PercentileCalculator.getPercentiles(list, perc).get(0); + } else if (stat.equals("count")) { + result = Long.valueOf(list.size()); + } else if (stat.equals("unique")) { + HashSet set = new HashSet(); + set.addAll(list); + result = Long.valueOf((long)set.size()); + } else if (stat.equals("max")) { + Collections.sort(list); + result = list.get(list.size()-1); + } else if (stat.equals("min")) { + Collections.sort(list); + result = list.get(0); + } else { + result = null; + } + return result; + } + + @SuppressWarnings("unchecked") + public > Long calculateMissing(ArrayList list, String type) { + T def = (T)defaults.get(type); + long miss = 0; + for (T element : list) { + if (element.compareTo(def)==0) { + miss++; + } + } + return Long.valueOf(miss); + } + + public static SolrQueryRequest request(String...args){ + return SolrTestCaseJ4.req( ObjectArrays.concat(BASEPARMS, args,String.class) ); + } + + public static String[] fileToStringArr(String fileName) throws FileNotFoundException { + Scanner file = new Scanner(new File(ExternalPaths.SOURCE_HOME, fileName), "UTF-8"); + ArrayList strList = new ArrayList(); + while (file.hasNextLine()) { + String line = file.nextLine(); + line = line.trim(); + if( StringUtils.isBlank(line) || line.startsWith("#")){ + continue; + } + String[] param = line.split("="); + strList.add(param[0]); + strList.add(param[1]); + } + return strList.toArray(new String[0]); + } + + +} diff --git a/solr/core/src/test/org/apache/solr/analytics/NoFacetTest.java b/solr/core/src/test/org/apache/solr/analytics/NoFacetTest.java new file mode 100644 index 00000000000..3c36db43582 --- /dev/null +++ b/solr/core/src/test/org/apache/solr/analytics/NoFacetTest.java @@ -0,0 +1,483 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics; + + +import java.util.ArrayList; +import java.util.List; + +import org.apache.lucene.util.LuceneTestCase.SuppressCodecs; +import org.junit.BeforeClass; +import org.junit.Test; + +@SuppressCodecs({"Lucene3x","Lucene40","Lucene41","Lucene42","Appending","Asserting"}) +public class NoFacetTest extends AbstractAnalyticsStatsTest { + static String fileName = "core/src/test-files/analytics/requestFiles/noFacets.txt"; + + static public final int INT = 71; + static public final int LONG = 36; + static public final int FLOAT = 93; + static public final int DOUBLE = 49; + static public final int DATE = 12; + static public final int STRING = 28; + static public final int NUM_LOOPS = 100; + + //INT + static ArrayList intTestStart; + static long intMissing = 0; + + //LONG + static ArrayList longTestStart; + static long longMissing = 0; + + //FLOAT + static ArrayList floatTestStart; + static long floatMissing = 0; + + //DOUBLE + static ArrayList doubleTestStart; + static long doubleMissing = 0; + + //DATE + static ArrayList dateTestStart; + static long dateMissing = 0; + + //STRING + static ArrayList stringTestStart; + static long stringMissing = 0; + + static String response; + + @BeforeClass + public static void beforeClass() throws Exception { + initCore("solrconfig-basic.xml","schema-analytics.xml"); + h.update("*:*"); + defaults.put("int_id", new Integer(0)); + defaults.put("long_ld", new Long(0)); + defaults.put("float_fd", new Float(0)); + defaults.put("double_dd", new Double(0)); + defaults.put("date_dtd", "1800-12-31T23:59:59Z"); + defaults.put("string_sd", "str0"); + + intTestStart = new ArrayList(); + longTestStart = new ArrayList(); + floatTestStart = new ArrayList(); + doubleTestStart = new ArrayList(); + dateTestStart = new ArrayList(); + stringTestStart = new ArrayList(); + + for (int j = 0; j < NUM_LOOPS; ++j) { + int i = j%INT; + long l = j%LONG; + float f = j%FLOAT; + double d = j%DOUBLE; + String dt = (1800+j%DATE) + "-12-31T23:59:59Z"; + String s = "str" + (j%STRING); + List fields = new ArrayList(); + fields.add("id"); fields.add("1000"+j); + + if( i != 0 ){ + fields.add("int_id"); fields.add("" + i); + intTestStart.add(i); + } else intMissing++; + + if( l != 0l ){ + fields.add("long_ld"); fields.add("" + l); + longTestStart.add(l); + } else longMissing++; + + if( f != 0.0f ){ + fields.add("float_fd"); fields.add("" + f); + floatTestStart.add(f); + } else floatMissing++; + + if( d != 0.0d ){ + fields.add("double_dd"); fields.add("" + d); + doubleTestStart.add(d); + } else doubleMissing++; + + if( (j%DATE) != 0 ){ + fields.add("date_dtd"); fields.add(dt); + dateTestStart.add(dt); + } else dateMissing++; + + if( (j%STRING) != 0 ){ + fields.add("string_sd"); fields.add(s); + stringTestStart.add(s); + } else stringMissing++; + + fields.add("int_i"); fields.add("" + i); + fields.add("long_l"); fields.add("" + l); + fields.add("float_f"); fields.add("" + f); + fields.add("double_d"); fields.add("" + d); + + assertU(adoc(fields.toArray(new String[0]))); + + + if (usually()) { + assertU(commit()); // to have several segments + } + } + + assertU(commit()); + + //Sort ascending tests + response = h.query(request(fileToStringArr(fileName))); + } + + @Test + public void sumTest() throws Exception { + //Int + Double intResult = (Double)getStatResult(response, "sr", "double", "int_id"); + Double intTest = (Double)calculateNumberStat(intTestStart, "sum"); + assertEquals(intResult,intTest); + + //Long + Double longResult = (Double)getStatResult(response, "sr", "double", "long_ld"); + Double longTest = (Double)calculateNumberStat(longTestStart, "sum"); + assertEquals(longResult,longTest); + + //Float + Double floatResult = (Double)getStatResult(response, "sr", "double", "float_fd"); + Double floatTest = (Double)calculateNumberStat(floatTestStart, "sum"); + assertEquals(floatResult,floatTest); + + //Double + Double doubleResult = (Double)getStatResult(response, "sr", "double", "double_dd"); + Double doubleTest = (Double)calculateNumberStat(doubleTestStart, "sum"); + assertEquals(doubleResult,doubleTest); + } + + @Test + public void sumOfSquaresTest() throws Exception { + //Int + Double intResult = (Double)getStatResult(response, "sosr", "double", "int_id"); + Double intTest = (Double)calculateNumberStat(intTestStart, "sumOfSquares"); + assertEquals(intResult,intTest); + + //Long + Double longResult = (Double)getStatResult(response, "sosr", "double", "long_ld"); + Double longTest = (Double)calculateNumberStat(longTestStart, "sumOfSquares"); + assertEquals(longResult,longTest); + + //Float + Double floatResult = (Double)getStatResult(response, "sosr", "double", "float_fd"); + Double floatTest = (Double)calculateNumberStat(floatTestStart, "sumOfSquares"); + assertEquals(floatResult,floatTest); + + //Double + Double doubleResult = (Double)getStatResult(response, "sosr", "double", "double_dd"); + Double doubleTest = (Double)calculateNumberStat(doubleTestStart, "sumOfSquares"); + assertEquals(doubleResult,doubleTest); + } + + @Test + public void meanTest() throws Exception { + //Int + Double intResult = (Double)getStatResult(response, "mr", "double", "int_id"); + Double intTest = (Double)calculateNumberStat(intTestStart, "mean"); + assertEquals(intResult,intTest); + + //Long + Double longResult = (Double)getStatResult(response, "mr", "double", "long_ld"); + Double longTest = (Double)calculateNumberStat(longTestStart, "mean"); + assertEquals(longResult,longTest); + + //Float + Double floatResult = (Double)getStatResult(response, "mr", "double", "float_fd"); + Double floatTest = (Double)calculateNumberStat(floatTestStart, "mean"); + assertEquals(floatResult,floatTest); + + //Double + Double doubleResult = (Double)getStatResult(response, "mr", "double", "double_dd"); + Double doubleTest = (Double)calculateNumberStat(doubleTestStart, "mean"); + assertEquals(doubleResult,doubleTest); + } + + @Test + public void stddevTest() throws Exception { + //Int + Double intResult = (Double)getStatResult(response, "str", "double", "int_id"); + Double intTest = (Double)calculateNumberStat(intTestStart, "stddev"); + assertTrue(Math.abs(intResult-intTest)<.00000000001); + + //Long + Double longResult = (Double)getStatResult(response, "str", "double", "long_ld"); + Double longTest = (Double)calculateNumberStat(longTestStart, "stddev"); + assertTrue(Math.abs(longResult-longTest)<.00000000001); + + //Float + Double floatResult = (Double)getStatResult(response, "str", "double", "float_fd"); + Double floatTest = (Double)calculateNumberStat(floatTestStart, "stddev"); + assertTrue(Math.abs(floatResult-floatTest)<.00000000001); + + //Double + Double doubleResult = (Double)getStatResult(response, "str", "double", "double_dd"); + Double doubleTest = (Double)calculateNumberStat(doubleTestStart, "stddev"); + assertTrue(Math.abs(doubleResult-doubleTest)<.00000000001); + } + + @Test + public void medianTest() throws Exception { + //Int + Double intResult = (Double)getStatResult(response, "medr", "double", "int_id"); + Double intTest = (Double)calculateNumberStat(intTestStart, "median"); + assertEquals(intResult,intTest); + + //Long + Double longResult = (Double)getStatResult(response, "medr", "double", "long_ld"); + Double longTest = (Double)calculateNumberStat(longTestStart, "median"); + assertEquals(longResult,longTest); + + //Float + Double floatResult = (Double)getStatResult(response, "medr", "double", "float_fd"); + Double floatTest = (Double)calculateNumberStat(floatTestStart, "median"); + assertEquals(floatResult,floatTest); + + //Double + Double doubleResult = (Double)getStatResult(response, "medr", "double", "double_dd"); + Double doubleTest = (Double)calculateNumberStat(doubleTestStart, "median"); + assertEquals(doubleResult,doubleTest); + } + + @Test + public void perc20Test() throws Exception { + //Int 20 + Integer intResult = (Integer)getStatResult(response, "p2r", "int", "int_id"); + Integer intTest = (Integer)calculateStat(intTestStart, "perc_20"); + assertEquals(intResult,intTest); + + //Long 20 + Long longResult = (Long)getStatResult(response, "p2r", "long", "long_ld"); + Long longTest = (Long)calculateStat(longTestStart, "perc_20"); + assertEquals(longResult,longTest); + + //Float 20 + Float floatResult = (Float)getStatResult(response, "p2r", "float", "float_fd"); + Float floatTest = (Float)calculateStat(floatTestStart, "perc_20"); + assertEquals(floatResult,floatTest); + + //Double 20 + Double doubleResult = (Double)getStatResult(response, "p2r", "double", "double_dd"); + Double doubleTest = (Double)calculateStat(doubleTestStart, "perc_20"); + assertEquals(doubleResult,doubleTest); + + //Date 20 + String dateResult = (String)getStatResult(response, "p2r", "date", "date_dtd"); + String dateTest = (String)calculateStat(dateTestStart, "perc_20"); + assertEquals(dateResult,dateTest); + + //String 20 + String stringResult = (String)getStatResult(response, "p2r", "str", "string_sd"); + String stringTest = (String)calculateStat(stringTestStart, "perc_20"); + assertEquals(stringResult,stringTest); + } + + @Test + public void perc60Test() throws Exception { + //Int 60 + Integer intResult = (Integer)getStatResult(response, "p6r", "int", "int_id"); + Integer intTest = (Integer)calculateStat(intTestStart, "perc_60"); + assertEquals(intResult,intTest); + + //Long 60 + Long longResult = (Long)getStatResult(response, "p6r", "long", "long_ld"); + Long longTest = (Long)calculateStat(longTestStart, "perc_60"); + assertEquals(longResult,longTest); + + //Float 60 + Float floatResult = (Float)getStatResult(response, "p6r", "float", "float_fd"); + Float floatTest = (Float)calculateStat(floatTestStart, "perc_60"); + assertEquals(floatResult,floatTest); + + //Double 60 + Double doubleResult = (Double)getStatResult(response, "p6r", "double", "double_dd"); + Double doubleTest = (Double)calculateStat(doubleTestStart, "perc_60"); + assertEquals(doubleResult,doubleTest); + + //Date 60 + String dateResult = (String)getStatResult(response, "p6r", "date", "date_dtd"); + String dateTest = (String)calculateStat(dateTestStart, "perc_60"); + assertEquals(dateResult,dateTest); + + //String 60 + String stringResult = (String)getStatResult(response, "p6r", "str", "string_sd"); + String stringTest = (String)calculateStat(stringTestStart, "perc_60"); + assertEquals(stringResult,stringTest); + } + + @Test + public void minTest() throws Exception { + //Int + Integer intResult = (Integer)getStatResult(response, "mir", "int", "int_id"); + Integer intTest = (Integer)calculateStat(intTestStart, "min"); + assertEquals(intResult,intTest); + + //Long + Long longResult = (Long)getStatResult(response, "mir", "long", "long_ld"); + Long longTest = (Long)calculateStat(longTestStart, "min"); + assertEquals(longResult,longTest); + + //Float + Float floatResult = (Float)getStatResult(response, "mir", "float", "float_fd"); + Float floatTest = (Float)calculateStat(floatTestStart, "min"); + assertEquals(floatResult,floatTest); + + //Double + Double doubleResult = (Double)getStatResult(response, "mir", "double", "double_dd"); + Double doubleTest = (Double)calculateStat(doubleTestStart, "min"); + assertEquals(doubleResult,doubleTest); + + //Date + String dateResult = (String)getStatResult(response, "mir", "date", "date_dtd"); + String dateTest = (String)calculateStat(dateTestStart, "min"); + assertEquals(dateResult,dateTest); + + //String + String stringResult = (String)getStatResult(response, "mir", "str", "string_sd"); + String stringTest = (String)calculateStat(stringTestStart, "min"); + assertEquals(stringResult,stringTest); + } + + @Test + public void maxTest() throws Exception { + //Int + Integer intResult = (Integer)getStatResult(response, "mar", "int", "int_id"); + Integer intTest = (Integer)calculateStat(intTestStart, "max"); + assertEquals(intResult,intTest); + + //Long + Long longResult = (Long)getStatResult(response, "mar", "long", "long_ld"); + Long longTest = (Long)calculateStat(longTestStart, "max"); + assertEquals(longResult,longTest); + + //Float + Float floatResult = (Float)getStatResult(response, "mar", "float", "float_fd"); + Float floatTest = (Float)calculateStat(floatTestStart, "max"); + assertEquals(floatResult,floatTest); + + //Double + Double doubleResult = (Double)getStatResult(response, "mar", "double", "double_dd"); + Double doubleTest = (Double)calculateStat(doubleTestStart, "max"); + assertEquals(doubleResult,doubleTest); + + //Date + String dateResult = (String)getStatResult(response, "mar", "date", "date_dtd"); + String dateTest = (String)calculateStat(dateTestStart, "max"); + assertEquals(dateResult,dateTest); + + //String + String stringResult = (String)getStatResult(response, "mar", "str", "string_sd"); + String stringTest = (String)calculateStat(stringTestStart, "max"); + assertEquals(stringResult,stringTest); + } + + @Test + public void uniqueTest() throws Exception { + //Int + Long intResult = (Long)getStatResult(response, "ur", "long", "int_id"); + Long intTest = (Long)calculateStat(intTestStart, "unique"); + assertEquals(intResult,intTest); + + //Long + Long longResult = (Long)getStatResult(response, "ur", "long", "long_ld"); + Long longTest = (Long)calculateStat(longTestStart, "unique"); + assertEquals(longResult,longTest); + + //Float + Long floatResult = (Long)getStatResult(response, "ur", "long", "float_fd"); + Long floatTest = (Long)calculateStat(floatTestStart, "unique"); + assertEquals(floatResult,floatTest); + + //Double + Long doubleResult = (Long)getStatResult(response, "ur", "long", "double_dd"); + Long doubleTest = (Long)calculateStat(doubleTestStart, "unique"); + assertEquals(doubleResult,doubleTest); + + //Date + Long dateResult = (Long)getStatResult(response, "ur", "long", "date_dtd"); + Long dateTest = (Long)calculateStat(dateTestStart, "unique"); + assertEquals(dateResult,dateTest); + + //String + Long stringResult = (Long)getStatResult(response, "ur", "long", "string_sd"); + Long stringTest = (Long)calculateStat(stringTestStart, "unique"); + assertEquals(stringResult,stringTest); + } + + @Test + public void countTest() throws Exception { + //Int + Long intResult = (Long)getStatResult(response, "cr", "long", "int_id"); + Long intTest = (Long)calculateStat(intTestStart, "count"); + assertEquals(intResult,intTest); + + //Long + Long longResult = (Long)getStatResult(response, "cr", "long", "long_ld"); + Long longTest = (Long)calculateStat(longTestStart, "count"); + assertEquals(longResult,longTest); + + //Float + Long floatResult = (Long)getStatResult(response, "cr", "long", "float_fd"); + Long floatTest = (Long)calculateStat(floatTestStart, "count"); + assertEquals(floatResult,floatTest); + + //Double + Long doubleResult = (Long)getStatResult(response, "cr", "long", "double_dd"); + Long doubleTest = (Long)calculateStat(doubleTestStart, "count"); + assertEquals(doubleResult,doubleTest); + + //Date + Long dateResult = (Long)getStatResult(response, "cr", "long", "date_dtd"); + Long dateTest = (Long)calculateStat(dateTestStart, "count"); + assertEquals(dateResult,dateTest); + + //String + Long stringResult = (Long)getStatResult(response, "cr", "long", "string_sd"); + Long stringTest = (Long)calculateStat(stringTestStart, "count"); + assertEquals(stringResult,stringTest); + } + + @Test + public void missingDefaultTest() throws Exception { + //Int + long intResult = (Long)getStatResult(response, "misr", "long", "int_id"); + assertEquals(intMissing,intResult); + + //Long + long longResult = (Long)getStatResult(response, "misr", "long", "long_ld"); + assertEquals(longMissing,longResult); + + //Float + long floatResult = (Long)getStatResult(response, "misr", "long", "float_fd"); + assertEquals(floatMissing,floatResult); + + //Double + long doubleResult = (Long)getStatResult(response, "misr", "long", "double_dd"); + assertEquals(doubleMissing,doubleResult); + + //Date + long dateResult = (Long)getStatResult(response, "misr", "long", "date_dtd"); + assertEquals(dateMissing,dateResult); + + //String + long stringResult = (Long)getStatResult(response, "misr", "long", "string_sd"); + assertEquals(stringMissing, stringResult); + } + +} diff --git a/solr/core/src/test/org/apache/solr/analytics/expression/ExpressionTest.java b/solr/core/src/test/org/apache/solr/analytics/expression/ExpressionTest.java new file mode 100644 index 00000000000..9a36d9d7b51 --- /dev/null +++ b/solr/core/src/test/org/apache/solr/analytics/expression/ExpressionTest.java @@ -0,0 +1,270 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.expression; + +import java.io.File; +import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Scanner; + +import org.apache.lucene.util.LuceneTestCase.SuppressCodecs; +import org.apache.solr.SolrTestCaseJ4; +import org.apache.solr.request.SolrQueryRequest; +import org.apache.solr.schema.TrieDateField; +import org.apache.solr.util.DateMathParser; +import org.apache.solr.util.ExternalPaths; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.google.common.collect.ObjectArrays; + +@SuppressCodecs({"Lucene3x","Lucene40","Lucene41","Lucene42","Appending","Asserting"}) +public class ExpressionTest extends SolrTestCaseJ4 { + static String fileName = "core/src/test-files/analytics/requestFiles/expressions.txt"; + + protected static final String[] BASEPARMS = new String[]{ "q", "*:*", "indent", "true", "stats", "true", "olap", "true", "rows", "0" }; + protected static final HashMap defaults = new HashMap(); + + static public final int INT = 71; + static public final int LONG = 36; + static public final int FLOAT = 93; + static public final int DOUBLE = 49; + static public final int DATE = 12; + static public final int STRING = 28; + static public final int NUM_LOOPS = 100; + + static String response; + + @BeforeClass + public static void beforeClass() throws Exception { + initCore("solrconfig-basic.xml","schema-analytics.xml"); + h.update("*:*"); + + for (int j = 0; j < NUM_LOOPS; ++j) { + int i = j%INT; + long l = j%LONG; + float f = j%FLOAT; + double d = j%DOUBLE; + String dt = (1800+j%DATE) + "-12-31T23:59:59Z"; + String s = "str" + (j%STRING); + assertU(adoc("id", "1000" + j, "int_id", "" + i, "long_ld", "" + l, "float_fd", "" + f, + "double_dd", "" + d, "date_dtd", dt, "string_sd", s)); + + if (usually()) { + commit(); // to have several segments + } + } + + assertU(commit()); + + //Sort ascending tests + response = h.query(request(fileToStringArr(fileName))); + } + + @Test + public void addTest() throws Exception { + double sumResult = (Double)getStatResult(response, "ar", "double", "sum"); + double uniqueResult = ((Long)getStatResult(response, "ar", "long", "unique")).doubleValue(); + double result = (Double)getStatResult(response, "ar", "double", "su"); + assertTrue(sumResult+uniqueResult==result); + + double meanResult = (Double)getStatResult(response, "ar", "double", "mean"); + double medianResult = (Double)getStatResult(response, "ar", "double", "median"); + double countResult = ((Long)getStatResult(response, "ar", "long", "count")).doubleValue(); + result = (Double)getStatResult(response, "ar", "double", "mcm"); + assertTrue(meanResult+countResult+medianResult==result); + } + + @Test + public void multiplyTest() throws Exception { + double sumResult = (Double)getStatResult(response, "mr", "double", "sum"); + double uniqueResult = ((Long)getStatResult(response, "mr", "long", "unique")).doubleValue(); + double result = (Double)getStatResult(response, "mr", "double", "su"); + assertTrue(sumResult*uniqueResult==result); + + double meanResult = (Double)getStatResult(response, "mr", "double", "mean"); + double medianResult = (Double)getStatResult(response, "mr", "double", "median"); + double countResult = ((Long)getStatResult(response, "mr", "long", "count")).doubleValue(); + result = (Double)getStatResult(response, "mr", "double", "mcm"); + assertTrue(meanResult*countResult*medianResult==result); + } + + @Test + public void divideTest() throws Exception { + double sumResult = (Double)getStatResult(response, "dr", "double", "sum"); + double uniqueResult = ((Long)getStatResult(response, "dr", "long", "unique")).doubleValue(); + double result = (Double)getStatResult(response, "dr", "double", "su"); + assertTrue(sumResult/uniqueResult==result); + + double meanResult = (Double)getStatResult(response, "dr", "double", "mean"); + double countResult = ((Long)getStatResult(response, "dr", "long", "count")).doubleValue(); + result = (Double)getStatResult(response, "dr", "double", "mc"); + assertTrue(meanResult/countResult==result); + } + + @Test + public void powerTest() throws Exception { + double sumResult = (Double)getStatResult(response, "pr", "double", "sum"); + double uniqueResult = ((Long)getStatResult(response, "pr", "long", "unique")).doubleValue(); + double result = (Double)getStatResult(response, "pr", "double", "su"); + assertTrue(Math.pow(sumResult,uniqueResult)==result); + + double meanResult = (Double)getStatResult(response, "pr", "double", "mean"); + double countResult = ((Long)getStatResult(response, "pr", "long", "count")).doubleValue(); + result = (Double)getStatResult(response, "pr", "double", "mc"); + assertTrue(Math.pow(meanResult,countResult)==result); + } + + @Test + public void negateTest() throws Exception { + double sumResult = (Double)getStatResult(response, "nr", "double", "sum"); + double result = (Double)getStatResult(response, "nr", "double", "s"); + assertTrue(-1*sumResult==result); + + double countResult = ((Long)getStatResult(response, "nr", "long", "count")).doubleValue(); + result = (Double)getStatResult(response, "nr", "double", "c"); + assertTrue(-1*countResult==result); + } + + @Test + public void absoluteValueTest() throws Exception { + double sumResult = (Double)getStatResult(response, "avr", "double", "sum"); + double result = (Double)getStatResult(response, "avr", "double", "s"); + assertTrue(sumResult==result); + + double countResult = ((Long)getStatResult(response, "avr", "long", "count")).doubleValue(); + result = (Double)getStatResult(response, "avr", "double", "c"); + assertTrue(countResult==result); + } + + @Test + public void constantNumberTest() throws Exception { + double result = (Double)getStatResult(response, "cnr", "double", "c8"); + assertTrue(8==result); + + result = (Double)getStatResult(response, "cnr", "double", "c10"); + assertTrue(10==result); + } + + @SuppressWarnings("deprecation") + @Test + public void dateMathTest() throws Exception { + String math = (String)getStatResult(response, "dmr", "str", "cme"); + DateMathParser date = new DateMathParser(); + date.setNow(TrieDateField.parseDate((String)getStatResult(response, "dmr", "date", "median"))); + String dateMath = (String)getStatResult(response, "dmr", "date", "dmme"); + assertTrue(TrieDateField.parseDate(dateMath).equals(date.parseMath(math))); + + math = (String)getStatResult(response, "dmr", "str", "cma"); + date = new DateMathParser(); + date.setNow(TrieDateField.parseDate((String)getStatResult(response, "dmr", "date", "max"))); + dateMath = (String)getStatResult(response, "dmr", "date", "dmma"); + assertTrue(TrieDateField.parseDate(dateMath).equals(date.parseMath(math))); + } + + @Test + public void constantDateTest() throws Exception { + String date = (String)getStatResult(response, "cdr", "date", "cd1"); + String str = (String)getStatResult(response, "cdr", "str", "cs1"); + assertTrue(date.equals(str)); + + date = (String)getStatResult(response, "cdr", "date", "cd2"); + str = (String)getStatResult(response, "cdr", "str", "cs2"); + assertTrue(date.equals(str)); + } + + @Test + public void constantStringTest() throws Exception { + String str = (String)getStatResult(response, "csr", "str", "cs1"); + assertTrue(str.equals("this is the first")); + + str = (String)getStatResult(response, "csr", "str", "cs2"); + assertTrue(str.equals("this is the second")); + + str = (String)getStatResult(response, "csr", "str", "cs3"); + assertTrue(str.equals("this is the third")); + } + + @Test + public void concatenateTest() throws Exception { + StringBuilder builder = new StringBuilder(); + builder.append((String)getStatResult(response, "cr", "str", "csmin")); + builder.append((String)getStatResult(response, "cr", "str", "min")); + String concat = (String)getStatResult(response, "cr", "str", "ccmin"); + assertTrue(concat.equals(builder.toString())); + + builder.setLength(0); + builder.append((String)getStatResult(response, "cr", "str", "csmax")); + builder.append((String)getStatResult(response, "cr", "str", "max")); + concat = (String)getStatResult(response, "cr", "str", "ccmax"); + assertTrue(concat.equals(builder.toString())); + } + + @Test + public void reverseTest() throws Exception { + StringBuilder builder = new StringBuilder(); + builder.append((String)getStatResult(response, "rr", "str", "min")); + String rev = (String)getStatResult(response, "rr", "str", "rmin"); + assertTrue(rev.equals(builder.reverse().toString())); + + builder.setLength(0); + builder.append((String)getStatResult(response, "rr", "str", "max")); + rev = (String)getStatResult(response, "rr", "str", "rmax"); + assertTrue(rev.equals(builder.reverse().toString())); + } + + public Object getStatResult(String response, String request, String type, String name) { + String cat = "\n "; + String begin = "<"+type+" name=\""+name+"\">"; + String end = ""; + int beginInt = response.indexOf(begin, response.indexOf(cat))+begin.length(); + int endInt = response.indexOf(end, beginInt); + String resultStr = response.substring(beginInt, endInt); + if (type.equals("double")) { + return Double.parseDouble(resultStr); + } else if (type.equals("int")) { + return Integer.parseInt(resultStr); + } else if (type.equals("long")) { + return Long.parseLong(resultStr); + } else if (type.equals("float")) { + return Float.parseFloat(resultStr); + } else { + return resultStr; + } + } + + public static SolrQueryRequest request(String...args){ + return SolrTestCaseJ4.req( ObjectArrays.concat(BASEPARMS, args,String.class) ); + } + + public static String[] fileToStringArr(String fileName) throws FileNotFoundException { + Scanner file = new Scanner(new File(ExternalPaths.SOURCE_HOME, fileName), "UTF-8"); + ArrayList strList = new ArrayList(); + while (file.hasNextLine()) { + String line = file.nextLine(); + if (line.length()<2) { + continue; + } + String[] param = line.split("="); + strList.add(param[0]); + strList.add(param[1]); + } + return strList.toArray(new String[0]); + } +} diff --git a/solr/core/src/test/org/apache/solr/analytics/facet/AbstractAnalyticsFacetTest.java b/solr/core/src/test/org/apache/solr/analytics/facet/AbstractAnalyticsFacetTest.java new file mode 100644 index 00000000000..f8af2967772 --- /dev/null +++ b/solr/core/src/test/org/apache/solr/analytics/facet/AbstractAnalyticsFacetTest.java @@ -0,0 +1,257 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.facet; + +import java.io.File; +import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Scanner; + +import org.apache.lucene.util.LuceneTestCase.SuppressCodecs; +import org.apache.solr.SolrTestCaseJ4; +import org.apache.solr.analytics.util.MedianCalculator; +import org.apache.solr.analytics.util.PercentileCalculator; +import org.apache.solr.request.SolrQueryRequest; + +import com.google.common.collect.ObjectArrays; +import org.apache.solr.util.ExternalPaths; + +@SuppressCodecs({"Lucene3x","Lucene40","Lucene41","Lucene42","Appending","Asserting"}) +public class AbstractAnalyticsFacetTest extends SolrTestCaseJ4 { + protected static final HashMap defaults = new HashMap(); + + protected String latestType = ""; + + public String getFacetXML(String response, String requestName, String facetType, String facet) { + String cat = "\n "; + String begin = " \n"; + String end = "\n "; + int beginInt = response.indexOf(begin, response.indexOf(cat))+begin.length(); + int endInt = response.indexOf(end, beginInt); + String fieldStr = response.substring(beginInt, endInt); + begin = " "; + end = "\n "; + beginInt = fieldStr.indexOf(begin); + endInt = fieldStr.indexOf(end, beginInt); + String facetStr = ""; + if (beginInt>=0) { + facetStr = fieldStr.substring(beginInt+begin.length(),endInt); + } + return facetStr+" "; + } + + public static void increment(List list, int idx){ + Long i = list.remove(idx); + list.add(idx, i+1); + } + + public static String[] filter(String...args){ + List l = new ArrayList(); + for( int i=0; i (); + } else if (type.equals("int")) { + list = new ArrayList(); + } else if (type.equals("long")) { + list = new ArrayList(); + } else if (type.equals("float")) { + list = new ArrayList(); + } else { + list = new ArrayList(); + } + String find = "<"+type+" name=\""+name+"\">"; + String endS = ""; + int findAt = facit.indexOf(find)+find.length(); + while (findAt>find.length()) { + int end = facit.indexOf(endS, findAt); + if (type.equals("double")) { + list.add(Double.parseDouble(facit.substring(findAt, end))); + } else if (type.equals("int")) { + list.add(Integer.parseInt(facit.substring(findAt, end))); + } else if (type.equals("long")) { + list.add(Long.parseLong(facit.substring(findAt, end))); + } else if (type.equals("float")) { + list.add(Float.parseFloat(facit.substring(findAt, end))); + } else { + list.add(facit.substring(findAt, end)); + } + findAt = facit.indexOf(find, end)+find.length(); + } + return list; + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + public > ArrayList calculateNumberStat(ArrayList> lists, String stat) { + ArrayList result; + if (stat.equals("median")) { + result = new ArrayList(); + for (List list : lists) { + result.add(MedianCalculator.getMedian(list)); + } + } else if (stat.equals("mean")) { + result = new ArrayList(); + for (List list : lists) { + double d = 0; + for (T element : list) { + d += element.doubleValue(); + } + result.add(d/list.size()); + } + } else if (stat.equals("sum")) { + result = new ArrayList(); + for (Collection list : lists) { + double d = 0; + for (T element : list) { + d += element.doubleValue(); + } + result.add(d); + } + } else if (stat.equals("sumOfSquares")) { + result = new ArrayList(); + for (List list : lists) { + double d = 0; + for (T element : list) { + d += element.doubleValue()*element.doubleValue(); + } + result.add(d); + } + } else if (stat.equals("stddev")) { + result = new ArrayList(); + for (List list : lists) { + double sum = 0; + double sumSquares = 0; + for (T element : list) { + sum += element.doubleValue(); + sumSquares += element.doubleValue()*element.doubleValue(); + } + String res = Double.toString(Math.sqrt(sumSquares/list.size()-sum*sum/(list.size()*list.size()))); + result.add(Double.parseDouble(res)); + } + } else { + throw new IllegalArgumentException(); + } + return result; + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + public > ArrayList calculateStat(ArrayList> lists, String stat) { + ArrayList result; + if (stat.contains("perc_")) { + double[] perc = new double[]{Double.parseDouble(stat.substring(5))/100}; + result = new ArrayList(); + for (List list : lists) { + if( list.size() == 0) continue; + result.add(PercentileCalculator.getPercentiles(list, perc).get(0)); + } + } else if (stat.equals("count")) { + result = new ArrayList(); + for (List list : lists) { + //if( list.size() == 0) continue; + result.add((long)list.size()); + } + } else if (stat.equals("missing")) { + result = new ArrayList(); + for (ArrayList list : lists) { + if( list.size() == 0) continue; + result.add(calculateMissing(list,latestType)); + } + } else if (stat.equals("unique")) { + result = new ArrayList(); + for (List list : lists) { + HashSet set = new HashSet(); + set.addAll(list); + result.add((long)set.size()); + } + } else if (stat.equals("max")) { + result = new ArrayList(); + for (List list : lists) { + if( list.size() == 0) continue; + Collections.sort(list); + result.add(list.get(list.size()-1)); + } + } else if (stat.equals("min")) { + result = new ArrayList(); + for (List list : lists) { + if( list.size() == 0) continue; + Collections.sort((List)list); + result.add(list.get(0)); + } + } else { + result = null; + } + return result; + } + + @SuppressWarnings("unchecked") + public > Long calculateMissing(ArrayList list, String type) { + T def = (T)defaults.get(type); + long miss = 0; + for (T element : list) { + if (element.compareTo(def)==0) { + miss++; + } + } + return Long.valueOf(miss); + } + + public static SolrQueryRequest request(String...args){ + return SolrTestCaseJ4.req( ObjectArrays.concat(BASEPARMS, args,String.class) ); + } + + public static final String[] BASEPARMS = new String[]{ "q", "*:*", "indent", "true", "olap", "true", "rows", "0" }; + + + public static String[] fileToStringArr(String fileName) throws FileNotFoundException { + Scanner file = new Scanner(new File(ExternalPaths.SOURCE_HOME, fileName), "UTF-8"); + ArrayList strList = new ArrayList(); + while (file.hasNextLine()) { + String line = file.nextLine(); + if (line.length()<2) { + continue; + } + String[] param = line.split("="); + strList.add(param[0]); + strList.add(param[1]); + } + return strList.toArray(new String[0]); + } +} diff --git a/solr/core/src/test/org/apache/solr/analytics/facet/FieldFacetExtrasTest.java b/solr/core/src/test/org/apache/solr/analytics/facet/FieldFacetExtrasTest.java new file mode 100644 index 00000000000..3c915555515 --- /dev/null +++ b/solr/core/src/test/org/apache/solr/analytics/facet/FieldFacetExtrasTest.java @@ -0,0 +1,190 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.facet; + + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.apache.lucene.util.LuceneTestCase.SuppressCodecs; +import org.junit.BeforeClass; +import org.junit.Test; + +@SuppressCodecs({"Lucene3x","Lucene40","Lucene41","Lucene42","Appending","Asserting"}) +public class FieldFacetExtrasTest extends AbstractAnalyticsFacetTest { + static String fileName = "core/src/test-files/analytics/requestFiles/fieldFacetExtras.txt"; + + public static final int INT = 21; + public static final int LONG = 22; + public static final int FLOAT = 23; + public static final int DOUBLE = 24; + public static final int DATE = 25; + public static final int STRING = 26; + public static final int NUM_LOOPS = 100; + + //INT + static ArrayList> intLongTestStart; + static ArrayList> intFloatTestStart; + static ArrayList> intDoubleTestStart; + static ArrayList> intStringTestStart; + + static String response; + + @BeforeClass + public static void beforeClass() throws Exception { + initCore("solrconfig-basic.xml","schema-analytics.xml"); + h.update("*:*"); + + //INT + intLongTestStart = new ArrayList>(); + intFloatTestStart = new ArrayList>(); + intDoubleTestStart = new ArrayList>(); + intStringTestStart = new ArrayList>(); + + for (int j = 0; j < NUM_LOOPS; ++j) { + int i = j%INT; + long l = j%LONG; + float f = j%FLOAT; + double d = j%DOUBLE; + int dt = j%DATE; + int s = j%STRING; + assertU(adoc("id", "1000" + j, "int_id", "" + i, "long_ld", "" + l, "float_fd", "" + f, + "double_dd", "" + d, "date_dtd", (1800+dt) + "-12-31T23:59:59.999Z", "string_sd", "abc" + s)); + //Long + if (j-LONG<0) { + ArrayList list1 = new ArrayList(); + list1.add(i); + intLongTestStart.add(list1); + } else { + intLongTestStart.get((int)l).add(i); + } + //String + if (j-FLOAT<0) { + ArrayList list1 = new ArrayList(); + list1.add(i); + intFloatTestStart.add(list1); + } else { + intFloatTestStart.get((int)f).add(i); + } + //String + if (j-DOUBLE<0) { + ArrayList list1 = new ArrayList(); + list1.add(i); + intDoubleTestStart.add(list1); + } else { + intDoubleTestStart.get((int)d).add(i); + } + //String + if (j-STRING<0) { + ArrayList list1 = new ArrayList(); + list1.add(i); + intStringTestStart.add(list1); + } else { + intStringTestStart.get(s).add(i); + } + + if (usually()) { + commit(); // to have several segments + } + } + + assertU(commit()); + response = h.query(request(fileToStringArr(fileName))); + } + + @SuppressWarnings("unchecked") + @Test + public void limitTest() throws Exception { + + String longLimit = getFacetXML(response, "lr", "fieldFacets", "long_ld"); + Collection lon = (ArrayList)xmlToList(longLimit, "double", "mean"); + assertEquals(lon.size(),5); + String floatLimit = getFacetXML(response, "lr", "fieldFacets", "float_fd"); + Collection flo = (ArrayList)xmlToList(floatLimit, "double", "median"); + assertEquals(flo.size(),3); + String doubleLimit = getFacetXML(response, "lr", "fieldFacets", "double_dd"); + Collection doub = (ArrayList)xmlToList(doubleLimit, "long", "count"); + assertEquals(doub.size(),7); + String stringLimit = getFacetXML(response, "lr", "fieldFacets", "string_sd"); + Collection string = (ArrayList)xmlToList(stringLimit, "int", "percentile_20"); + assertEquals(string.size(),1); + } + + @SuppressWarnings("unchecked") + @Test + public void offsetTest() throws Exception { + + String xml; + Collection lon; + + List all = new ArrayList(); + xml = getFacetXML(response, "off0", "fieldFacets", "long_ld"); + lon = (ArrayList)xmlToList(xml, "double", "mean"); + assertEquals(lon.size(),2); + assertArrayEquals(new Double[]{ 1.5, 2.0 }, lon.toArray(new Double[0])); + all.addAll(lon); + + xml = getFacetXML(response, "off1", "fieldFacets", "long_ld"); + lon = (ArrayList)xmlToList(xml, "double", "mean"); + assertEquals(lon.size(),2); + assertArrayEquals(new Double[]{ 3.0, 4.0 }, lon.toArray(new Double[0])); + all.addAll(lon); + + xml = getFacetXML(response, "off2", "fieldFacets", "long_ld"); + lon = (ArrayList)xmlToList(xml, "double", "mean"); + assertEquals(lon.size(),3); + assertArrayEquals(new Double[]{ 5.0, 5.75, 6.0 }, lon.toArray(new Double[0])); + all.addAll(lon); + + xml = getFacetXML(response, "offAll", "fieldFacets", "long_ld"); + lon = (ArrayList)xmlToList(xml, "double", "mean"); + assertEquals(lon.size(),7); + assertArrayEquals(all.toArray(new Double[0]), lon.toArray(new Double[0])); + } + + @SuppressWarnings("unchecked") + @Test + public void sortTest() throws Exception { + String longSort = getFacetXML(response, "sr", "fieldFacets", "long_ld"); + Collection lon = (ArrayList)xmlToList(longSort, "double", "mean"); + ArrayList longTest = calculateNumberStat(intLongTestStart, "mean"); + Collections.sort(longTest); + assertEquals(longTest,lon); + + String floatSort = getFacetXML(response, "sr", "fieldFacets", "float_fd"); + Collection flo = (ArrayList)xmlToList(floatSort, "double", "median"); + ArrayList floatTest = calculateNumberStat(intFloatTestStart, "median"); + Collections.sort(floatTest,Collections.reverseOrder()); + assertEquals(floatTest,flo); + + String doubleSort = getFacetXML(response, "sr", "fieldFacets", "double_dd"); + Collection doub = (ArrayList)xmlToList(doubleSort, "long", "count"); + ArrayList doubleTest = (ArrayList)calculateStat(intDoubleTestStart, "count"); + Collections.sort(doubleTest); + assertEquals(doubleTest,doub); + + String stringSort = getFacetXML(response, "sr", "fieldFacets", "string_sd"); + Collection string = (ArrayList)xmlToList(stringSort, "int", "percentile_20"); + ArrayList stringTest = (ArrayList)calculateStat(intStringTestStart, "perc_20"); + Collections.sort(stringTest,Collections.reverseOrder()); + assertEquals(stringTest,string); + } + +} diff --git a/solr/core/src/test/org/apache/solr/analytics/facet/FieldFacetTest.java b/solr/core/src/test/org/apache/solr/analytics/facet/FieldFacetTest.java new file mode 100644 index 00000000000..0a18edc45a2 --- /dev/null +++ b/solr/core/src/test/org/apache/solr/analytics/facet/FieldFacetTest.java @@ -0,0 +1,1196 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.facet; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.apache.lucene.util.LuceneTestCase.SuppressCodecs; +import org.junit.BeforeClass; +import org.junit.Test; + +@SuppressCodecs({"Lucene3x","Lucene40","Lucene41","Lucene42","Appending","Asserting"}) +public class FieldFacetTest extends AbstractAnalyticsFacetTest{ + static String fileName = "core/src/test-files/analytics/requestFiles/fieldFacets.txt"; + + public static final int INT = 71; + public static final int LONG = 36; + public static final int LONGM = 50; + public static final int FLOAT = 73; + public static final int FLOATM = 84; + public static final int DOUBLE = 49; + public static final int DATE = 12; + public static final int DATEM = 30; + public static final int STRING = 28; + public static final int STRINGM = 40; + public static final int NUM_LOOPS = 100; + + //INT + private static ArrayList> intDateTestStart; + private static ArrayList intDateTestMissing; + private static ArrayList> intStringTestStart; + private static ArrayList intStringTestMissing; + + //LONG + private static ArrayList> longDateTestStart; + private static ArrayList longDateTestMissing; + private static ArrayList> longStringTestStart; + private static ArrayList longStringTestMissing; + + //FLOAT + private static ArrayList> floatDateTestStart; + private static ArrayList floatDateTestMissing; + private static ArrayList> floatStringTestStart; + private static ArrayList floatStringTestMissing; + + //DOUBLE + private static ArrayList> doubleDateTestStart; + private static ArrayList doubleDateTestMissing; + private static ArrayList> doubleStringTestStart; + private static ArrayList doubleStringTestMissing; + + //DATE + private static ArrayList> dateIntTestStart; + private static ArrayList dateIntTestMissing; + private static ArrayList> dateLongTestStart; + private static ArrayList dateLongTestMissing; + + //String + private static ArrayList> stringIntTestStart; + private static ArrayList stringIntTestMissing; + private static ArrayList> stringLongTestStart; + private static ArrayList stringLongTestMissing; + + //Multi-Valued + private static ArrayList> multiLongTestStart; + private static ArrayList multiLongTestMissing; + private static ArrayList> multiStringTestStart; + private static ArrayList multiStringTestMissing; + private static ArrayList> multiDateTestStart; + private static ArrayList multiDateTestMissing; + + static String response; + + @BeforeClass + public static void beforeClass() throws Exception { + initCore("solrconfig-basic.xml","schema-analytics.xml"); + h.update("*:*"); + + defaults.put("int", new Integer(0)); + defaults.put("long", new Long(0)); + defaults.put("float", new Float(0)); + defaults.put("double", new Double(0)); + defaults.put("date", "1800-12-31T23:59:59Z"); + defaults.put("string", "str0"); + + //INT + intDateTestStart = new ArrayList>(); + intDateTestMissing = new ArrayList(); + intStringTestStart = new ArrayList>(); + intStringTestMissing = new ArrayList(); + + //LONG + longDateTestStart = new ArrayList>(); + longDateTestMissing = new ArrayList(); + longStringTestStart = new ArrayList>(); + longStringTestMissing = new ArrayList(); + + //FLOAT + floatDateTestStart = new ArrayList>(); + floatDateTestMissing = new ArrayList(); + floatStringTestStart = new ArrayList>(); + floatStringTestMissing = new ArrayList(); + + //DOUBLE + doubleDateTestStart = new ArrayList>(); + doubleDateTestMissing = new ArrayList(); + doubleStringTestStart = new ArrayList>(); + doubleStringTestMissing = new ArrayList(); + + //DATE + dateIntTestStart = new ArrayList>(); + dateIntTestMissing = new ArrayList(); + dateLongTestStart = new ArrayList>(); + dateLongTestMissing = new ArrayList(); + + //String + stringIntTestStart = new ArrayList>(); + stringIntTestMissing = new ArrayList(); + stringLongTestStart = new ArrayList>(); + stringLongTestMissing = new ArrayList(); + + //Multi-Valued + multiLongTestStart = new ArrayList>(); + multiLongTestMissing = new ArrayList(); + multiStringTestStart = new ArrayList>(); + multiStringTestMissing = new ArrayList(); + multiDateTestStart = new ArrayList>(); + multiDateTestMissing = new ArrayList(); + + for (int j = 0; j < NUM_LOOPS; ++j) { + int i = j%INT; + long l = j%LONG; + long lm = j%LONGM; + float f = j%FLOAT; + double d = j%DOUBLE; + int dt = j%DATE; + int dtm = j%DATEM; + int s = j%STRING; + int sm = j%STRINGM; + if (dt==0 && dtm == 0) { + assertU(adoc(filter("id", "1000" + j, "int_id", "" + i, "long_ld", "" + l, "float_fd", "" + f, + "double_dd", "" + d, "date_dtd", (1800+dt) + "-12-31T23:59:59Z", "string_sd", "str" + s, + "long_ldm", "" + l, "long_ldm", ""+lm, "string_sdm", "str" + s, "string_sdm", "str"+sm))); + } else if (dt == 0) { + assertU(adoc(filter("id", "1000" + j, "int_id", "" + i, "long_ld", "" + l, "float_fd", "" + f, + "double_dd", "" + d, "date_dtd", (1800+dt) + "-12-31T23:59:59Z", "string_sd", "str" + s, + "long_ldm", "" + l, "long_ldm", ""+lm, "string_sdm", "str" + s, "string_sdm", "str"+sm, + "date_dtdm", (1800+dtm) + "-12-31T23:59:59Z"))); + } else if (dtm == 0) { + assertU(adoc(filter("id", "1000" + j, "int_id", "" + i, "long_ld", "" + l, "float_fd", "" + f, + "double_dd", "" + d, "date_dtd", (1800+dt) + "-12-31T23:59:59Z", "string_sd", "str" + s, + "long_ldm", "" + l, "long_ldm", ""+lm, "string_sdm", "str" + s, "string_sdm", "str"+sm, + "date_dtdm", (1800+dt) + "-12-31T23:59:59Z"))); + } else { + assertU(adoc(filter("id", "1000" + j, "int_id", "" + i, "long_ld", "" + l, "float_fd", "" + f, + "double_dd", "" + d, "date_dtd", (1800+dt) + "-12-31T23:59:59Z", "string_sd", "str" + s, + "long_ldm", "" + l, "long_ldm", ""+lm, "string_sdm", "str" + s, "string_sdm", "str"+sm, + "date_dtdm", (1800+dt) + "-12-31T23:59:59Z", "date_dtdm", (1800+dtm) + "-12-31T23:59:59Z"))); + } + + if( dt != 0 ){ + //Dates + if (j-DATE<0) { + ArrayList list1 = new ArrayList(); + if( i != 0 ){ + list1.add(i); + intDateTestMissing.add(0l); + } else { + intDateTestMissing.add(1l); + } + intDateTestStart.add(list1); + ArrayList list2 = new ArrayList(); + if( l != 0l ){ + list2.add(l); + longDateTestMissing.add(0l); + } else { + longDateTestMissing.add(1l); + } + longDateTestStart.add(list2); + ArrayList list3 = new ArrayList(); + if ( f != 0.0f ){ + list3.add(f); + floatDateTestMissing.add(0l); + } else { + floatDateTestMissing.add(1l); + + } + floatDateTestStart.add(list3); + ArrayList list4 = new ArrayList(); + if( d != 0.0d ){ + list4.add(d); + doubleDateTestMissing.add(0l); + } else { + doubleDateTestMissing.add(1l); + } + doubleDateTestStart.add(list4); + ArrayList list5 = new ArrayList(); + if( i != 0 ){ + list5.add(i); + multiDateTestMissing.add(0l); + } else { + multiDateTestMissing.add(1l); + + } + multiDateTestStart.add(list5); + } else { + if( i != 0 ) intDateTestStart.get(dt-1).add(i); else increment(intDateTestMissing,dt-1); + if( l != 0l ) longDateTestStart.get(dt-1).add(l); else increment(longDateTestMissing,dt-1); + if( f != 0.0f ) floatDateTestStart.get(dt-1).add(f); else increment(floatDateTestMissing,dt-1); + if( d != 0.0d ) doubleDateTestStart.get(dt-1).add(d); else increment(doubleDateTestMissing,dt-1); + if( i != 0 ) multiDateTestStart.get(dt-1).add(i); else increment(multiDateTestMissing,dt-1); + } + } + + if (j-DATEM<0 && dtm!=dt && dtm!=0) { + ArrayList list1 = new ArrayList(); + if( i != 0 ){ + list1.add(i); + multiDateTestMissing.add(0l); + } else { + multiDateTestMissing.add(1l); + } + multiDateTestStart.add(list1); + } else if (dtm!=dt && dtm!=0) { + if( i != 0 ) multiDateTestStart.get(dtm-1).add(i); + } + + if( s != 0 ){ + //Strings + if (j-STRING<0) { + ArrayList list1 = new ArrayList(); + if( i != 0 ){ + list1.add(i); + intStringTestMissing.add(0l); + } else { + intStringTestMissing.add(1l); + } + intStringTestStart.add(list1); + ArrayList list2 = new ArrayList(); + if( l != 0l ){ + list2.add(l); + longStringTestMissing.add(0l); + } else { + longStringTestMissing.add(1l); + } + longStringTestStart.add(list2); + ArrayList list3 = new ArrayList(); + if( f != 0.0f ){ + list3.add(f); + floatStringTestMissing.add(0l); + } else { + floatStringTestMissing.add(1l); + } + floatStringTestStart.add(list3); + ArrayList list4 = new ArrayList(); + if( d != 0.0d ){ + list4.add(d); + doubleStringTestMissing.add(0l); + } else { + doubleStringTestMissing.add(1l); + } + doubleStringTestStart.add(list4); + ArrayList list5 = new ArrayList(); + if( i != 0 ){ + list5.add(i); + multiStringTestMissing.add(0l); + } else { + multiStringTestMissing.add(1l); + } + multiStringTestStart.add(list5); + } else { + if( i != 0 ) intStringTestStart.get(s-1).add(i); else increment(intStringTestMissing,s-1); + if( l != 0l ) longStringTestStart.get(s-1).add(l); else increment(longStringTestMissing,s-1); + if( f != 0.0f ) floatStringTestStart.get(s-1).add(f); else increment(floatStringTestMissing,s-1); + if( d != 0.0d ) doubleStringTestStart.get(s-1).add(d); else increment(doubleStringTestMissing,s-1); + if( i != 0 ) multiStringTestStart.get(s-1).add(i); else increment(multiStringTestMissing,s-1); + } + } + + //Strings + if( sm != 0 ){ + if (j-STRINGM<0&&sm!=s) { + ArrayList list1 = new ArrayList(); + if( i != 0 ){ + list1.add(i); + multiStringTestMissing.add(0l); + } else { + multiStringTestMissing.add(1l); + } + multiStringTestStart.add(list1); + } else if (sm!=s) { + if( i != 0 ) multiStringTestStart.get(sm-1).add(i); else increment(multiStringTestMissing,sm-1); + } + } + + //Int + if( i != 0 ){ + if (j-INT<0) { + ArrayList list1 = new ArrayList(); + if( dt != 0 ){ + list1.add((1800+dt) + "-12-31T23:59:59Z"); + dateIntTestMissing.add(0l); + } else { + dateIntTestMissing.add(1l); + } + dateIntTestStart.add(list1); + ArrayList list2 = new ArrayList(); + if( s != 0 ){ + list2.add("str"+s); + stringIntTestMissing.add(0l); + } else { + stringIntTestMissing.add(1l); + } + stringIntTestStart.add(list2); + } else { + if( dt != 0 ) dateIntTestStart.get(i-1).add((1800+dt) + "-12-31T23:59:59Z"); else increment(dateIntTestMissing,i-1); + if( s != 0 ) stringIntTestStart.get(i-1).add("str"+s); else increment(stringIntTestMissing,i-1); + } + } + + //Long + if( l != 0 ){ + if (j-LONG<0) { + ArrayList list1 = new ArrayList(); + if( dt != 0 ){ + list1.add((1800+dt) + "-12-31T23:59:59Z"); + dateLongTestMissing.add(0l); + } else { + dateLongTestMissing.add(1l); + } + dateLongTestStart.add(list1); + ArrayList list2 = new ArrayList(); + if( s != 0 ){ + list2.add("str"+s); + stringLongTestMissing.add(0l); + } else { + stringLongTestMissing.add(1l); + } + stringLongTestStart.add(list2); + ArrayList list3 = new ArrayList(); + if( i != 0 ){ + list3.add(i); + multiLongTestMissing.add(0l); + } else { + multiLongTestMissing.add(1l); + } + multiLongTestStart.add(list3); + } else { + if( dt != 0 ) dateLongTestStart.get((int)l-1).add((1800+dt) + "-12-31T23:59:59Z"); else increment(dateLongTestMissing,(int)l-1); + if( s != 0 ) stringLongTestStart.get((int)l-1).add("str"+s); else increment(stringLongTestMissing,(int)l-1); + if( i != 0 ) multiLongTestStart.get((int)l-1).add(i); else increment(multiLongTestMissing,(int)l-1); + } + } + + //Long + if( lm != 0 ){ + if (j-LONGM<0&&lm!=l) { + ArrayList list1 = new ArrayList(); + if( i != 0 ){ + list1.add(i); + multiLongTestMissing.add(0l); + } else { + multiLongTestMissing.add(1l); + } + multiLongTestStart.add(list1); + } else if (lm!=l) { + if( i != 0 ) multiLongTestStart.get((int)lm-1).add(i); else increment( multiLongTestMissing,(int)lm-1); + } + } + + if (usually()) { + commit(); // to have several segments + } + } + + assertU(commit()); + response = h.query(request(fileToStringArr(fileName))); + } + + @SuppressWarnings("unchecked") + @Test + public void sumTest() throws Exception { + //Int Date + String intDateFacet = getFacetXML(response, "sum","fieldFacets", "date_dtd"); + Collection intDate = (ArrayList)xmlToList(intDateFacet, "double", "int"); + ArrayList intDateTest = calculateNumberStat(intDateTestStart, "sum"); + assertEquals(intDate,intDateTest); + //Int String + String intStringFacet = getFacetXML(response, "sum","fieldFacets", "string_sd"); + Collection intString = (ArrayList)xmlToList(intStringFacet, "double", "int"); + ArrayList intStringTest = calculateNumberStat(intStringTestStart, "sum"); + assertEquals(intString,intStringTest); + + //Long Date + String longDateFacet = getFacetXML(response, "sum","fieldFacets", "date_dtd"); + Collection longDate = (ArrayList)xmlToList(longDateFacet, "double", "long"); + ArrayList longDateTest = calculateNumberStat(longDateTestStart, "sum"); + assertEquals(longDate,longDateTest); + //Long String + String longStringFacet = getFacetXML(response, "sum","fieldFacets", "string_sd"); + Collection longString = (ArrayList)xmlToList(longStringFacet, "double", "long"); + ArrayList longStringTest = calculateNumberStat(longStringTestStart, "sum"); + assertEquals(longString,longStringTest); + + //Float Date + String floatDateFacet = getFacetXML(response, "sum","fieldFacets", "date_dtd"); + Collection floatDate = (ArrayList)xmlToList(floatDateFacet, "double", "float"); + ArrayList floatDateTest = calculateNumberStat(floatDateTestStart, "sum"); + assertEquals(floatDate,floatDateTest); + //Float String + String floatStringFacet = getFacetXML(response, "sum","fieldFacets", "string_sd"); + Collection floatString = (ArrayList)xmlToList(floatStringFacet, "double", "float"); + ArrayList floatStringTest = calculateNumberStat(floatStringTestStart, "sum"); + assertEquals(floatString,floatStringTest); + + //Double Date + String doubleDateFacet = getFacetXML(response, "sum","fieldFacets", "date_dtd"); + Collection doubleDate = (ArrayList)xmlToList(doubleDateFacet, "double", "double"); + ArrayList doubleDateTest = calculateNumberStat(doubleDateTestStart, "sum"); + assertEquals(doubleDate,doubleDateTest); + //Double String + String doubleStringFacet = getFacetXML(response, "sum","fieldFacets", "string_sd"); + Collection doubleString = (ArrayList)xmlToList(doubleStringFacet, "double", "double"); + ArrayList doubleStringTest = calculateNumberStat(doubleStringTestStart, "sum"); + assertEquals(doubleString,doubleStringTest); + } + + @SuppressWarnings("unchecked") + @Test + public void meanTest() throws Exception { + //Int Date + String intDateFacet = getFacetXML(response, "mean","fieldFacets", "date_dtd"); + Collection intDate = (ArrayList)xmlToList(intDateFacet, "double", "int"); + ArrayList intDateTest = calculateNumberStat(intDateTestStart, "mean"); + assertEquals(intDate,intDateTest); + //Int String + String intStringFacet = getFacetXML(response, "mean","fieldFacets", "string_sd"); + Collection intString = (ArrayList)xmlToList(intStringFacet, "double", "int"); + ArrayList intStringTest = calculateNumberStat(intStringTestStart, "mean"); + assertEquals(intString,intStringTest); + + //Long Date + String longDateFacet = getFacetXML(response, "mean","fieldFacets", "date_dtd"); + Collection longDate = (ArrayList)xmlToList(longDateFacet, "double", "long"); + ArrayList longDateTest = calculateNumberStat(longDateTestStart, "mean"); + assertEquals(longDate,longDateTest); + //Long String + String longStringFacet = getFacetXML(response, "mean","fieldFacets", "string_sd"); + Collection longString = (ArrayList)xmlToList(longStringFacet, "double", "long"); + ArrayList longStringTest = calculateNumberStat(longStringTestStart, "mean"); + assertEquals(longString,longStringTest); + + //Float Date + String floatDateFacet = getFacetXML(response, "mean","fieldFacets", "date_dtd"); + Collection floatDate = (ArrayList)xmlToList(floatDateFacet, "double", "float"); + ArrayList floatDateTest = calculateNumberStat(floatDateTestStart, "mean"); + assertEquals(floatDate,floatDateTest); + //Float String + String floatStringFacet = getFacetXML(response, "mean","fieldFacets", "string_sd"); + Collection floatString = (ArrayList)xmlToList(floatStringFacet, "double", "float"); + ArrayList floatStringTest = calculateNumberStat(floatStringTestStart, "mean"); + assertEquals(floatString,floatStringTest); + + //Double Date + String doubleDateFacet = getFacetXML(response, "mean","fieldFacets", "date_dtd"); + Collection doubleDate = (ArrayList)xmlToList(doubleDateFacet, "double", "double"); + ArrayList doubleDateTest = calculateNumberStat(doubleDateTestStart, "mean"); + assertEquals(doubleDate,doubleDateTest); + //Double String + String doubleStringFacet = getFacetXML(response, "mean","fieldFacets", "string_sd"); + Collection doubleString = (ArrayList)xmlToList(doubleStringFacet, "double", "double"); + ArrayList doubleStringTest = calculateNumberStat(doubleStringTestStart, "mean"); + assertEquals(doubleString,doubleStringTest); + } + + @SuppressWarnings("unchecked") + @Test + public void sumOfSquaresFacetAscTest() throws Exception { + //Int Date + String intDateFacet = getFacetXML(response, "sumOfSquares","fieldFacets", "date_dtd"); + Collection intDate = (ArrayList)xmlToList(intDateFacet, "double", "int"); + ArrayList intDateTest = calculateNumberStat(intDateTestStart, "sumOfSquares"); + assertEquals(intDate,intDateTest); + //Int String + String intStringFacet = getFacetXML(response, "sumOfSquares","fieldFacets", "string_sd"); + Collection intString = (ArrayList)xmlToList(intStringFacet, "double", "int"); + ArrayList intStringTest = calculateNumberStat(intStringTestStart, "sumOfSquares"); + assertEquals(intString,intStringTest); + + //Long Date + String longDateFacet = getFacetXML(response, "sumOfSquares","fieldFacets", "date_dtd"); + Collection longDate = (ArrayList)xmlToList(longDateFacet, "double", "long"); + ArrayList longDateTest = calculateNumberStat(longDateTestStart, "sumOfSquares"); + assertEquals(longDate,longDateTest); + //Long String + String longStringFacet = getFacetXML(response, "sumOfSquares","fieldFacets", "string_sd"); + Collection longString = (ArrayList)xmlToList(longStringFacet, "double", "long"); + ArrayList longStringTest = calculateNumberStat(longStringTestStart, "sumOfSquares"); + assertEquals(longString,longStringTest); + + //Float Date + String floatDateFacet = getFacetXML(response, "sumOfSquares","fieldFacets", "date_dtd"); + Collection floatDate = (ArrayList)xmlToList(floatDateFacet, "double", "float"); + ArrayList floatDateTest = calculateNumberStat(floatDateTestStart, "sumOfSquares"); + assertEquals(floatDate,floatDateTest); + //Float String + String floatStringFacet = getFacetXML(response, "sumOfSquares","fieldFacets", "string_sd"); + Collection floatString = (ArrayList)xmlToList(floatStringFacet, "double", "float"); + ArrayList floatStringTest = calculateNumberStat(floatStringTestStart, "sumOfSquares"); + assertEquals(floatString,floatStringTest); + + //Double Date + String doubleDateFacet = getFacetXML(response, "sumOfSquares","fieldFacets", "date_dtd"); + Collection doubleDate = (ArrayList)xmlToList(doubleDateFacet, "double", "double"); + ArrayList doubleDateTest = calculateNumberStat(doubleDateTestStart, "sumOfSquares"); + assertEquals(doubleDate,doubleDateTest); + //Double String + String doubleStringFacet = getFacetXML(response, "sumOfSquares","fieldFacets", "string_sd"); + Collection doubleString = (ArrayList)xmlToList(doubleStringFacet, "double", "double"); + ArrayList doubleStringTest = calculateNumberStat(doubleStringTestStart, "sumOfSquares"); + assertEquals(doubleString,doubleStringTest); + } + + @SuppressWarnings("unchecked") + @Test + public void stddevFacetAscTest() throws Exception { + //Int Date + String intDateFacet = getFacetXML(response, "stddev","fieldFacets", "date_dtd"); + ArrayList intDate = (ArrayList)xmlToList(intDateFacet, "double", "int"); + ArrayList intDateTest = calculateNumberStat(intDateTestStart, "stddev"); + assertTrue(checkStddevs(intDate,intDateTest)); + //Int String + String intStringFacet = getFacetXML(response, "stddev","fieldFacets", "string_sd"); + ArrayList intString = (ArrayList)xmlToList(intStringFacet, "double", "int"); + ArrayList intStringTest = calculateNumberStat(intStringTestStart, "stddev"); + assertTrue(checkStddevs(intString,intStringTest)); + + //Long Date + String longDateFacet = getFacetXML(response, "stddev","fieldFacets", "date_dtd"); + ArrayList longDate = (ArrayList)xmlToList(longDateFacet, "double", "long"); + ArrayList longDateTest = calculateNumberStat(longDateTestStart, "stddev"); + assertTrue(checkStddevs(longDate,longDateTest)); + //Long String + String longStringFacet = getFacetXML(response, "stddev","fieldFacets", "string_sd"); + ArrayList longString = (ArrayList)xmlToList(longStringFacet, "double", "long"); + ArrayList longStringTest = calculateNumberStat(longStringTestStart, "stddev"); + assertTrue(checkStddevs(longString,longStringTest)); + + //Float Date + String floatDateFacet = getFacetXML(response, "stddev","fieldFacets", "date_dtd"); + ArrayList floatDate = (ArrayList)xmlToList(floatDateFacet, "double", "float"); + ArrayList floatDateTest = calculateNumberStat(floatDateTestStart, "stddev"); + assertTrue(checkStddevs(floatDate,floatDateTest)); + //Float String + String floatStringFacet = getFacetXML(response, "stddev","fieldFacets", "string_sd"); + ArrayList floatString = (ArrayList)xmlToList(floatStringFacet, "double", "float"); + ArrayList floatStringTest = calculateNumberStat(floatStringTestStart, "stddev"); + assertTrue(checkStddevs(floatString,floatStringTest)); + + //Double Date + String doubleDateFacet = getFacetXML(response, "stddev","fieldFacets", "date_dtd"); + ArrayList doubleDate = (ArrayList)xmlToList(doubleDateFacet, "double", "double"); + ArrayList doubleDateTest = calculateNumberStat(doubleDateTestStart, "stddev"); + assertTrue(checkStddevs(doubleDate,doubleDateTest)); + //Double String + String doubleStringFacet = getFacetXML(response, "stddev","fieldFacets", "string_sd"); + ArrayList doubleString = (ArrayList)xmlToList(doubleStringFacet, "double", "double"); + ArrayList doubleStringTest = calculateNumberStat(doubleStringTestStart, "stddev"); + assertTrue(checkStddevs(doubleString,doubleStringTest)); + } + + @SuppressWarnings("unchecked") + @Test + public void medianFacetAscTest() throws Exception { + //Int Date + String intDateFacet = getFacetXML(response, "median","fieldFacets", "date_dtd"); + Collection intDate = (ArrayList)xmlToList(intDateFacet, "double", "int"); + ArrayList intDateTest = calculateNumberStat(intDateTestStart, "median"); + assertEquals(intDate,intDateTest); + //Int String + String intStringFacet = getFacetXML(response, "median","fieldFacets", "string_sd"); + Collection intString = (ArrayList)xmlToList(intStringFacet, "double", "int"); + ArrayList intStringTest = calculateNumberStat(intStringTestStart, "median"); + assertEquals(intString,intStringTest); + + //Long Date + String longDateFacet = getFacetXML(response, "median","fieldFacets", "date_dtd"); + Collection longDate = (ArrayList)xmlToList(longDateFacet, "double", "long"); + ArrayList longDateTest = calculateNumberStat(longDateTestStart, "median"); + assertEquals(longDate,longDateTest); + //Long String + String longStringFacet = getFacetXML(response, "median","fieldFacets", "string_sd"); + Collection longString = (ArrayList)xmlToList(longStringFacet, "double", "long"); + ArrayList longStringTest = calculateNumberStat(longStringTestStart, "median"); + assertEquals(longString,longStringTest); + + //Float Date + String floatDateFacet = getFacetXML(response, "median","fieldFacets", "date_dtd"); + Collection floatDate = (ArrayList)xmlToList(floatDateFacet, "double", "float"); + ArrayList floatDateTest = calculateNumberStat(floatDateTestStart, "median"); + assertEquals(floatDate,floatDateTest); + //Float String + String floatStringFacet = getFacetXML(response, "median","fieldFacets", "string_sd"); + Collection floatString = (ArrayList)xmlToList(floatStringFacet, "double", "float"); + ArrayList floatStringTest = calculateNumberStat(floatStringTestStart, "median"); + assertEquals(floatString,floatStringTest); + + //Double Date + String doubleDateFacet = getFacetXML(response, "median","fieldFacets", "date_dtd"); + Collection doubleDate = (ArrayList)xmlToList(doubleDateFacet, "double", "double"); + ArrayList doubleDateTest = calculateNumberStat(doubleDateTestStart, "median"); + assertEquals(doubleDate,doubleDateTest); + //Double String + String doubleStringFacet = getFacetXML(response, "median","fieldFacets", "string_sd"); + Collection doubleString = (ArrayList)xmlToList(doubleStringFacet, "double", "double"); + ArrayList doubleStringTest = calculateNumberStat(doubleStringTestStart, "median"); + assertEquals(doubleString,doubleStringTest); + } + + @SuppressWarnings("unchecked") + @Test + public void perc20Test() throws Exception { + //Int Date + String intDateFacet = getFacetXML(response, "percentile_20n","fieldFacets", "date_dtd"); + Collection intDate = (ArrayList)xmlToList(intDateFacet, "int", "int"); + ArrayList intDateTest = (ArrayList)calculateStat(intDateTestStart, "perc_20"); + assertEquals(intDate,intDateTest); + //Int String + String intStringFacet = getFacetXML(response, "percentile_20n","fieldFacets", "string_sd"); + Collection intString = (ArrayList)xmlToList(intStringFacet, "int", "int"); + ArrayList intStringTest = (ArrayList)calculateStat(intStringTestStart, "perc_20"); + assertEquals(intString,intStringTest); + + //Long Date + String longDateFacet = getFacetXML(response, "percentile_20n","fieldFacets", "date_dtd"); + Collection longDate = (ArrayList)xmlToList(longDateFacet, "long", "long"); + ArrayList longDateTest = (ArrayList)calculateStat(longDateTestStart, "perc_20"); + assertEquals(longDate,longDateTest); + //Long String + String longStringFacet = getFacetXML(response, "percentile_20n","fieldFacets", "string_sd"); + Collection longString = (ArrayList)xmlToList(longStringFacet, "long", "long"); + ArrayList longStringTest = (ArrayList)calculateStat(longStringTestStart, "perc_20"); + assertEquals(longString,longStringTest); + + //Float Date + String floatDateFacet = getFacetXML(response, "percentile_20n","fieldFacets", "date_dtd"); + Collection floatDate = (ArrayList)xmlToList(floatDateFacet, "float", "float"); + ArrayList floatDateTest = (ArrayList)calculateStat(floatDateTestStart, "perc_20"); + assertEquals(floatDate,floatDateTest); + //Float String + String floatStringFacet = getFacetXML(response, "percentile_20n","fieldFacets", "string_sd"); + Collection floatString = (ArrayList)xmlToList(floatStringFacet, "float", "float"); + ArrayList floatStringTest = (ArrayList)calculateStat(floatStringTestStart, "perc_20"); + assertEquals(floatString,floatStringTest); + + //Double Date + String doubleDateFacet = getFacetXML(response, "percentile_20n","fieldFacets", "date_dtd"); + Collection doubleDate = (ArrayList)xmlToList(doubleDateFacet, "double", "double"); + ArrayList doubleDateTest = (ArrayList)calculateStat(doubleDateTestStart, "perc_20"); + assertEquals(doubleDate,doubleDateTest); + //Double String + String doubleStringFacet = getFacetXML(response, "percentile_20n","fieldFacets", "string_sd"); + Collection doubleString = (ArrayList)xmlToList(doubleStringFacet, "double", "double"); + ArrayList doubleStringTest = (ArrayList)calculateStat(doubleStringTestStart, "perc_20"); + assertEquals(doubleString,doubleStringTest); + + //Date Int + String dateIntFacet = getFacetXML(response, "percentile_20","fieldFacets", "int_id"); + Collection dateInt = (ArrayList)xmlToList(dateIntFacet, "date", "date"); + ArrayList dateIntTest = (ArrayList)calculateStat(dateIntTestStart, "perc_20"); + assertEquals(dateInt,dateIntTest); + //Date Long + String dateStringFacet = getFacetXML(response, "percentile_20","fieldFacets", "long_ld"); + Collection dateString = (ArrayList)xmlToList(dateStringFacet, "date", "date"); + ArrayList dateLongTest = (ArrayList)calculateStat(dateLongTestStart, "perc_20"); + assertEquals(dateString,dateLongTest); + + //String Int + String stringIntFacet = getFacetXML(response, "percentile_20","fieldFacets", "int_id"); + Collection stringInt = (ArrayList)xmlToList(stringIntFacet, "str", "str"); + ArrayList stringIntTest = (ArrayList)calculateStat(stringIntTestStart, "perc_20"); + assertEquals(stringInt,stringIntTest); + //String Long + String stringLongFacet = getFacetXML(response, "percentile_20","fieldFacets", "long_ld"); + Collection stringLong = (ArrayList)xmlToList(stringLongFacet, "str", "str"); + ArrayList stringLongTest = (ArrayList)calculateStat(stringLongTestStart, "perc_20"); + assertEquals(stringLong,stringLongTest); + } + + @SuppressWarnings("unchecked") + @Test + public void perc60Test() throws Exception { + //Int Date + String intDateFacet = getFacetXML(response, "percentile_60n","fieldFacets", "date_dtd"); + Collection intDate = (ArrayList)xmlToList(intDateFacet, "int", "int"); + ArrayList intDateTest = (ArrayList)calculateStat(intDateTestStart, "perc_60"); + assertEquals(intDate,intDateTest); + //Int String + String intStringFacet = getFacetXML(response, "percentile_60n","fieldFacets", "string_sd"); + Collection intString = (ArrayList)xmlToList(intStringFacet, "int", "int"); + ArrayList intStringTest = (ArrayList)calculateStat(intStringTestStart, "perc_60"); + assertEquals(intString,intStringTest); + + //Long Date + String longDateFacet = getFacetXML(response, "percentile_60n","fieldFacets", "date_dtd"); + Collection longDate = (ArrayList)xmlToList(longDateFacet, "long", "long"); + ArrayList longDateTest = (ArrayList)calculateStat(longDateTestStart, "perc_60"); + assertEquals(longDate,longDateTest); + //Long String + String longStringFacet = getFacetXML(response, "percentile_60n","fieldFacets", "string_sd"); + Collection longString = (ArrayList)xmlToList(longStringFacet, "long", "long"); + ArrayList longStringTest = (ArrayList)calculateStat(longStringTestStart, "perc_60"); + assertEquals(longString,longStringTest); + + //Float Date + String floatDateFacet = getFacetXML(response, "percentile_60n","fieldFacets", "date_dtd"); + Collection floatDate = (ArrayList)xmlToList(floatDateFacet, "float", "float"); + ArrayList floatDateTest = (ArrayList)calculateStat(floatDateTestStart, "perc_60"); + assertEquals(floatDate,floatDateTest); + //Float String + String floatStringFacet = getFacetXML(response, "percentile_60n","fieldFacets", "string_sd"); + Collection floatString = (ArrayList)xmlToList(floatStringFacet, "float", "float"); + ArrayList floatStringTest = (ArrayList)calculateStat(floatStringTestStart, "perc_60"); + assertEquals(floatString,floatStringTest); + + //Double Date + String doubleDateFacet = getFacetXML(response, "percentile_60n","fieldFacets", "date_dtd"); + Collection doubleDate = (ArrayList)xmlToList(doubleDateFacet, "double", "double"); + ArrayList doubleDateTest = (ArrayList)calculateStat(doubleDateTestStart, "perc_60"); + assertEquals(doubleDate,doubleDateTest); + //Double String + String doubleStringFacet = getFacetXML(response, "percentile_60n","fieldFacets", "string_sd"); + Collection doubleString = (ArrayList)xmlToList(doubleStringFacet, "double", "double"); + ArrayList doubleStringTest = (ArrayList)calculateStat(doubleStringTestStart, "perc_60"); + assertEquals(doubleString,doubleStringTest); + + //Date Int + String dateIntFacet = getFacetXML(response, "percentile_60","fieldFacets", "int_id"); + Collection dateInt = (ArrayList)xmlToList(dateIntFacet, "date", "date"); + ArrayList dateIntTest = (ArrayList)calculateStat(dateIntTestStart, "perc_60"); + assertEquals(dateInt,dateIntTest); + //Date Long + String dateStringFacet = getFacetXML(response, "percentile_60","fieldFacets", "long_ld"); + Collection dateString = (ArrayList)xmlToList(dateStringFacet, "date", "date"); + ArrayList dateLongTest = (ArrayList)calculateStat(dateLongTestStart, "perc_60"); + assertEquals(dateString,dateLongTest); + + //String Int + String stringIntFacet = getFacetXML(response, "percentile_60","fieldFacets", "int_id"); + Collection stringInt = (ArrayList)xmlToList(stringIntFacet, "str", "str"); + ArrayList stringIntTest = (ArrayList)calculateStat(stringIntTestStart, "perc_60"); + assertEquals(stringInt,stringIntTest); + //String Long + String stringLongFacet = getFacetXML(response, "percentile_60","fieldFacets", "long_ld"); + Collection stringLong = (ArrayList)xmlToList(stringLongFacet, "str", "str"); + ArrayList stringLongTest = (ArrayList)calculateStat(stringLongTestStart, "perc_60"); + assertEquals(stringLong,stringLongTest); + } + + @SuppressWarnings("unchecked") + @Test + public void minTest() throws Exception { + //Int Date + String intDateFacet = getFacetXML(response, "minn","fieldFacets", "date_dtd"); + Collection intDate = (ArrayList)xmlToList(intDateFacet, "int", "int"); + ArrayList intDateTest = (ArrayList)calculateStat(intDateTestStart, "min"); + assertEquals(intDate,intDateTest); + //Int String + String intStringFacet = getFacetXML(response, "minn","fieldFacets", "string_sd"); + Collection intString = (ArrayList)xmlToList(intStringFacet, "int", "int"); + ArrayList intStringTest = (ArrayList)calculateStat(intStringTestStart, "min"); + assertEquals(intString,intStringTest); + + //Long Date + String longDateFacet = getFacetXML(response, "minn","fieldFacets", "date_dtd"); + Collection longDate = (ArrayList)xmlToList(longDateFacet, "long", "long"); + ArrayList longDateTest = (ArrayList)calculateStat(longDateTestStart, "min"); + assertEquals(longDate,longDateTest); + //Long String + String longStringFacet = getFacetXML(response, "minn","fieldFacets", "string_sd"); + Collection longString = (ArrayList)xmlToList(longStringFacet, "long", "long"); + ArrayList longStringTest = (ArrayList)calculateStat(longStringTestStart, "min"); + assertEquals(longString,longStringTest); + + //Float Date + String floatDateFacet = getFacetXML(response, "minn","fieldFacets", "date_dtd"); + Collection floatDate = (ArrayList)xmlToList(floatDateFacet, "float", "float"); + ArrayList floatDateTest = (ArrayList)calculateStat(floatDateTestStart, "min"); + assertEquals(floatDate,floatDateTest); + //Float String + String floatStringFacet = getFacetXML(response, "minn","fieldFacets", "string_sd"); + Collection floatString = (ArrayList)xmlToList(floatStringFacet, "float", "float"); + ArrayList floatStringTest = (ArrayList)calculateStat(floatStringTestStart, "min"); + assertEquals(floatString,floatStringTest); + + //Double Date + String doubleDateFacet = getFacetXML(response, "minn","fieldFacets", "date_dtd"); + Collection doubleDate = (ArrayList)xmlToList(doubleDateFacet, "double", "double"); + ArrayList doubleDateTest = (ArrayList)calculateStat(doubleDateTestStart, "min"); + assertEquals(doubleDate,doubleDateTest); + //Double String + String doubleStringFacet = getFacetXML(response, "minn","fieldFacets", "string_sd"); + Collection doubleString = (ArrayList)xmlToList(doubleStringFacet, "double", "double"); + ArrayList doubleStringTest = (ArrayList)calculateStat(doubleStringTestStart, "min"); + assertEquals(doubleString,doubleStringTest); + + //Date Int + String dateIntFacet = getFacetXML(response, "min","fieldFacets", "int_id"); + Collection dateInt = (ArrayList)xmlToList(dateIntFacet, "date", "date"); + ArrayList dateIntTest = (ArrayList)calculateStat(dateIntTestStart, "min"); + assertEquals(dateInt,dateIntTest); + //Date Long + String dateStringFacet = getFacetXML(response, "min","fieldFacets", "long_ld"); + Collection dateString = (ArrayList)xmlToList(dateStringFacet, "date", "date"); + ArrayList dateLongTest = (ArrayList)calculateStat(dateLongTestStart, "min"); + assertEquals(dateString,dateLongTest); + + //String Int + String stringIntFacet = getFacetXML(response, "min","fieldFacets", "int_id"); + Collection stringInt = (ArrayList)xmlToList(stringIntFacet, "str", "str"); + ArrayList stringIntTest = (ArrayList)calculateStat(stringIntTestStart, "min"); + assertEquals(stringInt,stringIntTest); + //String Long + String stringLongFacet = getFacetXML(response, "min","fieldFacets", "long_ld"); + Collection stringLong = (ArrayList)xmlToList(stringLongFacet, "str", "str"); + ArrayList stringLongTest = (ArrayList)calculateStat(stringLongTestStart, "min"); + assertEquals(stringLong,stringLongTest); + } + + @SuppressWarnings("unchecked") + @Test + public void maxTest() throws Exception { + //Int Date + String intDateFacet = getFacetXML(response, "maxn","fieldFacets", "date_dtd"); + Collection intDate = (ArrayList)xmlToList(intDateFacet, "int", "int"); + ArrayList intDateTest = (ArrayList)calculateStat(intDateTestStart, "max"); + assertEquals(intDate,intDateTest); + + //Int String + String intStringFacet = getFacetXML(response, "maxn","fieldFacets", "string_sd"); + Collection intString = (ArrayList)xmlToList(intStringFacet, "int", "int"); + ArrayList intStringTest = (ArrayList)calculateStat(intStringTestStart, "max"); + assertEquals(intString,intStringTest); + + //Long Date + String longDateFacet = getFacetXML(response, "maxn","fieldFacets", "date_dtd"); + Collection longDate = (ArrayList)xmlToList(longDateFacet, "long", "long"); + ArrayList longDateTest = (ArrayList)calculateStat(longDateTestStart, "max"); + assertEquals(longDate,longDateTest); + + //Long String + String longStringFacet = getFacetXML(response, "maxn","fieldFacets", "string_sd"); + Collection longString = (ArrayList)xmlToList(longStringFacet, "long", "long"); + ArrayList longStringTest = (ArrayList)calculateStat(longStringTestStart, "max"); + assertEquals(longString,longStringTest); + + //Float Date + String floatDateFacet = getFacetXML(response, "maxn","fieldFacets", "date_dtd"); + Collection floatDate = (ArrayList)xmlToList(floatDateFacet, "float", "float"); + ArrayList floatDateTest = (ArrayList)calculateStat(floatDateTestStart, "max"); + assertEquals(floatDate,floatDateTest); + + //Float String + String floatStringFacet = getFacetXML(response, "maxn","fieldFacets", "string_sd"); + Collection floatString = (ArrayList)xmlToList(floatStringFacet, "float", "float"); + ArrayList floatStringTest = (ArrayList)calculateStat(floatStringTestStart, "max"); + assertEquals(floatString,floatStringTest); + + //Double Date + String doubleDateFacet = getFacetXML(response, "maxn","fieldFacets", "date_dtd"); + Collection doubleDate = (ArrayList)xmlToList(doubleDateFacet, "double", "double"); + ArrayList doubleDateTest = (ArrayList)calculateStat(doubleDateTestStart, "max"); + assertEquals(doubleDate,doubleDateTest); + + //Double String + String doubleStringFacet = getFacetXML(response, "maxn","fieldFacets", "string_sd"); + Collection doubleString = (ArrayList)xmlToList(doubleStringFacet, "double", "double"); + ArrayList doubleStringTest = (ArrayList)calculateStat(doubleStringTestStart, "max"); + assertEquals(doubleString,doubleStringTest); + + //String Int + String stringIntFacet = getFacetXML(response, "max","fieldFacets", "int_id"); + Collection stringInt = (ArrayList)xmlToList(stringIntFacet, "str", "str"); + ArrayList stringIntTest = (ArrayList)calculateStat(stringIntTestStart, "max"); + assertEquals(stringInt,stringIntTest); + + //String Long + String stringLongFacet = getFacetXML(response, "max","fieldFacets", "long_ld"); + Collection stringLong = (ArrayList)xmlToList(stringLongFacet, "str", "str"); + ArrayList stringLongTest = (ArrayList)calculateStat(stringLongTestStart, "max"); + assertEquals(stringLong,stringLongTest); + + //Date Int + String dateIntFacet = getFacetXML(response, "max","fieldFacets", "int_id"); + Collection dateInt = (ArrayList)xmlToList(dateIntFacet, "date", "date"); + ArrayList dateIntTest = (ArrayList)calculateStat(dateIntTestStart, "max"); + assertEquals(dateInt,dateIntTest); + + //Date Long + String dateStringFacet = getFacetXML(response, "max","fieldFacets", "long_ld"); + Collection dateString = (ArrayList)xmlToList(dateStringFacet, "date", "date"); + ArrayList dateLongTest = (ArrayList)calculateStat(dateLongTestStart, "max"); + assertEquals(dateString,dateLongTest); + + } + + @SuppressWarnings("unchecked") + @Test + public void uniqueTest() throws Exception { + //Int Date + String intDateFacet = getFacetXML(response, "uniquen", "fieldFacets", "date_dtd"); + Collection intDate = (ArrayList)xmlToList(intDateFacet, "long", "int"); + ArrayList intDateTest = (ArrayList)calculateStat(intDateTestStart, "unique"); + assertEquals(intDate,intDateTest); + //Int String + String intStringFacet = getFacetXML(response, "uniquen", "fieldFacets", "string_sd"); + Collection intString = (ArrayList)xmlToList(intStringFacet, "long", "int"); + ArrayList intStringTest = (ArrayList)calculateStat(intStringTestStart, "unique"); + assertEquals(intString,intStringTest); + + //Long Date + String longDateFacet = getFacetXML(response, "uniquen", "fieldFacets", "date_dtd"); + Collection longDate = (ArrayList)xmlToList(longDateFacet, "long", "long"); + ArrayList longDateTest = (ArrayList)calculateStat(longDateTestStart, "unique"); + assertEquals(longDate,longDateTest); + //Long String + String longStringFacet = getFacetXML(response, "uniquen", "fieldFacets", "string_sd"); + Collection longString = (ArrayList)xmlToList(longStringFacet, "long", "long"); + ArrayList longStringTest = (ArrayList)calculateStat(longStringTestStart, "unique"); + assertEquals(longString,longStringTest); + + //Float Date + String floatDateFacet = getFacetXML(response, "uniquen", "fieldFacets", "date_dtd"); + Collection floatDate = (ArrayList)xmlToList(floatDateFacet, "long", "float"); + ArrayList floatDateTest = (ArrayList)calculateStat(floatDateTestStart, "unique"); + assertEquals(floatDate,floatDateTest); + //Float String + String floatStringFacet = getFacetXML(response, "uniquen", "fieldFacets", "string_sd"); + Collection floatString = (ArrayList)xmlToList(floatStringFacet, "long", "float"); + ArrayList floatStringTest = (ArrayList)calculateStat(floatStringTestStart, "unique"); + assertEquals(floatString,floatStringTest); + + //Double Date + String doubleDateFacet = getFacetXML(response, "uniquen", "fieldFacets", "date_dtd"); + Collection doubleDate = (ArrayList)xmlToList(doubleDateFacet, "long", "double"); + ArrayList doubleDateTest = (ArrayList)calculateStat(doubleDateTestStart, "unique"); + assertEquals(doubleDate,doubleDateTest); + //Double String + String doubleStringFacet = getFacetXML(response, "uniquen", "fieldFacets", "string_sd"); + Collection doubleString = (ArrayList)xmlToList(doubleStringFacet, "long", "double"); + ArrayList doubleStringTest = (ArrayList)calculateStat(doubleStringTestStart, "unique"); + assertEquals(doubleString,doubleStringTest); + + //Date Int + String dateIntFacet = getFacetXML(response, "unique", "fieldFacets", "int_id"); + Collection dateInt = (ArrayList)xmlToList(dateIntFacet, "long", "date"); + ArrayList dateIntTest = (ArrayList)calculateStat(dateIntTestStart, "unique"); + assertEquals(dateInt,dateIntTest); + //Date Long + String dateStringFacet = getFacetXML(response, "unique", "fieldFacets", "long_ld"); + Collection dateString = (ArrayList)xmlToList(dateStringFacet, "long", "date"); + ArrayList dateLongTest = (ArrayList)calculateStat(dateLongTestStart, "unique"); + assertEquals(dateString,dateLongTest); + + //String Int + String stringIntFacet = getFacetXML(response, "unique", "fieldFacets", "int_id"); + Collection stringInt = (ArrayList)xmlToList(stringIntFacet, "long", "str"); + ArrayList stringIntTest = (ArrayList)calculateStat(stringIntTestStart, "unique"); + assertEquals(stringInt,stringIntTest); + //String Long + String stringLongFacet = getFacetXML(response, "unique", "fieldFacets", "long_ld"); + Collection stringLong = (ArrayList)xmlToList(stringLongFacet, "long", "str"); + ArrayList stringLongTest = (ArrayList)calculateStat(stringLongTestStart, "unique"); + assertEquals(stringLong,stringLongTest); + } + + @SuppressWarnings("unchecked") + @Test + public void countTest() throws Exception { + //Int Date + String intDateFacet = getFacetXML(response, "countn", "fieldFacets", "date_dtd"); + Collection intDate = (ArrayList)xmlToList(intDateFacet, "long", "int"); + ArrayList intDateTest = (ArrayList)calculateStat(intDateTestStart, "count"); + assertEquals(intDate,intDateTest); + + //Int String + String intStringFacet = getFacetXML(response, "countn", "fieldFacets", "string_sd"); + Collection intString = (ArrayList)xmlToList(intStringFacet, "long", "int"); + ArrayList intStringTest = (ArrayList)calculateStat(intStringTestStart, "count"); + assertEquals(intString,intStringTest); + + //Long Date + String longDateFacet = getFacetXML(response, "countn", "fieldFacets", "date_dtd"); + Collection longDate = (ArrayList)xmlToList(longDateFacet, "long", "long"); + ArrayList longDateTest = (ArrayList)calculateStat(longDateTestStart, "count"); + assertEquals(longDate,longDateTest); + + //Long String + String longStringFacet = getFacetXML(response, "countn", "fieldFacets", "string_sd"); + Collection longString = (ArrayList)xmlToList(longStringFacet, "long", "long"); + ArrayList longStringTest = (ArrayList)calculateStat(longStringTestStart, "count"); + assertEquals(longString,longStringTest); + + //Float Date + String floatDateFacet = getFacetXML(response, "countn", "fieldFacets", "date_dtd"); + Collection floatDate = (ArrayList)xmlToList(floatDateFacet, "long", "float"); + ArrayList floatDateTest = (ArrayList)calculateStat(floatDateTestStart, "count"); + assertEquals(floatDate,floatDateTest); + + //Float String + String floatStringFacet = getFacetXML(response, "countn", "fieldFacets", "string_sd"); + Collection floatString = (ArrayList)xmlToList(floatStringFacet, "long", "float"); + ArrayList floatStringTest = (ArrayList)calculateStat(floatStringTestStart, "count"); + assertEquals(floatString,floatStringTest); + + //Double Date + String doubleDateFacet = getFacetXML(response, "countn", "fieldFacets", "date_dtd"); + Collection doubleDate = (ArrayList)xmlToList(doubleDateFacet, "long", "double"); + ArrayList doubleDateTest = (ArrayList)calculateStat(doubleDateTestStart, "count"); + assertEquals(doubleDate,doubleDateTest); + + //Double String + String doubleStringFacet = getFacetXML(response, "countn", "fieldFacets", "string_sd"); + Collection doubleString = (ArrayList)xmlToList(doubleStringFacet, "long", "double"); + ArrayList doubleStringTest = (ArrayList)calculateStat(doubleStringTestStart, "count"); + assertEquals(doubleString,doubleStringTest); + + //Date Int + String dateIntFacet = getFacetXML(response, "count", "fieldFacets", "int_id"); + Collection dateInt = (ArrayList)xmlToList(dateIntFacet, "long", "date"); + ArrayList dateIntTest = (ArrayList)calculateStat(dateIntTestStart, "count"); + assertEquals(dateIntTest,dateInt); + + //Date Long + String dateLongFacet = getFacetXML(response, "count", "fieldFacets", "long_ld"); + Collection dateLong = (ArrayList)xmlToList(dateLongFacet, "long", "date"); + ArrayList dateLongTest = (ArrayList)calculateStat(dateLongTestStart, "count"); + assertEquals(dateLong,dateLongTest); + + //String Int + String stringIntFacet = getFacetXML(response, "count", "fieldFacets", "int_id"); + Collection stringInt = (ArrayList)xmlToList(stringIntFacet, "long", "str"); + ArrayList stringIntTest = (ArrayList)calculateStat(stringIntTestStart, "count"); + assertEquals(stringInt,stringIntTest); + + //String Long + String stringLongFacet = getFacetXML(response, "count", "fieldFacets", "long_ld"); + Collection stringLong = (ArrayList)xmlToList(stringLongFacet, "long", "str"); + ArrayList stringLongTest = (ArrayList)calculateStat(stringLongTestStart, "count"); + assertEquals(stringLong,stringLongTest); + } + + @SuppressWarnings("unchecked") + @Test + public void missingTest() throws Exception { + //Int Date + String intDateFacet = getFacetXML(response, "missingn", "fieldFacets", "date_dtd"); + Collection intDate = (ArrayList)xmlToList(intDateFacet, "long", "int"); + setLatestType("int"); + assertEquals(intDateTestMissing,intDate); + + //Int String + String intStringFacet = getFacetXML(response, "missingn", "fieldFacets", "string_sd"); + Collection intString = (ArrayList)xmlToList(intStringFacet, "long", "int"); + assertEquals(intStringTestMissing,intString); + + //Long Date + String longDateFacet = getFacetXML(response, "missingn", "fieldFacets", "date_dtd"); + Collection longDate = (ArrayList)xmlToList(longDateFacet, "long", "long"); + setLatestType("long"); + assertEquals(longDateTestMissing,longDate); + + //Long String + String longStringFacet = getFacetXML(response, "missingn", "fieldFacets", "string_sd"); + Collection longString = (ArrayList)xmlToList(longStringFacet, "long", "long"); + assertEquals(longStringTestMissing,longString); + + //Float Date + String floatDateFacet = getFacetXML(response, "missingn", "fieldFacets", "date_dtd"); + Collection floatDate = (ArrayList)xmlToList(floatDateFacet, "long", "float"); + setLatestType("float"); + assertEquals(floatDateTestMissing,floatDate); + + //Float String + String floatStringFacet = getFacetXML(response, "missingn", "fieldFacets", "string_sd"); + Collection floatString = (ArrayList)xmlToList(floatStringFacet, "long", "float"); + assertEquals(floatStringTestMissing,floatString); + + //Double Date + String doubleDateFacet = getFacetXML(response, "missingn", "fieldFacets", "date_dtd"); + Collection doubleDate = (ArrayList)xmlToList(doubleDateFacet, "long", "double"); + setLatestType("double"); + assertEquals(doubleDateTestMissing,doubleDate); + + //Double String + String doubleStringFacet = getFacetXML(response, "missingn", "fieldFacets", "string_sd"); + Collection doubleString = (ArrayList)xmlToList(doubleStringFacet, "long", "double"); + assertEquals(doubleStringTestMissing,doubleString); + + //Date Int + String dateIntFacet = getFacetXML(response, "missing", "fieldFacets", "int_id"); + Collection dateInt = (ArrayList)xmlToList(dateIntFacet, "long", "date"); + setLatestType("date"); + assertEquals(dateIntTestMissing,dateInt); + + //Date Long + String dateStringFacet = getFacetXML(response, "missing", "fieldFacets", "long_ld"); + Collection dateLong = (ArrayList)xmlToList(dateStringFacet, "long", "date"); + assertEquals(dateLongTestMissing,dateLong); + + //String Int + String stringIntFacet = getFacetXML(response, "missing", "fieldFacets", "int_id"); + Collection stringInt = (ArrayList)xmlToList(stringIntFacet, "long", "str"); + setLatestType("string"); + assertEquals(stringIntTestMissing,stringInt); + + //String Long + String stringLongFacet = getFacetXML(response, "missing", "fieldFacets", "long_ld"); + Collection stringLong = (ArrayList)xmlToList(stringLongFacet, "long", "str"); + assertEquals(stringLongTestMissing,stringLong); + } + + @SuppressWarnings("unchecked") + @Test + public void multiValueTest() throws Exception { + //Long + String longFacet = getFacetXML(response, "multivalued", "fieldFacets", "long_ldm"); + Collection lon = (ArrayList)xmlToList(longFacet, "double", "mean"); + ArrayList longTest = calculateNumberStat(multiLongTestStart, "mean"); + assertEquals(lon,longTest); + //Date + String dateFacet = getFacetXML(response, "multivalued", "fieldFacets", "date_dtdm"); + Collection date = (ArrayList)xmlToList(dateFacet, "double", "mean"); + ArrayList dateTest = calculateNumberStat(multiDateTestStart, "mean"); + assertEquals(date,dateTest); + //String + String stringFacet = getFacetXML(response, "multivalued", "fieldFacets", "string_sdm"); + Collection string = (ArrayList)xmlToList(stringFacet, "double", "mean"); + ArrayList stringTest = calculateNumberStat(multiStringTestStart, "mean"); + assertEquals(string,stringTest); + } + + @SuppressWarnings("unchecked") + @Test + public void missingFacetTest() throws Exception { + //int MultiDate + String stringFacet = getFacetXML(response, "missingf", "fieldFacets", "date_dtdm"); + assertTrue(stringFacet.contains("")); + ArrayList string = (ArrayList)xmlToList(stringFacet, "double", "mean"); + string.remove(0); + ArrayList stringTest = calculateNumberStat(multiDateTestStart, "mean"); + assertEquals(string,stringTest); + + //Int String + String intStringFacet = getFacetXML(response, "missingf", "fieldFacets", "string_sd"); + assertTrue(intStringFacet.contains("")&&!intStringFacet.contains("")); + List intString = (ArrayList)xmlToList(intStringFacet, "double", "mean"); + intString.remove(0); + ArrayList intStringTest = calculateNumberStat(intStringTestStart, "mean"); + assertEquals(intString,intStringTest); + + //Int Date + String intDateFacet = getFacetXML(response, "missingf", "fieldFacets", "date_dtd"); + Collection intDate = (ArrayList)xmlToList(intDateFacet, "double", "mean"); + ArrayList> intDateMissingTestStart = (ArrayList>) intDateTestStart.clone(); + ArrayList intDateTest = calculateNumberStat(intDateMissingTestStart, "mean"); + assertEquals(intDate,intDateTest); + + + } + + private boolean checkStddevs(ArrayList list1, ArrayList list2) { + boolean b = true; + for (int i = 0; i*:*"); + //INT + ArrayList> int1TestStart = new ArrayList>(); + int1TestStart.add(new ArrayList()); + ArrayList> int2TestStart = new ArrayList>(); + int2TestStart.add(new ArrayList()); + + //LONG + ArrayList> longTestStart = new ArrayList>(); + longTestStart.add(new ArrayList()); + longTestStart.add(new ArrayList()); + + //FLOAT + ArrayList> floatTestStart = new ArrayList>(); + floatTestStart.add(new ArrayList()); + floatTestStart.add(new ArrayList()); + floatTestStart.add(new ArrayList()); + + for (int j = 0; j < NUM_LOOPS; ++j) { + int i = j%INT; + long l = j%LONG; + float f = j%FLOAT; + double d = j%DOUBLE; + int dt = j%DATE; + int s = j%STRING; + assertU(adoc("id", "1000" + j, "int_id", "" + i, "long_ld", "" + l, "float_fd", "" + f, + "double_dd", "" + d, "date_dtd", (1800+dt) + "-12-31T23:59:59.999Z", "string_sd", "abc" + new Integer(s).toString().charAt(0))); + + if (f<=50) { + int1TestStart.get(0).add(i); + } + if (f<=30) { + int2TestStart.get(0).add(i); + } + if (new Integer(s).toString().charAt(0)=='1') { + longTestStart.get(0).add(l); + } + if (new Integer(s).toString().charAt(0)=='2') { + longTestStart.get(1).add(l); + } + if (l>=20) { + floatTestStart.get(0).add(f); + } + if (l>=30) { + floatTestStart.get(1).add(f); + } + if (d<=50) { + floatTestStart.get(2).add(f); + } + + if (usually()) { + commit(); // to have several segments + } + } + + assertU(commit()); + + //Query ascending tests + String response = h.query(request(fileToStringArr(fileName))); + + //Int One + String int1Query = getFacetXML(response, "ir", "queryFacets", "float1"); + ArrayList int1 = (ArrayList)xmlToList(int1Query, "double", "sum"); + ArrayList int1Test = calculateNumberStat(int1TestStart, "sum"); + assertEquals(int1,int1Test); + //Int Two + String int2Query = getFacetXML(response, "ir", "queryFacets", "float2"); + ArrayList int2 = (ArrayList)xmlToList(int2Query, "int", "percentile_8"); + ArrayList int2Test = (ArrayList)calculateStat(int2TestStart, "perc_8"); + assertEquals(int2,int2Test); + + //Long + String long1Query = getFacetXML(response, "lr", "queryFacets", "string"); + ArrayList long1 = (ArrayList)xmlToList(long1Query, "double", "median"); + ArrayList long1Test = calculateNumberStat(longTestStart, "median"); + assertEquals(long1,long1Test); + + //Float + String float1Query = getFacetXML(response, "fr", "queryFacets", "lad"); + ArrayList float1 = (ArrayList)xmlToList(float1Query, "double", "mean"); + ArrayList float1Test = calculateNumberStat(floatTestStart, "mean"); + assertEquals(float1,float1Test); + } + +} diff --git a/solr/core/src/test/org/apache/solr/analytics/facet/RangeFacetTest.java b/solr/core/src/test/org/apache/solr/analytics/facet/RangeFacetTest.java new file mode 100644 index 00000000000..6e9562b101d --- /dev/null +++ b/solr/core/src/test/org/apache/solr/analytics/facet/RangeFacetTest.java @@ -0,0 +1,467 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.facet; + + +import java.util.ArrayList; + +import org.apache.lucene.util.LuceneTestCase.SuppressCodecs; +import org.junit.BeforeClass; +import org.junit.Test; + + +@SuppressCodecs({"Lucene3x","Lucene40","Lucene41","Lucene42","Appending","Asserting"}) +public class RangeFacetTest extends AbstractAnalyticsFacetTest { + static String fileName = "core/src/test-files/analytics/requestFiles/rangeFacets.txt"; + + public static final int INT = 71; + public static final int LONG = 36; + public static final int FLOAT = 93; + public static final int DOUBLE = 48; + public static final int DATE = 52; + public static final int STRING = 28; + public static final int NUM_LOOPS = 100; + + //INT + static ArrayList> intLongTestStart; + static ArrayList> intDoubleTestStart; + static ArrayList> intDateTestStart; + + //FLOAT + static ArrayList> floatLongTestStart; + static ArrayList> floatDoubleTestStart; + static ArrayList> floatDateTestStart; + + static String response; + + @BeforeClass + public static void beforeClass() throws Exception { + initCore("solrconfig-basic.xml","schema-analytics.xml"); + h.update("*:*"); + + //INT + intLongTestStart = new ArrayList>(); + intDoubleTestStart = new ArrayList>(); + intDateTestStart = new ArrayList>(); + + //FLOAT + floatLongTestStart = new ArrayList>(); + floatDoubleTestStart = new ArrayList>(); + floatDateTestStart = new ArrayList>(); + + for (int j = 0; j < NUM_LOOPS; ++j) { + int i = j%INT; + long l = j%LONG; + float f = j%FLOAT; + double d = j%DOUBLE; + int dt = j%DATE; + int s = j%STRING; + assertU(adoc("id", "1000" + j, "int_id", "" + i, "long_ld", "" + l, "float_fd", "" + f, + "double_dd", "" + d, "date_dtd", (1000+dt) + "-01-01T23:59:59Z", "string_sd", "abc" + s)); + //Longs + if (j-LONG<0) { + ArrayList list1 = new ArrayList(); + list1.add(i); + intLongTestStart.add(list1); + ArrayList list2 = new ArrayList(); + list2.add(f); + floatLongTestStart.add(list2); + } else { + intLongTestStart.get((int)l).add(i); + floatLongTestStart.get((int)l).add(f); + } + //Doubles + if (j-DOUBLE<0) { + ArrayList list1 = new ArrayList(); + list1.add(i); + intDoubleTestStart.add(list1); + ArrayList list2 = new ArrayList(); + list2.add(f); + floatDoubleTestStart.add(list2); + } else { + intDoubleTestStart.get((int)d).add(i); + floatDoubleTestStart.get((int)d).add(f); + } + //Dates + if (j-DATE<0) { + ArrayList list1 = new ArrayList(); + list1.add(i); + intDateTestStart.add(list1); + ArrayList list2 = new ArrayList(); + list2.add(f); + floatDateTestStart.add(list2); + } else { + intDateTestStart.get(dt).add(i); + floatDateTestStart.get(dt).add(f); + } + + if (usually()) { + assertU(commit()); // to have several segments + } + } + + assertU(commit()); + + response = h.query(request(fileToStringArr(fileName))); + } + + @SuppressWarnings("unchecked") + @Test + public void rangeTest() throws Exception { + + //Int Long + String intLongRange = getFacetXML(response, "ri", "rangeFacets", "long_ld"); + ArrayList intLong = (ArrayList)xmlToList(intLongRange, "long", "count"); + ArrayList intLongTest = calculateStat(transformLists(intLongTestStart, 5, 30, 5 + , false, true, false, false, false), "count"); + assertEquals(intLong,intLongTest); + //Int Double + String intDoubleRange = getFacetXML(response, "ri", "rangeFacets", "double_dd"); + ArrayList intDouble = (ArrayList)xmlToList(intDoubleRange, "double", "mean"); + ArrayList intDoubleTest = calculateNumberStat(transformLists(intDoubleTestStart, 3, 39, 7 + , false, false, true, false, true), "mean"); + assertEquals(intDouble,intDoubleTest); + //Int Date + String intDateRange = getFacetXML(response, "ri", "rangeFacets", "date_dtd"); + ArrayList intDate = (ArrayList)xmlToList(intDateRange, "long", "count"); + ArrayList intDateTest = (ArrayList)calculateStat(transformLists(intDateTestStart, 7, 44, 7 + , false, true, false, true, true), "count"); + assertEquals(intDate,intDateTest); + + //Float Long + String floatLongRange = getFacetXML(response, "rf", "rangeFacets", "long_ld"); + ArrayList floatLong = (ArrayList)xmlToList(floatLongRange, "double", "median"); + ArrayList floatLongTest = calculateNumberStat(transformLists(floatLongTestStart, 0, 29, 4 + , false, true, true, true, true), "median"); + assertEquals(floatLong,floatLongTest); + //Float Double + String floatDoubleRange = getFacetXML(response, "rf", "rangeFacets", "double_dd"); + ArrayList floatDouble = (ArrayList)xmlToList(floatDoubleRange, "long", "count"); + ArrayList floatDoubleTest = (ArrayList)calculateStat(transformLists(floatDoubleTestStart, 4, 47, 11 + , false, false, false, true, false), "count"); + assertEquals(floatDouble,floatDoubleTest); + //Float Date + String floatDateRange = getFacetXML(response, "rf", "rangeFacets", "date_dtd"); + ArrayList floatDate = (ArrayList)xmlToList(floatDateRange, "double", "sumOfSquares"); + ArrayList floatDateTest = calculateNumberStat(transformLists(floatDateTestStart, 4, 46, 5 + , false, false, true, true, false), "sumOfSquares"); + assertEquals(floatDate,floatDateTest); + } + + + @SuppressWarnings("unchecked") + @Test + public void hardendRangeTest() throws Exception { + //Int Long + String intLongRange = getFacetXML(response, "hi", "rangeFacets", "long_ld"); + ArrayList intLong = (ArrayList)xmlToList(intLongRange, "double", "sum"); + ArrayList intLongTest = calculateNumberStat(transformLists(intLongTestStart, 5, 30, 5 + , true, true, false, false, false), "sum"); + assertEquals(intLong,intLongTest); + //Int Double + String intDoubleRange = getFacetXML(response, "hi", "rangeFacets", "double_dd"); + ArrayList intDouble = (ArrayList)xmlToList(intDoubleRange, "double", "mean"); + ArrayList intDoubleTest = calculateNumberStat(transformLists(intDoubleTestStart, 3, 39, 7 + , true, false, true, false, true), "mean"); + assertEquals(intDouble,intDoubleTest); + //Int Date + String intDateRange = getFacetXML(response, "hi", "rangeFacets", "date_dtd"); + ArrayList intDate = (ArrayList)xmlToList(intDateRange, "long", "count"); + ArrayList intDateTest = (ArrayList)calculateStat(transformLists(intDateTestStart, 7, 44, 7 + , true, true, false, true, true), "count"); + assertEquals(intDate,intDateTest); + + //Float Long + String floatLongRange = getFacetXML(response, "hf", "rangeFacets", "long_ld"); + ArrayList floatLong = (ArrayList)xmlToList(floatLongRange, "double", "median"); + ArrayList floatLongTest = calculateNumberStat(transformLists(floatLongTestStart, 0, 29, 4 + , true, true, true, true, true), "median"); + assertEquals(floatLong,floatLongTest); + //Float Double + String floatDoubleRange = getFacetXML(response, "hf", "rangeFacets", "double_dd"); + ArrayList floatDouble = (ArrayList)xmlToList(floatDoubleRange, "long", "count"); + ArrayList floatDoubleTest = (ArrayList)calculateStat(transformLists(floatDoubleTestStart, 4, 47, 11 + , true, false, false, true, false), "count"); + assertEquals(floatDouble,floatDoubleTest); + //Float Date + String floatDateRange = getFacetXML(response, "hf", "rangeFacets", "date_dtd"); + ArrayList floatDate = (ArrayList)xmlToList(floatDateRange, "double", "sumOfSquares"); + ArrayList floatDateTest = calculateNumberStat(transformLists(floatDateTestStart, 4, 46, 5 + , true, false, true, true, false), "sumOfSquares"); + assertEquals(floatDate,floatDateTest); + } + + @SuppressWarnings("unchecked") + @Test + public void multiGapTest() throws Exception { + //Int Long + String intLongRange = getFacetXML(response, "mi", "rangeFacets", "long_ld"); + ArrayList intLong = (ArrayList)xmlToList(intLongRange, "double", "sum"); + ArrayList intLongTest = calculateNumberStat(transformLists(intLongTestStart, 5, 30, "4,2,6,3" + , false, true, false, false, false), "sum"); + assertEquals(intLong,intLongTest); + //Int Double + String intDoubleRange = getFacetXML(response, "mi", "rangeFacets", "double_dd"); + ArrayList intDouble = (ArrayList)xmlToList(intDoubleRange, "double", "mean"); + ArrayList intDoubleTest = calculateNumberStat(transformLists(intDoubleTestStart, 3, 39, "3,1,7" + , false, false, true, false, true), "mean"); + assertEquals(intDouble,intDoubleTest); + //Int Date + String intDateRange = getFacetXML(response, "mi", "rangeFacets", "date_dtd"); + ArrayList intDate = (ArrayList)xmlToList(intDateRange, "long", "count"); + ArrayList intDateTest = (ArrayList)calculateStat(transformLists(intDateTestStart, 7, 44, "2,7" + , false, true, false, true, true), "count"); + assertEquals(intDate,intDateTest); + + //Float Long + String floatLongRange = getFacetXML(response, "mf", "rangeFacets", "long_ld"); + ArrayList floatLong = (ArrayList)xmlToList(floatLongRange, "double", "median"); + ArrayList floatLongTest = calculateNumberStat(transformLists(floatLongTestStart, 0, 29, "1,4" + , false, true, true, true, true), "median");; + assertEquals(floatLong,floatLongTest); + //Float Double + String floatDoubleRange = getFacetXML(response, "mf", "rangeFacets", "double_dd"); + ArrayList floatDouble = (ArrayList)xmlToList(floatDoubleRange, "long", "count"); + ArrayList floatDoubleTest = (ArrayList)calculateStat(transformLists(floatDoubleTestStart, 4, 47, "2,3,11" + , false, false, false, true, false), "count"); + assertEquals(floatDouble,floatDoubleTest); + //Float Date + String floatDateRange = getFacetXML(response, "mf", "rangeFacets", "date_dtd"); + ArrayList floatDate = (ArrayList)xmlToList(floatDateRange, "double", "sumOfSquares"); + ArrayList floatDateTest = calculateNumberStat(transformLists(floatDateTestStart, 4, 46, "4,5" + , false, false, true, true, false), "sumOfSquares"); + assertEquals(floatDate,floatDateTest); + } + + private ArrayList> transformLists(ArrayList> listsStart, int start, int end, int gap + , boolean hardend, boolean incLow, boolean incUp, boolean incEdge, boolean incOut) { + int off = (end-start)%gap; + if (!hardend && off>0) { + end+=gap-off; + } + + ArrayList> lists = new ArrayList>(); + ArrayList between = new ArrayList(); + if (incLow && incUp) { + for (int i = start; i list = new ArrayList(); + for (int j = i; j<=i+gap && j<=end && j list = new ArrayList(); + for (int j = i; j list = new ArrayList(); + for (int j = i+1; j<=i+gap && j<=end && j list = new ArrayList(); + for (int j = i+1; j=0) { + lists.get(0).addAll(listsStart.get(start)); + between.addAll(listsStart.get(start)); + } + if (incEdge && !incUp && end before = new ArrayList(); + ArrayList after = new ArrayList(); + if (incOut || !(incLow||incEdge)) { + for (int i = 0; i<=start; i++) { + before.addAll(listsStart.get(i)); + } + } else { + for (int i = 0; i0) { + lists.add(before); + } + if (after.size()>0) { + lists.add(after); + } + if (between.size()>0) { + lists.add(between); + } + return lists; + } + + private ArrayList> transformLists(ArrayList> listsStart, int start, int end, String gapString + , boolean hardend, boolean incLow, boolean incUp, boolean incEdge, boolean incOut) { + String[] stringGaps = gapString.split(","); + int[] gaps = new int[stringGaps.length]; + for (int i = 0; i0) { + end+=last-off; + } + + ArrayList> lists = new ArrayList>(); + ArrayList between = new ArrayList(); + int gap = 0; + int gapCounter = 0; + if (incLow && incUp) { + for (int i = start; i list = new ArrayList(); + for (int j = i; j<=i+gap && j<=end && j list = new ArrayList(); + for (int j = i; j list = new ArrayList(); + for (int j = i+1; j<=i+gap && j<=end && j list = new ArrayList(); + for (int j = i+1; j=0) { + lists.get(0).addAll(listsStart.get(start)); + between.addAll(listsStart.get(start)); + } + if (incEdge && !incUp && end before = new ArrayList(); + ArrayList after = new ArrayList(); + if (incOut || !(incLow||incEdge)) { + for (int i = 0; i<=start; i++) { + before.addAll(listsStart.get(i)); + } + } else { + for (int i = 0; i0) { + lists.add(before); + } + if (after.size()>0) { + lists.add(after); + } + if (between.size()>0) { + lists.add(between); + } + return lists; + } + +} diff --git a/solr/core/src/test/org/apache/solr/analytics/util/valuesource/FunctionTest.java b/solr/core/src/test/org/apache/solr/analytics/util/valuesource/FunctionTest.java new file mode 100644 index 00000000000..8ccfed6d743 --- /dev/null +++ b/solr/core/src/test/org/apache/solr/analytics/util/valuesource/FunctionTest.java @@ -0,0 +1,231 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.analytics.util.valuesource; + + +import org.apache.lucene.util.LuceneTestCase.SuppressCodecs; +import org.apache.solr.analytics.AbstractAnalyticsStatsTest; +import org.apache.solr.analytics.facet.AbstractAnalyticsFacetTest; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +@SuppressCodecs({"Lucene3x","Lucene40","Lucene41","Lucene42","Appending","Asserting"}) +public class FunctionTest extends AbstractAnalyticsStatsTest { + static String fileName = "core/src/test-files/analytics/requestFiles/functions.txt"; + + static public final int INT = 71; + static public final int LONG = 36; + static public final int FLOAT = 93; + static public final int DOUBLE = 49; + static public final int DATE = 12; + static public final int STRING = 28; + static public final int NUM_LOOPS = 100; + + static String response; + + @BeforeClass + public static void beforeClass() throws Exception { + initCore("solrconfig-basic.xml","schema-analytics.xml"); + h.update("*:*"); + + for (int j = 0; j < NUM_LOOPS; ++j) { + int i = j%INT+1; + long l = j%LONG+1; + float f = j%FLOAT+1; + double d = j%DOUBLE+1; + double d0 = j%DOUBLE; + String dt = (1800+j%DATE) + "-06-30T23:59:59Z"; + String s = "str" + (j%STRING); + + double add_if = (double)i+f; + double add_ldf = (double)l+d+f; + double mult_if = (double)i*f; + double mult_ldf = (double)l*d*f; + double div_if = (double)i/f; + double div_ld = (double)l/d; + double pow_if = Math.pow(i,f); + double pow_ld = Math.pow(l,d); + double neg_i = (double)i*-1; + double neg_l = (double)l*-1; + String dm_2y = (1802+j%DATE) + "-06-30T23:59:59Z"; + String dm_2m = (1800+j%DATE) + "-08-30T23:59:59Z"; + String concat_first = "this is the first"+s; + String concat_second = "this is the second"+s; + String rev = new StringBuilder(s).reverse().toString(); + + assertU(adoc(AbstractAnalyticsFacetTest.filter("id", "1000" + j, "int_id", "" + i, "long_ld", "" + l, "float_fd", "" + f, + "double_dd", "" + d, "date_dtd", dt, "string_sd", s, + "add_if_dd", ""+add_if, "add_ldf_dd", ""+add_ldf, "mult_if_dd", ""+mult_if, "mult_ldf_dd", ""+mult_ldf, + "div_if_dd", ""+div_if, "div_ld_dd", ""+div_ld, "pow_if_dd", ""+pow_if, "pow_ld_dd", ""+pow_ld, + "neg_i_dd", ""+neg_i, "neg_l_dd", ""+neg_l, "const_8_dd", "8", "const_10_dd", "10", "dm_2y_dtd", dm_2y, "dm_2m_dtd", dm_2m, + "const_00_dtd", "1800-06-30T23:59:59Z", "const_04_dtd", "1804-06-30T23:59:59Z", "const_first_sd", "this is the first", "const_second_sd", "this is the second", + "concat_first_sd", concat_first, "concat_second_sd", concat_second, "rev_sd", rev, "miss_dd", ""+d0 ))); + + + if (usually()) { + commit(); // to have several segments + } + } + + assertU(commit()); + + response = h.query(request(fileToStringArr(fileName))); + } + + @Test + public void addTest() throws Exception { + double result = (Double)getStatResult(response, "ar", "double", "sum"); + double calculated = (Double)getStatResult(response, "ar", "double", "sumc"); + assertTrue(result==calculated); + + result = (Double)getStatResult(response, "ar", "double", "mean"); + calculated = (Double)getStatResult(response, "ar", "double", "meanc"); + assertTrue(result==calculated); + } + + @Test + public void multiplyTest() throws Exception { + double result = (Double)getStatResult(response, "mr", "double", "sum"); + double calculated = (Double)getStatResult(response, "mr", "double", "sumc"); + assertTrue(result==calculated); + + result = (Double)getStatResult(response, "mr", "double", "mean"); + calculated = (Double)getStatResult(response, "mr", "double", "meanc"); + assertTrue(result==calculated); + } + + @Test + public void divideTest() throws Exception { + Double result = (Double)getStatResult(response, "dr", "double", "sum"); + Double calculated = (Double)getStatResult(response, "dr", "double", "sumc"); + assertTrue(result.equals(calculated)); + + result = (Double)getStatResult(response, "dr", "double", "mean"); + calculated = (Double)getStatResult(response, "dr", "double", "meanc"); + assertTrue(result.equals(calculated)); + } + + @Test + public void powerTest() throws Exception { + double result = (Double)getStatResult(response, "pr", "double", "sum"); + double calculated = (Double)getStatResult(response, "pr", "double", "sumc"); + assertTrue(result==calculated); + + result = (Double)getStatResult(response, "pr", "double", "mean"); + calculated = (Double)getStatResult(response, "pr", "double", "meanc"); + assertTrue(result==calculated); + } + + @Test + public void negateTest() throws Exception { + double result = (Double)getStatResult(response, "nr", "double", "sum"); + double calculated = (Double)getStatResult(response, "nr", "double", "sumc"); + assertTrue(result==calculated); + + result = (Double)getStatResult(response, "nr", "double", "mean"); + calculated = (Double)getStatResult(response, "nr", "double", "meanc"); + assertTrue(result==calculated); + } + + @Test + public void absoluteValueTest() throws Exception { + double result = (Double)getStatResult(response, "avr", "double", "sum"); + double calculated = (Double)getStatResult(response, "avr", "double", "sumc"); + assertTrue(result==calculated); + + result = (Double)getStatResult(response, "avr", "double", "mean"); + calculated = (Double)getStatResult(response, "avr", "double", "meanc"); + assertTrue(result==calculated); + } + + @Test + public void constantNumberTest() throws Exception { + double result = (Double)getStatResult(response, "cnr", "double", "sum"); + double calculated = (Double)getStatResult(response, "cnr", "double", "sumc"); + assertTrue(result==calculated); + + result = (Double)getStatResult(response, "cnr", "double", "mean"); + calculated = (Double)getStatResult(response, "cnr", "double", "meanc"); + assertTrue(result==calculated); + } + + @Test + public void dateMathTest() throws Exception { + String result = (String)getStatResult(response, "dmr", "date", "median"); + String calculated = (String)getStatResult(response, "dmr", "date", "medianc"); + assertTrue(result.equals(calculated)); + + result = (String)getStatResult(response, "dmr", "date", "max"); + calculated = (String)getStatResult(response, "dmr", "date", "maxc"); + assertTrue(result.equals(calculated)); + } + + @Test + public void constantDateTest() throws Exception { + String result = (String)getStatResult(response, "cdr", "date", "median"); + String calculated = (String)getStatResult(response, "cdr", "date", "medianc"); + assertTrue(result.equals(calculated)); + + result = (String)getStatResult(response, "cdr", "date", "max"); + calculated = (String)getStatResult(response, "cdr", "date", "maxc"); + assertTrue(result.equals(calculated)); + } + + @Test + public void constantStringTest() throws Exception { + String result = (String)getStatResult(response, "csr", "str", "min"); + String calculated = (String)getStatResult(response, "csr", "str", "minc"); + assertTrue(result.equals(calculated)); + + result = (String)getStatResult(response, "csr", "str", "max"); + calculated = (String)getStatResult(response, "csr", "str", "maxc"); + assertTrue(result.equals(calculated)); + } + + @Test + public void concatenateTest() throws Exception { + String result = (String)getStatResult(response, "cr", "str", "min"); + String calculated = (String)getStatResult(response, "cr", "str", "minc"); + assertTrue(result.equals(calculated)); + + result = (String)getStatResult(response, "cr", "str", "max"); + calculated = (String)getStatResult(response, "cr", "str", "maxc"); + assertTrue(result.equals(calculated)); + } + + @Test + public void reverseTest() throws Exception { + String result = (String)getStatResult(response, "rr", "str", "min"); + String calculated = (String)getStatResult(response, "rr", "str", "minc"); + assertTrue(result.equals(calculated)); + + result = (String)getStatResult(response, "rr", "str", "max"); + calculated = (String)getStatResult(response, "rr", "str", "maxc"); + assertTrue(result.equals(calculated)); + } + + @Test + public void missingTest() throws Exception { + double min = (Double)getStatResult(response, "ms", "double", "min"); + double max = (Double)getStatResult(response, "ms", "double", "max"); + Assert.assertEquals((Double)48.0,(Double)max); + Assert.assertEquals((Double)1.0,(Double)min); + } + +} From fe2e612ebda0d373718dd1ffb748fa1a9130735c Mon Sep 17 00:00:00 2001 From: Erick Erickson Date: Wed, 20 Nov 2013 00:15:13 +0000 Subject: [PATCH 044/223] SOLR-5459: Try loading a temporary core when saving a file in the admin UI config editing mode git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1543660 13f79535-47bb-0310-9956-ffa450edef68 --- .../handler/admin/ShowFileRequestHandler.java | 101 +++++++++++++++++- .../solr/cloud/TestModifyConfFiles.java | 4 +- .../solr/schema/ModifyConfFileTest.java | 7 +- solr/example/solr/collection1/conf/schema.xml | 2 +- 4 files changed, 103 insertions(+), 11 deletions(-) diff --git a/solr/core/src/java/org/apache/solr/handler/admin/ShowFileRequestHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/ShowFileRequestHandler.java index aaa5b9b6d32..72e8099f69a 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/ShowFileRequestHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/ShowFileRequestHandler.java @@ -19,6 +19,7 @@ package org.apache.solr.handler.admin; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; +import org.apache.solr.cloud.ZkController; import org.apache.solr.cloud.ZkSolrResourceLoader; import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrException.ErrorCode; @@ -30,6 +31,7 @@ import org.apache.solr.common.util.ContentStreamBase; import org.apache.solr.common.util.NamedList; import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.core.CoreContainer; +import org.apache.solr.core.CoreDescriptor; import org.apache.solr.core.SolrCore; import org.apache.solr.core.SolrResourceLoader; import org.apache.solr.handler.RequestHandlerBase; @@ -128,7 +130,12 @@ public class ShowFileRequestHandler extends RequestHandlerBase public static final String USE_CONTENT_TYPE = "contentType"; protected Set hiddenFiles; - + + private final static String OP_PARAM = "op"; + private final static String OP_WRITE = "write"; + private final static String OP_TEST = "test"; + + public ShowFileRequestHandler() { super(); @@ -160,14 +167,14 @@ public class ShowFileRequestHandler extends RequestHandlerBase throws InterruptedException, KeeperException, IOException { CoreContainer coreContainer = req.getCore().getCoreDescriptor().getCoreContainer(); - String op = req.getParams().get("op"); + String op = req.getParams().get(OP_PARAM); if (op == null) { if (coreContainer.isZooKeeperAware()) { showFromZooKeeper(req, rsp, coreContainer); } else { showFromFileSystem(req, rsp); } - } else if ("write".equalsIgnoreCase(op)) { + } else if (OP_WRITE.equalsIgnoreCase(op) || OP_TEST.equalsIgnoreCase(op)) { String fname = req.getParams().get("file", null); if (fname == null) { rsp.setException(new SolrException(ErrorCode.BAD_REQUEST, "No file name specified for write operation.")); @@ -175,7 +182,7 @@ public class ShowFileRequestHandler extends RequestHandlerBase fname = fname.replace('\\', '/'); if (isHiddenFile(req, rsp, fname, true) == false) { if (coreContainer.isZooKeeperAware()) { - writeToZooKeeper(req, rsp, coreContainer); + writeToZooKeeper(req, rsp); } else { writeToFileSystem(req, rsp); } @@ -264,8 +271,10 @@ public class ShowFileRequestHandler extends RequestHandlerBase // file=velocity/error.vm or file=schema.xml // // Important: Assumes that the file already exists in ZK, so far we aren't creating files there. - private void writeToZooKeeper(SolrQueryRequest req, SolrQueryResponse rsp, CoreContainer coreContainer) + private void writeToZooKeeper(SolrQueryRequest req, SolrQueryResponse rsp) throws KeeperException, InterruptedException, IOException { + + CoreContainer coreContainer = req.getCore().getCoreDescriptor().getCoreContainer(); SolrZkClient zkClient = coreContainer.getZkController().getZkClient(); String adminFile = getAdminFileFromZooKeeper(req, rsp, zkClient); @@ -276,6 +285,10 @@ public class ShowFileRequestHandler extends RequestHandlerBase byte[] data = IOUtils.toByteArray(new InputStreamReader(stream.getStream(), "UTF-8"), "UTF-8"); String fname = req.getParams().get("file", null); + if (OP_TEST.equals(req.getParams().get(OP_PARAM))) { + testReloadSuccess(req, rsp, stream); + return; + } // Persist the managed schema try { // Assumption: the path exists @@ -395,11 +408,89 @@ public class ShowFileRequestHandler extends RequestHandlerBase rsp.setException(new SolrException( ErrorCode.BAD_REQUEST, "File " + fname + " is a directory.")); return; } + if (OP_TEST.equals(req.getParams().get(OP_PARAM))) { + testReloadSuccess(req, rsp, stream); + return; + } FileUtils.copyInputStreamToFile(stream.getStream(), adminFile); log.info("Successfully saved file " + adminFile.getAbsolutePath() + " locally"); } + private boolean testReloadSuccess(SolrQueryRequest req, SolrQueryResponse rsp, ContentStream stream) { + // Try writing the config to a temporary core and reloading to see that we don't allow people to shoot themselves + // in the foot. + File home = null; + try { + home = new File(FileUtils.getTempDirectory(), "SOLR_5459"); // Unlikely to name a core or collection this! + FileUtils.writeStringToFile(new File(home, "solr.xml"), ""); // Use auto-discovery + File coll = new File(home, "SOLR_5459"); + + SolrCore core = req.getCore(); + CoreDescriptor desc = core.getCoreDescriptor(); + CoreContainer coreContainer = desc.getCoreContainer(); + + if (coreContainer.isZooKeeperAware()) { + try { + String confPath = ((ZkSolrResourceLoader) core.getResourceLoader()).getCollectionZkPath(); + + ZkController.downloadConfigDir(coreContainer.getZkController().getZkClient(), confPath, + new File(coll, "conf")); + } catch (Exception ex) { + log.error("Error when attempting to download conf from ZooKeeper: " + ex.getMessage()); + rsp.setException(new SolrException(ErrorCode.BAD_REQUEST, + "Error when attempting to download conf from ZooKeeper" + ex.getMessage())); + return false; + } + } else { + FileUtils.copyDirectory(new File(desc.getInstanceDir(), "conf"), + new File(coll, "conf")); + } + + FileUtils.writeStringToFile(new File(coll, "core.properties"), "name=SOLR_5459"); + + FileUtils.copyInputStreamToFile(stream.getStream(), + new File(new File(coll, "conf"), req.getParams().get("file", null))); + + return tryReloading(rsp, home); + + } catch (IOException ex) { + log.warn("Caught IO exception when trying to verify configs. " + ex.getMessage()); + rsp.setException(new SolrException(ErrorCode.SERVER_ERROR, + "Caught IO exception when trying to verify configs. " + ex.getMessage())); + return false; + } finally { + if (home != null) { + try { + FileUtils.deleteDirectory(home); + } catch (IOException e) { + log.warn("Caught IO exception trying to delete temporary directory " + home + e.getMessage()); + return true; // Don't fail for this reason! + } + } + } + } + + private boolean tryReloading(SolrQueryResponse rsp, File home) { + CoreContainer cc = null; + try { + cc = CoreContainer.createAndLoad(home.getAbsolutePath(), new File(home, "solr.xml")); + if (cc.getCoreInitFailures().size() > 0) { + for (Exception ex : cc.getCoreInitFailures().values()) { + log.error("Error when attempting to reload core: " + ex.getMessage()); + rsp.setException(new SolrException( ErrorCode.BAD_REQUEST, + "Error when attempting to reload core after writing config" + ex.getMessage())); + } + return false; + } + return true; + } finally { + if (cc != null) { + cc.shutdown(); + } + } + } + // Find the file indicated by the "file=XXX" parameter or the root of the conf directory on the local // file system. Respects all the "interesting" stuff around what the resource loader does to find files. private File getAdminFileFromFileSystem(SolrQueryRequest req, SolrQueryResponse rsp) { diff --git a/solr/core/src/test/org/apache/solr/cloud/TestModifyConfFiles.java b/solr/core/src/test/org/apache/solr/cloud/TestModifyConfFiles.java index f633b77ee7c..aa36cde2fd7 100644 --- a/solr/core/src/test/org/apache/solr/cloud/TestModifyConfFiles.java +++ b/solr/core/src/test/org/apache/solr/cloud/TestModifyConfFiles.java @@ -48,6 +48,7 @@ public class TestModifyConfFiles extends AbstractFullDistribZkTestBase { params.remove("file"); params.set("stream.body", "Testing rewrite of schema.xml file."); + params.set("op", "test"); request = new QueryRequest(params); request.setPath("/admin/file"); try { @@ -57,6 +58,7 @@ public class TestModifyConfFiles extends AbstractFullDistribZkTestBase { assertEquals(e.getMessage(), "No file name specified for write operation."); } + params.set("op", "write"); params.set("file", "bogus.txt"); request = new QueryRequest(params); request.setPath("/admin/file"); @@ -76,8 +78,6 @@ public class TestModifyConfFiles extends AbstractFullDistribZkTestBase { SolrZkClient zkClient = cloudClient.getZkStateReader().getZkClient(); String contents = new String(zkClient.getData("/configs/conf1/schema.xml", null, null, true), "UTF-8"); - //String schema = getFileContentFromZooKeeper("schema.xml"); - assertTrue("Schema contents should have changed!", "Testing rewrite of schema.xml file.".equals(contents)); // Create a velocity/whatever node. Put a bit of data in it. See if you can change it. diff --git a/solr/core/src/test/org/apache/solr/schema/ModifyConfFileTest.java b/solr/core/src/test/org/apache/solr/schema/ModifyConfFileTest.java index 60420887dbb..c6698b353d7 100644 --- a/solr/core/src/test/org/apache/solr/schema/ModifyConfFileTest.java +++ b/solr/core/src/test/org/apache/solr/schema/ModifyConfFileTest.java @@ -86,15 +86,16 @@ public class ModifyConfFileTest extends SolrTestCaseJ4 { ArrayList streams = new ArrayList( 2 ); streams.add( new ContentStreamBase.StringStream( "Testing rewrite of schema.xml file." ) ); - //streams.add( new ContentStreamBase.StringStream( "there" ) ); - params = params("op", "write", "file", "schema.xml", "stream.body", "Testing rewrite of schema.xml file."); + params = params("op", "test", "file", "schema.xml", "stream.body", "Testing rewrite of schema.xml file."); LocalSolrQueryRequest locReq = new LocalSolrQueryRequest(core, params); locReq.setContentStreams(streams); core.execute(handler, locReq, rsp); + assertTrue("Schema should have caused core reload to fail!", + rsp.getException().getMessage().indexOf("SAXParseException") != -1); String contents = FileUtils.readFileToString(new File(core.getCoreDescriptor().getInstanceDir(), "conf/schema.xml")); - assertEquals("Schema contents should have changed!", "Testing rewrite of schema.xml file.", contents); + assertFalse("Schema contents should NOT have changed!", contents.contains("Testing rewrite of schema.xml file.")); streams.add(new ContentStreamBase.StringStream("This should barf")); locReq = new LocalSolrQueryRequest(core, params); diff --git a/solr/example/solr/collection1/conf/schema.xml b/solr/example/solr/collection1/conf/schema.xml index 95e9c36dcad..9829987a7ab 100755 --- a/solr/example/solr/collection1/conf/schema.xml +++ b/solr/example/solr/collection1/conf/schema.xml @@ -63,7 +63,7 @@ (int, float, boolean, string...) --> - + - + application/json add-unknown-fields-to-the-schema - + application/csv add-unknown-fields-to-the-schema diff --git a/solr/example/solr/collection1/conf/solrconfig.xml b/solr/example/solr/collection1/conf/solrconfig.xml index 54f8af36a63..1f825b8c5ba 100755 --- a/solr/example/solr/collection1/conf/solrconfig.xml +++ b/solr/example/solr/collection1/conf/solrconfig.xml @@ -1011,12 +1011,12 @@ - + application/json - + application/csv From f005912635a15548ea273de26980b518e0158b60 Mon Sep 17 00:00:00 2001 From: Michael McCandless Date: Wed, 20 Nov 2013 15:59:28 +0000 Subject: [PATCH 048/223] improve javadocs git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1543852 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/core/src/java/org/apache/lucene/util/SloppyMath.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lucene/core/src/java/org/apache/lucene/util/SloppyMath.java b/lucene/core/src/java/org/apache/lucene/util/SloppyMath.java index d27c8b3677b..52a2087f283 100644 --- a/lucene/core/src/java/org/apache/lucene/util/SloppyMath.java +++ b/lucene/core/src/java/org/apache/lucene/util/SloppyMath.java @@ -33,7 +33,8 @@ package org.apache.lucene.util; public class SloppyMath { /** - * Returns the distance between two points in decimal degrees. + * Returns the distance in kilometers between two points + * specified in decimal degrees (latitude/longitude). * @param lat1 Latitude of the first point. * @param lon1 Longitude of the first point. * @param lat2 Latitude of the second point. From 83e28ca6dd3bb77fc19b95a624998a23226d1e54 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Wed, 20 Nov 2013 20:44:43 +0000 Subject: [PATCH 049/223] SOLR-5479: SolrCmdDistributor retry logic stops if a leader for the request cannot be found in 1 second. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1543940 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 3 + .../solr/update/SolrCmdDistributor.java | 82 +++++++++++-------- 2 files changed, 50 insertions(+), 35 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 3529f2ea3de..7b061f70804 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -114,6 +114,9 @@ Bug Fixes * SOLR-5461: Request proxying should only set con.setDoOutput(true) if the request is a post. (Mark Miller) +* SOLR-5479: SolrCmdDistributor retry logic stops if a leader for the request + cannot be found in 1 second. (Mark Miller) + Optimizations ---------------------- diff --git a/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java b/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java index f77a774ea39..6f1ab9f9c4a 100644 --- a/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java +++ b/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java @@ -72,48 +72,56 @@ public class SolrCmdDistributor { List resubmitList = new ArrayList(); for (Error err : errors) { - String oldNodeUrl = err.req.node.getUrl(); - - // if there is a retry url, we want to retry... - boolean isRetry = err.req.node.checkRetry(); - boolean doRetry = false; - int rspCode = err.statusCode; - - if (testing_errorHook != null) Diagnostics.call(testing_errorHook, err.e); - - // this can happen in certain situations such as shutdown - if (isRetry) { - if (rspCode == 404 || rspCode == 403 || rspCode == 503 - || rspCode == 500) { - doRetry = true; - } + try { + String oldNodeUrl = err.req.node.getUrl(); - // if its an ioexception, lets try again - if (err.e instanceof IOException) { - doRetry = true; - } else if (err.e instanceof SolrServerException) { - if (((SolrServerException) err.e).getRootCause() instanceof IOException) { + // if there is a retry url, we want to retry... + boolean isRetry = err.req.node.checkRetry(); + + boolean doRetry = false; + int rspCode = err.statusCode; + + if (testing_errorHook != null) Diagnostics.call(testing_errorHook, + err.e); + + // this can happen in certain situations such as shutdown + if (isRetry) { + if (rspCode == 404 || rspCode == 403 || rspCode == 503 + || rspCode == 500) { doRetry = true; } - } - if (err.req.retries < MAX_RETRIES_ON_FORWARD && doRetry) { - err.req.retries++; - SolrException.log(SolrCmdDistributor.log, "forwarding update to " - + oldNodeUrl + " failed - retrying ... retries: " + err.req.retries); - try { - Thread.sleep(500); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - log.warn(null, e); + // if its an ioexception, lets try again + if (err.e instanceof IOException) { + doRetry = true; + } else if (err.e instanceof SolrServerException) { + if (((SolrServerException) err.e).getRootCause() instanceof IOException) { + doRetry = true; + } + } + if (err.req.retries < MAX_RETRIES_ON_FORWARD && doRetry) { + err.req.retries++; + + SolrException.log(SolrCmdDistributor.log, "forwarding update to " + + oldNodeUrl + " failed - retrying ... retries: " + + err.req.retries); + try { + Thread.sleep(500); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + log.warn(null, e); + } + + resubmitList.add(err); + } else { + allErrors.add(err); } - - resubmitList.add(err); } else { allErrors.add(err); } - } else { - allErrors.add(err); + } catch (Exception e) { + // continue on + log.error("Unexpected Error while doing request retries", e); } } @@ -353,10 +361,14 @@ public class SolrCmdDistributor { } catch (InterruptedException e) { Thread.currentThread().interrupt(); return false; + } catch (Exception e) { + // we retry with same info + log.warn(null, e); + return true; } this.nodeProps = leaderProps; - + return true; } From 4f1ed4ee8669f7066cbfba57684e55e061e21925 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Wed, 20 Nov 2013 20:59:11 +0000 Subject: [PATCH 050/223] tests: check for fails again - if there was a fail and we compare against control, it's going to fail later anyway git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1543944 13f79535-47bb-0310-9956-ffa450edef68 --- .../solr/cloud/ChaosMonkeyNothingIsSafeTest.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java b/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java index 0e161120638..f34ea1f43b7 100644 --- a/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java @@ -164,12 +164,11 @@ public class ChaosMonkeyNothingIsSafeTest extends AbstractFullDistribZkTestBase } // we expect full throttle fails, but cloud client should not easily fail - // but it's allowed to fail and sometimes does, so commented out for now -// for (StopableThread indexThread : threads) { -// if (indexThread instanceof StopableIndexingThread && !(indexThread instanceof FullThrottleStopableIndexingThread)) { -// assertEquals(0, ((StopableIndexingThread) indexThread).getFails()); -// } -// } + for (StopableThread indexThread : threads) { + if (indexThread instanceof StopableIndexingThread && !(indexThread instanceof FullThrottleStopableIndexingThread)) { + assertEquals(0, ((StopableIndexingThread) indexThread).getFails()); + } + } // try and wait for any replications and what not to finish... From 51a45c9f4dcbdf4816bbd66bdaa4673bd2421f8a Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Wed, 20 Nov 2013 21:59:56 +0000 Subject: [PATCH 051/223] SOLR-5479: Deal with null message in SolrLogLayout git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1543966 13f79535-47bb-0310-9956-ffa450edef68 --- solr/core/src/java/org/apache/solr/util/SolrLogLayout.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/solr/core/src/java/org/apache/solr/util/SolrLogLayout.java b/solr/core/src/java/org/apache/solr/util/SolrLogLayout.java index 4fc04e93216..6b6d011acf3 100644 --- a/solr/core/src/java/org/apache/solr/util/SolrLogLayout.java +++ b/solr/core/src/java/org/apache/solr/util/SolrLogLayout.java @@ -112,7 +112,9 @@ public class SolrLogLayout extends Layout { public String _format(LoggingEvent event) { String message = (String) event.getMessage(); - + if (message == null) { + message = ""; + } StringBuilder sb = new StringBuilder(message.length() + 80); long now = event.timeStamp; From 4dc4d39cb934b3ec1a5a4590247ed8f72d8ccb4c Mon Sep 17 00:00:00 2001 From: Erick Erickson Date: Wed, 20 Nov 2013 22:15:17 +0000 Subject: [PATCH 052/223] SOLR-5208: Support for the setting of core.properties key/values at create-time on Collections API git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1543969 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 3 +++ .../solr/cloud/OverseerCollectionProcessor.java | 14 +++++++++++++- .../solr/handler/admin/CollectionsHandler.java | 16 +++++++++++++++- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 7b061f70804..96655b85bba 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -91,6 +91,9 @@ New Features * SOLR-5456: Admin UI - Allow creating new Files (steffkes) +* SOLR-5208: Support for the setting of core.properties key/values at create-time on + Collections API (Erick Erickson) + Bug Fixes ---------------------- diff --git a/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java b/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java index 1a0dff8fe69..c8e50b00b19 100644 --- a/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java +++ b/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java @@ -111,6 +111,7 @@ public class OverseerCollectionProcessor implements Runnable, ClosableThread { public static final String COLL_CONF = "collection.configName"; + public static final String COLL_PROP_PREFIX = "property."; public static final Map COLL_PROPS = ZkNodeProps.makeMap( ROUTER, DocRouter.DEFAULT_NAME, @@ -545,6 +546,7 @@ public class OverseerCollectionProcessor implements Runnable, ClosableThread { params.set(CoreAdminParams.COLLECTION, collectionName); params.set(CoreAdminParams.SHARD, sliceName); params.set(ZkStateReader.NUM_SHARDS_PROP, numSlices); + addPropertyParams(message, params); ShardRequest sreq = new ShardRequest(); params.set("qt", adminPath); @@ -739,7 +741,7 @@ public class OverseerCollectionProcessor implements Runnable, ClosableThread { params.set(CoreAdminParams.SHARD_RANGE, subRange.toString()); params.set(CoreAdminParams.SHARD_STATE, Slice.CONSTRUCTION); params.set(CoreAdminParams.SHARD_PARENT, parentSlice.getName()); - + addPropertyParams(message, params); sendShardRequest(nodeName, params); } @@ -849,6 +851,7 @@ public class OverseerCollectionProcessor implements Runnable, ClosableThread { params.set(CoreAdminParams.NAME, shardName); params.set(CoreAdminParams.COLLECTION, collectionName); params.set(CoreAdminParams.SHARD, sliceName); + addPropertyParams(message, params); // TODO: Figure the config used by the parent shard and use it. //params.set("collection.configName", configName); @@ -1287,6 +1290,14 @@ public class OverseerCollectionProcessor implements Runnable, ClosableThread { shardHandler.submit(sreq, replica, sreq.params); } + private void addPropertyParams(ZkNodeProps message, ModifiableSolrParams params) { + // Now add the property.key=value pairs + for (String key : message.keySet()) { + if (key.indexOf(COLL_PROP_PREFIX) != -1) { + params.set(key, message.getStr(key)); + } + } + } private void createCollection(ClusterState clusterState, ZkNodeProps message, NamedList results) throws KeeperException, InterruptedException { String collectionName = message.getStr("name"); if (clusterState.getCollections().contains(collectionName)) { @@ -1401,6 +1412,7 @@ public class OverseerCollectionProcessor implements Runnable, ClosableThread { params.set(CoreAdminParams.COLLECTION, collectionName); params.set(CoreAdminParams.SHARD, sliceName); params.set(ZkStateReader.NUM_SHARDS_PROP, numSlices); + addPropertyParams(message, params); ShardRequest sreq = new ShardRequest(); params.set("qt", adminPath); diff --git a/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java index 87bcf14ccfa..5d539c0ad65 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java @@ -318,6 +318,7 @@ public class CollectionsHandler extends RequestHandlerBase { SHARDS_PROP, "router."); + copyPropertiesIfNotNull(req.getParams(), props); ZkNodeProps m = new ZkNodeProps(props); handleResponse(OverseerCollectionProcessor.CREATECOLLECTION, m, rsp); @@ -342,6 +343,7 @@ public class CollectionsHandler extends RequestHandlerBase { Map map = makeMap(QUEUE_OPERATION, CREATESHARD); copyIfNotNull(req.getParams(),map,COLLECTION_PROP, SHARD_ID_PROP, REPLICATION_FACTOR,CREATE_NODE_SET); + copyPropertiesIfNotNull(req.getParams(), map); ZkNodeProps m = new ZkNodeProps(map); handleResponse(CREATESHARD, m, rsp); } @@ -372,7 +374,18 @@ public class CollectionsHandler extends RequestHandlerBase { } } - + + private void copyPropertiesIfNotNull(SolrParams params, Map props) { + Iterator iter = params.getParameterNamesIterator(); + while (iter.hasNext()) { + String param = iter.next(); + if (param.indexOf(OverseerCollectionProcessor.COLL_PROP_PREFIX) != -1) { + props.put(param, params.get(param)); + } + } + } + + private void handleDeleteShardAction(SolrQueryRequest req, SolrQueryResponse rsp) throws InterruptedException, KeeperException { log.info("Deleting Shard : " + req.getParamString()); @@ -420,6 +433,7 @@ public class CollectionsHandler extends RequestHandlerBase { if (rangesStr != null) { props.put(CoreAdminParams.RANGES, rangesStr); } + copyPropertiesIfNotNull(req.getParams(), props); ZkNodeProps m = new ZkNodeProps(props); From 1c00bcd42403987070933176a97af62d7eacb430 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Wed, 20 Nov 2013 23:47:06 +0000 Subject: [PATCH 053/223] SOLR-5481: SolrCmdDistributor should not let the http client do it's own retries. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1543986 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 3 +++ .../src/java/org/apache/solr/update/StreamingSolrServers.java | 1 + 2 files changed, 4 insertions(+) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 96655b85bba..216b1255f4e 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -120,6 +120,9 @@ Bug Fixes * SOLR-5479: SolrCmdDistributor retry logic stops if a leader for the request cannot be found in 1 second. (Mark Miller) +* SOLR-5481: SolrCmdDistributor should not let the http client do it's own + retries. (Mark Miller) + Optimizations ---------------------- diff --git a/solr/core/src/java/org/apache/solr/update/StreamingSolrServers.java b/solr/core/src/java/org/apache/solr/update/StreamingSolrServers.java index 4d460ef4c0e..a457736eaa9 100644 --- a/solr/core/src/java/org/apache/solr/update/StreamingSolrServers.java +++ b/solr/core/src/java/org/apache/solr/update/StreamingSolrServers.java @@ -50,6 +50,7 @@ public class StreamingSolrServers { params.set(HttpClientUtil.PROP_MAX_CONNECTIONS_PER_HOST, 32); params.set(HttpClientUtil.PROP_FOLLOW_REDIRECTS, false); params.set(HttpClientUtil.PROP_CONNECTION_TIMEOUT, 30000); + params.set(HttpClientUtil.PROP_USE_RETRY, false); httpClient = HttpClientUtil.createClient(params); } From 8def69cd7f16b3b4e2e81349832e0f1a39b5e847 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Thu, 21 Nov 2013 02:24:43 +0000 Subject: [PATCH 054/223] SOLR-5369: clean up this test git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1544006 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/solr/cloud/LeaderElector.java | 11 +++++- .../java/org/apache/solr/cloud/Overseer.java | 8 +++- .../org/apache/solr/cloud/ZkController.java | 8 ++++ .../solr/cloud/SliceStateUpdateTest.java | 37 +++++++++++++------ 4 files changed, 50 insertions(+), 14 deletions(-) diff --git a/solr/core/src/java/org/apache/solr/cloud/LeaderElector.java b/solr/core/src/java/org/apache/solr/cloud/LeaderElector.java index a2fd4c70e96..9335097bfd7 100644 --- a/solr/core/src/java/org/apache/solr/cloud/LeaderElector.java +++ b/solr/core/src/java/org/apache/solr/cloud/LeaderElector.java @@ -63,12 +63,20 @@ public class LeaderElector { protected SolrZkClient zkClient; private ZkCmdExecutor zkCmdExecutor; - + + // for tests + private volatile ElectionContext context; + public LeaderElector(SolrZkClient zkClient) { this.zkClient = zkClient; zkCmdExecutor = new ZkCmdExecutor((int) (zkClient.getZkClientTimeout()/1000.0 + 3000)); } + // for tests + public ElectionContext getContext() { + return context; + } + /** * Check if the candidate with the given n_* sequence number is the leader. * If it is, set the leaderId on the leader zk node. If it is not, start @@ -273,6 +281,7 @@ public class LeaderElector { */ public void setup(final ElectionContext context) throws InterruptedException, KeeperException { + this.context = context; String electZKPath = context.electionPath + LeaderElector.ELECTION_NODE; zkCmdExecutor.ensureExists(electZKPath, zkClient); diff --git a/solr/core/src/java/org/apache/solr/cloud/Overseer.java b/solr/core/src/java/org/apache/solr/cloud/Overseer.java index 7da3abb75b8..df2630193b4 100644 --- a/solr/core/src/java/org/apache/solr/cloud/Overseer.java +++ b/solr/core/src/java/org/apache/solr/cloud/Overseer.java @@ -935,9 +935,9 @@ public class Overseer { } - private OverseerThread ccThread; + private volatile OverseerThread ccThread; - private OverseerThread updaterThread; + private volatile OverseerThread updaterThread; private volatile boolean isClosed; @@ -970,6 +970,10 @@ public class Overseer { ccThread.start(); } + public OverseerThread getUpdaterThread() { + return updaterThread; + } + public void close() { isClosed = true; if (updaterThread != null) { diff --git a/solr/core/src/java/org/apache/solr/cloud/ZkController.java b/solr/core/src/java/org/apache/solr/cloud/ZkController.java index d32f37db637..2b016a39edf 100644 --- a/solr/core/src/java/org/apache/solr/cloud/ZkController.java +++ b/solr/core/src/java/org/apache/solr/cloud/ZkController.java @@ -1567,6 +1567,14 @@ public final class ZkController { return updateShardHandler; } + public Overseer getOverseer() { + return overseer; + } + + public LeaderElector getOverseerElector() { + return overseerElector; + } + /** * Returns the nodeName that should be used based on the specified properties. * diff --git a/solr/core/src/test/org/apache/solr/cloud/SliceStateUpdateTest.java b/solr/core/src/test/org/apache/solr/cloud/SliceStateUpdateTest.java index d896c75887e..c72273efafe 100644 --- a/solr/core/src/test/org/apache/solr/cloud/SliceStateUpdateTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/SliceStateUpdateTest.java @@ -19,6 +19,7 @@ package org.apache.solr.cloud; import org.apache.lucene.util.LuceneTestCase.Slow; import org.apache.solr.SolrTestCaseJ4; +import org.apache.solr.cloud.Overseer.OverseerThread; import org.apache.solr.common.cloud.ClusterState; import org.apache.solr.common.cloud.DocCollection; import org.apache.solr.common.cloud.DocRouter; @@ -59,8 +60,6 @@ public class SliceStateUpdateTest extends SolrTestCaseJ4 { private File dataDir2; - private File dataDir3; - @BeforeClass public static void beforeClass() { System.setProperty("solrcloud.skip.autorecovery", "true"); @@ -105,9 +104,6 @@ public class SliceStateUpdateTest extends SolrTestCaseJ4 { dataDir2 = new File(dataDir + File.separator + "data2"); dataDir2.mkdirs(); - dataDir3 = new File(dataDir + File.separator + "data3"); - dataDir3.mkdirs(); - // set some system properties for use by tests System.setProperty("solr.test.sys.prop1", "propone"); System.setProperty("solr.test.sys.prop2", "proptwo"); @@ -116,21 +112,19 @@ public class SliceStateUpdateTest extends SolrTestCaseJ4 { System.setProperty("hostPort", "1661"); System.setProperty("solr.data.dir", SliceStateUpdateTest.this.dataDir1.getAbsolutePath()); container1 = new CoreContainer(); - + container1.load(); System.clearProperty("hostPort"); System.setProperty("hostPort", "1662"); System.setProperty("solr.data.dir", SliceStateUpdateTest.this.dataDir2.getAbsolutePath()); container2 = new CoreContainer(); + container2.load(); System.clearProperty("hostPort"); System.clearProperty("solr.solr.home"); - container1.load(); - container2.load(); log.info("####SETUP_END " + getTestName()); - } @@ -139,7 +133,14 @@ public class SliceStateUpdateTest extends SolrTestCaseJ4 { System.setProperty("solrcloud.update.delay", "1"); /* Get ClusterState, update slice state and publish it to Zookeeper */ - + container1.getZkController().getZkStateReader().updateClusterState(true); + + // we don't want to race with legit overseer updates + OverseerThread updaterThread = container1.getZkController().getOverseer().getUpdaterThread(); + closeThread(updaterThread); + updaterThread = container2.getZkController().getOverseer().getUpdaterThread(); + closeThread(updaterThread); + ClusterState clusterState = container1.getZkController().getClusterState(); Map collectionStates = new LinkedHashMap(clusterState.getCollectionStates()); @@ -167,7 +168,7 @@ public class SliceStateUpdateTest extends SolrTestCaseJ4 { ZkController zkController2 = container2.getZkController(); ClusterState clusterState2 = null; Map slices = null; - for (int i = 100; i > 0; i--) { + for (int i = 60; i > 0; i--) { clusterState2 = zkController2.getClusterState(); slices = clusterState2.getSlicesMap("collection1"); if (slices != null && slices.containsKey("shard1") @@ -181,6 +182,20 @@ public class SliceStateUpdateTest extends SolrTestCaseJ4 { assertEquals("shard1", slices.get("shard1").getName()); assertEquals("inactive", slices.get("shard1").getState()); + + container1.getZkController().getOverseerElector().getContext().cancelElection(); + container2.getZkController().getOverseerElector().getContext().cancelElection(); + } + + private void closeThread(OverseerThread updaterThread) { + if (updaterThread != null) { + try { + updaterThread.close(); + updaterThread.interrupt(); + } catch (Throwable t) { + log.error("Error closing updaterThread", t); + } + } } @Override From cd3f22f76b40367647b93d5257ebab0dec0729ce Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Thu, 21 Nov 2013 04:56:22 +0000 Subject: [PATCH 055/223] SOLR-5486: cleanup DeleteInactiveReplicaTest git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1544033 13f79535-47bb-0310-9956-ffa450edef68 --- .../solr/cloud/DeleteInactiveReplicaTest.java | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/solr/core/src/test/org/apache/solr/cloud/DeleteInactiveReplicaTest.java b/solr/core/src/test/org/apache/solr/cloud/DeleteInactiveReplicaTest.java index f5482ed12ef..ffe89a1c84c 100644 --- a/solr/core/src/test/org/apache/solr/cloud/DeleteInactiveReplicaTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/DeleteInactiveReplicaTest.java @@ -17,6 +17,11 @@ package org.apache.solr.cloud; * limitations under the License. */ +import static org.apache.solr.common.cloud.ZkNodeProps.makeMap; + +import java.net.URL; +import java.util.Map; + import org.apache.solr.client.solrj.embedded.JettySolrRunner; import org.apache.solr.client.solrj.impl.CloudSolrServer; import org.apache.solr.client.solrj.impl.HttpSolrServer; @@ -27,24 +32,32 @@ import org.apache.solr.common.cloud.Slice; import org.apache.solr.common.cloud.ZkStateReader; import org.apache.solr.common.params.MapSolrParams; import org.apache.solr.common.util.NamedList; - -import java.net.URL; -import java.util.Map; -import java.util.Random; -import java.util.concurrent.Future; - -import static org.apache.solr.common.cloud.ZkNodeProps.makeMap; +import org.junit.After; +import org.junit.Before; public class DeleteInactiveReplicaTest extends DeleteReplicaTest{ + private CloudSolrServer client; + @Override public void doTest() throws Exception { deleteInactiveReplicaTest(); } + @Before + public void setUp() throws Exception { + super.setUp(); + client = createCloudClient(null); + } + + @After + public void tearDown() throws Exception { + super.tearDown(); + client.shutdown(); + } + private void deleteInactiveReplicaTest() throws Exception{ String COLL_NAME = "delDeadColl"; - CloudSolrServer client = createCloudClient(null); - createCloudClient(null); + createColl(COLL_NAME, client); boolean stopped = false; @@ -105,7 +118,6 @@ public class DeleteInactiveReplicaTest extends DeleteReplicaTest{ } log.info("removed_replicas {}/{} ",shard1.getName(),replica1.getName()); removeAndWaitForReplicaGone(COLL_NAME, client, replica1, shard1.getName()); - client.shutdown(); ChaosMonkey.start(stoppedJetty); log.info("restarted jetty"); From 54508fbe7a7b8f31f2dfbcf4e0af06197f83489d Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Thu, 21 Nov 2013 04:57:45 +0000 Subject: [PATCH 056/223] SOLR-5437: cleanup DeleteReplicaTest git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1544034 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/solr/cloud/DeleteReplicaTest.java | 64 +++++++------------ 1 file changed, 24 insertions(+), 40 deletions(-) diff --git a/solr/core/src/test/org/apache/solr/cloud/DeleteReplicaTest.java b/solr/core/src/test/org/apache/solr/cloud/DeleteReplicaTest.java index 8e247da601f..e28f673eb02 100644 --- a/solr/core/src/test/org/apache/solr/cloud/DeleteReplicaTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/DeleteReplicaTest.java @@ -17,7 +17,18 @@ package org.apache.solr.cloud; * limitations under the License. */ -import org.apache.lucene.util.Constants; +import static org.apache.solr.cloud.OverseerCollectionProcessor.DELETEREPLICA; +import static org.apache.solr.cloud.OverseerCollectionProcessor.MAX_SHARDS_PER_NODE; +import static org.apache.solr.cloud.OverseerCollectionProcessor.NUM_SLICES; +import static org.apache.solr.cloud.OverseerCollectionProcessor.REPLICATION_FACTOR; +import static org.apache.solr.common.cloud.ZkNodeProps.makeMap; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + import org.apache.solr.client.solrj.SolrRequest; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.impl.CloudSolrServer; @@ -29,43 +40,16 @@ import org.apache.solr.common.cloud.Slice; import org.apache.solr.common.params.MapSolrParams; import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.params.SolrParams; -import org.apache.solr.update.SolrCmdDistributor; -import org.apache.solr.util.DefaultSolrThreadFactory; +import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; -import java.io.IOException; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.CompletionService; -import java.util.concurrent.ExecutorCompletionService; -import java.util.concurrent.Future; -import java.util.concurrent.SynchronousQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; - -import static org.apache.solr.cloud.OverseerCollectionProcessor.DELETEREPLICA; -import static org.apache.solr.cloud.OverseerCollectionProcessor.MAX_SHARDS_PER_NODE; -import static org.apache.solr.cloud.OverseerCollectionProcessor.NUM_SLICES; -import static org.apache.solr.cloud.OverseerCollectionProcessor.REPLICATION_FACTOR; -import static org.apache.solr.common.cloud.ZkNodeProps.makeMap; - public class DeleteReplicaTest extends AbstractFullDistribZkTestBase { - private static final boolean DEBUG = false; - - ThreadPoolExecutor executor = new ThreadPoolExecutor(0, - Integer.MAX_VALUE, 5, TimeUnit.SECONDS, new SynchronousQueue(), - new DefaultSolrThreadFactory("testExecutor")); - - CompletionService completionService; - Set> pending; - + private CloudSolrServer client; + @BeforeClass public static void beforeThisClass2() throws Exception { - assumeFalse("FIXME: This test fails under Java 8 all the time, see SOLR-4711", Constants.JRE_IS_MINIMUM_JAVA8); + } @Before @@ -74,22 +58,26 @@ public class DeleteReplicaTest extends AbstractFullDistribZkTestBase { super.setUp(); System.setProperty("numShards", Integer.toString(sliceCount)); System.setProperty("solr.xml.persist", "true"); + client = createCloudClient(null); + } + + @After + public void tearDown() throws Exception { + super.tearDown(); + client.shutdown(); } protected String getSolrXml() { return "solr-no-core.xml"; } - public DeleteReplicaTest() { fixShardCount = true; sliceCount = 2; shardCount = 4; - completionService = new ExecutorCompletionService(executor); - pending = new HashSet>(); - checkCreatedVsState = false; + checkCreatedVsState = false; } @Override @@ -109,7 +97,6 @@ public class DeleteReplicaTest extends AbstractFullDistribZkTestBase { } } - @Override public void doTest() throws Exception { deleteLiveReplicaTest(); @@ -117,8 +104,6 @@ public class DeleteReplicaTest extends AbstractFullDistribZkTestBase { // super.printLayout(); } - - private void deleteLiveReplicaTest() throws Exception{ String COLL_NAME = "delLiveColl"; CloudSolrServer client = createCloudClient(null); @@ -140,7 +125,6 @@ public class DeleteReplicaTest extends AbstractFullDistribZkTestBase { Thread.sleep(2500);//remove this later.not sure if the clusterstate is not propagated and that is why the tests are failing.SOLR-5437 removeAndWaitForReplicaGone(COLL_NAME, client, replica1, shard1.getName()); client.shutdown(); - } protected void removeAndWaitForReplicaGone(String COLL_NAME, CloudSolrServer client, Replica replica, String shard) throws SolrServerException, IOException, InterruptedException { From f7d1b43c9ec9631304d8018c1d3f570a73fa1730 Mon Sep 17 00:00:00 2001 From: Shalin Shekhar Mangar Date: Thu, 21 Nov 2013 06:27:11 +0000 Subject: [PATCH 057/223] SOLR-5428: New 'stats.calcdistinct' parameter in StatsComponent returns set of distinct values and their count. This can also be specified per field e.g. 'f.field.stats.calcdistinct' git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1544043 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 4 ++ .../handler/component/FieldFacetStats.java | 8 +-- .../handler/component/StatsComponent.java | 14 ++--- .../handler/component/StatsValuesFactory.java | 53 ++++++++++++------- .../apache/solr/request/UnInvertedField.java | 7 +-- .../handler/component/StatsComponentTest.java | 51 +++++++++++++----- .../apache/solr/client/solrj/SolrQuery.java | 8 +++ .../client/solrj/response/FieldStatsInfo.java | 23 ++++++++ .../solr/common/params/StatsParams.java | 1 + 9 files changed, 125 insertions(+), 44 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 216b1255f4e..fca31985424 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -94,6 +94,10 @@ New Features * SOLR-5208: Support for the setting of core.properties key/values at create-time on Collections API (Erick Erickson) +* SOLR-5428: New 'stats.calcdistinct' parameter in StatsComponent returns + set of distinct values and their count. This can also be specified per field + e.g. 'f.field.stats.calcdistinct'. (Elran Dvir via shalin) + Bug Fixes ---------------------- diff --git a/solr/core/src/java/org/apache/solr/handler/component/FieldFacetStats.java b/solr/core/src/java/org/apache/solr/handler/component/FieldFacetStats.java index 6cd9a190573..0a8703ebfae 100644 --- a/solr/core/src/java/org/apache/solr/handler/component/FieldFacetStats.java +++ b/solr/core/src/java/org/apache/solr/handler/component/FieldFacetStats.java @@ -48,6 +48,7 @@ public class FieldFacetStats { public final String name; final SchemaField facet_sf; final SchemaField field_sf; + final boolean calcDistinct; public final Map facetStatsValues; @@ -63,10 +64,11 @@ public class FieldFacetStats { private final BytesRef tempBR = new BytesRef(); - public FieldFacetStats(SolrIndexSearcher searcher, String name, SchemaField field_sf, SchemaField facet_sf) { + public FieldFacetStats(SolrIndexSearcher searcher, String name, SchemaField field_sf, SchemaField facet_sf, boolean calcDistinct) { this.name = name; this.field_sf = field_sf; this.facet_sf = facet_sf; + this.calcDistinct = calcDistinct; topLevelReader = searcher.getAtomicReader(); valueSource = facet_sf.getType().getValueSource(facet_sf, null); @@ -78,7 +80,7 @@ public class FieldFacetStats { private StatsValues getStatsValues(String key) throws IOException { StatsValues stats = facetStatsValues.get(key); if (stats == null) { - stats = StatsValuesFactory.createStatsValues(field_sf); + stats = StatsValuesFactory.createStatsValues(field_sf, calcDistinct); facetStatsValues.put(key, stats); stats.setNextReader(context); } @@ -139,7 +141,7 @@ public class FieldFacetStats { String key = (String) pairs.getKey(); StatsValues facetStats = facetStatsValues.get(key); if (facetStats == null) { - facetStats = StatsValuesFactory.createStatsValues(field_sf); + facetStats = StatsValuesFactory.createStatsValues(field_sf, calcDistinct); facetStatsValues.put(key, facetStats); } Integer count = (Integer) pairs.getValue(); diff --git a/solr/core/src/java/org/apache/solr/handler/component/StatsComponent.java b/solr/core/src/java/org/apache/solr/handler/component/StatsComponent.java index 11a4c824e99..3af0f62e5b8 100644 --- a/solr/core/src/java/org/apache/solr/handler/component/StatsComponent.java +++ b/solr/core/src/java/org/apache/solr/handler/component/StatsComponent.java @@ -167,8 +167,9 @@ class StatsInfo { String[] statsFs = params.getParams(StatsParams.STATS_FIELD); if (statsFs != null) { for (String field : statsFs) { + boolean calcDistinct = params.getFieldBool(field, StatsParams.STATS_CALC_DISTINCT, false); SchemaField sf = rb.req.getSchema().getField(field); - statsFields.put(field, StatsValuesFactory.createStatsValues(sf)); + statsFields.put(field, StatsValuesFactory.createStatsValues(sf, calcDistinct)); } } } @@ -207,6 +208,7 @@ class SimpleStats { if (null != statsFs) { final IndexSchema schema = searcher.getSchema(); for (String f : statsFs) { + boolean calcDistinct = params.getFieldBool(f, StatsParams.STATS_CALC_DISTINCT, false); String[] facets = params.getFieldParams(f, StatsParams.STATS_FACET); if (facets == null) { facets = new String[0]; // make sure it is something... @@ -218,9 +220,9 @@ class SimpleStats { if (sf.multiValued() || ft.multiValuedFieldCache()) { //use UnInvertedField for multivalued fields UnInvertedField uif = UnInvertedField.getUnInvertedField(f, searcher); - stv = uif.getStats(searcher, docs, facets).getStatsValues(); + stv = uif.getStats(searcher, docs, calcDistinct, facets).getStatsValues(); } else { - stv = getFieldCacheStats(f, facets); + stv = getFieldCacheStats(f, calcDistinct, facets); } if (isShard == true || (Long) stv.get("count") > 0) { res.add(f, stv); @@ -232,11 +234,11 @@ class SimpleStats { return res; } - public NamedList getFieldCacheStats(String fieldName, String[] facet) throws IOException { + public NamedList getFieldCacheStats(String fieldName, boolean calcDistinct, String[] facet) throws IOException { IndexSchema schema = searcher.getSchema(); final SchemaField sf = schema.getField(fieldName); - final StatsValues allstats = StatsValuesFactory.createStatsValues(sf); + final StatsValues allstats = StatsValuesFactory.createStatsValues(sf, calcDistinct); List facetStats = new ArrayList(); for( String facetField : facet ) { @@ -247,7 +249,7 @@ class SimpleStats { "Stats can only facet on single-valued fields, not: " + facetField ); } - facetStats.add(new FieldFacetStats(searcher, facetField, sf, fsf)); + facetStats.add(new FieldFacetStats(searcher, facetField, sf, fsf, calcDistinct)); } final Iterator ctxIt = searcher.getIndexReader().leaves().iterator(); diff --git a/solr/core/src/java/org/apache/solr/handler/component/StatsValuesFactory.java b/solr/core/src/java/org/apache/solr/handler/component/StatsValuesFactory.java index 2777a48a01e..e4508afab07 100644 --- a/solr/core/src/java/org/apache/solr/handler/component/StatsValuesFactory.java +++ b/solr/core/src/java/org/apache/solr/handler/component/StatsValuesFactory.java @@ -18,10 +18,7 @@ package org.apache.solr.handler.component; import java.io.IOException; -import java.util.Collections; -import java.util.Date; -import java.util.Map; -import java.util.HashMap; +import java.util.*; import org.apache.lucene.index.AtomicReaderContext; import org.apache.lucene.queries.function.FunctionValues; @@ -44,7 +41,7 @@ public class StatsValuesFactory { * @param sf SchemaField for the field whose statistics will be created by the resulting StatsValues * @return Instance of StatsValues that will create statistics from values from a field of the given type */ - public static StatsValues createStatsValues(SchemaField sf) { + public static StatsValues createStatsValues(SchemaField sf, boolean calcDistinct) { // TODO: allow for custom field types FieldType fieldType = sf.getType(); if (DoubleField.class.isInstance(fieldType) || @@ -56,13 +53,13 @@ public class StatsValuesFactory { SortableIntField.class.isInstance(fieldType) || SortableLongField.class.isInstance(fieldType) || SortableFloatField.class.isInstance(fieldType)) { - return new NumericStatsValues(sf); + return new NumericStatsValues(sf, calcDistinct); } else if (DateField.class.isInstance(fieldType)) { - return new DateStatsValues(sf); + return new DateStatsValues(sf, calcDistinct); } else if (StrField.class.isInstance(fieldType)) { - return new StringStatsValues(sf); + return new StringStatsValues(sf, calcDistinct); } else if (sf.getType().getClass().equals(EnumField.class)) { - return new EnumStatsValues(sf); + return new EnumStatsValues(sf, calcDistinct); } else { throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Field type " + fieldType + " is not currently supported"); } @@ -84,15 +81,20 @@ abstract class AbstractStatsValues implements StatsValues { protected T min; protected long missing; protected long count; + protected long countDistinct; + protected Set distinctValues; private ValueSource valueSource; protected FunctionValues values; + protected boolean calcDistinct = false; // facetField facetValue protected Map> facets = new HashMap>(); - protected AbstractStatsValues(SchemaField sf) { + protected AbstractStatsValues(SchemaField sf, boolean calcDistinct) { this.sf = sf; this.ft = sf.getType(); + this.distinctValues = new TreeSet(); + this.calcDistinct = calcDistinct; } /** @@ -102,6 +104,10 @@ abstract class AbstractStatsValues implements StatsValues { public void accumulate(NamedList stv) { count += (Long) stv.get("count"); missing += (Long) stv.get("missing"); + if (calcDistinct) { + distinctValues.addAll((Collection) stv.get("distinctValues")); + countDistinct = distinctValues.size(); + } updateMinMax((T) stv.get("min"), (T) stv.get("max")); updateTypeSpecificStats(stv); @@ -123,7 +129,7 @@ abstract class AbstractStatsValues implements StatsValues { String val = vals.getName(j); StatsValues vvals = addTo.get(val); if (vvals == null) { - vvals = StatsValuesFactory.createStatsValues(sf); + vvals = StatsValuesFactory.createStatsValues(sf, calcDistinct); addTo.put(val, vvals); } vvals.accumulate((NamedList) vals.getVal(j)); @@ -142,6 +148,10 @@ abstract class AbstractStatsValues implements StatsValues { public void accumulate(T value, int count) { this.count += count; + if (calcDistinct) { + distinctValues.add(value); + countDistinct = distinctValues.size(); + } updateMinMax(value, value); updateTypeSpecificStats(value, count); } @@ -181,6 +191,11 @@ abstract class AbstractStatsValues implements StatsValues { res.add("max", max); res.add("count", count); res.add("missing", missing); + if (calcDistinct) { + res.add("distinctValues", distinctValues); + res.add("countDistinct", countDistinct); + } + addTypeSpecificStats(res); // add the facet stats @@ -242,8 +257,8 @@ class NumericStatsValues extends AbstractStatsValues { double sum; double sumOfSquares; - public NumericStatsValues(SchemaField sf) { - super(sf); + public NumericStatsValues(SchemaField sf, boolean calcDistinct) { + super(sf, calcDistinct); min = Double.POSITIVE_INFINITY; max = Double.NEGATIVE_INFINITY; } @@ -317,8 +332,8 @@ class NumericStatsValues extends AbstractStatsValues { */ class EnumStatsValues extends AbstractStatsValues { - public EnumStatsValues(SchemaField sf) { - super(sf); + public EnumStatsValues(SchemaField sf, boolean calcDistinct) { + super(sf, calcDistinct); } /** @@ -386,8 +401,8 @@ class DateStatsValues extends AbstractStatsValues { private long sum = -1; double sumOfSquares = 0; - public DateStatsValues(SchemaField sf) { - super(sf); + public DateStatsValues(SchemaField sf, boolean calcDistinct) { + super(sf, calcDistinct); } @Override @@ -469,8 +484,8 @@ class DateStatsValues extends AbstractStatsValues { */ class StringStatsValues extends AbstractStatsValues { - public StringStatsValues(SchemaField sf) { - super(sf); + public StringStatsValues(SchemaField sf, boolean calcDistinct) { + super(sf, calcDistinct); } @Override diff --git a/solr/core/src/java/org/apache/solr/request/UnInvertedField.java b/solr/core/src/java/org/apache/solr/request/UnInvertedField.java index 1939b63a684..1a33b8a51ca 100644 --- a/solr/core/src/java/org/apache/solr/request/UnInvertedField.java +++ b/solr/core/src/java/org/apache/solr/request/UnInvertedField.java @@ -464,11 +464,12 @@ public class UnInvertedField extends DocTermOrds { * * @param searcher The Searcher to use to gather the statistics * @param baseDocs The {@link org.apache.solr.search.DocSet} to gather the stats on + * @param calcDistinct whether distinct values should be collected and counted * @param facet One or more fields to facet on. * @return The {@link org.apache.solr.handler.component.StatsValues} collected * @throws IOException If there is a low-level I/O error. */ - public StatsValues getStats(SolrIndexSearcher searcher, DocSet baseDocs, String[] facet) throws IOException { + public StatsValues getStats(SolrIndexSearcher searcher, DocSet baseDocs, boolean calcDistinct, String[] facet) throws IOException { //this function is ripped off nearly wholesale from the getCounts function to use //for multiValued fields within the StatsComponent. may be useful to find common //functionality between the two and refactor code somewhat @@ -477,7 +478,7 @@ public class UnInvertedField extends DocTermOrds { SchemaField sf = searcher.getSchema().getField(field); // FieldType ft = sf.getType(); - StatsValues allstats = StatsValuesFactory.createStatsValues(sf); + StatsValues allstats = StatsValuesFactory.createStatsValues(sf, calcDistinct); DocSet docs = baseDocs; @@ -494,7 +495,7 @@ public class UnInvertedField extends DocTermOrds { SortedDocValues si; for (String f : facet) { SchemaField facet_sf = searcher.getSchema().getField(f); - finfo[i] = new FieldFacetStats(searcher, f, sf, facet_sf); + finfo[i] = new FieldFacetStats(searcher, f, sf, facet_sf, calcDistinct); i++; } diff --git a/solr/core/src/test/org/apache/solr/handler/component/StatsComponentTest.java b/solr/core/src/test/org/apache/solr/handler/component/StatsComponentTest.java index 98bf0dd2f70..338ee571137 100644 --- a/solr/core/src/test/org/apache/solr/handler/component/StatsComponentTest.java +++ b/solr/core/src/test/org/apache/solr/handler/component/StatsComponentTest.java @@ -80,12 +80,14 @@ public class StatsComponentTest extends AbstractSolrTestCase { assertU(adoc("id", "4", f, "-40")); assertU(commit()); - assertQ("test statistics values", req("q","*:*", "stats","true", "stats.field",f) + assertQ("test statistics values", req("q", "*:*", "stats", "true", "stats.field", f, "stats.calcdistinct", "true") , "//double[@name='min'][.='-40.0']" , "//double[@name='max'][.='-10.0']" , "//double[@name='sum'][.='-100.0']" , "//long[@name='count'][.='4']" , "//long[@name='missing'][.='0']" + , "//long[@name='countDistinct'][.='4']" + , "count(//arr[@name='distinctValues']/*)='4'" , "//double[@name='sumOfSquares'][.='3000.0']" , "//double[@name='mean'][.='-25.0']" , "//double[@name='stddev'][.='12.909944487358056']" @@ -101,45 +103,53 @@ public class StatsComponentTest extends AbstractSolrTestCase { assertU(adoc("id", "5", "active_s", "false")); assertU(commit()); - assertQ("test statistics values", req("q","*:*", "stats","true", "stats.field",f) + assertQ("test statistics values", req("q", "*:*", "stats", "true", "stats.field", f, "stats.calcdistinct", "true") , "//double[@name='min'][.='-100.0']" , "//double[@name='max'][.='200.0']" , "//double[@name='sum'][.='9.0']" , "//long[@name='count'][.='8']" , "//long[@name='missing'][.='1']" + , "//long[@name='countDistinct'][.='8']" + , "count(//arr[@name='distinctValues']/*)='8'" , "//double[@name='sumOfSquares'][.='53101.0']" , "//double[@name='mean'][.='1.125']" , "//double[@name='stddev'][.='87.08852228787508']" ); - assertQ("test statistics values", req("q","*:*", "stats","true", "stats.field",f, "stats.facet","active_s") + assertQ("test statistics values", req("q", "*:*", "stats", "true", "stats.field", f, "stats.facet", "active_s", "stats.calcdistinct", "true") , "//double[@name='min'][.='-100.0']" , "//double[@name='max'][.='200.0']" , "//double[@name='sum'][.='9.0']" , "//long[@name='count'][.='8']" , "//long[@name='missing'][.='1']" + , "//long[@name='countDistinct'][.='8']" + , "count(//lst[@name='" + f + "']/arr[@name='distinctValues']/*)='8'" , "//double[@name='sumOfSquares'][.='53101.0']" , "//double[@name='mean'][.='1.125']" , "//double[@name='stddev'][.='87.08852228787508']" ); - assertQ("test value for active_s=true", req("q","*:*", "stats","true", "stats.field",f, "stats.facet","active_s") + assertQ("test value for active_s=true", req("q", "*:*", "stats", "true", "stats.field", f, "stats.facet", "active_s", "stats.calcdistinct", "true") , "//lst[@name='true']/double[@name='min'][.='-100.0']" , "//lst[@name='true']/double[@name='max'][.='200.0']" , "//lst[@name='true']/double[@name='sum'][.='70.0']" , "//lst[@name='true']/long[@name='count'][.='4']" , "//lst[@name='true']/long[@name='missing'][.='0']" + , "//lst[@name='true']//long[@name='countDistinct'][.='4']" + , "count(//lst[@name='true']/arr[@name='distinctValues']/*)='4'" , "//lst[@name='true']/double[@name='sumOfSquares'][.='50500.0']" , "//lst[@name='true']/double[@name='mean'][.='17.5']" , "//lst[@name='true']/double[@name='stddev'][.='128.16005617976296']" ); - assertQ("test value for active_s=false", req("q","*:*", "stats","true", "stats.field",f, "stats.facet","active_s", "indent","true") + assertQ("test value for active_s=false", req("q", "*:*", "stats", "true", "stats.field", f, "stats.facet", "active_s", "stats.calcdistinct", "true", "indent", "true") , "//lst[@name='false']/double[@name='min'][.='-40.0']" , "//lst[@name='false']/double[@name='max'][.='10.0']" , "//lst[@name='false']/double[@name='sum'][.='-61.0']" , "//lst[@name='false']/long[@name='count'][.='4']" , "//lst[@name='false']/long[@name='missing'][.='1']" + , "//lst[@name='true']//long[@name='countDistinct'][.='4']" + , "count(//lst[@name='true']/arr[@name='distinctValues']/*)='4'" , "//lst[@name='false']/double[@name='sumOfSquares'][.='2601.0']" , "//lst[@name='false']/double[@name='mean'][.='-15.25']" , "//lst[@name='false']/double[@name='stddev'][.='23.59908190304586']" @@ -160,6 +170,7 @@ public class StatsComponentTest extends AbstractSolrTestCase { args.put(CommonParams.Q, "*:*"); args.put(StatsParams.STATS, "true"); args.put(StatsParams.STATS_FIELD, "active_s"); + args.put("f.active_s.stats.calcdistinct","true"); args.put("indent", "true"); SolrQueryRequest req = new LocalSolrQueryRequest(core, new MapSolrParams(args)); @@ -167,7 +178,9 @@ public class StatsComponentTest extends AbstractSolrTestCase { "//str[@name='min'][.='string1']", "//str[@name='max'][.='string3']", "//long[@name='count'][.='3']", - "//long[@name='missing'][.='1']"); + "//long[@name='missing'][.='1']", + "//long[@name='countDistinct'][.='3']", + "count(//arr[@name='distinctValues']/str)='3'"); } public void testFieldStatisticsResultsDateField() throws Exception { @@ -188,6 +201,7 @@ public class StatsComponentTest extends AbstractSolrTestCase { args.put(CommonParams.Q, "*:*"); args.put(StatsParams.STATS, "true"); args.put(StatsParams.STATS_FIELD, "active_dt"); + args.put("f.active_dt.stats.calcdistinct","true"); args.put("indent", "true"); SolrQueryRequest req = new LocalSolrQueryRequest(core, new MapSolrParams(args)); @@ -195,14 +209,15 @@ public class StatsComponentTest extends AbstractSolrTestCase { "//long[@name='count'][.='2']", "//long[@name='missing'][.='1']", "//date[@name='min'][.='1970-01-02T10:17:36Z']", - "//date[@name='max'][.='1970-01-12T10:20:54Z']" + "//date[@name='max'][.='1970-01-12T10:20:54Z']", + "//long[@name='countDistinct'][.='2']", + "count(//arr[@name='distinctValues']/date)='2'" // "//date[@name='sum'][.='1970-01-13T20:38:30Z']", // sometimes 29.999Z // "//date[@name='mean'][.='1970-01-07T10:19:15Z']" // sometiems 14.999Z ); } - public void doTestFieldStatisticsMissingResult(String f) throws Exception { assertU(adoc("id", "1", f, "-10")); assertU(adoc("id", "2", f, "-20")); @@ -211,12 +226,14 @@ public class StatsComponentTest extends AbstractSolrTestCase { assertU(adoc("id", "4", f, "-40")); assertU(commit()); - assertQ("test statistics values", req("q","*:*", "stats","true", "stats.field",f) + assertQ("test statistics values", req("q", "*:*", "stats", "true", "stats.field", f, "stats.calcdistinct", "true") , "//double[@name='min'][.='-40.0']" , "//double[@name='max'][.='-10.0']" , "//double[@name='sum'][.='-70.0']" , "//long[@name='count'][.='3']" , "//long[@name='missing'][.='1']" + , "//long[@name='countDistinct'][.='3']" + , "count(//arr[@name='distinctValues']/*)='3'" , "//double[@name='sumOfSquares'][.='2100.0']" , "//double[@name='mean'][.='-23.333333333333332']" , "//double[@name='stddev'][.='15.275252316519467']" @@ -233,24 +250,28 @@ public class StatsComponentTest extends AbstractSolrTestCase { final String pre = "//lst[@name='stats_fields']/lst[@name='"+f+"']/lst[@name='facets']/lst[@name='active_s']"; - assertQ("test value for active_s=true", req("q","*:*", "stats","true", "stats.field",f, "stats.facet","active_s","stats.facet","other_s","indent","true") + assertQ("test value for active_s=true", req("q", "*:*", "stats", "true", "stats.field", f, "stats.facet", "active_s", "stats.facet", "other_s", "stats.calcdistinct", "true", "indent", "true") , "*[count("+pre+")=1]" , pre+"/lst[@name='true']/double[@name='min'][.='10.0']" , pre+"/lst[@name='true']/double[@name='max'][.='20.0']" , pre+"/lst[@name='true']/double[@name='sum'][.='30.0']" , pre+"/lst[@name='true']/long[@name='count'][.='2']" , pre+"/lst[@name='true']/long[@name='missing'][.='0']" + , pre + "/lst[@name='true']/long[@name='countDistinct'][.='2']" + , "count(" + pre + "/lst[@name='true']/arr[@name='distinctValues']/*)='2'" , pre+"/lst[@name='true']/double[@name='sumOfSquares'][.='500.0']" , pre+"/lst[@name='true']/double[@name='mean'][.='15.0']" , pre+"/lst[@name='true']/double[@name='stddev'][.='7.0710678118654755']" ); - assertQ("test value for active_s=false", req("q","*:*", "stats","true", "stats.field",f, "stats.facet","active_s") + assertQ("test value for active_s=false", req("q", "*:*", "stats", "true", "stats.field", f, "stats.facet", "active_s", "stats.calcdistinct", "true") , pre+"/lst[@name='false']/double[@name='min'][.='30.0']" , pre+"/lst[@name='false']/double[@name='max'][.='40.0']" , pre+"/lst[@name='false']/double[@name='sum'][.='70.0']" , pre+"/lst[@name='false']/long[@name='count'][.='2']" , pre+"/lst[@name='false']/long[@name='missing'][.='0']" + , pre + "/lst[@name='true']/long[@name='countDistinct'][.='2']" + , "count(" + pre + "/lst[@name='true']/arr[@name='distinctValues']/*)='2'" , pre+"/lst[@name='false']/double[@name='sumOfSquares'][.='2500.0']" , pre+"/lst[@name='false']/double[@name='mean'][.='35.0']" , pre+"/lst[@name='false']/double[@name='stddev'][.='7.0710678118654755']" @@ -265,23 +286,27 @@ public class StatsComponentTest extends AbstractSolrTestCase { assertU(adoc("id", "4", f, "40", "active_s", "false")); assertU(commit()); - assertQ("test value for active_s=true", req("q","*:*", "stats","true", "stats.field",f, "stats.facet","active_s") + assertQ("test value for active_s=true", req("q", "*:*", "stats", "true", "stats.field", f, "stats.facet", "active_s", "stats.calcdistinct", "true") , "//lst[@name='true']/double[@name='min'][.='10.0']" , "//lst[@name='true']/double[@name='max'][.='20.0']" , "//lst[@name='true']/double[@name='sum'][.='30.0']" , "//lst[@name='true']/long[@name='count'][.='2']" , "//lst[@name='true']/long[@name='missing'][.='0']" + , "//lst[@name='true']/long[@name='countDistinct'][.='2']" + , "count(//lst[@name='true']/arr[@name='distinctValues']/*)='2'" , "//lst[@name='true']/double[@name='sumOfSquares'][.='500.0']" , "//lst[@name='true']/double[@name='mean'][.='15.0']" , "//lst[@name='true']/double[@name='stddev'][.='7.0710678118654755']" ); - assertQ("test value for active_s=false", req("q","*:*", "stats","true", "stats.field",f, "stats.facet","active_s") + assertQ("test value for active_s=false", req("q", "*:*", "stats", "true", "stats.field", f, "stats.facet", "active_s", "stats.calcdistinct", "true") , "//lst[@name='false']/double[@name='min'][.='40.0']" , "//lst[@name='false']/double[@name='max'][.='40.0']" , "//lst[@name='false']/double[@name='sum'][.='40.0']" , "//lst[@name='false']/long[@name='count'][.='1']" , "//lst[@name='false']/long[@name='missing'][.='1']" + , "//lst[@name='false']/long[@name='countDistinct'][.='1']" + , "count(//lst[@name='false']/arr[@name='distinctValues']/*)='1'" , "//lst[@name='false']/double[@name='sumOfSquares'][.='1600.0']" , "//lst[@name='false']/double[@name='mean'][.='40.0']" , "//lst[@name='false']/double[@name='stddev'][.='0.0']" diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/SolrQuery.java b/solr/solrj/src/java/org/apache/solr/client/solrj/SolrQuery.java index 0e933dd9a48..f510c472c78 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/SolrQuery.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/SolrQuery.java @@ -782,6 +782,14 @@ public class SolrQuery extends ModifiableSolrParams } } + public void addStatsFieldCalcDistinct(String field, boolean calcDistinct) { + if (field == null) { + this.add(StatsParams.STATS_CALC_DISTINCT, Boolean.toString(calcDistinct)); + } else { + this.add("f." + field + "." + StatsParams.STATS_CALC_DISTINCT, Boolean.toString(calcDistinct)); + } + } + public SolrQuery setFilterQueries(String ... fq) { this.set(CommonParams.FQ, fq); return this; diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/response/FieldStatsInfo.java b/solr/solrj/src/java/org/apache/solr/client/solrj/response/FieldStatsInfo.java index 3e3f216c943..b56938ba543 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/response/FieldStatsInfo.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/response/FieldStatsInfo.java @@ -20,6 +20,7 @@ import org.apache.solr.common.util.NamedList; import java.io.Serializable; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -37,6 +38,8 @@ public class FieldStatsInfo implements Serializable { Object max; Object sum; Long count; + Long countDistinct; + Collection distinctValues; Long missing; Object mean = null; Double sumOfSquares = null; @@ -61,6 +64,12 @@ public class FieldStatsInfo implements Serializable { else if( "count".equals( entry.getKey() ) ) { count = (Long)entry.getValue(); } + else if ("countDistinct".equals(entry.getKey())) { + countDistinct = (Long) entry.getValue(); + } + else if ("distinctValues".equals(entry.getKey())) { + distinctValues = (Collection) entry.getValue(); + } else if( "missing".equals( entry.getKey() ) ) { missing = (Long)entry.getValue(); } @@ -112,6 +121,12 @@ public class FieldStatsInfo implements Serializable { if( count != null ) { sb.append( " count:").append( count ); } + if (countDistinct != null) { + sb.append(" countDistinct:").append(countDistinct); + } + if (distinctValues != null) { + sb.append(" distinctValues:").append(distinctValues); + } if( missing != null ) { sb.append( " missing:").append( missing ); } @@ -145,6 +160,14 @@ public class FieldStatsInfo implements Serializable { return count; } + public Long getCountDistinct() { + return countDistinct; + } + + public Collection getDistinctValues() { + return distinctValues; + } + public Long getMissing() { return missing; } diff --git a/solr/solrj/src/java/org/apache/solr/common/params/StatsParams.java b/solr/solrj/src/java/org/apache/solr/common/params/StatsParams.java index 628b5496bc1..6fb7935c7f7 100644 --- a/solr/solrj/src/java/org/apache/solr/common/params/StatsParams.java +++ b/solr/solrj/src/java/org/apache/solr/common/params/StatsParams.java @@ -24,4 +24,5 @@ public interface StatsParams { public static final String STATS = "stats"; public static final String STATS_FIELD = STATS + ".field"; public static final String STATS_FACET = STATS + ".facet"; + public static final String STATS_CALC_DISTINCT = STATS + ".calcdistinct"; } From 20591fd6f75eb479a2e685d049e116c80cb96ca1 Mon Sep 17 00:00:00 2001 From: Shalin Shekhar Mangar Date: Thu, 21 Nov 2013 07:25:23 +0000 Subject: [PATCH 058/223] SOLR-5487: Replication factor error message doesn't match constraint git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1544050 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 3 +++ .../org/apache/solr/cloud/OverseerCollectionProcessor.java | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index fca31985424..0711db37d18 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -144,6 +144,9 @@ Other Changes * SOLR-5404: The example config references deprecated classes. (Uwe Schindler, Rafał Kuć via Mark Miller) +* SOLR-5487: Replication factor error message doesn't match constraint. + (Patrick Hunt via shalin) + ================== 4.6.0 ================== Versions of Major Components diff --git a/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java b/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java index c8e50b00b19..c0047628ed4 100644 --- a/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java +++ b/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java @@ -1328,7 +1328,7 @@ public class OverseerCollectionProcessor implements Runnable, ClosableThread { List createNodeList = ((createNodeSetStr = message.getStr(CREATE_NODE_SET)) == null)?null:StrUtils.splitSmart(createNodeSetStr, ",", true); if (repFactor <= 0) { - throw new SolrException(ErrorCode.BAD_REQUEST, REPLICATION_FACTOR + " must be greater than or equal to 0"); + throw new SolrException(ErrorCode.BAD_REQUEST, REPLICATION_FACTOR + " must be greater than 0"); } if (numSlices <= 0) { From ed723bfaee7625f12f37962afd530418fd28db98 Mon Sep 17 00:00:00 2001 From: Adrien Grand Date: Thu, 21 Nov 2013 10:20:53 +0000 Subject: [PATCH 059/223] Fix test bug: StoredFieldsWriter.close can be called in case an exception occurred. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1544087 13f79535-47bb-0310-9956-ffa450edef68 --- .../lucene/codecs/asserting/AssertingStoredFieldsFormat.java | 1 - 1 file changed, 1 deletion(-) diff --git a/lucene/test-framework/src/java/org/apache/lucene/codecs/asserting/AssertingStoredFieldsFormat.java b/lucene/test-framework/src/java/org/apache/lucene/codecs/asserting/AssertingStoredFieldsFormat.java index b637559c381..a2763875662 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/codecs/asserting/AssertingStoredFieldsFormat.java +++ b/lucene/test-framework/src/java/org/apache/lucene/codecs/asserting/AssertingStoredFieldsFormat.java @@ -135,7 +135,6 @@ public class AssertingStoredFieldsFormat extends StoredFieldsFormat { @Override public void close() throws IOException { in.close(); - assert docStatus != Status.STARTED; } } } From db8f24dbadc56f1f5061cc0b2d20bb4059948790 Mon Sep 17 00:00:00 2001 From: Michael McCandless Date: Thu, 21 Nov 2013 11:16:44 +0000 Subject: [PATCH 060/223] fix test bug git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1544118 13f79535-47bb-0310-9956-ffa450edef68 --- .../lucene/index/TestIndexWriterReader.java | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterReader.java b/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterReader.java index ef0352f1c29..6304f52cd35 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterReader.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterReader.java @@ -1103,18 +1103,9 @@ public class TestIndexWriterReader extends LuceneTestCase { * writer, we don't see merge starvation. */ public void testTooManySegments() throws Exception { Directory dir = newDirectory(); - IndexWriterConfig iwc = newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random())); - MergePolicy mp = iwc.getMergePolicy(); - - // If we get TieredMP and it's maxMergedSegmentMB is 0 - // then this test falsely fails: - if (mp instanceof TieredMergePolicy) { - TieredMergePolicy tmp = (TieredMergePolicy) mp; - tmp.setMaxMergedSegmentMB(Math.max(.01, tmp.getMaxMergedSegmentMB())); - if (tmp.getSegmentsPerTier() > 20) { - tmp.setSegmentsPerTier(20); - } - } + // Don't use newIndexWriterConfig, because we need a + // "sane" mergePolicy: + IndexWriterConfig iwc = new IndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random())); IndexWriter w = new IndexWriter(dir, iwc); // Create 500 segments: for(int i=0;i<500;i++) { From 493ce1b65a82e332f4a48a1c4b72f3419d717a7b Mon Sep 17 00:00:00 2001 From: Erick Erickson Date: Thu, 21 Nov 2013 12:19:45 +0000 Subject: [PATCH 061/223] Adding debug information to diagnose failure, this time so it shows. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1544154 13f79535-47bb-0310-9956-ffa450edef68 --- solr/core/src/test/org/apache/solr/analytics/NoFacetTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/solr/core/src/test/org/apache/solr/analytics/NoFacetTest.java b/solr/core/src/test/org/apache/solr/analytics/NoFacetTest.java index 94703d1b2f6..992edc9c76d 100644 --- a/solr/core/src/test/org/apache/solr/analytics/NoFacetTest.java +++ b/solr/core/src/test/org/apache/solr/analytics/NoFacetTest.java @@ -224,8 +224,6 @@ public class NoFacetTest extends AbstractAnalyticsStatsTest { //Float Double floatResult = (Double)getStatResult(response, "str", "double", "float_fd"); Double floatTest = (Double)calculateNumberStat(floatTestStart, "stddev"); - assertTrue(Math.abs(floatResult-floatTest)<.00000000001); - assertTrue("Oops: (double raws) " + Double.doubleToRawLongBits(floatResult) + " - " + Double.doubleToRawLongBits(floatTest) + " < " + Double.doubleToRawLongBits(.00000000001) + " Calculated diff " + Double.doubleToRawLongBits(floatResult - floatTest), From 8f08d90bb0e1ca9b60a8fad621116838f9244aa8 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Thu, 21 Nov 2013 15:40:07 +0000 Subject: [PATCH 062/223] SOLR-4709: The core reload after replication if config files have changed can fail due to a race condition. SOLR-5489: TestIndexAndConfigAliasReplication commonly fails because it tries to get a lock for a locked index. SOLR-5343: TestReplicationHandler.doTestStressReplication fails ~ 33% of the time git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1544220 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 3 +++ .../org/apache/solr/handler/SnapPuller.java | 20 ++++++++++++++++++- .../solr/handler/TestReplicationHandler.java | 2 +- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 0711db37d18..a6abda46d4f 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -127,6 +127,9 @@ Bug Fixes * SOLR-5481: SolrCmdDistributor should not let the http client do it's own retries. (Mark Miller) +* SOLR-4709: The core reload after replication if config files have changed + can fail due to a race condition. (Mark Miller, Hossman)) + Optimizations ---------------------- diff --git a/solr/core/src/java/org/apache/solr/handler/SnapPuller.java b/solr/core/src/java/org/apache/solr/handler/SnapPuller.java index 343aff62fe5..1417506112f 100644 --- a/solr/core/src/java/org/apache/solr/handler/SnapPuller.java +++ b/solr/core/src/java/org/apache/solr/handler/SnapPuller.java @@ -57,6 +57,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Properties; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -416,6 +417,9 @@ public class SnapPuller { solrCore.getUpdateHandler().getSolrCoreState() .closeIndexWriter(core, true); } + + boolean reloadCore = false; + try { LOG.info("Starting download to " + tmpIndexDir + " fullCopy=" + isFullCopyNeeded); @@ -450,7 +454,7 @@ public class SnapPuller { logReplicationTimeAndConfFiles(modifiedConfFiles, successfulInstall);// write to a file time of replication and // conf files. - reloadCore(); + reloadCore = true; } } else { terminateAndWaitFsyncService(); @@ -470,6 +474,11 @@ public class SnapPuller { solrCore.getUpdateHandler().getSolrCoreState().openIndexWriter(core); } } + + // we must reload the core after we open the IW back up + if (reloadCore) { + reloadCore(); + } if (successfulInstall) { if (isFullCopyNeeded) { @@ -699,6 +708,7 @@ public class SnapPuller { } private void reloadCore() { + final CountDownLatch latch = new CountDownLatch(1); new Thread() { @Override public void run() { @@ -706,9 +716,17 @@ public class SnapPuller { solrCore.getCoreDescriptor().getCoreContainer().reload(solrCore.getName()); } catch (Exception e) { LOG.error("Could not reload core ", e); + } finally { + latch.countDown(); } } }.start(); + try { + latch.await(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new RuntimeException("Interrupted while waiting for core reload to finish", e); + } } private void downloadConfFiles(List> confFilesToDownload, long latestGeneration) throws Exception { diff --git a/solr/core/src/test/org/apache/solr/handler/TestReplicationHandler.java b/solr/core/src/test/org/apache/solr/handler/TestReplicationHandler.java index ee7e218fa4b..a561b655d64 100644 --- a/solr/core/src/test/org/apache/solr/handler/TestReplicationHandler.java +++ b/solr/core/src/test/org/apache/solr/handler/TestReplicationHandler.java @@ -751,7 +751,7 @@ public class TestReplicationHandler extends SolrTestCaseJ4 { } - @Test @Ignore("https://issues.apache.org/jira/browse/SOLR-5343") + @Test public void doTestStressReplication() throws Exception { // change solrconfig on slave // this has no entry for pollinginterval From a5c6c6ddd679969318a572d5d4061f456abad17e Mon Sep 17 00:00:00 2001 From: Simon Willnauer Date: Thu, 21 Nov 2013 15:50:47 +0000 Subject: [PATCH 063/223] Make sure there is at least one document when testing expression dictionary with deletes git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1544224 13f79535-47bb-0310-9956-ffa450edef68 --- .../search/suggest/DocumentExpressionDictionaryTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lucene/suggest/src/test/org/apache/lucene/search/suggest/DocumentExpressionDictionaryTest.java b/lucene/suggest/src/test/org/apache/lucene/search/suggest/DocumentExpressionDictionaryTest.java index 4cc719662a4..448d6b5ff8b 100644 --- a/lucene/suggest/src/test/org/apache/lucene/search/suggest/DocumentExpressionDictionaryTest.java +++ b/lucene/suggest/src/test/org/apache/lucene/search/suggest/DocumentExpressionDictionaryTest.java @@ -151,7 +151,7 @@ public class DocumentExpressionDictionaryTest extends LuceneTestCase { Random rand = random(); List termsToDel = new ArrayList<>(); for(Document doc : docs.values()) { - if(rand.nextBoolean()) { + if(rand.nextBoolean() && termsToDel.size() < docs.size()-1) { termsToDel.add(doc.get(FIELD_NAME)); } writer.addDocument(doc); @@ -174,6 +174,7 @@ public class DocumentExpressionDictionaryTest extends LuceneTestCase { } IndexReader ir = DirectoryReader.open(dir); + assertTrue("NumDocs should be > 0 but was " + ir.numDocs(), ir.numDocs() > 0); assertEquals(ir.numDocs(), docs.size()); Set sortFields = new HashSet(); sortFields.add(new SortField(WEIGHT_FIELD_NAME_1, SortField.Type.LONG)); From 21afda7b2285aad21acf2af89c87bb672830244b Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Thu, 21 Nov 2013 17:28:36 +0000 Subject: [PATCH 064/223] SOLR-5436: Eliminate the 1500ms wait in overseer loop as well as polling the ZK distributed queue. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1544255 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 3 + .../apache/solr/cloud/DistributedQueue.java | 43 +++++++---- .../apache/solr/cloud/ElectionContext.java | 15 ++++ .../org/apache/solr/cloud/LeaderElector.java | 3 + .../java/org/apache/solr/cloud/Overseer.java | 77 +++++++++++-------- .../cloud/OverseerCollectionProcessor.java | 5 +- .../org/apache/solr/cloud/ZkController.java | 55 ++++++++----- .../org/apache/solr/cloud/OverseerTest.java | 22 +++++- .../solr/common/cloud/BeforeReconnect.java | 22 ++++++ .../solr/common/cloud/ConnectionManager.java | 8 +- .../solr/common/cloud/SolrZkClient.java | 15 ++-- 11 files changed, 189 insertions(+), 79 deletions(-) create mode 100644 solr/solrj/src/java/org/apache/solr/common/cloud/BeforeReconnect.java diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index a6abda46d4f..11c754cf15d 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -135,6 +135,9 @@ Optimizations * SOLR-5458: Admin UI - Remove separated Pages for Config & Schema (steffkes) +* SOLR-5436: Eliminate the 1500ms wait in overseer loop as well as + polling the ZK distributed queue. (Noble Paul, Mark Miller) + Other Changes --------------------- diff --git a/solr/core/src/java/org/apache/solr/cloud/DistributedQueue.java b/solr/core/src/java/org/apache/solr/cloud/DistributedQueue.java index bbb42dff636..2e6d2ef3dcf 100644 --- a/solr/core/src/java/org/apache/solr/cloud/DistributedQueue.java +++ b/solr/core/src/java/org/apache/solr/cloud/DistributedQueue.java @@ -115,7 +115,7 @@ public class DistributedQueue { * * @return the data at the head of the queue. */ - private QueueEvent element() throws NoSuchElementException, KeeperException, + private QueueEvent element() throws KeeperException, InterruptedException { TreeMap orderedChildren; @@ -130,9 +130,9 @@ public class DistributedQueue { try { orderedChildren = orderedChildren(null); } catch (KeeperException.NoNodeException e) { - throw new NoSuchElementException(); + return null; } - if (orderedChildren.size() == 0) throw new NoSuchElementException(); + if (orderedChildren.size() == 0) return null; for (String headNode : orderedChildren.values()) { if (headNode != null) { @@ -208,7 +208,7 @@ public class DistributedQueue { @Override public void process(WatchedEvent event) { - LOG.info("Watcher fired on path: " + event.getPath() + " state: " + LOG.info("LatchChildWatcher fired on path: " + event.getPath() + " state: " + event.getState() + " type " + event.getType()); synchronized (lock) { this.event = event; @@ -322,11 +322,9 @@ public class DistributedQueue { * @return data at the first element of the queue, or null. */ public byte[] peek() throws KeeperException, InterruptedException { - try { - return element().getBytes(); - } catch (NoSuchElementException e) { - return null; - } + QueueEvent element = element(); + if(element == null) return null; + return element.getBytes(); } public static class QueueEvent { @@ -384,16 +382,29 @@ public class DistributedQueue { /** * Returns the data at the first element of the queue, or null if the queue is - * empty. + * empty and block is false. * + * @param block if true, blocks until an element enters the queue * @return data at the first element of the queue, or null. */ public QueueEvent peek(boolean block) throws KeeperException, InterruptedException { - if (!block) { + return peek(block ? Long.MAX_VALUE : 0); + } + + /** + * Returns the data at the first element of the queue, or null if the queue is + * empty after wait ms. + * + * @param wait max wait time in ms. + * @return data at the first element of the queue, or null. + */ + public QueueEvent peek(long wait) throws KeeperException, InterruptedException { + if (wait == 0) { return element(); } - + TreeMap orderedChildren; + boolean waitedEnough = false; while (true) { LatchChildWatcher childWatcher = new LatchChildWatcher(); try { @@ -402,11 +413,15 @@ public class DistributedQueue { zookeeper.create(dir, new byte[0], acl, CreateMode.PERSISTENT, true); continue; } + if(waitedEnough) { + if(orderedChildren.isEmpty()) return null; + } if (orderedChildren.size() == 0) { - childWatcher.await(DEFAULT_TIMEOUT); + childWatcher.await(wait == Long.MAX_VALUE ? DEFAULT_TIMEOUT: wait); + waitedEnough = wait != Long.MAX_VALUE; continue; } - + for (String headNode : orderedChildren.values()) { String path = dir + "/" + headNode; try { diff --git a/solr/core/src/java/org/apache/solr/cloud/ElectionContext.java b/solr/core/src/java/org/apache/solr/cloud/ElectionContext.java index ca5634044d5..ecc393640cb 100644 --- a/solr/core/src/java/org/apache/solr/cloud/ElectionContext.java +++ b/solr/core/src/java/org/apache/solr/cloud/ElectionContext.java @@ -71,6 +71,10 @@ public abstract class ElectionContext { } abstract void runLeaderProcess(boolean weAreReplacement) throws KeeperException, InterruptedException, IOException; + + public void checkIfIamLeaderFired() {} + + public void joinedElectionFired() {} } class ShardLeaderElectionContextBase extends ElectionContext { @@ -438,4 +442,15 @@ final class OverseerElectionContext extends ElectionContext { overseer.start(id); } + @Override + public void joinedElectionFired() { + overseer.close(); + } + + @Override + public void checkIfIamLeaderFired() { + // leader changed - close the overseer + overseer.close(); + } + } diff --git a/solr/core/src/java/org/apache/solr/cloud/LeaderElector.java b/solr/core/src/java/org/apache/solr/cloud/LeaderElector.java index 9335097bfd7..0a8bdccf236 100644 --- a/solr/core/src/java/org/apache/solr/cloud/LeaderElector.java +++ b/solr/core/src/java/org/apache/solr/cloud/LeaderElector.java @@ -87,6 +87,7 @@ public class LeaderElector { */ private void checkIfIamLeader(final int seq, final ElectionContext context, boolean replacement) throws KeeperException, InterruptedException, IOException { + context.checkIfIamLeaderFired(); // get all other numbers... final String holdElectionPath = context.electionPath + ELECTION_NODE; List seqs = zkClient.getChildren(holdElectionPath, null, true); @@ -216,6 +217,8 @@ public class LeaderElector { * @return sequential node number */ public int joinElection(ElectionContext context, boolean replacement) throws KeeperException, InterruptedException, IOException { + context.joinedElectionFired(); + final String shardsElectZkPath = context.electionPath + LeaderElector.ELECTION_NODE; long sessionId = zkClient.getSolrZooKeeper().getSessionId(); diff --git a/solr/core/src/java/org/apache/solr/cloud/Overseer.java b/solr/core/src/java/org/apache/solr/cloud/Overseer.java index df2630193b4..eca5032d611 100644 --- a/solr/core/src/java/org/apache/solr/cloud/Overseer.java +++ b/solr/core/src/java/org/apache/solr/cloud/Overseer.java @@ -63,6 +63,8 @@ public class Overseer { static enum LeaderStatus { DONT_KNOW, NO, YES }; + private long lastUpdatedTime = 0; + private class ClusterStateUpdater implements Runnable, ClosableThread { private final ZkStateReader reader; @@ -151,33 +153,51 @@ public class Overseer { break; } else if (LeaderStatus.YES != isLeader) { - log.debug("am_i_leader unclear {}", isLeader); + log.debug("am_i_leader unclear {}", isLeader); continue; // not a no, not a yes, try ask again } + DistributedQueue.QueueEvent head = null; + try { + head = stateUpdateQueue.peek(true); + } catch (KeeperException e) { + if (e.code() == KeeperException.Code.SESSIONEXPIRED) { + log.warn( + "Solr cannot talk to ZK, exiting Overseer main queue loop", e); + return; + } + log.error("Exception in Overseer main queue loop", e); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + return; + + } catch (Exception e) { + log.error("Exception in Overseer main queue loop", e); + } synchronized (reader.getUpdateLock()) { try { - byte[] head = stateUpdateQueue.peek(); - - if (head != null) { - reader.updateClusterState(true); - ClusterState clusterState = reader.getClusterState(); + reader.updateClusterState(true); + ClusterState clusterState = reader.getClusterState(); + + while (head != null) { + final ZkNodeProps message = ZkNodeProps.load(head.getBytes()); + final String operation = message.getStr(QUEUE_OPERATION); + + clusterState = processMessage(clusterState, message, operation); + workQueue.offer(head.getBytes()); + + stateUpdateQueue.poll(); + + if (System.currentTimeMillis() - lastUpdatedTime > STATE_UPDATE_DELAY) break; - while (head != null) { - final ZkNodeProps message = ZkNodeProps.load(head); - final String operation = message.getStr(QUEUE_OPERATION); - - clusterState = processMessage(clusterState, message, operation); - workQueue.offer(head); - - stateUpdateQueue.poll(); - head = stateUpdateQueue.peek(); - } - zkClient.setData(ZkStateReader.CLUSTER_STATE, - ZkStateReader.toJSON(clusterState), true); + // if an event comes in the next 100ms batch it together + head = stateUpdateQueue.peek(100); } + lastUpdatedTime = System.currentTimeMillis(); + zkClient.setData(ZkStateReader.CLUSTER_STATE, + ZkStateReader.toJSON(clusterState), true); // clean work queue - while (workQueue.poll() != null); - + while (workQueue.poll() != null) ; + } catch (KeeperException e) { if (e.code() == KeeperException.Code.SESSIONEXPIRED) { log.warn("Solr cannot talk to ZK, exiting Overseer main queue loop", e); @@ -193,11 +213,6 @@ public class Overseer { } } - try { - Thread.sleep(STATE_UPDATE_DELAY); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } } } @@ -939,8 +954,6 @@ public class Overseer { private volatile OverseerThread updaterThread; - private volatile boolean isClosed; - private ZkStateReader reader; private ShardHandler shardHandler; @@ -954,6 +967,7 @@ public class Overseer { } public void start(String id) { + close(); log.info("Overseer (id=" + id + ") starting"); createOverseerNode(reader.getZkClient()); //launch cluster state updater thread @@ -975,7 +989,6 @@ public class Overseer { } public void close() { - isClosed = true; if (updaterThread != null) { try { updaterThread.close(); @@ -992,12 +1005,8 @@ public class Overseer { log.error("Error closing ccThread", t); } } - - try { - reader.close(); - } catch (Throwable t) { - log.error("Error closing zkStateReader", t); - } + updaterThread = null; + ccThread = null; } /** diff --git a/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java b/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java index c0047628ed4..c149a94a433 100644 --- a/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java +++ b/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java @@ -292,9 +292,8 @@ public class OverseerCollectionProcessor implements Runnable, ClosableThread { deleteCoreNode(collectionName, replicaName, replica, core); if(waitForCoreNodeGone(collectionName, shard, replicaName)) return; } else { - Map m = ZkNodeProps.makeMap("qt", adminPath, - CoreAdminParams.ACTION, CoreAdminAction.UNLOAD.toString(), - CoreAdminParams.CORE, core) ; + Map m = ZkNodeProps.makeMap("qt", adminPath, CoreAdminParams.ACTION, + CoreAdminAction.UNLOAD.toString(), CoreAdminParams.CORE, core); ShardRequest sreq = new ShardRequest(); sreq.purpose = 1; diff --git a/solr/core/src/java/org/apache/solr/cloud/ZkController.java b/solr/core/src/java/org/apache/solr/cloud/ZkController.java index 2b016a39edf..8b3d99cf594 100644 --- a/solr/core/src/java/org/apache/solr/cloud/ZkController.java +++ b/solr/core/src/java/org/apache/solr/cloud/ZkController.java @@ -23,10 +23,10 @@ import org.apache.solr.client.solrj.impl.HttpSolrServer; import org.apache.solr.client.solrj.request.CoreAdminRequest.WaitForState; import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrException.ErrorCode; +import org.apache.solr.common.cloud.BeforeReconnect; import org.apache.solr.common.cloud.ClusterState; +import org.apache.solr.common.cloud.DefaultConnectionStrategy; import org.apache.solr.common.cloud.DocCollection; -import org.apache.solr.common.cloud.DocRouter; -import org.apache.solr.common.cloud.ImplicitDocRouter; import org.apache.solr.common.cloud.OnReconnect; import org.apache.solr.common.cloud.Replica; import org.apache.solr.common.cloud.Slice; @@ -203,46 +203,53 @@ public final class ZkController { this.leaderVoteWait = leaderVoteWait; this.clientTimeout = zkClientTimeout; - zkClient = new SolrZkClient(zkServerAddress, zkClientTimeout, zkClientConnectTimeout, + zkClient = new SolrZkClient(zkServerAddress, zkClientTimeout, + zkClientConnectTimeout, new DefaultConnectionStrategy(), // on reconnect, reload cloud info new OnReconnect() { - + @Override public void command() { try { markAllAsNotLeader(registerOnReconnect); - // this is troublesome - we dont want to kill anything the old leader accepted - // though I guess sync will likely get those updates back? But only if + // this is troublesome - we dont want to kill anything the old + // leader accepted + // though I guess sync will likely get those updates back? But + // only if // he is involved in the sync, and he certainly may not be - // ExecutorUtil.shutdownAndAwaitTermination(cc.getCmdDistribExecutor()); + // ExecutorUtil.shutdownAndAwaitTermination(cc.getCmdDistribExecutor()); // we need to create all of our lost watches // seems we dont need to do this again... - //Overseer.createClientNodes(zkClient, getNodeName()); + // Overseer.createClientNodes(zkClient, getNodeName()); ShardHandler shardHandler; String adminPath; shardHandler = cc.getShardHandlerFactory().getShardHandler(); adminPath = cc.getAdminPath(); - + cc.cancelCoreRecoveries(); registerAllCoresAsDown(registerOnReconnect, false); - - ZkController.this.overseer = new Overseer(shardHandler, adminPath, zkStateReader); - ElectionContext context = new OverseerElectionContext(zkClient, overseer, getNodeName()); + + ElectionContext context = new OverseerElectionContext(zkClient, + overseer, getNodeName()); + overseerElector.joinElection(context, true); zkStateReader.createClusterStateWatchersAndUpdate(); // we have to register as live first to pick up docs in the buffer createEphemeralLiveNode(); - List descriptors = registerOnReconnect.getCurrentDescriptors(); + List descriptors = registerOnReconnect + .getCurrentDescriptors(); // re register all descriptors - if (descriptors != null) { + if (descriptors != null) { for (CoreDescriptor descriptor : descriptors) { - // TODO: we need to think carefully about what happens when it was - // a leader that was expired - as well as what to do about leaders/overseers + // TODO: we need to think carefully about what happens when it + // was + // a leader that was expired - as well as what to do about + // leaders/overseers // with connection loss try { register(descriptor.getName(), descriptor, true, true); @@ -251,7 +258,7 @@ public final class ZkController { } } } - + } catch (InterruptedException e) { // Restore the interrupted status Thread.currentThread().interrupt(); @@ -262,10 +269,18 @@ public final class ZkController { throw new ZooKeeperException( SolrException.ErrorCode.SERVER_ERROR, "", e); } - } - - + + }, new BeforeReconnect() { + + @Override + public void command() { + try { + ZkController.this.overseer.close(); + } catch (Exception e) { + log.error("Error trying to stop any Overseer threads", e); + } + } }); this.overseerJobQueue = Overseer.getInQueue(zkClient); diff --git a/solr/core/src/test/org/apache/solr/cloud/OverseerTest.java b/solr/core/src/test/org/apache/solr/cloud/OverseerTest.java index e722f524ed4..d0569eb82fd 100644 --- a/solr/core/src/test/org/apache/solr/cloud/OverseerTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/OverseerTest.java @@ -19,9 +19,11 @@ package org.apache.solr.cloud; import java.io.File; import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ExecutorService; @@ -47,6 +49,7 @@ import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.KeeperException.NodeExistsException; import org.apache.zookeeper.data.Stat; +import org.junit.After; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; @@ -57,7 +60,9 @@ public class OverseerTest extends SolrTestCaseJ4 { static final int TIMEOUT = 10000; private static final boolean DEBUG = false; - + + private List overseers = new ArrayList(); + private List readers = new ArrayList(); public static class MockZKController{ @@ -182,6 +187,19 @@ public class OverseerTest extends SolrTestCaseJ4 { initCore(); Thread.sleep(3000); //XXX wait for threads to die... } + + @After + public void tearDown() throws Exception { + super.tearDown(); + for (Overseer overseer : overseers) { + overseer.close(); + } + overseers.clear(); + for (ZkStateReader reader : readers) { + reader.close(); + } + readers.clear(); + } @Test public void testShardAssignment() throws Exception { @@ -884,10 +902,12 @@ public class OverseerTest extends SolrTestCaseJ4 { KeeperException, ParserConfigurationException, SAXException { SolrZkClient zkClient = new SolrZkClient(address, TIMEOUT); ZkStateReader reader = new ZkStateReader(zkClient); + readers.add(reader); LeaderElector overseerElector = new LeaderElector(zkClient); // TODO: close Overseer Overseer overseer = new Overseer( new HttpShardHandlerFactory().getShardHandler(), "/admin/cores", reader); + overseers.add(overseer); ElectionContext ec = new OverseerElectionContext(zkClient, overseer, address.replaceAll("/", "_")); overseerElector.setup(ec); overseerElector.joinElection(ec, false); diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/BeforeReconnect.java b/solr/solrj/src/java/org/apache/solr/common/cloud/BeforeReconnect.java new file mode 100644 index 00000000000..44379a4b3c2 --- /dev/null +++ b/solr/solrj/src/java/org/apache/solr/common/cloud/BeforeReconnect.java @@ -0,0 +1,22 @@ +package org.apache.solr.common.cloud; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with this + * work for additional information regarding copyright ownership. The ASF + * licenses this file to You under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +public interface BeforeReconnect { + public void command(); +} diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/ConnectionManager.java b/solr/solrj/src/java/org/apache/solr/common/cloud/ConnectionManager.java index 4ede215e46c..b61dec98a11 100644 --- a/solr/solrj/src/java/org/apache/solr/common/cloud/ConnectionManager.java +++ b/solr/solrj/src/java/org/apache/solr/common/cloud/ConnectionManager.java @@ -45,16 +45,18 @@ class ConnectionManager implements Watcher { private final SolrZkClient client; private final OnReconnect onReconnect; + private final BeforeReconnect beforeReconnect; private volatile boolean isClosed = false; - public ConnectionManager(String name, SolrZkClient client, String zkServerAddress, int zkClientTimeout, ZkClientConnectionStrategy strat, OnReconnect onConnect) { + public ConnectionManager(String name, SolrZkClient client, String zkServerAddress, int zkClientTimeout, ZkClientConnectionStrategy strat, OnReconnect onConnect, BeforeReconnect beforeReconnect) { this.name = name; this.client = client; this.connectionStrategy = strat; this.zkServerAddress = zkServerAddress; this.zkClientTimeout = zkClientTimeout; this.onReconnect = onConnect; + this.beforeReconnect = beforeReconnect; reset(); } @@ -84,7 +86,9 @@ class ConnectionManager implements Watcher { } else if (state == KeeperState.Expired) { connected = false; log.info("Our previous ZooKeeper session was expired. Attempting to reconnect to recover relationship with ZooKeeper..."); - + if (beforeReconnect != null) { + beforeReconnect.command(); + } try { connectionStrategy.reconnect(zkServerAddress, zkClientTimeout, this, new ZkClientConnectionStrategy.ZkUpdate() { diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/SolrZkClient.java b/solr/solrj/src/java/org/apache/solr/common/cloud/SolrZkClient.java index e1e8b6b0ab4..f9a1890e4ef 100644 --- a/solr/solrj/src/java/org/apache/solr/common/cloud/SolrZkClient.java +++ b/solr/solrj/src/java/org/apache/solr/common/cloud/SolrZkClient.java @@ -85,22 +85,27 @@ public class SolrZkClient { } public SolrZkClient(String zkServerAddress, int zkClientTimeout, int zkClientConnectTimeout, OnReconnect onReonnect) { - this(zkServerAddress, zkClientTimeout, new DefaultConnectionStrategy(), onReonnect, zkClientConnectTimeout); + this(zkServerAddress, zkClientTimeout, zkClientConnectTimeout, new DefaultConnectionStrategy(), onReonnect); } public SolrZkClient(String zkServerAddress, int zkClientTimeout, ZkClientConnectionStrategy strat, final OnReconnect onReconnect) { - this(zkServerAddress, zkClientTimeout, strat, onReconnect, DEFAULT_CLIENT_CONNECT_TIMEOUT); + this(zkServerAddress, zkClientTimeout, DEFAULT_CLIENT_CONNECT_TIMEOUT, strat, onReconnect); + } + + public SolrZkClient(String zkServerAddress, int zkClientTimeout, int clientConnectTimeout, + ZkClientConnectionStrategy strat, final OnReconnect onReconnect) { + this(zkServerAddress, zkClientTimeout, clientConnectTimeout, strat, onReconnect, null); } - public SolrZkClient(String zkServerAddress, int zkClientTimeout, - ZkClientConnectionStrategy strat, final OnReconnect onReconnect, int clientConnectTimeout) { + public SolrZkClient(String zkServerAddress, int zkClientTimeout, int clientConnectTimeout, + ZkClientConnectionStrategy strat, final OnReconnect onReconnect, BeforeReconnect beforeReconnect) { this.zkClientConnectionStrategy = strat; this.zkClientTimeout = zkClientTimeout; // we must retry at least as long as the session timeout zkCmdExecutor = new ZkCmdExecutor(zkClientTimeout); connManager = new ConnectionManager("ZooKeeperConnection Watcher:" - + zkServerAddress, this, zkServerAddress, zkClientTimeout, strat, onReconnect); + + zkServerAddress, this, zkServerAddress, zkClientTimeout, strat, onReconnect, beforeReconnect); try { strat.connect(zkServerAddress, zkClientTimeout, connManager, new ZkUpdate() { From 0971bc8f219b7e558efe659f0af77c163d96a019 Mon Sep 17 00:00:00 2001 From: Uwe Schindler Date: Thu, 21 Nov 2013 23:27:19 +0000 Subject: [PATCH 065/223] LUCENE-5347: Upgrade forbidden-apis checker to version 1.4. Fix Zookeeper bug with default encoding. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1544370 13f79535-47bb-0310-9956-ffa450edef68 --- dev-tools/maven/pom.xml.template | 2 +- lucene/CHANGES.txt | 3 +++ lucene/common-build.xml | 2 +- solr/CHANGES.txt | 5 +++++ .../apache/solr/handler/admin/ShowFileRequestHandler.java | 4 ++-- .../test/org/apache/solr/AnalysisAfterCoreReloadTest.java | 2 +- solr/core/src/test/org/apache/solr/core/TestLazyCores.java | 2 +- .../test/org/apache/solr/handler/PingRequestHandlerTest.java | 2 +- .../src/test/org/apache/solr/schema/ModifyConfFileTest.java | 4 ++-- .../src/java/org/apache/solr/common/cloud/SolrZkClient.java | 4 ++-- 10 files changed, 19 insertions(+), 11 deletions(-) diff --git a/dev-tools/maven/pom.xml.template b/dev-tools/maven/pom.xml.template index 81131dd817f..5539f18857e 100644 --- a/dev-tools/maven/pom.xml.template +++ b/dev-tools/maven/pom.xml.template @@ -159,7 +159,7 @@ de.thetaphi forbiddenapis - 1.3 + 1.4 - + @@ -295,6 +297,7 @@ + diff --git a/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java b/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java index 0e8e6d6faf8..fe86a0b6e8d 100644 --- a/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java +++ b/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java @@ -79,7 +79,7 @@ public class SolrResourceLoader implements ResourceLoader,Closeable static final String project = "solr"; static final String base = "org.apache" + "." + project; - static final String[] packages = {"","analysis.","schema.","handler.","search.","update.","core.","response.","request.","update.processor.","util.", "spelling.", "handler.component.", "handler.dataimport." }; + static final String[] packages = {"","analysis.","schema.","handler.","search.","update.","core.","response.","request.","update.processor.","util.", "spelling.", "handler.component.", "handler.dataimport.", "spelling.suggest.", "spelling.suggest.fst." }; protected URLClassLoader classLoader; private final String instanceDir; diff --git a/solr/core/src/java/org/apache/solr/handler/component/SuggestComponent.java b/solr/core/src/java/org/apache/solr/handler/component/SuggestComponent.java new file mode 100644 index 00000000000..c272c2af7e8 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/handler/component/SuggestComponent.java @@ -0,0 +1,442 @@ +package org.apache.solr.handler.component; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.lucene.search.suggest.Lookup; +import org.apache.lucene.search.suggest.Lookup.LookupResult; +import org.apache.lucene.util.BytesRef; +import org.apache.lucene.util.CharsRef; +import org.apache.solr.common.params.CommonParams; +import org.apache.solr.common.params.ModifiableSolrParams; +import org.apache.solr.common.params.ShardParams; +import org.apache.solr.common.params.SolrParams; +import org.apache.solr.common.util.NamedList; +import org.apache.solr.common.util.SimpleOrderedMap; +import org.apache.solr.core.SolrCore; +import org.apache.solr.core.SolrEventListener; +import org.apache.solr.search.SolrIndexSearcher; +import org.apache.solr.spelling.suggest.SolrSuggester; +import org.apache.solr.spelling.suggest.SuggesterOptions; +import org.apache.solr.spelling.suggest.SuggesterParams; +import org.apache.solr.spelling.suggest.SuggesterResult; +import org.apache.solr.util.plugin.SolrCoreAware; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * SuggestComponent: interacts with multiple {@link SolrSuggester} to serve up suggestions + * Responsible for routing commands and queries to the appropriate {@link SolrSuggester} + * and for initializing them as specified by SolrConfig + */ +public class SuggestComponent extends SearchComponent implements SolrCoreAware, SuggesterParams { + private static final Logger LOG = LoggerFactory.getLogger(SuggestComponent.class); + + /** Name used to identify whether the user query concerns this component */ + public static final String COMPONENT_NAME = "suggest"; + + /** Name assigned to an unnamed suggester (at most one suggester) can be unnamed */ + private static final String DEFAULT_DICT_NAME = SolrSuggester.DEFAULT_DICT_NAME; + + /** SolrConfig label to identify Config time settings */ + private static final String CONFIG_PARAM_LABEL = "suggester"; + + /** SolrConfig label to identify boolean value to build suggesters on commit */ + private static final String BUILD_ON_COMMIT_LABEL = "buildOnCommit"; + + /** SolrConfig label to identify boolean value to build suggesters on optimize */ + private static final String BUILD_ON_OPTIMIZE_LABEL = "buildOnOptimize"; + + @SuppressWarnings("unchecked") + protected NamedList initParams; + + /** + * Key is the dictionary name used in SolrConfig, value is the corrosponding {@link SolrSuggester} + */ + protected Map suggesters = new ConcurrentHashMap(); + + /** Container for various labels used in the responses generated by this component */ + private static class SuggesterResultLabels { + static final String SUGGEST = "suggest"; + static final String SUGGESTIONS = "suggestions"; + static final String SUGGESTION = "suggestion"; + static final String SUGGESTION_NUM_FOUND = "numFound"; + static final String SUGGESTION_TERM = "term"; + static final String SUGGESTION_WEIGHT = "weight"; + static final String SUGGESTION_PAYLOAD = "payload"; + } + + @Override + @SuppressWarnings("unchecked") + public void init(NamedList args) { + super.init(args); + this.initParams = args; + } + + @Override + public void inform(SolrCore core) { + if (initParams != null) { + LOG.info("Initializing SuggesterComponent"); + boolean hasDefault = false; + for (int i = 0; i < initParams.size(); i++) { + if (initParams.getName(i).equals(CONFIG_PARAM_LABEL)) { + NamedList suggesterParams = (NamedList) initParams.getVal(i); + SolrSuggester suggester = new SolrSuggester(); + String dictionary = suggester.init(suggesterParams, core); + if (dictionary != null) { + boolean isDefault = dictionary.equals(DEFAULT_DICT_NAME); + if (isDefault && !hasDefault) { + hasDefault = true; + } else if (isDefault){ + throw new RuntimeException("More than one dictionary is missing name."); + } + suggesters.put(dictionary, suggester); + } else { + if (!hasDefault){ + suggesters.put(DEFAULT_DICT_NAME, suggester); + hasDefault = true; + } else { + throw new RuntimeException("More than one dictionary is missing name."); + } + } + + // Register event listeners for this Suggester + core.registerFirstSearcherListener(new SuggesterListener(core, suggester, false, false)); + boolean buildOnCommit = Boolean.parseBoolean((String) suggesterParams.get(BUILD_ON_COMMIT_LABEL)); + boolean buildOnOptimize = Boolean.parseBoolean((String) suggesterParams.get(BUILD_ON_OPTIMIZE_LABEL)); + if (buildOnCommit || buildOnOptimize) { + LOG.info("Registering newSearcher listener for suggester: " + suggester.getName()); + core.registerNewSearcherListener(new SuggesterListener(core, suggester, buildOnCommit, buildOnOptimize)); + } + } + } + } + } + + /** Responsible for issuing build and rebload command to the specified {@link SolrSuggester} */ + @Override + public void prepare(ResponseBuilder rb) throws IOException { + SolrParams params = rb.req.getParams(); + LOG.info("Suggester prepare with : " + params); + if (!params.getBool(COMPONENT_NAME, false)) { + return; + } + + SolrSuggester suggester = getSuggester(params); + if (suggester == null) { + throw new IllegalArgumentException("Error in configuration, no suggester found"); + } + if (params.getBool(SUGGEST_BUILD, false)) { + suggester.build(rb.req.getCore(), rb.req.getSearcher()); + rb.rsp.add("command", "build"); + } else if (params.getBool(SUGGEST_RELOAD, false)) { + suggester.reload(rb.req.getCore(), rb.req.getSearcher()); + rb.rsp.add("command", "reload"); + } + } + + /** Dispatch shard request in STAGE_EXECUTE_QUERY stage */ + @Override + public int distributedProcess(ResponseBuilder rb) { + SolrParams params = rb.req.getParams(); + LOG.info("Suggester distributedProcess with : " + params); + if (rb.stage < ResponseBuilder.STAGE_EXECUTE_QUERY) + return ResponseBuilder.STAGE_EXECUTE_QUERY; + if (rb.stage == ResponseBuilder.STAGE_EXECUTE_QUERY) { + ShardRequest sreq = new ShardRequest(); + sreq.purpose = ShardRequest.PURPOSE_GET_TOP_IDS; + sreq.params = new ModifiableSolrParams(rb.req.getParams()); + sreq.params.remove(ShardParams.SHARDS); + rb.addRequest(this, sreq); + return ResponseBuilder.STAGE_GET_FIELDS; + } + + return ResponseBuilder.STAGE_DONE; + } + + /** + * Responsible for using the specified suggester to get the suggestions + * for the query and write the results + * */ + @Override + public void process(ResponseBuilder rb) throws IOException { + SolrParams params = rb.req.getParams(); + LOG.info("Suggester process with : " + params); + if (!params.getBool(COMPONENT_NAME, false) || suggesters.isEmpty()) { + return; + } + + SolrSuggester suggester = getSuggester(params); + String query = params.get(SUGGEST_Q); + if (query == null) { + query = rb.getQueryString(); + if (query == null) { + query = params.get(CommonParams.Q); + } + } + + if (query != null) { + int count = params.getInt(SUGGEST_COUNT, 1); + SuggesterOptions options = new SuggesterOptions(new CharsRef(query), count); + SuggesterResult suggesterResult = suggester.getSuggestions(options); + + NamedList response = new SimpleOrderedMap(); + NamedList namedListResult = toNamedList(suggesterResult); + response.add(SuggesterResultLabels.SUGGESTIONS, namedListResult); + rb.rsp.add(SuggesterResultLabels.SUGGEST, response); + } + } + + /** + * Used in Distributed Search, merges the suggestion results from every shard + * */ + @Override + public void finishStage(ResponseBuilder rb) { + SolrParams params = rb.req.getParams(); + LOG.info("Suggester finishStage with : " + params); + if (!params.getBool(COMPONENT_NAME, false) || rb.stage != ResponseBuilder.STAGE_GET_FIELDS) + return; + int count = params.getInt(SUGGEST_COUNT, 1); + + List suggesterResults = new ArrayList<>(); + NamedList response = new SimpleOrderedMap(); + NamedList namedListResult = null; + + // Collect Shard responses + for (ShardRequest sreq : rb.finished) { + for (ShardResponse srsp : sreq.responses) { + NamedList namedList = + (NamedList) srsp.getSolrResponse().getResponse().get(SuggesterResultLabels.SUGGEST); + LOG.info(srsp.getShard() + " : " + namedList); + suggesterResults.add(toSuggesterResult(namedList)); + } + } + + // Merge Shard responses + SuggesterResult suggesterResult = merge(suggesterResults, count); + namedListResult = toNamedList(suggesterResult); + + response.add(SuggesterResultLabels.SUGGESTIONS, namedListResult); + rb.rsp.add(SuggesterResultLabels.SUGGEST, response); + }; + + /** + * Given a list of {@link SuggesterResult} and count + * returns a {@link SuggesterResult} containing count + * number of {@link LookupResult}, sorted by their associated + * weights + * */ + private static SuggesterResult merge(List suggesterResults, int count) { + SuggesterResult result = new SuggesterResult(); + Set allTokens = new HashSet<>(); + + // collect all tokens + for (SuggesterResult shardResult : suggesterResults) { + allTokens.addAll(shardResult.getTokens()); + } + + // Get Top N for every token in every shard (using weights) + for (String token : allTokens) { + Lookup.LookupPriorityQueue resultQueue = new Lookup.LookupPriorityQueue( + count); + for (SuggesterResult shardResult : suggesterResults) { + List suggests = shardResult.getLookupResult(token); + if (suggests == null) { + continue; + } + for (LookupResult res : suggests) { + resultQueue.insertWithOverflow(res); + } + } + List sortedSuggests = new LinkedList<>(); + Collections.addAll(sortedSuggests, resultQueue.getResults()); + result.add(token, sortedSuggests); + } + return result; + } + + @Override + public String getDescription() { + return "Suggester component"; + } + + @Override + public String getSource() { + return "$URL$"; + } + + @Override + public NamedList getStatistics() { + NamedList stats = new SimpleOrderedMap(); + stats.add("totalSizeInBytes", String.valueOf(sizeInBytes())); + for (Map.Entry entry : suggesters.entrySet()) { + SolrSuggester suggester = entry.getValue(); + stats.add(entry.getKey(), suggester.toString()); + } + return stats; + } + + private long sizeInBytes() { + long sizeInBytes = 0; + for (SolrSuggester suggester : suggesters.values()) { + sizeInBytes += suggester.sizeInBytes(); + } + return sizeInBytes; + } + + private SolrSuggester getSuggester(SolrParams params) { + return suggesters.get(getSuggesterName(params)); + + } + + private String getSuggesterName(SolrParams params){ + return (params.get(SUGGEST_DICT) != null) ? + (String)params.get(SUGGEST_DICT) + : DEFAULT_DICT_NAME; + + } + + /** Convert {@link SuggesterResult} to NamedList for constructing responses */ + private NamedList toNamedList(SuggesterResult suggesterResult) { + NamedList results = new NamedList(); + for (String token : suggesterResult.getTokens()) { + SimpleOrderedMap suggestionBody = new SimpleOrderedMap(); + List lookupResults = suggesterResult.getLookupResult(token); + suggestionBody.add(SuggesterResultLabels.SUGGESTION_NUM_FOUND, lookupResults.size()); + + for (LookupResult lookupResult : lookupResults) { + String suggestionString = lookupResult.key.toString(); + long weight = lookupResult.value; + String payload = (lookupResult.payload != null) ? + lookupResult.payload.utf8ToString() + : ""; + + SimpleOrderedMap suggestEntryNamedList = new SimpleOrderedMap(); + suggestEntryNamedList.add(SuggesterResultLabels.SUGGESTION_TERM, suggestionString); + suggestEntryNamedList.add(SuggesterResultLabels.SUGGESTION_WEIGHT, weight); + suggestEntryNamedList.add(SuggesterResultLabels.SUGGESTION_PAYLOAD, payload); + + suggestionBody.add(SuggesterResultLabels.SUGGESTION, suggestEntryNamedList); + } + results.add(token, suggestionBody); + } + return results; + } + + /** Convert NamedList (suggester response) to {@link SuggesterResult} */ + private SuggesterResult toSuggesterResult(NamedList suggesterRespNamedList) { + SuggesterResult result = new SuggesterResult(); + if (suggesterRespNamedList == null) { + return result; + } + NamedList suggestions = (NamedList) suggesterRespNamedList.get(SuggesterResultLabels.SUGGESTIONS); + if (suggestions != null) { + // for each token + for(int i = 0; i < suggestions.size() ; i++) { + String tokenString = suggestions.getName(i); + List lookupResults = new ArrayList<>(); + NamedList suggestion = (NamedList) suggestions.getVal(i); + // for each suggestion + for (int j = 0; j < suggestion.size(); j++) { + String property = suggestion.getName(j); + if (property.equals(SuggesterResultLabels.SUGGESTION)) { + NamedList suggestionEntry = (NamedList) suggestion.getVal(j); + String term = (String) suggestionEntry.get(SuggesterResultLabels.SUGGESTION_TERM); + long weight = (long) suggestionEntry.get(SuggesterResultLabels.SUGGESTION_WEIGHT); + String payload = (String) suggestionEntry.get(SuggesterResultLabels.SUGGESTION_PAYLOAD); + LookupResult res = new LookupResult(new CharsRef(term), weight, new BytesRef(payload)); + lookupResults.add(res); + } + result.add(tokenString, lookupResults); + } + } + } + return result; + } + + /** Listener to build or reload the maintained {@link SolrSuggester} by this component */ + private static class SuggesterListener implements SolrEventListener { + private final SolrCore core; + private final SolrSuggester suggester; + private final boolean buildOnCommit; + private final boolean buildOnOptimize; + + public SuggesterListener(SolrCore core, SolrSuggester checker, boolean buildOnCommit, boolean buildOnOptimize) { + this.core = core; + this.suggester = checker; + this.buildOnCommit = buildOnCommit; + this.buildOnOptimize = buildOnOptimize; + } + + @Override + public void init(NamedList args) { + } + + @Override + public void newSearcher(SolrIndexSearcher newSearcher, + SolrIndexSearcher currentSearcher) { + if (currentSearcher == null) { + // firstSearcher event + try { + LOG.info("Loading suggester index for: " + suggester.getName()); + suggester.reload(core, newSearcher); + } catch (IOException e) { + log.error("Exception in reloading suggester index for: " + suggester.getName(), e); + } + } else { + // newSearcher event + if (buildOnCommit) { + buildSuggesterIndex(newSearcher); + } else if (buildOnOptimize) { + if (newSearcher.getIndexReader().leaves().size() == 1) { + buildSuggesterIndex(newSearcher); + } else { + LOG.info("Index is not optimized therefore skipping building suggester index for: " + + suggester.getName()); + } + } + } + + } + + private void buildSuggesterIndex(SolrIndexSearcher newSearcher) { + try { + LOG.info("Building suggester index for: " + suggester.getName()); + suggester.build(core, newSearcher); + } catch (Exception e) { + log.error("Exception in building suggester index for: " + suggester.getName(), e); + } + } + + @Override + public void postCommit() {} + + @Override + public void postSoftCommit() {} + + } +} diff --git a/solr/core/src/java/org/apache/solr/spelling/suggest/DictionaryFactory.java b/solr/core/src/java/org/apache/solr/spelling/suggest/DictionaryFactory.java new file mode 100644 index 00000000000..831ddaaad33 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/spelling/suggest/DictionaryFactory.java @@ -0,0 +1,48 @@ +package org.apache.solr.spelling.suggest; +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.apache.lucene.search.spell.Dictionary; +import org.apache.solr.common.util.NamedList; +import org.apache.solr.core.SolrCore; +import org.apache.solr.search.SolrIndexSearcher; + +/** + * Encapsulates shared fields for all types of dictionaryFactory classes + */ +public abstract class DictionaryFactory { + + /** Default dictionary implementation to use for FileBasedDictionaries */ + public static String DEFAULT_FILE_BASED_DICT = FileDictionaryFactory.class.getName(); + + /** Default dictionary implementation to use for IndexBasedDictionaries */ + public static String DEFAULT_INDEX_BASED_DICT = HighFrequencyDictionaryFactory.class.getName(); + + protected NamedList params; + + /** Sets the parameters available to SolrSuggester for use in Dictionary creation */ + public void setParams(NamedList params) { + this.params = params; + } + + /** + * Create a Dictionary using options in core and optionally + * uses searcher, in case of index based dictionaries + */ + public abstract Dictionary create(SolrCore core, SolrIndexSearcher searcher); + +} diff --git a/solr/core/src/java/org/apache/solr/spelling/suggest/DocumentDictionaryFactory.java b/solr/core/src/java/org/apache/solr/spelling/suggest/DocumentDictionaryFactory.java new file mode 100644 index 00000000000..7a2f8f4dd71 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/spelling/suggest/DocumentDictionaryFactory.java @@ -0,0 +1,56 @@ +package org.apache.solr.spelling.suggest; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.apache.lucene.search.spell.Dictionary; +import org.apache.lucene.search.suggest.DocumentDictionary; +import org.apache.solr.core.SolrCore; +import org.apache.solr.search.SolrIndexSearcher; + +/** + * Factory for {@link DocumentDictionary} + */ +public class DocumentDictionaryFactory extends DictionaryFactory { + + public static final String FIELD = "field"; + + public static final String WEIGHT_FIELD = "weightField"; + + public static final String PAYLOAD_FIELD = "payloadField"; + + @Override + public Dictionary create(SolrCore core, SolrIndexSearcher searcher) { + if(params == null) { + // should not happen; implies setParams was not called + throw new IllegalStateException("Value of params not set"); + } + String field = (String) params.get(FIELD); + String weightField = (String) params.get(WEIGHT_FIELD); + String payloadField = (String) params.get(PAYLOAD_FIELD); + + if (field == null) { + throw new IllegalArgumentException(FIELD + " is a mandatory parameter"); + } + if (weightField == null) { + throw new IllegalArgumentException(WEIGHT_FIELD + " is a mandatory parameter"); + } + + return new DocumentDictionary(searcher.getIndexReader(), field, weightField, payloadField); + } + +} diff --git a/solr/core/src/java/org/apache/solr/spelling/suggest/DocumentExpressionDictionaryFactory.java b/solr/core/src/java/org/apache/solr/spelling/suggest/DocumentExpressionDictionaryFactory.java new file mode 100644 index 00000000000..e624232e808 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/spelling/suggest/DocumentExpressionDictionaryFactory.java @@ -0,0 +1,112 @@ +package org.apache.solr.spelling.suggest; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.util.HashSet; +import java.util.Set; + +import org.apache.lucene.search.SortField; +import org.apache.lucene.search.spell.Dictionary; +import org.apache.lucene.search.suggest.DocumentExpressionDictionary; +import org.apache.solr.core.SolrCore; +import org.apache.solr.schema.DoubleField; +import org.apache.solr.schema.FieldType; +import org.apache.solr.schema.FloatField; +import org.apache.solr.schema.IntField; +import org.apache.solr.schema.LongField; +import org.apache.solr.schema.TrieDoubleField; +import org.apache.solr.schema.TrieFloatField; +import org.apache.solr.schema.TrieIntField; +import org.apache.solr.schema.TrieLongField; +import org.apache.solr.search.SolrIndexSearcher; + +/** + * Factory for {@link DocumentExpressionDictionary} + */ +public class DocumentExpressionDictionaryFactory extends DictionaryFactory { + + /** Label for defining field to use for terms */ + public static final String FIELD = "field"; + + /** Label for defining payloadField to use for terms (optional) */ + public static final String PAYLOAD_FIELD = "payloadField"; + + /** Label for defining expression to evaluate the weight for the terms */ + public static final String WEIGHT_EXPRESSION = "weightExpression"; + + /** Label used to define the name of the + * sortField used in the {@link #WEIGHT_EXPRESSION} */ + public static final String SORT_FIELD = "sortField"; + + @Override + public Dictionary create(SolrCore core, SolrIndexSearcher searcher) { + if(params == null) { + // should not happen; implies setParams was not called + throw new IllegalStateException("Value of params not set"); + } + + String field = (String) params.get(FIELD); + String payloadField = (String) params.get(PAYLOAD_FIELD); + String weightExpression = (String) params.get(WEIGHT_EXPRESSION); + Set sortFields = new HashSet<>(); + + if (field == null) { + throw new IllegalArgumentException(FIELD + " is a mandatory parameter"); + } + + if (weightExpression == null) { + throw new IllegalArgumentException(WEIGHT_EXPRESSION + " is a mandatory parameter"); + } + + for(int i = 0; i < params.size(); i++) { + if (params.getName(i).equals(SORT_FIELD)) { + String sortFieldName = (String) params.getVal(i); + + SortField.Type sortFieldType = getSortFieldType(core, sortFieldName); + + if (sortFieldType == null) { + throw new IllegalArgumentException(sortFieldName + " could not be mapped to any appropriate type" + + " [long, int, float, double]"); + } + + SortField sortField = new SortField(sortFieldName, sortFieldType); + sortFields.add(sortField); + } + } + + return new DocumentExpressionDictionary(searcher.getIndexReader(), field, weightExpression, + sortFields, payloadField); + } + + private SortField.Type getSortFieldType(SolrCore core, String sortFieldName) { + SortField.Type type = null; + String fieldTypeName = core.getLatestSchema().getField(sortFieldName).getType().getTypeName(); + FieldType ft = core.getLatestSchema().getFieldTypes().get(fieldTypeName); + if (ft instanceof FloatField || ft instanceof TrieFloatField) { + type = SortField.Type.FLOAT; + } else if (ft instanceof IntField || ft instanceof TrieIntField) { + type = SortField.Type.INT; + } else if (ft instanceof LongField || ft instanceof TrieLongField) { + type = SortField.Type.LONG; + } else if (ft instanceof DoubleField || ft instanceof TrieDoubleField) { + type = SortField.Type.DOUBLE; + } + return type; + } + +} diff --git a/solr/core/src/java/org/apache/solr/spelling/suggest/FileDictionaryFactory.java b/solr/core/src/java/org/apache/solr/spelling/suggest/FileDictionaryFactory.java new file mode 100644 index 00000000000..986fe7ec64e --- /dev/null +++ b/solr/core/src/java/org/apache/solr/spelling/suggest/FileDictionaryFactory.java @@ -0,0 +1,62 @@ +package org.apache.solr.spelling.suggest; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.IOException; +import java.io.InputStreamReader; + +import org.apache.lucene.search.spell.Dictionary; +import org.apache.lucene.search.suggest.FileDictionary; +import org.apache.lucene.util.IOUtils; +import org.apache.solr.core.SolrCore; +import org.apache.solr.search.SolrIndexSearcher; + +/** + * Factory for {@link FileDictionary} + */ +public class FileDictionaryFactory extends DictionaryFactory { + + /** Label for defining fieldDelimiter to be used */ + public static final String FIELD_DELIMITER = "fieldDelimiter"; + + @Override + public Dictionary create(SolrCore core, SolrIndexSearcher searcher) { + if (params == null) { + // should not happen; implies setParams was not called + throw new IllegalStateException("Value of params not set"); + } + + String sourceLocation = (String)params.get(Suggester.LOCATION); + + if (sourceLocation == null) { + throw new IllegalArgumentException(Suggester.LOCATION + " parameter is mandatory for using FileDictionary"); + } + + String fieldDelimiter = (params.get(FIELD_DELIMITER) != null) + ? (String) params.get(FIELD_DELIMITER) : + FileDictionary.DEFAULT_FIELD_DELIMITER; + + try { + return new FileDictionary(new InputStreamReader( + core.getResourceLoader().openResource(sourceLocation), IOUtils.CHARSET_UTF_8), fieldDelimiter); + } catch (IOException e) { + throw new RuntimeException(); + } + } + +} diff --git a/solr/core/src/java/org/apache/solr/spelling/suggest/HighFrequencyDictionaryFactory.java b/solr/core/src/java/org/apache/solr/spelling/suggest/HighFrequencyDictionaryFactory.java new file mode 100644 index 00000000000..2d7c42bfd9d --- /dev/null +++ b/solr/core/src/java/org/apache/solr/spelling/suggest/HighFrequencyDictionaryFactory.java @@ -0,0 +1,53 @@ +package org.apache.solr.spelling.suggest; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.apache.lucene.search.spell.Dictionary; +import org.apache.lucene.search.spell.HighFrequencyDictionary; +import org.apache.solr.core.SolrCore; +import org.apache.solr.search.SolrIndexSearcher; +import org.apache.solr.spelling.SolrSpellChecker; + +/** + * Factory for {@link HighFrequencyDictionary} + */ +public class HighFrequencyDictionaryFactory extends DictionaryFactory { + /** + * Minimum frequency of terms to consider when building the dictionary. + */ + public static final String THRESHOLD_TOKEN_FREQUENCY = "threshold"; + + @Override + public Dictionary create(SolrCore core, SolrIndexSearcher searcher) { + if(params == null) { + // should not happen; implies setParams was not called + throw new IllegalStateException("Value of params not set"); + } + String field = (String)params.get(SolrSpellChecker.FIELD); + + if (field == null) { + throw new IllegalArgumentException(SolrSpellChecker.FIELD + " is a mandatory parameter"); + } + + float threshold = params.get(THRESHOLD_TOKEN_FREQUENCY) == null ? 0.0f + : (Float)params.get(THRESHOLD_TOKEN_FREQUENCY); + + return new HighFrequencyDictionary(searcher.getIndexReader(), field, threshold); + } + +} diff --git a/solr/core/src/java/org/apache/solr/spelling/suggest/LookupFactory.java b/solr/core/src/java/org/apache/solr/spelling/suggest/LookupFactory.java index 147b2611a98..33d1732e723 100644 --- a/solr/core/src/java/org/apache/solr/spelling/suggest/LookupFactory.java +++ b/solr/core/src/java/org/apache/solr/spelling/suggest/LookupFactory.java @@ -20,11 +20,25 @@ package org.apache.solr.spelling.suggest; import org.apache.lucene.search.suggest.Lookup; import org.apache.solr.common.util.NamedList; import org.apache.solr.core.SolrCore; +import org.apache.solr.spelling.suggest.jaspell.JaspellLookupFactory; /** * Suggester factory for creating {@link Lookup} instances. */ public abstract class LookupFactory { + + /** Default lookup implementation to use for SolrSuggester */ + public static String DEFAULT_FILE_BASED_DICT = JaspellLookupFactory.class.getName(); + + /** + * Create a Lookup using config options in params and + * current core + */ public abstract Lookup create(NamedList params, SolrCore core); + + /** + *

    Returns the filename in which the in-memory data structure is stored

    + * NOTE: not all {@link Lookup} implementations store in-memory data structures + * */ public abstract String storeFileName(); } diff --git a/solr/core/src/java/org/apache/solr/spelling/suggest/SolrSuggester.java b/solr/core/src/java/org/apache/solr/spelling/suggest/SolrSuggester.java new file mode 100644 index 00000000000..0f10128b494 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/spelling/suggest/SolrSuggester.java @@ -0,0 +1,206 @@ +package org.apache.solr.spelling.suggest; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.List; + +import org.apache.lucene.search.spell.Dictionary; +import org.apache.lucene.search.suggest.Lookup.LookupResult; +import org.apache.lucene.search.suggest.Lookup; +import org.apache.lucene.util.IOUtils; +import org.apache.solr.common.util.NamedList; +import org.apache.solr.core.SolrCore; +import org.apache.solr.search.SolrIndexSearcher; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Responsible for loading the lookup and dictionary Implementations specified by + * the SolrConfig. + * Interacts (query/build/reload) with Lucene Suggesters through {@link Lookup} and + * {@link Dictionary} + * */ +public class SolrSuggester { + private static final Logger LOG = LoggerFactory.getLogger(SolrSuggester.class); + + /** Name used when an unnamed suggester config is passed */ + public static final String DEFAULT_DICT_NAME = "default"; + + /** Label to identify the name of the suggester */ + public static final String NAME = "name"; + + /** Location of the source data - either a path to a file, or null for the + * current IndexReader. + * */ + public static final String LOCATION = "sourceLocation"; + + /** Fully-qualified class of the {@link Lookup} implementation. */ + public static final String LOOKUP_IMPL = "lookupImpl"; + + /** Fully-qualified class of the {@link Dictionary} implementation */ + public static final String DICTIONARY_IMPL = "dictionaryImpl"; + + /** + * Name of the location where to persist the dictionary. If this location + * is relative then the data will be stored under the core's dataDir. If this + * is null the storing will be disabled. + */ + public static final String STORE_DIR = "storeDir"; + + static SuggesterResult EMPTY_RESULT = new SuggesterResult(); + + private String sourceLocation; + private File storeDir; + private Dictionary dictionary; + private Lookup lookup; + private String lookupImpl; + private String dictionaryImpl; + private String name; + + private LookupFactory factory; + private DictionaryFactory dictionaryFactory; + + /** + * Uses the config and the core to initialize the underlying + * Lucene suggester + * */ + public String init(NamedList config, SolrCore core) { + LOG.info("init: " + config); + + // read the config + name = config.get(NAME) != null ? (String) config.get(NAME) + : DEFAULT_DICT_NAME; + sourceLocation = (String) config.get(LOCATION); + lookupImpl = (String) config.get(LOOKUP_IMPL); + dictionaryImpl = (String) config.get(DICTIONARY_IMPL); + String store = (String)config.get(STORE_DIR); + + if (lookupImpl == null) { + lookupImpl = LookupFactory.DEFAULT_FILE_BASED_DICT; + LOG.info("No " + LOOKUP_IMPL + " parameter was provided falling back to " + lookupImpl); + } + // initialize appropriate lookup instance + factory = core.getResourceLoader().newInstance(lookupImpl, LookupFactory.class); + lookup = factory.create(config, core); + + // if store directory is provided make it or load up the lookup with its content + if (store != null) { + storeDir = new File(store); + if (!storeDir.isAbsolute()) { + storeDir = new File(core.getDataDir() + File.separator + storeDir); + } + if (!storeDir.exists()) { + storeDir.mkdirs(); + } else { + // attempt reload of the stored lookup + try { + lookup.load(new FileInputStream(new File(storeDir, factory.storeFileName()))); + } catch (IOException e) { + LOG.warn("Loading stored lookup data failed, possibly not cached yet"); + } + } + } + + // dictionary configuration + if (dictionaryImpl == null) { + dictionaryImpl = (sourceLocation == null) ? DictionaryFactory.DEFAULT_INDEX_BASED_DICT : + DictionaryFactory.DEFAULT_FILE_BASED_DICT; + LOG.info("No " + DICTIONARY_IMPL + " parameter was provided falling back to " + dictionaryImpl); + } + + dictionaryFactory = core.getResourceLoader().newInstance(dictionaryImpl, DictionaryFactory.class); + dictionaryFactory.setParams(config); + LOG.info("Dictionary loaded with params: " + config); + + return name; + } + + /** Build the underlying Lucene Suggester */ + public void build(SolrCore core, SolrIndexSearcher searcher) throws IOException { + LOG.info("build()"); + + dictionary = dictionaryFactory.create(core, searcher); + lookup.build(dictionary); + if (storeDir != null) { + File target = new File(storeDir, factory.storeFileName()); + if(!lookup.store(new FileOutputStream(target))) { + LOG.error("Store Lookup build failed"); + } else { + LOG.info("Stored suggest data to: " + target.getAbsolutePath()); + } + } + } + + /** Reloads the underlying Lucene Suggester */ + public void reload(SolrCore core, SolrIndexSearcher searcher) throws IOException { + LOG.info("reload()"); + if (dictionary == null && storeDir != null) { + // this may be a firstSearcher event, try loading it + FileInputStream is = new FileInputStream(new File(storeDir, factory.storeFileName())); + try { + if (lookup.load(is)) { + return; // loaded ok + } + } finally { + IOUtils.closeWhileHandlingException(is); + } + LOG.debug("load failed, need to build Lookup again"); + } + // loading was unsuccessful - build it again + build(core, searcher); + } + + /** Returns suggestions based on the {@link SuggesterOptions} passed */ + public SuggesterResult getSuggestions(SuggesterOptions options) throws IOException { + LOG.debug("getSuggestions: " + options.token); + if (lookup == null) { + LOG.info("Lookup is null - invoke suggest.build first"); + return EMPTY_RESULT; + } + + SuggesterResult res = new SuggesterResult(); + List suggestions = lookup.lookup(options.token, false, options.count); + res.add(options.token.toString(), suggestions); + return res; + } + + /** Returns the unique name of the suggester */ + public String getName() { + return name; + } + + /** Returns the size of the in-memory data structure used by the underlying lookup implementation */ + public long sizeInBytes() { + return lookup.sizeInBytes(); + } + + @Override + public String toString() { + return "SolrSuggester [ name=" + name + ", " + + "sourceLocation=" + sourceLocation + ", " + + "storeDir=" + ((storeDir == null) ? "" : storeDir.getAbsoluteFile()) + ", " + + "lookupImpl=" + lookupImpl + ", " + + "dictionaryImpl=" + dictionaryImpl + ", " + + "sizeInBytes=" + ((lookup!=null) ? String.valueOf(sizeInBytes()) : "0") + " ]"; + } + +} diff --git a/solr/core/src/java/org/apache/solr/spelling/suggest/SuggesterOptions.java b/solr/core/src/java/org/apache/solr/spelling/suggest/SuggesterOptions.java new file mode 100644 index 00000000000..67ba529ab6b --- /dev/null +++ b/solr/core/src/java/org/apache/solr/spelling/suggest/SuggesterOptions.java @@ -0,0 +1,38 @@ +package org.apache.solr.spelling.suggest; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.apache.lucene.util.CharsRef; + +/** + * Encapsulates the inputs required to be passed on to + * the underlying suggester in {@link SolrSuggester} + **/ +public class SuggesterOptions { + + /** The token to lookup */ + CharsRef token; + + /** Number of suggestions requested */ + int count; + + public SuggesterOptions(CharsRef token, int count) { + this.token = token; + this.count = count; + } +} diff --git a/solr/core/src/java/org/apache/solr/spelling/suggest/SuggesterParams.java b/solr/core/src/java/org/apache/solr/spelling/suggest/SuggesterParams.java new file mode 100644 index 00000000000..d953dc06bc1 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/spelling/suggest/SuggesterParams.java @@ -0,0 +1,56 @@ +package org.apache.solr.spelling.suggest; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public interface SuggesterParams { + public static final String SUGGEST_PREFIX = "suggest."; + + /** + * The name of the dictionary to be used for giving the suggestion for a + * request. The value for this parameter is configured in solrconfig.xml + */ + public static final String SUGGEST_DICT = SUGGEST_PREFIX + "dictionary"; + + /** + * The count of suggestions to return for each query term not in the index and/or dictionary. + *

    + * If this parameter is absent in the request then only one suggestion is + * returned. If it is more than one then a maximum of given suggestions are + * returned for each token in the query. + */ + public static final String SUGGEST_COUNT = SUGGEST_PREFIX + "count"; + + /** + * Use the value for this parameter as the query to spell check. + *

    + * This parameter is optional. If absent, then the q parameter is + * used. + */ + public static final String SUGGEST_Q = SUGGEST_PREFIX + "q"; + + /** + * Whether to build the index or not. Optional and false by default. + */ + public static final String SUGGEST_BUILD = SUGGEST_PREFIX + "build"; + + /** + * Whether to reload the index. Optional and false by default. + */ + public static final String SUGGEST_RELOAD = SUGGEST_PREFIX + "reload"; + +} diff --git a/solr/core/src/java/org/apache/solr/spelling/suggest/SuggesterResult.java b/solr/core/src/java/org/apache/solr/spelling/suggest/SuggesterResult.java new file mode 100644 index 00000000000..6764a3b86d1 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/spelling/suggest/SuggesterResult.java @@ -0,0 +1,62 @@ +package org.apache.solr.spelling.suggest; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.lucene.search.suggest.Lookup.LookupResult; + +/** + * Encapsulates the results returned by the suggester in {@link SolrSuggester} + * */ +public class SuggesterResult { + + public SuggesterResult() {} + + /** token -> lookup results mapping*/ + private Map> suggestions = new HashMap>(); + + /** Add suggestion results for token */ + public void add(String token, List results) { + List res = this.suggestions.get(token); + if (res == null) { + res = results; + this.suggestions.put(token, res); + } + } + + /** + * Get a list of lookup result for a given token + * null can be returned, if there are no lookup results + * for the token + * */ + public List getLookupResult(String token) { + return this.suggestions.get(token); + } + + /** + * Get the set of tokens that are present in the + * instance + */ + public Set getTokens() { + return this.suggestions.keySet(); + } +} diff --git a/solr/core/src/java/org/apache/solr/spelling/suggest/fst/AnalyzingInfixLookupFactory.java b/solr/core/src/java/org/apache/solr/spelling/suggest/fst/AnalyzingInfixLookupFactory.java index e32859eebc0..e8196413cc6 100644 --- a/solr/core/src/java/org/apache/solr/spelling/suggest/fst/AnalyzingInfixLookupFactory.java +++ b/solr/core/src/java/org/apache/solr/spelling/suggest/fst/AnalyzingInfixLookupFactory.java @@ -69,6 +69,9 @@ public class AnalyzingInfixLookupFactory extends LookupFactory { throw new IllegalArgumentException("Error in configuration: " + QUERY_ANALYZER + " parameter is mandatory"); } FieldType ft = core.getLatestSchema().getFieldTypeByName(fieldTypeName.toString()); + if (ft == null) { + throw new IllegalArgumentException("Error in configuration: " + fieldTypeName.toString() + " is not defined in the schema"); + } Analyzer indexAnalyzer = ft.getAnalyzer(); Analyzer queryAnalyzer = ft.getQueryAnalyzer(); diff --git a/solr/core/src/java/org/apache/solr/spelling/suggest/fst/AnalyzingLookupFactory.java b/solr/core/src/java/org/apache/solr/spelling/suggest/fst/AnalyzingLookupFactory.java index 4dd4a186d7d..cba9d3a661b 100644 --- a/solr/core/src/java/org/apache/solr/spelling/suggest/fst/AnalyzingLookupFactory.java +++ b/solr/core/src/java/org/apache/solr/spelling/suggest/fst/AnalyzingLookupFactory.java @@ -83,6 +83,10 @@ public class AnalyzingLookupFactory extends LookupFactory { throw new IllegalArgumentException("Error in configuration: " + QUERY_ANALYZER + " parameter is mandatory"); } FieldType ft = core.getLatestSchema().getFieldTypeByName(fieldTypeName.toString()); + if (ft == null) { + throw new IllegalArgumentException("Error in configuration: " + fieldTypeName.toString() + " is not defined in the schema"); + } + Analyzer indexAnalyzer = ft.getAnalyzer(); Analyzer queryAnalyzer = ft.getQueryAnalyzer(); diff --git a/solr/core/src/java/org/apache/solr/spelling/suggest/fst/FuzzyLookupFactory.java b/solr/core/src/java/org/apache/solr/spelling/suggest/fst/FuzzyLookupFactory.java index 4eec5939c93..5dae427c729 100644 --- a/solr/core/src/java/org/apache/solr/spelling/suggest/fst/FuzzyLookupFactory.java +++ b/solr/core/src/java/org/apache/solr/spelling/suggest/fst/FuzzyLookupFactory.java @@ -78,6 +78,9 @@ public class FuzzyLookupFactory extends LookupFactory { } // retrieve index and query analyzers for the field FieldType ft = core.getLatestSchema().getFieldTypeByName(fieldTypeName.toString()); + if (ft == null) { + throw new IllegalArgumentException("Error in configuration: " + fieldTypeName.toString() + " is not defined in the schema"); + } Analyzer indexAnalyzer = ft.getAnalyzer(); Analyzer queryAnalyzer = ft.getQueryAnalyzer(); diff --git a/solr/core/src/test-files/solr/collection1/conf/schema-phrasesuggest.xml b/solr/core/src/test-files/solr/collection1/conf/schema-phrasesuggest.xml index f5ed9155e66..7d4876c270a 100644 --- a/solr/core/src/test-files/solr/collection1/conf/schema-phrasesuggest.xml +++ b/solr/core/src/test-files/solr/collection1/conf/schema-phrasesuggest.xml @@ -53,6 +53,7 @@ + text diff --git a/solr/core/src/test-files/solr/collection1/conf/solrconfig-phrasesuggest.xml b/solr/core/src/test-files/solr/collection1/conf/solrconfig-phrasesuggest.xml index b4f560ed32f..a25ac604c15 100644 --- a/solr/core/src/test-files/solr/collection1/conf/solrconfig-phrasesuggest.xml +++ b/solr/core/src/test-files/solr/collection1/conf/solrconfig-phrasesuggest.xml @@ -83,6 +83,42 @@ phrase_suggest + + + + + fuzzy_suggest_analyzing_with_high_freq_dict + org.apache.solr.spelling.suggest.fst.FuzzyLookupFactory + org.apache.solr.spelling.suggest.HighFrequencyDictionaryFactory + fuzzy_suggest_analyzing + false + + + true + text + false + stext + + + + + + + + fuzzy_suggest_analyzing_with_file_dict + org.apache.solr.spelling.suggest.fst.FuzzyLookupFactory + org.apache.solr.spelling.suggest.FileDictionaryFactory + fuzzy_suggest_analyzing + false + + + true + text + false + + fuzzysuggest.txt + + @@ -215,6 +251,26 @@ + + + true + fuzzy_suggest_analyzing_with_file_dict + + + fuzzy_suggest_analyzing_with_file_dict + + + + + + true + fuzzy_suggest_analyzing_with_high_freq_dict + + + fuzzy_suggest_analyzing_with_high_freq_dict + + + true diff --git a/solr/core/src/test-files/solr/collection1/conf/solrconfig-suggestercomponent.xml b/solr/core/src/test-files/solr/collection1/conf/solrconfig-suggestercomponent.xml new file mode 100644 index 00000000000..1d1a1e92082 --- /dev/null +++ b/solr/core/src/test-files/solr/collection1/conf/solrconfig-suggestercomponent.xml @@ -0,0 +1,95 @@ + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + ${solr.data.dir:} + + + + + + + + + + + suggest_fuzzy_with_high_freq_dict + FuzzyLookupFactory + cat + suggest_fuzzy_with_high_freq_dict + text + true + + + 0.0 + + + + + suggest_fuzzy_file_based + FuzzyLookupFactory + fuzzysuggest.txt + suggest_fuzzy_file_based + text + true + + + + + suggest_fuzzy_doc_dict + FuzzyLookupFactory + DocumentDictionaryFactory + cat + price + suggest_fuzzy_doc_dict_payload + text + true + + + + + suggest_fuzzy_doc_expr_dict + DocumentExpressionDictionaryFactory + FuzzyLookupFactory + cat + ((price * 2) + weight) + weight + price + suggest_fuzzy_doc_expr_dict + text + true + + + + + + true + + + suggest + + + + + + diff --git a/solr/core/src/test-files/solr/collection1/conf/solrconfig.xml b/solr/core/src/test-files/solr/collection1/conf/solrconfig.xml index 3c4f454439a..e38e1d6a01f 100644 --- a/solr/core/src/test-files/solr/collection1/conf/solrconfig.xml +++ b/solr/core/src/test-files/solr/collection1/conf/solrconfig.xml @@ -340,6 +340,8 @@ termsComp + + dell - electronics - monitor + electronics and computer1 30" TFT active matrix LCD, 2560 x 1600, .25mm dot pitch, 700:1 contrast USB cable 401.6 diff --git a/solr/example/exampledocs/monitor2.xml b/solr/example/exampledocs/monitor2.xml index 79b99494319..eaf9e223ccd 100644 --- a/solr/example/exampledocs/monitor2.xml +++ b/solr/example/exampledocs/monitor2.xml @@ -21,8 +21,7 @@ ViewSonic Corp. viewsonic - electronics - monitor + electronics and stuff2 19" TFT active matrix LCD, 8ms response time, 1280 x 1024 native resolution 190.4 279.95 diff --git a/solr/example/solr/collection1/conf/solrconfig.xml b/solr/example/solr/collection1/conf/solrconfig.xml index 1f825b8c5ba..d8b14dfb8e3 100755 --- a/solr/example/solr/collection1/conf/solrconfig.xml +++ b/solr/example/solr/collection1/conf/solrconfig.xml @@ -1320,7 +1320,7 @@ --> - + + DocumentDictionaryFactory + cat + price + string + + + + + + true + 10 + + + suggest + + + + + From e61acfdb0d5961b79fddc6302c7b3fdd6230a654 Mon Sep 17 00:00:00 2001 From: Noble Paul Date: Sun, 24 Nov 2013 06:06:32 +0000 Subject: [PATCH 082/223] SOLR-5493 git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1544925 13f79535-47bb-0310-9956-ffa450edef68 --- solr/core/src/java/org/apache/solr/handler/SnapPuller.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/solr/core/src/java/org/apache/solr/handler/SnapPuller.java b/solr/core/src/java/org/apache/solr/handler/SnapPuller.java index b88d7e8a3ce..12ca0ddca19 100644 --- a/solr/core/src/java/org/apache/solr/handler/SnapPuller.java +++ b/solr/core/src/java/org/apache/solr/handler/SnapPuller.java @@ -788,6 +788,8 @@ public class SnapPuller { for (Map file : filesToDownload) { if (dir.fileExists((String) file.get(NAME)) && dir.fileLength((String) file.get(NAME)) != (Long) file.get(SIZE)) { + LOG.warn("File " + file.get(NAME) + " expected to be " + file.get(SIZE) + + " while it is " + dir.fileLength((String) file.get(NAME))); // file exists and size is different, therefore we must assume // corrupted index return true; From 633ea330fe8196314f8598f1638a86f0b8587fb4 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Sun, 24 Nov 2013 14:48:50 +0000 Subject: [PATCH 083/223] tests: fix for random map order git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1544980 13f79535-47bb-0310-9956-ffa450edef68 --- .../solr/cloud/UnloadDistributedZkTest.java | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/solr/core/src/test/org/apache/solr/cloud/UnloadDistributedZkTest.java b/solr/core/src/test/org/apache/solr/cloud/UnloadDistributedZkTest.java index 2da5c679adc..3a0618d00ee 100644 --- a/solr/core/src/test/org/apache/solr/cloud/UnloadDistributedZkTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/UnloadDistributedZkTest.java @@ -25,7 +25,6 @@ import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import org.apache.lucene.util.LuceneTestCase.Slow; -import org.apache.lucene.util.Constants; import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.SolrServer; import org.apache.solr.client.solrj.SolrServerException; @@ -33,7 +32,6 @@ import org.apache.solr.client.solrj.impl.HttpSolrServer; import org.apache.solr.client.solrj.request.CoreAdminRequest.Create; import org.apache.solr.client.solrj.request.CoreAdminRequest.Unload; import org.apache.solr.common.SolrInputDocument; -import org.apache.solr.common.cloud.Slice; import org.apache.solr.common.cloud.ZkCoreNodeProps; import org.apache.solr.common.cloud.ZkStateReader; import org.apache.solr.common.params.ModifiableSolrParams; @@ -51,7 +49,7 @@ public class UnloadDistributedZkTest extends BasicDistributedZkTest { @BeforeClass public static void beforeThisClass3() throws Exception { - assumeFalse("FIXME: This test fails under Java 8 all the time, see SOLR-4711", Constants.JRE_IS_MINIMUM_JAVA8); + } @Before @@ -120,21 +118,17 @@ public class UnloadDistributedZkTest extends BasicDistributedZkTest { server.request(unloadCmd); // there should be only one shard - Slice shard2 = getCommonCloudSolrServer().getZkStateReader().getClusterState().getSlice(collection, "shard2"); + int slices = getCommonCloudSolrServer().getZkStateReader().getClusterState().getSlices(collection).size(); long timeoutAt = System.currentTimeMillis() + 45000; - while (shard2 != null) { + while (slices != 1) { if (System.currentTimeMillis() > timeoutAt) { printLayout(); - fail("Still found shard2 in collection " + collection); + fail("Expected to find only one slice in " + collection); } Thread.sleep(1000); - shard2 = getCommonCloudSolrServer().getZkStateReader().getClusterState().getSlice(collection, "shard2"); + slices = getCommonCloudSolrServer().getZkStateReader().getClusterState().getSlices(collection).size(); } - - Slice shard1 = getCommonCloudSolrServer().getZkStateReader().getClusterState().getSlice(collection, "shard1"); - assertNotNull(shard1); - assertTrue(getCommonCloudSolrServer().getZkStateReader().getClusterState().getCollections().contains(collection)); // now unload one of the other unloadCmd = new Unload(false); From 04fd728416b45ccd6af352da8317af3aa285d295 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Sun, 24 Nov 2013 15:00:48 +0000 Subject: [PATCH 084/223] tests: fix for random map order git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1544984 13f79535-47bb-0310-9956-ffa450edef68 --- .../solr/core/TestSolrXmlPersistor.java | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/solr/core/src/test/org/apache/solr/core/TestSolrXmlPersistor.java b/solr/core/src/test/org/apache/solr/core/TestSolrXmlPersistor.java index d1b7d3cf117..4878c6b161e 100644 --- a/solr/core/src/test/org/apache/solr/core/TestSolrXmlPersistor.java +++ b/solr/core/src/test/org/apache/solr/core/TestSolrXmlPersistor.java @@ -17,17 +17,15 @@ package org.apache.solr.core; * limitations under the License. */ -import com.google.common.collect.ImmutableList; -import org.apache.commons.io.FileUtils; -import org.apache.solr.SolrTestCaseJ4; -import org.junit.Test; - import java.io.File; import java.io.IOException; import java.util.List; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import org.apache.commons.io.FileUtils; +import org.apache.solr.SolrTestCaseJ4; +import org.junit.Test; + +import com.google.common.collect.ImmutableList; public class TestSolrXmlPersistor extends SolrTestCaseJ4 { @@ -78,10 +76,12 @@ public class TestSolrXmlPersistor extends SolrTestCaseJ4 { List cds = ImmutableList.of(cd); SolrXMLCoresLocator persistor = new SolrXMLCoresLocator(solrxml, null); - assertEquals(persistor.buildSolrXML(cds), - "" + SolrXMLCoresLocator.NEWLINE - + " " + SolrXMLCoresLocator.NEWLINE - + ""); + String xml = persistor.buildSolrXML(cds); + + assertTrue(xml.contains("")); + assertTrue(xml.contains("name=\"testcore\"")); + assertTrue(xml.contains("instanceDir=\"instance/dir/\"")); + assertTrue(xml.contains("")); } finally { if (solrHomeDirectory.exists()) { FileUtils.deleteDirectory(solrHomeDirectory); From 6c9d05e97dfb73047f1edfaf445fc4bf981cba35 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Sun, 24 Nov 2013 15:23:32 +0000 Subject: [PATCH 085/223] tests: tweak timeouts git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1544994 13f79535-47bb-0310-9956-ffa450edef68 --- .../test/org/apache/solr/cloud/UnloadDistributedZkTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/solr/core/src/test/org/apache/solr/cloud/UnloadDistributedZkTest.java b/solr/core/src/test/org/apache/solr/cloud/UnloadDistributedZkTest.java index 3a0618d00ee..9cf3d3dc516 100644 --- a/solr/core/src/test/org/apache/solr/cloud/UnloadDistributedZkTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/UnloadDistributedZkTest.java @@ -230,8 +230,8 @@ public class UnloadDistributedZkTest extends BasicDistributedZkTest { DirectUpdateHandler2.commitOnClose = false; HttpSolrServer addClient = new HttpSolrServer(url3 + "/unloadcollection3"); - addClient.setConnectionTimeout(15000); - addClient.setSoTimeout(30000); + addClient.setConnectionTimeout(30000); + // add a few docs for (int x = 20; x < 100; x++) { SolrInputDocument doc1 = getDoc(id, x, i1, -600, tlong, 600, t1, From 9a76dcdf9edba7aab9782fa75f017ae3c290c72b Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Sun, 24 Nov 2013 15:35:12 +0000 Subject: [PATCH 086/223] boost default zk connect timeout from 15s to 30s git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1544999 13f79535-47bb-0310-9956-ffa450edef68 --- solr/core/src/java/org/apache/solr/core/ZkContainer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solr/core/src/java/org/apache/solr/core/ZkContainer.java b/solr/core/src/java/org/apache/solr/core/ZkContainer.java index ca6711a5db3..6b281d8fa47 100644 --- a/solr/core/src/java/org/apache/solr/core/ZkContainer.java +++ b/solr/core/src/java/org/apache/solr/core/ZkContainer.java @@ -119,7 +119,7 @@ public class ZkContainer { } } - int zkClientConnectTimeout = 15000; + int zkClientConnectTimeout = 30000; if (zookeeperHost != null) { From 513c277e73e33651ba6802c34a01b7f06556187a Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Sun, 24 Nov 2013 15:53:00 +0000 Subject: [PATCH 087/223] tests: clean up a bit git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545005 13f79535-47bb-0310-9956-ffa450edef68 --- .../solr/cloud/BasicDistributedZk2Test.java | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/solr/core/src/test/org/apache/solr/cloud/BasicDistributedZk2Test.java b/solr/core/src/test/org/apache/solr/cloud/BasicDistributedZk2Test.java index fe71e88889b..944e959aded 100644 --- a/solr/core/src/test/org/apache/solr/cloud/BasicDistributedZk2Test.java +++ b/solr/core/src/test/org/apache/solr/cloud/BasicDistributedZk2Test.java @@ -55,11 +55,12 @@ import org.junit.BeforeClass; * work as expected. */ public class BasicDistributedZk2Test extends AbstractFullDistribZkTestBase { + private static final String SHARD1 = "shard1"; private static final String ONE_NODE_COLLECTION = "onenodecollection"; @BeforeClass public static void beforeThisClass2() throws Exception { - assumeFalse("FIXME: This test fails under Java 8 all the time, see SOLR-4711", Constants.JRE_IS_MINIMUM_JAVA8); + } public BasicDistributedZk2Test() { @@ -144,14 +145,15 @@ public class BasicDistributedZk2Test extends AbstractFullDistribZkTestBase { index_specific(client, "id", docId + 1, t1, "what happens here?"); // expire a session... - CloudJettyRunner cloudJetty = shardToJetty.get("shard1").get(0); + CloudJettyRunner cloudJetty = shardToJetty.get(SHARD1).get(0); chaosMonkey.expireSession(cloudJetty.jetty); indexr("id", docId + 1, t1, "slip this doc in"); waitForRecoveriesToFinish(false); - checkShardConsistency("shard1"); + checkShardConsistency(SHARD1); + checkShardConsistency(SHARD2); testFinished = true; } finally { @@ -185,9 +187,9 @@ public class BasicDistributedZk2Test extends AbstractFullDistribZkTestBase { waitForCollection(cloudClient.getZkStateReader(), ONE_NODE_COLLECTION, 1); waitForRecoveriesToFinish(ONE_NODE_COLLECTION, cloudClient.getZkStateReader(), false); - cloudClient.getZkStateReader().getLeaderRetry(ONE_NODE_COLLECTION, "shard1", 30000); + cloudClient.getZkStateReader().getLeaderRetry(ONE_NODE_COLLECTION, SHARD1, 30000); - final String baseUrl2 = getBaseUrl((HttpSolrServer) clients.get(1)); + final String baseUrl2 = getBaseUrl((HttpSolrServer) clients.get(random().nextInt(clients.size()))); HttpSolrServer qclient = new HttpSolrServer(baseUrl2 + "/onenodecollection" + "core"); // add a doc @@ -502,12 +504,17 @@ public class BasicDistributedZk2Test extends AbstractFullDistribZkTestBase { // new server should be part of first shard // how many docs are on the new shard? - for (CloudJettyRunner cjetty : shardToJetty.get("shard1")) { - if (VERBOSE) System.err.println("total:" + for (CloudJettyRunner cjetty : shardToJetty.get(SHARD1)) { + if (VERBOSE) System.err.println("shard1 total:" + + cjetty.client.solrClient.query(new SolrQuery("*:*")).getResults().getNumFound()); + } + for (CloudJettyRunner cjetty : shardToJetty.get("shard2")) { + if (VERBOSE) System.err.println("shard2 total:" + cjetty.client.solrClient.query(new SolrQuery("*:*")).getResults().getNumFound()); } - checkShardConsistency("shard1"); + checkShardConsistency(SHARD1); + checkShardConsistency("shard2"); assertDocCounts(VERBOSE); } From 4ff856d994154ca93e6f712625875d5aea63ce13 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Sun, 24 Nov 2013 17:12:05 +0000 Subject: [PATCH 088/223] SOLR-5488: fix set removal bug git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545009 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/solr/analytics/request/AnalyticsRequestFactory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solr/core/src/java/org/apache/solr/analytics/request/AnalyticsRequestFactory.java b/solr/core/src/java/org/apache/solr/analytics/request/AnalyticsRequestFactory.java index 1c8142a97c0..62fa7345601 100644 --- a/solr/core/src/java/org/apache/solr/analytics/request/AnalyticsRequestFactory.java +++ b/solr/core/src/java/org/apache/solr/analytics/request/AnalyticsRequestFactory.java @@ -295,7 +295,7 @@ public class AnalyticsRequestFactory implements AnalyticsParams { Set depends = queryFacet.getDependencies(); int place = 0; for (QueryFacetRequest qfr : currentList) { - if (qfr.getDependencies().remove(queryFacet)) { + if (qfr.getDependencies().remove(queryFacet.getName())) { break; } place++; From acee28acf4d4b5ec4d9c6484d1835ad7adfbc6cb Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Sun, 24 Nov 2013 17:14:50 +0000 Subject: [PATCH 089/223] tests: improve test git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545010 13f79535-47bb-0310-9956-ffa450edef68 --- .../solr/cloud/BasicDistributedZk2Test.java | 35 ++++++++++++------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/solr/core/src/test/org/apache/solr/cloud/BasicDistributedZk2Test.java b/solr/core/src/test/org/apache/solr/cloud/BasicDistributedZk2Test.java index 944e959aded..1dbf465b3d6 100644 --- a/solr/core/src/test/org/apache/solr/cloud/BasicDistributedZk2Test.java +++ b/solr/core/src/test/org/apache/solr/cloud/BasicDistributedZk2Test.java @@ -29,7 +29,6 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.io.IOUtils; -import org.apache.lucene.util.Constants; import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.SolrServer; import org.apache.solr.client.solrj.SolrServerException; @@ -55,6 +54,7 @@ import org.junit.BeforeClass; * work as expected. */ public class BasicDistributedZk2Test extends AbstractFullDistribZkTestBase { + private static final String SHARD2 = "shard2"; private static final String SHARD1 = "shard1"; private static final String ONE_NODE_COLLECTION = "onenodecollection"; @@ -169,8 +169,7 @@ public class BasicDistributedZk2Test extends AbstractFullDistribZkTestBase { try { final String baseUrl = getBaseUrl((HttpSolrServer) clients.get(0)); HttpSolrServer server = new HttpSolrServer(baseUrl); - server.setConnectionTimeout(15000); - server.setSoTimeout(60000); + server.setConnectionTimeout(30000); Create createCmd = new Create(); createCmd.setRoles("none"); createCmd.setCoreName(ONE_NODE_COLLECTION + "core"); @@ -189,32 +188,42 @@ public class BasicDistributedZk2Test extends AbstractFullDistribZkTestBase { cloudClient.getZkStateReader().getLeaderRetry(ONE_NODE_COLLECTION, SHARD1, 30000); - final String baseUrl2 = getBaseUrl((HttpSolrServer) clients.get(random().nextInt(clients.size()))); - HttpSolrServer qclient = new HttpSolrServer(baseUrl2 + "/onenodecollection" + "core"); + int docs = 2; + for (SolrServer client : clients) { + final String baseUrl = getBaseUrl((HttpSolrServer) client); + addAndQueryDocs(baseUrl, docs); + docs += 2; + } + } + + // 2 docs added every call + private void addAndQueryDocs(final String baseUrl, int docs) + throws SolrServerException, IOException { + HttpSolrServer qclient = new HttpSolrServer(baseUrl + "/onenodecollection" + "core"); // add a doc SolrInputDocument doc = new SolrInputDocument(); - doc.addField("id", "1"); + doc.addField("id", docs); qclient.add(doc); qclient.commit(); SolrQuery query = new SolrQuery("*:*"); QueryResponse results = qclient.query(query); - assertEquals(1, results.getResults().getNumFound()); + assertEquals(docs - 1, results.getResults().getNumFound()); - qclient = new HttpSolrServer(baseUrl2 + "/onenodecollection"); + qclient = new HttpSolrServer(baseUrl + "/onenodecollection"); results = qclient.query(query); - assertEquals(1, results.getResults().getNumFound()); + assertEquals(docs - 1, results.getResults().getNumFound()); doc = new SolrInputDocument(); - doc.addField("id", "2"); + doc.addField("id", docs + 1); qclient.add(doc); qclient.commit(); query = new SolrQuery("*:*"); query.set("rows", 0); results = qclient.query(query); - assertEquals(2, results.getResults().getNumFound()); + assertEquals(docs, results.getResults().getNumFound()); } private long testUpdateAndDelete() throws Exception { @@ -508,13 +517,13 @@ public class BasicDistributedZk2Test extends AbstractFullDistribZkTestBase { if (VERBOSE) System.err.println("shard1 total:" + cjetty.client.solrClient.query(new SolrQuery("*:*")).getResults().getNumFound()); } - for (CloudJettyRunner cjetty : shardToJetty.get("shard2")) { + for (CloudJettyRunner cjetty : shardToJetty.get(SHARD2)) { if (VERBOSE) System.err.println("shard2 total:" + cjetty.client.solrClient.query(new SolrQuery("*:*")).getResults().getNumFound()); } checkShardConsistency(SHARD1); - checkShardConsistency("shard2"); + checkShardConsistency(SHARD2); assertDocCounts(VERBOSE); } From 782b2e221c8db208e30420b3d21bb31e2a8f38f7 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Sun, 24 Nov 2013 17:30:00 +0000 Subject: [PATCH 090/223] tests: harden test git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545013 13f79535-47bb-0310-9956-ffa450edef68 --- .../test/org/apache/solr/cloud/BasicDistributedZk2Test.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/solr/core/src/test/org/apache/solr/cloud/BasicDistributedZk2Test.java b/solr/core/src/test/org/apache/solr/cloud/BasicDistributedZk2Test.java index 1dbf465b3d6..7a9bb992faa 100644 --- a/solr/core/src/test/org/apache/solr/cloud/BasicDistributedZk2Test.java +++ b/solr/core/src/test/org/apache/solr/cloud/BasicDistributedZk2Test.java @@ -34,6 +34,7 @@ import org.apache.solr.client.solrj.SolrServer; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.embedded.JettySolrRunner; import org.apache.solr.client.solrj.impl.HttpSolrServer; +import org.apache.solr.client.solrj.impl.HttpSolrServer.RemoteSolrException; import org.apache.solr.client.solrj.request.CoreAdminRequest.Create; import org.apache.solr.client.solrj.request.QueryRequest; import org.apache.solr.client.solrj.request.UpdateRequest; @@ -198,9 +199,12 @@ public class BasicDistributedZk2Test extends AbstractFullDistribZkTestBase { // 2 docs added every call private void addAndQueryDocs(final String baseUrl, int docs) - throws SolrServerException, IOException { + throws Exception { HttpSolrServer qclient = new HttpSolrServer(baseUrl + "/onenodecollection" + "core"); + // it might take a moment for the proxy node to see us in their cloud state + waitForNon403or404or503(qclient); + // add a doc SolrInputDocument doc = new SolrInputDocument(); doc.addField("id", docs); From e50b2b3da4941ff5d5de2e84154851ce7d6cbec1 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Sun, 24 Nov 2013 18:45:17 +0000 Subject: [PATCH 091/223] SOLR-4553: for some reason, a node can keep seeing slices inactive or something - we should attempt to proxy inactive slices anyway git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545027 13f79535-47bb-0310-9956-ffa450edef68 --- .../src/java/org/apache/solr/servlet/SolrDispatchFilter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java b/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java index 3437245cd8c..4c454ec5fa7 100644 --- a/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java +++ b/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java @@ -580,7 +580,7 @@ public class SolrDispatchFilter implements Filter Set collections = clusterState.getCollections(); for (String collection : collections) { slices = new ArrayList(); - slices.addAll(clusterState.getActiveSlices(collection)); + slices.addAll(clusterState.getSlices(collection)); } } From aaafda0f6e5b3ccee8898c05f599618ac28e0cff Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Sun, 24 Nov 2013 18:54:52 +0000 Subject: [PATCH 092/223] SOLR-4713: This should not be an issue anymore git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545035 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/solr/cloud/CollectionsAPIDistributedZkTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIDistributedZkTest.java b/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIDistributedZkTest.java index 695923a12e2..a88bf0a90ff 100644 --- a/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIDistributedZkTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIDistributedZkTest.java @@ -109,7 +109,7 @@ public class CollectionsAPIDistributedZkTest extends AbstractFullDistribZkTestBa @BeforeClass public static void beforeThisClass2() throws Exception { - assumeFalse("FIXME: This test fails under Java 8 all the time, see SOLR-4711", Constants.JRE_IS_MINIMUM_JAVA8); + } @Before From ac8cd42ebdd67fecce8482e6f3789431086e87c2 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Sun, 24 Nov 2013 19:12:50 +0000 Subject: [PATCH 093/223] SOLR-5497: See if this helps. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545049 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/solr/cloud/AbstractFullDistribZkTestBase.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java b/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java index 813d9e481c9..99108455f19 100644 --- a/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java +++ b/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java @@ -454,7 +454,7 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes String solrConfigOverride) throws Exception { JettySolrRunner jetty = new JettySolrRunner(getSolrHome(), context, 0, - solrConfigOverride, null, false, getExtraServlets()); + solrConfigOverride, null, true, getExtraServlets()); jetty.setShards(shardList); jetty.setDataDir(getDataDir(dataDir)); jetty.start(); From 2e461b4258447a66d6100f6e101c3203c792d119 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Sun, 24 Nov 2013 19:23:44 +0000 Subject: [PATCH 094/223] SOLR-5488: ignore this test for now git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545053 13f79535-47bb-0310-9956-ffa450edef68 --- solr/core/src/test/org/apache/solr/analytics/NoFacetTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/solr/core/src/test/org/apache/solr/analytics/NoFacetTest.java b/solr/core/src/test/org/apache/solr/analytics/NoFacetTest.java index f43303af74a..028179622a8 100644 --- a/solr/core/src/test/org/apache/solr/analytics/NoFacetTest.java +++ b/solr/core/src/test/org/apache/solr/analytics/NoFacetTest.java @@ -21,6 +21,8 @@ package org.apache.solr.analytics; import java.util.ArrayList; import java.util.List; +import jdk.nashorn.internal.ir.annotations.Ignore; + import org.apache.lucene.util.LuceneTestCase.SuppressCodecs; import org.junit.BeforeClass; import org.junit.Test; @@ -209,7 +211,7 @@ public class NoFacetTest extends AbstractAnalyticsStatsTest { assertEquals(doubleResult,doubleTest); } - @Test + @Test @Ignore() // See "SOLR-5488" public void stddevTest() throws Exception { //Int Double intResult = (Double)getStatResult(response, "str", "double", "int_id"); From fc7a21deea8bf2ba361fc5b71941f4ed389de0f1 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Sun, 24 Nov 2013 19:25:43 +0000 Subject: [PATCH 095/223] SOLR-5488: fix ignore import git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545054 13f79535-47bb-0310-9956-ffa450edef68 --- .../core/src/test/org/apache/solr/analytics/NoFacetTest.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/solr/core/src/test/org/apache/solr/analytics/NoFacetTest.java b/solr/core/src/test/org/apache/solr/analytics/NoFacetTest.java index 028179622a8..ae290a12c68 100644 --- a/solr/core/src/test/org/apache/solr/analytics/NoFacetTest.java +++ b/solr/core/src/test/org/apache/solr/analytics/NoFacetTest.java @@ -21,10 +21,9 @@ package org.apache.solr.analytics; import java.util.ArrayList; import java.util.List; -import jdk.nashorn.internal.ir.annotations.Ignore; - import org.apache.lucene.util.LuceneTestCase.SuppressCodecs; import org.junit.BeforeClass; +import org.junit.Ignore; import org.junit.Test; @SuppressCodecs({"Lucene3x","Lucene40","Lucene41","Lucene42","Appending","Asserting"}) @@ -211,7 +210,7 @@ public class NoFacetTest extends AbstractAnalyticsStatsTest { assertEquals(doubleResult,doubleTest); } - @Test @Ignore() // See "SOLR-5488" + @Test @Ignore("SOLR-5488") public void stddevTest() throws Exception { //Int Double intResult = (Double)getStatResult(response, "str", "double", "int_id"); From c95f5900acb0645a78ae94c1d8113e6ad4446fe5 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Sun, 24 Nov 2013 20:19:43 +0000 Subject: [PATCH 096/223] SOLR-4553: Bug in finding remote node when proxying update request in a cluster with more than one collection. Also, attempt to proxy requests more aggressively. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545065 13f79535-47bb-0310-9956-ffa450edef68 --- .../solr/servlet/SolrDispatchFilter.java | 44 ++++++++++++++++--- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java b/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java index 4c454ec5fa7..756ddb49855 100644 --- a/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java +++ b/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java @@ -574,13 +574,14 @@ public class SolrDispatchFilter implements Filter ClusterState clusterState = cores.getZkController().getClusterState(); Collection slices = clusterState.getActiveSlices(collectionName); boolean byCoreName = false; + if (slices == null) { + slices = new ArrayList(); // look by core name byCoreName = true; - Set collections = clusterState.getCollections(); - for (String collection : collections) { - slices = new ArrayList(); - slices.addAll(clusterState.getSlices(collection)); + slices = getSlicesForCollections(clusterState, slices, true); + if (slices == null || slices.size() == 0) { + slices = getSlicesForCollections(clusterState, slices, false); } } @@ -588,6 +589,21 @@ public class SolrDispatchFilter implements Filter return null; } + String coreUrl = getCoreUrl(cores, collectionName, origCorename, clusterState, + slices, byCoreName, true); + + if (coreUrl == null) { + coreUrl = getCoreUrl(cores, collectionName, origCorename, clusterState, + slices, byCoreName, false); + } + + return coreUrl; + } + + private String getCoreUrl(CoreContainer cores, String collectionName, + String origCorename, ClusterState clusterState, Collection slices, + boolean byCoreName, boolean activeReplicas) { + String coreUrl; Set liveNodes = clusterState.getLiveNodes(); Iterator it = slices.iterator(); while (it.hasNext()) { @@ -595,8 +611,9 @@ public class SolrDispatchFilter implements Filter Map sliceShards = slice.getReplicasMap(); for (ZkNodeProps nodeProps : sliceShards.values()) { ZkCoreNodeProps coreNodeProps = new ZkCoreNodeProps(nodeProps); - if (liveNodes.contains(coreNodeProps.getNodeName()) - && coreNodeProps.getState().equals(ZkStateReader.ACTIVE)) { + if (!activeReplicas || (liveNodes.contains(coreNodeProps.getNodeName()) + && coreNodeProps.getState().equals(ZkStateReader.ACTIVE))) { + if (byCoreName && !collectionName.equals(coreNodeProps.getCoreName())) { // if it's by core name, make sure they match continue; @@ -605,7 +622,7 @@ public class SolrDispatchFilter implements Filter // don't count a local core continue; } - String coreUrl; + if (origCorename != null) { coreUrl = coreNodeProps.getBaseUrl() + "/" + origCorename; } else { @@ -621,6 +638,19 @@ public class SolrDispatchFilter implements Filter } return null; } + + private Collection getSlicesForCollections(ClusterState clusterState, + Collection slices, boolean activeSlices) { + Set collections = clusterState.getCollections(); + for (String collection : collections) { + if (activeSlices) { + slices.addAll(clusterState.getActiveSlices(collection)); + } else { + slices.addAll(clusterState.getSlices(collection)); + } + } + return slices; + } private SolrCore getCoreByCollection(CoreContainer cores, String corename, String path) { String collection = corename; From aca845c6a0a4044fc08a9d3785a96c3c6969c44e Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Sun, 24 Nov 2013 20:20:10 +0000 Subject: [PATCH 097/223] SOLR-5497: Do not try and start a jetty that is not stopped git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545066 13f79535-47bb-0310-9956-ffa450edef68 --- .../src/java/org/apache/solr/cloud/ChaosMonkey.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solr/test-framework/src/java/org/apache/solr/cloud/ChaosMonkey.java b/solr/test-framework/src/java/org/apache/solr/cloud/ChaosMonkey.java index ec8d61b8c06..2e2c554beb5 100644 --- a/solr/test-framework/src/java/org/apache/solr/cloud/ChaosMonkey.java +++ b/solr/test-framework/src/java/org/apache/solr/cloud/ChaosMonkey.java @@ -460,7 +460,7 @@ public class ChaosMonkey { if (!deadPool.isEmpty()) { int index = random.nextInt(deadPool.size()); JettySolrRunner jetty = deadPool.get(index).jetty; - if (!ChaosMonkey.start(jetty)) { + if (jetty.isStopped() && !ChaosMonkey.start(jetty)) { continue; } //System.out.println("started on port:" + jetty.getLocalPort()); From 0e19da794bd378aec568fb5cdfa07d84c22d22a3 Mon Sep 17 00:00:00 2001 From: Erick Erickson Date: Sun, 24 Nov 2013 21:33:45 +0000 Subject: [PATCH 098/223] SOLR-5488: Added DOM parsing to the test cases rather than string manipulation git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545080 13f79535-47bb-0310-9956-ffa450edef68 --- .../analytics/AbstractAnalyticsStatsTest.java | 82 ++++++++--- .../apache/solr/analytics/NoFacetTest.java | 134 +++++++++--------- .../util/valuesource/FunctionTest.java | 113 ++++++++------- 3 files changed, 186 insertions(+), 143 deletions(-) diff --git a/solr/core/src/test/org/apache/solr/analytics/AbstractAnalyticsStatsTest.java b/solr/core/src/test/org/apache/solr/analytics/AbstractAnalyticsStatsTest.java index f5e008bd423..2d7c582c253 100644 --- a/solr/core/src/test/org/apache/solr/analytics/AbstractAnalyticsStatsTest.java +++ b/solr/core/src/test/org/apache/solr/analytics/AbstractAnalyticsStatsTest.java @@ -17,12 +17,15 @@ package org.apache.solr.analytics; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileNotFoundException; +import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.Locale; import java.util.Scanner; import org.apache.commons.lang.StringUtils; @@ -35,32 +38,75 @@ import org.apache.solr.request.SolrQueryRequest; import com.google.common.collect.ObjectArrays; import org.apache.solr.util.ExternalPaths; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; +import org.w3c.dom.Document; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + @SuppressCodecs({"Lucene3x","Lucene40","Lucene41","Lucene42","Appending","Asserting"}) public class AbstractAnalyticsStatsTest extends SolrTestCaseJ4 { protected static final String[] BASEPARMS = new String[]{ "q", "*:*", "indent", "true", "olap", "true", "rows", "0" }; protected static final HashMap defaults = new HashMap(); - - public Object getStatResult(String response, String request, String type, String name) { - String cat = "\n "; - String begin = "<"+type+" name=\""+name+"\">"; - String end = ""; - int beginInt = response.indexOf(begin, response.indexOf(cat))+begin.length(); - int endInt = response.indexOf(end, beginInt); - String resultStr = response.substring(beginInt, endInt); - if (type.equals("double")) { - return Double.parseDouble(resultStr); - } else if (type.equals("int")) { - return Integer.parseInt(resultStr); - } else if (type.equals("long")) { - return Long.parseLong(resultStr); - } else if (type.equals("float")) { - return Float.parseFloat(resultStr); - } else { - return resultStr; + + public static enum VAL_TYPE { + INTEGER("int"), + LONG("long"), + FLOAT("float"), + DOUBLE("double"), + STRING("str"), + DATE("date"); + + private VAL_TYPE (final String text) { + this.text = text; + } + + private final String text; + + @Override + public String toString() { + return text; } } + static private Document doc; + static private XPathFactory xPathFact = XPathFactory.newInstance(); + + public static void setResponse(String response) throws ParserConfigurationException, IOException, SAXException { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); // never forget this! + DocumentBuilder builder = factory.newDocumentBuilder(); + doc = builder.parse(new InputSource(new ByteArrayInputStream(response.getBytes()))); + xPathFact = XPathFactory.newInstance(); + } + + public Object getStatResult(String section, String name, VAL_TYPE type) throws XPathExpressionException { + + // Construct the XPath expression. The form better not change or all these will fail. + StringBuilder sb = new StringBuilder("/response/lst[@name='stats']/lst[@name='").append(section).append("']"); + + // This is a little fragile in that it demands the elements have the same name as type, i.e. when looking for a + // VAL_TYPE.DOUBLE, the element in question is 47.0. + sb.append("/").append(type.toString()).append("[@name='").append(name).append("']"); + String val = xPathFact.newXPath().compile(sb.toString()).evaluate(doc, XPathConstants.STRING).toString(); + switch (type) { + case INTEGER: return Integer.parseInt(val); + case DOUBLE: return Double.parseDouble(val); + case FLOAT: return Float.parseFloat(val); + case LONG: return Long.parseLong(val); + case STRING: return val; + case DATE: return val; + } + fail("Unknown type used in getStatResult"); + return null; // Really can't get here, but the compiler thinks we can! + } + + public > Double calculateNumberStat(ArrayList list, String stat) { Double result; if (stat.equals("median")) { diff --git a/solr/core/src/test/org/apache/solr/analytics/NoFacetTest.java b/solr/core/src/test/org/apache/solr/analytics/NoFacetTest.java index ae290a12c68..cbaa9a38f5f 100644 --- a/solr/core/src/test/org/apache/solr/analytics/NoFacetTest.java +++ b/solr/core/src/test/org/apache/solr/analytics/NoFacetTest.java @@ -58,12 +58,10 @@ public class NoFacetTest extends AbstractAnalyticsStatsTest { static ArrayList dateTestStart; static long dateMissing = 0; - //STRING + //STR static ArrayList stringTestStart; static long stringMissing = 0; - static String response; - @BeforeClass public static void beforeClass() throws Exception { initCore("solrconfig-basic.xml","schema-analytics.xml"); @@ -138,51 +136,51 @@ public class NoFacetTest extends AbstractAnalyticsStatsTest { assertU(commit()); //Sort ascending tests - response = h.query(request(fileToStringArr(fileName))); + setResponse(h.query(request(fileToStringArr(fileName)))); } @Test - public void sumTest() throws Exception { + public void sumTest() throws Exception { //Int - Double intResult = (Double)getStatResult(response, "sr", "double", "int_id"); + Double intResult = (Double)getStatResult("sr", "int_id", VAL_TYPE.DOUBLE); Double intTest = (Double)calculateNumberStat(intTestStart, "sum"); assertEquals(intResult,intTest); //Long - Double longResult = (Double)getStatResult(response, "sr", "double", "long_ld"); + Double longResult = (Double)getStatResult("sr", "long_ld", VAL_TYPE.DOUBLE); Double longTest = (Double)calculateNumberStat(longTestStart, "sum"); assertEquals(longResult,longTest); //Float - Double floatResult = (Double)getStatResult(response, "sr", "double", "float_fd"); + Double floatResult = (Double)getStatResult("sr", "float_fd", VAL_TYPE.DOUBLE); Double floatTest = (Double)calculateNumberStat(floatTestStart, "sum"); assertEquals(floatResult,floatTest); //Double - Double doubleResult = (Double)getStatResult(response, "sr", "double", "double_dd"); - Double doubleTest = (Double)calculateNumberStat(doubleTestStart, "sum"); + Double doubleResult = (Double)getStatResult("sr", "double_dd", VAL_TYPE.DOUBLE); + Double doubleTest = (Double) calculateNumberStat(doubleTestStart, "sum"); assertEquals(doubleResult,doubleTest); } @Test public void sumOfSquaresTest() throws Exception { //Int - Double intResult = (Double)getStatResult(response, "sosr", "double", "int_id"); + Double intResult = (Double)getStatResult("sosr", "int_id", VAL_TYPE.DOUBLE); Double intTest = (Double)calculateNumberStat(intTestStart, "sumOfSquares"); assertEquals(intResult,intTest); //Long - Double longResult = (Double)getStatResult(response, "sosr", "double", "long_ld"); + Double longResult = (Double)getStatResult("sosr", "long_ld", VAL_TYPE.DOUBLE); Double longTest = (Double)calculateNumberStat(longTestStart, "sumOfSquares"); assertEquals(longResult,longTest); //Float - Double floatResult = (Double)getStatResult(response, "sosr", "double", "float_fd"); + Double floatResult = (Double)getStatResult("sosr", "float_fd", VAL_TYPE.DOUBLE); Double floatTest = (Double)calculateNumberStat(floatTestStart, "sumOfSquares"); assertEquals(floatResult,floatTest); //Double - Double doubleResult = (Double)getStatResult(response, "sosr", "double", "double_dd"); + Double doubleResult = (Double)getStatResult("sosr", "double_dd", VAL_TYPE.DOUBLE); Double doubleTest = (Double)calculateNumberStat(doubleTestStart, "sumOfSquares"); assertEquals(doubleResult,doubleTest); } @@ -190,22 +188,22 @@ public class NoFacetTest extends AbstractAnalyticsStatsTest { @Test public void meanTest() throws Exception { //Int - Double intResult = (Double)getStatResult(response, "mr", "double", "int_id"); + Double intResult = (Double)getStatResult("mr", "int_id", VAL_TYPE.DOUBLE); Double intTest = (Double)calculateNumberStat(intTestStart, "mean"); assertEquals(intResult,intTest); //Long - Double longResult = (Double)getStatResult(response, "mr", "double", "long_ld"); + Double longResult = (Double)getStatResult("mr", "long_ld", VAL_TYPE.DOUBLE); Double longTest = (Double)calculateNumberStat(longTestStart, "mean"); assertEquals(longResult,longTest); //Float - Double floatResult = (Double)getStatResult(response, "mr", "double", "float_fd"); + Double floatResult = (Double)getStatResult("mr", "float_fd", VAL_TYPE.DOUBLE); Double floatTest = (Double)calculateNumberStat(floatTestStart, "mean"); assertEquals(floatResult,floatTest); //Double - Double doubleResult = (Double)getStatResult(response, "mr", "double", "double_dd"); + Double doubleResult = (Double)getStatResult("mr", "double_dd", VAL_TYPE.DOUBLE); Double doubleTest = (Double)calculateNumberStat(doubleTestStart, "mean"); assertEquals(doubleResult,doubleTest); } @@ -213,17 +211,17 @@ public class NoFacetTest extends AbstractAnalyticsStatsTest { @Test @Ignore("SOLR-5488") public void stddevTest() throws Exception { //Int - Double intResult = (Double)getStatResult(response, "str", "double", "int_id"); + Double intResult = (Double)getStatResult("str", "int_id", VAL_TYPE.DOUBLE); Double intTest = (Double)calculateNumberStat(intTestStart, "stddev"); assertTrue(Math.abs(intResult-intTest)<.00000000001); //Long - Double longResult = (Double)getStatResult(response, "str", "double", "long_ld"); + Double longResult = (Double)getStatResult("str", "long_ld", VAL_TYPE.DOUBLE); Double longTest = (Double)calculateNumberStat(longTestStart, "stddev"); assertTrue(Math.abs(longResult-longTest)<.00000000001); //Float - Double floatResult = (Double)getStatResult(response, "str", "double", "float_fd"); + Double floatResult = (Double)getStatResult("str", "float_fd", VAL_TYPE.DOUBLE); Double floatTest = (Double)calculateNumberStat(floatTestStart, "stddev"); assertTrue("Oops: (double raws) " + Double.doubleToRawLongBits(floatResult) + " - " + Double.doubleToRawLongBits(floatTest) + " < " + Double.doubleToRawLongBits(.00000000001) + @@ -234,7 +232,7 @@ public class NoFacetTest extends AbstractAnalyticsStatsTest { //Double - Double doubleResult = (Double)getStatResult(response, "str", "double", "double_dd"); + Double doubleResult = (Double)getStatResult("str", "double_dd", VAL_TYPE.DOUBLE); Double doubleTest = (Double)calculateNumberStat(doubleTestStart, "stddev"); assertTrue(Math.abs(doubleResult-doubleTest)<.00000000001); } @@ -242,22 +240,22 @@ public class NoFacetTest extends AbstractAnalyticsStatsTest { @Test public void medianTest() throws Exception { //Int - Double intResult = (Double)getStatResult(response, "medr", "double", "int_id"); + Double intResult = (Double)getStatResult("medr", "int_id", VAL_TYPE.DOUBLE); Double intTest = (Double)calculateNumberStat(intTestStart, "median"); assertEquals(intResult,intTest); //Long - Double longResult = (Double)getStatResult(response, "medr", "double", "long_ld"); + Double longResult = (Double)getStatResult("medr", "long_ld", VAL_TYPE.DOUBLE); Double longTest = (Double)calculateNumberStat(longTestStart, "median"); assertEquals(longResult,longTest); //Float - Double floatResult = (Double)getStatResult(response, "medr", "double", "float_fd"); + Double floatResult = (Double)getStatResult("medr", "float_fd", VAL_TYPE.DOUBLE); Double floatTest = (Double)calculateNumberStat(floatTestStart, "median"); assertEquals(floatResult,floatTest); //Double - Double doubleResult = (Double)getStatResult(response, "medr", "double", "double_dd"); + Double doubleResult = (Double)getStatResult("medr", "double_dd", VAL_TYPE.DOUBLE); Double doubleTest = (Double)calculateNumberStat(doubleTestStart, "median"); assertEquals(doubleResult,doubleTest); } @@ -265,32 +263,32 @@ public class NoFacetTest extends AbstractAnalyticsStatsTest { @Test public void perc20Test() throws Exception { //Int 20 - Integer intResult = (Integer)getStatResult(response, "p2r", "int", "int_id"); + Integer intResult = (Integer)getStatResult("p2r", "int_id", VAL_TYPE.INTEGER); Integer intTest = (Integer)calculateStat(intTestStart, "perc_20"); assertEquals(intResult,intTest); //Long 20 - Long longResult = (Long)getStatResult(response, "p2r", "long", "long_ld"); + Long longResult = (Long)getStatResult("p2r", "long_ld", VAL_TYPE.LONG); Long longTest = (Long)calculateStat(longTestStart, "perc_20"); assertEquals(longResult,longTest); //Float 20 - Float floatResult = (Float)getStatResult(response, "p2r", "float", "float_fd"); + Float floatResult = (Float)getStatResult("p2r", "float_fd", VAL_TYPE.FLOAT); Float floatTest = (Float)calculateStat(floatTestStart, "perc_20"); assertEquals(floatResult,floatTest); //Double 20 - Double doubleResult = (Double)getStatResult(response, "p2r", "double", "double_dd"); + Double doubleResult = (Double)getStatResult("p2r", "double_dd", VAL_TYPE.DOUBLE); Double doubleTest = (Double)calculateStat(doubleTestStart, "perc_20"); assertEquals(doubleResult,doubleTest); //Date 20 - String dateResult = (String)getStatResult(response, "p2r", "date", "date_dtd"); + String dateResult = (String)getStatResult("p2r", "date_dtd", VAL_TYPE.DATE); String dateTest = (String)calculateStat(dateTestStart, "perc_20"); assertEquals(dateResult,dateTest); //String 20 - String stringResult = (String)getStatResult(response, "p2r", "str", "string_sd"); + String stringResult = (String)getStatResult("p2r", "string_sd", VAL_TYPE.STRING); String stringTest = (String)calculateStat(stringTestStart, "perc_20"); assertEquals(stringResult,stringTest); } @@ -298,32 +296,32 @@ public class NoFacetTest extends AbstractAnalyticsStatsTest { @Test public void perc60Test() throws Exception { //Int 60 - Integer intResult = (Integer)getStatResult(response, "p6r", "int", "int_id"); + Integer intResult = (Integer)getStatResult("p6r", "int_id", VAL_TYPE.INTEGER); Integer intTest = (Integer)calculateStat(intTestStart, "perc_60"); assertEquals(intResult,intTest); //Long 60 - Long longResult = (Long)getStatResult(response, "p6r", "long", "long_ld"); + Long longResult = (Long)getStatResult("p6r", "long_ld", VAL_TYPE.LONG); Long longTest = (Long)calculateStat(longTestStart, "perc_60"); assertEquals(longResult,longTest); //Float 60 - Float floatResult = (Float)getStatResult(response, "p6r", "float", "float_fd"); + Float floatResult = (Float)getStatResult("p6r", "float_fd", VAL_TYPE.FLOAT); Float floatTest = (Float)calculateStat(floatTestStart, "perc_60"); assertEquals(floatResult,floatTest); //Double 60 - Double doubleResult = (Double)getStatResult(response, "p6r", "double", "double_dd"); + Double doubleResult = (Double)getStatResult("p6r", "double_dd", VAL_TYPE.DOUBLE); Double doubleTest = (Double)calculateStat(doubleTestStart, "perc_60"); assertEquals(doubleResult,doubleTest); //Date 60 - String dateResult = (String)getStatResult(response, "p6r", "date", "date_dtd"); + String dateResult = (String)getStatResult("p6r", "date_dtd", VAL_TYPE.DATE); String dateTest = (String)calculateStat(dateTestStart, "perc_60"); assertEquals(dateResult,dateTest); //String 60 - String stringResult = (String)getStatResult(response, "p6r", "str", "string_sd"); + String stringResult = (String)getStatResult("p6r", "string_sd", VAL_TYPE.STRING); String stringTest = (String)calculateStat(stringTestStart, "perc_60"); assertEquals(stringResult,stringTest); } @@ -331,32 +329,32 @@ public class NoFacetTest extends AbstractAnalyticsStatsTest { @Test public void minTest() throws Exception { //Int - Integer intResult = (Integer)getStatResult(response, "mir", "int", "int_id"); + Integer intResult = (Integer)getStatResult("mir", "int_id", VAL_TYPE.INTEGER); Integer intTest = (Integer)calculateStat(intTestStart, "min"); assertEquals(intResult,intTest); //Long - Long longResult = (Long)getStatResult(response, "mir", "long", "long_ld"); + Long longResult = (Long)getStatResult("mir", "long_ld", VAL_TYPE.LONG); Long longTest = (Long)calculateStat(longTestStart, "min"); assertEquals(longResult,longTest); //Float - Float floatResult = (Float)getStatResult(response, "mir", "float", "float_fd"); + Float floatResult = (Float)getStatResult("mir", "float_fd", VAL_TYPE.FLOAT); Float floatTest = (Float)calculateStat(floatTestStart, "min"); assertEquals(floatResult,floatTest); //Double - Double doubleResult = (Double)getStatResult(response, "mir", "double", "double_dd"); + Double doubleResult = (Double)getStatResult("mir", "double_dd", VAL_TYPE.DOUBLE); Double doubleTest = (Double)calculateStat(doubleTestStart, "min"); assertEquals(doubleResult,doubleTest); //Date - String dateResult = (String)getStatResult(response, "mir", "date", "date_dtd"); + String dateResult = (String)getStatResult("mir", "date_dtd", VAL_TYPE.DATE); String dateTest = (String)calculateStat(dateTestStart, "min"); assertEquals(dateResult,dateTest); //String - String stringResult = (String)getStatResult(response, "mir", "str", "string_sd"); + String stringResult = (String)getStatResult("mir", "string_sd", VAL_TYPE.STRING); String stringTest = (String)calculateStat(stringTestStart, "min"); assertEquals(stringResult,stringTest); } @@ -364,32 +362,32 @@ public class NoFacetTest extends AbstractAnalyticsStatsTest { @Test public void maxTest() throws Exception { //Int - Integer intResult = (Integer)getStatResult(response, "mar", "int", "int_id"); + Integer intResult = (Integer)getStatResult("mar", "int_id", VAL_TYPE.INTEGER); Integer intTest = (Integer)calculateStat(intTestStart, "max"); assertEquals(intResult,intTest); //Long - Long longResult = (Long)getStatResult(response, "mar", "long", "long_ld"); + Long longResult = (Long)getStatResult("mar", "long_ld", VAL_TYPE.LONG); Long longTest = (Long)calculateStat(longTestStart, "max"); assertEquals(longResult,longTest); //Float - Float floatResult = (Float)getStatResult(response, "mar", "float", "float_fd"); + Float floatResult = (Float)getStatResult("mar", "float_fd", VAL_TYPE.FLOAT); Float floatTest = (Float)calculateStat(floatTestStart, "max"); assertEquals(floatResult,floatTest); //Double - Double doubleResult = (Double)getStatResult(response, "mar", "double", "double_dd"); + Double doubleResult = (Double)getStatResult("mar", "double_dd", VAL_TYPE.DOUBLE); Double doubleTest = (Double)calculateStat(doubleTestStart, "max"); assertEquals(doubleResult,doubleTest); //Date - String dateResult = (String)getStatResult(response, "mar", "date", "date_dtd"); + String dateResult = (String)getStatResult("mar", "date_dtd", VAL_TYPE.DATE); String dateTest = (String)calculateStat(dateTestStart, "max"); assertEquals(dateResult,dateTest); //String - String stringResult = (String)getStatResult(response, "mar", "str", "string_sd"); + String stringResult = (String)getStatResult("mar", "string_sd", VAL_TYPE.STRING); String stringTest = (String)calculateStat(stringTestStart, "max"); assertEquals(stringResult,stringTest); } @@ -397,32 +395,32 @@ public class NoFacetTest extends AbstractAnalyticsStatsTest { @Test public void uniqueTest() throws Exception { //Int - Long intResult = (Long)getStatResult(response, "ur", "long", "int_id"); + Long intResult = (Long)getStatResult("ur", "int_id", VAL_TYPE.LONG); Long intTest = (Long)calculateStat(intTestStart, "unique"); assertEquals(intResult,intTest); //Long - Long longResult = (Long)getStatResult(response, "ur", "long", "long_ld"); + Long longResult = (Long)getStatResult("ur", "long_ld", VAL_TYPE.LONG); Long longTest = (Long)calculateStat(longTestStart, "unique"); assertEquals(longResult,longTest); //Float - Long floatResult = (Long)getStatResult(response, "ur", "long", "float_fd"); + Long floatResult = (Long)getStatResult("ur", "float_fd", VAL_TYPE.LONG); Long floatTest = (Long)calculateStat(floatTestStart, "unique"); assertEquals(floatResult,floatTest); //Double - Long doubleResult = (Long)getStatResult(response, "ur", "long", "double_dd"); + Long doubleResult = (Long)getStatResult("ur", "double_dd", VAL_TYPE.LONG); Long doubleTest = (Long)calculateStat(doubleTestStart, "unique"); assertEquals(doubleResult,doubleTest); //Date - Long dateResult = (Long)getStatResult(response, "ur", "long", "date_dtd"); + Long dateResult = (Long)getStatResult("ur", "date_dtd", VAL_TYPE.LONG); Long dateTest = (Long)calculateStat(dateTestStart, "unique"); assertEquals(dateResult,dateTest); //String - Long stringResult = (Long)getStatResult(response, "ur", "long", "string_sd"); + Long stringResult = (Long)getStatResult("ur", "string_sd", VAL_TYPE.LONG); Long stringTest = (Long)calculateStat(stringTestStart, "unique"); assertEquals(stringResult,stringTest); } @@ -430,32 +428,32 @@ public class NoFacetTest extends AbstractAnalyticsStatsTest { @Test public void countTest() throws Exception { //Int - Long intResult = (Long)getStatResult(response, "cr", "long", "int_id"); + Long intResult = (Long)getStatResult("cr", "int_id", VAL_TYPE.LONG); Long intTest = (Long)calculateStat(intTestStart, "count"); assertEquals(intResult,intTest); //Long - Long longResult = (Long)getStatResult(response, "cr", "long", "long_ld"); + Long longResult = (Long)getStatResult("cr", "long_ld", VAL_TYPE.LONG); Long longTest = (Long)calculateStat(longTestStart, "count"); assertEquals(longResult,longTest); //Float - Long floatResult = (Long)getStatResult(response, "cr", "long", "float_fd"); + Long floatResult = (Long)getStatResult("cr", "float_fd", VAL_TYPE.LONG); Long floatTest = (Long)calculateStat(floatTestStart, "count"); assertEquals(floatResult,floatTest); //Double - Long doubleResult = (Long)getStatResult(response, "cr", "long", "double_dd"); + Long doubleResult = (Long)getStatResult("cr", "double_dd", VAL_TYPE.LONG); Long doubleTest = (Long)calculateStat(doubleTestStart, "count"); assertEquals(doubleResult,doubleTest); //Date - Long dateResult = (Long)getStatResult(response, "cr", "long", "date_dtd"); + Long dateResult = (Long)getStatResult("cr", "date_dtd", VAL_TYPE.LONG); Long dateTest = (Long)calculateStat(dateTestStart, "count"); assertEquals(dateResult,dateTest); //String - Long stringResult = (Long)getStatResult(response, "cr", "long", "string_sd"); + Long stringResult = (Long)getStatResult("cr", "string_sd", VAL_TYPE.LONG); Long stringTest = (Long)calculateStat(stringTestStart, "count"); assertEquals(stringResult,stringTest); } @@ -463,27 +461,27 @@ public class NoFacetTest extends AbstractAnalyticsStatsTest { @Test public void missingDefaultTest() throws Exception { //Int - long intResult = (Long)getStatResult(response, "misr", "long", "int_id"); + long intResult = (Long)getStatResult("misr", "int_id", VAL_TYPE.LONG); assertEquals(intMissing,intResult); //Long - long longResult = (Long)getStatResult(response, "misr", "long", "long_ld"); + long longResult = (Long)getStatResult("misr", "long_ld", VAL_TYPE.LONG); assertEquals(longMissing,longResult); //Float - long floatResult = (Long)getStatResult(response, "misr", "long", "float_fd"); + long floatResult = (Long)getStatResult("misr", "float_fd", VAL_TYPE.LONG); assertEquals(floatMissing,floatResult); //Double - long doubleResult = (Long)getStatResult(response, "misr", "long", "double_dd"); + long doubleResult = (Long)getStatResult("misr", "double_dd", VAL_TYPE.LONG); assertEquals(doubleMissing,doubleResult); //Date - long dateResult = (Long)getStatResult(response, "misr", "long", "date_dtd"); + long dateResult = (Long)getStatResult("misr", "date_dtd", VAL_TYPE.LONG); assertEquals(dateMissing,dateResult); //String - long stringResult = (Long)getStatResult(response, "misr", "long", "string_sd"); + long stringResult = (Long)getStatResult("misr", "string_sd", VAL_TYPE.LONG); assertEquals(stringMissing, stringResult); } diff --git a/solr/core/src/test/org/apache/solr/analytics/util/valuesource/FunctionTest.java b/solr/core/src/test/org/apache/solr/analytics/util/valuesource/FunctionTest.java index 8ccfed6d743..6037028eb6b 100644 --- a/solr/core/src/test/org/apache/solr/analytics/util/valuesource/FunctionTest.java +++ b/solr/core/src/test/org/apache/solr/analytics/util/valuesource/FunctionTest.java @@ -23,6 +23,7 @@ import org.apache.solr.analytics.AbstractAnalyticsStatsTest; import org.apache.solr.analytics.facet.AbstractAnalyticsFacetTest; import org.junit.Assert; import org.junit.BeforeClass; +import org.junit.Ignore; import org.junit.Test; @SuppressCodecs({"Lucene3x","Lucene40","Lucene41","Lucene42","Appending","Asserting"}) @@ -36,8 +37,6 @@ public class FunctionTest extends AbstractAnalyticsStatsTest { static public final int DATE = 12; static public final int STRING = 28; static public final int NUM_LOOPS = 100; - - static String response; @BeforeClass public static void beforeClass() throws Exception { @@ -85,145 +84,145 @@ public class FunctionTest extends AbstractAnalyticsStatsTest { assertU(commit()); - response = h.query(request(fileToStringArr(fileName))); + setResponse(h.query(request(fileToStringArr(fileName)))); } @Test public void addTest() throws Exception { - double result = (Double)getStatResult(response, "ar", "double", "sum"); - double calculated = (Double)getStatResult(response, "ar", "double", "sumc"); + double result = (Double)getStatResult("ar", "sum", VAL_TYPE.DOUBLE); + double calculated = (Double)getStatResult("ar", "sumc", VAL_TYPE.DOUBLE); assertTrue(result==calculated); - result = (Double)getStatResult(response, "ar", "double", "mean"); - calculated = (Double)getStatResult(response, "ar", "double", "meanc"); + result = (Double)getStatResult("ar", "mean", VAL_TYPE.DOUBLE); + calculated = (Double)getStatResult("ar", "meanc", VAL_TYPE.DOUBLE); assertTrue(result==calculated); } @Test public void multiplyTest() throws Exception { - double result = (Double)getStatResult(response, "mr", "double", "sum"); - double calculated = (Double)getStatResult(response, "mr", "double", "sumc"); + double result = (Double)getStatResult("mr", "sum", VAL_TYPE.DOUBLE); + double calculated = (Double)getStatResult("mr", "sumc", VAL_TYPE.DOUBLE); assertTrue(result==calculated); - result = (Double)getStatResult(response, "mr", "double", "mean"); - calculated = (Double)getStatResult(response, "mr", "double", "meanc"); + result = (Double)getStatResult("mr", "mean", VAL_TYPE.DOUBLE); + calculated = (Double)getStatResult("mr", "meanc", VAL_TYPE.DOUBLE); assertTrue(result==calculated); } @Test public void divideTest() throws Exception { - Double result = (Double)getStatResult(response, "dr", "double", "sum"); - Double calculated = (Double)getStatResult(response, "dr", "double", "sumc"); + Double result = (Double)getStatResult("dr", "sum", VAL_TYPE.DOUBLE); + Double calculated = (Double)getStatResult("dr", "sumc", VAL_TYPE.DOUBLE); assertTrue(result.equals(calculated)); - result = (Double)getStatResult(response, "dr", "double", "mean"); - calculated = (Double)getStatResult(response, "dr", "double", "meanc"); + result = (Double)getStatResult("dr", "mean", VAL_TYPE.DOUBLE); + calculated = (Double)getStatResult("dr", "meanc", VAL_TYPE.DOUBLE); assertTrue(result.equals(calculated)); } @Test public void powerTest() throws Exception { - double result = (Double)getStatResult(response, "pr", "double", "sum"); - double calculated = (Double)getStatResult(response, "pr", "double", "sumc"); + double result = (Double)getStatResult("pr", "sum", VAL_TYPE.DOUBLE); + double calculated = (Double)getStatResult("pr", "sumc", VAL_TYPE.DOUBLE); assertTrue(result==calculated); - result = (Double)getStatResult(response, "pr", "double", "mean"); - calculated = (Double)getStatResult(response, "pr", "double", "meanc"); + result = (Double)getStatResult("pr", "mean", VAL_TYPE.DOUBLE); + calculated = (Double)getStatResult("pr", "meanc", VAL_TYPE.DOUBLE); assertTrue(result==calculated); } @Test public void negateTest() throws Exception { - double result = (Double)getStatResult(response, "nr", "double", "sum"); - double calculated = (Double)getStatResult(response, "nr", "double", "sumc"); + double result = (Double)getStatResult("nr", "sum", VAL_TYPE.DOUBLE); + double calculated = (Double)getStatResult("nr", "sumc", VAL_TYPE.DOUBLE); assertTrue(result==calculated); - result = (Double)getStatResult(response, "nr", "double", "mean"); - calculated = (Double)getStatResult(response, "nr", "double", "meanc"); + result = (Double)getStatResult("nr", "mean", VAL_TYPE.DOUBLE); + calculated = (Double)getStatResult("nr", "meanc", VAL_TYPE.DOUBLE); assertTrue(result==calculated); } - - @Test - public void absoluteValueTest() throws Exception { - double result = (Double)getStatResult(response, "avr", "double", "sum"); - double calculated = (Double)getStatResult(response, "avr", "double", "sumc"); + + @Test @Ignore("SOLR-5488") + public void absoluteValueTest() throws Exception { + double result = (Double)getStatResult("avr", "sum", VAL_TYPE.DOUBLE); + double calculated = (Double)getStatResult("avr", "sumc", VAL_TYPE.DOUBLE); assertTrue(result==calculated); - result = (Double)getStatResult(response, "avr", "double", "mean"); - calculated = (Double)getStatResult(response, "avr", "double", "meanc"); + result = (Double)getStatResult("avr", "mean", VAL_TYPE.DOUBLE); + calculated = (Double)getStatResult("avr", "meanc", VAL_TYPE.DOUBLE); assertTrue(result==calculated); } @Test public void constantNumberTest() throws Exception { - double result = (Double)getStatResult(response, "cnr", "double", "sum"); - double calculated = (Double)getStatResult(response, "cnr", "double", "sumc"); + double result = (Double)getStatResult("cnr", "sum", VAL_TYPE.DOUBLE); + double calculated = (Double)getStatResult("cnr", "sumc", VAL_TYPE.DOUBLE); assertTrue(result==calculated); - result = (Double)getStatResult(response, "cnr", "double", "mean"); - calculated = (Double)getStatResult(response, "cnr", "double", "meanc"); + result = (Double)getStatResult("cnr", "mean", VAL_TYPE.DOUBLE); + calculated = (Double)getStatResult("cnr", "meanc", VAL_TYPE.DOUBLE); assertTrue(result==calculated); } @Test - public void dateMathTest() throws Exception { - String result = (String)getStatResult(response, "dmr", "date", "median"); - String calculated = (String)getStatResult(response, "dmr", "date", "medianc"); + public void dateMathTest() throws Exception { + String result = (String)getStatResult("dmr", "median", VAL_TYPE.STRING); + String calculated = (String)getStatResult("dmr", "medianc", VAL_TYPE.STRING); assertTrue(result.equals(calculated)); - result = (String)getStatResult(response, "dmr", "date", "max"); - calculated = (String)getStatResult(response, "dmr", "date", "maxc"); + result = (String)getStatResult("dmr", "max", VAL_TYPE.STRING); + calculated = (String)getStatResult("dmr", "maxc", VAL_TYPE.STRING); assertTrue(result.equals(calculated)); } @Test public void constantDateTest() throws Exception { - String result = (String)getStatResult(response, "cdr", "date", "median"); - String calculated = (String)getStatResult(response, "cdr", "date", "medianc"); + String result = (String)getStatResult("cdr", "median", VAL_TYPE.STRING); + String calculated = (String)getStatResult("cdr", "medianc", VAL_TYPE.STRING); assertTrue(result.equals(calculated)); - result = (String)getStatResult(response, "cdr", "date", "max"); - calculated = (String)getStatResult(response, "cdr", "date", "maxc"); + result = (String)getStatResult("cdr", "max", VAL_TYPE.STRING); + calculated = (String)getStatResult("cdr", "maxc", VAL_TYPE.STRING); assertTrue(result.equals(calculated)); } @Test public void constantStringTest() throws Exception { - String result = (String)getStatResult(response, "csr", "str", "min"); - String calculated = (String)getStatResult(response, "csr", "str", "minc"); + String result = (String)getStatResult("csr", "min", VAL_TYPE.STRING); + String calculated = (String)getStatResult("csr", "minc", VAL_TYPE.STRING); assertTrue(result.equals(calculated)); - result = (String)getStatResult(response, "csr", "str", "max"); - calculated = (String)getStatResult(response, "csr", "str", "maxc"); + result = (String)getStatResult("csr", "max", VAL_TYPE.STRING); + calculated = (String)getStatResult("csr", "maxc", VAL_TYPE.STRING); assertTrue(result.equals(calculated)); } @Test public void concatenateTest() throws Exception { - String result = (String)getStatResult(response, "cr", "str", "min"); - String calculated = (String)getStatResult(response, "cr", "str", "minc"); + String result = (String)getStatResult("cr", "min", VAL_TYPE.STRING); + String calculated = (String)getStatResult("cr", "minc", VAL_TYPE.STRING); assertTrue(result.equals(calculated)); - result = (String)getStatResult(response, "cr", "str", "max"); - calculated = (String)getStatResult(response, "cr", "str", "maxc"); + result = (String)getStatResult("cr", "max", VAL_TYPE.STRING); + calculated = (String)getStatResult("cr", "maxc", VAL_TYPE.STRING); assertTrue(result.equals(calculated)); } @Test public void reverseTest() throws Exception { - String result = (String)getStatResult(response, "rr", "str", "min"); - String calculated = (String)getStatResult(response, "rr", "str", "minc"); + String result = (String)getStatResult("rr", "min", VAL_TYPE.STRING); + String calculated = (String)getStatResult("rr", "minc", VAL_TYPE.STRING); assertTrue(result.equals(calculated)); - result = (String)getStatResult(response, "rr", "str", "max"); - calculated = (String)getStatResult(response, "rr", "str", "maxc"); + result = (String)getStatResult("rr", "max", VAL_TYPE.STRING); + calculated = (String)getStatResult("rr", "maxc", VAL_TYPE.STRING); assertTrue(result.equals(calculated)); } @Test public void missingTest() throws Exception { - double min = (Double)getStatResult(response, "ms", "double", "min"); - double max = (Double)getStatResult(response, "ms", "double", "max"); + double min = (Double)getStatResult("ms", "min", VAL_TYPE.DOUBLE); + double max = (Double)getStatResult("ms", "max", VAL_TYPE.DOUBLE); Assert.assertEquals((Double)48.0,(Double)max); Assert.assertEquals((Double)1.0,(Double)min); } From 262e0c41909dd94b9c16b598a598e7042c51af57 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Sun, 24 Nov 2013 23:15:51 +0000 Subject: [PATCH 099/223] SOLR-5497: Did not help. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545107 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/solr/cloud/AbstractFullDistribZkTestBase.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java b/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java index 99108455f19..813d9e481c9 100644 --- a/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java +++ b/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java @@ -454,7 +454,7 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes String solrConfigOverride) throws Exception { JettySolrRunner jetty = new JettySolrRunner(getSolrHome(), context, 0, - solrConfigOverride, null, true, getExtraServlets()); + solrConfigOverride, null, false, getExtraServlets()); jetty.setShards(shardList); jetty.setDataDir(getDataDir(dataDir)); jetty.start(); From 56a116aae85741e0bbba99f8835d091f38aac8a7 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Mon, 25 Nov 2013 01:11:51 +0000 Subject: [PATCH 100/223] SOLR-5417: fail if the chaosmonkey runs for over 20 seconds and doesn't kill a jetty git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545125 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java | 2 +- .../org/apache/solr/cloud/ChaosMonkeySafeLeaderTest.java | 2 +- .../src/java/org/apache/solr/cloud/ChaosMonkey.java | 8 +++++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java b/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java index f34ea1f43b7..1161ce38cea 100644 --- a/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java @@ -144,7 +144,7 @@ public class ChaosMonkeyNothingIsSafeTest extends AbstractFullDistribZkTestBase if (RUN_LENGTH != -1) { runLength = RUN_LENGTH; } else { - int[] runTimes = new int[] {5000,6000,10000,15000,15000,30000,30000,45000,90000,120000}; + int[] runTimes = new int[] {5000,6000,10000,15000,25000,30000,30000,45000,90000,120000}; runLength = runTimes[random().nextInt(runTimes.length - 1)]; } diff --git a/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeySafeLeaderTest.java b/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeySafeLeaderTest.java index 67681acd87c..ff09b192fcf 100644 --- a/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeySafeLeaderTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeySafeLeaderTest.java @@ -104,7 +104,7 @@ public class ChaosMonkeySafeLeaderTest extends AbstractFullDistribZkTestBase { if (RUN_LENGTH != -1) { runLength = RUN_LENGTH; } else { - int[] runTimes = new int[] {5000,6000,10000,15000,15000,30000,30000,45000,90000,120000}; + int[] runTimes = new int[] {5000,6000,10000,25000,27000,30000,30000,45000,90000,120000}; runLength = runTimes[random().nextInt(runTimes.length - 1)]; } try { diff --git a/solr/test-framework/src/java/org/apache/solr/cloud/ChaosMonkey.java b/solr/test-framework/src/java/org/apache/solr/cloud/ChaosMonkey.java index 2e2c554beb5..a2bce0e903b 100644 --- a/solr/test-framework/src/java/org/apache/solr/cloud/ChaosMonkey.java +++ b/solr/test-framework/src/java/org/apache/solr/cloud/ChaosMonkey.java @@ -23,6 +23,8 @@ import java.util.Map; import java.util.Random; import java.util.concurrent.atomic.AtomicInteger; +import junit.framework.TestCase; + import org.apache.lucene.util.LuceneTestCase; import org.apache.solr.client.solrj.SolrServer; import org.apache.solr.client.solrj.embedded.JettySolrRunner; @@ -74,7 +76,7 @@ public class ChaosMonkey { private boolean causeConnectionLoss; private boolean aggressivelyKillLeaders; private Map shardToLeaderJetty; - private long startTime; + private volatile long startTime; private Thread monkeyThread; @@ -519,6 +521,10 @@ public class ChaosMonkey { } catch (InterruptedException e) { Thread.currentThread().interrupt(); } + float runtime = (System.currentTimeMillis() - startTime)/1000.0f; + if (runtime > 20 && stops.get() == 0) { + TestCase.fail("The Monkey ran for over 20 seconds and no jetties were stopped - this is worth investigating!"); + } } public int getStarts() { From 2cd275ce2590b4c451dfa238d5f2e350ca572a93 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Mon, 25 Nov 2013 01:27:56 +0000 Subject: [PATCH 101/223] SOLR-5417: make forbidden API's happy git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545128 13f79535-47bb-0310-9956-ffa450edef68 --- .../src/java/org/apache/solr/cloud/ChaosMonkey.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/solr/test-framework/src/java/org/apache/solr/cloud/ChaosMonkey.java b/solr/test-framework/src/java/org/apache/solr/cloud/ChaosMonkey.java index a2bce0e903b..c1128f9bdf0 100644 --- a/solr/test-framework/src/java/org/apache/solr/cloud/ChaosMonkey.java +++ b/solr/test-framework/src/java/org/apache/solr/cloud/ChaosMonkey.java @@ -23,8 +23,6 @@ import java.util.Map; import java.util.Random; import java.util.concurrent.atomic.AtomicInteger; -import junit.framework.TestCase; - import org.apache.lucene.util.LuceneTestCase; import org.apache.solr.client.solrj.SolrServer; import org.apache.solr.client.solrj.embedded.JettySolrRunner; @@ -523,7 +521,7 @@ public class ChaosMonkey { } float runtime = (System.currentTimeMillis() - startTime)/1000.0f; if (runtime > 20 && stops.get() == 0) { - TestCase.fail("The Monkey ran for over 20 seconds and no jetties were stopped - this is worth investigating!"); + LuceneTestCase.fail("The Monkey ran for over 20 seconds and no jetties were stopped - this is worth investigating!"); } } From 88c177ead68a93c31215609813c8399d5baf3b61 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Mon, 25 Nov 2013 01:42:01 +0000 Subject: [PATCH 102/223] SOLR-4711: enable these tests on java 8 git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545131 13f79535-47bb-0310-9956-ffa450edef68 --- .../src/test/org/apache/solr/cloud/CustomCollectionTest.java | 5 ----- .../apache/solr/cloud/hdfs/HdfsUnloadDistributedZkTest.java | 3 --- 2 files changed, 8 deletions(-) diff --git a/solr/core/src/test/org/apache/solr/cloud/CustomCollectionTest.java b/solr/core/src/test/org/apache/solr/cloud/CustomCollectionTest.java index d96d6f90bde..a84c9ea99b3 100644 --- a/solr/core/src/test/org/apache/solr/cloud/CustomCollectionTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/CustomCollectionTest.java @@ -49,14 +49,10 @@ import org.apache.solr.client.solrj.impl.HttpSolrServer; import org.apache.solr.client.solrj.request.QueryRequest; import org.apache.solr.client.solrj.request.UpdateRequest; import org.apache.solr.client.solrj.response.QueryResponse; -import org.apache.solr.common.SolrException; -import org.apache.solr.common.SolrException.ErrorCode; import org.apache.solr.common.cloud.ClusterState; import org.apache.solr.common.cloud.DocCollection; import org.apache.solr.common.cloud.ImplicitDocRouter; import org.apache.solr.common.cloud.Replica; -import org.apache.solr.common.cloud.Slice; -import org.apache.solr.common.cloud.ZkCoreNodeProps; import org.apache.solr.common.cloud.ZkNodeProps; import org.apache.solr.common.cloud.ZkStateReader; import org.apache.solr.common.params.CollectionParams.CollectionAction; @@ -84,7 +80,6 @@ public class CustomCollectionTest extends AbstractFullDistribZkTestBase { @BeforeClass public static void beforeThisClass2() throws Exception { - assumeFalse("FIXME: This test fails under Java 8 all the time, see SOLR-4711", Constants.JRE_IS_MINIMUM_JAVA8); } @Before diff --git a/solr/core/src/test/org/apache/solr/cloud/hdfs/HdfsUnloadDistributedZkTest.java b/solr/core/src/test/org/apache/solr/cloud/hdfs/HdfsUnloadDistributedZkTest.java index bcb758060f3..7f89b79e94a 100644 --- a/solr/core/src/test/org/apache/solr/cloud/hdfs/HdfsUnloadDistributedZkTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/hdfs/HdfsUnloadDistributedZkTest.java @@ -21,7 +21,6 @@ import java.io.File; import java.io.IOException; import org.apache.hadoop.hdfs.MiniDFSCluster; -import org.apache.lucene.util.Constants; import org.apache.lucene.util.LuceneTestCase.Slow; import org.apache.solr.cloud.UnloadDistributedZkTest; import org.junit.AfterClass; @@ -39,8 +38,6 @@ public class HdfsUnloadDistributedZkTest extends UnloadDistributedZkTest { @BeforeClass public static void setupClass() throws Exception { - assumeFalse("FIXME: This test fails under Java 8 all the time, see SOLR-4711", Constants.JRE_IS_MINIMUM_JAVA8); - dfsCluster = HdfsTestUtil.setupClass(new File(TEMP_DIR, HdfsUnloadDistributedZkTest.class.getName() + "_" + System.currentTimeMillis()).getAbsolutePath()); From 4eaf2769ad9668c78180baca0d6a5802a12987e8 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Mon, 25 Nov 2013 02:44:47 +0000 Subject: [PATCH 103/223] tests: boost timeout a bit git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545137 13f79535-47bb-0310-9956-ffa450edef68 --- solr/core/src/test/org/apache/solr/cloud/OverseerTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solr/core/src/test/org/apache/solr/cloud/OverseerTest.java b/solr/core/src/test/org/apache/solr/cloud/OverseerTest.java index d0569eb82fd..68446b36264 100644 --- a/solr/core/src/test/org/apache/solr/cloud/OverseerTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/OverseerTest.java @@ -519,7 +519,7 @@ public class OverseerTest extends SolrTestCaseJ4 { return; } } - Thread.sleep(100); + Thread.sleep(200); } assertEquals("Unexpected shard leader coll:" + collection + " shard:" + shard, expectedCore, (reader.getClusterState().getLeader(collection, shard)!=null)?reader.getClusterState().getLeader(collection, shard).getStr(ZkStateReader.CORE_NAME_PROP):null); From 7d5363964c8af37c03cfbe7c5c8321e5db5f52b7 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Mon, 25 Nov 2013 03:16:26 +0000 Subject: [PATCH 104/223] SOLR-5488: fix forbidden api call git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545143 13f79535-47bb-0310-9956-ffa450edef68 --- .../analytics/AbstractAnalyticsStatsTest.java | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/solr/core/src/test/org/apache/solr/analytics/AbstractAnalyticsStatsTest.java b/solr/core/src/test/org/apache/solr/analytics/AbstractAnalyticsStatsTest.java index 2d7c582c253..7bba1ff98f5 100644 --- a/solr/core/src/test/org/apache/solr/analytics/AbstractAnalyticsStatsTest.java +++ b/solr/core/src/test/org/apache/solr/analytics/AbstractAnalyticsStatsTest.java @@ -25,29 +25,28 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; -import java.util.Locale; import java.util.Scanner; -import org.apache.commons.lang.StringUtils; -import org.apache.lucene.util.LuceneTestCase.SuppressCodecs; -import org.apache.solr.SolrTestCaseJ4; -import org.apache.solr.analytics.util.MedianCalculator; -import org.apache.solr.analytics.util.PercentileCalculator; -import org.apache.solr.request.SolrQueryRequest; - -import com.google.common.collect.ObjectArrays; -import org.apache.solr.util.ExternalPaths; - import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; + +import org.apache.commons.lang.StringUtils; +import org.apache.lucene.util.LuceneTestCase.SuppressCodecs; +import org.apache.solr.SolrTestCaseJ4; +import org.apache.solr.analytics.util.MedianCalculator; +import org.apache.solr.analytics.util.PercentileCalculator; +import org.apache.solr.request.SolrQueryRequest; +import org.apache.solr.util.ExternalPaths; import org.w3c.dom.Document; import org.xml.sax.InputSource; import org.xml.sax.SAXException; +import com.google.common.collect.ObjectArrays; + @SuppressCodecs({"Lucene3x","Lucene40","Lucene41","Lucene42","Appending","Asserting"}) public class AbstractAnalyticsStatsTest extends SolrTestCaseJ4 { @@ -81,7 +80,7 @@ public class AbstractAnalyticsStatsTest extends SolrTestCaseJ4 { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); // never forget this! DocumentBuilder builder = factory.newDocumentBuilder(); - doc = builder.parse(new InputSource(new ByteArrayInputStream(response.getBytes()))); + doc = builder.parse(new InputSource(new ByteArrayInputStream(response.getBytes("UTF-8")))); xPathFact = XPathFactory.newInstance(); } From 9e7b76f893a85b1102a607547926cef33929c72a Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Mon, 25 Nov 2013 06:46:35 +0000 Subject: [PATCH 105/223] tests: have TestLBHttpSolrServer extend SolrTestCaseJ4 so it runs jetty in test mode and is happier git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545161 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/solr/client/solrj/TestLBHttpSolrServer.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/TestLBHttpSolrServer.java b/solr/solrj/src/test/org/apache/solr/client/solrj/TestLBHttpSolrServer.java index b038afb754d..1d272e332db 100644 --- a/solr/solrj/src/test/org/apache/solr/client/solrj/TestLBHttpSolrServer.java +++ b/solr/solrj/src/test/org/apache/solr/client/solrj/TestLBHttpSolrServer.java @@ -39,7 +39,6 @@ import org.apache.solr.client.solrj.impl.HttpSolrServer; import org.apache.solr.client.solrj.impl.LBHttpSolrServer; import org.apache.solr.client.solrj.response.QueryResponse; import org.apache.solr.client.solrj.response.SolrResponseBase; -import org.apache.solr.client.solrj.response.UpdateResponse; import org.apache.solr.common.SolrInputDocument; import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.util.AbstractSolrTestCase; @@ -60,7 +59,7 @@ import com.carrotsearch.randomizedtesting.annotations.ThreadLeakFilters; SolrIgnoredThreadsFilter.class, QuickPatchThreadsFilter.class }) -public class TestLBHttpSolrServer extends LuceneTestCase { +public class TestLBHttpSolrServer extends SolrTestCaseJ4 { private static final Logger log = LoggerFactory .getLogger(TestLBHttpSolrServer.class); SolrInstance[] solr = new SolrInstance[3]; From 5d45ce858ff27af3ecc9380559032ad33c1281d1 Mon Sep 17 00:00:00 2001 From: Shalin Shekhar Mangar Date: Mon, 25 Nov 2013 14:59:29 +0000 Subject: [PATCH 106/223] SOLR-5378: Add dependencies of lucene's expressions module to Solr git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545311 13f79535-47bb-0310-9956-ffa450edef68 --- solr/core/ivy.xml | 3 +++ solr/licenses/antlr-runtime-3.5.jar.sha1 | 1 + .../antlr-runtime-LICENSE-BSD_LIKE.txt | 7 +++++ solr/licenses/antlr-runtime-NOTICE.txt | 1 + solr/licenses/asm-4.1.jar.sha1 | 1 + solr/licenses/asm-LICENSE-BSD_LIKE.txt | 26 +++++++++++++++++++ solr/licenses/asm-NOTICE.txt | 1 + solr/licenses/asm-commons-4.1.jar.sha1 | 1 + .../licenses/asm-commons-LICENSE-BSD_LIKE.txt | 26 +++++++++++++++++++ solr/licenses/asm-commons-NOTICE.txt | 1 + 10 files changed, 68 insertions(+) create mode 100644 solr/licenses/antlr-runtime-3.5.jar.sha1 create mode 100644 solr/licenses/antlr-runtime-LICENSE-BSD_LIKE.txt create mode 100644 solr/licenses/antlr-runtime-NOTICE.txt create mode 100644 solr/licenses/asm-4.1.jar.sha1 create mode 100644 solr/licenses/asm-LICENSE-BSD_LIKE.txt create mode 100644 solr/licenses/asm-NOTICE.txt create mode 100644 solr/licenses/asm-commons-4.1.jar.sha1 create mode 100644 solr/licenses/asm-commons-LICENSE-BSD_LIKE.txt create mode 100644 solr/licenses/asm-commons-NOTICE.txt diff --git a/solr/core/ivy.xml b/solr/core/ivy.xml index 2d165ba8819..06806ff40a6 100644 --- a/solr/core/ivy.xml +++ b/solr/core/ivy.xml @@ -35,6 +35,9 @@ + + + diff --git a/solr/licenses/antlr-runtime-3.5.jar.sha1 b/solr/licenses/antlr-runtime-3.5.jar.sha1 new file mode 100644 index 00000000000..d90b777a4a7 --- /dev/null +++ b/solr/licenses/antlr-runtime-3.5.jar.sha1 @@ -0,0 +1 @@ +0baa82bff19059401e90e1b90020beb9c96305d7 diff --git a/solr/licenses/antlr-runtime-LICENSE-BSD_LIKE.txt b/solr/licenses/antlr-runtime-LICENSE-BSD_LIKE.txt new file mode 100644 index 00000000000..a6e3ad08507 --- /dev/null +++ b/solr/licenses/antlr-runtime-LICENSE-BSD_LIKE.txt @@ -0,0 +1,7 @@ +Copyright (c) 2012 Terence Parr and Sam Harwell +All rights reserved. +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/solr/licenses/antlr-runtime-NOTICE.txt b/solr/licenses/antlr-runtime-NOTICE.txt new file mode 100644 index 00000000000..8d1c8b69c3f --- /dev/null +++ b/solr/licenses/antlr-runtime-NOTICE.txt @@ -0,0 +1 @@ + diff --git a/solr/licenses/asm-4.1.jar.sha1 b/solr/licenses/asm-4.1.jar.sha1 new file mode 100644 index 00000000000..fca9878081d --- /dev/null +++ b/solr/licenses/asm-4.1.jar.sha1 @@ -0,0 +1 @@ +ad568238ee36a820bd6c6806807e8a14ea34684d diff --git a/solr/licenses/asm-LICENSE-BSD_LIKE.txt b/solr/licenses/asm-LICENSE-BSD_LIKE.txt new file mode 100644 index 00000000000..afb064f2f26 --- /dev/null +++ b/solr/licenses/asm-LICENSE-BSD_LIKE.txt @@ -0,0 +1,26 @@ +Copyright (c) 2012 France Télécom +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of the copyright holders nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +THE POSSIBILITY OF SUCH DAMAGE. diff --git a/solr/licenses/asm-NOTICE.txt b/solr/licenses/asm-NOTICE.txt new file mode 100644 index 00000000000..8d1c8b69c3f --- /dev/null +++ b/solr/licenses/asm-NOTICE.txt @@ -0,0 +1 @@ + diff --git a/solr/licenses/asm-commons-4.1.jar.sha1 b/solr/licenses/asm-commons-4.1.jar.sha1 new file mode 100644 index 00000000000..2b534751bf1 --- /dev/null +++ b/solr/licenses/asm-commons-4.1.jar.sha1 @@ -0,0 +1 @@ +f8b86f4ee6e02082f63a658e00eb5506821253c6 diff --git a/solr/licenses/asm-commons-LICENSE-BSD_LIKE.txt b/solr/licenses/asm-commons-LICENSE-BSD_LIKE.txt new file mode 100644 index 00000000000..afb064f2f26 --- /dev/null +++ b/solr/licenses/asm-commons-LICENSE-BSD_LIKE.txt @@ -0,0 +1,26 @@ +Copyright (c) 2012 France Télécom +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of the copyright holders nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +THE POSSIBILITY OF SUCH DAMAGE. diff --git a/solr/licenses/asm-commons-NOTICE.txt b/solr/licenses/asm-commons-NOTICE.txt new file mode 100644 index 00000000000..8d1c8b69c3f --- /dev/null +++ b/solr/licenses/asm-commons-NOTICE.txt @@ -0,0 +1 @@ + From 64c394c714aecea0daafecbfe61916c83f183948 Mon Sep 17 00:00:00 2001 From: Shalin Shekhar Mangar Date: Mon, 25 Nov 2013 15:16:00 +0000 Subject: [PATCH 107/223] SOLR-5378: lucene expressions module's lib directory is not necessary in solr.lucene.libs path git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545318 13f79535-47bb-0310-9956-ffa450edef68 --- solr/common-build.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/solr/common-build.xml b/solr/common-build.xml index c92162b9e93..5d0d8d04aea 100644 --- a/solr/common-build.xml +++ b/solr/common-build.xml @@ -92,7 +92,6 @@ - From 42ead72e6f778d55a3fa9565c79c2a84f7c4466b Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Mon, 25 Nov 2013 16:25:51 +0000 Subject: [PATCH 108/223] tests: mark the control requests in logging output git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545336 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/solr/cloud/AbstractFullDistribZkTestBase.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java b/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java index 813d9e481c9..99c9aec79c2 100644 --- a/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java +++ b/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java @@ -614,6 +614,11 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes @Override protected void indexDoc(SolrInputDocument doc) throws IOException, SolrServerException { + + UpdateRequest req = new UpdateRequest(); + req.add(doc); + req.setParam("CONTROL", "TRUE"); + req.process(controlClient); controlClient.add(doc); // if we wanted to randomly pick a client - but sometimes they may be From 78a40b68fb3b2b69f041a24b770cf9890b267752 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Mon, 25 Nov 2013 18:09:40 +0000 Subject: [PATCH 109/223] tests: remove extra control add from last commit git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545359 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/solr/cloud/AbstractFullDistribZkTestBase.java | 1 - 1 file changed, 1 deletion(-) diff --git a/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java b/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java index 99c9aec79c2..0fcda295689 100644 --- a/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java +++ b/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java @@ -619,7 +619,6 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes req.add(doc); req.setParam("CONTROL", "TRUE"); req.process(controlClient); - controlClient.add(doc); // if we wanted to randomly pick a client - but sometimes they may be // down... From dc147b8ee0c4459e75f8fbc893cda9ee84408656 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Mon, 25 Nov 2013 20:46:17 +0000 Subject: [PATCH 110/223] tests: mark the control requests in logging output for deletes as well git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545399 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/solr/cloud/AbstractFullDistribZkTestBase.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java b/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java index 0fcda295689..6e15ed7d283 100644 --- a/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java +++ b/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java @@ -1375,7 +1375,11 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes Integer delete = deletes.remove(0); try { numDeletes++; - controlClient.deleteById(Integer.toString(delete)); + UpdateRequest req = new UpdateRequest(); + req.deleteById(Integer.toString(delete)); + req.setParam("CONTROL", "TRUE"); + req.process(controlClient); + cloudClient.deleteById(Integer.toString(delete)); } catch (Exception e) { System.err.println("REQUEST FAILED:"); From 295ce29bfb98f0abb9463c5bb2e3a67bec8a44a9 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Mon, 25 Nov 2013 21:14:11 +0000 Subject: [PATCH 111/223] tests: have ChaosMonkeyNothingIsSafeTest start up down nodes at the end so that any final updates won't fail because there is no leader coming git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545409 13f79535-47bb-0310-9956-ffa450edef68 --- .../cloud/ChaosMonkeyNothingIsSafeTest.java | 18 ++++++++++-------- .../solr/cloud/ChaosMonkeySafeLeaderTest.java | 2 +- .../org/apache/solr/cloud/ChaosMonkey.java | 12 +++++++++++- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java b/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java index 1161ce38cea..e4183f027e0 100644 --- a/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java @@ -138,7 +138,7 @@ public class ChaosMonkeyNothingIsSafeTest extends AbstractFullDistribZkTestBase ftIndexThread.start(); } - chaosMonkey.startTheMonkey(true, 10000); + chaosMonkey.startTheMonkey(true, true, 10000); long runLength; if (RUN_LENGTH != -1) { @@ -158,18 +158,13 @@ public class ChaosMonkeyNothingIsSafeTest extends AbstractFullDistribZkTestBase indexThread.safeStop(); } + // start any downed jetties to be sure we still will end up with a leader per shard... + // wait for stop... for (StopableThread indexThread : threads) { indexThread.join(); } - // we expect full throttle fails, but cloud client should not easily fail - for (StopableThread indexThread : threads) { - if (indexThread instanceof StopableIndexingThread && !(indexThread instanceof FullThrottleStopableIndexingThread)) { - assertEquals(0, ((StopableIndexingThread) indexThread).getFails()); - } - } - // try and wait for any replications and what not to finish... Thread.sleep(2000); @@ -190,6 +185,13 @@ public class ChaosMonkeyNothingIsSafeTest extends AbstractFullDistribZkTestBase assertTrue(zkStateReader.getClusterState().getLiveNodes().size() > 0); + // we expect full throttle fails, but cloud client should not easily fail + for (StopableThread indexThread : threads) { + if (indexThread instanceof StopableIndexingThread && !(indexThread instanceof FullThrottleStopableIndexingThread)) { + assertEquals("There were expected update fails", 0, ((StopableIndexingThread) indexThread).getFails()); + } + } + // full throttle thread can // have request fails checkShardConsistency(!runFullThrottle, true); diff --git a/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeySafeLeaderTest.java b/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeySafeLeaderTest.java index ff09b192fcf..5d71fe99b70 100644 --- a/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeySafeLeaderTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeySafeLeaderTest.java @@ -99,7 +99,7 @@ public class ChaosMonkeySafeLeaderTest extends AbstractFullDistribZkTestBase { indexThread.start(); } - chaosMonkey.startTheMonkey(false, 500); + chaosMonkey.startTheMonkey(false, false, 500); long runLength; if (RUN_LENGTH != -1) { runLength = RUN_LENGTH; diff --git a/solr/test-framework/src/java/org/apache/solr/cloud/ChaosMonkey.java b/solr/test-framework/src/java/org/apache/solr/cloud/ChaosMonkey.java index c1128f9bdf0..b9e0561f7ee 100644 --- a/solr/test-framework/src/java/org/apache/solr/cloud/ChaosMonkey.java +++ b/solr/test-framework/src/java/org/apache/solr/cloud/ChaosMonkey.java @@ -435,7 +435,7 @@ public class ChaosMonkey { // synchronously starts and stops shards randomly, unless there is only one // active shard up for a slice or if there is one active and others recovering - public void startTheMonkey(boolean killLeaders, final int roundPauseUpperLimit) { + public void startTheMonkey(boolean killLeaders, final boolean startDeadPool, final int roundPauseUpperLimit) { if (!MONKEY_ENABLED) { monkeyLog("The Monkey is disabled and will not start"); return; @@ -503,6 +503,16 @@ public class ChaosMonkey { monkeyLog("I ran for " + (System.currentTimeMillis() - startTime)/1000.0f + "sec. I stopped " + stops + " and I started " + starts + ". I also expired " + expires.get() + " and caused " + connloss + " connection losses"); + if (startDeadPool) { + // starting down nodes + for (CloudJettyRunner jetty : deadPool) { + try { + if (jetty.jetty.isStopped()) ChaosMonkey.start(jetty.jetty); + } catch (Exception e) { + log.error("", e); + } + } + } } }; monkeyThread.start(); From 728b740edea31c3763d2fbfc9baa09965cdb3cad Mon Sep 17 00:00:00 2001 From: Erick Erickson Date: Mon, 25 Nov 2013 21:59:09 +0000 Subject: [PATCH 112/223] SOLR-5488: Fixing up tests for analytics component git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545417 13f79535-47bb-0310-9956-ffa450edef68 --- .../analytics/requestFiles/functions.txt | 8 +-- .../analytics/requestFiles/noFacets.txt | 2 +- .../apache/solr/analytics/NoFacetTest.java | 3 +- .../util/valuesource/FunctionTest.java | 50 +++++++++++-------- 4 files changed, 34 insertions(+), 29 deletions(-) diff --git a/solr/core/src/test-files/analytics/requestFiles/functions.txt b/solr/core/src/test-files/analytics/requestFiles/functions.txt index 93f4ba56f15..e4930b6ba6b 100644 --- a/solr/core/src/test-files/analytics/requestFiles/functions.txt +++ b/solr/core/src/test-files/analytics/requestFiles/functions.txt @@ -23,10 +23,10 @@ o.nr.s.sumc=sum(neg_i_dd) o.nr.s.mean=mean(neg(long_ld)) o.nr.s.meanc=mean(neg_l_dd) -o.nr.s.sum=sum(abs(neg(int_id))) -o.nr.s.sumc=sum(int_id) -o.nr.s.mean=mean(abs(neg(long_ld))) -o.nr.s.meanc=mean(int_id) +o.avr.s.sum=sum(abs(neg(int_id))) +o.avr.s.sumc=sum(int_id) +o.avr.s.mean=mean(abs(neg(int_id))) +o.avr.s.meanc=mean(int_id) o.cnr.s.sum=sum(const_num(8)) o.cnr.s.sumc=sum(const_8_dd) diff --git a/solr/core/src/test-files/analytics/requestFiles/noFacets.txt b/solr/core/src/test-files/analytics/requestFiles/noFacets.txt index e69b4fe58f2..b3d91638cf8 100644 --- a/solr/core/src/test-files/analytics/requestFiles/noFacets.txt +++ b/solr/core/src/test-files/analytics/requestFiles/noFacets.txt @@ -15,7 +15,7 @@ o.mr.s.double_dd=mean(double_dd) o.str.s.int_id=stddev(int_id) o.str.s.long_ld=stddev(long_ld) -o.st.s.float_fd=stddev(float_fd) +o.str.s.float_fd=stddev(float_fd) o.str.s.double_dd=stddev(double_dd) o.medr.s.int_id=median(int_id) diff --git a/solr/core/src/test/org/apache/solr/analytics/NoFacetTest.java b/solr/core/src/test/org/apache/solr/analytics/NoFacetTest.java index cbaa9a38f5f..0ab1be5c849 100644 --- a/solr/core/src/test/org/apache/solr/analytics/NoFacetTest.java +++ b/solr/core/src/test/org/apache/solr/analytics/NoFacetTest.java @@ -23,7 +23,6 @@ import java.util.List; import org.apache.lucene.util.LuceneTestCase.SuppressCodecs; import org.junit.BeforeClass; -import org.junit.Ignore; import org.junit.Test; @SuppressCodecs({"Lucene3x","Lucene40","Lucene41","Lucene42","Appending","Asserting"}) @@ -208,7 +207,7 @@ public class NoFacetTest extends AbstractAnalyticsStatsTest { assertEquals(doubleResult,doubleTest); } - @Test @Ignore("SOLR-5488") + @Test public void stddevTest() throws Exception { //Int Double intResult = (Double)getStatResult("str", "int_id", VAL_TYPE.DOUBLE); diff --git a/solr/core/src/test/org/apache/solr/analytics/util/valuesource/FunctionTest.java b/solr/core/src/test/org/apache/solr/analytics/util/valuesource/FunctionTest.java index 6037028eb6b..eca83685249 100644 --- a/solr/core/src/test/org/apache/solr/analytics/util/valuesource/FunctionTest.java +++ b/solr/core/src/test/org/apache/solr/analytics/util/valuesource/FunctionTest.java @@ -21,9 +21,7 @@ package org.apache.solr.analytics.util.valuesource; import org.apache.lucene.util.LuceneTestCase.SuppressCodecs; import org.apache.solr.analytics.AbstractAnalyticsStatsTest; import org.apache.solr.analytics.facet.AbstractAnalyticsFacetTest; -import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Ignore; import org.junit.Test; @SuppressCodecs({"Lucene3x","Lucene40","Lucene41","Lucene42","Appending","Asserting"}) @@ -92,32 +90,34 @@ public class FunctionTest extends AbstractAnalyticsStatsTest { double result = (Double)getStatResult("ar", "sum", VAL_TYPE.DOUBLE); double calculated = (Double)getStatResult("ar", "sumc", VAL_TYPE.DOUBLE); assertTrue(result==calculated); + assertEquals("add sum", result, calculated, 0.0); result = (Double)getStatResult("ar", "mean", VAL_TYPE.DOUBLE); calculated = (Double)getStatResult("ar", "meanc", VAL_TYPE.DOUBLE); assertTrue(result==calculated); + assertEquals("add mean", result, calculated, 0.0); } @Test public void multiplyTest() throws Exception { double result = (Double)getStatResult("mr", "sum", VAL_TYPE.DOUBLE); double calculated = (Double)getStatResult("mr", "sumc", VAL_TYPE.DOUBLE); - assertTrue(result==calculated); + assertEquals("multiply sum", result, calculated, 0.0); result = (Double)getStatResult("mr", "mean", VAL_TYPE.DOUBLE); calculated = (Double)getStatResult("mr", "meanc", VAL_TYPE.DOUBLE); - assertTrue(result==calculated); + assertEquals("multiply mean", result, calculated, 0.0); } @Test public void divideTest() throws Exception { Double result = (Double)getStatResult("dr", "sum", VAL_TYPE.DOUBLE); Double calculated = (Double)getStatResult("dr", "sumc", VAL_TYPE.DOUBLE); - assertTrue(result.equals(calculated)); + assertEquals("power sum", result, calculated, 0.0); result = (Double)getStatResult("dr", "mean", VAL_TYPE.DOUBLE); calculated = (Double)getStatResult("dr", "meanc", VAL_TYPE.DOUBLE); - assertTrue(result.equals(calculated)); + assertEquals("power mean", result, calculated, 0.0); } @Test @@ -125,32 +125,35 @@ public class FunctionTest extends AbstractAnalyticsStatsTest { double result = (Double)getStatResult("pr", "sum", VAL_TYPE.DOUBLE); double calculated = (Double)getStatResult("pr", "sumc", VAL_TYPE.DOUBLE); assertTrue(result==calculated); + assertEquals("power sum", result, calculated, 0.0); result = (Double)getStatResult("pr", "mean", VAL_TYPE.DOUBLE); calculated = (Double)getStatResult("pr", "meanc", VAL_TYPE.DOUBLE); assertTrue(result==calculated); + assertEquals("power mean", result, calculated, 0.0); } @Test public void negateTest() throws Exception { double result = (Double)getStatResult("nr", "sum", VAL_TYPE.DOUBLE); double calculated = (Double)getStatResult("nr", "sumc", VAL_TYPE.DOUBLE); - assertTrue(result==calculated); + assertEquals("negate sum", result, calculated, 0.0); result = (Double)getStatResult("nr", "mean", VAL_TYPE.DOUBLE); calculated = (Double)getStatResult("nr", "meanc", VAL_TYPE.DOUBLE); - assertTrue(result==calculated); + assertEquals("negate mean", result, calculated, 0.0); } - @Test @Ignore("SOLR-5488") + @Test public void absoluteValueTest() throws Exception { double result = (Double)getStatResult("avr", "sum", VAL_TYPE.DOUBLE); double calculated = (Double)getStatResult("avr", "sumc", VAL_TYPE.DOUBLE); - assertTrue(result==calculated); + System.out.println(Double.doubleToRawLongBits(result) + " " + Double.doubleToRawLongBits(calculated) ); + assertEquals("absolute values sum", result, calculated, 0.0); result = (Double)getStatResult("avr", "mean", VAL_TYPE.DOUBLE); calculated = (Double)getStatResult("avr", "meanc", VAL_TYPE.DOUBLE); - assertTrue(result==calculated); + assertEquals("absolute values mean", result, calculated, 0.0); } @Test @@ -158,21 +161,23 @@ public class FunctionTest extends AbstractAnalyticsStatsTest { double result = (Double)getStatResult("cnr", "sum", VAL_TYPE.DOUBLE); double calculated = (Double)getStatResult("cnr", "sumc", VAL_TYPE.DOUBLE); assertTrue(result==calculated); + assertEquals("constant sum", result, calculated, 0.0); result = (Double)getStatResult("cnr", "mean", VAL_TYPE.DOUBLE); calculated = (Double)getStatResult("cnr", "meanc", VAL_TYPE.DOUBLE); assertTrue(result==calculated); + assertEquals("constant mean", result, calculated, 0.0); } @Test public void dateMathTest() throws Exception { String result = (String)getStatResult("dmr", "median", VAL_TYPE.STRING); String calculated = (String)getStatResult("dmr", "medianc", VAL_TYPE.STRING); - assertTrue(result.equals(calculated)); + assertEquals("date math median", result, calculated); result = (String)getStatResult("dmr", "max", VAL_TYPE.STRING); calculated = (String)getStatResult("dmr", "maxc", VAL_TYPE.STRING); - assertTrue(result.equals(calculated)); + assertEquals("date math mean", result, calculated); } @Test @@ -180,51 +185,52 @@ public class FunctionTest extends AbstractAnalyticsStatsTest { String result = (String)getStatResult("cdr", "median", VAL_TYPE.STRING); String calculated = (String)getStatResult("cdr", "medianc", VAL_TYPE.STRING); assertTrue(result.equals(calculated)); + assertEquals("constant date median", result, calculated); result = (String)getStatResult("cdr", "max", VAL_TYPE.STRING); calculated = (String)getStatResult("cdr", "maxc", VAL_TYPE.STRING); - assertTrue(result.equals(calculated)); + assertEquals("constant date mean", result, calculated); } @Test public void constantStringTest() throws Exception { String result = (String)getStatResult("csr", "min", VAL_TYPE.STRING); String calculated = (String)getStatResult("csr", "minc", VAL_TYPE.STRING); - assertTrue(result.equals(calculated)); + assertEquals("constant min", result, calculated); result = (String)getStatResult("csr", "max", VAL_TYPE.STRING); calculated = (String)getStatResult("csr", "maxc", VAL_TYPE.STRING); - assertTrue(result.equals(calculated)); + assertEquals("constant max", result, calculated); } @Test public void concatenateTest() throws Exception { String result = (String)getStatResult("cr", "min", VAL_TYPE.STRING); String calculated = (String)getStatResult("cr", "minc", VAL_TYPE.STRING); - assertTrue(result.equals(calculated)); + assertEquals("concat min", result, calculated); result = (String)getStatResult("cr", "max", VAL_TYPE.STRING); calculated = (String)getStatResult("cr", "maxc", VAL_TYPE.STRING); - assertTrue(result.equals(calculated)); + assertEquals("concat max", result, calculated); } @Test public void reverseTest() throws Exception { String result = (String)getStatResult("rr", "min", VAL_TYPE.STRING); String calculated = (String)getStatResult("rr", "minc", VAL_TYPE.STRING); - assertTrue(result.equals(calculated)); + assertEquals("reverse min", result, calculated); result = (String)getStatResult("rr", "max", VAL_TYPE.STRING); calculated = (String)getStatResult("rr", "maxc", VAL_TYPE.STRING); - assertTrue(result.equals(calculated)); + assertEquals("reverse max", result, calculated); } @Test public void missingTest() throws Exception { double min = (Double)getStatResult("ms", "min", VAL_TYPE.DOUBLE); double max = (Double)getStatResult("ms", "max", VAL_TYPE.DOUBLE); - Assert.assertEquals((Double)48.0,(Double)max); - Assert.assertEquals((Double)1.0,(Double)min); + assertEquals("missingTest 1", 48.0d, max, 0.0); + assertEquals("missingTest 2", 1.0d, min, 0.0); } } From 2678a15112d3776b59cfd54c8a0ceaf9e2a4e459 Mon Sep 17 00:00:00 2001 From: Steven Rowe Date: Mon, 25 Nov 2013 22:25:43 +0000 Subject: [PATCH 113/223] Bring IntelliJ configuration up-to-date git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545426 13f79535-47bb-0310-9956-ffa450edef68 --- dev-tools/idea/lucene/benchmark/src/benchmark.iml | 1 + dev-tools/idea/lucene/demo/demo.iml | 2 ++ dev-tools/idea/lucene/facet/facet.iml | 1 + 3 files changed, 4 insertions(+) diff --git a/dev-tools/idea/lucene/benchmark/src/benchmark.iml b/dev-tools/idea/lucene/benchmark/src/benchmark.iml index 6e3d1b7774a..6c1d5581646 100644 --- a/dev-tools/idea/lucene/benchmark/src/benchmark.iml +++ b/dev-tools/idea/lucene/benchmark/src/benchmark.iml @@ -33,5 +33,6 @@ + diff --git a/dev-tools/idea/lucene/demo/demo.iml b/dev-tools/idea/lucene/demo/demo.iml index 50b0bcad843..a200e9f5779 100644 --- a/dev-tools/idea/lucene/demo/demo.iml +++ b/dev-tools/idea/lucene/demo/demo.iml @@ -26,5 +26,7 @@ + + diff --git a/dev-tools/idea/lucene/facet/facet.iml b/dev-tools/idea/lucene/facet/facet.iml index 8da5b5da794..02cbf8f84f1 100644 --- a/dev-tools/idea/lucene/facet/facet.iml +++ b/dev-tools/idea/lucene/facet/facet.iml @@ -15,6 +15,7 @@ + From bf251f501d8f23b5f4bf47ebab4ceb4308c36bbe Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Mon, 25 Nov 2013 22:32:05 +0000 Subject: [PATCH 114/223] We need better testing for SolrCmdDistributor retry logic. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545428 13f79535-47bb-0310-9956-ffa450edef68 --- .../solr/update/SolrCmdDistributor.java | 18 ++- .../solr/update/MockStreamingSolrServers.java | 86 ++++++++++++ .../solr/update/SolrCmdDistributorTest.java | 123 +++++++++++++++--- 3 files changed, 206 insertions(+), 21 deletions(-) create mode 100644 solr/core/src/test/org/apache/solr/update/MockStreamingSolrServers.java diff --git a/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java b/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java index 8c0492e9f6b..26ec0cbde42 100644 --- a/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java +++ b/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java @@ -43,6 +43,9 @@ public class SolrCmdDistributor { private StreamingSolrServers servers; + private int retryPause = 500; + private int maxRetriesOnForward = MAX_RETRIES_ON_FORWARD; + private List allErrors = new ArrayList(); private List errors = new ArrayList(); @@ -54,6 +57,12 @@ public class SolrCmdDistributor { servers = new StreamingSolrServers(updateShardHandler); } + public SolrCmdDistributor(StreamingSolrServers servers, int maxRetriesOnForward, int retryPause) { + this.servers = servers; + this.maxRetriesOnForward = maxRetriesOnForward; + this.retryPause = retryPause; + } + public void finish() { try { servers.blockUntilFinished(); @@ -85,8 +94,7 @@ public class SolrCmdDistributor { // this can happen in certain situations such as shutdown if (isRetry) { - if (rspCode == 404 || rspCode == 403 || rspCode == 503 - || rspCode == 500) { + if (rspCode == 404 || rspCode == 403 || rspCode == 503) { doRetry = true; } @@ -98,14 +106,14 @@ public class SolrCmdDistributor { doRetry = true; } } - if (err.req.retries < MAX_RETRIES_ON_FORWARD && doRetry) { + if (err.req.retries < maxRetriesOnForward && doRetry) { err.req.retries++; SolrException.log(SolrCmdDistributor.log, "forwarding update to " + oldNodeUrl + " failed - retrying ... retries: " + err.req.retries); try { - Thread.sleep(500); + Thread.sleep(retryPause); } catch (InterruptedException e) { Thread.currentThread().interrupt(); log.warn(null, e); @@ -252,7 +260,7 @@ public class SolrCmdDistributor { public static class Error { public Exception e; - public int statusCode; + public int statusCode = -1; public Req req; } diff --git a/solr/core/src/test/org/apache/solr/update/MockStreamingSolrServers.java b/solr/core/src/test/org/apache/solr/update/MockStreamingSolrServers.java new file mode 100644 index 00000000000..681e6b70363 --- /dev/null +++ b/solr/core/src/test/org/apache/solr/update/MockStreamingSolrServers.java @@ -0,0 +1,86 @@ +package org.apache.solr.update; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.IOException; +import java.net.ConnectException; + +import org.apache.solr.client.solrj.SolrRequest; +import org.apache.solr.client.solrj.SolrServer; +import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.common.util.NamedList; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MockStreamingSolrServers extends StreamingSolrServers { + public static Logger log = LoggerFactory + .getLogger(MockStreamingSolrServers.class); + + public enum Exp {CONNECT_EXCEPTION}; + + private volatile Exp exp = null; + + public MockStreamingSolrServers(UpdateShardHandler updateShardHandler) { + super(updateShardHandler); + } + + @Override + public synchronized SolrServer getSolrServer(final SolrCmdDistributor.Req req) { + SolrServer server = super.getSolrServer(req); + return new MockSolrServer(server); + } + + public void setExp(Exp exp) { + this.exp = exp; + } + + private IOException exception() { + switch (exp) { + case CONNECT_EXCEPTION: + return new ConnectException(); + + default: + break; + } + return null; + } + + class MockSolrServer extends SolrServer { + + private SolrServer solrServer; + + public MockSolrServer(SolrServer solrServer) { + this.solrServer = solrServer; + } + + @Override + public NamedList request(SolrRequest request) + throws SolrServerException, IOException { + if (exp != null) { + throw exception(); + } + + return solrServer.request(request); + } + + + @Override + public void shutdown() {} + + } +} diff --git a/solr/core/src/test/org/apache/solr/update/SolrCmdDistributorTest.java b/solr/core/src/test/org/apache/solr/update/SolrCmdDistributorTest.java index 5392c871e4c..d2f5b612637 100644 --- a/solr/core/src/test/org/apache/solr/update/SolrCmdDistributorTest.java +++ b/solr/core/src/test/org/apache/solr/update/SolrCmdDistributorTest.java @@ -30,6 +30,7 @@ import org.apache.lucene.index.LogDocMergePolicy; import org.apache.solr.BaseDistributedSearchTestCase; import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.SolrServer; +import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.embedded.JettySolrRunner; import org.apache.solr.client.solrj.impl.HttpSolrServer; import org.apache.solr.client.solrj.request.LukeRequest; @@ -46,6 +47,7 @@ import org.apache.solr.core.SolrCore; import org.apache.solr.core.SolrEventListener; import org.apache.solr.search.SolrIndexSearcher; import org.apache.solr.servlet.SolrDispatchFilter; +import org.apache.solr.update.MockStreamingSolrServers.Exp; import org.apache.solr.update.SolrCmdDistributor.Error; import org.apache.solr.update.SolrCmdDistributor.Node; import org.apache.solr.update.SolrCmdDistributor.RetryNode; @@ -55,6 +57,9 @@ import org.junit.BeforeClass; import org.xml.sax.SAXException; public class SolrCmdDistributorTest extends BaseDistributedSearchTestCase { + + private AtomicInteger id = new AtomicInteger(); + @BeforeClass public static void beforeClass() throws Exception { @@ -139,7 +144,7 @@ public class SolrCmdDistributorTest extends BaseDistributedSearchTestCase { // add one doc to controlClient AddUpdateCommand cmd = new AddUpdateCommand(null); - cmd.solrDoc = sdoc("id", 1); + cmd.solrDoc = sdoc("id", id.incrementAndGet()); params = new ModifiableSolrParams(); cmdDistrib.distribAdd(cmd, nodes, params); @@ -166,20 +171,21 @@ public class SolrCmdDistributorTest extends BaseDistributedSearchTestCase { // add another 2 docs to control and 3 to client cmdDistrib = new SolrCmdDistributor(updateShardHandler); - cmd.solrDoc = sdoc("id", 2); + cmd.solrDoc = sdoc("id", id.incrementAndGet()); params = new ModifiableSolrParams(); params.set(DistributedUpdateProcessor.COMMIT_END_POINT, true); cmdDistrib.distribAdd(cmd, nodes, params); + int id2 = id.incrementAndGet(); AddUpdateCommand cmd2 = new AddUpdateCommand(null); - cmd2.solrDoc = sdoc("id", 3); + cmd2.solrDoc = sdoc("id", id2); params = new ModifiableSolrParams(); params.set(DistributedUpdateProcessor.COMMIT_END_POINT, true); cmdDistrib.distribAdd(cmd2, nodes, params); AddUpdateCommand cmd3 = new AddUpdateCommand(null); - cmd3.solrDoc = sdoc("id", 4); + cmd3.solrDoc = sdoc("id", id.incrementAndGet()); params = new ModifiableSolrParams(); params.set(DistributedUpdateProcessor.COMMIT_END_POINT, true); @@ -204,8 +210,7 @@ public class SolrCmdDistributorTest extends BaseDistributedSearchTestCase { // now delete doc 2 which is on both control and client1 DeleteUpdateCommand dcmd = new DeleteUpdateCommand(null); - dcmd.id = "2"; - + dcmd.id = Integer.toString(id2); cmdDistrib = new SolrCmdDistributor(updateShardHandler); @@ -239,8 +244,6 @@ public class SolrCmdDistributorTest extends BaseDistributedSearchTestCase { //System.out.println(clients.get(0).request(new LukeRequest())); } - int id = 5; - cmdDistrib = new SolrCmdDistributor(updateShardHandler); int cnt = atLeast(303); @@ -257,7 +260,7 @@ public class SolrCmdDistributorTest extends BaseDistributedSearchTestCase { } AddUpdateCommand c = new AddUpdateCommand(null); - c.solrDoc = sdoc("id", id++); + c.solrDoc = sdoc("id", id.incrementAndGet()); if (nodes.size() > 0) { params = new ModifiableSolrParams(); cmdDistrib.distribAdd(c, nodes, params); @@ -312,15 +315,100 @@ public class SolrCmdDistributorTest extends BaseDistributedSearchTestCase { ((NamedList) resp.get("index")).get("maxDoc")); } + + testMaxRetries(); + testOneRetry(); + testRetryNode(); + } + + private void testMaxRetries() throws IOException { + final MockStreamingSolrServers ss = new MockStreamingSolrServers(updateShardHandler); + SolrCmdDistributor cmdDistrib = new SolrCmdDistributor(ss, 5, 0); + ss.setExp(Exp.CONNECT_EXCEPTION); + ArrayList nodes = new ArrayList(); + final HttpSolrServer solrclient1 = (HttpSolrServer) clients.get(0); + + final AtomicInteger retries = new AtomicInteger(); + ZkNodeProps nodeProps = new ZkNodeProps(ZkStateReader.BASE_URL_PROP, solrclient1.getBaseURL(), ZkStateReader.CORE_NAME_PROP, ""); + RetryNode retryNode = new RetryNode(new ZkCoreNodeProps(nodeProps), null, "collection1", "shard1") { + @Override + public boolean checkRetry() { + retries.incrementAndGet(); + return true; + } + }; + + nodes.add(retryNode); + + AddUpdateCommand cmd = new AddUpdateCommand(null); + cmd.solrDoc = sdoc("id", id.incrementAndGet()); + ModifiableSolrParams params = new ModifiableSolrParams(); + + cmdDistrib.distribAdd(cmd, nodes, params); + cmdDistrib.finish(); + + assertEquals(6, retries.get()); + + assertEquals(1, cmdDistrib.getErrors().size()); + } + + private void testOneRetry() throws Exception { + final HttpSolrServer solrclient = (HttpSolrServer) clients.get(0); + long numFoundBefore = solrclient.query(new SolrQuery("*:*")).getResults() + .getNumFound(); + final MockStreamingSolrServers ss = new MockStreamingSolrServers(updateShardHandler); + SolrCmdDistributor cmdDistrib = new SolrCmdDistributor(ss, 5, 0); + ss.setExp(Exp.CONNECT_EXCEPTION); + ArrayList nodes = new ArrayList(); + + ZkNodeProps nodeProps = new ZkNodeProps(ZkStateReader.BASE_URL_PROP, solrclient.getBaseURL(), + ZkStateReader.CORE_NAME_PROP, ""); + + final AtomicInteger retries = new AtomicInteger(); + nodeProps = new ZkNodeProps(ZkStateReader.BASE_URL_PROP, solrclient.getBaseURL(), ZkStateReader.CORE_NAME_PROP, ""); + RetryNode retryNode = new RetryNode(new ZkCoreNodeProps(nodeProps), null, "collection1", "shard1") { + @Override + public boolean checkRetry() { + ss.setExp(null); + retries.incrementAndGet(); + return true; + } + }; + + + nodes.add(retryNode); + + AddUpdateCommand cmd = new AddUpdateCommand(null); + cmd.solrDoc = sdoc("id", id.incrementAndGet()); + ModifiableSolrParams params = new ModifiableSolrParams(); + + CommitUpdateCommand ccmd = new CommitUpdateCommand(null, false); + cmdDistrib.distribAdd(cmd, nodes, params); + cmdDistrib.distribCommit(ccmd, nodes, params); + cmdDistrib.finish(); + + assertEquals(1, retries.get()); + + + long numFoundAfter = solrclient.query(new SolrQuery("*:*")).getResults() + .getNumFound(); + + // we will get java.net.SocketException: Network is unreachable, which we don't retry on + assertEquals(numFoundBefore + 1, numFoundAfter); + assertEquals(0, cmdDistrib.getErrors().size()); + } + + + private void testRetryNode() throws SolrServerException, IOException { // Test RetryNode - cmdDistrib = new SolrCmdDistributor(updateShardHandler); + SolrCmdDistributor cmdDistrib = new SolrCmdDistributor(updateShardHandler); final HttpSolrServer solrclient = (HttpSolrServer) clients.get(0); long numFoundBefore = solrclient.query(new SolrQuery("*:*")).getResults() .getNumFound(); - nodes = new ArrayList(); + ArrayList nodes = new ArrayList(); - nodeProps = new ZkNodeProps(ZkStateReader.BASE_URL_PROP, "[ff01::114]:33332" + context, ZkStateReader.CORE_NAME_PROP, ""); + ZkNodeProps nodeProps = new ZkNodeProps(ZkStateReader.BASE_URL_PROP, "[ff01::114]:33332" + context, ZkStateReader.CORE_NAME_PROP, ""); RetryNode retryNode = new RetryNode(new ZkCoreNodeProps(nodeProps), null, "collection1", "shard1") { @Override public boolean checkRetry() { @@ -336,13 +424,13 @@ public class SolrCmdDistributorTest extends BaseDistributedSearchTestCase { nodes.add(retryNode); - cmd = new AddUpdateCommand(null); - cmd.solrDoc = sdoc("id", 1111111); - params = new ModifiableSolrParams(); + AddUpdateCommand cmd = new AddUpdateCommand(null); + cmd.solrDoc = sdoc("id", id.incrementAndGet()); + ModifiableSolrParams params = new ModifiableSolrParams(); cmdDistrib.distribAdd(cmd, nodes, params); - ccmd = new CommitUpdateCommand(null, false); + CommitUpdateCommand ccmd = new CommitUpdateCommand(null, false); params = new ModifiableSolrParams(); params.set(DistributedUpdateProcessor.COMMIT_END_POINT, true); cmdDistrib.distribCommit(ccmd, nodes, params); @@ -351,7 +439,10 @@ public class SolrCmdDistributorTest extends BaseDistributedSearchTestCase { long numFoundAfter = solrclient.query(new SolrQuery("*:*")).getResults() .getNumFound(); + // we will get java.net.SocketException: Network is unreachable and then retry assertEquals(numFoundBefore + 1, numFoundAfter); + + assertEquals(0, cmdDistrib.getErrors().size()); } @Override From 59186c5ae7810832b7f28e1f05cf04d357fcadf9 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Mon, 25 Nov 2013 23:00:08 +0000 Subject: [PATCH 115/223] LUCENE-5349: Ivy's resolution cache can easily corrupt and cause premature end of file errors. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545440 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/ivy-settings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lucene/ivy-settings.xml b/lucene/ivy-settings.xml index 3ab31383696..f7b24ad4562 100644 --- a/lucene/ivy-settings.xml +++ b/lucene/ivy-settings.xml @@ -28,7 +28,7 @@ - + From 8f94ae68deba648058450fb8a23f98660130cc96 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Mon, 25 Nov 2013 23:59:40 +0000 Subject: [PATCH 116/223] SOLR-5503: Retry 'forward to leader' requests less aggressively - rather than on IOException, ConnectException. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545464 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 3 +++ .../org/apache/solr/update/SolrCmdDistributor.java | 13 ++++++++++--- .../apache/solr/update/SolrCmdDistributorTest.java | 6 +++--- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 46b28142355..6eb7a008c78 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -151,6 +151,9 @@ Bug Fixes HttpClients and ensure all http connection managers get shutdown. (Mark Miller) +* SOLR-5503: Retry 'forward to leader' requests less aggressively - rather + than on IOException and status 500, ConnectException. (Mark Miller) + Optimizations ---------------------- diff --git a/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java b/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java index 26ec0cbde42..ac124d3877a 100644 --- a/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java +++ b/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java @@ -18,12 +18,14 @@ package org.apache.solr.update; */ import java.io.IOException; +import java.net.ConnectException; import java.util.ArrayList; import java.util.List; import org.apache.solr.client.solrj.SolrServer; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.impl.HttpSolrServer; +import org.apache.solr.client.solrj.impl.HttpSolrServer.RemoteSolrException; import org.apache.solr.client.solrj.request.AbstractUpdateRequest; import org.apache.solr.client.solrj.request.UpdateRequest; import org.apache.solr.common.SolrException; @@ -98,11 +100,16 @@ public class SolrCmdDistributor { doRetry = true; } - // if its an ioexception, lets try again - if (err.e instanceof IOException) { + // if its a connect exception, lets try again + if (err.e instanceof ConnectException) { doRetry = true; } else if (err.e instanceof SolrServerException) { - if (((SolrServerException) err.e).getRootCause() instanceof IOException) { + if (((SolrServerException) err.e).getRootCause() instanceof ConnectException) { + doRetry = true; + } + } else if (err.e instanceof RemoteSolrException) { + Exception cause = (RemoteSolrException) err.e.getCause(); + if (cause != null && cause instanceof ConnectException) { doRetry = true; } } diff --git a/solr/core/src/test/org/apache/solr/update/SolrCmdDistributorTest.java b/solr/core/src/test/org/apache/solr/update/SolrCmdDistributorTest.java index d2f5b612637..b881fb79655 100644 --- a/solr/core/src/test/org/apache/solr/update/SolrCmdDistributorTest.java +++ b/solr/core/src/test/org/apache/solr/update/SolrCmdDistributorTest.java @@ -439,10 +439,10 @@ public class SolrCmdDistributorTest extends BaseDistributedSearchTestCase { long numFoundAfter = solrclient.query(new SolrQuery("*:*")).getResults() .getNumFound(); - // we will get java.net.SocketException: Network is unreachable and then retry - assertEquals(numFoundBefore + 1, numFoundAfter); + // we will get java.net.SocketException: Network is unreachable and not retry + assertEquals(numFoundBefore, numFoundAfter); - assertEquals(0, cmdDistrib.getErrors().size()); + assertEquals(1, cmdDistrib.getErrors().size()); } @Override From ee21f3b465820dcfe8376c4a2e1639d137403004 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Tue, 26 Nov 2013 02:34:46 +0000 Subject: [PATCH 117/223] raise retries a bit - it can take a bit for a new leader to take over git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545512 13f79535-47bb-0310-9956-ffa450edef68 --- .../src/java/org/apache/solr/update/SolrCmdDistributor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java b/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java index ac124d3877a..3cfc1636d84 100644 --- a/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java +++ b/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java @@ -40,7 +40,7 @@ import org.slf4j.LoggerFactory; public class SolrCmdDistributor { - private static final int MAX_RETRIES_ON_FORWARD = 15; + private static final int MAX_RETRIES_ON_FORWARD = 25; public static Logger log = LoggerFactory.getLogger(SolrCmdDistributor.class); private StreamingSolrServers servers; From bc38be3e0708f0d45a5d9cb37c7b96bc5d7ef727 Mon Sep 17 00:00:00 2001 From: Erick Erickson Date: Tue, 26 Nov 2013 02:42:18 +0000 Subject: [PATCH 118/223] SOLR-5488: Fix up test failures for analytics component. Some cleanups suggested by IntelliJ's analysis git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545514 13f79535-47bb-0310-9956-ffa450edef68 --- .../analytics/expression/ExpressionFactory.java | 12 ++++-------- .../statistics/StatsCollectorSupplierFactory.java | 14 +++++++------- .../solr/analytics/facet/FieldFacetTest.java | 9 +++++---- 3 files changed, 16 insertions(+), 19 deletions(-) diff --git a/solr/core/src/java/org/apache/solr/analytics/expression/ExpressionFactory.java b/solr/core/src/java/org/apache/solr/analytics/expression/ExpressionFactory.java index 9dc78d4b031..5da5fb011c3 100644 --- a/solr/core/src/java/org/apache/solr/analytics/expression/ExpressionFactory.java +++ b/solr/core/src/java/org/apache/solr/analytics/expression/ExpressionFactory.java @@ -160,21 +160,17 @@ public class ExpressionFactory { int start = 0; List arguments = new ArrayList(); char[] chars = expression.toCharArray(); - boolean escapedCharacter = false; for (int count = 0; count < expression.length(); count++) { char c = chars[count]; - if (c==',' && stack == 0 && !escapedCharacter) { + if (c==',' && stack == 0) { arguments.add(expression.substring(start, count).replace("\\(","(").replace("\\)",")").replace("\\,",",").trim()); start = count+1; - } else if (c == '(' && !escapedCharacter) { + } else if (c == '(') { stack ++; - } else if (c == ')' && !escapedCharacter) { + } else if (c == ')') { stack --; } else if (c == '\\') { - escapedCharacter=true; - } - if (escapedCharacter) { - escapedCharacter=false; + ; // Do nothing. } } if (stack==0) { diff --git a/solr/core/src/java/org/apache/solr/analytics/statistics/StatsCollectorSupplierFactory.java b/solr/core/src/java/org/apache/solr/analytics/statistics/StatsCollectorSupplierFactory.java index 20d92d470a4..c4dea1b7ab9 100644 --- a/solr/core/src/java/org/apache/solr/analytics/statistics/StatsCollectorSupplierFactory.java +++ b/solr/core/src/java/org/apache/solr/analytics/statistics/StatsCollectorSupplierFactory.java @@ -421,7 +421,7 @@ public class StatsCollectorSupplierFactory { return null; } Object defaultObject; - Class type = delegateSource.getClass(); + ValueSource src = delegateSource; if (delegateSource instanceof FilterFieldSource) { src = ((FilterFieldSource)delegateSource).getRootSource(); @@ -432,6 +432,12 @@ public class StatsCollectorSupplierFactory { } catch (NumberFormatException e) { throw new SolrException(ErrorCode.BAD_REQUEST,"The filter value "+arguments[1]+" cannot be converted into an integer.",e); } + } else if ( src instanceof DateFieldSource || src instanceof MultiDateFunction) { + try { + defaultObject = TrieDateField.parseDate(arguments[1]); + } catch (ParseException e) { + throw new SolrException(ErrorCode.BAD_REQUEST,"The filter value "+arguments[1]+" cannot be converted into a date.",e); + } } else if ( src instanceof LongFieldSource ) { try { defaultObject = new Long(arguments[1]); @@ -451,12 +457,6 @@ public class StatsCollectorSupplierFactory { } catch (NumberFormatException e) { throw new SolrException(ErrorCode.BAD_REQUEST,"The filter value "+arguments[1]+" cannot be converted into a double.",e); } - } else if ( src instanceof DateFieldSource || src instanceof MultiDateFunction) { - try { - defaultObject = TrieDateField.parseDate(arguments[1]); - } catch (ParseException e) { - throw new SolrException(ErrorCode.BAD_REQUEST,"The filter value "+arguments[1]+" cannot be converted into a date.",e); - } } else { defaultObject = arguments[1]; } diff --git a/solr/core/src/test/org/apache/solr/analytics/facet/FieldFacetTest.java b/solr/core/src/test/org/apache/solr/analytics/facet/FieldFacetTest.java index 0a18edc45a2..895c43b6546 100644 --- a/solr/core/src/test/org/apache/solr/analytics/facet/FieldFacetTest.java +++ b/solr/core/src/test/org/apache/solr/analytics/facet/FieldFacetTest.java @@ -1186,11 +1186,12 @@ public class FieldFacetTest extends AbstractAnalyticsFacetTest{ } private boolean checkStddevs(ArrayList list1, ArrayList list2) { - boolean b = true; - for (int i = 0; i Date: Tue, 26 Nov 2013 03:30:40 +0000 Subject: [PATCH 119/223] tests: up get leader timeout default to 2s from 1s git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545530 13f79535-47bb-0310-9956-ffa450edef68 --- .../src/java/org/apache/solr/common/cloud/ZkStateReader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java b/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java index b8e5c83f8ae..28c478e6292 100644 --- a/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java +++ b/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java @@ -497,7 +497,7 @@ public class ZkStateReader { * Get shard leader properties, with retry if none exist. */ public Replica getLeaderRetry(String collection, String shard) throws InterruptedException { - return getLeaderRetry(collection, shard, 1000); + return getLeaderRetry(collection, shard, 2000); } /** From b1e82e75ff4ab2ea6387c0096fee9a8a0727744c Mon Sep 17 00:00:00 2001 From: Shalin Shekhar Mangar Date: Tue, 26 Nov 2013 06:28:06 +0000 Subject: [PATCH 120/223] SOLR-5494: Moving change log entry to bug fixes section git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545551 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 6eb7a008c78..e7353259dcf 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -103,9 +103,6 @@ New Features This is intended to eventually replace the Suggester support through the SpellCheckComponent. (Areek Zillur, Varun Thacker via shalin) -* SOLR-5494: CoreContainer#remove throws NPE rather than returning null when - a SolrCore does not exist in core discovery mode. (Mark Miller) - Bug Fixes ---------------------- @@ -154,6 +151,9 @@ Bug Fixes * SOLR-5503: Retry 'forward to leader' requests less aggressively - rather than on IOException and status 500, ConnectException. (Mark Miller) +* SOLR-5494: CoreContainer#remove throws NPE rather than returning null when + a SolrCore does not exist in core discovery mode. (Mark Miller) + Optimizations ---------------------- From 0302eeb254479e762f01f4f3c206dfee22f825b6 Mon Sep 17 00:00:00 2001 From: Shalin Shekhar Mangar Date: Tue, 26 Nov 2013 07:02:17 +0000 Subject: [PATCH 121/223] SOLR-5499: Log a warning if /get is not registered when using SolrCloud git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545554 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 3 +++ .../java/org/apache/solr/core/SolrCore.java | 24 ++++++++++++------- .../java/org/apache/solr/update/PeerSync.java | 3 ++- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index e7353259dcf..142b1c06448 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -177,6 +177,9 @@ Other Changes * SOLR-5487: Replication factor error message doesn't match constraint. (Patrick Hunt via shalin) +* SOLR-5499: Log a warning if /get is not registered when using SolrCloud. + (Daniel Collins via shalin) + ================== 4.6.0 ================== Versions of Major Components diff --git a/solr/core/src/java/org/apache/solr/core/SolrCore.java b/solr/core/src/java/org/apache/solr/core/SolrCore.java index 3ebd68edb16..ddc1723f766 100644 --- a/solr/core/src/java/org/apache/solr/core/SolrCore.java +++ b/solr/core/src/java/org/apache/solr/core/SolrCore.java @@ -770,7 +770,7 @@ public final class SolrCore implements SolrInfoMBean { updateProcessorChains = loadUpdateProcessorChains(); reqHandlers = new RequestHandlers(this); reqHandlers.initHandlersFromConfig(solrConfig); - + // Handle things that should eventually go away initDeprecatedSupport(); @@ -854,13 +854,21 @@ public final class SolrCore implements SolrInfoMBean { CoreContainer cc = cd.getCoreContainer(); - if (cc != null && cc.isZooKeeperAware() && Slice.CONSTRUCTION.equals(cd.getCloudDescriptor().getShardState())) { - // set update log to buffer before publishing the core - getUpdateHandler().getUpdateLog().bufferUpdates(); - - cd.getCloudDescriptor().setShardState(null); - cd.getCloudDescriptor().setShardRange(null); - cd.getCloudDescriptor().setShardParent(null); + if (cc != null && cc.isZooKeeperAware()) { + SolrRequestHandler realtimeGetHandler = reqHandlers.get("/get"); + if (realtimeGetHandler == null) { + log.warn("WARNING: RealTimeGetHandler is not registered at /get. " + + "SolrCloud will always use full index replication instead of the more efficient PeerSync method."); + } + + if (Slice.CONSTRUCTION.equals(cd.getCloudDescriptor().getShardState())) { + // set update log to buffer before publishing the core + getUpdateHandler().getUpdateLog().bufferUpdates(); + + cd.getCloudDescriptor().setShardState(null); + cd.getCloudDescriptor().setShardRange(null); + cd.getCloudDescriptor().setShardParent(null); + } } // For debugging // numOpens.incrementAndGet(); diff --git a/solr/core/src/java/org/apache/solr/update/PeerSync.java b/solr/core/src/java/org/apache/solr/update/PeerSync.java index 543042c3bd1..57f8e74f761 100644 --- a/solr/core/src/java/org/apache/solr/update/PeerSync.java +++ b/solr/core/src/java/org/apache/solr/update/PeerSync.java @@ -305,7 +305,8 @@ public class PeerSync { } if (cantReachIsSuccess && sreq.purpose == 1 && srsp.getException() instanceof SolrException && ((SolrException) srsp.getException()).code() == 404) { - log.warn(msg() + " got a 404 from " + srsp.getShardAddress() + ", counting as success"); + log.warn(msg() + " got a 404 from " + srsp.getShardAddress() + ", counting as success. " + + "Perhaps /get is not registered?"); return true; } // TODO: at least log??? From 765f907be1129ad27d7adbbb45685be941254566 Mon Sep 17 00:00:00 2001 From: Stefan Matheis Date: Tue, 26 Nov 2013 09:41:38 +0000 Subject: [PATCH 122/223] SOLR-5189: Solr 4.x Web UI Log Viewer does not display 'date' column from logs git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545581 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 3 ++ solr/webapp/web/css/styles/logging.css | 38 +++++++++++++++- solr/webapp/web/js/scripts/logging.js | 63 ++++++++++++++++++++++++-- 3 files changed, 100 insertions(+), 4 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 142b1c06448..50ecba43086 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -162,6 +162,9 @@ Optimizations * SOLR-5436: Eliminate the 1500ms wait in overseer loop as well as polling the ZK distributed queue. (Noble Paul, Mark Miller) +* SOLR-5189: Solr 4.x Web UI Log Viewer does not display 'date' column from + logs (steffkes) + Other Changes --------------------- diff --git a/solr/webapp/web/css/styles/logging.css b/solr/webapp/web/css/styles/logging.css index 86a835f51fd..6d309575de7 100644 --- a/solr/webapp/web/css/styles/logging.css +++ b/solr/webapp/web/css/styles/logging.css @@ -41,12 +41,48 @@ limitations under the License. position: relative; } +#content #logging #viewer time +{ + white-space: pre; +} + +#content #logging #viewer #footer +{ + margin-top: 20px; +} + #content #logging #viewer #state { background-position: 0 50%; + float: left; color: #c0c0c0; - margin-top: 20px; padding-left: 21px; + width: 45%; +} + +#content #logging #viewer #date-format +{ + float: right; +} + +#content #logging #viewer #date-format a +{ + background-image: url( ../../img/ico/ui-check-box-uncheck.png ); + background-position: 0 50%; + color: #c0c0c0; + display: block; + padding-left: 21px; +} + +#content #logging #viewer #date-format a:hover +{ + color: #008; +} + +#content #logging #viewer #date-format a.on +{ + background-image: url( ../../img/ico/ui-check-box.png ); + color: #333; } #content #logging #viewer table diff --git a/solr/webapp/web/js/scripts/logging.js b/solr/webapp/web/js/scripts/logging.js index 05f61b3f318..84faeacfd97 100644 --- a/solr/webapp/web/js/scripts/logging.js +++ b/solr/webapp/web/js/scripts/logging.js @@ -16,6 +16,7 @@ */ var loglevel_path = app.config.solr_path + '/admin/info/logging'; +var cookie_logging_timezone = 'logging_timezone'; var frame_element = null; var logging_handler = function( response, text_status, xhr ) @@ -253,10 +254,17 @@ var logging_handler = function( response, text_status, xhr ) }; +var format_time_options = {}; + var format_time = function( time ) { time = time ? new Date( time ) : new Date(); - return '' + time.toTimeString().split( ' ' ).shift().esc() + ''; + return '

    ' + "\n" + '' + "\n" + '' + "\n" + - '' + "\n" + + '' + "\n" + '' + "\n" + '' + "\n" + '' + "\n" + @@ -435,7 +443,10 @@ sammy.get '' + "\n" + '' + "\n" + '
    TimeTime (Local)LevelLoggerMessage
    ' + "\n" + - '
     
    ' + "\n" + + '' + "\n" + '
    ' ); @@ -475,6 +486,52 @@ sammy.get return false; } ); + + var date_format = $( '#date-format a', frame_element ); + + date_format + .off( 'click' ) + .on + ( + 'click', + function( event ) + { + var self = $( this ); + + if( !self.hasClass( 'on' ) ) + { + self.addClass( 'on' ); + $( 'table th.time span', frame_element ).text( 'UTC' ); + format_time_options.timeZone = 'UTC'; + $.cookie( cookie_logging_timezone, 'UTC' ); + } + else + { + self.removeClass( 'on' ); + $( 'table th.time span', frame_element ).text( 'Local' ); + delete format_time_options.timeZone; + $.cookie( cookie_logging_timezone, null ); + } + + $( 'time', frame_element ) + .each + ( + function( index, element ) + { + var self = $( element ); + self.text( format_time_content( new Date( self.attr( 'datetime' ) ) ) ); + } + ) + + return false; + } + ); + + if( 'UTC' === $.cookie( cookie_logging_timezone ) ) + { + date_format + .trigger( 'click' ); + } } ); } From 9db2e666e204d599996d652a90fe2b2e80347b60 Mon Sep 17 00:00:00 2001 From: Erick Erickson Date: Tue, 26 Nov 2013 13:25:20 +0000 Subject: [PATCH 123/223] SOLR-5488: Revamped ExpressionTest to use the DOM parsing in AbstractAnalyticsStatsTest rather than string operations git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545650 13f79535-47bb-0310-9956-ffa450edef68 --- .../analytics/expression/ExpressionTest.java | 362 ++++++++---------- 1 file changed, 169 insertions(+), 193 deletions(-) diff --git a/solr/core/src/test/org/apache/solr/analytics/expression/ExpressionTest.java b/solr/core/src/test/org/apache/solr/analytics/expression/ExpressionTest.java index 9a36d9d7b51..45d86d83715 100644 --- a/solr/core/src/test/org/apache/solr/analytics/expression/ExpressionTest.java +++ b/solr/core/src/test/org/apache/solr/analytics/expression/ExpressionTest.java @@ -17,14 +17,10 @@ package org.apache.solr.analytics.expression; -import java.io.File; -import java.io.FileNotFoundException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Scanner; - +import com.google.common.collect.ObjectArrays; import org.apache.lucene.util.LuceneTestCase.SuppressCodecs; import org.apache.solr.SolrTestCaseJ4; +import org.apache.solr.analytics.AbstractAnalyticsStatsTest; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.schema.TrieDateField; import org.apache.solr.util.DateMathParser; @@ -32,233 +28,213 @@ import org.apache.solr.util.ExternalPaths; import org.junit.BeforeClass; import org.junit.Test; -import com.google.common.collect.ObjectArrays; +import java.io.File; +import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.Scanner; -@SuppressCodecs({"Lucene3x","Lucene40","Lucene41","Lucene42","Appending","Asserting"}) -public class ExpressionTest extends SolrTestCaseJ4 { - static String fileName = "core/src/test-files/analytics/requestFiles/expressions.txt"; - - protected static final String[] BASEPARMS = new String[]{ "q", "*:*", "indent", "true", "stats", "true", "olap", "true", "rows", "0" }; - protected static final HashMap defaults = new HashMap(); +@SuppressCodecs({"Lucene3x", "Lucene40", "Lucene41", "Lucene42", "Appending", "Asserting"}) +public class ExpressionTest extends AbstractAnalyticsStatsTest { + private static final String fileName = "core/src/test-files/analytics/requestFiles/expressions.txt"; + + private static final String[] BASEPARMS = new String[]{"q", "*:*", "indent", "true", "stats", "true", "olap", "true", "rows", "0"}; + + private static final int INT = 71; + private static final int LONG = 36; + private static final int FLOAT = 93; + private static final int DOUBLE = 49; + private static final int DATE = 12; + private static final int STRING = 28; + private static final int NUM_LOOPS = 100; - static public final int INT = 71; - static public final int LONG = 36; - static public final int FLOAT = 93; - static public final int DOUBLE = 49; - static public final int DATE = 12; - static public final int STRING = 28; - static public final int NUM_LOOPS = 100; - - static String response; @BeforeClass public static void beforeClass() throws Exception { - initCore("solrconfig-basic.xml","schema-analytics.xml"); + initCore("solrconfig-basic.xml", "schema-analytics.xml"); h.update("*:*"); - + for (int j = 0; j < NUM_LOOPS; ++j) { - int i = j%INT; - long l = j%LONG; - float f = j%FLOAT; - double d = j%DOUBLE; - String dt = (1800+j%DATE) + "-12-31T23:59:59Z"; - String s = "str" + (j%STRING); - assertU(adoc("id", "1000" + j, "int_id", "" + i, "long_ld", "" + l, "float_fd", "" + f, - "double_dd", "" + d, "date_dtd", dt, "string_sd", s)); - + int i = j % INT; + long l = j % LONG; + float f = j % FLOAT; + double d = j % DOUBLE; + String dt = (1800 + j % DATE) + "-12-31T23:59:59Z"; + String s = "str" + (j % STRING); + assertU(adoc("id", "1000" + j, "int_id", "" + i, "long_ld", "" + l, "float_fd", "" + f, + "double_dd", "" + d, "date_dtd", dt, "string_sd", s)); + if (usually()) { commit(); // to have several segments } } - - assertU(commit()); - - //Sort ascending tests - response = h.query(request(fileToStringArr(fileName))); - } - - @Test - public void addTest() throws Exception { - double sumResult = (Double)getStatResult(response, "ar", "double", "sum"); - double uniqueResult = ((Long)getStatResult(response, "ar", "long", "unique")).doubleValue(); - double result = (Double)getStatResult(response, "ar", "double", "su"); - assertTrue(sumResult+uniqueResult==result); - double meanResult = (Double)getStatResult(response, "ar", "double", "mean"); - double medianResult = (Double)getStatResult(response, "ar", "double", "median"); - double countResult = ((Long)getStatResult(response, "ar", "long", "count")).doubleValue(); - result = (Double)getStatResult(response, "ar", "double", "mcm"); - assertTrue(meanResult+countResult+medianResult==result); - } - - @Test - public void multiplyTest() throws Exception { - double sumResult = (Double)getStatResult(response, "mr", "double", "sum"); - double uniqueResult = ((Long)getStatResult(response, "mr", "long", "unique")).doubleValue(); - double result = (Double)getStatResult(response, "mr", "double", "su"); - assertTrue(sumResult*uniqueResult==result); - - double meanResult = (Double)getStatResult(response, "mr", "double", "mean"); - double medianResult = (Double)getStatResult(response, "mr", "double", "median"); - double countResult = ((Long)getStatResult(response, "mr", "long", "count")).doubleValue(); - result = (Double)getStatResult(response, "mr", "double", "mcm"); - assertTrue(meanResult*countResult*medianResult==result); - } - - @Test - public void divideTest() throws Exception { - double sumResult = (Double)getStatResult(response, "dr", "double", "sum"); - double uniqueResult = ((Long)getStatResult(response, "dr", "long", "unique")).doubleValue(); - double result = (Double)getStatResult(response, "dr", "double", "su"); - assertTrue(sumResult/uniqueResult==result); - - double meanResult = (Double)getStatResult(response, "dr", "double", "mean"); - double countResult = ((Long)getStatResult(response, "dr", "long", "count")).doubleValue(); - result = (Double)getStatResult(response, "dr", "double", "mc"); - assertTrue(meanResult/countResult==result); - } - - @Test - public void powerTest() throws Exception { - double sumResult = (Double)getStatResult(response, "pr", "double", "sum"); - double uniqueResult = ((Long)getStatResult(response, "pr", "long", "unique")).doubleValue(); - double result = (Double)getStatResult(response, "pr", "double", "su"); - assertTrue(Math.pow(sumResult,uniqueResult)==result); - - double meanResult = (Double)getStatResult(response, "pr", "double", "mean"); - double countResult = ((Long)getStatResult(response, "pr", "long", "count")).doubleValue(); - result = (Double)getStatResult(response, "pr", "double", "mc"); - assertTrue(Math.pow(meanResult,countResult)==result); - } - - @Test - public void negateTest() throws Exception { - double sumResult = (Double)getStatResult(response, "nr", "double", "sum"); - double result = (Double)getStatResult(response, "nr", "double", "s"); - assertTrue(-1*sumResult==result); + assertU(commit()); - double countResult = ((Long)getStatResult(response, "nr", "long", "count")).doubleValue(); - result = (Double)getStatResult(response, "nr", "double", "c"); - assertTrue(-1*countResult==result); + setResponse(h.query(request(fileToStringArr(fileName)))); } - - @Test - public void absoluteValueTest() throws Exception { - double sumResult = (Double)getStatResult(response, "avr", "double", "sum"); - double result = (Double)getStatResult(response, "avr", "double", "s"); - assertTrue(sumResult==result); - double countResult = ((Long)getStatResult(response, "avr", "long", "count")).doubleValue(); - result = (Double)getStatResult(response, "avr", "double", "c"); - assertTrue(countResult==result); - } - @Test - public void constantNumberTest() throws Exception { - double result = (Double)getStatResult(response, "cnr", "double", "c8"); - assertTrue(8==result); + public void addTest() throws Exception { + double sumResult = (Double) getStatResult("ar", "sum", VAL_TYPE.DOUBLE); + double uniqueResult = ((Long) getStatResult("ar", "unique", VAL_TYPE.LONG)).doubleValue(); + double result = (Double) getStatResult("ar", "su", VAL_TYPE.DOUBLE); + assertEquals(sumResult + uniqueResult, result, 0.0); - result = (Double)getStatResult(response, "cnr", "double", "c10"); - assertTrue(10==result); + double meanResult = (Double) getStatResult("ar", "mean", VAL_TYPE.DOUBLE); + double medianResult = (Double) getStatResult("ar", "median", VAL_TYPE.DOUBLE); + double countResult = ((Long) getStatResult("ar", "count", VAL_TYPE.LONG)).doubleValue(); + result = (Double) getStatResult("ar", "mcm", VAL_TYPE.DOUBLE); + assertEquals(meanResult + countResult + medianResult, result, 0.0); } - + + @Test + public void multiplyTest() throws Exception { + double sumResult = (Double) getStatResult("mr", "sum", VAL_TYPE.DOUBLE); + double uniqueResult = ((Long) getStatResult("mr", "unique", VAL_TYPE.LONG)).doubleValue(); + double result = (Double) getStatResult("mr", "su", VAL_TYPE.DOUBLE); + assertEquals(sumResult * uniqueResult, result, 0.0); + + double meanResult = (Double) getStatResult("mr", "mean", VAL_TYPE.DOUBLE); + double medianResult = (Double) getStatResult("mr", "median", VAL_TYPE.DOUBLE); + double countResult = ((Long) getStatResult("mr", "count", VAL_TYPE.LONG)).doubleValue(); + result = (Double) getStatResult("mr", "mcm", VAL_TYPE.DOUBLE); + assertEquals(meanResult * countResult * medianResult, result, 0.0); + } + + @Test + public void divideTest() throws Exception { + double sumResult = (Double) getStatResult("dr", "sum", VAL_TYPE.DOUBLE); + double uniqueResult = ((Long) getStatResult("dr", "unique", VAL_TYPE.LONG)).doubleValue(); + double result = (Double) getStatResult("dr", "su", VAL_TYPE.DOUBLE); + assertEquals(sumResult / uniqueResult, result, 0.0); + + double meanResult = (Double) getStatResult("dr", "mean", VAL_TYPE.DOUBLE); + double countResult = ((Long) getStatResult("dr", "count", VAL_TYPE.LONG)).doubleValue(); + result = (Double) getStatResult("dr", "mc", VAL_TYPE.DOUBLE); + assertEquals(meanResult / countResult, result, 0.0); + } + + @Test + public void powerTest() throws Exception { + double sumResult = (Double) getStatResult("pr", "sum", VAL_TYPE.DOUBLE); + double uniqueResult = ((Long) getStatResult("pr", "unique", VAL_TYPE.LONG)).doubleValue(); + double result = (Double) getStatResult("pr", "su", VAL_TYPE.DOUBLE); + assertEquals(Math.pow(sumResult, uniqueResult), result, 0.0); + + double meanResult = (Double) getStatResult("pr", "mean", VAL_TYPE.DOUBLE); + double countResult = ((Long) getStatResult("pr", "count", VAL_TYPE.LONG)).doubleValue(); + result = (Double) getStatResult("pr", "mc", VAL_TYPE.DOUBLE); + assertEquals(Math.pow(meanResult, countResult), result, 0.0); + } + + @Test + public void negateTest() throws Exception { + double sumResult = (Double) getStatResult("nr", "sum", VAL_TYPE.DOUBLE); + double result = (Double) getStatResult("nr", "s", VAL_TYPE.DOUBLE); + assertEquals(-1 * sumResult, result, 0.0); + + double countResult = ((Long) getStatResult("nr", "count", VAL_TYPE.LONG)).doubleValue(); + result = (Double) getStatResult("nr", "c", VAL_TYPE.DOUBLE); + assertEquals(-1 * countResult, result, 0.0); + } + + @Test + public void absoluteValueTest() throws Exception { + double sumResult = (Double) getStatResult("avr", "sum", VAL_TYPE.DOUBLE); + double result = (Double) getStatResult("avr", "s", VAL_TYPE.DOUBLE); + assertEquals(sumResult, result, 0.0); + + double countResult = ((Long) getStatResult("avr", "count", VAL_TYPE.LONG)).doubleValue(); + result = (Double) getStatResult("avr", "c", VAL_TYPE.DOUBLE); + assertEquals(countResult, result, 0.0); + } + + @Test + public void constantNumberTest() throws Exception { + double result = (Double) getStatResult("cnr", "c8", VAL_TYPE.DOUBLE); + assertEquals(8, result, 0.0); + + result = (Double) getStatResult("cnr", "c10", VAL_TYPE.DOUBLE); + assertEquals(10, result, 0.0); + } + @SuppressWarnings("deprecation") @Test - public void dateMathTest() throws Exception { - String math = (String)getStatResult(response, "dmr", "str", "cme"); + public void dateMathTest() throws Exception { + String math = (String) getStatResult("dmr", "cme", VAL_TYPE.STRING); DateMathParser date = new DateMathParser(); - date.setNow(TrieDateField.parseDate((String)getStatResult(response, "dmr", "date", "median"))); - String dateMath = (String)getStatResult(response, "dmr", "date", "dmme"); - assertTrue(TrieDateField.parseDate(dateMath).equals(date.parseMath(math))); - - math = (String)getStatResult(response, "dmr", "str", "cma"); + date.setNow(TrieDateField.parseDate((String) getStatResult("dmr", "median", VAL_TYPE.DATE))); + String dateMath = (String) getStatResult("dmr", "dmme", VAL_TYPE.DATE); + assertEquals(TrieDateField.parseDate(dateMath), date.parseMath(math)); + + math = (String) getStatResult("dmr", "cma", VAL_TYPE.STRING); date = new DateMathParser(); - date.setNow(TrieDateField.parseDate((String)getStatResult(response, "dmr", "date", "max"))); - dateMath = (String)getStatResult(response, "dmr", "date", "dmma"); - assertTrue(TrieDateField.parseDate(dateMath).equals(date.parseMath(math))); + date.setNow(TrieDateField.parseDate((String) getStatResult("dmr", "max", VAL_TYPE.DATE))); + dateMath = (String) getStatResult("dmr", "dmma", VAL_TYPE.DATE); + assertEquals(TrieDateField.parseDate(dateMath), date.parseMath(math)); } - - @Test - public void constantDateTest() throws Exception { - String date = (String)getStatResult(response, "cdr", "date", "cd1"); - String str = (String)getStatResult(response, "cdr", "str", "cs1"); - assertTrue(date.equals(str)); - - date = (String)getStatResult(response, "cdr", "date", "cd2"); - str = (String)getStatResult(response, "cdr", "str", "cs2"); - assertTrue(date.equals(str)); - } - - @Test - public void constantStringTest() throws Exception { - String str = (String)getStatResult(response, "csr", "str", "cs1"); - assertTrue(str.equals("this is the first")); - str = (String)getStatResult(response, "csr", "str", "cs2"); - assertTrue(str.equals("this is the second")); - - str = (String)getStatResult(response, "csr", "str", "cs3"); - assertTrue(str.equals("this is the third")); - } - @Test - public void concatenateTest() throws Exception { + public void constantDateTest() throws Exception { + String date = (String) getStatResult("cdr", "cd1", VAL_TYPE.DATE); + String str = (String) getStatResult("cdr", "cs1", VAL_TYPE.STRING); + assertEquals(date, str); + + date = (String) getStatResult("cdr", "cd2", VAL_TYPE.DATE); + str = (String) getStatResult("cdr", "cs2", VAL_TYPE.STRING); + assertEquals(date, str); + } + + @Test + public void constantStringTest() throws Exception { + String str = (String) getStatResult("csr", "cs1", VAL_TYPE.STRING); + assertEquals(str, "this is the first"); + + str = (String) getStatResult("csr", "cs2", VAL_TYPE.STRING); + assertEquals(str, "this is the second"); + + str = (String) getStatResult("csr", "cs3", VAL_TYPE.STRING); + assertEquals(str, "this is the third"); + } + + @Test + public void concatenateTest() throws Exception { StringBuilder builder = new StringBuilder(); - builder.append((String)getStatResult(response, "cr", "str", "csmin")); - builder.append((String)getStatResult(response, "cr", "str", "min")); - String concat = (String)getStatResult(response, "cr", "str", "ccmin"); - assertTrue(concat.equals(builder.toString())); + builder.append((String) getStatResult("cr", "csmin", VAL_TYPE.STRING)); + builder.append((String) getStatResult("cr", "min", VAL_TYPE.STRING)); + String concat = (String) getStatResult("cr", "ccmin", VAL_TYPE.STRING); + assertEquals(concat, builder.toString()); builder.setLength(0); - builder.append((String)getStatResult(response, "cr", "str", "csmax")); - builder.append((String)getStatResult(response, "cr", "str", "max")); - concat = (String)getStatResult(response, "cr", "str", "ccmax"); - assertTrue(concat.equals(builder.toString())); + builder.append((String) getStatResult("cr", "csmax", VAL_TYPE.STRING)); + builder.append((String) getStatResult("cr", "max", VAL_TYPE.STRING)); + concat = (String) getStatResult("cr", "ccmax", VAL_TYPE.STRING); + assertEquals(concat, builder.toString()); } - + @Test - public void reverseTest() throws Exception { + public void reverseTest() throws Exception { StringBuilder builder = new StringBuilder(); - builder.append((String)getStatResult(response, "rr", "str", "min")); - String rev = (String)getStatResult(response, "rr", "str", "rmin"); - assertTrue(rev.equals(builder.reverse().toString())); + builder.append((String) getStatResult("rr", "min", VAL_TYPE.STRING)); + String rev = (String) getStatResult("rr", "rmin", VAL_TYPE.STRING); + assertEquals(rev, builder.reverse().toString()); builder.setLength(0); - builder.append((String)getStatResult(response, "rr", "str", "max")); - rev = (String)getStatResult(response, "rr", "str", "rmax"); - assertTrue(rev.equals(builder.reverse().toString())); + builder.append((String) getStatResult("rr", "max", VAL_TYPE.STRING)); + rev = (String) getStatResult("rr", "rmax", VAL_TYPE.STRING); + assertEquals(rev, builder.reverse().toString()); } - - public Object getStatResult(String response, String request, String type, String name) { - String cat = "\n "; - String begin = "<"+type+" name=\""+name+"\">"; - String end = ""; - int beginInt = response.indexOf(begin, response.indexOf(cat))+begin.length(); - int endInt = response.indexOf(end, beginInt); - String resultStr = response.substring(beginInt, endInt); - if (type.equals("double")) { - return Double.parseDouble(resultStr); - } else if (type.equals("int")) { - return Integer.parseInt(resultStr); - } else if (type.equals("long")) { - return Long.parseLong(resultStr); - } else if (type.equals("float")) { - return Float.parseFloat(resultStr); - } else { - return resultStr; - } + + public static SolrQueryRequest request(String... args) { + return SolrTestCaseJ4.req(ObjectArrays.concat(BASEPARMS, args, String.class)); } - - public static SolrQueryRequest request(String...args){ - return SolrTestCaseJ4.req( ObjectArrays.concat(BASEPARMS, args,String.class) ); - } - + public static String[] fileToStringArr(String fileName) throws FileNotFoundException { Scanner file = new Scanner(new File(ExternalPaths.SOURCE_HOME, fileName), "UTF-8"); ArrayList strList = new ArrayList(); while (file.hasNextLine()) { String line = file.nextLine(); - if (line.length()<2) { + if (line.length() < 2) { continue; } String[] param = line.split("="); From b1a7190dbbc9f33b787b5c16401ca7c075b1e53c Mon Sep 17 00:00:00 2001 From: Shalin Shekhar Mangar Date: Tue, 26 Nov 2013 14:05:12 +0000 Subject: [PATCH 124/223] SOLR-5492: Return the replica that actually served the query in shards.info response git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545662 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 3 +++ .../org/apache/solr/handler/component/QueryComponent.java | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 50ecba43086..4039571ddbc 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -103,6 +103,9 @@ New Features This is intended to eventually replace the Suggester support through the SpellCheckComponent. (Areek Zillur, Varun Thacker via shalin) +* SOLR-5492: Return the replica that actually served the query in shards.info + response. (shalin) + Bug Fixes ---------------------- diff --git a/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java b/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java index cdd5b2d3c6b..0a020569a66 100644 --- a/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java +++ b/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java @@ -813,11 +813,15 @@ public class QueryComponent extends SearchComponent StringWriter trace = new StringWriter(); t.printStackTrace(new PrintWriter(trace)); nl.add("trace", trace.toString() ); + if (srsp.getShardAddress() != null) { + nl.add("shardAddress", srsp.getShardAddress()); + } } else { docs = (SolrDocumentList)srsp.getSolrResponse().getResponse().get("response"); nl.add("numFound", docs.getNumFound()); nl.add("maxScore", docs.getMaxScore()); + nl.add("shardAddress", srsp.getShardAddress()); } if(srsp.getSolrResponse()!=null) { nl.add("time", srsp.getSolrResponse().getElapsedTime()); From 18bcf7fc8252e6b6083147fa18b730c68bd4e0ab Mon Sep 17 00:00:00 2001 From: Steven Rowe Date: Tue, 26 Nov 2013 15:55:10 +0000 Subject: [PATCH 125/223] Fix improperly named module solr-extraction -> solr-cell git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545699 13f79535-47bb-0310-9956-ffa450edef68 --- dev-tools/maven/solr/contrib/extraction/pom.xml.template | 8 ++++---- .../lucene/dependencies/GetMavenDependenciesTask.java | 5 +---- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/dev-tools/maven/solr/contrib/extraction/pom.xml.template b/dev-tools/maven/solr/contrib/extraction/pom.xml.template index c2bb94d937c..51b1ae99692 100644 --- a/dev-tools/maven/solr/contrib/extraction/pom.xml.template +++ b/dev-tools/maven/solr/contrib/extraction/pom.xml.template @@ -58,10 +58,10 @@ solr-test-framework test -@solr-extraction.internal.dependencies@ -@solr-extraction.external.dependencies@ -@solr-extraction.internal.test.dependencies@ -@solr-extraction.external.test.dependencies@ +@solr-cell.internal.dependencies@ +@solr-cell.external.dependencies@ +@solr-cell.internal.test.dependencies@ +@solr-cell.external.test.dependencies@ ${module-path}/src/java diff --git a/lucene/tools/src/java/org/apache/lucene/dependencies/GetMavenDependenciesTask.java b/lucene/tools/src/java/org/apache/lucene/dependencies/GetMavenDependenciesTask.java index 17c88d2074b..e4988201ec0 100644 --- a/lucene/tools/src/java/org/apache/lucene/dependencies/GetMavenDependenciesTask.java +++ b/lucene/tools/src/java/org/apache/lucene/dependencies/GetMavenDependenciesTask.java @@ -622,16 +622,13 @@ public class GetMavenDependenciesTask extends Task { /** * Convert Ant project names to artifact names: prepend "lucene-" - * to Lucene project names; and "solr-cell" -> "solr-extraction" + * to Lucene project names */ private String antProjectToArtifactName(String origModule) { String module = origModule; if ( ! origModule.startsWith("solr-")) { // lucene modules names don't have "lucene-" prepended module = "lucene-" + module; } - if (module.equals("solr-cell")) { - module = "solr-extraction"; - } return module; } From b821c13488d8381811ba755c196ac9e40aeb0b2a Mon Sep 17 00:00:00 2001 From: Steven Rowe Date: Tue, 26 Nov 2013 21:46:11 +0000 Subject: [PATCH 126/223] Handle indirect test-scoped cross-module dependencies; handle multiple artifacts for a single dependency declaration in ivy.xml files; handle solr module names that start with 'solr-' git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1545855 13f79535-47bb-0310-9956-ffa450edef68 --- .../GetMavenDependenciesTask.java | 64 ++++++++++++------- 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/lucene/tools/src/java/org/apache/lucene/dependencies/GetMavenDependenciesTask.java b/lucene/tools/src/java/org/apache/lucene/dependencies/GetMavenDependenciesTask.java index e4988201ec0..b01f81f9cf7 100644 --- a/lucene/tools/src/java/org/apache/lucene/dependencies/GetMavenDependenciesTask.java +++ b/lucene/tools/src/java/org/apache/lucene/dependencies/GetMavenDependenciesTask.java @@ -88,7 +88,7 @@ public class GetMavenDependenciesTask extends Task { private static final String UNWANTED_INTERNAL_DEPENDENCIES = "/(?:test-)?lib/|test-framework/classes/java|/test-files|/resources"; private static final Pattern SHARED_EXTERNAL_DEPENDENCIES_PATTERN - = Pattern.compile("((?:solr|lucene)/(?!test-framework).*)/lib/"); + = Pattern.compile("((?:solr|lucene)/(?!test-framework).*)/((?:test-)?)lib/"); private static final String DEPENDENCY_MANAGEMENT_PROPERTY = "lucene.solr.dependency.management"; private static final String IVY_USER_DIR_PROPERTY = "ivy.default.ivy.user.dir"; @@ -281,10 +281,16 @@ public class GetMavenDependenciesTask extends Task { Set moduleDependencies = interModuleExternalTestScopeDependencies.get(artifactId); if (null != moduleDependencies) { for (String otherArtifactId : moduleDependencies) { + int testScopePos = otherArtifactId.indexOf(":test"); + boolean isTestScope = false; + if (-1 != testScopePos) { + otherArtifactId = otherArtifactId.substring(0, testScopePos); + isTestScope = true; + } SortedSet otherExtDeps = allExternalDependencies.get(otherArtifactId); if (null != otherExtDeps) { for (ExternalDependency otherDep : otherExtDeps) { - if ( ! otherDep.isTestDependency) { + if (otherDep.isTestDependency == isTestScope) { if ( ! deps.contains(otherDep) && ( null == allExternalDependencies.get(artifactId) || ! allExternalDependencies.get(artifactId).contains(otherDep))) { @@ -523,8 +529,10 @@ public class GetMavenDependenciesTask extends Task { matcher = SHARED_EXTERNAL_DEPENDENCIES_PATTERN.matcher(dependency); if (matcher.find()) { String otherArtifactName = matcher.group(1); + boolean isTestScope = null != matcher.group(2) && matcher.group(2).length() > 0; otherArtifactName = otherArtifactName.replace('/', '-'); otherArtifactName = otherArtifactName.replace("lucene-analysis", "lucene-analyzers"); + otherArtifactName = otherArtifactName.replace("solr-contrib-solr-", "solr-"); otherArtifactName = otherArtifactName.replace("solr-contrib-", "solr-"); if ( ! otherArtifactName.equals(artifactName)) { Map> sharedDeps @@ -534,6 +542,9 @@ public class GetMavenDependenciesTask extends Task { sharedSet = new HashSet(); sharedDeps.put(artifactName, sharedSet); } + if (isTestScope) { + otherArtifactName += ":test"; + } sharedSet.add(otherArtifactName); } } @@ -645,34 +656,16 @@ public class GetMavenDependenciesTask extends Task { Document document = documentBuilder.parse(ivyXmlFile); String dependencyPath = "/ivy-module/dependencies/dependency[not(starts-with(@conf,'start->'))]"; NodeList dependencies = (NodeList)xpath.evaluate(dependencyPath, document, XPathConstants.NODESET); - for (int i = 0 ; i < dependencies.getLength() ; ++i) { - Element dependency = (Element)dependencies.item(i); + for (int depNum = 0 ; depNum < dependencies.getLength() ; ++depNum) { + Element dependency = (Element)dependencies.item(depNum); String groupId = dependency.getAttribute("org"); String artifactId = dependency.getAttribute("name"); String dependencyCoordinate = groupId + ':' + artifactId; - String classifier = null; Set classifiers = dependencyClassifiers.get(dependencyCoordinate); if (null == classifiers) { classifiers = new HashSet<>(); dependencyClassifiers.put(dependencyCoordinate, classifiers); } - if (dependency.hasChildNodes()) { - NodeList artifacts = (NodeList)xpath.evaluate("artifact", dependency, XPathConstants.NODESET); - Element firstArtifact = (Element)artifacts.item(0); - if (artifacts.getLength() > 0) { - if ( ! "jar".equals(firstArtifact.getAttribute("type")) - && ! "jar".equals(firstArtifact.getAttribute("ext"))) { - nonJarDependencies.add(dependencyCoordinate); - continue; // ignore non-jar dependencies - } - String mavenClassifier = firstArtifact.getAttribute("maven:classifier"); - if ( ! mavenClassifier.isEmpty()) { - classifier = mavenClassifier; - classifiers.add(classifier); - } - } - } - classifiers.add(classifier); String conf = dependency.getAttribute("conf"); boolean isTestDependency = conf.contains("test"); boolean isOptional = optionalExternalDependencies.contains(dependencyCoordinate); @@ -681,7 +674,30 @@ public class GetMavenDependenciesTask extends Task { deps = new TreeSet(); allExternalDependencies.put(module, deps); } - deps.add(new ExternalDependency(groupId, artifactId, classifier, isTestDependency, isOptional)); + NodeList artifacts = null; + if (dependency.hasChildNodes()) { + artifacts = (NodeList)xpath.evaluate("artifact", dependency, XPathConstants.NODESET); + } + if (null != artifacts && artifacts.getLength() > 0) { + for (int artifactNum = 0 ; artifactNum < artifacts.getLength() ; ++artifactNum) { + Element artifact = (Element)artifacts.item(artifactNum); + String type = artifact.getAttribute("type"); + String ext = artifact.getAttribute("ext"); + if ((type.isEmpty() && ext.isEmpty()) || type.equals("jar") || ext.equals("jar")) { + String classifier = artifact.getAttribute("maven:classifier"); + if (classifier.isEmpty()) { + classifier = null; + } + classifiers.add(classifier); + deps.add(new ExternalDependency(groupId, artifactId, classifier, isTestDependency, isOptional)); + } else { // not a jar + nonJarDependencies.add(dependencyCoordinate); + } + } + } else { + classifiers.add(null); + deps.add(new ExternalDependency(groupId, artifactId, null, isTestDependency, isOptional)); + } } } @@ -771,7 +787,7 @@ public class GetMavenDependenciesTask extends Task { } builder.append('-'); builder.append(matcher.group(4)); - return builder.toString(); + return builder.toString().replace("solr-solr-", "solr-"); } /** From 38643894d1f8caadc4f4fa5deaeb209a2e399e68 Mon Sep 17 00:00:00 2001 From: Erick Erickson Date: Wed, 27 Nov 2013 15:24:24 +0000 Subject: [PATCH 127/223] SOLR-5488: Changing Facets testing to use DOM rather than string operations git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1546074 13f79535-47bb-0310-9956-ffa450edef68 --- .../facet/AbstractAnalyticsFacetTest.java | 143 ++-- .../analytics/facet/FieldFacetExtrasTest.java | 65 +- .../solr/analytics/facet/FieldFacetTest.java | 669 +++++++----------- .../solr/analytics/facet/QueryFacetTest.java | 22 +- .../solr/analytics/facet/RangeFacetTest.java | 94 +-- 5 files changed, 433 insertions(+), 560 deletions(-) diff --git a/solr/core/src/test/org/apache/solr/analytics/facet/AbstractAnalyticsFacetTest.java b/solr/core/src/test/org/apache/solr/analytics/facet/AbstractAnalyticsFacetTest.java index f8af2967772..dba19a8aaa9 100644 --- a/solr/core/src/test/org/apache/solr/analytics/facet/AbstractAnalyticsFacetTest.java +++ b/solr/core/src/test/org/apache/solr/analytics/facet/AbstractAnalyticsFacetTest.java @@ -17,8 +17,10 @@ package org.apache.solr.analytics.facet; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileNotFoundException; +import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -35,6 +37,18 @@ import org.apache.solr.request.SolrQueryRequest; import com.google.common.collect.ObjectArrays; import org.apache.solr.util.ExternalPaths; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; @SuppressCodecs({"Lucene3x","Lucene40","Lucene41","Lucene42","Appending","Asserting"}) public class AbstractAnalyticsFacetTest extends SolrTestCaseJ4 { @@ -42,24 +56,84 @@ public class AbstractAnalyticsFacetTest extends SolrTestCaseJ4 { protected String latestType = ""; - public String getFacetXML(String response, String requestName, String facetType, String facet) { - String cat = "\n "; - String begin = " \n"; - String end = "\n "; - int beginInt = response.indexOf(begin, response.indexOf(cat))+begin.length(); - int endInt = response.indexOf(end, beginInt); - String fieldStr = response.substring(beginInt, endInt); - begin = " "; - end = "\n "; - beginInt = fieldStr.indexOf(begin); - endInt = fieldStr.indexOf(end, beginInt); - String facetStr = ""; - if (beginInt>=0) { - facetStr = fieldStr.substring(beginInt+begin.length(),endInt); - } - return facetStr+" "; + private static Document doc; + private static XPathFactory xPathFact = XPathFactory.newInstance(); + private static String rawResponse; + + protected static void setResponse(String response) throws ParserConfigurationException, IOException, SAXException { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); // never forget this! + DocumentBuilder builder = factory.newDocumentBuilder(); + doc = builder.parse(new InputSource(new ByteArrayInputStream(response.getBytes("UTF-8")))); + xPathFact = XPathFactory.newInstance(); + rawResponse = response; } - + + protected String getRawResponse() { + return rawResponse; + } + + protected Node getNode(String xPath) throws XPathExpressionException { + return (Node)xPathFact.newXPath().compile(xPath).evaluate(doc, XPathConstants.NODE); + } + private NodeList getNodes(String n1, String n2, String n3, String element, String n4) throws XPathExpressionException { + // Construct the XPath expression. The form better not change or all these will fail. + StringBuilder sb = new StringBuilder("/response/lst[@name='stats']/lst[@name='").append(n1).append("']"); + sb.append("/lst[@name='").append(n2).append("']"); + sb.append("/lst[@name='").append(n3).append("']"); + sb.append("//").append(element).append("[@name='").append(n4).append("']"); + return (NodeList)xPathFact.newXPath().compile(sb.toString()).evaluate(doc, XPathConstants.NODESET); + + } + protected ArrayList getStringList(String n1, String n2, String n3, String element, String n4) + throws XPathExpressionException { + ArrayList ret = new ArrayList(); + NodeList nodes = getNodes(n1, n2, n3, element, n4); + for (int idx = 0; idx < nodes.getLength(); ++idx) { + ret.add(nodes.item(idx).getTextContent()); + } + return ret; + } + + protected ArrayList getIntegerList(String n1, String n2, String n3, String element, String n4) + throws XPathExpressionException { + ArrayList ret = new ArrayList(); + NodeList nodes = getNodes(n1, n2, n3, element, n4); + for (int idx = 0; idx < nodes.getLength(); ++idx) { + ret.add(Integer.parseInt(nodes.item(idx).getTextContent())); + } + return ret; + } + protected ArrayList getLongList(String n1, String n2, String n3, String element, String n4) + throws XPathExpressionException { + ArrayList ret = new ArrayList(); + NodeList nodes = getNodes(n1, n2, n3, element, n4); + for (int idx = 0; idx < nodes.getLength(); ++idx) { + ret.add(Long.parseLong(nodes.item(idx).getTextContent())); + } + return ret; + } + protected ArrayList getFloatList(String n1, String n2, String n3, String element, String n4) + throws XPathExpressionException { + ArrayList ret = new ArrayList(); + NodeList nodes = getNodes(n1, n2, n3, element, n4); + for (int idx = 0; idx < nodes.getLength(); ++idx) { + ret.add(Float.parseFloat(nodes.item(idx).getTextContent())); + } + return ret; + } + + protected ArrayList getDoubleList(String n1, String n2, String n3, String element, String n4) + throws XPathExpressionException { + ArrayList ret = new ArrayList(); + NodeList nodes = getNodes(n1, n2, n3, element, n4); + for (int idx = 0; idx < nodes.getLength(); ++idx) { + ret.add(Double.parseDouble(nodes.item(idx).getTextContent())); + } + return ret; + } + + public static void increment(List list, int idx){ Long i = list.remove(idx); list.add(idx, i+1); @@ -84,41 +158,6 @@ public class AbstractAnalyticsFacetTest extends SolrTestCaseJ4 { this.latestType = latestType; } - @SuppressWarnings({ "unchecked", "rawtypes" }) - public ArrayList xmlToList(String facit, String type, String name) { - ArrayList list; - if (type.equals("double")) { - list = new ArrayList(); - } else if (type.equals("int")) { - list = new ArrayList(); - } else if (type.equals("long")) { - list = new ArrayList(); - } else if (type.equals("float")) { - list = new ArrayList(); - } else { - list = new ArrayList(); - } - String find = "<"+type+" name=\""+name+"\">"; - String endS = ""; - int findAt = facit.indexOf(find)+find.length(); - while (findAt>find.length()) { - int end = facit.indexOf(endS, findAt); - if (type.equals("double")) { - list.add(Double.parseDouble(facit.substring(findAt, end))); - } else if (type.equals("int")) { - list.add(Integer.parseInt(facit.substring(findAt, end))); - } else if (type.equals("long")) { - list.add(Long.parseLong(facit.substring(findAt, end))); - } else if (type.equals("float")) { - list.add(Float.parseFloat(facit.substring(findAt, end))); - } else { - list.add(facit.substring(findAt, end)); - } - findAt = facit.indexOf(find, end)+find.length(); - } - return list; - } - @SuppressWarnings({ "unchecked", "rawtypes" }) public > ArrayList calculateNumberStat(ArrayList> lists, String stat) { ArrayList result; diff --git a/solr/core/src/test/org/apache/solr/analytics/facet/FieldFacetExtrasTest.java b/solr/core/src/test/org/apache/solr/analytics/facet/FieldFacetExtrasTest.java index 3c915555515..7c9d740be75 100644 --- a/solr/core/src/test/org/apache/solr/analytics/facet/FieldFacetExtrasTest.java +++ b/solr/core/src/test/org/apache/solr/analytics/facet/FieldFacetExtrasTest.java @@ -45,8 +45,6 @@ public class FieldFacetExtrasTest extends AbstractAnalyticsFacetTest { static ArrayList> intDoubleTestStart; static ArrayList> intStringTestStart; - static String response; - @BeforeClass public static void beforeClass() throws Exception { initCore("solrconfig-basic.xml","schema-analytics.xml"); @@ -106,85 +104,72 @@ public class FieldFacetExtrasTest extends AbstractAnalyticsFacetTest { } assertU(commit()); - response = h.query(request(fileToStringArr(fileName))); + setResponse(h.query(request(fileToStringArr(fileName)))); } @SuppressWarnings("unchecked") @Test public void limitTest() throws Exception { - String longLimit = getFacetXML(response, "lr", "fieldFacets", "long_ld"); - Collection lon = (ArrayList)xmlToList(longLimit, "double", "mean"); - assertEquals(lon.size(),5); - String floatLimit = getFacetXML(response, "lr", "fieldFacets", "float_fd"); - Collection flo = (ArrayList)xmlToList(floatLimit, "double", "median"); - assertEquals(flo.size(),3); - String doubleLimit = getFacetXML(response, "lr", "fieldFacets", "double_dd"); - Collection doub = (ArrayList)xmlToList(doubleLimit, "long", "count"); - assertEquals(doub.size(),7); - String stringLimit = getFacetXML(response, "lr", "fieldFacets", "string_sd"); - Collection string = (ArrayList)xmlToList(stringLimit, "int", "percentile_20"); - assertEquals(string.size(),1); + Collection lon = getDoubleList("lr", "fieldFacets", "long_ld", "double", "mean"); + assertEquals(getRawResponse(), lon.size(),5); + Collection flo = getDoubleList("lr", "fieldFacets", "float_fd", "double", "median"); + assertEquals(getRawResponse(), flo.size(),3); + Collection doub = getLongList("lr", "fieldFacets", "double_dd", "long", "count"); + assertEquals(getRawResponse(), doub.size(),7); + Collection string = getIntegerList("lr", "fieldFacets", "string_sd", "int", "percentile_20"); + assertEquals(getRawResponse(), string.size(),1); } @SuppressWarnings("unchecked") @Test public void offsetTest() throws Exception { - String xml; Collection lon; List all = new ArrayList(); - xml = getFacetXML(response, "off0", "fieldFacets", "long_ld"); - lon = (ArrayList)xmlToList(xml, "double", "mean"); - assertEquals(lon.size(),2); + lon = getDoubleList("off0", "fieldFacets", "long_ld", "double", "mean"); + assertEquals(getRawResponse(), lon.size(),2); assertArrayEquals(new Double[]{ 1.5, 2.0 }, lon.toArray(new Double[0])); all.addAll(lon); - xml = getFacetXML(response, "off1", "fieldFacets", "long_ld"); - lon = (ArrayList)xmlToList(xml, "double", "mean"); - assertEquals(lon.size(),2); + lon = getDoubleList("off1", "fieldFacets", "long_ld", "double", "mean"); + assertEquals(getRawResponse(), lon.size(),2); assertArrayEquals(new Double[]{ 3.0, 4.0 }, lon.toArray(new Double[0])); all.addAll(lon); - xml = getFacetXML(response, "off2", "fieldFacets", "long_ld"); - lon = (ArrayList)xmlToList(xml, "double", "mean"); - assertEquals(lon.size(),3); + lon = getDoubleList("off2", "fieldFacets", "long_ld", "double", "mean"); + assertEquals(getRawResponse(), lon.size(),3); assertArrayEquals(new Double[]{ 5.0, 5.75, 6.0 }, lon.toArray(new Double[0])); all.addAll(lon); - xml = getFacetXML(response, "offAll", "fieldFacets", "long_ld"); - lon = (ArrayList)xmlToList(xml, "double", "mean"); - assertEquals(lon.size(),7); + lon = getDoubleList("offAll", "fieldFacets", "long_ld", "double", "mean"); + assertEquals(getRawResponse(), lon.size(),7); assertArrayEquals(all.toArray(new Double[0]), lon.toArray(new Double[0])); } @SuppressWarnings("unchecked") @Test public void sortTest() throws Exception { - String longSort = getFacetXML(response, "sr", "fieldFacets", "long_ld"); - Collection lon = (ArrayList)xmlToList(longSort, "double", "mean"); + Collection lon = getDoubleList("sr", "fieldFacets", "long_ld", "double", "mean"); ArrayList longTest = calculateNumberStat(intLongTestStart, "mean"); Collections.sort(longTest); - assertEquals(longTest,lon); + assertEquals(getRawResponse(), longTest,lon); - String floatSort = getFacetXML(response, "sr", "fieldFacets", "float_fd"); - Collection flo = (ArrayList)xmlToList(floatSort, "double", "median"); + Collection flo = getDoubleList("sr", "fieldFacets", "float_fd", "double", "median"); ArrayList floatTest = calculateNumberStat(intFloatTestStart, "median"); Collections.sort(floatTest,Collections.reverseOrder()); - assertEquals(floatTest,flo); + assertEquals(getRawResponse(), floatTest,flo); - String doubleSort = getFacetXML(response, "sr", "fieldFacets", "double_dd"); - Collection doub = (ArrayList)xmlToList(doubleSort, "long", "count"); + Collection doub = getLongList("sr", "fieldFacets", "double_dd", "long", "count"); ArrayList doubleTest = (ArrayList)calculateStat(intDoubleTestStart, "count"); Collections.sort(doubleTest); - assertEquals(doubleTest,doub); + assertEquals(getRawResponse(), doubleTest,doub); - String stringSort = getFacetXML(response, "sr", "fieldFacets", "string_sd"); - Collection string = (ArrayList)xmlToList(stringSort, "int", "percentile_20"); + Collection string = getIntegerList("sr", "fieldFacets", "string_sd", "int", "percentile_20"); ArrayList stringTest = (ArrayList)calculateStat(intStringTestStart, "perc_20"); Collections.sort(stringTest,Collections.reverseOrder()); - assertEquals(stringTest,string); + assertEquals(getRawResponse(), stringTest,string); } } diff --git a/solr/core/src/test/org/apache/solr/analytics/facet/FieldFacetTest.java b/solr/core/src/test/org/apache/solr/analytics/facet/FieldFacetTest.java index 895c43b6546..38a3c16e815 100644 --- a/solr/core/src/test/org/apache/solr/analytics/facet/FieldFacetTest.java +++ b/solr/core/src/test/org/apache/solr/analytics/facet/FieldFacetTest.java @@ -85,8 +85,6 @@ public class FieldFacetTest extends AbstractAnalyticsFacetTest{ private static ArrayList> multiDateTestStart; private static ArrayList multiDateTestMissing; - static String response; - @BeforeClass public static void beforeClass() throws Exception { initCore("solrconfig-basic.xml","schema-analytics.xml"); @@ -390,533 +388,445 @@ public class FieldFacetTest extends AbstractAnalyticsFacetTest{ } assertU(commit()); - response = h.query(request(fileToStringArr(fileName))); + setResponse(h.query(request(fileToStringArr(fileName)))); } @SuppressWarnings("unchecked") @Test public void sumTest() throws Exception { //Int Date - String intDateFacet = getFacetXML(response, "sum","fieldFacets", "date_dtd"); - Collection intDate = (ArrayList)xmlToList(intDateFacet, "double", "int"); + Collection intDate = getDoubleList("sum","fieldFacets", "date_dtd", "double", "int"); ArrayList intDateTest = calculateNumberStat(intDateTestStart, "sum"); - assertEquals(intDate,intDateTest); + assertEquals(getRawResponse(),intDate,intDateTest); //Int String - String intStringFacet = getFacetXML(response, "sum","fieldFacets", "string_sd"); - Collection intString = (ArrayList)xmlToList(intStringFacet, "double", "int"); + Collection intString = getDoubleList("sum","fieldFacets", "string_sd", "double", "int"); ArrayList intStringTest = calculateNumberStat(intStringTestStart, "sum"); - assertEquals(intString,intStringTest); + assertEquals(getRawResponse(),intString,intStringTest); //Long Date - String longDateFacet = getFacetXML(response, "sum","fieldFacets", "date_dtd"); - Collection longDate = (ArrayList)xmlToList(longDateFacet, "double", "long"); + Collection longDate = getDoubleList("sum","fieldFacets", "date_dtd", "double", "long"); ArrayList longDateTest = calculateNumberStat(longDateTestStart, "sum"); - assertEquals(longDate,longDateTest); + assertEquals(getRawResponse(),longDate,longDateTest); //Long String - String longStringFacet = getFacetXML(response, "sum","fieldFacets", "string_sd"); - Collection longString = (ArrayList)xmlToList(longStringFacet, "double", "long"); + Collection longString = getDoubleList("sum","fieldFacets", "string_sd", "double", "long"); ArrayList longStringTest = calculateNumberStat(longStringTestStart, "sum"); - assertEquals(longString,longStringTest); + assertEquals(getRawResponse(),longString,longStringTest); //Float Date - String floatDateFacet = getFacetXML(response, "sum","fieldFacets", "date_dtd"); - Collection floatDate = (ArrayList)xmlToList(floatDateFacet, "double", "float"); + Collection floatDate = getDoubleList("sum","fieldFacets", "date_dtd", "double", "float"); ArrayList floatDateTest = calculateNumberStat(floatDateTestStart, "sum"); - assertEquals(floatDate,floatDateTest); + assertEquals(getRawResponse(),floatDate,floatDateTest); //Float String - String floatStringFacet = getFacetXML(response, "sum","fieldFacets", "string_sd"); - Collection floatString = (ArrayList)xmlToList(floatStringFacet, "double", "float"); + Collection floatString = getDoubleList("sum","fieldFacets", "string_sd", "double", "float"); ArrayList floatStringTest = calculateNumberStat(floatStringTestStart, "sum"); - assertEquals(floatString,floatStringTest); + assertEquals(getRawResponse(),floatString,floatStringTest); //Double Date - String doubleDateFacet = getFacetXML(response, "sum","fieldFacets", "date_dtd"); - Collection doubleDate = (ArrayList)xmlToList(doubleDateFacet, "double", "double"); + Collection doubleDate = getDoubleList("sum","fieldFacets", "date_dtd", "double", "double"); ArrayList doubleDateTest = calculateNumberStat(doubleDateTestStart, "sum"); - assertEquals(doubleDate,doubleDateTest); + assertEquals(getRawResponse(),doubleDate,doubleDateTest); //Double String - String doubleStringFacet = getFacetXML(response, "sum","fieldFacets", "string_sd"); - Collection doubleString = (ArrayList)xmlToList(doubleStringFacet, "double", "double"); + Collection doubleString = getDoubleList("sum","fieldFacets", "string_sd", "double", "double"); ArrayList doubleStringTest = calculateNumberStat(doubleStringTestStart, "sum"); - assertEquals(doubleString,doubleStringTest); + assertEquals(getRawResponse(),doubleString,doubleStringTest); } @SuppressWarnings("unchecked") @Test public void meanTest() throws Exception { //Int Date - String intDateFacet = getFacetXML(response, "mean","fieldFacets", "date_dtd"); - Collection intDate = (ArrayList)xmlToList(intDateFacet, "double", "int"); + Collection intDate = getDoubleList("mean","fieldFacets", "date_dtd", "double", "int"); ArrayList intDateTest = calculateNumberStat(intDateTestStart, "mean"); - assertEquals(intDate,intDateTest); + assertEquals(getRawResponse(),intDate,intDateTest); //Int String - String intStringFacet = getFacetXML(response, "mean","fieldFacets", "string_sd"); - Collection intString = (ArrayList)xmlToList(intStringFacet, "double", "int"); + Collection intString = getDoubleList("mean","fieldFacets", "string_sd", "double", "int"); ArrayList intStringTest = calculateNumberStat(intStringTestStart, "mean"); - assertEquals(intString,intStringTest); + assertEquals(getRawResponse(),intString,intStringTest); //Long Date - String longDateFacet = getFacetXML(response, "mean","fieldFacets", "date_dtd"); - Collection longDate = (ArrayList)xmlToList(longDateFacet, "double", "long"); + Collection longDate = getDoubleList("mean","fieldFacets", "date_dtd", "double", "long"); ArrayList longDateTest = calculateNumberStat(longDateTestStart, "mean"); - assertEquals(longDate,longDateTest); + assertEquals(getRawResponse(),longDate,longDateTest); //Long String - String longStringFacet = getFacetXML(response, "mean","fieldFacets", "string_sd"); - Collection longString = (ArrayList)xmlToList(longStringFacet, "double", "long"); + Collection longString = getDoubleList("mean","fieldFacets", "string_sd", "double", "long"); ArrayList longStringTest = calculateNumberStat(longStringTestStart, "mean"); - assertEquals(longString,longStringTest); + assertEquals(getRawResponse(),longString,longStringTest); //Float Date - String floatDateFacet = getFacetXML(response, "mean","fieldFacets", "date_dtd"); - Collection floatDate = (ArrayList)xmlToList(floatDateFacet, "double", "float"); + Collection floatDate = getDoubleList("mean","fieldFacets", "date_dtd", "double", "float"); ArrayList floatDateTest = calculateNumberStat(floatDateTestStart, "mean"); - assertEquals(floatDate,floatDateTest); + assertEquals(getRawResponse(),floatDate,floatDateTest); //Float String - String floatStringFacet = getFacetXML(response, "mean","fieldFacets", "string_sd"); - Collection floatString = (ArrayList)xmlToList(floatStringFacet, "double", "float"); + Collection floatString = getDoubleList("mean","fieldFacets", "string_sd", "double", "float"); ArrayList floatStringTest = calculateNumberStat(floatStringTestStart, "mean"); - assertEquals(floatString,floatStringTest); + assertEquals(getRawResponse(),floatString,floatStringTest); //Double Date - String doubleDateFacet = getFacetXML(response, "mean","fieldFacets", "date_dtd"); - Collection doubleDate = (ArrayList)xmlToList(doubleDateFacet, "double", "double"); + Collection doubleDate = getDoubleList("mean","fieldFacets", "date_dtd", "double", "double"); ArrayList doubleDateTest = calculateNumberStat(doubleDateTestStart, "mean"); - assertEquals(doubleDate,doubleDateTest); + assertEquals(getRawResponse(),doubleDate,doubleDateTest); //Double String - String doubleStringFacet = getFacetXML(response, "mean","fieldFacets", "string_sd"); - Collection doubleString = (ArrayList)xmlToList(doubleStringFacet, "double", "double"); + Collection doubleString = getDoubleList("mean","fieldFacets", "string_sd", "double", "double"); ArrayList doubleStringTest = calculateNumberStat(doubleStringTestStart, "mean"); - assertEquals(doubleString,doubleStringTest); + assertEquals(getRawResponse(),doubleString,doubleStringTest); } @SuppressWarnings("unchecked") @Test public void sumOfSquaresFacetAscTest() throws Exception { //Int Date - String intDateFacet = getFacetXML(response, "sumOfSquares","fieldFacets", "date_dtd"); - Collection intDate = (ArrayList)xmlToList(intDateFacet, "double", "int"); + Collection intDate = getDoubleList("sumOfSquares","fieldFacets", "date_dtd", "double", "int"); ArrayList intDateTest = calculateNumberStat(intDateTestStart, "sumOfSquares"); - assertEquals(intDate,intDateTest); + assertEquals(getRawResponse(),intDate,intDateTest); //Int String - String intStringFacet = getFacetXML(response, "sumOfSquares","fieldFacets", "string_sd"); - Collection intString = (ArrayList)xmlToList(intStringFacet, "double", "int"); + Collection intString = getDoubleList("sumOfSquares","fieldFacets", "string_sd", "double", "int"); ArrayList intStringTest = calculateNumberStat(intStringTestStart, "sumOfSquares"); - assertEquals(intString,intStringTest); + assertEquals(getRawResponse(),intString,intStringTest); //Long Date - String longDateFacet = getFacetXML(response, "sumOfSquares","fieldFacets", "date_dtd"); - Collection longDate = (ArrayList)xmlToList(longDateFacet, "double", "long"); + Collection longDate = getDoubleList("sumOfSquares","fieldFacets", "date_dtd", "double", "long"); ArrayList longDateTest = calculateNumberStat(longDateTestStart, "sumOfSquares"); - assertEquals(longDate,longDateTest); + assertEquals(getRawResponse(),longDate,longDateTest); //Long String - String longStringFacet = getFacetXML(response, "sumOfSquares","fieldFacets", "string_sd"); - Collection longString = (ArrayList)xmlToList(longStringFacet, "double", "long"); + Collection longString = getDoubleList("sumOfSquares","fieldFacets", "string_sd", "double", "long"); ArrayList longStringTest = calculateNumberStat(longStringTestStart, "sumOfSquares"); - assertEquals(longString,longStringTest); + assertEquals(getRawResponse(),longString,longStringTest); //Float Date - String floatDateFacet = getFacetXML(response, "sumOfSquares","fieldFacets", "date_dtd"); - Collection floatDate = (ArrayList)xmlToList(floatDateFacet, "double", "float"); + Collection floatDate = getDoubleList("sumOfSquares","fieldFacets", "date_dtd", "double", "float"); ArrayList floatDateTest = calculateNumberStat(floatDateTestStart, "sumOfSquares"); - assertEquals(floatDate,floatDateTest); + assertEquals(getRawResponse(),floatDate,floatDateTest); //Float String - String floatStringFacet = getFacetXML(response, "sumOfSquares","fieldFacets", "string_sd"); - Collection floatString = (ArrayList)xmlToList(floatStringFacet, "double", "float"); + Collection floatString = getDoubleList("sumOfSquares","fieldFacets", "string_sd", "double", "float"); ArrayList floatStringTest = calculateNumberStat(floatStringTestStart, "sumOfSquares"); - assertEquals(floatString,floatStringTest); + assertEquals(getRawResponse(),floatString,floatStringTest); //Double Date - String doubleDateFacet = getFacetXML(response, "sumOfSquares","fieldFacets", "date_dtd"); - Collection doubleDate = (ArrayList)xmlToList(doubleDateFacet, "double", "double"); + Collection doubleDate = getDoubleList("sumOfSquares","fieldFacets", "date_dtd", "double", "double"); ArrayList doubleDateTest = calculateNumberStat(doubleDateTestStart, "sumOfSquares"); - assertEquals(doubleDate,doubleDateTest); + assertEquals(getRawResponse(),doubleDate,doubleDateTest); //Double String - String doubleStringFacet = getFacetXML(response, "sumOfSquares","fieldFacets", "string_sd"); - Collection doubleString = (ArrayList)xmlToList(doubleStringFacet, "double", "double"); + Collection doubleString = getDoubleList("sumOfSquares","fieldFacets", "string_sd", "double", "double"); ArrayList doubleStringTest = calculateNumberStat(doubleStringTestStart, "sumOfSquares"); - assertEquals(doubleString,doubleStringTest); + assertEquals(getRawResponse(),doubleString,doubleStringTest); } @SuppressWarnings("unchecked") @Test public void stddevFacetAscTest() throws Exception { //Int Date - String intDateFacet = getFacetXML(response, "stddev","fieldFacets", "date_dtd"); - ArrayList intDate = (ArrayList)xmlToList(intDateFacet, "double", "int"); + ArrayList intDate = getDoubleList("stddev","fieldFacets", "date_dtd", "double", "int"); ArrayList intDateTest = calculateNumberStat(intDateTestStart, "stddev"); - assertTrue(checkStddevs(intDate,intDateTest)); + checkStddevs(intDate,intDateTest); //Int String - String intStringFacet = getFacetXML(response, "stddev","fieldFacets", "string_sd"); - ArrayList intString = (ArrayList)xmlToList(intStringFacet, "double", "int"); + ArrayList intString = getDoubleList("stddev","fieldFacets", "string_sd", "double", "int"); ArrayList intStringTest = calculateNumberStat(intStringTestStart, "stddev"); - assertTrue(checkStddevs(intString,intStringTest)); + checkStddevs(intString,intStringTest); //Long Date - String longDateFacet = getFacetXML(response, "stddev","fieldFacets", "date_dtd"); - ArrayList longDate = (ArrayList)xmlToList(longDateFacet, "double", "long"); + ArrayList longDate = getDoubleList("stddev","fieldFacets", "date_dtd", "double", "long"); ArrayList longDateTest = calculateNumberStat(longDateTestStart, "stddev"); - assertTrue(checkStddevs(longDate,longDateTest)); + checkStddevs(longDate,longDateTest); //Long String - String longStringFacet = getFacetXML(response, "stddev","fieldFacets", "string_sd"); - ArrayList longString = (ArrayList)xmlToList(longStringFacet, "double", "long"); + ArrayList longString = getDoubleList("stddev","fieldFacets", "string_sd", "double", "long"); ArrayList longStringTest = calculateNumberStat(longStringTestStart, "stddev"); - assertTrue(checkStddevs(longString,longStringTest)); + checkStddevs(longString,longStringTest); //Float Date - String floatDateFacet = getFacetXML(response, "stddev","fieldFacets", "date_dtd"); - ArrayList floatDate = (ArrayList)xmlToList(floatDateFacet, "double", "float"); + ArrayList floatDate = getDoubleList("stddev","fieldFacets", "date_dtd", "double", "float"); ArrayList floatDateTest = calculateNumberStat(floatDateTestStart, "stddev"); - assertTrue(checkStddevs(floatDate,floatDateTest)); + checkStddevs(floatDate,floatDateTest); //Float String - String floatStringFacet = getFacetXML(response, "stddev","fieldFacets", "string_sd"); - ArrayList floatString = (ArrayList)xmlToList(floatStringFacet, "double", "float"); + ArrayList floatString = getDoubleList("stddev","fieldFacets", "string_sd", "double", "float"); ArrayList floatStringTest = calculateNumberStat(floatStringTestStart, "stddev"); - assertTrue(checkStddevs(floatString,floatStringTest)); + checkStddevs(floatString,floatStringTest); //Double Date - String doubleDateFacet = getFacetXML(response, "stddev","fieldFacets", "date_dtd"); - ArrayList doubleDate = (ArrayList)xmlToList(doubleDateFacet, "double", "double"); + ArrayList doubleDate = getDoubleList("stddev","fieldFacets", "date_dtd", "double", "double"); ArrayList doubleDateTest = calculateNumberStat(doubleDateTestStart, "stddev"); - assertTrue(checkStddevs(doubleDate,doubleDateTest)); + checkStddevs(doubleDate,doubleDateTest); //Double String - String doubleStringFacet = getFacetXML(response, "stddev","fieldFacets", "string_sd"); - ArrayList doubleString = (ArrayList)xmlToList(doubleStringFacet, "double", "double"); + ArrayList doubleString = getDoubleList("stddev","fieldFacets", "string_sd", "double", "double"); ArrayList doubleStringTest = calculateNumberStat(doubleStringTestStart, "stddev"); - assertTrue(checkStddevs(doubleString,doubleStringTest)); + checkStddevs(doubleString,doubleStringTest); } @SuppressWarnings("unchecked") @Test public void medianFacetAscTest() throws Exception { //Int Date - String intDateFacet = getFacetXML(response, "median","fieldFacets", "date_dtd"); - Collection intDate = (ArrayList)xmlToList(intDateFacet, "double", "int"); + Collection intDate = getDoubleList( "median","fieldFacets", "date_dtd", "double", "int"); ArrayList intDateTest = calculateNumberStat(intDateTestStart, "median"); - assertEquals(intDate,intDateTest); + assertEquals(getRawResponse(),intDate,intDateTest); //Int String - String intStringFacet = getFacetXML(response, "median","fieldFacets", "string_sd"); - Collection intString = (ArrayList)xmlToList(intStringFacet, "double", "int"); + Collection intString = getDoubleList("median","fieldFacets", "string_sd", "double", "int"); ArrayList intStringTest = calculateNumberStat(intStringTestStart, "median"); - assertEquals(intString,intStringTest); + assertEquals(getRawResponse(),intString,intStringTest); //Long Date - String longDateFacet = getFacetXML(response, "median","fieldFacets", "date_dtd"); - Collection longDate = (ArrayList)xmlToList(longDateFacet, "double", "long"); + Collection longDate = getDoubleList("median","fieldFacets", "date_dtd", "double", "long"); ArrayList longDateTest = calculateNumberStat(longDateTestStart, "median"); - assertEquals(longDate,longDateTest); + assertEquals(getRawResponse(),longDate,longDateTest); //Long String - String longStringFacet = getFacetXML(response, "median","fieldFacets", "string_sd"); - Collection longString = (ArrayList)xmlToList(longStringFacet, "double", "long"); + Collection longString = getDoubleList("median","fieldFacets", "string_sd", "double", "long"); ArrayList longStringTest = calculateNumberStat(longStringTestStart, "median"); - assertEquals(longString,longStringTest); + assertEquals(getRawResponse(),longString,longStringTest); //Float Date - String floatDateFacet = getFacetXML(response, "median","fieldFacets", "date_dtd"); - Collection floatDate = (ArrayList)xmlToList(floatDateFacet, "double", "float"); + Collection floatDate = getDoubleList("median","fieldFacets", "date_dtd", "double", "float"); ArrayList floatDateTest = calculateNumberStat(floatDateTestStart, "median"); - assertEquals(floatDate,floatDateTest); + assertEquals(getRawResponse(),floatDate,floatDateTest); //Float String - String floatStringFacet = getFacetXML(response, "median","fieldFacets", "string_sd"); - Collection floatString = (ArrayList)xmlToList(floatStringFacet, "double", "float"); + Collection floatString = getDoubleList("median","fieldFacets", "string_sd", "double", "float"); ArrayList floatStringTest = calculateNumberStat(floatStringTestStart, "median"); - assertEquals(floatString,floatStringTest); + assertEquals(getRawResponse(),floatString,floatStringTest); //Double Date - String doubleDateFacet = getFacetXML(response, "median","fieldFacets", "date_dtd"); - Collection doubleDate = (ArrayList)xmlToList(doubleDateFacet, "double", "double"); + Collection doubleDate = getDoubleList("median","fieldFacets", "date_dtd", "double", "double"); ArrayList doubleDateTest = calculateNumberStat(doubleDateTestStart, "median"); - assertEquals(doubleDate,doubleDateTest); + assertEquals(getRawResponse(),doubleDate,doubleDateTest); //Double String - String doubleStringFacet = getFacetXML(response, "median","fieldFacets", "string_sd"); - Collection doubleString = (ArrayList)xmlToList(doubleStringFacet, "double", "double"); + Collection doubleString = getDoubleList("median","fieldFacets", "string_sd", "double", "double"); ArrayList doubleStringTest = calculateNumberStat(doubleStringTestStart, "median"); - assertEquals(doubleString,doubleStringTest); + assertEquals(getRawResponse(),doubleString,doubleStringTest); } @SuppressWarnings("unchecked") @Test public void perc20Test() throws Exception { //Int Date - String intDateFacet = getFacetXML(response, "percentile_20n","fieldFacets", "date_dtd"); - Collection intDate = (ArrayList)xmlToList(intDateFacet, "int", "int"); + Collection intDate = getIntegerList("percentile_20n","fieldFacets", "date_dtd", "int", "int"); ArrayList intDateTest = (ArrayList)calculateStat(intDateTestStart, "perc_20"); - assertEquals(intDate,intDateTest); + assertEquals(getRawResponse(),intDate,intDateTest); //Int String - String intStringFacet = getFacetXML(response, "percentile_20n","fieldFacets", "string_sd"); - Collection intString = (ArrayList)xmlToList(intStringFacet, "int", "int"); + Collection intString = getIntegerList("percentile_20n","fieldFacets", "string_sd", "int", "int"); ArrayList intStringTest = (ArrayList)calculateStat(intStringTestStart, "perc_20"); - assertEquals(intString,intStringTest); + assertEquals(getRawResponse(),intString,intStringTest); //Long Date - String longDateFacet = getFacetXML(response, "percentile_20n","fieldFacets", "date_dtd"); - Collection longDate = (ArrayList)xmlToList(longDateFacet, "long", "long"); + Collection longDate = getLongList("percentile_20n","fieldFacets", "date_dtd", "long", "long"); ArrayList longDateTest = (ArrayList)calculateStat(longDateTestStart, "perc_20"); - assertEquals(longDate,longDateTest); + assertEquals(getRawResponse(),longDate,longDateTest); //Long String - String longStringFacet = getFacetXML(response, "percentile_20n","fieldFacets", "string_sd"); - Collection longString = (ArrayList)xmlToList(longStringFacet, "long", "long"); + Collection longString = getLongList("percentile_20n","fieldFacets", "string_sd", "long", "long"); ArrayList longStringTest = (ArrayList)calculateStat(longStringTestStart, "perc_20"); - assertEquals(longString,longStringTest); + assertEquals(getRawResponse(),longString,longStringTest); //Float Date - String floatDateFacet = getFacetXML(response, "percentile_20n","fieldFacets", "date_dtd"); - Collection floatDate = (ArrayList)xmlToList(floatDateFacet, "float", "float"); + Collection floatDate = getFloatList("percentile_20n","fieldFacets", "date_dtd", "float", "float"); ArrayList floatDateTest = (ArrayList)calculateStat(floatDateTestStart, "perc_20"); - assertEquals(floatDate,floatDateTest); + assertEquals(getRawResponse(),floatDate,floatDateTest); //Float String - String floatStringFacet = getFacetXML(response, "percentile_20n","fieldFacets", "string_sd"); - Collection floatString = (ArrayList)xmlToList(floatStringFacet, "float", "float"); + Collection floatString = getFloatList("percentile_20n","fieldFacets", "string_sd", "float", "float"); ArrayList floatStringTest = (ArrayList)calculateStat(floatStringTestStart, "perc_20"); - assertEquals(floatString,floatStringTest); + assertEquals(getRawResponse(),floatString,floatStringTest); //Double Date - String doubleDateFacet = getFacetXML(response, "percentile_20n","fieldFacets", "date_dtd"); - Collection doubleDate = (ArrayList)xmlToList(doubleDateFacet, "double", "double"); + Collection doubleDate = getDoubleList("percentile_20n","fieldFacets", "date_dtd", "double", "double"); ArrayList doubleDateTest = (ArrayList)calculateStat(doubleDateTestStart, "perc_20"); - assertEquals(doubleDate,doubleDateTest); + assertEquals(getRawResponse(),doubleDate,doubleDateTest); //Double String - String doubleStringFacet = getFacetXML(response, "percentile_20n","fieldFacets", "string_sd"); - Collection doubleString = (ArrayList)xmlToList(doubleStringFacet, "double", "double"); + Collection doubleString = getDoubleList("percentile_20n","fieldFacets", "string_sd", "double", "double"); ArrayList doubleStringTest = (ArrayList)calculateStat(doubleStringTestStart, "perc_20"); - assertEquals(doubleString,doubleStringTest); + assertEquals(getRawResponse(),doubleString,doubleStringTest); //Date Int - String dateIntFacet = getFacetXML(response, "percentile_20","fieldFacets", "int_id"); - Collection dateInt = (ArrayList)xmlToList(dateIntFacet, "date", "date"); + Collection dateInt = getStringList("percentile_20","fieldFacets", "int_id", "date", "date"); ArrayList dateIntTest = (ArrayList)calculateStat(dateIntTestStart, "perc_20"); - assertEquals(dateInt,dateIntTest); + assertEquals(getRawResponse(),dateInt,dateIntTest); //Date Long - String dateStringFacet = getFacetXML(response, "percentile_20","fieldFacets", "long_ld"); - Collection dateString = (ArrayList)xmlToList(dateStringFacet, "date", "date"); + Collection dateString = getStringList("percentile_20","fieldFacets", "long_ld", "date", "date"); ArrayList dateLongTest = (ArrayList)calculateStat(dateLongTestStart, "perc_20"); - assertEquals(dateString,dateLongTest); + assertEquals(getRawResponse(),dateString,dateLongTest); //String Int - String stringIntFacet = getFacetXML(response, "percentile_20","fieldFacets", "int_id"); - Collection stringInt = (ArrayList)xmlToList(stringIntFacet, "str", "str"); + Collection stringInt = getStringList("percentile_20","fieldFacets", "int_id", "str", "str"); ArrayList stringIntTest = (ArrayList)calculateStat(stringIntTestStart, "perc_20"); - assertEquals(stringInt,stringIntTest); + assertEquals(getRawResponse(),stringInt,stringIntTest); //String Long - String stringLongFacet = getFacetXML(response, "percentile_20","fieldFacets", "long_ld"); - Collection stringLong = (ArrayList)xmlToList(stringLongFacet, "str", "str"); + Collection stringLong = getStringList("percentile_20","fieldFacets", "long_ld", "str", "str"); ArrayList stringLongTest = (ArrayList)calculateStat(stringLongTestStart, "perc_20"); - assertEquals(stringLong,stringLongTest); + assertEquals(getRawResponse(),stringLong,stringLongTest); } @SuppressWarnings("unchecked") @Test public void perc60Test() throws Exception { //Int Date - String intDateFacet = getFacetXML(response, "percentile_60n","fieldFacets", "date_dtd"); - Collection intDate = (ArrayList)xmlToList(intDateFacet, "int", "int"); + Collection intDate = getIntegerList("percentile_60n","fieldFacets", "date_dtd", "int", "int"); ArrayList intDateTest = (ArrayList)calculateStat(intDateTestStart, "perc_60"); - assertEquals(intDate,intDateTest); + assertEquals(getRawResponse(),intDate,intDateTest); //Int String - String intStringFacet = getFacetXML(response, "percentile_60n","fieldFacets", "string_sd"); - Collection intString = (ArrayList)xmlToList(intStringFacet, "int", "int"); + Collection intString = getIntegerList("percentile_60n","fieldFacets", "string_sd", "int", "int"); ArrayList intStringTest = (ArrayList)calculateStat(intStringTestStart, "perc_60"); - assertEquals(intString,intStringTest); + assertEquals(getRawResponse(),intString,intStringTest); //Long Date - String longDateFacet = getFacetXML(response, "percentile_60n","fieldFacets", "date_dtd"); - Collection longDate = (ArrayList)xmlToList(longDateFacet, "long", "long"); + Collection longDate = getLongList("percentile_60n","fieldFacets", "date_dtd", "long", "long"); ArrayList longDateTest = (ArrayList)calculateStat(longDateTestStart, "perc_60"); - assertEquals(longDate,longDateTest); + assertEquals(getRawResponse(),longDate,longDateTest); //Long String - String longStringFacet = getFacetXML(response, "percentile_60n","fieldFacets", "string_sd"); - Collection longString = (ArrayList)xmlToList(longStringFacet, "long", "long"); + Collection longString = getLongList("percentile_60n","fieldFacets", "string_sd", "long", "long"); ArrayList longStringTest = (ArrayList)calculateStat(longStringTestStart, "perc_60"); - assertEquals(longString,longStringTest); + assertEquals(getRawResponse(),longString,longStringTest); //Float Date - String floatDateFacet = getFacetXML(response, "percentile_60n","fieldFacets", "date_dtd"); - Collection floatDate = (ArrayList)xmlToList(floatDateFacet, "float", "float"); + Collection floatDate = getFloatList("percentile_60n","fieldFacets", "date_dtd", "float", "float"); ArrayList floatDateTest = (ArrayList)calculateStat(floatDateTestStart, "perc_60"); - assertEquals(floatDate,floatDateTest); + assertEquals(getRawResponse(),floatDate,floatDateTest); //Float String - String floatStringFacet = getFacetXML(response, "percentile_60n","fieldFacets", "string_sd"); - Collection floatString = (ArrayList)xmlToList(floatStringFacet, "float", "float"); + Collection floatString = getFloatList("percentile_60n","fieldFacets", "string_sd", "float", "float"); ArrayList floatStringTest = (ArrayList)calculateStat(floatStringTestStart, "perc_60"); - assertEquals(floatString,floatStringTest); + assertEquals(getRawResponse(),floatString,floatStringTest); //Double Date - String doubleDateFacet = getFacetXML(response, "percentile_60n","fieldFacets", "date_dtd"); - Collection doubleDate = (ArrayList)xmlToList(doubleDateFacet, "double", "double"); + Collection doubleDate = getDoubleList("percentile_60n","fieldFacets", "date_dtd", "double", "double"); ArrayList doubleDateTest = (ArrayList)calculateStat(doubleDateTestStart, "perc_60"); - assertEquals(doubleDate,doubleDateTest); + assertEquals(getRawResponse(),doubleDate,doubleDateTest); //Double String - String doubleStringFacet = getFacetXML(response, "percentile_60n","fieldFacets", "string_sd"); - Collection doubleString = (ArrayList)xmlToList(doubleStringFacet, "double", "double"); + Collection doubleString = getDoubleList("percentile_60n","fieldFacets", "string_sd", "double", "double"); ArrayList doubleStringTest = (ArrayList)calculateStat(doubleStringTestStart, "perc_60"); - assertEquals(doubleString,doubleStringTest); + assertEquals(getRawResponse(),doubleString,doubleStringTest); //Date Int - String dateIntFacet = getFacetXML(response, "percentile_60","fieldFacets", "int_id"); - Collection dateInt = (ArrayList)xmlToList(dateIntFacet, "date", "date"); + Collection dateInt = getStringList("percentile_60","fieldFacets", "int_id", "date", "date"); ArrayList dateIntTest = (ArrayList)calculateStat(dateIntTestStart, "perc_60"); - assertEquals(dateInt,dateIntTest); + assertEquals(getRawResponse(),dateInt,dateIntTest); //Date Long - String dateStringFacet = getFacetXML(response, "percentile_60","fieldFacets", "long_ld"); - Collection dateString = (ArrayList)xmlToList(dateStringFacet, "date", "date"); + Collection dateString = getStringList("percentile_60","fieldFacets", "long_ld", "date", "date"); ArrayList dateLongTest = (ArrayList)calculateStat(dateLongTestStart, "perc_60"); - assertEquals(dateString,dateLongTest); + assertEquals(getRawResponse(),dateString,dateLongTest); //String Int - String stringIntFacet = getFacetXML(response, "percentile_60","fieldFacets", "int_id"); - Collection stringInt = (ArrayList)xmlToList(stringIntFacet, "str", "str"); + Collection stringInt = getStringList("percentile_60","fieldFacets", "int_id", "str", "str"); ArrayList stringIntTest = (ArrayList)calculateStat(stringIntTestStart, "perc_60"); - assertEquals(stringInt,stringIntTest); + assertEquals(getRawResponse(),stringInt,stringIntTest); //String Long - String stringLongFacet = getFacetXML(response, "percentile_60","fieldFacets", "long_ld"); - Collection stringLong = (ArrayList)xmlToList(stringLongFacet, "str", "str"); + Collection stringLong = getStringList("percentile_60","fieldFacets", "long_ld", "str", "str"); ArrayList stringLongTest = (ArrayList)calculateStat(stringLongTestStart, "perc_60"); - assertEquals(stringLong,stringLongTest); + assertEquals(getRawResponse(),stringLong,stringLongTest); } @SuppressWarnings("unchecked") @Test public void minTest() throws Exception { //Int Date - String intDateFacet = getFacetXML(response, "minn","fieldFacets", "date_dtd"); - Collection intDate = (ArrayList)xmlToList(intDateFacet, "int", "int"); + Collection intDate = getIntegerList("minn","fieldFacets", "date_dtd", "int", "int"); ArrayList intDateTest = (ArrayList)calculateStat(intDateTestStart, "min"); - assertEquals(intDate,intDateTest); + assertEquals(getRawResponse(),intDate,intDateTest); //Int String - String intStringFacet = getFacetXML(response, "minn","fieldFacets", "string_sd"); - Collection intString = (ArrayList)xmlToList(intStringFacet, "int", "int"); + Collection intString = getIntegerList("minn","fieldFacets", "string_sd", "int", "int"); ArrayList intStringTest = (ArrayList)calculateStat(intStringTestStart, "min"); - assertEquals(intString,intStringTest); + assertEquals(getRawResponse(),intString,intStringTest); //Long Date - String longDateFacet = getFacetXML(response, "minn","fieldFacets", "date_dtd"); - Collection longDate = (ArrayList)xmlToList(longDateFacet, "long", "long"); + Collection longDate = getLongList("minn","fieldFacets", "date_dtd", "long", "long"); ArrayList longDateTest = (ArrayList)calculateStat(longDateTestStart, "min"); - assertEquals(longDate,longDateTest); + assertEquals(getRawResponse(),longDate,longDateTest); //Long String - String longStringFacet = getFacetXML(response, "minn","fieldFacets", "string_sd"); - Collection longString = (ArrayList)xmlToList(longStringFacet, "long", "long"); + Collection longString = getLongList("minn","fieldFacets", "string_sd", "long", "long"); ArrayList longStringTest = (ArrayList)calculateStat(longStringTestStart, "min"); - assertEquals(longString,longStringTest); + assertEquals(getRawResponse(),longString,longStringTest); //Float Date - String floatDateFacet = getFacetXML(response, "minn","fieldFacets", "date_dtd"); - Collection floatDate = (ArrayList)xmlToList(floatDateFacet, "float", "float"); + Collection floatDate = getFloatList("minn","fieldFacets", "date_dtd", "float", "float"); ArrayList floatDateTest = (ArrayList)calculateStat(floatDateTestStart, "min"); - assertEquals(floatDate,floatDateTest); + assertEquals(getRawResponse(),floatDate,floatDateTest); //Float String - String floatStringFacet = getFacetXML(response, "minn","fieldFacets", "string_sd"); - Collection floatString = (ArrayList)xmlToList(floatStringFacet, "float", "float"); + Collection floatString = getFloatList("minn","fieldFacets", "string_sd", "float", "float"); ArrayList floatStringTest = (ArrayList)calculateStat(floatStringTestStart, "min"); - assertEquals(floatString,floatStringTest); + assertEquals(getRawResponse(),floatString,floatStringTest); //Double Date - String doubleDateFacet = getFacetXML(response, "minn","fieldFacets", "date_dtd"); - Collection doubleDate = (ArrayList)xmlToList(doubleDateFacet, "double", "double"); + Collection doubleDate = getDoubleList("minn","fieldFacets", "date_dtd", "double", "double"); ArrayList doubleDateTest = (ArrayList)calculateStat(doubleDateTestStart, "min"); - assertEquals(doubleDate,doubleDateTest); + assertEquals(getRawResponse(),doubleDate,doubleDateTest); //Double String - String doubleStringFacet = getFacetXML(response, "minn","fieldFacets", "string_sd"); - Collection doubleString = (ArrayList)xmlToList(doubleStringFacet, "double", "double"); + Collection doubleString = getDoubleList("minn","fieldFacets", "string_sd", "double", "double"); ArrayList doubleStringTest = (ArrayList)calculateStat(doubleStringTestStart, "min"); - assertEquals(doubleString,doubleStringTest); + assertEquals(getRawResponse(),doubleString,doubleStringTest); //Date Int - String dateIntFacet = getFacetXML(response, "min","fieldFacets", "int_id"); - Collection dateInt = (ArrayList)xmlToList(dateIntFacet, "date", "date"); + Collection dateInt = getStringList("min","fieldFacets", "int_id", "date", "date"); ArrayList dateIntTest = (ArrayList)calculateStat(dateIntTestStart, "min"); - assertEquals(dateInt,dateIntTest); + assertEquals(getRawResponse(),dateInt,dateIntTest); //Date Long - String dateStringFacet = getFacetXML(response, "min","fieldFacets", "long_ld"); - Collection dateString = (ArrayList)xmlToList(dateStringFacet, "date", "date"); + Collection dateString = getStringList("min","fieldFacets", "long_ld", "date", "date"); ArrayList dateLongTest = (ArrayList)calculateStat(dateLongTestStart, "min"); - assertEquals(dateString,dateLongTest); + assertEquals(getRawResponse(),dateString,dateLongTest); //String Int - String stringIntFacet = getFacetXML(response, "min","fieldFacets", "int_id"); - Collection stringInt = (ArrayList)xmlToList(stringIntFacet, "str", "str"); + Collection stringInt = getStringList("min","fieldFacets", "int_id", "str", "str"); ArrayList stringIntTest = (ArrayList)calculateStat(stringIntTestStart, "min"); - assertEquals(stringInt,stringIntTest); + assertEquals(getRawResponse(),stringInt,stringIntTest); //String Long - String stringLongFacet = getFacetXML(response, "min","fieldFacets", "long_ld"); - Collection stringLong = (ArrayList)xmlToList(stringLongFacet, "str", "str"); + Collection stringLong = getStringList("min","fieldFacets", "long_ld", "str", "str"); ArrayList stringLongTest = (ArrayList)calculateStat(stringLongTestStart, "min"); - assertEquals(stringLong,stringLongTest); + assertEquals(getRawResponse(),stringLong,stringLongTest); } @SuppressWarnings("unchecked") @Test public void maxTest() throws Exception { //Int Date - String intDateFacet = getFacetXML(response, "maxn","fieldFacets", "date_dtd"); - Collection intDate = (ArrayList)xmlToList(intDateFacet, "int", "int"); + Collection intDate = getIntegerList("maxn","fieldFacets", "date_dtd", "int", "int"); ArrayList intDateTest = (ArrayList)calculateStat(intDateTestStart, "max"); - assertEquals(intDate,intDateTest); + assertEquals(getRawResponse(),intDate,intDateTest); //Int String - String intStringFacet = getFacetXML(response, "maxn","fieldFacets", "string_sd"); - Collection intString = (ArrayList)xmlToList(intStringFacet, "int", "int"); + Collection intString = getIntegerList("maxn","fieldFacets", "string_sd", "int", "int"); ArrayList intStringTest = (ArrayList)calculateStat(intStringTestStart, "max"); - assertEquals(intString,intStringTest); + assertEquals(getRawResponse(),intString,intStringTest); //Long Date - String longDateFacet = getFacetXML(response, "maxn","fieldFacets", "date_dtd"); - Collection longDate = (ArrayList)xmlToList(longDateFacet, "long", "long"); + Collection longDate = getLongList("maxn","fieldFacets", "date_dtd", "long", "long"); ArrayList longDateTest = (ArrayList)calculateStat(longDateTestStart, "max"); - assertEquals(longDate,longDateTest); + assertEquals(getRawResponse(),longDate,longDateTest); //Long String - String longStringFacet = getFacetXML(response, "maxn","fieldFacets", "string_sd"); - Collection longString = (ArrayList)xmlToList(longStringFacet, "long", "long"); + Collection longString = getLongList("maxn","fieldFacets", "string_sd", "long", "long"); ArrayList longStringTest = (ArrayList)calculateStat(longStringTestStart, "max"); - assertEquals(longString,longStringTest); + assertEquals(getRawResponse(),longString,longStringTest); //Float Date - String floatDateFacet = getFacetXML(response, "maxn","fieldFacets", "date_dtd"); - Collection floatDate = (ArrayList)xmlToList(floatDateFacet, "float", "float"); + Collection floatDate = getFloatList("maxn","fieldFacets", "date_dtd", "float", "float"); ArrayList floatDateTest = (ArrayList)calculateStat(floatDateTestStart, "max"); - assertEquals(floatDate,floatDateTest); + assertEquals(getRawResponse(),floatDate,floatDateTest); //Float String - String floatStringFacet = getFacetXML(response, "maxn","fieldFacets", "string_sd"); - Collection floatString = (ArrayList)xmlToList(floatStringFacet, "float", "float"); + Collection floatString = getFloatList("maxn","fieldFacets", "string_sd", "float", "float"); ArrayList floatStringTest = (ArrayList)calculateStat(floatStringTestStart, "max"); - assertEquals(floatString,floatStringTest); + assertEquals(getRawResponse(),floatString,floatStringTest); //Double Date - String doubleDateFacet = getFacetXML(response, "maxn","fieldFacets", "date_dtd"); - Collection doubleDate = (ArrayList)xmlToList(doubleDateFacet, "double", "double"); + Collection doubleDate = getDoubleList("maxn","fieldFacets", "date_dtd", "double", "double"); ArrayList doubleDateTest = (ArrayList)calculateStat(doubleDateTestStart, "max"); - assertEquals(doubleDate,doubleDateTest); + assertEquals(getRawResponse(),doubleDate,doubleDateTest); //Double String - String doubleStringFacet = getFacetXML(response, "maxn","fieldFacets", "string_sd"); - Collection doubleString = (ArrayList)xmlToList(doubleStringFacet, "double", "double"); + Collection doubleString = getDoubleList("maxn","fieldFacets", "string_sd", "double", "double"); ArrayList doubleStringTest = (ArrayList)calculateStat(doubleStringTestStart, "max"); - assertEquals(doubleString,doubleStringTest); + assertEquals(getRawResponse(),doubleString,doubleStringTest); //String Int - String stringIntFacet = getFacetXML(response, "max","fieldFacets", "int_id"); - Collection stringInt = (ArrayList)xmlToList(stringIntFacet, "str", "str"); + Collection stringInt = getStringList("max","fieldFacets", "int_id", "str", "str"); ArrayList stringIntTest = (ArrayList)calculateStat(stringIntTestStart, "max"); - assertEquals(stringInt,stringIntTest); + assertEquals(getRawResponse(),stringInt,stringIntTest); //String Long - String stringLongFacet = getFacetXML(response, "max","fieldFacets", "long_ld"); - Collection stringLong = (ArrayList)xmlToList(stringLongFacet, "str", "str"); + Collection stringLong = getStringList("max","fieldFacets", "long_ld", "str", "str"); ArrayList stringLongTest = (ArrayList)calculateStat(stringLongTestStart, "max"); - assertEquals(stringLong,stringLongTest); + assertEquals(getRawResponse(),stringLong,stringLongTest); //Date Int - String dateIntFacet = getFacetXML(response, "max","fieldFacets", "int_id"); - Collection dateInt = (ArrayList)xmlToList(dateIntFacet, "date", "date"); + Collection dateInt = getStringList("max","fieldFacets", "int_id", "date", "date"); ArrayList dateIntTest = (ArrayList)calculateStat(dateIntTestStart, "max"); - assertEquals(dateInt,dateIntTest); + assertEquals(getRawResponse(),dateInt,dateIntTest); //Date Long - String dateStringFacet = getFacetXML(response, "max","fieldFacets", "long_ld"); - Collection dateString = (ArrayList)xmlToList(dateStringFacet, "date", "date"); + Collection dateString = getStringList("max","fieldFacets", "long_ld", "date", "date"); ArrayList dateLongTest = (ArrayList)calculateStat(dateLongTestStart, "max"); - assertEquals(dateString,dateLongTest); + assertEquals(getRawResponse(),dateString,dateLongTest); } @@ -924,274 +834,237 @@ public class FieldFacetTest extends AbstractAnalyticsFacetTest{ @Test public void uniqueTest() throws Exception { //Int Date - String intDateFacet = getFacetXML(response, "uniquen", "fieldFacets", "date_dtd"); - Collection intDate = (ArrayList)xmlToList(intDateFacet, "long", "int"); + Collection intDate = getLongList("uniquen", "fieldFacets", "date_dtd", "long", "int"); ArrayList intDateTest = (ArrayList)calculateStat(intDateTestStart, "unique"); - assertEquals(intDate,intDateTest); + assertEquals(getRawResponse(),intDate,intDateTest); //Int String - String intStringFacet = getFacetXML(response, "uniquen", "fieldFacets", "string_sd"); - Collection intString = (ArrayList)xmlToList(intStringFacet, "long", "int"); + Collection intString = getLongList("uniquen", "fieldFacets", "string_sd", "long", "int"); ArrayList intStringTest = (ArrayList)calculateStat(intStringTestStart, "unique"); - assertEquals(intString,intStringTest); + assertEquals(getRawResponse(),intString,intStringTest); //Long Date - String longDateFacet = getFacetXML(response, "uniquen", "fieldFacets", "date_dtd"); - Collection longDate = (ArrayList)xmlToList(longDateFacet, "long", "long"); + Collection longDate = getLongList("uniquen", "fieldFacets", "date_dtd", "long", "long"); ArrayList longDateTest = (ArrayList)calculateStat(longDateTestStart, "unique"); - assertEquals(longDate,longDateTest); + assertEquals(getRawResponse(),longDate,longDateTest); //Long String - String longStringFacet = getFacetXML(response, "uniquen", "fieldFacets", "string_sd"); - Collection longString = (ArrayList)xmlToList(longStringFacet, "long", "long"); + Collection longString = getLongList("uniquen", "fieldFacets", "string_sd", "long", "long"); ArrayList longStringTest = (ArrayList)calculateStat(longStringTestStart, "unique"); - assertEquals(longString,longStringTest); + assertEquals(getRawResponse(),longString,longStringTest); //Float Date - String floatDateFacet = getFacetXML(response, "uniquen", "fieldFacets", "date_dtd"); - Collection floatDate = (ArrayList)xmlToList(floatDateFacet, "long", "float"); + Collection floatDate = getLongList("uniquen", "fieldFacets", "date_dtd", "long", "float"); ArrayList floatDateTest = (ArrayList)calculateStat(floatDateTestStart, "unique"); - assertEquals(floatDate,floatDateTest); + assertEquals(getRawResponse(),floatDate,floatDateTest); //Float String - String floatStringFacet = getFacetXML(response, "uniquen", "fieldFacets", "string_sd"); - Collection floatString = (ArrayList)xmlToList(floatStringFacet, "long", "float"); + Collection floatString = getLongList("uniquen", "fieldFacets", "string_sd", "long", "float"); ArrayList floatStringTest = (ArrayList)calculateStat(floatStringTestStart, "unique"); - assertEquals(floatString,floatStringTest); + assertEquals(getRawResponse(),floatString,floatStringTest); //Double Date - String doubleDateFacet = getFacetXML(response, "uniquen", "fieldFacets", "date_dtd"); - Collection doubleDate = (ArrayList)xmlToList(doubleDateFacet, "long", "double"); + Collection doubleDate = getLongList("uniquen", "fieldFacets", "date_dtd", "long", "double"); ArrayList doubleDateTest = (ArrayList)calculateStat(doubleDateTestStart, "unique"); - assertEquals(doubleDate,doubleDateTest); + assertEquals(getRawResponse(),doubleDate,doubleDateTest); //Double String - String doubleStringFacet = getFacetXML(response, "uniquen", "fieldFacets", "string_sd"); - Collection doubleString = (ArrayList)xmlToList(doubleStringFacet, "long", "double"); + Collection doubleString = getLongList("uniquen", "fieldFacets", "string_sd", "long", "double"); ArrayList doubleStringTest = (ArrayList)calculateStat(doubleStringTestStart, "unique"); - assertEquals(doubleString,doubleStringTest); + assertEquals(getRawResponse(),doubleString,doubleStringTest); //Date Int - String dateIntFacet = getFacetXML(response, "unique", "fieldFacets", "int_id"); - Collection dateInt = (ArrayList)xmlToList(dateIntFacet, "long", "date"); + Collection dateInt = getLongList("unique", "fieldFacets", "int_id", "long", "date"); ArrayList dateIntTest = (ArrayList)calculateStat(dateIntTestStart, "unique"); - assertEquals(dateInt,dateIntTest); + assertEquals(getRawResponse(),dateInt,dateIntTest); //Date Long - String dateStringFacet = getFacetXML(response, "unique", "fieldFacets", "long_ld"); - Collection dateString = (ArrayList)xmlToList(dateStringFacet, "long", "date"); + Collection dateString = getLongList("unique", "fieldFacets", "long_ld", "long", "date"); ArrayList dateLongTest = (ArrayList)calculateStat(dateLongTestStart, "unique"); - assertEquals(dateString,dateLongTest); + assertEquals(getRawResponse(),dateString,dateLongTest); //String Int - String stringIntFacet = getFacetXML(response, "unique", "fieldFacets", "int_id"); - Collection stringInt = (ArrayList)xmlToList(stringIntFacet, "long", "str"); + Collection stringInt = getLongList("unique", "fieldFacets", "int_id", "long", "str"); ArrayList stringIntTest = (ArrayList)calculateStat(stringIntTestStart, "unique"); - assertEquals(stringInt,stringIntTest); + assertEquals(getRawResponse(),stringInt,stringIntTest); //String Long - String stringLongFacet = getFacetXML(response, "unique", "fieldFacets", "long_ld"); - Collection stringLong = (ArrayList)xmlToList(stringLongFacet, "long", "str"); + Collection stringLong = getLongList("unique", "fieldFacets", "long_ld", "long", "str"); ArrayList stringLongTest = (ArrayList)calculateStat(stringLongTestStart, "unique"); - assertEquals(stringLong,stringLongTest); + assertEquals(getRawResponse(),stringLong,stringLongTest); } @SuppressWarnings("unchecked") @Test public void countTest() throws Exception { //Int Date - String intDateFacet = getFacetXML(response, "countn", "fieldFacets", "date_dtd"); - Collection intDate = (ArrayList)xmlToList(intDateFacet, "long", "int"); + Collection intDate = getLongList("countn", "fieldFacets", "date_dtd", "long", "int"); ArrayList intDateTest = (ArrayList)calculateStat(intDateTestStart, "count"); - assertEquals(intDate,intDateTest); + assertEquals(getRawResponse(),intDate,intDateTest); //Int String - String intStringFacet = getFacetXML(response, "countn", "fieldFacets", "string_sd"); - Collection intString = (ArrayList)xmlToList(intStringFacet, "long", "int"); + Collection intString = getLongList("countn", "fieldFacets", "string_sd", "long", "int"); ArrayList intStringTest = (ArrayList)calculateStat(intStringTestStart, "count"); - assertEquals(intString,intStringTest); + assertEquals(getRawResponse(),intString,intStringTest); //Long Date - String longDateFacet = getFacetXML(response, "countn", "fieldFacets", "date_dtd"); - Collection longDate = (ArrayList)xmlToList(longDateFacet, "long", "long"); + Collection longDate = getLongList("countn", "fieldFacets", "date_dtd", "long", "long"); ArrayList longDateTest = (ArrayList)calculateStat(longDateTestStart, "count"); - assertEquals(longDate,longDateTest); + assertEquals(getRawResponse(),longDate,longDateTest); //Long String - String longStringFacet = getFacetXML(response, "countn", "fieldFacets", "string_sd"); - Collection longString = (ArrayList)xmlToList(longStringFacet, "long", "long"); + Collection longString = getLongList("countn", "fieldFacets", "string_sd", "long", "long"); ArrayList longStringTest = (ArrayList)calculateStat(longStringTestStart, "count"); - assertEquals(longString,longStringTest); + assertEquals(getRawResponse(),longString,longStringTest); //Float Date - String floatDateFacet = getFacetXML(response, "countn", "fieldFacets", "date_dtd"); - Collection floatDate = (ArrayList)xmlToList(floatDateFacet, "long", "float"); + Collection floatDate = getLongList("countn", "fieldFacets", "date_dtd", "long", "float"); ArrayList floatDateTest = (ArrayList)calculateStat(floatDateTestStart, "count"); - assertEquals(floatDate,floatDateTest); + assertEquals(getRawResponse(),floatDate,floatDateTest); //Float String - String floatStringFacet = getFacetXML(response, "countn", "fieldFacets", "string_sd"); - Collection floatString = (ArrayList)xmlToList(floatStringFacet, "long", "float"); + Collection floatString = getLongList("countn", "fieldFacets", "string_sd", "long", "float"); ArrayList floatStringTest = (ArrayList)calculateStat(floatStringTestStart, "count"); - assertEquals(floatString,floatStringTest); + assertEquals(getRawResponse(),floatString,floatStringTest); //Double Date - String doubleDateFacet = getFacetXML(response, "countn", "fieldFacets", "date_dtd"); - Collection doubleDate = (ArrayList)xmlToList(doubleDateFacet, "long", "double"); + Collection doubleDate = getLongList("countn", "fieldFacets", "date_dtd", "long", "double"); ArrayList doubleDateTest = (ArrayList)calculateStat(doubleDateTestStart, "count"); - assertEquals(doubleDate,doubleDateTest); + assertEquals(getRawResponse(),doubleDate,doubleDateTest); //Double String - String doubleStringFacet = getFacetXML(response, "countn", "fieldFacets", "string_sd"); - Collection doubleString = (ArrayList)xmlToList(doubleStringFacet, "long", "double"); + Collection doubleString = getLongList("countn", "fieldFacets", "string_sd", "long", "double"); ArrayList doubleStringTest = (ArrayList)calculateStat(doubleStringTestStart, "count"); - assertEquals(doubleString,doubleStringTest); + assertEquals(getRawResponse(),doubleString,doubleStringTest); //Date Int - String dateIntFacet = getFacetXML(response, "count", "fieldFacets", "int_id"); - Collection dateInt = (ArrayList)xmlToList(dateIntFacet, "long", "date"); + Collection dateInt = getLongList("count", "fieldFacets", "int_id", "long", "date"); ArrayList dateIntTest = (ArrayList)calculateStat(dateIntTestStart, "count"); - assertEquals(dateIntTest,dateInt); + assertEquals(getRawResponse(),dateIntTest,dateInt); //Date Long - String dateLongFacet = getFacetXML(response, "count", "fieldFacets", "long_ld"); - Collection dateLong = (ArrayList)xmlToList(dateLongFacet, "long", "date"); + Collection dateLong = getLongList("count", "fieldFacets", "long_ld", "long", "date"); ArrayList dateLongTest = (ArrayList)calculateStat(dateLongTestStart, "count"); - assertEquals(dateLong,dateLongTest); + assertEquals(getRawResponse(),dateLong,dateLongTest); //String Int - String stringIntFacet = getFacetXML(response, "count", "fieldFacets", "int_id"); - Collection stringInt = (ArrayList)xmlToList(stringIntFacet, "long", "str"); + Collection stringInt = getLongList("count", "fieldFacets", "int_id", "long", "str"); ArrayList stringIntTest = (ArrayList)calculateStat(stringIntTestStart, "count"); - assertEquals(stringInt,stringIntTest); + assertEquals(getRawResponse(),stringInt,stringIntTest); //String Long - String stringLongFacet = getFacetXML(response, "count", "fieldFacets", "long_ld"); - Collection stringLong = (ArrayList)xmlToList(stringLongFacet, "long", "str"); + Collection stringLong = getLongList("count", "fieldFacets", "long_ld", "long", "str"); ArrayList stringLongTest = (ArrayList)calculateStat(stringLongTestStart, "count"); - assertEquals(stringLong,stringLongTest); + assertEquals(getRawResponse(),stringLong,stringLongTest); } @SuppressWarnings("unchecked") @Test public void missingTest() throws Exception { //Int Date - String intDateFacet = getFacetXML(response, "missingn", "fieldFacets", "date_dtd"); - Collection intDate = (ArrayList)xmlToList(intDateFacet, "long", "int"); + Collection intDate = getLongList("missingn", "fieldFacets", "date_dtd", "long", "int"); setLatestType("int"); - assertEquals(intDateTestMissing,intDate); + assertEquals(getRawResponse(),intDateTestMissing,intDate); //Int String - String intStringFacet = getFacetXML(response, "missingn", "fieldFacets", "string_sd"); - Collection intString = (ArrayList)xmlToList(intStringFacet, "long", "int"); - assertEquals(intStringTestMissing,intString); + Collection intString = getLongList("missingn", "fieldFacets", "string_sd", "long", "int"); + assertEquals(getRawResponse(),intStringTestMissing,intString); //Long Date - String longDateFacet = getFacetXML(response, "missingn", "fieldFacets", "date_dtd"); - Collection longDate = (ArrayList)xmlToList(longDateFacet, "long", "long"); + Collection longDate = getLongList("missingn", "fieldFacets", "date_dtd", "long", "long"); setLatestType("long"); - assertEquals(longDateTestMissing,longDate); + assertEquals(getRawResponse(),longDateTestMissing,longDate); //Long String - String longStringFacet = getFacetXML(response, "missingn", "fieldFacets", "string_sd"); - Collection longString = (ArrayList)xmlToList(longStringFacet, "long", "long"); - assertEquals(longStringTestMissing,longString); + Collection longString = getLongList("missingn", "fieldFacets", "string_sd", "long", "long"); + assertEquals(getRawResponse(),longStringTestMissing,longString); //Float Date - String floatDateFacet = getFacetXML(response, "missingn", "fieldFacets", "date_dtd"); - Collection floatDate = (ArrayList)xmlToList(floatDateFacet, "long", "float"); + Collection floatDate = getLongList("missingn", "fieldFacets", "date_dtd", "long", "float"); setLatestType("float"); - assertEquals(floatDateTestMissing,floatDate); + assertEquals(getRawResponse(),floatDateTestMissing,floatDate); //Float String - String floatStringFacet = getFacetXML(response, "missingn", "fieldFacets", "string_sd"); - Collection floatString = (ArrayList)xmlToList(floatStringFacet, "long", "float"); - assertEquals(floatStringTestMissing,floatString); + Collection floatString = getLongList("missingn", "fieldFacets", "string_sd", "long", "float"); + assertEquals(getRawResponse(),floatStringTestMissing,floatString); //Double Date - String doubleDateFacet = getFacetXML(response, "missingn", "fieldFacets", "date_dtd"); - Collection doubleDate = (ArrayList)xmlToList(doubleDateFacet, "long", "double"); + Collection doubleDate = getLongList("missingn", "fieldFacets", "date_dtd", "long", "double"); setLatestType("double"); - assertEquals(doubleDateTestMissing,doubleDate); + assertEquals(getRawResponse(),doubleDateTestMissing,doubleDate); //Double String - String doubleStringFacet = getFacetXML(response, "missingn", "fieldFacets", "string_sd"); - Collection doubleString = (ArrayList)xmlToList(doubleStringFacet, "long", "double"); - assertEquals(doubleStringTestMissing,doubleString); + Collection doubleString = getLongList("missingn", "fieldFacets", "string_sd", "long", "double"); + assertEquals(getRawResponse(),doubleStringTestMissing,doubleString); //Date Int - String dateIntFacet = getFacetXML(response, "missing", "fieldFacets", "int_id"); - Collection dateInt = (ArrayList)xmlToList(dateIntFacet, "long", "date"); + Collection dateInt = getLongList("missing", "fieldFacets", "int_id", "long", "date"); setLatestType("date"); - assertEquals(dateIntTestMissing,dateInt); + assertEquals(getRawResponse(),dateIntTestMissing,dateInt); //Date Long - String dateStringFacet = getFacetXML(response, "missing", "fieldFacets", "long_ld"); - Collection dateLong = (ArrayList)xmlToList(dateStringFacet, "long", "date"); - assertEquals(dateLongTestMissing,dateLong); + Collection dateLong = getLongList("missing", "fieldFacets", "long_ld", "long", "date"); + assertEquals(getRawResponse(),dateLongTestMissing,dateLong); //String Int - String stringIntFacet = getFacetXML(response, "missing", "fieldFacets", "int_id"); - Collection stringInt = (ArrayList)xmlToList(stringIntFacet, "long", "str"); + Collection stringInt = getLongList("missing", "fieldFacets", "int_id", "long", "str"); setLatestType("string"); - assertEquals(stringIntTestMissing,stringInt); + assertEquals(getRawResponse(),stringIntTestMissing,stringInt); //String Long - String stringLongFacet = getFacetXML(response, "missing", "fieldFacets", "long_ld"); - Collection stringLong = (ArrayList)xmlToList(stringLongFacet, "long", "str"); - assertEquals(stringLongTestMissing,stringLong); + Collection stringLong = getLongList("missing", "fieldFacets", "long_ld", "long", "str"); + assertEquals(getRawResponse(),stringLongTestMissing,stringLong); } @SuppressWarnings("unchecked") @Test public void multiValueTest() throws Exception { //Long - String longFacet = getFacetXML(response, "multivalued", "fieldFacets", "long_ldm"); - Collection lon = (ArrayList)xmlToList(longFacet, "double", "mean"); + Collection lon = getDoubleList("multivalued", "fieldFacets", "long_ldm", "double", "mean"); ArrayList longTest = calculateNumberStat(multiLongTestStart, "mean"); - assertEquals(lon,longTest); + assertEquals(getRawResponse(),lon,longTest); //Date - String dateFacet = getFacetXML(response, "multivalued", "fieldFacets", "date_dtdm"); - Collection date = (ArrayList)xmlToList(dateFacet, "double", "mean"); + Collection date = getDoubleList("multivalued", "fieldFacets", "date_dtdm", "double", "mean"); ArrayList dateTest = calculateNumberStat(multiDateTestStart, "mean"); - assertEquals(date,dateTest); + assertEquals(getRawResponse(),date,dateTest); //String - String stringFacet = getFacetXML(response, "multivalued", "fieldFacets", "string_sdm"); - Collection string = (ArrayList)xmlToList(stringFacet, "double", "mean"); + Collection string = getDoubleList("multivalued", "fieldFacets", "string_sdm", "double", "mean"); ArrayList stringTest = calculateNumberStat(multiStringTestStart, "mean"); - assertEquals(string,stringTest); + assertEquals(getRawResponse(),string,stringTest); } @SuppressWarnings("unchecked") @Test public void missingFacetTest() throws Exception { //int MultiDate - String stringFacet = getFacetXML(response, "missingf", "fieldFacets", "date_dtdm"); - assertTrue(stringFacet.contains("")); - ArrayList string = (ArrayList)xmlToList(stringFacet, "double", "mean"); + String xPath = "/response/lst[@name='stats']/lst[@name='missingf']/lst[@name='fieldFacets']/lst[@name='date_dtdm']/lst[@name='(MISSING)']"; + assertNotNull(getRawResponse(), getNode(xPath)); + + ArrayList string = getDoubleList("missingf", "fieldFacets", "date_dtdm", "double", "mean"); string.remove(0); ArrayList stringTest = calculateNumberStat(multiDateTestStart, "mean"); - assertEquals(string,stringTest); + assertEquals(getRawResponse(), string,stringTest); //Int String - String intStringFacet = getFacetXML(response, "missingf", "fieldFacets", "string_sd"); - assertTrue(intStringFacet.contains("")&&!intStringFacet.contains("")); - List intString = (ArrayList)xmlToList(intStringFacet, "double", "mean"); + xPath = "/response/lst[@name='stats']/lst[@name='missingf']/lst[@name='fieldFacets']/lst[@name='string_sd']/lst[@name='(MISSING)']"; + assertNotNull(getRawResponse(), getNode(xPath)); + + xPath = "/response/lst[@name='stats']/lst[@name='missingf']/lst[@name='fieldFacets']/lst[@name='string_sd']/lst[@name='str0']"; + assertNull(getRawResponse(), getNode(xPath)); + List intString = getDoubleList("missingf", "fieldFacets", "string_sd", "double", "mean"); intString.remove(0); ArrayList intStringTest = calculateNumberStat(intStringTestStart, "mean"); - assertEquals(intString,intStringTest); + assertEquals(getRawResponse(), intString,intStringTest); //Int Date - String intDateFacet = getFacetXML(response, "missingf", "fieldFacets", "date_dtd"); - Collection intDate = (ArrayList)xmlToList(intDateFacet, "double", "mean"); + Collection intDate = getDoubleList("missingf", "fieldFacets", "date_dtd", "double", "mean"); ArrayList> intDateMissingTestStart = (ArrayList>) intDateTestStart.clone(); ArrayList intDateTest = calculateNumberStat(intDateMissingTestStart, "mean"); - assertEquals(intDate,intDateTest); + assertEquals(getRawResponse(),intDate,intDateTest); } - private boolean checkStddevs(ArrayList list1, ArrayList list2) { + private void checkStddevs(ArrayList list1, ArrayList list2) { for (int i = 0; i int1 = (ArrayList)xmlToList(int1Query, "double", "sum"); + ArrayList int1 = getDoubleList("ir", "queryFacets", "float1", "double", "sum"); ArrayList int1Test = calculateNumberStat(int1TestStart, "sum"); - assertEquals(int1,int1Test); + assertEquals(getRawResponse(), int1, int1Test); //Int Two - String int2Query = getFacetXML(response, "ir", "queryFacets", "float2"); - ArrayList int2 = (ArrayList)xmlToList(int2Query, "int", "percentile_8"); + ArrayList int2 = getIntegerList("ir", "queryFacets", "float2", "int", "percentile_8"); ArrayList int2Test = (ArrayList)calculateStat(int2TestStart, "perc_8"); - assertEquals(int2,int2Test); + assertEquals(getRawResponse(), int2, int2Test); //Long - String long1Query = getFacetXML(response, "lr", "queryFacets", "string"); - ArrayList long1 = (ArrayList)xmlToList(long1Query, "double", "median"); + ArrayList long1 = getDoubleList("lr", "queryFacets", "string", "double", "median"); ArrayList long1Test = calculateNumberStat(longTestStart, "median"); - assertEquals(long1,long1Test); + assertEquals(getRawResponse(),long1,long1Test); //Float - String float1Query = getFacetXML(response, "fr", "queryFacets", "lad"); - ArrayList float1 = (ArrayList)xmlToList(float1Query, "double", "mean"); + ArrayList float1 = getDoubleList("fr", "queryFacets", "lad", "double", "mean"); ArrayList float1Test = calculateNumberStat(floatTestStart, "mean"); - assertEquals(float1,float1Test); + assertEquals(getRawResponse(), float1, float1Test); } } diff --git a/solr/core/src/test/org/apache/solr/analytics/facet/RangeFacetTest.java b/solr/core/src/test/org/apache/solr/analytics/facet/RangeFacetTest.java index 6e9562b101d..e62f7ec52ce 100644 --- a/solr/core/src/test/org/apache/solr/analytics/facet/RangeFacetTest.java +++ b/solr/core/src/test/org/apache/solr/analytics/facet/RangeFacetTest.java @@ -47,8 +47,6 @@ public class RangeFacetTest extends AbstractAnalyticsFacetTest { static ArrayList> floatDoubleTestStart; static ArrayList> floatDateTestStart; - static String response; - @BeforeClass public static void beforeClass() throws Exception { initCore("solrconfig-basic.xml","schema-analytics.xml"); @@ -117,7 +115,7 @@ public class RangeFacetTest extends AbstractAnalyticsFacetTest { assertU(commit()); - response = h.query(request(fileToStringArr(fileName))); + setResponse(h.query(request(fileToStringArr(fileName)))); } @SuppressWarnings("unchecked") @@ -125,42 +123,36 @@ public class RangeFacetTest extends AbstractAnalyticsFacetTest { public void rangeTest() throws Exception { //Int Long - String intLongRange = getFacetXML(response, "ri", "rangeFacets", "long_ld"); - ArrayList intLong = (ArrayList)xmlToList(intLongRange, "long", "count"); + ArrayList intLong = getLongList("ri", "rangeFacets", "long_ld", "long", "count"); ArrayList intLongTest = calculateStat(transformLists(intLongTestStart, 5, 30, 5 , false, true, false, false, false), "count"); - assertEquals(intLong,intLongTest); + assertEquals(getRawResponse(), intLong,intLongTest); //Int Double - String intDoubleRange = getFacetXML(response, "ri", "rangeFacets", "double_dd"); - ArrayList intDouble = (ArrayList)xmlToList(intDoubleRange, "double", "mean"); + ArrayList intDouble = getDoubleList("ri", "rangeFacets", "double_dd", "double", "mean"); ArrayList intDoubleTest = calculateNumberStat(transformLists(intDoubleTestStart, 3, 39, 7 , false, false, true, false, true), "mean"); - assertEquals(intDouble,intDoubleTest); + assertEquals(getRawResponse(), intDouble,intDoubleTest); //Int Date - String intDateRange = getFacetXML(response, "ri", "rangeFacets", "date_dtd"); - ArrayList intDate = (ArrayList)xmlToList(intDateRange, "long", "count"); + ArrayList intDate = getLongList("ri", "rangeFacets", "date_dtd", "long", "count"); ArrayList intDateTest = (ArrayList)calculateStat(transformLists(intDateTestStart, 7, 44, 7 , false, true, false, true, true), "count"); - assertEquals(intDate,intDateTest); + assertEquals(getRawResponse(), intDate,intDateTest); //Float Long - String floatLongRange = getFacetXML(response, "rf", "rangeFacets", "long_ld"); - ArrayList floatLong = (ArrayList)xmlToList(floatLongRange, "double", "median"); + ArrayList floatLong = getDoubleList("rf", "rangeFacets", "long_ld", "double", "median"); ArrayList floatLongTest = calculateNumberStat(transformLists(floatLongTestStart, 0, 29, 4 , false, true, true, true, true), "median"); - assertEquals(floatLong,floatLongTest); + assertEquals(getRawResponse(), floatLong,floatLongTest); //Float Double - String floatDoubleRange = getFacetXML(response, "rf", "rangeFacets", "double_dd"); - ArrayList floatDouble = (ArrayList)xmlToList(floatDoubleRange, "long", "count"); + ArrayList floatDouble = getLongList("rf", "rangeFacets", "double_dd", "long", "count"); ArrayList floatDoubleTest = (ArrayList)calculateStat(transformLists(floatDoubleTestStart, 4, 47, 11 , false, false, false, true, false), "count"); - assertEquals(floatDouble,floatDoubleTest); + assertEquals(getRawResponse(), floatDouble,floatDoubleTest); //Float Date - String floatDateRange = getFacetXML(response, "rf", "rangeFacets", "date_dtd"); - ArrayList floatDate = (ArrayList)xmlToList(floatDateRange, "double", "sumOfSquares"); + ArrayList floatDate = getDoubleList("rf", "rangeFacets", "date_dtd", "double", "sumOfSquares"); ArrayList floatDateTest = calculateNumberStat(transformLists(floatDateTestStart, 4, 46, 5 , false, false, true, true, false), "sumOfSquares"); - assertEquals(floatDate,floatDateTest); + assertEquals(getRawResponse(), floatDate,floatDateTest); } @@ -168,84 +160,72 @@ public class RangeFacetTest extends AbstractAnalyticsFacetTest { @Test public void hardendRangeTest() throws Exception { //Int Long - String intLongRange = getFacetXML(response, "hi", "rangeFacets", "long_ld"); - ArrayList intLong = (ArrayList)xmlToList(intLongRange, "double", "sum"); + ArrayList intLong = getDoubleList("hi", "rangeFacets", "long_ld", "double", "sum"); ArrayList intLongTest = calculateNumberStat(transformLists(intLongTestStart, 5, 30, 5 , true, true, false, false, false), "sum"); - assertEquals(intLong,intLongTest); + assertEquals(getRawResponse(), intLong,intLongTest); //Int Double - String intDoubleRange = getFacetXML(response, "hi", "rangeFacets", "double_dd"); - ArrayList intDouble = (ArrayList)xmlToList(intDoubleRange, "double", "mean"); + ArrayList intDouble = getDoubleList("hi", "rangeFacets", "double_dd", "double", "mean"); ArrayList intDoubleTest = calculateNumberStat(transformLists(intDoubleTestStart, 3, 39, 7 , true, false, true, false, true), "mean"); - assertEquals(intDouble,intDoubleTest); + assertEquals(getRawResponse(), intDouble,intDoubleTest); //Int Date - String intDateRange = getFacetXML(response, "hi", "rangeFacets", "date_dtd"); - ArrayList intDate = (ArrayList)xmlToList(intDateRange, "long", "count"); + ArrayList intDate = getLongList("hi", "rangeFacets", "date_dtd", "long", "count"); ArrayList intDateTest = (ArrayList)calculateStat(transformLists(intDateTestStart, 7, 44, 7 , true, true, false, true, true), "count"); - assertEquals(intDate,intDateTest); + assertEquals(getRawResponse(), intDate,intDateTest); //Float Long - String floatLongRange = getFacetXML(response, "hf", "rangeFacets", "long_ld"); - ArrayList floatLong = (ArrayList)xmlToList(floatLongRange, "double", "median"); + ArrayList floatLong = getDoubleList("hf", "rangeFacets", "long_ld", "double", "median"); ArrayList floatLongTest = calculateNumberStat(transformLists(floatLongTestStart, 0, 29, 4 , true, true, true, true, true), "median"); - assertEquals(floatLong,floatLongTest); + assertEquals(getRawResponse(), floatLong,floatLongTest); //Float Double - String floatDoubleRange = getFacetXML(response, "hf", "rangeFacets", "double_dd"); - ArrayList floatDouble = (ArrayList)xmlToList(floatDoubleRange, "long", "count"); + ArrayList floatDouble = getLongList("hf", "rangeFacets", "double_dd", "long", "count"); ArrayList floatDoubleTest = (ArrayList)calculateStat(transformLists(floatDoubleTestStart, 4, 47, 11 , true, false, false, true, false), "count"); - assertEquals(floatDouble,floatDoubleTest); + assertEquals(getRawResponse(), floatDouble,floatDoubleTest); //Float Date - String floatDateRange = getFacetXML(response, "hf", "rangeFacets", "date_dtd"); - ArrayList floatDate = (ArrayList)xmlToList(floatDateRange, "double", "sumOfSquares"); + ArrayList floatDate = getDoubleList("hf", "rangeFacets", "date_dtd", "double", "sumOfSquares"); ArrayList floatDateTest = calculateNumberStat(transformLists(floatDateTestStart, 4, 46, 5 , true, false, true, true, false), "sumOfSquares"); - assertEquals(floatDate,floatDateTest); + assertEquals(getRawResponse(), floatDate,floatDateTest); } @SuppressWarnings("unchecked") @Test public void multiGapTest() throws Exception { //Int Long - String intLongRange = getFacetXML(response, "mi", "rangeFacets", "long_ld"); - ArrayList intLong = (ArrayList)xmlToList(intLongRange, "double", "sum"); + ArrayList intLong = getDoubleList("mi", "rangeFacets", "long_ld", "double", "sum"); ArrayList intLongTest = calculateNumberStat(transformLists(intLongTestStart, 5, 30, "4,2,6,3" , false, true, false, false, false), "sum"); - assertEquals(intLong,intLongTest); + assertEquals(getRawResponse(), intLong,intLongTest); //Int Double - String intDoubleRange = getFacetXML(response, "mi", "rangeFacets", "double_dd"); - ArrayList intDouble = (ArrayList)xmlToList(intDoubleRange, "double", "mean"); + ArrayList intDouble = getDoubleList("mi", "rangeFacets", "double_dd", "double", "mean"); ArrayList intDoubleTest = calculateNumberStat(transformLists(intDoubleTestStart, 3, 39, "3,1,7" , false, false, true, false, true), "mean"); - assertEquals(intDouble,intDoubleTest); + assertEquals(getRawResponse(), intDouble,intDoubleTest); //Int Date - String intDateRange = getFacetXML(response, "mi", "rangeFacets", "date_dtd"); - ArrayList intDate = (ArrayList)xmlToList(intDateRange, "long", "count"); + ArrayList intDate = getLongList("mi", "rangeFacets", "date_dtd", "long", "count"); ArrayList intDateTest = (ArrayList)calculateStat(transformLists(intDateTestStart, 7, 44, "2,7" , false, true, false, true, true), "count"); - assertEquals(intDate,intDateTest); + assertEquals(getRawResponse(), intDate,intDateTest); //Float Long - String floatLongRange = getFacetXML(response, "mf", "rangeFacets", "long_ld"); - ArrayList floatLong = (ArrayList)xmlToList(floatLongRange, "double", "median"); + ArrayList floatLong = getDoubleList("mf", "rangeFacets", "long_ld", "double", "median"); ArrayList floatLongTest = calculateNumberStat(transformLists(floatLongTestStart, 0, 29, "1,4" , false, true, true, true, true), "median");; - assertEquals(floatLong,floatLongTest); + assertEquals(getRawResponse(), floatLong,floatLongTest); //Float Double - String floatDoubleRange = getFacetXML(response, "mf", "rangeFacets", "double_dd"); - ArrayList floatDouble = (ArrayList)xmlToList(floatDoubleRange, "long", "count"); + ArrayList floatDouble = getLongList("mf", "rangeFacets", "double_dd", "long", "count"); ArrayList floatDoubleTest = (ArrayList)calculateStat(transformLists(floatDoubleTestStart, 4, 47, "2,3,11" , false, false, false, true, false), "count"); - assertEquals(floatDouble,floatDoubleTest); + assertEquals(getRawResponse(), floatDouble,floatDoubleTest); //Float Date - String floatDateRange = getFacetXML(response, "mf", "rangeFacets", "date_dtd"); - ArrayList floatDate = (ArrayList)xmlToList(floatDateRange, "double", "sumOfSquares"); + ArrayList floatDate = getDoubleList("mf", "rangeFacets", "date_dtd", "double", "sumOfSquares"); ArrayList floatDateTest = calculateNumberStat(transformLists(floatDateTestStart, 4, 46, "4,5" , false, false, true, true, false), "sumOfSquares"); - assertEquals(floatDate,floatDateTest); + assertEquals(getRawResponse(), floatDate,floatDateTest); } private ArrayList> transformLists(ArrayList> listsStart, int start, int end, int gap From 83da40be815eb2945b04b12efe6ba8ee9ccdc6a4 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Wed, 27 Nov 2013 19:24:22 +0000 Subject: [PATCH 128/223] SOLR-5509: Beef up retry logging git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1546164 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/solr/update/SolrCmdDistributor.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java b/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java index 3cfc1636d84..fda2fa86840 100644 --- a/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java +++ b/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java @@ -118,7 +118,7 @@ public class SolrCmdDistributor { SolrException.log(SolrCmdDistributor.log, "forwarding update to " + oldNodeUrl + " failed - retrying ... retries: " - + err.req.retries); + + err.req.retries + " " + err.req.cmdString, err.e); try { Thread.sleep(retryPause); } catch (InterruptedException e) { @@ -166,7 +166,7 @@ public class SolrCmdDistributor { uReq.deleteByQuery(cmd.query); } - submit(new Req(node, uReq, sync)); + submit(new Req(cmd.toString(), node, uReq, sync)); } } @@ -180,7 +180,7 @@ public class SolrCmdDistributor { UpdateRequest uReq = new UpdateRequest(); uReq.setParams(params); uReq.add(cmd.solrDoc, cmd.commitWithin, cmd.overwrite); - submit(new Req(node, uReq, synchronous)); + submit(new Req(cmd.toString(), node, uReq, synchronous)); } } @@ -200,7 +200,7 @@ public class SolrCmdDistributor { log.debug("Distrib commit to:" + nodes + " params:" + params); for (Node node : nodes) { - submit(new Req(node, uReq, false)); + submit(new Req(cmd.toString(), node, uReq, false)); } } @@ -249,11 +249,13 @@ public class SolrCmdDistributor { public UpdateRequest uReq; public int retries; public boolean synchronous; + public String cmdString; - public Req(Node node, UpdateRequest uReq, boolean synchronous) { + public Req(String cmdString, Node node, UpdateRequest uReq, boolean synchronous) { this.node = node; this.uReq = uReq; this.synchronous = synchronous; + this.cmdString = cmdString; } } From 2939fce489e90a0e093cca15269f2c0af8c494eb Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Wed, 27 Nov 2013 20:40:01 +0000 Subject: [PATCH 129/223] SOLR-5509: better debug logging git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1546186 13f79535-47bb-0310-9956-ffa450edef68 --- .../update/processor/DistributedUpdateProcessor.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java b/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java index 50c4e951112..b07e9aea13b 100644 --- a/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java +++ b/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java @@ -579,6 +579,9 @@ public class DistributedUpdateProcessor extends UpdateRequestProcessor { if (isLeader || isSubShardLeader) { params.set(DISTRIB_FROM, ZkCoreNodeProps.getCoreUrl( zkController.getBaseUrl(), req.getCore().getName())); + } else if (log.isDebugEnabled()) { + params.set(DISTRIB_FROM, ZkCoreNodeProps.getCoreUrl( + zkController.getBaseUrl(), req.getCore().getName())); } cmdDistrib.distribAdd(cmd, nodes, params); @@ -1008,6 +1011,9 @@ public class DistributedUpdateProcessor extends UpdateRequestProcessor { if (isLeader || isSubShardLeader) { params.set(DISTRIB_FROM, ZkCoreNodeProps.getCoreUrl( zkController.getBaseUrl(), req.getCore().getName())); + } else if (log.isDebugEnabled()) { + params.set(DISTRIB_FROM, ZkCoreNodeProps.getCoreUrl( + zkController.getBaseUrl(), req.getCore().getName())); } cmdDistrib.distribDelete(cmd, nodes, params); } @@ -1069,6 +1075,10 @@ public class DistributedUpdateProcessor extends UpdateRequestProcessor { ModifiableSolrParams outParams = new ModifiableSolrParams(filterParams(req.getParams())); outParams.set(DISTRIB_UPDATE_PARAM, DistribPhase.TOLEADER.toString()); + if (log.isDebugEnabled()) { + outParams.set(DISTRIB_FROM, ZkCoreNodeProps.getCoreUrl( + zkController.getBaseUrl(), req.getCore().getName())); + } SolrParams params = req.getParams(); String route = params.get(ShardParams._ROUTE_); From e54b08e2abff578bb565def6b9361489a1ce28d9 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Wed, 27 Nov 2013 20:43:35 +0000 Subject: [PATCH 130/223] SOLR-5509: fix possible npe git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1546189 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/solr/update/AddUpdateCommand.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/solr/core/src/java/org/apache/solr/update/AddUpdateCommand.java b/solr/core/src/java/org/apache/solr/update/AddUpdateCommand.java index 3facac9f554..6def045784f 100644 --- a/solr/core/src/java/org/apache/solr/update/AddUpdateCommand.java +++ b/solr/core/src/java/org/apache/solr/update/AddUpdateCommand.java @@ -109,14 +109,16 @@ public class AddUpdateCommand extends UpdateCommand implements Iterable Date: Wed, 27 Nov 2013 23:15:13 +0000 Subject: [PATCH 131/223] SOLR-5504: Windows can throw a ConnectException when Linux throws a SocketException - also add a bit more testing. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1546224 13f79535-47bb-0310-9956-ffa450edef68 --- .../solr/update/MockStreamingSolrServers.java | 6 +- .../solr/update/SolrCmdDistributorTest.java | 67 +++++++++++++++++-- 2 files changed, 65 insertions(+), 8 deletions(-) diff --git a/solr/core/src/test/org/apache/solr/update/MockStreamingSolrServers.java b/solr/core/src/test/org/apache/solr/update/MockStreamingSolrServers.java index 681e6b70363..d95958e9f2d 100644 --- a/solr/core/src/test/org/apache/solr/update/MockStreamingSolrServers.java +++ b/solr/core/src/test/org/apache/solr/update/MockStreamingSolrServers.java @@ -19,6 +19,7 @@ package org.apache.solr.update; import java.io.IOException; import java.net.ConnectException; +import java.net.SocketException; import org.apache.solr.client.solrj.SolrRequest; import org.apache.solr.client.solrj.SolrServer; @@ -31,7 +32,7 @@ public class MockStreamingSolrServers extends StreamingSolrServers { public static Logger log = LoggerFactory .getLogger(MockStreamingSolrServers.class); - public enum Exp {CONNECT_EXCEPTION}; + public enum Exp {CONNECT_EXCEPTION, SOCKET_EXCEPTION}; private volatile Exp exp = null; @@ -53,7 +54,8 @@ public class MockStreamingSolrServers extends StreamingSolrServers { switch (exp) { case CONNECT_EXCEPTION: return new ConnectException(); - + case SOCKET_EXCEPTION: + return new SocketException(); default: break; } diff --git a/solr/core/src/test/org/apache/solr/update/SolrCmdDistributorTest.java b/solr/core/src/test/org/apache/solr/update/SolrCmdDistributorTest.java index b881fb79655..3b1ef9bfc33 100644 --- a/solr/core/src/test/org/apache/solr/update/SolrCmdDistributorTest.java +++ b/solr/core/src/test/org/apache/solr/update/SolrCmdDistributorTest.java @@ -318,7 +318,8 @@ public class SolrCmdDistributorTest extends BaseDistributedSearchTestCase { testMaxRetries(); testOneRetry(); - testRetryNode(); + testRetryNodeAgainstBadAddress(); + testRetryNodeWontRetrySocketError(); } private void testMaxRetries() throws IOException { @@ -393,13 +394,60 @@ public class SolrCmdDistributorTest extends BaseDistributedSearchTestCase { long numFoundAfter = solrclient.query(new SolrQuery("*:*")).getResults() .getNumFound(); - // we will get java.net.SocketException: Network is unreachable, which we don't retry on + // we will get java.net.ConnectException which we retry on assertEquals(numFoundBefore + 1, numFoundAfter); assertEquals(0, cmdDistrib.getErrors().size()); } + private void testRetryNodeWontRetrySocketError() throws Exception { + final HttpSolrServer solrclient = (HttpSolrServer) clients.get(0); + long numFoundBefore = solrclient.query(new SolrQuery("*:*")).getResults() + .getNumFound(); + final MockStreamingSolrServers ss = new MockStreamingSolrServers(updateShardHandler); + SolrCmdDistributor cmdDistrib = new SolrCmdDistributor(ss, 5, 0); + ss.setExp(Exp.SOCKET_EXCEPTION); + ArrayList nodes = new ArrayList(); - private void testRetryNode() throws SolrServerException, IOException { + ZkNodeProps nodeProps = new ZkNodeProps(ZkStateReader.BASE_URL_PROP, solrclient.getBaseURL(), + ZkStateReader.CORE_NAME_PROP, ""); + + final AtomicInteger retries = new AtomicInteger(); + nodeProps = new ZkNodeProps(ZkStateReader.BASE_URL_PROP, solrclient.getBaseURL(), ZkStateReader.CORE_NAME_PROP, ""); + RetryNode retryNode = new RetryNode(new ZkCoreNodeProps(nodeProps), null, "collection1", "shard1") { + @Override + public boolean checkRetry() { + retries.incrementAndGet(); + return true; + } + }; + + + nodes.add(retryNode); + + AddUpdateCommand cmd = new AddUpdateCommand(null); + cmd.solrDoc = sdoc("id", id.incrementAndGet()); + ModifiableSolrParams params = new ModifiableSolrParams(); + + CommitUpdateCommand ccmd = new CommitUpdateCommand(null, false); + cmdDistrib.distribAdd(cmd, nodes, params); + + ss.setExp(null); + cmdDistrib.distribCommit(ccmd, nodes, params); + cmdDistrib.finish(); + + // it will checkRetry, but not actually do it... + assertEquals(1, retries.get()); + + + long numFoundAfter = solrclient.query(new SolrQuery("*:*")).getResults() + .getNumFound(); + + // we will get java.net.SocketException: Network is unreachable, which we don't retry on + assertEquals(numFoundBefore, numFoundAfter); + assertEquals(1, cmdDistrib.getErrors().size()); + } + + private void testRetryNodeAgainstBadAddress() throws SolrServerException, IOException { // Test RetryNode SolrCmdDistributor cmdDistrib = new SolrCmdDistributor(updateShardHandler); final HttpSolrServer solrclient = (HttpSolrServer) clients.get(0); @@ -439,10 +487,17 @@ public class SolrCmdDistributorTest extends BaseDistributedSearchTestCase { long numFoundAfter = solrclient.query(new SolrQuery("*:*")).getResults() .getNumFound(); - // we will get java.net.SocketException: Network is unreachable and not retry - assertEquals(numFoundBefore, numFoundAfter); + // different OS's will throw different exceptions for the bad address above + if (numFoundBefore != numFoundAfter) { + assertEquals(0, cmdDistrib.getErrors().size()); + assertEquals(numFoundBefore + 1, numFoundAfter); + } else { + // we will get java.net.SocketException: Network is unreachable and not retry + assertEquals(numFoundBefore, numFoundAfter); + + assertEquals(1, cmdDistrib.getErrors().size()); + } - assertEquals(1, cmdDistrib.getErrors().size()); } @Override From fcb7e37c29ba7522b0580cb62b7d4f69d2394aef Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Thu, 28 Nov 2013 00:31:03 +0000 Subject: [PATCH 132/223] SOLR-5506: Support docValues in (ICU)CollationField git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1546245 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 3 + .../apache/solr/schema/ICUCollationField.java | 56 ++++- .../collection1/conf/schema-icucollate-dv.xml | 59 +++++ .../TestICUCollationFieldDocValues.java | 186 ++++++++++++++++ .../apache/solr/schema/CollationField.java | 54 ++++- .../collection1/conf/schema-collate-dv.xml | 62 ++++++ .../schema/TestCollationFieldDocValues.java | 201 ++++++++++++++++++ 7 files changed, 606 insertions(+), 15 deletions(-) create mode 100644 solr/contrib/analysis-extras/src/test-files/analysis-extras/solr/collection1/conf/schema-icucollate-dv.xml create mode 100644 solr/contrib/analysis-extras/src/test/org/apache/solr/schema/TestICUCollationFieldDocValues.java create mode 100644 solr/core/src/test-files/solr/collection1/conf/schema-collate-dv.xml create mode 100644 solr/core/src/test/org/apache/solr/schema/TestCollationFieldDocValues.java diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 4039571ddbc..32b69c18ef0 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -106,6 +106,9 @@ New Features * SOLR-5492: Return the replica that actually served the query in shards.info response. (shalin) +* SOLR-5506: Support docValues in CollationField and ICUCollationField. + (Robert Muir) + Bug Fixes ---------------------- diff --git a/solr/contrib/analysis-extras/src/java/org/apache/solr/schema/ICUCollationField.java b/solr/contrib/analysis-extras/src/java/org/apache/solr/schema/ICUCollationField.java index e1489474281..30cba33d96e 100644 --- a/solr/contrib/analysis-extras/src/java/org/apache/solr/schema/ICUCollationField.java +++ b/solr/contrib/analysis-extras/src/java/org/apache/solr/schema/ICUCollationField.java @@ -19,6 +19,9 @@ package org.apache.solr.schema; import java.io.IOException; import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.Map; import org.apache.commons.io.IOUtils; @@ -26,7 +29,12 @@ import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.tokenattributes.TermToBytesRefAttribute; import org.apache.lucene.collation.ICUCollationKeyAnalyzer; +import org.apache.lucene.document.SortedDocValuesField; +import org.apache.lucene.document.SortedSetDocValuesField; import org.apache.lucene.index.StorableField; +import org.apache.lucene.search.ConstantScoreQuery; +import org.apache.lucene.search.DocTermOrdsRangeFilter; +import org.apache.lucene.search.FieldCacheRangeFilter; import org.apache.lucene.search.Query; import org.apache.lucene.search.SortField; import org.apache.lucene.search.TermRangeQuery; @@ -229,12 +237,12 @@ public class ICUCollationField extends FieldType { } /** - * analyze the range with the analyzer, instead of the collator. + * analyze the text with the analyzer, instead of the collator. * because icu collators are not thread safe, this keeps things * simple (we already have a threadlocal clone in the reused TS) */ - private BytesRef analyzeRangePart(String field, String part) { - try (TokenStream source = analyzer.tokenStream(field, part)) { + private BytesRef getCollationKey(String field, String text) { + try (TokenStream source = analyzer.tokenStream(field, text)) { source.reset(); TermToBytesRefAttribute termAtt = source.getAttribute(TermToBytesRefAttribute.class); @@ -242,22 +250,54 @@ public class ICUCollationField extends FieldType { // we control the analyzer here: most errors are impossible if (!source.incrementToken()) - throw new IllegalArgumentException("analyzer returned no terms for range part: " + part); + throw new IllegalArgumentException("analyzer returned no terms for text: " + text); termAtt.fillBytesRef(); assert !source.incrementToken(); source.end(); return BytesRef.deepCopyOf(bytes); } catch (IOException e) { - throw new RuntimeException("Unable analyze range part: " + part, e); + throw new RuntimeException("Unable to analyze text: " + text, e); } } @Override public Query getRangeQuery(QParser parser, SchemaField field, String part1, String part2, boolean minInclusive, boolean maxInclusive) { String f = field.getName(); - BytesRef low = part1 == null ? null : analyzeRangePart(f, part1); - BytesRef high = part2 == null ? null : analyzeRangePart(f, part2); - return new TermRangeQuery(field.getName(), low, high, minInclusive, maxInclusive); + BytesRef low = part1 == null ? null : getCollationKey(f, part1); + BytesRef high = part2 == null ? null : getCollationKey(f, part2); + if (!field.indexed() && field.hasDocValues()) { + if (field.multiValued()) { + return new ConstantScoreQuery(DocTermOrdsRangeFilter.newBytesRefRange( + field.getName(), low, high, minInclusive, maxInclusive)); + } else { + return new ConstantScoreQuery(FieldCacheRangeFilter.newBytesRefRange( + field.getName(), low, high, minInclusive, maxInclusive)); + } + } else { + return new TermRangeQuery(field.getName(), low, high, minInclusive, maxInclusive); + } + } + + @Override + public void checkSchemaField(SchemaField field) { + // no-op + } + + @Override + public List createFields(SchemaField field, Object value, float boost) { + if (field.hasDocValues()) { + List fields = new ArrayList(); + fields.add(createField(field, value, boost)); + final BytesRef bytes = getCollationKey(field.getName(), value.toString()); + if (field.multiValued()) { + fields.add(new SortedSetDocValuesField(field.getName(), bytes)); + } else { + fields.add(new SortedDocValuesField(field.getName(), bytes)); + } + return fields; + } else { + return Collections.singletonList(createField(field, value, boost)); + } } } diff --git a/solr/contrib/analysis-extras/src/test-files/analysis-extras/solr/collection1/conf/schema-icucollate-dv.xml b/solr/contrib/analysis-extras/src/test-files/analysis-extras/solr/collection1/conf/schema-icucollate-dv.xml new file mode 100644 index 00000000000..62c2651d14b --- /dev/null +++ b/solr/contrib/analysis-extras/src/test-files/analysis-extras/solr/collection1/conf/schema-icucollate-dv.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text + id + + + + + + + + diff --git a/solr/contrib/analysis-extras/src/test/org/apache/solr/schema/TestICUCollationFieldDocValues.java b/solr/contrib/analysis-extras/src/test/org/apache/solr/schema/TestICUCollationFieldDocValues.java new file mode 100644 index 00000000000..b7ddfaf7c4f --- /dev/null +++ b/solr/contrib/analysis-extras/src/test/org/apache/solr/schema/TestICUCollationFieldDocValues.java @@ -0,0 +1,186 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.schema; + +import java.io.File; +import java.io.FileOutputStream; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.apache.lucene.util.LuceneTestCase.SuppressCodecs; +import org.apache.solr.SolrTestCaseJ4; +import org.junit.BeforeClass; + +import com.ibm.icu.text.Collator; +import com.ibm.icu.text.RuleBasedCollator; +import com.ibm.icu.util.ULocale; + +/** + * Tests {@link ICUCollationField} with docValues. + */ +@SuppressCodecs({"Lucene40", "Lucene41"}) +public class TestICUCollationFieldDocValues extends SolrTestCaseJ4 { + + @BeforeClass + public static void beforeClass() throws Exception { + String home = setupSolrHome(); + initCore("solrconfig.xml","schema.xml", home); + // add some docs + assertU(adoc("id", "1", "text", "\u0633\u0627\u0628")); + assertU(adoc("id", "2", "text", "I WİLL USE TURKİSH CASING")); + assertU(adoc("id", "3", "text", "ı will use turkish casıng")); + assertU(adoc("id", "4", "text", "Töne")); + assertU(adoc("id", "5", "text", "I W\u0049\u0307LL USE TURKİSH CASING")); + assertU(adoc("id", "6", "text", "Testing")); + assertU(adoc("id", "7", "text", "Tone")); + assertU(adoc("id", "8", "text", "Testing")); + assertU(adoc("id", "9", "text", "testing")); + assertU(adoc("id", "10", "text", "toene")); + assertU(adoc("id", "11", "text", "Tzne")); + assertU(adoc("id", "12", "text", "\u0698\u0698")); + assertU(commit()); + } + + /** + * Ugly: but what to do? We want to test custom sort, which reads rules in as a resource. + * These are largish files, and jvm-specific (as our documentation says, you should always + * look out for jvm differences with collation). + * So its preferable to create this file on-the-fly. + */ + public static String setupSolrHome() throws Exception { + // make a solr home underneath the test's TEMP_DIR + File tmpFile = File.createTempFile("test", "tmp", TEMP_DIR); + tmpFile.delete(); + tmpFile.mkdir(); + + // make data and conf dirs + new File(tmpFile + "/collection1", "data").mkdirs(); + File confDir = new File(tmpFile + "/collection1", "conf"); + confDir.mkdirs(); + + // copy over configuration files + FileUtils.copyFile(getFile("analysis-extras/solr/collection1/conf/solrconfig-icucollate.xml"), new File(confDir, "solrconfig.xml")); + FileUtils.copyFile(getFile("analysis-extras/solr/collection1/conf/schema-icucollate-dv.xml"), new File(confDir, "schema.xml")); + + // generate custom collation rules (DIN 5007-2), saving to customrules.dat + RuleBasedCollator baseCollator = (RuleBasedCollator) Collator.getInstance(new ULocale("de", "DE")); + + String DIN5007_2_tailorings = + "& ae , a\u0308 & AE , A\u0308"+ + "& oe , o\u0308 & OE , O\u0308"+ + "& ue , u\u0308 & UE , u\u0308"; + + RuleBasedCollator tailoredCollator = new RuleBasedCollator(baseCollator.getRules() + DIN5007_2_tailorings); + String tailoredRules = tailoredCollator.getRules(); + FileOutputStream os = new FileOutputStream(new File(confDir, "customrules.dat")); + IOUtils.write(tailoredRules, os, "UTF-8"); + os.close(); + + return tmpFile.getAbsolutePath(); + } + + /** + * Test termquery with german DIN 5007-1 primary strength. + * In this case, ö is equivalent to o (but not oe) + */ + public void testBasicTermQuery() { + assertQ("Collated TQ: ", + req("fl", "id", "q", "sort_de:tone", "sort", "id asc" ), + "//*[@numFound='2']", + "//result/doc[1]/int[@name='id'][.=4]", + "//result/doc[2]/int[@name='id'][.=7]" + ); + } + + /** + * Test rangequery again with the DIN 5007-1 collator. + * We do a range query of tone .. tp, in binary order this + * would retrieve nothing due to case and accent differences. + */ + public void testBasicRangeQuery() { + assertQ("Collated RangeQ: ", + req("fl", "id", "q", "sort_de:[tone TO tp]", "sort", "id asc" ), + "//*[@numFound='2']", + "//result/doc[1]/int[@name='id'][.=4]", + "//result/doc[2]/int[@name='id'][.=7]" + ); + } + + /** + * Test sort with a danish collator. ö is ordered after z + */ + public void testBasicSort() { + assertQ("Collated Sort: ", + req("fl", "id", "q", "sort_da:[tz TO töz]", "sort", "sort_da asc" ), + "//*[@numFound='2']", + "//result/doc[1]/int[@name='id'][.=11]", + "//result/doc[2]/int[@name='id'][.=4]" + ); + } + + /** + * Test sort with an arabic collator. U+0633 is ordered after U+0698. + * With a binary collator, the range would also return nothing. + */ + public void testArabicSort() { + assertQ("Collated Sort: ", + req("fl", "id", "q", "sort_ar:[\u0698 TO \u0633\u0633]", "sort", "sort_ar asc" ), + "//*[@numFound='2']", + "//result/doc[1]/int[@name='id'][.=12]", + "//result/doc[2]/int[@name='id'][.=1]" + ); + } + + /** + * Test rangequery again with an Arabic collator. + * Binary order would normally order U+0633 in this range. + */ + public void testNegativeRangeQuery() { + assertQ("Collated RangeQ: ", + req("fl", "id", "q", "sort_ar:[\u062F TO \u0698]", "sort", "id asc" ), + "//*[@numFound='0']" + ); + } + /** + * Test canonical decomposition with turkish primary strength. + * With this sort order, İ is the uppercase form of i, and I is the uppercase form of ı. + * We index a decomposed form of İ. + */ + public void testCanonicalDecomposition() { + assertQ("Collated TQ: ", + req("fl", "id", "q", "sort_tr_canon:\"I Will Use Turkish Casıng\"", "sort", "id asc" ), + "//*[@numFound='3']", + "//result/doc[1]/int[@name='id'][.=2]", + "//result/doc[2]/int[@name='id'][.=3]", + "//result/doc[3]/int[@name='id'][.=5]" + ); + } + + /** + * Test termquery with custom collator (DIN 5007-2). + * In this case, ö is equivalent to oe (but not o) + */ + public void testCustomCollation() { + assertQ("Collated TQ: ", + req("fl", "id", "q", "sort_custom:toene", "sort", "id asc" ), + "//*[@numFound='2']", + "//result/doc[1]/int[@name='id'][.=4]", + "//result/doc[2]/int[@name='id'][.=10]" + ); + } +} diff --git a/solr/core/src/java/org/apache/solr/schema/CollationField.java b/solr/core/src/java/org/apache/solr/schema/CollationField.java index 2c47097e596..cfea5f348d6 100644 --- a/solr/core/src/java/org/apache/solr/schema/CollationField.java +++ b/solr/core/src/java/org/apache/solr/schema/CollationField.java @@ -22,6 +22,9 @@ import java.io.InputStream; import java.text.Collator; import java.text.ParseException; import java.text.RuleBasedCollator; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.Locale; import java.util.Map; @@ -30,7 +33,12 @@ import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.tokenattributes.TermToBytesRefAttribute; import org.apache.lucene.collation.CollationKeyAnalyzer; +import org.apache.lucene.document.SortedDocValuesField; +import org.apache.lucene.document.SortedSetDocValuesField; import org.apache.lucene.index.StorableField; +import org.apache.lucene.search.ConstantScoreQuery; +import org.apache.lucene.search.DocTermOrdsRangeFilter; +import org.apache.lucene.search.FieldCacheRangeFilter; import org.apache.lucene.search.Query; import org.apache.lucene.search.SortField; import org.apache.lucene.search.TermRangeQuery; @@ -209,30 +217,62 @@ public class CollationField extends FieldType { * its just that all methods are synced), this keeps things * simple (we already have a threadlocal clone in the reused TS) */ - private BytesRef analyzeRangePart(String field, String part) { - try (TokenStream source = analyzer.tokenStream(field, part)) { + private BytesRef getCollationKey(String field, String text) { + try (TokenStream source = analyzer.tokenStream(field, text)) { source.reset(); TermToBytesRefAttribute termAtt = source.getAttribute(TermToBytesRefAttribute.class); BytesRef bytes = termAtt.getBytesRef(); // we control the analyzer here: most errors are impossible if (!source.incrementToken()) - throw new IllegalArgumentException("analyzer returned no terms for range part: " + part); + throw new IllegalArgumentException("analyzer returned no terms for text: " + text); termAtt.fillBytesRef(); assert !source.incrementToken(); source.end(); return BytesRef.deepCopyOf(bytes); } catch (IOException e) { - throw new RuntimeException("Unable to analyze range part: " + part, e); + throw new RuntimeException("Unable to analyze text: " + text, e); } } @Override public Query getRangeQuery(QParser parser, SchemaField field, String part1, String part2, boolean minInclusive, boolean maxInclusive) { String f = field.getName(); - BytesRef low = part1 == null ? null : analyzeRangePart(f, part1); - BytesRef high = part2 == null ? null : analyzeRangePart(f, part2); - return new TermRangeQuery(field.getName(), low, high, minInclusive, maxInclusive); + BytesRef low = part1 == null ? null : getCollationKey(f, part1); + BytesRef high = part2 == null ? null : getCollationKey(f, part2); + if (!field.indexed() && field.hasDocValues()) { + if (field.multiValued()) { + return new ConstantScoreQuery(DocTermOrdsRangeFilter.newBytesRefRange( + field.getName(), low, high, minInclusive, maxInclusive)); + } else { + return new ConstantScoreQuery(FieldCacheRangeFilter.newBytesRefRange( + field.getName(), low, high, minInclusive, maxInclusive)); + } + } else { + return new TermRangeQuery(field.getName(), low, high, minInclusive, maxInclusive); + } + } + + @Override + public void checkSchemaField(SchemaField field) { + // no-op + } + + @Override + public List createFields(SchemaField field, Object value, float boost) { + if (field.hasDocValues()) { + List fields = new ArrayList(); + fields.add(createField(field, value, boost)); + final BytesRef bytes = getCollationKey(field.getName(), value.toString()); + if (field.multiValued()) { + fields.add(new SortedSetDocValuesField(field.getName(), bytes)); + } else { + fields.add(new SortedDocValuesField(field.getName(), bytes)); + } + return fields; + } else { + return Collections.singletonList(createField(field, value, boost)); + } } } diff --git a/solr/core/src/test-files/solr/collection1/conf/schema-collate-dv.xml b/solr/core/src/test-files/solr/collection1/conf/schema-collate-dv.xml new file mode 100644 index 00000000000..933e405ec29 --- /dev/null +++ b/solr/core/src/test-files/solr/collection1/conf/schema-collate-dv.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text + id + + + + + + + + + diff --git a/solr/core/src/test/org/apache/solr/schema/TestCollationFieldDocValues.java b/solr/core/src/test/org/apache/solr/schema/TestCollationFieldDocValues.java new file mode 100644 index 00000000000..0417fe4e3a9 --- /dev/null +++ b/solr/core/src/test/org/apache/solr/schema/TestCollationFieldDocValues.java @@ -0,0 +1,201 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.schema; + +import java.io.File; +import java.io.FileOutputStream; +import java.text.Collator; +import java.text.RuleBasedCollator; +import java.util.Locale; + +import org.apache.lucene.util._TestUtil; +import org.apache.lucene.util.LuceneTestCase.SuppressCodecs; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.apache.solr.SolrTestCaseJ4; +import org.junit.BeforeClass; + +/** + * Tests {@link CollationField} with docvalues + */ +@SuppressCodecs({"Lucene40", "Lucene41"}) +public class TestCollationFieldDocValues extends SolrTestCaseJ4 { + + @BeforeClass + public static void beforeClass() throws Exception { + String home = setupSolrHome(); + initCore("solrconfig.xml","schema.xml", home); + // add some docs + assertU(adoc("id", "1", "text", "\u0633\u0627\u0628")); + assertU(adoc("id", "2", "text", "I WİLL USE TURKİSH CASING")); + assertU(adoc("id", "3", "text", "ı will use turkish casıng")); + assertU(adoc("id", "4", "text", "Töne")); + assertU(adoc("id", "5", "text", "I W\u0049\u0307LL USE TURKİSH CASING")); + assertU(adoc("id", "6", "text", "Testing")); + assertU(adoc("id", "7", "text", "Tone")); + assertU(adoc("id", "8", "text", "Testing")); + assertU(adoc("id", "9", "text", "testing")); + assertU(adoc("id", "10", "text", "toene")); + assertU(adoc("id", "11", "text", "Tzne")); + assertU(adoc("id", "12", "text", "\u0698\u0698")); + assertU(commit()); + } + + /** + * Ugly: but what to do? We want to test custom sort, which reads rules in as a resource. + * These are largish files, and jvm-specific (as our documentation says, you should always + * look out for jvm differences with collation). + * So its preferable to create this file on-the-fly. + */ + public static String setupSolrHome() throws Exception { + // make a solr home underneath the test's TEMP_DIR + File tmpFile = _TestUtil.getTempDir("collation1"); + tmpFile.delete(); + tmpFile.mkdir(); + + // make data and conf dirs + new File(tmpFile, "data").mkdir(); + File confDir = new File(tmpFile + "/collection1", "conf"); + confDir.mkdirs(); + + // copy over configuration files + FileUtils.copyFile(getFile("solr/collection1/conf/solrconfig-basic.xml"), new File(confDir, "solrconfig.xml")); + FileUtils.copyFile(getFile("solr/collection1/conf/solrconfig.snippet.randomindexconfig.xml"), new File(confDir, "solrconfig.snippet.randomindexconfig.xml")); + FileUtils.copyFile(getFile("solr/collection1/conf/schema-collate-dv.xml"), new File(confDir, "schema.xml")); + + // generate custom collation rules (DIN 5007-2), saving to customrules.dat + RuleBasedCollator baseCollator = (RuleBasedCollator) Collator.getInstance(new Locale("de", "DE")); + + String DIN5007_2_tailorings = + "& ae , a\u0308 & AE , A\u0308"+ + "& oe , o\u0308 & OE , O\u0308"+ + "& ue , u\u0308 & UE , u\u0308"; + + RuleBasedCollator tailoredCollator = new RuleBasedCollator(baseCollator.getRules() + DIN5007_2_tailorings); + String tailoredRules = tailoredCollator.getRules(); + FileOutputStream os = new FileOutputStream(new File(confDir, "customrules.dat")); + IOUtils.write(tailoredRules, os, "UTF-8"); + os.close(); + + return tmpFile.getAbsolutePath(); + } + + /** + * Test termquery with german DIN 5007-1 primary strength. + * In this case, ö is equivalent to o (but not oe) + */ + public void testBasicTermQuery() { + assertQ("Collated TQ: ", + req("fl", "id", "q", "sort_de:tone", "sort", "id asc" ), + "//*[@numFound='2']", + "//result/doc[1]/int[@name='id'][.=4]", + "//result/doc[2]/int[@name='id'][.=7]" + ); + } + + /** + * Test rangequery again with the DIN 5007-1 collator. + * We do a range query of tone .. tp, in binary order this + * would retrieve nothing due to case and accent differences. + */ + public void testBasicRangeQuery() { + assertQ("Collated RangeQ: ", + req("fl", "id", "q", "sort_de:[tone TO tp]", "sort", "id asc" ), + "//*[@numFound='2']", + "//result/doc[1]/int[@name='id'][.=4]", + "//result/doc[2]/int[@name='id'][.=7]" + ); + } + + /** + * Test sort with a danish collator. ö is ordered after z + */ + public void testBasicSort() { + assertQ("Collated Sort: ", + req("fl", "id", "q", "sort_da:[tz TO töz]", "sort", "sort_da asc" ), + "//*[@numFound='2']", + "//result/doc[1]/int[@name='id'][.=11]", + "//result/doc[2]/int[@name='id'][.=4]" + ); + } + + /** + * Test sort with an arabic collator. U+0633 is ordered after U+0698. + * With a binary collator, the range would also return nothing. + */ + public void testArabicSort() { + assertQ("Collated Sort: ", + req("fl", "id", "q", "sort_ar:[\u0698 TO \u0633\u0633]", "sort", "sort_ar asc" ), + "//*[@numFound='2']", + "//result/doc[1]/int[@name='id'][.=12]", + "//result/doc[2]/int[@name='id'][.=1]" + ); + } + + /** + * Test rangequery again with an Arabic collator. + * Binary order would normally order U+0633 in this range. + */ + public void testNegativeRangeQuery() { + assertQ("Collated RangeQ: ", + req("fl", "id", "q", "sort_ar:[\u062F TO \u0698]", "sort", "id asc" ), + "//*[@numFound='0']" + ); + } + /** + * Test canonical decomposition with turkish primary strength. + * With this sort order, İ is the uppercase form of i, and I is the uppercase form of ı. + * We index a decomposed form of İ. + */ + public void testCanonicalDecomposition() { + assertQ("Collated TQ: ", + req("fl", "id", "q", "sort_tr_canon:\"I Will Use Turkish Casıng\"", "sort", "id asc" ), + "//*[@numFound='3']", + "//result/doc[1]/int[@name='id'][.=2]", + "//result/doc[2]/int[@name='id'][.=3]", + "//result/doc[3]/int[@name='id'][.=5]" + ); + } + + /** + * Test full decomposition with chinese identical strength. + * The full width form "Testing" is treated identical to "Testing" + */ + public void testFullDecomposition() { + assertQ("Collated TQ: ", + req("fl", "id", "q", "sort_zh_full:Testing", "sort", "id asc" ), + "//*[@numFound='2']", + "//result/doc[1]/int[@name='id'][.=6]", + "//result/doc[2]/int[@name='id'][.=8]" + ); + } + + /** + * Test termquery with custom collator (DIN 5007-2). + * In this case, ö is equivalent to oe (but not o) + */ + public void testCustomCollation() { + assertQ("Collated TQ: ", + req("fl", "id", "q", "sort_custom:toene", "sort", "id asc" ), + "//*[@numFound='2']", + "//result/doc[1]/int[@name='id'][.=4]", + "//result/doc[2]/int[@name='id'][.=10]" + ); + } +} From efbc66ca8f36541d9d5f4b0bceeeb1e67643cee6 Mon Sep 17 00:00:00 2001 From: Erick Erickson Date: Thu, 28 Nov 2013 03:17:30 +0000 Subject: [PATCH 133/223] SOLR-5488: Added more test info output. Somehow lost some of what I did yesterday git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1546263 13f79535-47bb-0310-9956-ffa450edef68 --- .../analytics/AbstractAnalyticsStatsTest.java | 25 +++- .../apache/solr/analytics/NoFacetTest.java | 129 +++++++++--------- .../analytics/expression/ExpressionTest.java | 50 +++---- .../util/valuesource/FunctionTest.java | 65 +++++---- 4 files changed, 137 insertions(+), 132 deletions(-) diff --git a/solr/core/src/test/org/apache/solr/analytics/AbstractAnalyticsStatsTest.java b/solr/core/src/test/org/apache/solr/analytics/AbstractAnalyticsStatsTest.java index 7bba1ff98f5..7c64673422f 100644 --- a/solr/core/src/test/org/apache/solr/analytics/AbstractAnalyticsStatsTest.java +++ b/solr/core/src/test/org/apache/solr/analytics/AbstractAnalyticsStatsTest.java @@ -76,12 +76,19 @@ public class AbstractAnalyticsStatsTest extends SolrTestCaseJ4 { static private Document doc; static private XPathFactory xPathFact = XPathFactory.newInstance(); + static private String rawResponse; + public static void setResponse(String response) throws ParserConfigurationException, IOException, SAXException { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); // never forget this! DocumentBuilder builder = factory.newDocumentBuilder(); doc = builder.parse(new InputSource(new ByteArrayInputStream(response.getBytes("UTF-8")))); xPathFact = XPathFactory.newInstance(); + rawResponse = response; + } + + protected String getRawResponse() { + return rawResponse; } public Object getStatResult(String section, String name, VAL_TYPE type) throws XPathExpressionException { @@ -93,13 +100,17 @@ public class AbstractAnalyticsStatsTest extends SolrTestCaseJ4 { // VAL_TYPE.DOUBLE, the element in question is 47.0. sb.append("/").append(type.toString()).append("[@name='").append(name).append("']"); String val = xPathFact.newXPath().compile(sb.toString()).evaluate(doc, XPathConstants.STRING).toString(); - switch (type) { - case INTEGER: return Integer.parseInt(val); - case DOUBLE: return Double.parseDouble(val); - case FLOAT: return Float.parseFloat(val); - case LONG: return Long.parseLong(val); - case STRING: return val; - case DATE: return val; + try { + switch (type) { + case INTEGER: return Integer.parseInt(val); + case DOUBLE: return Double.parseDouble(val); + case FLOAT: return Float.parseFloat(val); + case LONG: return Long.parseLong(val); + case STRING: return val; + case DATE: return val; + } + } catch (Exception e) { + fail("Caught exception in getStatResult, xPath = " + sb.toString() + " \nraw data: " + rawResponse); } fail("Unknown type used in getStatResult"); return null; // Really can't get here, but the compiler thinks we can! diff --git a/solr/core/src/test/org/apache/solr/analytics/NoFacetTest.java b/solr/core/src/test/org/apache/solr/analytics/NoFacetTest.java index 0ab1be5c849..986b88d59c8 100644 --- a/solr/core/src/test/org/apache/solr/analytics/NoFacetTest.java +++ b/solr/core/src/test/org/apache/solr/analytics/NoFacetTest.java @@ -143,22 +143,22 @@ public class NoFacetTest extends AbstractAnalyticsStatsTest { //Int Double intResult = (Double)getStatResult("sr", "int_id", VAL_TYPE.DOUBLE); Double intTest = (Double)calculateNumberStat(intTestStart, "sum"); - assertEquals(intResult,intTest); + assertEquals(getRawResponse(), intResult,intTest); //Long Double longResult = (Double)getStatResult("sr", "long_ld", VAL_TYPE.DOUBLE); Double longTest = (Double)calculateNumberStat(longTestStart, "sum"); - assertEquals(longResult,longTest); + assertEquals(getRawResponse(), longResult,longTest); //Float Double floatResult = (Double)getStatResult("sr", "float_fd", VAL_TYPE.DOUBLE); Double floatTest = (Double)calculateNumberStat(floatTestStart, "sum"); - assertEquals(floatResult,floatTest); + assertEquals(getRawResponse(), floatResult,floatTest); //Double Double doubleResult = (Double)getStatResult("sr", "double_dd", VAL_TYPE.DOUBLE); Double doubleTest = (Double) calculateNumberStat(doubleTestStart, "sum"); - assertEquals(doubleResult,doubleTest); + assertEquals(getRawResponse(), doubleResult,doubleTest); } @Test @@ -166,22 +166,22 @@ public class NoFacetTest extends AbstractAnalyticsStatsTest { //Int Double intResult = (Double)getStatResult("sosr", "int_id", VAL_TYPE.DOUBLE); Double intTest = (Double)calculateNumberStat(intTestStart, "sumOfSquares"); - assertEquals(intResult,intTest); + assertEquals(getRawResponse(), intResult,intTest); //Long Double longResult = (Double)getStatResult("sosr", "long_ld", VAL_TYPE.DOUBLE); Double longTest = (Double)calculateNumberStat(longTestStart, "sumOfSquares"); - assertEquals(longResult,longTest); + assertEquals(getRawResponse(), longResult,longTest); //Float Double floatResult = (Double)getStatResult("sosr", "float_fd", VAL_TYPE.DOUBLE); Double floatTest = (Double)calculateNumberStat(floatTestStart, "sumOfSquares"); - assertEquals(floatResult,floatTest); + assertEquals(getRawResponse(), floatResult,floatTest); //Double Double doubleResult = (Double)getStatResult("sosr", "double_dd", VAL_TYPE.DOUBLE); Double doubleTest = (Double)calculateNumberStat(doubleTestStart, "sumOfSquares"); - assertEquals(doubleResult,doubleTest); + assertEquals(getRawResponse(), doubleResult,doubleTest); } @Test @@ -189,22 +189,22 @@ public class NoFacetTest extends AbstractAnalyticsStatsTest { //Int Double intResult = (Double)getStatResult("mr", "int_id", VAL_TYPE.DOUBLE); Double intTest = (Double)calculateNumberStat(intTestStart, "mean"); - assertEquals(intResult,intTest); + assertEquals(getRawResponse(), intResult,intTest); //Long Double longResult = (Double)getStatResult("mr", "long_ld", VAL_TYPE.DOUBLE); Double longTest = (Double)calculateNumberStat(longTestStart, "mean"); - assertEquals(longResult,longTest); + assertEquals(getRawResponse(), longResult,longTest); //Float Double floatResult = (Double)getStatResult("mr", "float_fd", VAL_TYPE.DOUBLE); Double floatTest = (Double)calculateNumberStat(floatTestStart, "mean"); - assertEquals(floatResult,floatTest); + assertEquals(getRawResponse(), floatResult,floatTest); //Double Double doubleResult = (Double)getStatResult("mr", "double_dd", VAL_TYPE.DOUBLE); Double doubleTest = (Double)calculateNumberStat(doubleTestStart, "mean"); - assertEquals(doubleResult,doubleTest); + assertEquals(getRawResponse(), doubleResult,doubleTest); } @Test @@ -212,28 +212,23 @@ public class NoFacetTest extends AbstractAnalyticsStatsTest { //Int Double intResult = (Double)getStatResult("str", "int_id", VAL_TYPE.DOUBLE); Double intTest = (Double)calculateNumberStat(intTestStart, "stddev"); - assertTrue(Math.abs(intResult-intTest)<.00000000001); + assertEquals(getRawResponse(), intResult, intTest, 0.00000000001); //Long Double longResult = (Double)getStatResult("str", "long_ld", VAL_TYPE.DOUBLE); Double longTest = (Double)calculateNumberStat(longTestStart, "stddev"); - assertTrue(Math.abs(longResult-longTest)<.00000000001); + assertEquals(getRawResponse(), longResult, longTest, 0.00000000001); //Float Double floatResult = (Double)getStatResult("str", "float_fd", VAL_TYPE.DOUBLE); Double floatTest = (Double)calculateNumberStat(floatTestStart, "stddev"); - assertTrue("Oops: (double raws) " + Double.doubleToRawLongBits(floatResult) + " - " - + Double.doubleToRawLongBits(floatTest) + " < " + Double.doubleToRawLongBits(.00000000001) + - " Calculated diff " + Double.doubleToRawLongBits(floatResult - floatTest) - + " Let's see what the JVM thinks these bits are. FloatResult: " + floatResult.toString() + - " floatTest: " + floatTest.toString() + " Diff " + Double.toString(floatResult - floatTest), - Math.abs(floatResult - floatTest) < .00000000001); + assertEquals(getRawResponse(), floatResult, floatTest, 0.00000000001); //Double Double doubleResult = (Double)getStatResult("str", "double_dd", VAL_TYPE.DOUBLE); Double doubleTest = (Double)calculateNumberStat(doubleTestStart, "stddev"); - assertTrue(Math.abs(doubleResult-doubleTest)<.00000000001); + assertEquals(getRawResponse(), doubleResult, doubleTest, 0.00000000001); } @Test @@ -241,22 +236,22 @@ public class NoFacetTest extends AbstractAnalyticsStatsTest { //Int Double intResult = (Double)getStatResult("medr", "int_id", VAL_TYPE.DOUBLE); Double intTest = (Double)calculateNumberStat(intTestStart, "median"); - assertEquals(intResult,intTest); + assertEquals(getRawResponse(), intResult,intTest); //Long Double longResult = (Double)getStatResult("medr", "long_ld", VAL_TYPE.DOUBLE); Double longTest = (Double)calculateNumberStat(longTestStart, "median"); - assertEquals(longResult,longTest); + assertEquals(getRawResponse(), longResult,longTest); //Float Double floatResult = (Double)getStatResult("medr", "float_fd", VAL_TYPE.DOUBLE); Double floatTest = (Double)calculateNumberStat(floatTestStart, "median"); - assertEquals(floatResult,floatTest); + assertEquals(getRawResponse(), floatResult,floatTest); //Double Double doubleResult = (Double)getStatResult("medr", "double_dd", VAL_TYPE.DOUBLE); Double doubleTest = (Double)calculateNumberStat(doubleTestStart, "median"); - assertEquals(doubleResult,doubleTest); + assertEquals(getRawResponse(), doubleResult,doubleTest); } @Test @@ -264,32 +259,32 @@ public class NoFacetTest extends AbstractAnalyticsStatsTest { //Int 20 Integer intResult = (Integer)getStatResult("p2r", "int_id", VAL_TYPE.INTEGER); Integer intTest = (Integer)calculateStat(intTestStart, "perc_20"); - assertEquals(intResult,intTest); + assertEquals(getRawResponse(), intResult,intTest); //Long 20 Long longResult = (Long)getStatResult("p2r", "long_ld", VAL_TYPE.LONG); Long longTest = (Long)calculateStat(longTestStart, "perc_20"); - assertEquals(longResult,longTest); + assertEquals(getRawResponse(), longResult,longTest); //Float 20 Float floatResult = (Float)getStatResult("p2r", "float_fd", VAL_TYPE.FLOAT); Float floatTest = (Float)calculateStat(floatTestStart, "perc_20"); - assertEquals(floatResult,floatTest); + assertEquals(getRawResponse(), floatResult,floatTest); //Double 20 Double doubleResult = (Double)getStatResult("p2r", "double_dd", VAL_TYPE.DOUBLE); Double doubleTest = (Double)calculateStat(doubleTestStart, "perc_20"); - assertEquals(doubleResult,doubleTest); + assertEquals(getRawResponse(), doubleResult,doubleTest); //Date 20 String dateResult = (String)getStatResult("p2r", "date_dtd", VAL_TYPE.DATE); String dateTest = (String)calculateStat(dateTestStart, "perc_20"); - assertEquals(dateResult,dateTest); + assertEquals(getRawResponse(), dateResult,dateTest); //String 20 String stringResult = (String)getStatResult("p2r", "string_sd", VAL_TYPE.STRING); String stringTest = (String)calculateStat(stringTestStart, "perc_20"); - assertEquals(stringResult,stringTest); + assertEquals(getRawResponse(), stringResult,stringTest); } @Test @@ -297,32 +292,32 @@ public class NoFacetTest extends AbstractAnalyticsStatsTest { //Int 60 Integer intResult = (Integer)getStatResult("p6r", "int_id", VAL_TYPE.INTEGER); Integer intTest = (Integer)calculateStat(intTestStart, "perc_60"); - assertEquals(intResult,intTest); + assertEquals(getRawResponse(), intResult,intTest); //Long 60 Long longResult = (Long)getStatResult("p6r", "long_ld", VAL_TYPE.LONG); Long longTest = (Long)calculateStat(longTestStart, "perc_60"); - assertEquals(longResult,longTest); + assertEquals(getRawResponse(), longResult,longTest); //Float 60 Float floatResult = (Float)getStatResult("p6r", "float_fd", VAL_TYPE.FLOAT); Float floatTest = (Float)calculateStat(floatTestStart, "perc_60"); - assertEquals(floatResult,floatTest); + assertEquals(getRawResponse(), floatResult,floatTest); //Double 60 Double doubleResult = (Double)getStatResult("p6r", "double_dd", VAL_TYPE.DOUBLE); Double doubleTest = (Double)calculateStat(doubleTestStart, "perc_60"); - assertEquals(doubleResult,doubleTest); + assertEquals(getRawResponse(), doubleResult,doubleTest); //Date 60 String dateResult = (String)getStatResult("p6r", "date_dtd", VAL_TYPE.DATE); String dateTest = (String)calculateStat(dateTestStart, "perc_60"); - assertEquals(dateResult,dateTest); + assertEquals(getRawResponse(), dateResult,dateTest); //String 60 String stringResult = (String)getStatResult("p6r", "string_sd", VAL_TYPE.STRING); String stringTest = (String)calculateStat(stringTestStart, "perc_60"); - assertEquals(stringResult,stringTest); + assertEquals(getRawResponse(), stringResult,stringTest); } @Test @@ -330,32 +325,32 @@ public class NoFacetTest extends AbstractAnalyticsStatsTest { //Int Integer intResult = (Integer)getStatResult("mir", "int_id", VAL_TYPE.INTEGER); Integer intTest = (Integer)calculateStat(intTestStart, "min"); - assertEquals(intResult,intTest); + assertEquals(getRawResponse(), intResult,intTest); //Long Long longResult = (Long)getStatResult("mir", "long_ld", VAL_TYPE.LONG); Long longTest = (Long)calculateStat(longTestStart, "min"); - assertEquals(longResult,longTest); + assertEquals(getRawResponse(), longResult,longTest); //Float Float floatResult = (Float)getStatResult("mir", "float_fd", VAL_TYPE.FLOAT); Float floatTest = (Float)calculateStat(floatTestStart, "min"); - assertEquals(floatResult,floatTest); + assertEquals(getRawResponse(), floatResult,floatTest); //Double Double doubleResult = (Double)getStatResult("mir", "double_dd", VAL_TYPE.DOUBLE); Double doubleTest = (Double)calculateStat(doubleTestStart, "min"); - assertEquals(doubleResult,doubleTest); + assertEquals(getRawResponse(), doubleResult,doubleTest); //Date String dateResult = (String)getStatResult("mir", "date_dtd", VAL_TYPE.DATE); String dateTest = (String)calculateStat(dateTestStart, "min"); - assertEquals(dateResult,dateTest); + assertEquals(getRawResponse(), dateResult,dateTest); //String String stringResult = (String)getStatResult("mir", "string_sd", VAL_TYPE.STRING); String stringTest = (String)calculateStat(stringTestStart, "min"); - assertEquals(stringResult,stringTest); + assertEquals(getRawResponse(), stringResult,stringTest); } @Test @@ -363,32 +358,32 @@ public class NoFacetTest extends AbstractAnalyticsStatsTest { //Int Integer intResult = (Integer)getStatResult("mar", "int_id", VAL_TYPE.INTEGER); Integer intTest = (Integer)calculateStat(intTestStart, "max"); - assertEquals(intResult,intTest); + assertEquals(getRawResponse(), intResult,intTest); //Long Long longResult = (Long)getStatResult("mar", "long_ld", VAL_TYPE.LONG); Long longTest = (Long)calculateStat(longTestStart, "max"); - assertEquals(longResult,longTest); + assertEquals(getRawResponse(), longResult,longTest); //Float Float floatResult = (Float)getStatResult("mar", "float_fd", VAL_TYPE.FLOAT); Float floatTest = (Float)calculateStat(floatTestStart, "max"); - assertEquals(floatResult,floatTest); + assertEquals(getRawResponse(), floatResult,floatTest); //Double Double doubleResult = (Double)getStatResult("mar", "double_dd", VAL_TYPE.DOUBLE); Double doubleTest = (Double)calculateStat(doubleTestStart, "max"); - assertEquals(doubleResult,doubleTest); + assertEquals(getRawResponse(), doubleResult,doubleTest); //Date String dateResult = (String)getStatResult("mar", "date_dtd", VAL_TYPE.DATE); String dateTest = (String)calculateStat(dateTestStart, "max"); - assertEquals(dateResult,dateTest); + assertEquals(getRawResponse(), dateResult,dateTest); //String String stringResult = (String)getStatResult("mar", "string_sd", VAL_TYPE.STRING); String stringTest = (String)calculateStat(stringTestStart, "max"); - assertEquals(stringResult,stringTest); + assertEquals(getRawResponse(), stringResult,stringTest); } @Test @@ -396,32 +391,32 @@ public class NoFacetTest extends AbstractAnalyticsStatsTest { //Int Long intResult = (Long)getStatResult("ur", "int_id", VAL_TYPE.LONG); Long intTest = (Long)calculateStat(intTestStart, "unique"); - assertEquals(intResult,intTest); + assertEquals(getRawResponse(), intResult,intTest); //Long Long longResult = (Long)getStatResult("ur", "long_ld", VAL_TYPE.LONG); Long longTest = (Long)calculateStat(longTestStart, "unique"); - assertEquals(longResult,longTest); + assertEquals(getRawResponse(), longResult,longTest); //Float Long floatResult = (Long)getStatResult("ur", "float_fd", VAL_TYPE.LONG); Long floatTest = (Long)calculateStat(floatTestStart, "unique"); - assertEquals(floatResult,floatTest); + assertEquals(getRawResponse(), floatResult,floatTest); //Double Long doubleResult = (Long)getStatResult("ur", "double_dd", VAL_TYPE.LONG); Long doubleTest = (Long)calculateStat(doubleTestStart, "unique"); - assertEquals(doubleResult,doubleTest); + assertEquals(getRawResponse(), doubleResult,doubleTest); //Date Long dateResult = (Long)getStatResult("ur", "date_dtd", VAL_TYPE.LONG); Long dateTest = (Long)calculateStat(dateTestStart, "unique"); - assertEquals(dateResult,dateTest); + assertEquals(getRawResponse(), dateResult,dateTest); //String Long stringResult = (Long)getStatResult("ur", "string_sd", VAL_TYPE.LONG); Long stringTest = (Long)calculateStat(stringTestStart, "unique"); - assertEquals(stringResult,stringTest); + assertEquals(getRawResponse(), stringResult,stringTest); } @Test @@ -429,59 +424,59 @@ public class NoFacetTest extends AbstractAnalyticsStatsTest { //Int Long intResult = (Long)getStatResult("cr", "int_id", VAL_TYPE.LONG); Long intTest = (Long)calculateStat(intTestStart, "count"); - assertEquals(intResult,intTest); + assertEquals(getRawResponse(), intResult,intTest); //Long Long longResult = (Long)getStatResult("cr", "long_ld", VAL_TYPE.LONG); Long longTest = (Long)calculateStat(longTestStart, "count"); - assertEquals(longResult,longTest); + assertEquals(getRawResponse(), longResult,longTest); //Float Long floatResult = (Long)getStatResult("cr", "float_fd", VAL_TYPE.LONG); Long floatTest = (Long)calculateStat(floatTestStart, "count"); - assertEquals(floatResult,floatTest); + assertEquals(getRawResponse(), floatResult,floatTest); //Double Long doubleResult = (Long)getStatResult("cr", "double_dd", VAL_TYPE.LONG); Long doubleTest = (Long)calculateStat(doubleTestStart, "count"); - assertEquals(doubleResult,doubleTest); + assertEquals(getRawResponse(), doubleResult,doubleTest); //Date Long dateResult = (Long)getStatResult("cr", "date_dtd", VAL_TYPE.LONG); Long dateTest = (Long)calculateStat(dateTestStart, "count"); - assertEquals(dateResult,dateTest); + assertEquals(getRawResponse(), dateResult,dateTest); //String Long stringResult = (Long)getStatResult("cr", "string_sd", VAL_TYPE.LONG); Long stringTest = (Long)calculateStat(stringTestStart, "count"); - assertEquals(stringResult,stringTest); + assertEquals(getRawResponse(), stringResult,stringTest); } @Test public void missingDefaultTest() throws Exception { //Int long intResult = (Long)getStatResult("misr", "int_id", VAL_TYPE.LONG); - assertEquals(intMissing,intResult); + assertEquals(getRawResponse(), intMissing,intResult); //Long long longResult = (Long)getStatResult("misr", "long_ld", VAL_TYPE.LONG); - assertEquals(longMissing,longResult); + assertEquals(getRawResponse(), longMissing,longResult); //Float long floatResult = (Long)getStatResult("misr", "float_fd", VAL_TYPE.LONG); - assertEquals(floatMissing,floatResult); + assertEquals(getRawResponse(), floatMissing,floatResult); //Double long doubleResult = (Long)getStatResult("misr", "double_dd", VAL_TYPE.LONG); - assertEquals(doubleMissing,doubleResult); + assertEquals(getRawResponse(), doubleMissing,doubleResult); //Date long dateResult = (Long)getStatResult("misr", "date_dtd", VAL_TYPE.LONG); - assertEquals(dateMissing,dateResult); + assertEquals(getRawResponse(), dateMissing,dateResult); //String long stringResult = (Long)getStatResult("misr", "string_sd", VAL_TYPE.LONG); - assertEquals(stringMissing, stringResult); + assertEquals(getRawResponse(), stringMissing, stringResult); } } diff --git a/solr/core/src/test/org/apache/solr/analytics/expression/ExpressionTest.java b/solr/core/src/test/org/apache/solr/analytics/expression/ExpressionTest.java index 45d86d83715..d1ea7585ed6 100644 --- a/solr/core/src/test/org/apache/solr/analytics/expression/ExpressionTest.java +++ b/solr/core/src/test/org/apache/solr/analytics/expression/ExpressionTest.java @@ -78,13 +78,13 @@ public class ExpressionTest extends AbstractAnalyticsStatsTest { double sumResult = (Double) getStatResult("ar", "sum", VAL_TYPE.DOUBLE); double uniqueResult = ((Long) getStatResult("ar", "unique", VAL_TYPE.LONG)).doubleValue(); double result = (Double) getStatResult("ar", "su", VAL_TYPE.DOUBLE); - assertEquals(sumResult + uniqueResult, result, 0.0); + assertEquals(getRawResponse(), sumResult + uniqueResult, result, 0.0); double meanResult = (Double) getStatResult("ar", "mean", VAL_TYPE.DOUBLE); double medianResult = (Double) getStatResult("ar", "median", VAL_TYPE.DOUBLE); double countResult = ((Long) getStatResult("ar", "count", VAL_TYPE.LONG)).doubleValue(); result = (Double) getStatResult("ar", "mcm", VAL_TYPE.DOUBLE); - assertEquals(meanResult + countResult + medianResult, result, 0.0); + assertEquals(getRawResponse(), meanResult + countResult + medianResult, result, 0.0); } @Test @@ -92,13 +92,13 @@ public class ExpressionTest extends AbstractAnalyticsStatsTest { double sumResult = (Double) getStatResult("mr", "sum", VAL_TYPE.DOUBLE); double uniqueResult = ((Long) getStatResult("mr", "unique", VAL_TYPE.LONG)).doubleValue(); double result = (Double) getStatResult("mr", "su", VAL_TYPE.DOUBLE); - assertEquals(sumResult * uniqueResult, result, 0.0); + assertEquals(getRawResponse(), sumResult * uniqueResult, result, 0.0); double meanResult = (Double) getStatResult("mr", "mean", VAL_TYPE.DOUBLE); double medianResult = (Double) getStatResult("mr", "median", VAL_TYPE.DOUBLE); double countResult = ((Long) getStatResult("mr", "count", VAL_TYPE.LONG)).doubleValue(); result = (Double) getStatResult("mr", "mcm", VAL_TYPE.DOUBLE); - assertEquals(meanResult * countResult * medianResult, result, 0.0); + assertEquals(getRawResponse(), meanResult * countResult * medianResult, result, 0.0); } @Test @@ -106,12 +106,12 @@ public class ExpressionTest extends AbstractAnalyticsStatsTest { double sumResult = (Double) getStatResult("dr", "sum", VAL_TYPE.DOUBLE); double uniqueResult = ((Long) getStatResult("dr", "unique", VAL_TYPE.LONG)).doubleValue(); double result = (Double) getStatResult("dr", "su", VAL_TYPE.DOUBLE); - assertEquals(sumResult / uniqueResult, result, 0.0); + assertEquals(getRawResponse(), sumResult / uniqueResult, result, 0.0); double meanResult = (Double) getStatResult("dr", "mean", VAL_TYPE.DOUBLE); double countResult = ((Long) getStatResult("dr", "count", VAL_TYPE.LONG)).doubleValue(); result = (Double) getStatResult("dr", "mc", VAL_TYPE.DOUBLE); - assertEquals(meanResult / countResult, result, 0.0); + assertEquals(getRawResponse(), meanResult / countResult, result, 0.0); } @Test @@ -119,43 +119,43 @@ public class ExpressionTest extends AbstractAnalyticsStatsTest { double sumResult = (Double) getStatResult("pr", "sum", VAL_TYPE.DOUBLE); double uniqueResult = ((Long) getStatResult("pr", "unique", VAL_TYPE.LONG)).doubleValue(); double result = (Double) getStatResult("pr", "su", VAL_TYPE.DOUBLE); - assertEquals(Math.pow(sumResult, uniqueResult), result, 0.0); + assertEquals(getRawResponse(), Math.pow(sumResult, uniqueResult), result, 0.0); double meanResult = (Double) getStatResult("pr", "mean", VAL_TYPE.DOUBLE); double countResult = ((Long) getStatResult("pr", "count", VAL_TYPE.LONG)).doubleValue(); result = (Double) getStatResult("pr", "mc", VAL_TYPE.DOUBLE); - assertEquals(Math.pow(meanResult, countResult), result, 0.0); + assertEquals(getRawResponse(), Math.pow(meanResult, countResult), result, 0.0); } @Test public void negateTest() throws Exception { double sumResult = (Double) getStatResult("nr", "sum", VAL_TYPE.DOUBLE); double result = (Double) getStatResult("nr", "s", VAL_TYPE.DOUBLE); - assertEquals(-1 * sumResult, result, 0.0); + assertEquals(getRawResponse(), -1 * sumResult, result, 0.0); double countResult = ((Long) getStatResult("nr", "count", VAL_TYPE.LONG)).doubleValue(); result = (Double) getStatResult("nr", "c", VAL_TYPE.DOUBLE); - assertEquals(-1 * countResult, result, 0.0); + assertEquals(getRawResponse(), -1 * countResult, result, 0.0); } @Test public void absoluteValueTest() throws Exception { double sumResult = (Double) getStatResult("avr", "sum", VAL_TYPE.DOUBLE); double result = (Double) getStatResult("avr", "s", VAL_TYPE.DOUBLE); - assertEquals(sumResult, result, 0.0); + assertEquals(getRawResponse(), sumResult, result, 0.0); double countResult = ((Long) getStatResult("avr", "count", VAL_TYPE.LONG)).doubleValue(); result = (Double) getStatResult("avr", "c", VAL_TYPE.DOUBLE); - assertEquals(countResult, result, 0.0); + assertEquals(getRawResponse(), countResult, result, 0.0); } @Test public void constantNumberTest() throws Exception { double result = (Double) getStatResult("cnr", "c8", VAL_TYPE.DOUBLE); - assertEquals(8, result, 0.0); + assertEquals(getRawResponse(), 8, result, 0.0); result = (Double) getStatResult("cnr", "c10", VAL_TYPE.DOUBLE); - assertEquals(10, result, 0.0); + assertEquals(getRawResponse(), 10, result, 0.0); } @SuppressWarnings("deprecation") @@ -165,36 +165,36 @@ public class ExpressionTest extends AbstractAnalyticsStatsTest { DateMathParser date = new DateMathParser(); date.setNow(TrieDateField.parseDate((String) getStatResult("dmr", "median", VAL_TYPE.DATE))); String dateMath = (String) getStatResult("dmr", "dmme", VAL_TYPE.DATE); - assertEquals(TrieDateField.parseDate(dateMath), date.parseMath(math)); + assertEquals(getRawResponse(), TrieDateField.parseDate(dateMath), date.parseMath(math)); math = (String) getStatResult("dmr", "cma", VAL_TYPE.STRING); date = new DateMathParser(); date.setNow(TrieDateField.parseDate((String) getStatResult("dmr", "max", VAL_TYPE.DATE))); dateMath = (String) getStatResult("dmr", "dmma", VAL_TYPE.DATE); - assertEquals(TrieDateField.parseDate(dateMath), date.parseMath(math)); + assertEquals(getRawResponse(), TrieDateField.parseDate(dateMath), date.parseMath(math)); } @Test public void constantDateTest() throws Exception { String date = (String) getStatResult("cdr", "cd1", VAL_TYPE.DATE); String str = (String) getStatResult("cdr", "cs1", VAL_TYPE.STRING); - assertEquals(date, str); + assertEquals(getRawResponse(), date, str); date = (String) getStatResult("cdr", "cd2", VAL_TYPE.DATE); str = (String) getStatResult("cdr", "cs2", VAL_TYPE.STRING); - assertEquals(date, str); + assertEquals(getRawResponse(), date, str); } @Test public void constantStringTest() throws Exception { String str = (String) getStatResult("csr", "cs1", VAL_TYPE.STRING); - assertEquals(str, "this is the first"); + assertEquals(getRawResponse(), str, "this is the first"); str = (String) getStatResult("csr", "cs2", VAL_TYPE.STRING); - assertEquals(str, "this is the second"); + assertEquals(getRawResponse(), str, "this is the second"); str = (String) getStatResult("csr", "cs3", VAL_TYPE.STRING); - assertEquals(str, "this is the third"); + assertEquals(getRawResponse(), str, "this is the third"); } @Test @@ -203,13 +203,13 @@ public class ExpressionTest extends AbstractAnalyticsStatsTest { builder.append((String) getStatResult("cr", "csmin", VAL_TYPE.STRING)); builder.append((String) getStatResult("cr", "min", VAL_TYPE.STRING)); String concat = (String) getStatResult("cr", "ccmin", VAL_TYPE.STRING); - assertEquals(concat, builder.toString()); + assertEquals(getRawResponse(), concat, builder.toString()); builder.setLength(0); builder.append((String) getStatResult("cr", "csmax", VAL_TYPE.STRING)); builder.append((String) getStatResult("cr", "max", VAL_TYPE.STRING)); concat = (String) getStatResult("cr", "ccmax", VAL_TYPE.STRING); - assertEquals(concat, builder.toString()); + assertEquals(getRawResponse(), concat, builder.toString()); } @Test @@ -217,12 +217,12 @@ public class ExpressionTest extends AbstractAnalyticsStatsTest { StringBuilder builder = new StringBuilder(); builder.append((String) getStatResult("rr", "min", VAL_TYPE.STRING)); String rev = (String) getStatResult("rr", "rmin", VAL_TYPE.STRING); - assertEquals(rev, builder.reverse().toString()); + assertEquals(getRawResponse(), rev, builder.reverse().toString()); builder.setLength(0); builder.append((String) getStatResult("rr", "max", VAL_TYPE.STRING)); rev = (String) getStatResult("rr", "rmax", VAL_TYPE.STRING); - assertEquals(rev, builder.reverse().toString()); + assertEquals(getRawResponse(), rev, builder.reverse().toString()); } public static SolrQueryRequest request(String... args) { diff --git a/solr/core/src/test/org/apache/solr/analytics/util/valuesource/FunctionTest.java b/solr/core/src/test/org/apache/solr/analytics/util/valuesource/FunctionTest.java index eca83685249..a9dd8b749d6 100644 --- a/solr/core/src/test/org/apache/solr/analytics/util/valuesource/FunctionTest.java +++ b/solr/core/src/test/org/apache/solr/analytics/util/valuesource/FunctionTest.java @@ -89,148 +89,147 @@ public class FunctionTest extends AbstractAnalyticsStatsTest { public void addTest() throws Exception { double result = (Double)getStatResult("ar", "sum", VAL_TYPE.DOUBLE); double calculated = (Double)getStatResult("ar", "sumc", VAL_TYPE.DOUBLE); - assertTrue(result==calculated); - assertEquals("add sum", result, calculated, 0.0); + assertEquals(getRawResponse(), result, calculated, 0.0); + assertEquals(getRawResponse(), result, calculated, 0.0); result = (Double)getStatResult("ar", "mean", VAL_TYPE.DOUBLE); calculated = (Double)getStatResult("ar", "meanc", VAL_TYPE.DOUBLE); assertTrue(result==calculated); - assertEquals("add mean", result, calculated, 0.0); + assertEquals(getRawResponse(), result, calculated, 0.0); } @Test public void multiplyTest() throws Exception { double result = (Double)getStatResult("mr", "sum", VAL_TYPE.DOUBLE); double calculated = (Double)getStatResult("mr", "sumc", VAL_TYPE.DOUBLE); - assertEquals("multiply sum", result, calculated, 0.0); + assertEquals(getRawResponse(), result, calculated, 0.0); result = (Double)getStatResult("mr", "mean", VAL_TYPE.DOUBLE); calculated = (Double)getStatResult("mr", "meanc", VAL_TYPE.DOUBLE); - assertEquals("multiply mean", result, calculated, 0.0); + assertEquals(getRawResponse(), result, calculated, 0.0); } @Test public void divideTest() throws Exception { Double result = (Double)getStatResult("dr", "sum", VAL_TYPE.DOUBLE); Double calculated = (Double)getStatResult("dr", "sumc", VAL_TYPE.DOUBLE); - assertEquals("power sum", result, calculated, 0.0); + assertEquals(getRawResponse(), result, calculated, 0.0); result = (Double)getStatResult("dr", "mean", VAL_TYPE.DOUBLE); calculated = (Double)getStatResult("dr", "meanc", VAL_TYPE.DOUBLE); - assertEquals("power mean", result, calculated, 0.0); + assertEquals(getRawResponse(), result, calculated, 0.0); } @Test public void powerTest() throws Exception { double result = (Double)getStatResult("pr", "sum", VAL_TYPE.DOUBLE); double calculated = (Double)getStatResult("pr", "sumc", VAL_TYPE.DOUBLE); - assertTrue(result==calculated); - assertEquals("power sum", result, calculated, 0.0); + assertEquals(getRawResponse(), result, calculated, 0.0); + assertEquals(getRawResponse(), result, calculated, 0.0); result = (Double)getStatResult("pr", "mean", VAL_TYPE.DOUBLE); calculated = (Double)getStatResult("pr", "meanc", VAL_TYPE.DOUBLE); - assertTrue(result==calculated); - assertEquals("power mean", result, calculated, 0.0); + assertEquals(getRawResponse(), result, calculated, 0.0); + assertEquals(getRawResponse(), result, calculated, 0.0); } @Test public void negateTest() throws Exception { double result = (Double)getStatResult("nr", "sum", VAL_TYPE.DOUBLE); double calculated = (Double)getStatResult("nr", "sumc", VAL_TYPE.DOUBLE); - assertEquals("negate sum", result, calculated, 0.0); + assertEquals(getRawResponse(), result, calculated, 0.0); result = (Double)getStatResult("nr", "mean", VAL_TYPE.DOUBLE); calculated = (Double)getStatResult("nr", "meanc", VAL_TYPE.DOUBLE); - assertEquals("negate mean", result, calculated, 0.0); + assertEquals(getRawResponse(), result, calculated, 0.0); } @Test public void absoluteValueTest() throws Exception { double result = (Double)getStatResult("avr", "sum", VAL_TYPE.DOUBLE); double calculated = (Double)getStatResult("avr", "sumc", VAL_TYPE.DOUBLE); - System.out.println(Double.doubleToRawLongBits(result) + " " + Double.doubleToRawLongBits(calculated) ); - assertEquals("absolute values sum", result, calculated, 0.0); + assertEquals(getRawResponse(), result, calculated, 0.0); result = (Double)getStatResult("avr", "mean", VAL_TYPE.DOUBLE); calculated = (Double)getStatResult("avr", "meanc", VAL_TYPE.DOUBLE); - assertEquals("absolute values mean", result, calculated, 0.0); + assertEquals(getRawResponse(), result, calculated, 0.0); } @Test public void constantNumberTest() throws Exception { double result = (Double)getStatResult("cnr", "sum", VAL_TYPE.DOUBLE); double calculated = (Double)getStatResult("cnr", "sumc", VAL_TYPE.DOUBLE); - assertTrue(result==calculated); - assertEquals("constant sum", result, calculated, 0.0); + assertEquals(getRawResponse(), result, calculated, 0.0); + assertEquals(getRawResponse(), result, calculated, 0.0); result = (Double)getStatResult("cnr", "mean", VAL_TYPE.DOUBLE); calculated = (Double)getStatResult("cnr", "meanc", VAL_TYPE.DOUBLE); - assertTrue(result==calculated); - assertEquals("constant mean", result, calculated, 0.0); + assertEquals(getRawResponse(), result, calculated, 0.0); + assertEquals(getRawResponse(), result, calculated, 0.0); } @Test public void dateMathTest() throws Exception { String result = (String)getStatResult("dmr", "median", VAL_TYPE.STRING); String calculated = (String)getStatResult("dmr", "medianc", VAL_TYPE.STRING); - assertEquals("date math median", result, calculated); + assertEquals(getRawResponse(), result, calculated); result = (String)getStatResult("dmr", "max", VAL_TYPE.STRING); calculated = (String)getStatResult("dmr", "maxc", VAL_TYPE.STRING); - assertEquals("date math mean", result, calculated); + assertEquals(getRawResponse(), result, calculated); } @Test public void constantDateTest() throws Exception { String result = (String)getStatResult("cdr", "median", VAL_TYPE.STRING); String calculated = (String)getStatResult("cdr", "medianc", VAL_TYPE.STRING); - assertTrue(result.equals(calculated)); - assertEquals("constant date median", result, calculated); + assertEquals(getRawResponse(), result, calculated); + assertEquals(getRawResponse(), result, calculated); result = (String)getStatResult("cdr", "max", VAL_TYPE.STRING); calculated = (String)getStatResult("cdr", "maxc", VAL_TYPE.STRING); - assertEquals("constant date mean", result, calculated); + assertEquals(getRawResponse(), result, calculated); } @Test public void constantStringTest() throws Exception { String result = (String)getStatResult("csr", "min", VAL_TYPE.STRING); String calculated = (String)getStatResult("csr", "minc", VAL_TYPE.STRING); - assertEquals("constant min", result, calculated); + assertEquals(getRawResponse(), result, calculated); result = (String)getStatResult("csr", "max", VAL_TYPE.STRING); calculated = (String)getStatResult("csr", "maxc", VAL_TYPE.STRING); - assertEquals("constant max", result, calculated); + assertEquals(getRawResponse(), result, calculated); } @Test public void concatenateTest() throws Exception { String result = (String)getStatResult("cr", "min", VAL_TYPE.STRING); String calculated = (String)getStatResult("cr", "minc", VAL_TYPE.STRING); - assertEquals("concat min", result, calculated); + assertEquals(getRawResponse(), result, calculated); result = (String)getStatResult("cr", "max", VAL_TYPE.STRING); calculated = (String)getStatResult("cr", "maxc", VAL_TYPE.STRING); - assertEquals("concat max", result, calculated); + assertEquals(getRawResponse(), result, calculated); } @Test public void reverseTest() throws Exception { String result = (String)getStatResult("rr", "min", VAL_TYPE.STRING); String calculated = (String)getStatResult("rr", "minc", VAL_TYPE.STRING); - assertEquals("reverse min", result, calculated); + assertEquals(getRawResponse(), result, calculated); result = (String)getStatResult("rr", "max", VAL_TYPE.STRING); calculated = (String)getStatResult("rr", "maxc", VAL_TYPE.STRING); - assertEquals("reverse max", result, calculated); + assertEquals(getRawResponse(), result, calculated); } @Test public void missingTest() throws Exception { double min = (Double)getStatResult("ms", "min", VAL_TYPE.DOUBLE); double max = (Double)getStatResult("ms", "max", VAL_TYPE.DOUBLE); - assertEquals("missingTest 1", 48.0d, max, 0.0); - assertEquals("missingTest 2", 1.0d, min, 0.0); + assertEquals(getRawResponse(), 48.0d, max, 0.0); + assertEquals(getRawResponse(), 1.0d, min, 0.0); } } From 301d7a080ac850aebd99463431cbfd6a0f7214d8 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Thu, 28 Nov 2013 04:09:02 +0000 Subject: [PATCH 134/223] SOLR-5509: Always add a param for 'from' node. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1546278 13f79535-47bb-0310-9956-ffa450edef68 --- .../solr/servlet/SolrDispatchFilter.java | 4 +-- .../solr/update/SolrCmdDistributor.java | 2 +- .../processor/DistributedUpdateProcessor.java | 34 +++++++------------ 3 files changed, 14 insertions(+), 26 deletions(-) diff --git a/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java b/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java index 756ddb49855..01b23eae3c0 100644 --- a/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java +++ b/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java @@ -52,7 +52,6 @@ import org.apache.solr.response.QueryResponseWriter; import org.apache.solr.response.SolrQueryResponse; import org.apache.solr.servlet.cache.HttpCacheHeaderUtil; import org.apache.solr.servlet.cache.Method; -import org.apache.solr.update.processor.DistributedUpdateProcessor; import org.apache.solr.update.processor.DistributingUpdateProcessorFactory; import org.apache.solr.util.FastWriter; import org.slf4j.Logger; @@ -319,8 +318,7 @@ public class SolrDispatchFilter implements Filter SolrParams queryParams = SolrRequestParsers.parseQueryString(req.getQueryString()); if (coreUrl != null && queryParams - .get(DistributingUpdateProcessorFactory.DISTRIB_UPDATE_PARAM) == null - && queryParams.get(DistributedUpdateProcessor.DISTRIB_FROM) == null) { + .get(DistributingUpdateProcessorFactory.DISTRIB_UPDATE_PARAM) == null) { path = path.substring(idx); remoteQuery(coreUrl + path, req, solrReq, resp); return; diff --git a/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java b/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java index fda2fa86840..9967550d5e5 100644 --- a/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java +++ b/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java @@ -197,7 +197,7 @@ public class SolrCmdDistributor { addCommit(uReq, cmd); - log.debug("Distrib commit to:" + nodes + " params:" + params); + log.debug("Distrib commit to: {} params: {}", nodes, params); for (Node node : nodes) { submit(new Req(cmd.toString(), node, uReq, false)); diff --git a/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java b/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java index b07e9aea13b..e2db6812b9c 100644 --- a/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java +++ b/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java @@ -576,13 +576,8 @@ public class DistributedUpdateProcessor extends UpdateRequestProcessor { (isLeader || isSubShardLeader ? DistribPhase.FROMLEADER.toString() : DistribPhase.TOLEADER.toString())); - if (isLeader || isSubShardLeader) { - params.set(DISTRIB_FROM, ZkCoreNodeProps.getCoreUrl( - zkController.getBaseUrl(), req.getCore().getName())); - } else if (log.isDebugEnabled()) { - params.set(DISTRIB_FROM, ZkCoreNodeProps.getCoreUrl( - zkController.getBaseUrl(), req.getCore().getName())); - } + params.set(DISTRIB_FROM, ZkCoreNodeProps.getCoreUrl( + zkController.getBaseUrl(), req.getCore().getName())); cmdDistrib.distribAdd(cmd, nodes, params); } @@ -1005,16 +1000,11 @@ public class DistributedUpdateProcessor extends UpdateRequestProcessor { params = new ModifiableSolrParams(filterParams(req.getParams())); params.set(DISTRIB_UPDATE_PARAM, - (isLeader || isSubShardLeader ? - DistribPhase.FROMLEADER.toString() : - DistribPhase.TOLEADER.toString())); - if (isLeader || isSubShardLeader) { - params.set(DISTRIB_FROM, ZkCoreNodeProps.getCoreUrl( - zkController.getBaseUrl(), req.getCore().getName())); - } else if (log.isDebugEnabled()) { - params.set(DISTRIB_FROM, ZkCoreNodeProps.getCoreUrl( - zkController.getBaseUrl(), req.getCore().getName())); - } + (isLeader || isSubShardLeader ? DistribPhase.FROMLEADER.toString() + : DistribPhase.TOLEADER.toString())); + params.set(DISTRIB_FROM, ZkCoreNodeProps.getCoreUrl( + zkController.getBaseUrl(), req.getCore().getName())); + cmdDistrib.distribDelete(cmd, nodes, params); } @@ -1075,10 +1065,8 @@ public class DistributedUpdateProcessor extends UpdateRequestProcessor { ModifiableSolrParams outParams = new ModifiableSolrParams(filterParams(req.getParams())); outParams.set(DISTRIB_UPDATE_PARAM, DistribPhase.TOLEADER.toString()); - if (log.isDebugEnabled()) { - outParams.set(DISTRIB_FROM, ZkCoreNodeProps.getCoreUrl( - zkController.getBaseUrl(), req.getCore().getName())); - } + outParams.set(DISTRIB_FROM, ZkCoreNodeProps.getCoreUrl( + zkController.getBaseUrl(), req.getCore().getName())); SolrParams params = req.getParams(); String route = params.get(ShardParams._ROUTE_); @@ -1434,7 +1422,9 @@ public class DistributedUpdateProcessor extends UpdateRequestProcessor { ModifiableSolrParams params = new ModifiableSolrParams(filterParams(req.getParams())); if (!req.getParams().getBool(COMMIT_END_POINT, false)) { params.set(COMMIT_END_POINT, true); - + params.set(DISTRIB_UPDATE_PARAM, DistribPhase.FROMLEADER.toString()); + params.set(DISTRIB_FROM, ZkCoreNodeProps.getCoreUrl( + zkController.getBaseUrl(), req.getCore().getName())); if (nodes != null) { cmdDistrib.distribCommit(cmd, nodes, params); finish(); From 8ed8d46efe812df21c14fcf4bf8946c889fba27b Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Thu, 28 Nov 2013 05:15:16 +0000 Subject: [PATCH 135/223] SOLR-5509: Do not retry to yourself. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1546286 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/solr/update/SolrCmdDistributor.java | 10 ++++++++-- .../update/processor/DistributedUpdateProcessor.java | 3 ++- .../org/apache/solr/update/SolrCmdDistributorTest.java | 8 ++++---- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java b/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java index 9967550d5e5..1fa6850d676 100644 --- a/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java +++ b/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java @@ -360,12 +360,14 @@ public class SolrCmdDistributor { private ZkStateReader zkStateReader; private String collection; private String shardId; + private String fromAddress; - public RetryNode(ZkCoreNodeProps nodeProps, ZkStateReader zkStateReader, String collection, String shardId) { + public RetryNode(ZkCoreNodeProps nodeProps, ZkStateReader zkStateReader, String collection, String shardId, String fromCoreUrl) { super(nodeProps); this.zkStateReader = zkStateReader; this.collection = collection; this.shardId = shardId; + this.fromAddress = fromCoreUrl; } @Override @@ -382,7 +384,11 @@ public class SolrCmdDistributor { log.warn(null, e); return true; } - + + if (fromAddress.equals(leaderProps.getCoreUrl())) { + // we became the leader + return false; + } this.nodeProps = leaderProps; return true; diff --git a/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java b/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java index e2db6812b9c..4bc4e92c7f7 100644 --- a/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java +++ b/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java @@ -298,7 +298,8 @@ public class DistributedUpdateProcessor extends UpdateRequestProcessor { } else { // I need to forward onto the leader... nodes = new ArrayList(1); - nodes.add(new RetryNode(new ZkCoreNodeProps(leaderReplica), zkController.getZkStateReader(), collection, shardId)); + nodes.add(new RetryNode(new ZkCoreNodeProps(leaderReplica), zkController.getZkStateReader(), collection, shardId, ZkCoreNodeProps.getCoreUrl( + zkController.getBaseUrl(), req.getCore().getName()))); forwardToLeader = true; } diff --git a/solr/core/src/test/org/apache/solr/update/SolrCmdDistributorTest.java b/solr/core/src/test/org/apache/solr/update/SolrCmdDistributorTest.java index 3b1ef9bfc33..a7a4cf8ee25 100644 --- a/solr/core/src/test/org/apache/solr/update/SolrCmdDistributorTest.java +++ b/solr/core/src/test/org/apache/solr/update/SolrCmdDistributorTest.java @@ -331,7 +331,7 @@ public class SolrCmdDistributorTest extends BaseDistributedSearchTestCase { final AtomicInteger retries = new AtomicInteger(); ZkNodeProps nodeProps = new ZkNodeProps(ZkStateReader.BASE_URL_PROP, solrclient1.getBaseURL(), ZkStateReader.CORE_NAME_PROP, ""); - RetryNode retryNode = new RetryNode(new ZkCoreNodeProps(nodeProps), null, "collection1", "shard1") { + RetryNode retryNode = new RetryNode(new ZkCoreNodeProps(nodeProps), null, "collection1", "shard1", "locahost") { @Override public boolean checkRetry() { retries.incrementAndGet(); @@ -367,7 +367,7 @@ public class SolrCmdDistributorTest extends BaseDistributedSearchTestCase { final AtomicInteger retries = new AtomicInteger(); nodeProps = new ZkNodeProps(ZkStateReader.BASE_URL_PROP, solrclient.getBaseURL(), ZkStateReader.CORE_NAME_PROP, ""); - RetryNode retryNode = new RetryNode(new ZkCoreNodeProps(nodeProps), null, "collection1", "shard1") { + RetryNode retryNode = new RetryNode(new ZkCoreNodeProps(nodeProps), null, "collection1", "shard1", "locahost") { @Override public boolean checkRetry() { ss.setExp(null); @@ -413,7 +413,7 @@ public class SolrCmdDistributorTest extends BaseDistributedSearchTestCase { final AtomicInteger retries = new AtomicInteger(); nodeProps = new ZkNodeProps(ZkStateReader.BASE_URL_PROP, solrclient.getBaseURL(), ZkStateReader.CORE_NAME_PROP, ""); - RetryNode retryNode = new RetryNode(new ZkCoreNodeProps(nodeProps), null, "collection1", "shard1") { + RetryNode retryNode = new RetryNode(new ZkCoreNodeProps(nodeProps), null, "collection1", "shard1", "locahost") { @Override public boolean checkRetry() { retries.incrementAndGet(); @@ -457,7 +457,7 @@ public class SolrCmdDistributorTest extends BaseDistributedSearchTestCase { ArrayList nodes = new ArrayList(); ZkNodeProps nodeProps = new ZkNodeProps(ZkStateReader.BASE_URL_PROP, "[ff01::114]:33332" + context, ZkStateReader.CORE_NAME_PROP, ""); - RetryNode retryNode = new RetryNode(new ZkCoreNodeProps(nodeProps), null, "collection1", "shard1") { + RetryNode retryNode = new RetryNode(new ZkCoreNodeProps(nodeProps), null, "collection1", "shard1", "locahost") { @Override public boolean checkRetry() { ZkNodeProps leaderProps = new ZkNodeProps(ZkStateReader.BASE_URL_PROP, solrclient.getBaseURL(), From 921bd4791957746f137f5f9e21cb1b7d0d50a270 Mon Sep 17 00:00:00 2001 From: Steven Rowe Date: Thu, 28 Nov 2013 21:00:28 +0000 Subject: [PATCH 136/223] SOLR-5354: Distributed sort is broken with CUSTOM FieldType git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1546457 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 3 + .../apache/solr/schema/ICUCollationField.java | 20 ++ .../handler/component/QueryComponent.java | 53 ++-- .../solr/handler/component/ShardDoc.java | 169 ++++------- .../apache/solr/schema/CollationField.java | 20 ++ .../org/apache/solr/schema/FieldType.java | 16 + .../solr/schema/SortableDoubleField.java | 21 ++ .../solr/schema/SortableFloatField.java | 21 ++ .../apache/solr/schema/SortableIntField.java | 21 ++ .../apache/solr/schema/SortableLongField.java | 21 ++ .../java/org/apache/solr/schema/StrField.java | 23 ++ .../org/apache/solr/schema/TextField.java | 23 ++ .../collection1/conf/schema-custom-field.xml | 42 +++ .../conf/schema-distributed-missing-sort.xml | 83 +++++ .../solr/TestDistributedMissingSort.java | 287 ++++++++++++++++++ ...stributedQueryComponentCustomSortTest.java | 110 +++++++ .../solr/schema/SortableBinaryField.java | 103 +++++++ .../apache/solr/search/TestCustomSort.java | 126 ++++++++ .../solr/BaseDistributedSearchTestCase.java | 16 +- .../java/org/apache/solr/SolrTestCaseJ4.java | 26 ++ 20 files changed, 1057 insertions(+), 147 deletions(-) create mode 100644 solr/core/src/test-files/solr/collection1/conf/schema-custom-field.xml create mode 100644 solr/core/src/test-files/solr/collection1/conf/schema-distributed-missing-sort.xml create mode 100644 solr/core/src/test/org/apache/solr/TestDistributedMissingSort.java create mode 100644 solr/core/src/test/org/apache/solr/handler/component/DistributedQueryComponentCustomSortTest.java create mode 100644 solr/core/src/test/org/apache/solr/schema/SortableBinaryField.java create mode 100644 solr/core/src/test/org/apache/solr/search/TestCustomSort.java diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 32b69c18ef0..6bbe418ecf3 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -159,6 +159,9 @@ Bug Fixes * SOLR-5494: CoreContainer#remove throws NPE rather than returning null when a SolrCore does not exist in core discovery mode. (Mark Miller) + +* SOLR-5354: Distributed sort is broken with CUSTOM FieldType. + (Steve Rowe, hossman, Jessica Cheng) Optimizations ---------------------- diff --git a/solr/contrib/analysis-extras/src/java/org/apache/solr/schema/ICUCollationField.java b/solr/contrib/analysis-extras/src/java/org/apache/solr/schema/ICUCollationField.java index 30cba33d96e..7c33a3dd335 100644 --- a/solr/contrib/analysis-extras/src/java/org/apache/solr/schema/ICUCollationField.java +++ b/solr/contrib/analysis-extras/src/java/org/apache/solr/schema/ICUCollationField.java @@ -43,6 +43,7 @@ import org.apache.lucene.util.Version; import org.apache.lucene.analysis.util.ResourceLoader; import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrException.ErrorCode; +import org.apache.solr.common.util.Base64; import org.apache.solr.response.TextResponseWriter; import org.apache.solr.search.QParser; @@ -300,4 +301,23 @@ public class ICUCollationField extends FieldType { return Collections.singletonList(createField(field, value, boost)); } } + + @Override + public Object marshalSortValue(Object value) { + if (null == value) { + return null; + } + final BytesRef val = (BytesRef)value; + return Base64.byteArrayToBase64(val.bytes, val.offset, val.length); + } + + @Override + public Object unmarshalSortValue(Object value) { + if (null == value) { + return null; + } + final String val = (String)value; + final byte[] bytes = Base64.base64ToByteArray(val); + return new BytesRef(bytes); + } } diff --git a/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java b/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java index 0a020569a66..ca072e18dec 100644 --- a/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java +++ b/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java @@ -34,7 +34,6 @@ import org.apache.lucene.search.grouping.SearchGroup; import org.apache.lucene.search.grouping.TopGroups; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.CharsRef; -import org.apache.lucene.util.UnicodeUtil; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrDocumentList; @@ -47,6 +46,7 @@ import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.ResultContext; import org.apache.solr.response.SolrQueryResponse; import org.apache.solr.schema.FieldType; +import org.apache.solr.schema.IndexSchema; import org.apache.solr.schema.SchemaField; import org.apache.solr.search.DocIterator; import org.apache.solr.search.DocList; @@ -449,7 +449,6 @@ public class QueryComponent extends SearchComponent { SolrQueryRequest req = rb.req; SolrQueryResponse rsp = rb.rsp; - final CharsRef spare = new CharsRef(); // The query cache doesn't currently store sort field values, and SolrIndexSearcher doesn't // currently have an option to return sort field values. Because of this, we // take the documents given and re-derive the sort values. @@ -458,7 +457,6 @@ public class QueryComponent extends SearchComponent Sort sort = searcher.weightSort(rb.getSortSpec().getSort()); SortField[] sortFields = sort==null ? new SortField[]{SortField.FIELD_SCORE} : sort.getSort(); NamedList sortVals = new NamedList(); // order is important for the sort fields - Field field = new StringField("dummy", "", Field.Store.NO); // a dummy Field IndexReaderContext topReaderContext = searcher.getTopReaderContext(); List leaves = topReaderContext.leaves(); AtomicReaderContext currentLeaf = null; @@ -516,27 +514,7 @@ public class QueryComponent extends SearchComponent doc -= currentLeaf.docBase; // adjust for what segment this is in comparator.copy(0, doc); Object val = comparator.value(0); - - // Sortable float, double, int, long types all just use a string - // comparator. For these, we need to put the type into a readable - // format. One reason for this is that XML can't represent all - // string values (or even all unicode code points). - // indexedToReadable() should be a no-op and should - // thus be harmless anyway (for all current ways anyway) - if (val instanceof String) { - field.setStringValue((String)val); - val = ft.toObject(field); - } - - // Must do the same conversion when sorting by a - // String field in Lucene, which returns the terms - // data as BytesRef: - if (val instanceof BytesRef) { - UnicodeUtil.UTF8toUTF16((BytesRef)val, spare); - field.setStringValue(spare.toString()); - val = ft.toObject(field); - } - + if (null != ft) val = ft.marshalSortValue(val); vals[position] = val; } @@ -778,7 +756,8 @@ public class QueryComponent extends SearchComponent sortFields = new SortField[]{SortField.FIELD_SCORE}; } - SchemaField uniqueKeyField = rb.req.getSchema().getUniqueKeyField(); + IndexSchema schema = rb.req.getSchema(); + SchemaField uniqueKeyField = schema.getUniqueKeyField(); // id to shard mapping, to eliminate any accidental dups @@ -787,7 +766,7 @@ public class QueryComponent extends SearchComponent // Merge the docs via a priority queue so we don't have to sort *all* of the // documents... we only need to order the top (rows+start) ShardFieldSortedHitQueue queue; - queue = new ShardFieldSortedHitQueue(sortFields, ss.getOffset() + ss.getCount()); + queue = new ShardFieldSortedHitQueue(sortFields, ss.getOffset() + ss.getCount(), rb.req.getSearcher()); NamedList shardInfo = null; if(rb.req.getParams().getBool(ShardParams.SHARDS_INFO, false)) { @@ -886,7 +865,7 @@ public class QueryComponent extends SearchComponent } } - shardDoc.sortFieldValues = sortFieldValues; + shardDoc.sortFieldValues = unmarshalSortValues(sortFieldValues, schema); queue.insertWithOverflow(shardDoc); } // end for-each-doc-in-response @@ -928,6 +907,26 @@ public class QueryComponent extends SearchComponent } } + private NamedList unmarshalSortValues(NamedList sortFieldValues, IndexSchema schema) { + NamedList unmarshalledSortValsPerField = new NamedList(); + for (int fieldNum = 0 ; fieldNum < sortFieldValues.size() ; ++fieldNum) { + String fieldName = sortFieldValues.getName(fieldNum); + SchemaField field = schema.getFieldOrNull(fieldName); + List sortVals = (List)sortFieldValues.getVal(fieldNum); + if (null == field) { + unmarshalledSortValsPerField.add(fieldName, sortVals); + } else { + FieldType fieldType = field.getType(); + List unmarshalledSortVals = new ArrayList(); + for (Object sortVal : sortVals) { + unmarshalledSortVals.add(fieldType.unmarshalSortValue(sortVal)); + } + unmarshalledSortValsPerField.add(fieldName, unmarshalledSortVals); + } + } + return unmarshalledSortValsPerField; + } + private void createRetrieveDocs(ResponseBuilder rb) { // TODO: in a system with nTiers > 2, we could be passed "ids" here diff --git a/solr/core/src/java/org/apache/solr/handler/component/ShardDoc.java b/solr/core/src/java/org/apache/solr/handler/component/ShardDoc.java index 3ffb0a97ecc..603f262d925 100644 --- a/solr/core/src/java/org/apache/solr/handler/component/ShardDoc.java +++ b/solr/core/src/java/org/apache/solr/handler/component/ShardDoc.java @@ -16,18 +16,21 @@ */ package org.apache.solr.handler.component; -import org.apache.lucene.search.FieldComparatorSource; +import org.apache.lucene.search.FieldComparator; import org.apache.lucene.search.FieldDoc; +import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.SortField; import org.apache.lucene.util.PriorityQueue; +import org.apache.solr.common.SolrException; import org.apache.solr.common.util.NamedList; -import org.apache.solr.search.MissingStringLastComparatorSource; +import org.apache.solr.search.SolrIndexSearcher; -import java.text.Collator; +import java.io.IOException; import java.util.ArrayList; import java.util.Comparator; import java.util.List; -import java.util.Locale; + +import static org.apache.solr.common.SolrException.ErrorCode.SERVER_ERROR; public class ShardDoc extends FieldDoc { public String shard; @@ -101,7 +104,7 @@ public class ShardDoc extends FieldDoc { class ShardFieldSortedHitQueue extends PriorityQueue { /** Stores a comparator corresponding to each field being sorted by */ - protected Comparator[] comparators; + protected Comparator[] comparators; /** Stores the sort criteria being used. */ protected SortField[] fields; @@ -109,9 +112,10 @@ class ShardFieldSortedHitQueue extends PriorityQueue { /** The order of these fieldNames should correspond to the order of sort field values retrieved from the shard */ protected List fieldNames = new ArrayList(); - public ShardFieldSortedHitQueue(SortField[] fields, int size) { + public ShardFieldSortedHitQueue(SortField[] fields, int size, IndexSearcher searcher) { super(size); final int n = fields.length; + //noinspection unchecked comparators = new Comparator[n]; this.fields = new SortField[n]; for (int i = 0; i < n; ++i) { @@ -123,8 +127,7 @@ class ShardFieldSortedHitQueue extends PriorityQueue { } String fieldname = fields[i].getField(); - comparators[i] = getCachedComparator(fieldname, fields[i] - .getType(), fields[i].getComparatorSource()); + comparators[i] = getCachedComparator(fields[i], searcher); if (fields[i].getType() == SortField.Type.STRING) { this.fields[i] = new SortField(fieldname, SortField.Type.STRING, @@ -169,47 +172,36 @@ class ShardFieldSortedHitQueue extends PriorityQueue { return c < 0; } - Comparator getCachedComparator(String fieldname, SortField.Type type, FieldComparatorSource factory) { - Comparator comparator = null; - switch (type) { - case SCORE: - comparator = comparatorScore(fieldname); - break; - case STRING: - comparator = comparatorNatural(fieldname); - break; - case CUSTOM: - if (factory instanceof MissingStringLastComparatorSource){ - comparator = comparatorMissingStringLast(fieldname); - } else { - // TODO: support other types such as random... is there a way to - // support generically? Perhaps just comparing Object - comparator = comparatorNatural(fieldname); - // throw new RuntimeException("Custom sort not supported factory is "+factory.getClass()); + Comparator getCachedComparator(SortField sortField, IndexSearcher searcher) { + SortField.Type type = sortField.getType(); + if (type == SortField.Type.SCORE) { + return comparatorScore(); + } else if (type == SortField.Type.REWRITEABLE) { + try { + sortField = sortField.rewrite(searcher); + } catch (IOException e) { + throw new SolrException(SERVER_ERROR, "Exception rewriting sort field " + sortField, e); } - break; - case DOC: - // TODO: we can support this! - throw new RuntimeException("Doc sort not supported"); - default: - comparator = comparatorNatural(fieldname); - break; } - return comparator; + return comparatorFieldComparator(sortField); } - class ShardComparator implements Comparator { - String fieldName; - int fieldNum; - public ShardComparator(String fieldName) { - this.fieldName = fieldName; - this.fieldNum=0; + abstract class ShardComparator implements Comparator { + final SortField sortField; + final String fieldName; + final int fieldNum; + + public ShardComparator(SortField sortField) { + this.sortField = sortField; + this.fieldName = sortField.getField(); + int fieldNum = 0; for (int i=0; i { List lst = (List)shardDoc.sortFieldValues.getVal(fieldNum); return lst.get(shardDoc.orderInShard); } - - @Override - public int compare(Object o1, Object o2) { - return 0; - } } - static Comparator comparatorScore(final String fieldName) { - return new Comparator() { + static Comparator comparatorScore() { + return new Comparator() { @Override - public final int compare(final Object o1, final Object o2) { - ShardDoc e1 = (ShardDoc) o1; - ShardDoc e2 = (ShardDoc) o2; - - final float f1 = e1.score; - final float f2 = e2.score; + public final int compare(final ShardDoc o1, final ShardDoc o2) { + final float f1 = o1.score; + final float f2 = o2.score; if (f1 < f2) return -1; if (f1 > f2) @@ -242,71 +226,24 @@ class ShardFieldSortedHitQueue extends PriorityQueue { }; } - // The lucene natural sort ordering corresponds to numeric - // and string natural sort orderings (ascending). Since - // the PriorityQueue keeps the biggest elements by default, - // we need to reverse the natural compare ordering so that the - // smallest elements are kept instead of the largest... hence - // the negative sign on the final compareTo(). - Comparator comparatorNatural(String fieldName) { - return new ShardComparator(fieldName) { + Comparator comparatorFieldComparator(SortField sortField) { + final FieldComparator fieldComparator; + try { + fieldComparator = sortField.getComparator(0, 0); + } catch (IOException e) { + throw new RuntimeException("Unable to get FieldComparator for sortField " + sortField); + } + + return new ShardComparator(sortField) { + // Since the PriorityQueue keeps the biggest elements by default, + // we need to reverse the field compare ordering so that the + // smallest elements are kept instead of the largest... hence + // the negative sign. @Override - public final int compare(final Object o1, final Object o2) { - ShardDoc sd1 = (ShardDoc) o1; - ShardDoc sd2 = (ShardDoc) o2; - Comparable v1 = (Comparable)sortVal(sd1); - Comparable v2 = (Comparable)sortVal(sd2); - if (v1==v2) - return 0; - if (v1==null) - return 1; - if(v2==null) - return -1; - return -v1.compareTo(v2); + public int compare(final ShardDoc o1, final ShardDoc o2) { + //noinspection unchecked + return -fieldComparator.compareValues(sortVal(o1), sortVal(o2)); } }; } - - - Comparator comparatorStringLocale(final String fieldName, - Locale locale) { - final Collator collator = Collator.getInstance(locale); - return new ShardComparator(fieldName) { - @Override - public final int compare(final Object o1, final Object o2) { - ShardDoc sd1 = (ShardDoc) o1; - ShardDoc sd2 = (ShardDoc) o2; - Comparable v1 = (Comparable)sortVal(sd1); - Comparable v2 = (Comparable)sortVal(sd2); - if (v1==v2) - return 0; - if (v1==null) - return 1; - if(v2==null) - return -1; - return -collator.compare(v1,v2); - } - }; - } - - - Comparator comparatorMissingStringLast(final String fieldName) { - return new ShardComparator(fieldName) { - @Override - public final int compare(final Object o1, final Object o2) { - ShardDoc sd1 = (ShardDoc) o1; - ShardDoc sd2 = (ShardDoc) o2; - Comparable v1 = (Comparable)sortVal(sd1); - Comparable v2 = (Comparable)sortVal(sd2); - if (v1==v2) - return 0; - if (v1==null) - return -1; - if(v2==null) - return 1; - return -v1.compareTo(v2); - } - }; - } - } diff --git a/solr/core/src/java/org/apache/solr/schema/CollationField.java b/solr/core/src/java/org/apache/solr/schema/CollationField.java index cfea5f348d6..5b46159bae4 100644 --- a/solr/core/src/java/org/apache/solr/schema/CollationField.java +++ b/solr/core/src/java/org/apache/solr/schema/CollationField.java @@ -47,6 +47,7 @@ import org.apache.lucene.util.Version; import org.apache.lucene.analysis.util.ResourceLoader; import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrException.ErrorCode; +import org.apache.solr.common.util.Base64; import org.apache.solr.response.TextResponseWriter; import org.apache.solr.search.QParser; @@ -275,4 +276,23 @@ public class CollationField extends FieldType { return Collections.singletonList(createField(field, value, boost)); } } + + @Override + public Object marshalSortValue(Object value) { + if (null == value) { + return null; + } + final BytesRef val = (BytesRef)value; + return Base64.byteArrayToBase64(val.bytes, val.offset, val.length); + } + + @Override + public Object unmarshalSortValue(Object value) { + if (null == value) { + return null; + } + final String val = (String)value; + final byte[] bytes = Base64.base64ToByteArray(val); + return new BytesRef(bytes); + } } diff --git a/solr/core/src/java/org/apache/solr/schema/FieldType.java b/solr/core/src/java/org/apache/solr/schema/FieldType.java index 5d03d383060..8d2a1d3aded 100644 --- a/solr/core/src/java/org/apache/solr/schema/FieldType.java +++ b/solr/core/src/java/org/apache/solr/schema/FieldType.java @@ -932,4 +932,20 @@ public abstract class FieldType extends FieldProperties { } return analyzerProps; } + + /** + * Convert a value used by the FieldComparator for this FieldType's SortField + * into a marshalable value for distributed sorting. + */ + public Object marshalSortValue(Object value) { + return value; + } + + /** + * Convert a value marshaled via {@link #marshalSortValue} back + * into a value usable by the FieldComparator for this FieldType's SortField + */ + public Object unmarshalSortValue(Object value) { + return value; + } } diff --git a/solr/core/src/java/org/apache/solr/schema/SortableDoubleField.java b/solr/core/src/java/org/apache/solr/schema/SortableDoubleField.java index 2f4b0a65dda..382dfd430d4 100644 --- a/solr/core/src/java/org/apache/solr/schema/SortableDoubleField.java +++ b/solr/core/src/java/org/apache/solr/schema/SortableDoubleField.java @@ -100,6 +100,27 @@ public class SortableDoubleField extends PrimitiveFieldType implements DoubleVal String sval = f.stringValue(); writer.writeDouble(name, NumberUtils.SortableStr2double(sval)); } + + @Override + public Object marshalSortValue(Object value) { + if (null == value) { + return null; + } + CharsRef chars = new CharsRef(); + UnicodeUtil.UTF8toUTF16((BytesRef)value, chars); + return NumberUtils.SortableStr2double(chars.toString()); + } + + @Override + public Object unmarshalSortValue(Object value) { + if (null == value) { + return null; + } + String sortableString = NumberUtils.double2sortableStr(value.toString()); + BytesRef bytes = new BytesRef(); + UnicodeUtil.UTF16toUTF8(sortableString, 0, sortableString.length(), bytes); + return bytes; + } } class SortableDoubleFieldSource extends FieldCacheSource { diff --git a/solr/core/src/java/org/apache/solr/schema/SortableFloatField.java b/solr/core/src/java/org/apache/solr/schema/SortableFloatField.java index e66e25563e7..aa7a075c867 100644 --- a/solr/core/src/java/org/apache/solr/schema/SortableFloatField.java +++ b/solr/core/src/java/org/apache/solr/schema/SortableFloatField.java @@ -101,6 +101,27 @@ public class SortableFloatField extends PrimitiveFieldType implements FloatValue String sval = f.stringValue(); writer.writeFloat(name, NumberUtils.SortableStr2float(sval)); } + + @Override + public Object marshalSortValue(Object value) { + if (null == value) { + return null; + } + CharsRef chars = new CharsRef(); + UnicodeUtil.UTF8toUTF16((BytesRef)value, chars); + return NumberUtils.SortableStr2float(chars.toString()); + } + + @Override + public Object unmarshalSortValue(Object value) { + if (null == value) { + return null; + } + String sortableString = NumberUtils.float2sortableStr(value.toString()); + BytesRef bytes = new BytesRef(); + UnicodeUtil.UTF16toUTF8(sortableString, 0, sortableString.length(), bytes); + return bytes; + } } diff --git a/solr/core/src/java/org/apache/solr/schema/SortableIntField.java b/solr/core/src/java/org/apache/solr/schema/SortableIntField.java index 955857370f9..97cbfe2b134 100644 --- a/solr/core/src/java/org/apache/solr/schema/SortableIntField.java +++ b/solr/core/src/java/org/apache/solr/schema/SortableIntField.java @@ -104,6 +104,27 @@ public class SortableIntField extends PrimitiveFieldType implements IntValueFiel String sval = f.stringValue(); writer.writeInt(name, NumberUtils.SortableStr2int(sval,0,sval.length())); } + + @Override + public Object marshalSortValue(Object value) { + if (null == value) { + return null; + } + CharsRef chars = new CharsRef(); + UnicodeUtil.UTF8toUTF16((BytesRef)value, chars); + return NumberUtils.SortableStr2int(chars.toString()); + } + + @Override + public Object unmarshalSortValue(Object value) { + if (null == value) { + return null; + } + String sortableString = NumberUtils.int2sortableStr(value.toString()); + BytesRef bytes = new BytesRef(); + UnicodeUtil.UTF16toUTF8(sortableString, 0, sortableString.length(), bytes); + return bytes; + } } diff --git a/solr/core/src/java/org/apache/solr/schema/SortableLongField.java b/solr/core/src/java/org/apache/solr/schema/SortableLongField.java index 0e61eef6f91..3c48af14bad 100644 --- a/solr/core/src/java/org/apache/solr/schema/SortableLongField.java +++ b/solr/core/src/java/org/apache/solr/schema/SortableLongField.java @@ -100,6 +100,27 @@ public class SortableLongField extends PrimitiveFieldType { String sval = f.stringValue(); writer.writeLong(name, NumberUtils.SortableStr2long(sval,0,sval.length())); } + + @Override + public Object marshalSortValue(Object value) { + if (null == value) { + return null; + } + CharsRef chars = new CharsRef(); + UnicodeUtil.UTF8toUTF16((BytesRef)value, chars); + return NumberUtils.SortableStr2long(chars.toString()); + } + + @Override + public Object unmarshalSortValue(Object value) { + if (null == value) { + return null; + } + String sortableString = NumberUtils.long2sortableStr(value.toString()); + BytesRef bytes = new BytesRef(); + UnicodeUtil.UTF16toUTF8(sortableString, 0, sortableString.length(), bytes); + return bytes; + } } diff --git a/solr/core/src/java/org/apache/solr/schema/StrField.java b/solr/core/src/java/org/apache/solr/schema/StrField.java index 2c9600c67de..15060b9b74d 100644 --- a/solr/core/src/java/org/apache/solr/schema/StrField.java +++ b/solr/core/src/java/org/apache/solr/schema/StrField.java @@ -29,6 +29,8 @@ import org.apache.lucene.index.StorableField; import org.apache.lucene.queries.function.ValueSource; import org.apache.lucene.search.SortField; import org.apache.lucene.util.BytesRef; +import org.apache.lucene.util.CharsRef; +import org.apache.lucene.util.UnicodeUtil; import org.apache.solr.response.TextResponseWriter; import org.apache.solr.search.QParser; @@ -81,6 +83,27 @@ public class StrField extends PrimitiveFieldType { @Override public void checkSchemaField(SchemaField field) { } + + @Override + public Object marshalSortValue(Object value) { + if (null == value) { + return null; + } + CharsRef spare = new CharsRef(); + UnicodeUtil.UTF8toUTF16((BytesRef)value, spare); + return spare.toString(); + } + + @Override + public Object unmarshalSortValue(Object value) { + if (null == value) { + return null; + } + BytesRef spare = new BytesRef(); + String stringVal = (String)value; + UnicodeUtil.UTF16toUTF8(stringVal, 0, stringVal.length(), spare); + return spare; + } } diff --git a/solr/core/src/java/org/apache/solr/schema/TextField.java b/solr/core/src/java/org/apache/solr/schema/TextField.java index b7fd860f11a..f0741f51445 100644 --- a/solr/core/src/java/org/apache/solr/schema/TextField.java +++ b/solr/core/src/java/org/apache/solr/schema/TextField.java @@ -23,7 +23,9 @@ import org.apache.lucene.index.StorableField; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.util.BytesRef; +import org.apache.lucene.util.CharsRef; import org.apache.lucene.util.QueryBuilder; +import org.apache.lucene.util.UnicodeUtil; import org.apache.solr.common.SolrException; import org.apache.solr.response.TextResponseWriter; import org.apache.solr.search.QParser; @@ -165,4 +167,25 @@ public class TextField extends FieldType { public boolean isExplicitMultiTermAnalyzer() { return isExplicitMultiTermAnalyzer; } + + @Override + public Object marshalSortValue(Object value) { + if (null == value) { + return null; + } + CharsRef spare = new CharsRef(); + UnicodeUtil.UTF8toUTF16((BytesRef)value, spare); + return spare.toString(); + } + + @Override + public Object unmarshalSortValue(Object value) { + if (null == value) { + return null; + } + BytesRef spare = new BytesRef(); + String stringVal = (String)value; + UnicodeUtil.UTF16toUTF8(stringVal, 0, stringVal.length(), spare); + return spare; + } } diff --git a/solr/core/src/test-files/solr/collection1/conf/schema-custom-field.xml b/solr/core/src/test-files/solr/collection1/conf/schema-custom-field.xml new file mode 100644 index 00000000000..de206bce0bb --- /dev/null +++ b/solr/core/src/test-files/solr/collection1/conf/schema-custom-field.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + text + id + diff --git a/solr/core/src/test-files/solr/collection1/conf/schema-distributed-missing-sort.xml b/solr/core/src/test-files/solr/collection1/conf/schema-distributed-missing-sort.xml new file mode 100644 index 00000000000..c78c11c3da1 --- /dev/null +++ b/solr/core/src/test-files/solr/collection1/conf/schema-distributed-missing-sort.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id + diff --git a/solr/core/src/test/org/apache/solr/TestDistributedMissingSort.java b/solr/core/src/test/org/apache/solr/TestDistributedMissingSort.java new file mode 100644 index 00000000000..6f7956d9d22 --- /dev/null +++ b/solr/core/src/test/org/apache/solr/TestDistributedMissingSort.java @@ -0,0 +1,287 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr; + +import org.apache.lucene.util.LuceneTestCase.Slow; +import org.apache.solr.client.solrj.response.QueryResponse; + +/** + * Tests sortMissingFirst and sortMissingLast in distributed sort + */ +@Slow +public class TestDistributedMissingSort extends BaseDistributedSearchTestCase { + + public TestDistributedMissingSort() { + schemaString = "schema-distributed-missing-sort.xml"; + } + + String sint1_ml = "one_si_ml"; // SortableIntField, sortMissingLast=true, multiValued=false + String sint1_mf = "two_si_mf"; // SortableIntField, sortMissingFirst=true, multiValued=false + String long1_ml = "three_l1_ml"; // TrieLongField, sortMissingLast=true, multiValued=false + String long1_mf = "four_l1_mf"; // TrieLongField, sortMissingFirst=true, multiValued=false + String string1_ml = "five_s1_ml"; // StringField, sortMissingLast=true, multiValued=false + String string1_mf = "six_s1_mf"; // StringField, sortMissingFirst=true, multiValued=false + + @Override + public void doTest() throws Exception { + index(); + testSortMissingLast(); + testSortMissingFirst(); + } + + private void index() throws Exception { + del("*:*"); + indexr(id,1, sint1_ml, 100, sint1_mf, 100, long1_ml, 100, long1_mf, 100, + "foo_f", 1.414f, "foo_b", "true", "foo_d", 1.414d, + string1_ml, "DE", string1_mf, "DE"); + indexr(id,2, sint1_ml, 50, sint1_mf, 50, long1_ml, 50, long1_mf, 50, + string1_ml, "ABC", string1_mf, "ABC"); + indexr(id,3, sint1_ml, 2, sint1_mf, 2, long1_ml, 2, long1_mf, 2, + string1_ml, "HIJK", string1_mf, "HIJK"); + indexr(id,4, sint1_ml, -100, sint1_mf, -100, long1_ml, -101, long1_mf, -101, + string1_ml, "L M", string1_mf, "L M"); + indexr(id,5, sint1_ml, 500, sint1_mf, 500, long1_ml, 500, long1_mf, 500, + string1_ml, "YB", string1_mf, "YB"); + indexr(id,6, sint1_ml, -600, sint1_mf, -600, long1_ml, -600, long1_mf, -600, + string1_ml, "WX", string1_mf, "WX"); + indexr(id,7, sint1_ml, 123, sint1_mf, 123, long1_ml, 123, long1_mf, 123, + string1_ml, "N", string1_mf, "N"); + indexr(id,8, sint1_ml, 876, sint1_mf, 876, long1_ml, 876, long1_mf, 876, + string1_ml, "QRS", string1_mf, "QRS"); + indexr(id,9, sint1_ml, 7, sint1_mf, 7, long1_ml, 7, long1_mf, 7, + string1_ml, "P", string1_mf, "P"); + + commit(); // try to ensure there's more than one segment + + indexr(id,10, sint1_ml, 4321, sint1_mf, 4321, long1_ml, 4321, long1_mf, 4321, + string1_ml, "O", string1_mf, "O"); + indexr(id,11, sint1_ml, -987, sint1_mf, -987, long1_ml, -987, long1_mf, -987, + string1_ml, "YA", string1_mf, "YA"); + indexr(id,12, sint1_ml, 379, sint1_mf, 379, long1_ml, 379, long1_mf, 379, + string1_ml, "TUV", string1_mf, "TUV"); + indexr(id,13, sint1_ml, 232, sint1_mf, 232, long1_ml, 232, long1_mf, 232, + string1_ml, "F G", string1_mf, "F G"); + + indexr(id, 14, "SubjectTerms_mfacet", new String[] {"mathematical models", "mathematical analysis"}); + indexr(id, 15, "SubjectTerms_mfacet", new String[] {"test 1", "test 2", "test3"}); + indexr(id, 16, "SubjectTerms_mfacet", new String[] {"test 1", "test 2", "test3"}); + String[] vals = new String[100]; + for (int i=0; i<100; i++) { + vals[i] = "test " + i; + } + indexr(id, 17, "SubjectTerms_mfacet", vals); + + for (int i=100; i<150; i++) { + indexr(id, i); + } + + commit(); + + handle.clear(); + handle.put("QTime", SKIPVAL); + handle.put("timestamp", SKIPVAL); + handle.put("_version_", SKIPVAL); // not a cloud test, but may use updateLog + } + + private void testSortMissingLast() throws Exception { + // id field values: 1 2 3 4 5 6 7 8 9 10 11 12 13 + // sint1_ml field values: 100 50 2 -100 500 -600 123 876 7 4321 -987 379 232 + // sint1_ml asc sort pos: 7 6 4 3 11 2 8 12 5 13 1 10 9 + // sint1_ml desc sort pos: 7 8 10 11 3 12 6 2 9 1 13 4 5 + + QueryResponse rsp = query("q","*:*", "sort", sint1_ml + " desc", "rows", "13"); + assertFieldValues(rsp.getResults(), id, 10, 8, 5, 12, 13, 7, 1, 2, 9, 3, 4, 6, 11); + + rsp = query("q","*:*", "sort", sint1_ml + " asc", "rows", "13"); + assertFieldValues(rsp.getResults(), id, 11, 6, 4, 3, 9, 2, 1, 7, 13, 12, 5, 8, 10); + + rsp = query("q","*:*", "sort", sint1_ml + " desc," + id + " asc", "rows", "200"); + assertFieldValues(rsp.getResults(), id, + 10, 8, 5, 12, 13, 7, 1, 2, 9, 3, 4, 6, 11, + // missing field sint1_ml="a_si", ascending id sort + 14, 15, 16, 17, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, + 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143, 144, 145, 146, 147, 148, 149); + + rsp = query("q","*:*", "sort", sint1_ml + " asc," + id + " desc", "rows", "200"); + assertFieldValues(rsp.getResults(), id, + 11, 6, 4, 3, 9, 2, 1, 7, 13, 12, 5, 8, 10, + // missing field sint1_ml="a_si", descending id sort + 149, 148, 147, 146, 145, 144, 143, 142, 141, 140, + 139, 138, 137, 136, 135, 134, 133, 132, 131, 130, + 129, 128, 127, 126, 125, 124, 123, 122, 121, 120, + 119, 118, 117, 116, 115, 114, 113, 112, 111, 110, + 109, 108, 107, 106, 105, 104, 103, 102, 101, 100, + 17, 16, 15, 14); + + // id field values: 1 2 3 4 5 6 7 8 9 10 11 12 13 + // long1_ml field values: 100 50 2 -100 500 -600 123 876 7 4321 -987 379 232 + // long1_ml asc sort pos: 7 6 4 3 11 2 8 12 5 13 1 10 9 + // long1_ml desc sort pos: 7 8 10 11 3 12 6 2 9 1 13 4 5 + + rsp = query("q","*:*", "sort", long1_ml + " desc", "rows", "13"); + assertFieldValues(rsp.getResults(), id, 10, 8, 5, 12, 13, 7, 1, 2, 9, 3, 4, 6, 11); + + rsp = query("q","*:*", "sort", long1_ml + " asc", "rows", "13"); + assertFieldValues(rsp.getResults(), id, 11, 6, 4, 3, 9, 2, 1, 7, 13, 12, 5, 8, 10); + + rsp = query("q","*:*", "sort", long1_ml + " desc," + id + " asc", "rows", "200"); + assertFieldValues(rsp.getResults(), id, + 10, 8, 5, 12, 13, 7, 1, 2, 9, 3, 4, 6, 11, + // missing field sint1_ml="a_si", ascending id sort + 14, 15, 16, 17, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, + 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143, 144, 145, 146, 147, 148, 149); + + rsp = query("q","*:*", "sort", long1_ml + " asc," + id + " desc", "rows", "200"); + assertFieldValues(rsp.getResults(), id, + 11, 6, 4, 3, 9, 2, 1, 7, 13, 12, 5, 8, 10, + // missing field sint1_ml="a_si", descending id sort + 149, 148, 147, 146, 145, 144, 143, 142, 141, 140, + 139, 138, 137, 136, 135, 134, 133, 132, 131, 130, + 129, 128, 127, 126, 125, 124, 123, 122, 121, 120, + 119, 118, 117, 116, 115, 114, 113, 112, 111, 110, + 109, 108, 107, 106, 105, 104, 103, 102, 101, 100, + 17, 16, 15, 14); + + + // id field values: 1 2 3 4 5 6 7 8 9 10 11 12 13 + // string1_ml field values: DE ABC HIJK L M YB WX N QRS P O YA TUV F G + // string1_ml asc sort pos: 2 1 4 5 13 11 6 9 8 7 12 10 3 + // string1_ml desc sort pos: 12 13 10 9 1 3 8 5 6 7 2 4 11 + + rsp = query("q","*:*", "sort", string1_ml + " desc", "rows", "13"); + assertFieldValues(rsp.getResults(), id, 5, 11, 6, 12, 8, 9, 10, 7, 4, 3, 13, 1, 2); + + rsp = query("q","*:*", "sort", string1_ml + " asc", "rows", "13"); + assertFieldValues(rsp.getResults(), id, 2, 1, 13, 3, 4, 7, 10, 9, 8, 12, 6, 11, 5); + + rsp = query("q","*:*", "sort", string1_ml + " desc," + id + " asc", "rows", "200"); + assertFieldValues(rsp.getResults(), id, + 5, 11, 6, 12, 8, 9, 10, 7, 4, 3, 13, 1, 2, + // missing field string1_ml="a_s1", ascending id sort + 14, 15, 16, 17, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, + 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143, 144, 145, 146, 147, 148, 149); + + rsp = query("q","*:*", "sort", string1_ml + " asc," + id + " desc", "rows", "200"); + assertFieldValues(rsp.getResults(), id, + 2, 1, 13, 3, 4, 7, 10, 9, 8, 12, 6, 11, 5, + // missing field string1_ml="a_s1", descending id sort + 149, 148, 147, 146, 145, 144, 143, 142, 141, 140, + 139, 138, 137, 136, 135, 134, 133, 132, 131, 130, + 129, 128, 127, 126, 125, 124, 123, 122, 121, 120, + 119, 118, 117, 116, 115, 114, 113, 112, 111, 110, + 109, 108, 107, 106, 105, 104, 103, 102, 101, 100, + 17, 16, 15, 14); + } + + private void testSortMissingFirst() throws Exception { + // id field values: 1 2 3 4 5 6 7 8 9 10 11 12 13 + // sint1_mf field values: 100 50 2 -100 500 -600 123 876 7 4321 -987 379 232 + // sint1_mf asc sort pos: 7 6 4 3 11 2 8 12 5 13 1 10 9 + // sint1_mf desc sort pos: 7 8 10 11 3 12 6 2 9 1 13 4 5 + + QueryResponse rsp = query("q","*:*", "sort", sint1_mf + " desc," + id + " asc", "rows", "200"); + assertFieldValues(rsp.getResults(), id, + // missing field sint1_mf="a_si_mf", ascending id sort + 14, 15, 16, 17, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, + 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 10, 8, 5, 12, 13, 7, 1, 2, 9, 3, 4, 6, 11); + + rsp = query("q","*:*", "sort", sint1_mf + " asc," + id + " desc", "rows", "200"); + assertFieldValues(rsp.getResults(), id, + // missing field sint1_mf="a_si_mf", descending id sort + 149, 148, 147, 146, 145, 144, 143, 142, 141, 140, + 139, 138, 137, 136, 135, 134, 133, 132, 131, 130, + 129, 128, 127, 126, 125, 124, 123, 122, 121, 120, + 119, 118, 117, 116, 115, 114, 113, 112, 111, 110, + 109, 108, 107, 106, 105, 104, 103, 102, 101, 100, + 17, 16, 15, 14, + 11, 6, 4, 3, 9, 2, 1, 7, 13, 12, 5, 8, 10); + + + // id field values: 1 2 3 4 5 6 7 8 9 10 11 12 13 + // long1_mf field values: 100 50 2 -100 500 -600 123 876 7 4321 -987 379 232 + // long1_mf asc sort pos: 7 6 4 3 11 2 8 12 5 13 1 10 9 + // long1_mf desc sort pos: 7 8 10 11 3 12 6 2 9 1 13 4 5 + + rsp = query("q","*:*", "sort", long1_mf + " desc," + id + " asc", "rows", "200"); + assertFieldValues(rsp.getResults(), id, + // missing field sint1_mf="a_si_mf", ascending id sort + 14, 15, 16, 17, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, + 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 10, 8, 5, 12, 13, 7, 1, 2, 9, 3, 4, 6, 11); + + rsp = query("q","*:*", "sort", long1_mf + " asc," + id + " desc", "rows", "200"); + assertFieldValues(rsp.getResults(), id, + // missing field sint1_mf="a_si_mf", descending id sort + 149, 148, 147, 146, 145, 144, 143, 142, 141, 140, + 139, 138, 137, 136, 135, 134, 133, 132, 131, 130, + 129, 128, 127, 126, 125, 124, 123, 122, 121, 120, + 119, 118, 117, 116, 115, 114, 113, 112, 111, 110, + 109, 108, 107, 106, 105, 104, 103, 102, 101, 100, + 17, 16, 15, 14, + 11, 6, 4, 3, 9, 2, 1, 7, 13, 12, 5, 8, 10); + + + // id field values: 1 2 3 4 5 6 7 8 9 10 11 12 13 + // string1_mf field values: DE ABC HIJK L M YB WX N QRS P O YA TUV F G + // string1_mf asc sort pos: 2 1 4 5 13 11 6 9 8 7 12 10 3 + // string1_mf desc sort pos: 12 13 10 9 1 3 8 5 6 7 2 4 11 + + rsp = query("q","*:*", "sort", string1_mf + " desc," + id + " asc", "rows", "200"); + assertFieldValues(rsp.getResults(), id, + // missing field string1_mf="a_s1_mf", ascending id sort + 14, 15, 16, 17, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, + 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 5, 11, 6, 12, 8, 9, 10, 7, 4, 3, 13, 1, 2); + + rsp = query("q","*:*", "sort", string1_mf + " asc," + id + " desc", "rows", "200"); + assertFieldValues(rsp.getResults(), id, + // missing field string1_mf="a_s1_mf", descending id sort + 149, 148, 147, 146, 145, 144, 143, 142, 141, 140, + 139, 138, 137, 136, 135, 134, 133, 132, 131, 130, + 129, 128, 127, 126, 125, 124, 123, 122, 121, 120, + 119, 118, 117, 116, 115, 114, 113, 112, 111, 110, + 109, 108, 107, 106, 105, 104, 103, 102, 101, 100, + 17, 16, 15, 14, + 2, 1, 13, 3, 4, 7, 10, 9, 8, 12, 6, 11, 5); + } +} diff --git a/solr/core/src/test/org/apache/solr/handler/component/DistributedQueryComponentCustomSortTest.java b/solr/core/src/test/org/apache/solr/handler/component/DistributedQueryComponentCustomSortTest.java new file mode 100644 index 00000000000..8a4b9735e0b --- /dev/null +++ b/solr/core/src/test/org/apache/solr/handler/component/DistributedQueryComponentCustomSortTest.java @@ -0,0 +1,110 @@ +package org.apache.solr.handler.component; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.apache.solr.BaseDistributedSearchTestCase; +import org.apache.solr.client.solrj.response.QueryResponse; +import org.apache.solr.common.SolrDocument; +import org.apache.solr.common.SolrDocumentList; +import org.junit.BeforeClass; + +import java.nio.ByteBuffer; + +/** + * Test for QueryComponent's distributed querying + * + * @see org.apache.solr.handler.component.QueryComponent + */ +public class DistributedQueryComponentCustomSortTest extends BaseDistributedSearchTestCase { + + public DistributedQueryComponentCustomSortTest() { + fixShardCount = true; + shardCount = 3; + stress = 0; + } + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + initCore("solrconfig.xml", "schema-custom-field.xml"); + } + + @Override + public void doTest() throws Exception { + del("*:*"); + + index(id, "1", "text", "a", "payload", ByteBuffer.wrap(new byte[] { 0x12, 0x62, 0x15 })); // 2 + index(id, "2", "text", "b", "payload", ByteBuffer.wrap(new byte[] { 0x25, 0x21, 0x16 })); // 5 + index(id, "3", "text", "a", "payload", ByteBuffer.wrap(new byte[] { 0x35, 0x32, 0x58 })); // 8 + index(id, "4", "text", "b", "payload", ByteBuffer.wrap(new byte[] { 0x25, 0x21, 0x15 })); // 4 + index(id, "5", "text", "a", "payload", ByteBuffer.wrap(new byte[] { 0x35, 0x35, 0x10, 0x00 })); // 9 + index(id, "6", "text", "c", "payload", ByteBuffer.wrap(new byte[] { 0x1a, 0x2b, 0x3c, 0x00, 0x00, 0x03 })); // 3 + index(id, "7", "text", "c", "payload", ByteBuffer.wrap(new byte[] { 0x00, 0x3c, 0x73 })); // 1 + index(id, "8", "text", "c", "payload", ByteBuffer.wrap(new byte[] { 0x59, 0x2d, 0x4d })); // 11 + index(id, "9", "text", "a", "payload", ByteBuffer.wrap(new byte[] { 0x39, 0x79, 0x7a })); // 10 + index(id, "10", "text", "b", "payload", ByteBuffer.wrap(new byte[] { 0x31, 0x39, 0x7c })); // 6 + index(id, "11", "text", "d", "payload", ByteBuffer.wrap(new byte[] { (byte)0xff, (byte)0xaf, (byte)0x9c })); // 13 + index(id, "12", "text", "d", "payload", ByteBuffer.wrap(new byte[] { 0x34, (byte)0xdd, 0x4d })); // 7 + index(id, "13", "text", "d", "payload", ByteBuffer.wrap(new byte[] { (byte)0x80, 0x11, 0x33 })); // 12 + commit(); + + handle.put("QTime", SKIPVAL); + + QueryResponse rsp; + rsp = query("q", "*:*", "fl", "id", "sort", "payload asc", "rows", "20"); + assertFieldValues(rsp.getResults(), id, 7, 1, 6, 4, 2, 10, 12, 3, 5, 9, 8, 13, 11); + rsp = query("q", "*:*", "fl", "id", "sort", "payload desc", "rows", "20"); + assertFieldValues(rsp.getResults(), id, 11, 13, 8, 9, 5, 3, 12, 10, 2, 4, 6, 1, 7); + + rsp = query("q", "text:a", "fl", "id", "sort", "payload asc", "rows", "20"); + assertFieldValues(rsp.getResults(), id, 1, 3, 5, 9); + rsp = query("q", "text:a", "fl", "id", "sort", "payload desc", "rows", "20"); + assertFieldValues(rsp.getResults(), id, 9, 5, 3, 1); + + rsp = query("q", "text:b", "fl", "id", "sort", "payload asc", "rows", "20"); + assertFieldValues(rsp.getResults(), id, 4, 2, 10); + rsp = query("q", "text:b", "fl", "id", "sort", "payload desc", "rows", "20"); + assertFieldValues(rsp.getResults(), id, 10, 2, 4); + + rsp = query("q", "text:c", "fl", "id", "sort", "payload asc", "rows", "20"); + assertFieldValues(rsp.getResults(), id, 7, 6, 8); + rsp = query("q", "text:c", "fl", "id", "sort", "payload desc", "rows", "20"); + assertFieldValues(rsp.getResults(), id, 8, 6, 7); + + rsp = query("q", "text:d", "fl", "id", "sort", "payload asc", "rows", "20"); + assertFieldValues(rsp.getResults(), id, 12, 13, 11); + rsp = query("q", "text:d", "fl", "id", "sort", "payload desc", "rows", "20"); + assertFieldValues(rsp.getResults(), id, 11, 13, 12); + + + // Add two more docs with same payload as in doc #4 + index(id, "14", "text", "b", "payload", ByteBuffer.wrap(new byte[] { 0x25, 0x21, 0x15 })); + index(id, "15", "text", "b", "payload", ByteBuffer.wrap(new byte[] { 0x25, 0x21, 0x15 })); + + // Add three more docs with same payload as in doc #10 + index(id, "16", "text", "b", "payload", ByteBuffer.wrap(new byte[] { 0x31, 0x39, 0x7c })); + index(id, "17", "text", "b", "payload", ByteBuffer.wrap(new byte[] { 0x31, 0x39, 0x7c })); + index(id, "18", "text", "b", "payload", ByteBuffer.wrap(new byte[] { 0x31, 0x39, 0x7c })); + + commit(); + + rsp = query("q", "*:*", "fl", "id", "sort", "payload asc, id desc", "rows", "20"); + assertFieldValues(rsp.getResults(), id, 7, 1, 6, 15,14,4, 2, 18,17,16,10, 12, 3, 5, 9, 8, 13, 11); + rsp = query("q", "*:*", "fl", "id", "sort", "payload desc, id asc", "rows", "20"); + assertFieldValues(rsp.getResults(), id, 11, 13, 8, 9, 5, 3, 12, 10,16,17,18, 2, 4,14,15, 6, 1, 7); + } +} diff --git a/solr/core/src/test/org/apache/solr/schema/SortableBinaryField.java b/solr/core/src/test/org/apache/solr/schema/SortableBinaryField.java new file mode 100644 index 00000000000..1fa86d6eb36 --- /dev/null +++ b/solr/core/src/test/org/apache/solr/schema/SortableBinaryField.java @@ -0,0 +1,103 @@ +package org.apache.solr.schema; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.apache.lucene.document.SortedDocValuesField; +import org.apache.lucene.document.SortedSetDocValuesField; +import org.apache.lucene.index.StorableField; +import org.apache.lucene.search.FieldComparator; +import org.apache.lucene.search.FieldComparatorSource; +import org.apache.lucene.search.SortField; +import org.apache.lucene.util.BytesRef; +import org.apache.solr.common.util.Base64; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Custom field representing a {@link BinaryField} that's sortable. + */ +public class SortableBinaryField extends BinaryField { + + @Override + public void checkSchemaField(final SchemaField field) { + if (field.hasDocValues() && !field.multiValued() && !(field.isRequired() || field.getDefaultValue() != null)) { + throw new IllegalStateException( + "Field " + this + " has single-valued doc values enabled, but has no default value and is not required"); + } + } + + @Override + public List createFields(SchemaField field, Object value, float boost) { + if (field.hasDocValues()) { + List fields = new ArrayList(); + StorableField storedField = createField(field, value, boost); + fields.add(storedField); + ByteBuffer byteBuffer = toObject(storedField); + BytesRef bytes = new BytesRef + (byteBuffer.array(), byteBuffer.arrayOffset() + byteBuffer.position(), byteBuffer.remaining()); + if (field.multiValued()) { + fields.add(new SortedSetDocValuesField(field.getName(), bytes)); + } else { + fields.add(new SortedDocValuesField(field.getName(), bytes)); + } + return fields; + } else { + return Collections.singletonList(createField(field, value, boost)); + } + } + + @Override + public SortField getSortField(final SchemaField field, final boolean reverse) { + field.checkSortability(); + return new BinarySortField(field.getName(), reverse); + } + + private static class BinarySortField extends SortField { + public BinarySortField(final String field, final boolean reverse) { + super(field, new FieldComparatorSource() { + @Override + public FieldComparator.TermOrdValComparator newComparator + (final String fieldname, final int numHits, final int sortPos, final boolean reversed) throws IOException { + return new FieldComparator.TermOrdValComparator(numHits, fieldname); + }}, reverse); + } + } + + @Override + public Object marshalSortValue(Object value) { + if (null == value) { + return null; + } + final BytesRef val = (BytesRef)value; + return Base64.byteArrayToBase64(val.bytes, val.offset, val.length); + } + + @Override + public Object unmarshalSortValue(Object value) { + if (null == value) { + return null; + } + final String val = (String)value; + final byte[] bytes = Base64.base64ToByteArray(val); + return new BytesRef(bytes); + } +} diff --git a/solr/core/src/test/org/apache/solr/search/TestCustomSort.java b/solr/core/src/test/org/apache/solr/search/TestCustomSort.java new file mode 100644 index 00000000000..d2afe4d3f6c --- /dev/null +++ b/solr/core/src/test/org/apache/solr/search/TestCustomSort.java @@ -0,0 +1,126 @@ +package org.apache.solr.search; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.apache.solr.SolrTestCaseJ4; +import org.junit.BeforeClass; + +import java.nio.ByteBuffer; + + +/** + * Test SortField.CUSTOM sorts + */ +public class TestCustomSort extends SolrTestCaseJ4 { + + @BeforeClass + public static void beforeClass() throws Exception { + initCore("solrconfig.xml", "schema-custom-field.xml"); + } + + public void testSortableBinary() throws Exception { + clearIndex(); + assertU(adoc(sdoc("id", "1", "text", "a", "payload", ByteBuffer.wrap(new byte[] { 0x12, 0x62, 0x15 })))); // 2 + assertU(adoc(sdoc("id", "2", "text", "b", "payload", ByteBuffer.wrap(new byte[] { 0x25, 0x21, 0x16 })))); // 5 + assertU(adoc(sdoc("id", "3", "text", "a", "payload", ByteBuffer.wrap(new byte[] { 0x35, 0x32, 0x58 })))); // 8 + assertU(adoc(sdoc("id", "4", "text", "b", "payload", ByteBuffer.wrap(new byte[] { 0x25, 0x21, 0x15 })))); // 4 + assertU(adoc(sdoc("id", "5", "text", "a", "payload", ByteBuffer.wrap(new byte[] { 0x35, 0x35, 0x10, 0x00 })))); // 9 + assertU(adoc(sdoc("id", "6", "text", "c", "payload", ByteBuffer.wrap(new byte[] { 0x1a, 0x2b, 0x3c, 0x00, 0x00, 0x03 })))); // 3 + assertU(adoc(sdoc("id", "7", "text", "c", "payload", ByteBuffer.wrap(new byte[] { 0x00, 0x3c, 0x73 })))); // 1 + assertU(adoc(sdoc("id", "8", "text", "c", "payload", ByteBuffer.wrap(new byte[] { 0x59, 0x2d, 0x4d })))); // 11 + assertU(adoc(sdoc("id", "9", "text", "a", "payload", ByteBuffer.wrap(new byte[] { 0x39, 0x79, 0x7a })))); // 10 + assertU(adoc(sdoc("id", "10", "text", "b", "payload", ByteBuffer.wrap(new byte[] { 0x31, 0x39, 0x7c })))); // 6 + assertU(adoc(sdoc("id", "11", "text", "d", "payload", ByteBuffer.wrap(new byte[] { (byte)0xff, (byte)0xaf, (byte)0x9c })))); // 13 + assertU(adoc(sdoc("id", "12", "text", "d", "payload", ByteBuffer.wrap(new byte[] { 0x34, (byte)0xdd, 0x4d })))); // 7 + assertU(adoc(sdoc("id", "13", "text", "d", "payload", ByteBuffer.wrap(new byte[] { (byte)0x80, 0x11, 0x33 })))); // 12 + assertU(commit()); + + assertQ(req("q", "*:*", "fl", "id", "sort", "payload asc", "rows", "20") + , "//result[@numFound='13']" // + , "//result/doc[int='7' and position()=1]" // 7 00 3c 73 + , "//result/doc[int='1' and position()=2]" // 1 12 62 15 + , "//result/doc[int='6' and position()=3]" // 6 1a 2b 3c 00 00 03 + , "//result/doc[int='4' and position()=4]" // 4 25 21 15 + , "//result/doc[int='2' and position()=5]" // 2 25 21 16 + , "//result/doc[int='10' and position()=6]" // 10 31 39 7c + , "//result/doc[int='12' and position()=7]" // 12 34 dd 4d + , "//result/doc[int='3' and position()=8]" // 3 35 32 58 + , "//result/doc[int='5' and position()=9]" // 5 35 35 10 00 + , "//result/doc[int='9' and position()=10]" // 9 39 79 7a + , "//result/doc[int='8' and position()=11]" // 8 59 2d 4d + , "//result/doc[int='13' and position()=12]" // 13 80 11 33 + , "//result/doc[int='11' and position()=13]"); // 11 ff af 9c + assertQ(req("q", "*:*", "fl", "id", "sort", "payload desc", "rows", "20") + , "//result[@numFound='13']" // + , "//result/doc[int='11' and position()=1]" // 11 ff af 9c + , "//result/doc[int='13' and position()=2]" // 13 80 11 33 + , "//result/doc[int='8' and position()=3]" // 8 59 2d 4d + , "//result/doc[int='9' and position()=4]" // 9 39 79 7a + , "//result/doc[int='5' and position()=5]" // 5 35 35 10 00 + , "//result/doc[int='3' and position()=6]" // 3 35 32 58 + , "//result/doc[int='12' and position()=7]" // 12 34 dd 4d + , "//result/doc[int='10' and position()=8]" // 10 31 39 7c + , "//result/doc[int='2' and position()=9]" // 2 25 21 16 + , "//result/doc[int='4' and position()=10]" // 4 25 21 15 + , "//result/doc[int='6' and position()=11]" // 6 1a 2b 3c 00 00 03 + , "//result/doc[int='1' and position()=12]" // 1 12 62 15 + , "//result/doc[int='7' and position()=13]"); // 7 00 3c 73 + assertQ(req("q", "text:a", "fl", "id", "sort", "payload asc", "rows", "20") + , "//result[@numFound='4']" // + , "//result/doc[int='1' and position()=1]" // 1 12 62 15 + , "//result/doc[int='3' and position()=2]" // 3 35 32 58 + , "//result/doc[int='5' and position()=3]" // 5 35 35 10 00 + , "//result/doc[int='9' and position()=4]"); // 9 39 79 7a + assertQ(req("q", "text:a", "fl", "id", "sort", "payload desc", "rows", "20") + , "//result[@numFound='4']" // + , "//result/doc[int='9' and position()=1]" // 9 39 79 7a + , "//result/doc[int='5' and position()=2]" // 5 35 35 10 00 + , "//result/doc[int='3' and position()=3]" // 3 35 32 58 + , "//result/doc[int='1' and position()=4]"); // 1 12 62 15 + assertQ(req("q", "text:b", "fl", "id", "sort", "payload asc", "rows", "20") + , "//result[@numFound='3']" // + , "//result/doc[int='4' and position()=1]" // 4 25 21 15 + , "//result/doc[int='2' and position()=2]" // 2 25 21 16 + , "//result/doc[int='10' and position()=3]"); // 10 31 39 7c + assertQ(req("q", "text:b", "fl", "id", "sort", "payload desc", "rows", "20") + , "//result[@numFound='3']" // + , "//result/doc[int='10' and position()=1]" // 10 31 39 7c + , "//result/doc[int='2' and position()=2]" // 2 25 21 16 + , "//result/doc[int='4' and position()=3]"); // 4 25 21 15 + assertQ(req("q", "text:c", "fl", "id", "sort", "payload asc", "rows", "20") + , "//result[@numFound='3']" // + , "//result/doc[int='7' and position()=1]" // 7 00 3c 73 + , "//result/doc[int='6' and position()=2]" // 6 1a 2b 3c 00 00 03 + , "//result/doc[int='8' and position()=3]"); // 8 59 2d 4d + assertQ(req("q", "text:c", "fl", "id", "sort", "payload desc", "rows", "20") + , "//result[@numFound='3']" // + , "//result/doc[int='8' and position()=1]" // 8 59 2d 4d + , "//result/doc[int='6' and position()=2]" // 6 1a 2b 3c 00 00 03 + , "//result/doc[int='7' and position()=3]"); // 7 00 3c 73 + assertQ(req("q", "text:d", "fl", "id", "sort", "payload asc", "rows", "20") + , "//result[@numFound='3']" // + , "//result/doc[int='12' and position()=1]" // 12 34 dd 4d + , "//result/doc[int='13' and position()=2]" // 13 80 11 33 + , "//result/doc[int='11' and position()=3]"); // 11 ff af 9c + assertQ(req("q", "text:d", "fl", "id", "sort", "payload desc", "rows", "20") + , "//result[@numFound='3']" // + , "//result/doc[int='11' and position()=1]" // 11 ff af 9c + , "//result/doc[int='13' and position()=2]" // 13 80 11 33 + , "//result/doc[int='12' and position()=3]"); // 12 34 dd 4d + } +} diff --git a/solr/test-framework/src/java/org/apache/solr/BaseDistributedSearchTestCase.java b/solr/test-framework/src/java/org/apache/solr/BaseDistributedSearchTestCase.java index 1a8ebf43d53..877bed1f4f2 100644 --- a/solr/test-framework/src/java/org/apache/solr/BaseDistributedSearchTestCase.java +++ b/solr/test-framework/src/java/org/apache/solr/BaseDistributedSearchTestCase.java @@ -507,11 +507,18 @@ public abstract class BaseDistributedSearchTestCase extends SolrTestCaseJ4 { return rsp; } - protected void query(Object... q) throws Exception { - query(true, q); + /** + * Sets distributed params. + * Returns the QueryResponse from {@link #queryServer}, + */ + protected QueryResponse query(Object... q) throws Exception { + return query(true, q); } - - protected void query(boolean setDistribParams, Object[] q) throws Exception { + + /** + * Returns the QueryResponse from {@link #queryServer} + */ + protected QueryResponse query(boolean setDistribParams, Object[] q) throws Exception { final ModifiableSolrParams params = new ModifiableSolrParams(); @@ -558,6 +565,7 @@ public abstract class BaseDistributedSearchTestCase extends SolrTestCaseJ4 { thread.join(); } } + return rsp; } public QueryResponse queryAndCompare(SolrParams params, SolrServer... servers) throws SolrServerException { diff --git a/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java b/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java index 6c8faecf2c2..61f2d1be823 100644 --- a/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java +++ b/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java @@ -47,6 +47,8 @@ import org.apache.lucene.util.LuceneTestCase; import org.apache.lucene.util.QuickPatchThreadsFilter; import org.apache.lucene.util._TestUtil; import org.apache.solr.client.solrj.util.ClientUtils; +import org.apache.solr.common.SolrDocument; +import org.apache.solr.common.SolrDocumentList; import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrInputDocument; import org.apache.solr.common.SolrInputField; @@ -1627,6 +1629,30 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase { throw new RuntimeException("XPath is invalid", e2); } } + + /** + * Fails if the number of documents in the given SolrDocumentList differs + * from the given number of expected values, or if any of the values in the + * given field don't match the expected values in the same order. + */ + public static void assertFieldValues(SolrDocumentList documents, String fieldName, Object... expectedValues) { + if (documents.size() != expectedValues.length) { + fail("Number of documents (" + documents.size() + + ") is different from number of expected values (" + expectedValues.length); + } + for (int docNum = 1 ; docNum <= documents.size() ; ++docNum) { + SolrDocument doc = documents.get(docNum - 1); + Object expected = expectedValues[docNum - 1]; + Object actual = doc.get(fieldName); + if (null != expected && null != actual) { + if ( ! expected.equals(actual)) { + fail( "Unexpected " + fieldName + " field value in document #" + docNum + + ": expected=[" + expected + "], actual=[" + actual + "]"); + } + } + } + } + public static void copyMinConf(File dstRoot) throws IOException { copyMinConf(dstRoot, null); } From 52e8ead225bccee3227c1d9a729440ab9732ae21 Mon Sep 17 00:00:00 2001 From: Steven Rowe Date: Fri, 29 Nov 2013 16:03:21 +0000 Subject: [PATCH 137/223] SOLR-5354: fix attribution git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1546589 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 6bbe418ecf3..1138c397b21 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -161,7 +161,7 @@ Bug Fixes a SolrCore does not exist in core discovery mode. (Mark Miller) * SOLR-5354: Distributed sort is broken with CUSTOM FieldType. - (Steve Rowe, hossman, Jessica Cheng) + (Steve Rowe, hossman, Robert Muir, Jessica Cheng) Optimizations ---------------------- From 4213413f0bd85be4f28e0e49a2229544e158205f Mon Sep 17 00:00:00 2001 From: Adrien Grand Date: Fri, 29 Nov 2013 16:45:01 +0000 Subject: [PATCH 138/223] LUCENE-5285: Improved highlighting of multi-valued fields with FastVectorHighlighter. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1546603 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/CHANGES.txt | 5 ++ .../vectorhighlight/BaseFragmentsBuilder.java | 8 ++-- .../search/vectorhighlight/FieldFragList.java | 10 +++- .../vectorhighlight/SimpleFieldFragList.java | 2 +- .../WeightedFieldFragList.java | 34 +++++++------ .../FastVectorHighlighterTest.java | 48 +++++++++++++++++++ .../WeightedFragListBuilderTest.java | 39 +++++++++++++-- 7 files changed, 120 insertions(+), 26 deletions(-) diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 34d28f56e06..9859b412fb5 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -86,6 +86,11 @@ Build * LUCENE-5347: Upgrade forbidden-apis checker to version 1.4. (Uwe Schindler) +Bug fixes + +* LUCENE-5285: Improved highlighting of multi-valued fields with + FastVectorHighlighter. (Nik Everett via Adrien Grand) + ======================= Lucene 4.6.0 ======================= New Features diff --git a/lucene/highlighter/src/java/org/apache/lucene/search/vectorhighlight/BaseFragmentsBuilder.java b/lucene/highlighter/src/java/org/apache/lucene/search/vectorhighlight/BaseFragmentsBuilder.java index 012e6696460..8ee06dc9471 100644 --- a/lucene/highlighter/src/java/org/apache/lucene/search/vectorhighlight/BaseFragmentsBuilder.java +++ b/lucene/highlighter/src/java/org/apache/lucene/search/vectorhighlight/BaseFragmentsBuilder.java @@ -258,9 +258,8 @@ public abstract class BaseFragmentsBuilder implements FragmentsBuilder { List subInfos = new ArrayList(); - WeightedFragInfo weightedFragInfo = new WeightedFragInfo(fragStart, fragEnd, subInfos, fragInfo.getTotalBoost()); - Iterator subInfoIterator = fragInfo.getSubInfos().iterator(); + float boost = 0.0f; // The boost of the new info will be the sum of the boosts of its SubInfos while (subInfoIterator.hasNext()) { SubInfo subInfo = subInfoIterator.next(); List toffsList = new ArrayList(); @@ -268,18 +267,21 @@ public abstract class BaseFragmentsBuilder implements FragmentsBuilder { while (toffsIterator.hasNext()) { Toffs toffs = toffsIterator.next(); if (toffs.getStartOffset() >= fieldStart && toffs.getEndOffset() <= fieldEnd) { + toffsList.add(toffs); toffsIterator.remove(); } } if (!toffsList.isEmpty()) { - subInfos.add(new SubInfo(subInfo.getText(), toffsList, subInfo.getSeqnum())); + subInfos.add(new SubInfo(subInfo.getText(), toffsList, subInfo.getSeqnum(), subInfo.getBoost())); + boost += subInfo.getBoost(); } if (subInfo.getTermsOffsets().isEmpty()) { subInfoIterator.remove(); } } + WeightedFragInfo weightedFragInfo = new WeightedFragInfo(fragStart, fragEnd, subInfos, boost); fieldNameToFragInfos.get(field.name()).add(weightedFragInfo); } } diff --git a/lucene/highlighter/src/java/org/apache/lucene/search/vectorhighlight/FieldFragList.java b/lucene/highlighter/src/java/org/apache/lucene/search/vectorhighlight/FieldFragList.java index 158cc879eb7..81afd4e3023 100644 --- a/lucene/highlighter/src/java/org/apache/lucene/search/vectorhighlight/FieldFragList.java +++ b/lucene/highlighter/src/java/org/apache/lucene/search/vectorhighlight/FieldFragList.java @@ -107,12 +107,14 @@ public abstract class FieldFragList { private final String text; // unnecessary member, just exists for debugging purpose private final List termsOffsets; // usually termsOffsets.size() == 1, // but if position-gap > 1 and slop > 0 then size() could be greater than 1 - private int seqnum; + private final int seqnum; + private final float boost; // used for scoring split WeightedPhraseInfos. - public SubInfo( String text, List termsOffsets, int seqnum ){ + public SubInfo( String text, List termsOffsets, int seqnum, float boost ){ this.text = text; this.termsOffsets = termsOffsets; this.seqnum = seqnum; + this.boost = boost; } public List getTermsOffsets(){ @@ -127,6 +129,10 @@ public abstract class FieldFragList { return text; } + public float getBoost(){ + return boost; + } + @Override public String toString(){ StringBuilder sb = new StringBuilder(); diff --git a/lucene/highlighter/src/java/org/apache/lucene/search/vectorhighlight/SimpleFieldFragList.java b/lucene/highlighter/src/java/org/apache/lucene/search/vectorhighlight/SimpleFieldFragList.java index d9f0b473469..93d1140cd60 100644 --- a/lucene/highlighter/src/java/org/apache/lucene/search/vectorhighlight/SimpleFieldFragList.java +++ b/lucene/highlighter/src/java/org/apache/lucene/search/vectorhighlight/SimpleFieldFragList.java @@ -45,7 +45,7 @@ public class SimpleFieldFragList extends FieldFragList { float totalBoost = 0; List subInfos = new ArrayList(); for( WeightedPhraseInfo phraseInfo : phraseInfoList ){ - subInfos.add( new SubInfo( phraseInfo.getText(), phraseInfo.getTermsOffsets(), phraseInfo.getSeqnum() ) ); + subInfos.add( new SubInfo( phraseInfo.getText(), phraseInfo.getTermsOffsets(), phraseInfo.getSeqnum(), phraseInfo.getBoost() ) ); totalBoost += phraseInfo.getBoost(); } getFragInfos().add( new WeightedFragInfo( startOffset, endOffset, subInfos, totalBoost ) ); diff --git a/lucene/highlighter/src/java/org/apache/lucene/search/vectorhighlight/WeightedFieldFragList.java b/lucene/highlighter/src/java/org/apache/lucene/search/vectorhighlight/WeightedFieldFragList.java index 54122ff3267..e542f6d2b3b 100644 --- a/lucene/highlighter/src/java/org/apache/lucene/search/vectorhighlight/WeightedFieldFragList.java +++ b/lucene/highlighter/src/java/org/apache/lucene/search/vectorhighlight/WeightedFieldFragList.java @@ -44,33 +44,37 @@ public class WeightedFieldFragList extends FieldFragList { */ @Override public void add( int startOffset, int endOffset, List phraseInfoList ) { - - float totalBoost = 0; - - List subInfos = new ArrayList(); - - HashSet distinctTerms = new HashSet(); - + List tempSubInfos = new ArrayList(); + List realSubInfos = new ArrayList(); + HashSet distinctTerms = new HashSet(); int length = 0; for( WeightedPhraseInfo phraseInfo : phraseInfoList ){ - - subInfos.add( new SubInfo( phraseInfo.getText(), phraseInfo.getTermsOffsets(), phraseInfo.getSeqnum() ) ); - + float phraseTotalBoost = 0; for ( TermInfo ti : phraseInfo.getTermsInfos()) { if ( distinctTerms.add( ti.getText() ) ) - totalBoost += ti.getWeight() * phraseInfo.getBoost(); + phraseTotalBoost += ti.getWeight() * phraseInfo.getBoost(); length++; } + tempSubInfos.add( new SubInfo( phraseInfo.getText(), phraseInfo.getTermsOffsets(), + phraseInfo.getSeqnum(), phraseTotalBoost ) ); } // We want that terms per fragment (length) is included into the weight. Otherwise a one-word-query // would cause an equal weight for all fragments regardless of how much words they contain. // To avoid that fragments containing a high number of words possibly "outrank" more relevant fragments - // we "bend" the length with a standard-normalization a little bit. - totalBoost *= length * ( 1 / Math.sqrt( length ) ); - - getFragInfos().add( new WeightedFragInfo( startOffset, endOffset, subInfos, totalBoost ) ); + // we "bend" the length with a standard-normalization a little bit. + float norm = length * ( 1 / (float)Math.sqrt( length ) ); + + float totalBoost = 0; + for ( SubInfo tempSubInfo : tempSubInfos ) { + float subInfoBoost = tempSubInfo.getBoost() * norm; + realSubInfos.add( new SubInfo( tempSubInfo.getText(), tempSubInfo.getTermsOffsets(), + tempSubInfo.getSeqnum(), subInfoBoost )); + totalBoost += subInfoBoost; + } + + getFragInfos().add( new WeightedFragInfo( startOffset, endOffset, realSubInfos, totalBoost ) ); } } \ No newline at end of file diff --git a/lucene/highlighter/src/test/org/apache/lucene/search/vectorhighlight/FastVectorHighlighterTest.java b/lucene/highlighter/src/test/org/apache/lucene/search/vectorhighlight/FastVectorHighlighterTest.java index 40ab5e91635..8fe273b5f16 100644 --- a/lucene/highlighter/src/test/org/apache/lucene/search/vectorhighlight/FastVectorHighlighterTest.java +++ b/lucene/highlighter/src/test/org/apache/lucene/search/vectorhighlight/FastVectorHighlighterTest.java @@ -412,6 +412,54 @@ public class FastVectorHighlighterTest extends LuceneTestCase { clause( "field_der_red", "red" ), clause( "field_der_red", "der" ), clause( "field_exact", "a", "cat" ) ); } + public void testMultiValuedSortByScore() throws IOException { + Directory dir = newDirectory(); + IndexWriter writer = new IndexWriter( dir, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer( random() ) ) ); + Document doc = new Document(); + FieldType type = new FieldType( TextField.TYPE_STORED ); + type.setStoreTermVectorOffsets( true ); + type.setStoreTermVectorPositions( true ); + type.setStoreTermVectors( true ); + type.freeze(); + doc.add( new Field( "field", "zero if naught", type ) ); // The first two fields contain the best match + doc.add( new Field( "field", "hero of legend", type ) ); // but total a lower score (3) than the bottom + doc.add( new Field( "field", "naught of hero", type ) ); // two fields (4) + doc.add( new Field( "field", "naught of hero", type ) ); + writer.addDocument(doc); + + FastVectorHighlighter highlighter = new FastVectorHighlighter(); + + ScoreOrderFragmentsBuilder fragmentsBuilder = new ScoreOrderFragmentsBuilder(); + fragmentsBuilder.setDiscreteMultiValueHighlighting( true ); + IndexReader reader = DirectoryReader.open(writer, true ); + String[] preTags = new String[] { "" }; + String[] postTags = new String[] { "" }; + Encoder encoder = new DefaultEncoder(); + int docId = 0; + BooleanQuery query = new BooleanQuery(); + query.add( clause( "field", "hero" ), Occur.SHOULD); + query.add( clause( "field", "of" ), Occur.SHOULD); + query.add( clause( "field", "legend" ), Occur.SHOULD); + FieldQuery fieldQuery = highlighter.getFieldQuery( query, reader ); + + for ( FragListBuilder fragListBuilder : new FragListBuilder[] { + new SimpleFragListBuilder(), new WeightedFragListBuilder() } ) { + String[] bestFragments = highlighter.getBestFragments( fieldQuery, reader, docId, "field", 20, 1, + fragListBuilder, fragmentsBuilder, preTags, postTags, encoder ); + assertEquals("hero of legend", bestFragments[0]); + bestFragments = highlighter.getBestFragments( fieldQuery, reader, docId, "field", 28, 1, + fragListBuilder, fragmentsBuilder, preTags, postTags, encoder ); + assertEquals("hero of legend", bestFragments[0]); + bestFragments = highlighter.getBestFragments( fieldQuery, reader, docId, "field", 30000, 1, + fragListBuilder, fragmentsBuilder, preTags, postTags, encoder ); + assertEquals("hero of legend", bestFragments[0]); + } + + reader.close(); + writer.close(); + dir.close(); + } + private void matchedFieldsTestCase( String fieldValue, String expected, Query... queryClauses ) throws IOException { matchedFieldsTestCase( true, true, fieldValue, expected, queryClauses ); } diff --git a/lucene/highlighter/src/test/org/apache/lucene/search/vectorhighlight/WeightedFragListBuilderTest.java b/lucene/highlighter/src/test/org/apache/lucene/search/vectorhighlight/WeightedFragListBuilderTest.java index 1071544ac7e..bfe2817249b 100644 --- a/lucene/highlighter/src/test/org/apache/lucene/search/vectorhighlight/WeightedFragListBuilderTest.java +++ b/lucene/highlighter/src/test/org/apache/lucene/search/vectorhighlight/WeightedFragListBuilderTest.java @@ -17,19 +17,48 @@ package org.apache.lucene.search.vectorhighlight; * limitations under the License. */ +import org.apache.lucene.search.BooleanClause.Occur; +import org.apache.lucene.search.BooleanQuery; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.vectorhighlight.FieldFragList.WeightedFragInfo; +import org.apache.lucene.search.vectorhighlight.FieldFragList.WeightedFragInfo.SubInfo; + public class WeightedFragListBuilderTest extends AbstractTestCase { - public void test2WeightedFragList() throws Exception { - + testCase( pqF( "the", "both" ), 100, + "subInfos=(theboth((195,203)))/0.8679108(149,249)", + 0.8679108 ); + } + + public void test2SubInfos() throws Exception { + BooleanQuery query = new BooleanQuery(); + query.add( pqF( "the", "both" ), Occur.MUST ); + query.add( tq( "examples" ), Occur.MUST ); + + testCase( query, 1000, + "subInfos=(examples((19,27))examples((66,74))theboth((195,203)))/1.8411169(0,1000)", + 1.8411169 ); + } + + private void testCase( Query query, int fragCharSize, String expectedFragInfo, + double expectedTotalSubInfoBoost ) throws Exception { makeIndexLongMV(); - FieldQuery fq = new FieldQuery( pqF( "the", "both" ), true, true ); + FieldQuery fq = new FieldQuery( query, true, true ); FieldTermStack stack = new FieldTermStack( reader, 0, F, fq ); FieldPhraseList fpl = new FieldPhraseList( stack, fq ); WeightedFragListBuilder wflb = new WeightedFragListBuilder(); - FieldFragList ffl = wflb.createFieldFragList( fpl, 100 ); + FieldFragList ffl = wflb.createFieldFragList( fpl, fragCharSize ); assertEquals( 1, ffl.getFragInfos().size() ); - assertEquals( "subInfos=(theboth((195,203)))/0.86791086(149,249)", ffl.getFragInfos().get( 0 ).toString() ); + assertEquals( expectedFragInfo, ffl.getFragInfos().get( 0 ).toString() ); + + float totalSubInfoBoost = 0; + for ( WeightedFragInfo info : ffl.getFragInfos() ) { + for ( SubInfo subInfo : info.getSubInfos() ) { + totalSubInfoBoost += subInfo.getBoost(); + } + } + assertEquals( expectedTotalSubInfoBoost, totalSubInfoBoost, .0000001 ); } } From 7bae4083e180228da02988cf4bca84fe5f0b8d61 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Sat, 30 Nov 2013 01:04:27 +0000 Subject: [PATCH 139/223] SOLR-5509: allow retry updates to self again, don't retry on remote solrserver exceptions git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1546670 13f79535-47bb-0310-9956-ffa450edef68 --- .../solr/update/SolrCmdDistributor.java | 24 +++++++------------ .../processor/DistributedUpdateProcessor.java | 3 +-- .../solr/update/MockStreamingSolrServers.java | 7 +++++- .../solr/update/SolrCmdDistributorTest.java | 8 +++---- 4 files changed, 19 insertions(+), 23 deletions(-) diff --git a/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java b/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java index 1fa6850d676..48fc2bf4c14 100644 --- a/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java +++ b/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java @@ -101,24 +101,22 @@ public class SolrCmdDistributor { } // if its a connect exception, lets try again - if (err.e instanceof ConnectException) { - doRetry = true; - } else if (err.e instanceof SolrServerException) { + if (err.e instanceof SolrServerException) { if (((SolrServerException) err.e).getRootCause() instanceof ConnectException) { doRetry = true; } - } else if (err.e instanceof RemoteSolrException) { - Exception cause = (RemoteSolrException) err.e.getCause(); - if (cause != null && cause instanceof ConnectException) { - doRetry = true; - } } + + if (err.e instanceof ConnectException) { + doRetry = true; + } + if (err.req.retries < maxRetriesOnForward && doRetry) { err.req.retries++; SolrException.log(SolrCmdDistributor.log, "forwarding update to " + oldNodeUrl + " failed - retrying ... retries: " - + err.req.retries + " " + err.req.cmdString, err.e); + + err.req.retries + " " + err.req.cmdString + " rsp:" + rspCode, err.e); try { Thread.sleep(retryPause); } catch (InterruptedException e) { @@ -360,14 +358,12 @@ public class SolrCmdDistributor { private ZkStateReader zkStateReader; private String collection; private String shardId; - private String fromAddress; - public RetryNode(ZkCoreNodeProps nodeProps, ZkStateReader zkStateReader, String collection, String shardId, String fromCoreUrl) { + public RetryNode(ZkCoreNodeProps nodeProps, ZkStateReader zkStateReader, String collection, String shardId) { super(nodeProps); this.zkStateReader = zkStateReader; this.collection = collection; this.shardId = shardId; - this.fromAddress = fromCoreUrl; } @Override @@ -385,10 +381,6 @@ public class SolrCmdDistributor { return true; } - if (fromAddress.equals(leaderProps.getCoreUrl())) { - // we became the leader - return false; - } this.nodeProps = leaderProps; return true; diff --git a/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java b/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java index 4bc4e92c7f7..e2db6812b9c 100644 --- a/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java +++ b/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java @@ -298,8 +298,7 @@ public class DistributedUpdateProcessor extends UpdateRequestProcessor { } else { // I need to forward onto the leader... nodes = new ArrayList(1); - nodes.add(new RetryNode(new ZkCoreNodeProps(leaderReplica), zkController.getZkStateReader(), collection, shardId, ZkCoreNodeProps.getCoreUrl( - zkController.getBaseUrl(), req.getCore().getName()))); + nodes.add(new RetryNode(new ZkCoreNodeProps(leaderReplica), zkController.getZkStateReader(), collection, shardId)); forwardToLeader = true; } diff --git a/solr/core/src/test/org/apache/solr/update/MockStreamingSolrServers.java b/solr/core/src/test/org/apache/solr/update/MockStreamingSolrServers.java index d95958e9f2d..39d262ff8a7 100644 --- a/solr/core/src/test/org/apache/solr/update/MockStreamingSolrServers.java +++ b/solr/core/src/test/org/apache/solr/update/MockStreamingSolrServers.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.net.ConnectException; import java.net.SocketException; +import org.apache.lucene.util.LuceneTestCase; import org.apache.solr.client.solrj.SolrRequest; import org.apache.solr.client.solrj.SolrServer; import org.apache.solr.client.solrj.SolrServerException; @@ -74,7 +75,11 @@ public class MockStreamingSolrServers extends StreamingSolrServers { public NamedList request(SolrRequest request) throws SolrServerException, IOException { if (exp != null) { - throw exception(); + if (LuceneTestCase.random().nextBoolean()) { + throw exception(); + } else { + throw new SolrServerException(exception()); + } } return solrServer.request(request); diff --git a/solr/core/src/test/org/apache/solr/update/SolrCmdDistributorTest.java b/solr/core/src/test/org/apache/solr/update/SolrCmdDistributorTest.java index a7a4cf8ee25..3b1ef9bfc33 100644 --- a/solr/core/src/test/org/apache/solr/update/SolrCmdDistributorTest.java +++ b/solr/core/src/test/org/apache/solr/update/SolrCmdDistributorTest.java @@ -331,7 +331,7 @@ public class SolrCmdDistributorTest extends BaseDistributedSearchTestCase { final AtomicInteger retries = new AtomicInteger(); ZkNodeProps nodeProps = new ZkNodeProps(ZkStateReader.BASE_URL_PROP, solrclient1.getBaseURL(), ZkStateReader.CORE_NAME_PROP, ""); - RetryNode retryNode = new RetryNode(new ZkCoreNodeProps(nodeProps), null, "collection1", "shard1", "locahost") { + RetryNode retryNode = new RetryNode(new ZkCoreNodeProps(nodeProps), null, "collection1", "shard1") { @Override public boolean checkRetry() { retries.incrementAndGet(); @@ -367,7 +367,7 @@ public class SolrCmdDistributorTest extends BaseDistributedSearchTestCase { final AtomicInteger retries = new AtomicInteger(); nodeProps = new ZkNodeProps(ZkStateReader.BASE_URL_PROP, solrclient.getBaseURL(), ZkStateReader.CORE_NAME_PROP, ""); - RetryNode retryNode = new RetryNode(new ZkCoreNodeProps(nodeProps), null, "collection1", "shard1", "locahost") { + RetryNode retryNode = new RetryNode(new ZkCoreNodeProps(nodeProps), null, "collection1", "shard1") { @Override public boolean checkRetry() { ss.setExp(null); @@ -413,7 +413,7 @@ public class SolrCmdDistributorTest extends BaseDistributedSearchTestCase { final AtomicInteger retries = new AtomicInteger(); nodeProps = new ZkNodeProps(ZkStateReader.BASE_URL_PROP, solrclient.getBaseURL(), ZkStateReader.CORE_NAME_PROP, ""); - RetryNode retryNode = new RetryNode(new ZkCoreNodeProps(nodeProps), null, "collection1", "shard1", "locahost") { + RetryNode retryNode = new RetryNode(new ZkCoreNodeProps(nodeProps), null, "collection1", "shard1") { @Override public boolean checkRetry() { retries.incrementAndGet(); @@ -457,7 +457,7 @@ public class SolrCmdDistributorTest extends BaseDistributedSearchTestCase { ArrayList nodes = new ArrayList(); ZkNodeProps nodeProps = new ZkNodeProps(ZkStateReader.BASE_URL_PROP, "[ff01::114]:33332" + context, ZkStateReader.CORE_NAME_PROP, ""); - RetryNode retryNode = new RetryNode(new ZkCoreNodeProps(nodeProps), null, "collection1", "shard1", "locahost") { + RetryNode retryNode = new RetryNode(new ZkCoreNodeProps(nodeProps), null, "collection1", "shard1") { @Override public boolean checkRetry() { ZkNodeProps leaderProps = new ZkNodeProps(ZkStateReader.BASE_URL_PROP, solrclient.getBaseURL(), From cafdce601cd20bd27186c78cca76d95ec3eaecac Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Sat, 30 Nov 2013 01:32:26 +0000 Subject: [PATCH 140/223] SOLR-5512: Optimize DocValuesFacets git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1546675 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 2 + .../apache/solr/request/DocValuesFacets.java | 93 ++++++++++++++++++- .../org/apache/solr/request/SimpleFacets.java | 2 +- .../org/apache/solr/search/BitDocSet.java | 6 +- 4 files changed, 96 insertions(+), 7 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 1138c397b21..e81dc7941e0 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -174,6 +174,8 @@ Optimizations * SOLR-5189: Solr 4.x Web UI Log Viewer does not display 'date' column from logs (steffkes) +* SOLR-5512: Optimize DocValuesFacets. (Robert Muir) + Other Changes --------------------- diff --git a/solr/core/src/java/org/apache/solr/request/DocValuesFacets.java b/solr/core/src/java/org/apache/solr/request/DocValuesFacets.java index 98a2140759c..81c04f87cde 100644 --- a/solr/core/src/java/org/apache/solr/request/DocValuesFacets.java +++ b/solr/core/src/java/org/apache/solr/request/DocValuesFacets.java @@ -232,9 +232,20 @@ public class DocValuesFacets { return res; } - /** accumulates per-segment single-valued facet counts, mapping to global ordinal space */ - // specialized since the single-valued case is different + /** accumulates per-segment single-valued facet counts */ static void accumSingle(int counts[], int startTermIndex, SortedDocValues si, DocIdSetIterator disi, int subIndex, OrdinalMap map) throws IOException { + if (startTermIndex == -1 && (map == null || si.getValueCount() < disi.cost()*10)) { + // no prefixing, not too many unique values wrt matching docs (lucene/facets heuristic): + // collect separately per-segment, then map to global ords + accumSingleSeg(counts, si, disi, subIndex, map); + } else { + // otherwise: do collect+map on the fly + accumSingleGeneric(counts, startTermIndex, si, disi, subIndex, map); + } + } + + /** accumulates per-segment single-valued facet counts, mapping to global ordinal space on-the-fly */ + static void accumSingleGeneric(int counts[], int startTermIndex, SortedDocValues si, DocIdSetIterator disi, int subIndex, OrdinalMap map) throws IOException { int doc; while ((doc = disi.nextDoc()) != DocIdSetIterator.NO_MORE_DOCS) { int term = si.getOrd(doc); @@ -246,8 +257,41 @@ public class DocValuesFacets { } } - /** accumulates per-segment multi-valued facet counts, mapping to global ordinal space */ + /** "typical" single-valued faceting: not too many unique values, no prefixing. maps to global ordinals as a separate step */ + static void accumSingleSeg(int counts[], SortedDocValues si, DocIdSetIterator disi, int subIndex, OrdinalMap map) throws IOException { + // First count in seg-ord space: + final int segCounts[]; + if (map == null) { + segCounts = counts; + } else { + segCounts = new int[1+si.getValueCount()]; + } + + int doc; + while ((doc = disi.nextDoc()) != DocIdSetIterator.NO_MORE_DOCS) { + segCounts[1+si.getOrd(doc)]++; + } + + // migrate to global ords (if necessary) + if (map != null) { + migrateGlobal(counts, segCounts, subIndex, map); + } + } + + /** accumulates per-segment multi-valued facet counts */ static void accumMulti(int counts[], int startTermIndex, SortedSetDocValues si, DocIdSetIterator disi, int subIndex, OrdinalMap map) throws IOException { + if (startTermIndex == -1 && (map == null || si.getValueCount() < disi.cost()*10)) { + // no prefixing, not too many unique values wrt matching docs (lucene/facets heuristic): + // collect separately per-segment, then map to global ords + accumMultiSeg(counts, si, disi, subIndex, map); + } else { + // otherwise: do collect+map on the fly + accumMultiGeneric(counts, startTermIndex, si, disi, subIndex, map); + } + } + + /** accumulates per-segment multi-valued facet counts, mapping to global ordinal space on-the-fly */ + static void accumMultiGeneric(int counts[], int startTermIndex, SortedSetDocValues si, DocIdSetIterator disi, int subIndex, OrdinalMap map) throws IOException { int doc; while ((doc = disi.nextDoc()) != DocIdSetIterator.NO_MORE_DOCS) { si.setDocument(doc); @@ -269,4 +313,47 @@ public class DocValuesFacets { } while ((term = (int) si.nextOrd()) >= 0); } } + + /** "typical" multi-valued faceting: not too many unique values, no prefixing. maps to global ordinals as a separate step */ + static void accumMultiSeg(int counts[], SortedSetDocValues si, DocIdSetIterator disi, int subIndex, OrdinalMap map) throws IOException { + // First count in seg-ord space: + final int segCounts[]; + if (map == null) { + segCounts = counts; + } else { + segCounts = new int[1+(int)si.getValueCount()]; + } + + int doc; + while ((doc = disi.nextDoc()) != DocIdSetIterator.NO_MORE_DOCS) { + si.setDocument(doc); + int term = (int) si.nextOrd(); + if (term < 0) { + counts[0]++; // missing + } else { + do { + segCounts[1+term]++; + } while ((term = (int)si.nextOrd()) >= 0); + } + } + + // migrate to global ords (if necessary) + if (map != null) { + migrateGlobal(counts, segCounts, subIndex, map); + } + } + + /** folds counts in segment ordinal space (segCounts) into global ordinal space (counts) */ + static void migrateGlobal(int counts[], int segCounts[], int subIndex, OrdinalMap map) { + // missing count + counts[0] += segCounts[0]; + + // migrate actual ordinals + for (int ord = 1; ord < segCounts.length; ord++) { + int count = segCounts[ord]; + if (count != 0) { + counts[1+(int) map.getGlobalOrd(subIndex, ord-1)] += count; + } + } + } } diff --git a/solr/core/src/java/org/apache/solr/request/SimpleFacets.java b/solr/core/src/java/org/apache/solr/request/SimpleFacets.java index f1d2965eafa..1fdeec23198 100644 --- a/solr/core/src/java/org/apache/solr/request/SimpleFacets.java +++ b/solr/core/src/java/org/apache/solr/request/SimpleFacets.java @@ -566,7 +566,7 @@ public class SimpleFacets { throw se; } catch (Exception e) { throw new SolrException(ErrorCode.SERVER_ERROR, - "Exception during facet.field: " + workerFacetValue, e.getCause()); + "Exception during facet.field: " + workerFacetValue, e); } finally { semaphore.release(); } diff --git a/solr/core/src/java/org/apache/solr/search/BitDocSet.java b/solr/core/src/java/org/apache/solr/search/BitDocSet.java index 0346ab71a57..f793982a9ff 100644 --- a/solr/core/src/java/org/apache/solr/search/BitDocSet.java +++ b/solr/core/src/java/org/apache/solr/search/BitDocSet.java @@ -296,11 +296,11 @@ public class BitDocSet extends DocSetBase { @Override public long cost() { // we don't want to actually compute cardinality, but - // if its already been computed, we use it + // if its already been computed, we use it (pro-rated for the segment) if (size != -1) { - return size; + return (long)(size * ((OpenBitSet.bits2words(maxDoc)<<6) / (float)bs.capacity())); } else { - return bs.capacity(); + return maxDoc; } } }; From 4460efe7290705f2327c5d4041ccec6199844e0b Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Sat, 30 Nov 2013 02:19:12 +0000 Subject: [PATCH 141/223] tests: remove start the deadpool option when monkey stops git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1546677 13f79535-47bb-0310-9956-ffa450edef68 --- .../solr/cloud/ChaosMonkeyNothingIsSafeTest.java | 2 +- .../apache/solr/cloud/ChaosMonkeySafeLeaderTest.java | 2 +- .../src/java/org/apache/solr/cloud/ChaosMonkey.java | 12 +----------- 3 files changed, 3 insertions(+), 13 deletions(-) diff --git a/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java b/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java index e4183f027e0..13ccc6dae4b 100644 --- a/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java @@ -138,7 +138,7 @@ public class ChaosMonkeyNothingIsSafeTest extends AbstractFullDistribZkTestBase ftIndexThread.start(); } - chaosMonkey.startTheMonkey(true, true, 10000); + chaosMonkey.startTheMonkey(true, 10000); long runLength; if (RUN_LENGTH != -1) { diff --git a/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeySafeLeaderTest.java b/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeySafeLeaderTest.java index 5d71fe99b70..ff09b192fcf 100644 --- a/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeySafeLeaderTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeySafeLeaderTest.java @@ -99,7 +99,7 @@ public class ChaosMonkeySafeLeaderTest extends AbstractFullDistribZkTestBase { indexThread.start(); } - chaosMonkey.startTheMonkey(false, false, 500); + chaosMonkey.startTheMonkey(false, 500); long runLength; if (RUN_LENGTH != -1) { runLength = RUN_LENGTH; diff --git a/solr/test-framework/src/java/org/apache/solr/cloud/ChaosMonkey.java b/solr/test-framework/src/java/org/apache/solr/cloud/ChaosMonkey.java index b9e0561f7ee..c1128f9bdf0 100644 --- a/solr/test-framework/src/java/org/apache/solr/cloud/ChaosMonkey.java +++ b/solr/test-framework/src/java/org/apache/solr/cloud/ChaosMonkey.java @@ -435,7 +435,7 @@ public class ChaosMonkey { // synchronously starts and stops shards randomly, unless there is only one // active shard up for a slice or if there is one active and others recovering - public void startTheMonkey(boolean killLeaders, final boolean startDeadPool, final int roundPauseUpperLimit) { + public void startTheMonkey(boolean killLeaders, final int roundPauseUpperLimit) { if (!MONKEY_ENABLED) { monkeyLog("The Monkey is disabled and will not start"); return; @@ -503,16 +503,6 @@ public class ChaosMonkey { monkeyLog("I ran for " + (System.currentTimeMillis() - startTime)/1000.0f + "sec. I stopped " + stops + " and I started " + starts + ". I also expired " + expires.get() + " and caused " + connloss + " connection losses"); - if (startDeadPool) { - // starting down nodes - for (CloudJettyRunner jetty : deadPool) { - try { - if (jetty.jetty.isStopped()) ChaosMonkey.start(jetty.jetty); - } catch (Exception e) { - log.error("", e); - } - } - } } }; monkeyThread.start(); From a6eb226481c5cccfb62e89b8c25b6cc77ef4f976 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Sat, 30 Nov 2013 02:30:56 +0000 Subject: [PATCH 142/223] boost the get leader timeout a bit git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1546679 13f79535-47bb-0310-9956-ffa450edef68 --- .../src/java/org/apache/solr/common/cloud/ZkStateReader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java b/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java index 28c478e6292..ee17f8ab270 100644 --- a/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java +++ b/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java @@ -497,7 +497,7 @@ public class ZkStateReader { * Get shard leader properties, with retry if none exist. */ public Replica getLeaderRetry(String collection, String shard) throws InterruptedException { - return getLeaderRetry(collection, shard, 2000); + return getLeaderRetry(collection, shard, 4000); } /** From 1641ccea60965caca5501a17799f4edfa0e843c5 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Sat, 30 Nov 2013 03:03:44 +0000 Subject: [PATCH 143/223] SOLR-5516: wait a moment before trying to Sync git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1546683 13f79535-47bb-0310-9956-ffa450edef68 --- .../core/src/java/org/apache/solr/cloud/SyncStrategy.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/solr/core/src/java/org/apache/solr/cloud/SyncStrategy.java b/solr/core/src/java/org/apache/solr/cloud/SyncStrategy.java index 4c104269506..0b5a67a44df 100644 --- a/solr/core/src/java/org/apache/solr/cloud/SyncStrategy.java +++ b/solr/core/src/java/org/apache/solr/cloud/SyncStrategy.java @@ -27,6 +27,7 @@ import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.impl.HttpSolrServer; import org.apache.solr.client.solrj.request.CoreAdminRequest.RequestRecovery; import org.apache.solr.common.SolrException; +import org.apache.solr.common.SolrException.ErrorCode; import org.apache.solr.common.cloud.ZkCoreNodeProps; import org.apache.solr.common.cloud.ZkNodeProps; import org.apache.solr.common.cloud.ZkStateReader; @@ -93,6 +94,13 @@ public class SyncStrategy { log.error("No UpdateLog found - cannot sync"); return false; } + // wait a second for any floating updates to finish + try { + Thread.sleep(1500); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new SolrException(ErrorCode.SERVICE_UNAVAILABLE, e); + } success = syncReplicas(zkController, core, leaderProps); } finally { SolrRequestInfo.clearRequestInfo(); From 484c8e98bbdbcdc0c8ac406328392afcd079ac0a Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Sat, 30 Nov 2013 03:34:27 +0000 Subject: [PATCH 144/223] SOLR-5509: More logging git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1546685 13f79535-47bb-0310-9956-ffa450edef68 --- .../java/org/apache/solr/update/SolrCmdDistributor.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java b/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java index 48fc2bf4c14..e5e5baf7bc9 100644 --- a/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java +++ b/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java @@ -116,7 +116,8 @@ public class SolrCmdDistributor { SolrException.log(SolrCmdDistributor.log, "forwarding update to " + oldNodeUrl + " failed - retrying ... retries: " - + err.req.retries + " " + err.req.cmdString + " rsp:" + rspCode, err.e); + + err.req.retries + " " + err.req.cmdString + " params:" + + err.req.uReq.getParams() + " rsp:" + rspCode, err.e); try { Thread.sleep(retryPause); } catch (InterruptedException e) { @@ -226,7 +227,11 @@ public class SolrCmdDistributor { return; } - + if (log.isDebugEnabled()) { + log.debug("sending update to " + + req.node.getUrl() + " retry:" + + req.retries + " " + req.cmdString + " params:" + req.uReq.getParams()); + } try { SolrServer solrServer = servers.getSolrServer(req); NamedList rsp = solrServer.request(req.uReq); From 655a12466f1e50bd5d36f6cbc776fa3ec8d71c64 Mon Sep 17 00:00:00 2001 From: Shalin Shekhar Mangar Date: Sat, 30 Nov 2013 13:04:23 +0000 Subject: [PATCH 145/223] SOLR-5515: NPE when getting stats on date field with empty result on SolrCloud git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1546725 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 5 ++++- .../solr/handler/component/StatsValuesFactory.java | 7 +++++-- .../src/test/org/apache/solr/TestDistributedSearch.java | 9 +++++++++ 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index e81dc7941e0..0c89faf6a64 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -161,7 +161,10 @@ Bug Fixes a SolrCore does not exist in core discovery mode. (Mark Miller) * SOLR-5354: Distributed sort is broken with CUSTOM FieldType. - (Steve Rowe, hossman, Robert Muir, Jessica Cheng) + (Steve Rowe, hossman, Robert Muir, Jessica Cheng) + +* SOLR-5515: NPE when getting stats on date field with empty result on + SolrCloud. (Alexander Sagen, shalin) Optimizations ---------------------- diff --git a/solr/core/src/java/org/apache/solr/handler/component/StatsValuesFactory.java b/solr/core/src/java/org/apache/solr/handler/component/StatsValuesFactory.java index e4508afab07..b59283cfc78 100644 --- a/solr/core/src/java/org/apache/solr/handler/component/StatsValuesFactory.java +++ b/solr/core/src/java/org/apache/solr/handler/component/StatsValuesFactory.java @@ -419,8 +419,11 @@ class DateStatsValues extends AbstractStatsValues { */ @Override protected void updateTypeSpecificStats(NamedList stv) { - sum += ((Date) stv.get("sum")).getTime(); - sumOfSquares += ((Number)stv.get("sumOfSquares")).doubleValue(); + Date date = (Date) stv.get("sum"); + if (date != null) { + sum += date.getTime(); + sumOfSquares += ((Number)stv.get("sumOfSquares")).doubleValue(); + } } /** diff --git a/solr/core/src/test/org/apache/solr/TestDistributedSearch.java b/solr/core/src/test/org/apache/solr/TestDistributedSearch.java index d18dde208c4..2c6f0232f46 100644 --- a/solr/core/src/test/org/apache/solr/TestDistributedSearch.java +++ b/solr/core/src/test/org/apache/solr/TestDistributedSearch.java @@ -398,6 +398,15 @@ public class TestDistributedSearch extends BaseDistributedSearchTestCase { // Thread.sleep(10000000000L); FieldCache.DEFAULT.purgeAllCaches(); // avoid FC insanity + + del("*:*"); // delete all docs and test stats request + commit(); + try { + query("q", "*:*", "stats", "true", "stats.field", "stats_dt", "stats.calcdistinct", "true"); + } catch (Exception e) { + log.error("Exception on distrib stats request on empty index", e); + fail("NullPointerException with stats request on empty index"); + } } protected void queryPartialResults(final List upShards, From c3cbded1b1f9306f89350aaf6662c07d91a344b0 Mon Sep 17 00:00:00 2001 From: Shalin Shekhar Mangar Date: Sun, 1 Dec 2013 04:43:27 +0000 Subject: [PATCH 146/223] SOLR-5499: Added a warning note in example solrconfig.xml against removing realtime get handler git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1546776 13f79535-47bb-0310-9956-ffa450edef68 --- solr/example/solr/collection1/conf/solrconfig.xml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/solr/example/solr/collection1/conf/solrconfig.xml b/solr/example/solr/collection1/conf/solrconfig.xml index d8b14dfb8e3..fa467336a97 100755 --- a/solr/example/solr/collection1/conf/solrconfig.xml +++ b/solr/example/solr/collection1/conf/solrconfig.xml @@ -872,7 +872,15 @@ + current implementation relies on the updateLog feature being enabled. + + ** WARNING ** + Do NOT disable the realtime get handler at /get if you are using + SolrCloud otherwise any leader election will cause a full sync in ALL + replicas for the shard in question. Similarly, a replica recovery will + also always fetch the complete index from the leader because a partial + sync will not be possible in the absence of this handler. + --> true From 7b7339d733ad52b3ca9629e4d13f25909e9248d9 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Sun, 1 Dec 2013 05:09:31 +0000 Subject: [PATCH 147/223] SOLR-5509: Raise id's per thread so they won't overlap git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1546779 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java b/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java index 13ccc6dae4b..a99848742a3 100644 --- a/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java @@ -115,8 +115,9 @@ public class ChaosMonkeyNothingIsSafeTest extends AbstractFullDistribZkTestBase int threadCount = 1; int i = 0; for (i = 0; i < threadCount; i++) { + // ensure the id start is high enough that threads will not overlap doc ids StopableIndexingThread indexThread = new StopableIndexingThread( - (i+1) * 50000, true); + (i+1) * 25000000, true); threads.add(indexThread); indexThread.start(); } From 1460d8c9d55200430cd09d28f9be8ee971928af2 Mon Sep 17 00:00:00 2001 From: Shalin Shekhar Mangar Date: Sun, 1 Dec 2013 09:06:31 +0000 Subject: [PATCH 148/223] SOLR-5023: Add support for deleteInstanceDir to be passed from SolrJ for Core Unload action git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1546793 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 3 ++ .../handler/admin/CoreAdminHandlerTest.java | 53 +++++++++++++++++++ .../solrj/request/CoreAdminRequest.java | 28 ++++++++-- 3 files changed, 79 insertions(+), 5 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 0c89faf6a64..60aa15162b3 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -109,6 +109,9 @@ New Features * SOLR-5506: Support docValues in CollationField and ICUCollationField. (Robert Muir) +* SOLR-5023: Add support for deleteInstanceDir to be passed from SolrJ for Core + Unload action. (shalin) + Bug Fixes ---------------------- diff --git a/solr/core/src/test/org/apache/solr/handler/admin/CoreAdminHandlerTest.java b/solr/core/src/test/org/apache/solr/handler/admin/CoreAdminHandlerTest.java index bab126f7cfc..cb05b54b5b0 100644 --- a/solr/core/src/test/org/apache/solr/handler/admin/CoreAdminHandlerTest.java +++ b/solr/core/src/test/org/apache/solr/handler/admin/CoreAdminHandlerTest.java @@ -18,9 +18,14 @@ package org.apache.solr.handler.admin; import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule; +import org.apache.commons.codec.Charsets; import org.apache.commons.io.FileUtils; import org.apache.solr.SolrTestCaseJ4; +import org.apache.solr.client.solrj.embedded.JettySolrRunner; +import org.apache.solr.client.solrj.impl.HttpSolrServer; +import org.apache.solr.client.solrj.request.CoreAdminRequest; import org.apache.solr.common.SolrException; +import org.apache.solr.common.SolrInputDocument; import org.apache.solr.common.params.CoreAdminParams; import org.apache.solr.common.util.NamedList; import org.apache.solr.core.CoreContainer; @@ -221,4 +226,52 @@ public class CoreAdminHandlerTest extends SolrTestCaseJ4 { FileUtils.deleteDirectory(workDir); } + + @Test + public void testDeleteInstanceDir() throws Exception { + File solrHomeDirectory = new File(TEMP_DIR, getClass().getName() + "-corex-" + + System.currentTimeMillis()); + solrHomeDirectory.mkdirs(); + copySolrHomeToTemp(solrHomeDirectory, "corex", true); + File corex = new File(solrHomeDirectory, "corex"); + FileUtils.write(new File(corex, "core.properties"), "", Charsets.UTF_8.toString()); + JettySolrRunner runner = new JettySolrRunner(solrHomeDirectory.getAbsolutePath(), "/solr", 0); + HttpSolrServer server = null; + try { + runner.start(); + server = new HttpSolrServer("http://localhost:" + runner.getLocalPort() + "/solr/corex"); + server.setConnectionTimeout(SolrTestCaseJ4.DEFAULT_CONNECTION_TIMEOUT); + server.setSoTimeout(SolrTestCaseJ4.DEFAULT_CONNECTION_TIMEOUT); + SolrInputDocument doc = new SolrInputDocument(); + doc.addField("id", "123"); + server.add(doc); + server.commit(); + server.shutdown(); + + server = new HttpSolrServer("http://localhost:" + runner.getLocalPort() + "/solr"); + server.setConnectionTimeout(SolrTestCaseJ4.DEFAULT_CONNECTION_TIMEOUT); + server.setSoTimeout(SolrTestCaseJ4.DEFAULT_CONNECTION_TIMEOUT); + CoreAdminRequest.Unload req = new CoreAdminRequest.Unload(false); + req.setDeleteInstanceDir(true); + req.setCoreName("corex"); + req.process(server); + server.shutdown(); + + runner.stop(); + + assertFalse("Instance directory exists after core unload with deleteInstanceDir=true : " + corex, + corex.exists()); + } catch (Exception e) { + log.error("Exception testing core unload with deleteInstanceDir=true", e); + } finally { + if (server != null) { + server.shutdown(); + } + if (!runner.isStopped()) { + runner.stop(); + } + recurseDelete(solrHomeDirectory); + } + } + } diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/request/CoreAdminRequest.java b/solr/solrj/src/java/org/apache/solr/client/solrj/request/CoreAdminRequest.java index 7ce5a5ac375..9543ccd4c9e 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/request/CoreAdminRequest.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/request/CoreAdminRequest.java @@ -371,7 +371,8 @@ public class CoreAdminRequest extends SolrRequest public static class Unload extends CoreAdminRequest { protected boolean deleteIndex; - private boolean deleteDataDir; + protected boolean deleteDataDir; + protected boolean deleteInstanceDir; public Unload(boolean deleteIndex) { action = CoreAdminAction.UNLOAD; @@ -390,11 +391,24 @@ public class CoreAdminRequest extends SolrRequest this.deleteDataDir = deleteDataDir; } + public void setDeleteInstanceDir(boolean deleteInstanceDir){ + this.deleteInstanceDir = deleteInstanceDir; + } + + public boolean isDeleteDataDir() { + return deleteDataDir; + } + + public boolean isDeleteInstanceDir() { + return deleteInstanceDir; + } + @Override public SolrParams getParams() { ModifiableSolrParams params = (ModifiableSolrParams) super.getParams(); params.set(CoreAdminParams.DELETE_INDEX, deleteIndex); params.set(CoreAdminParams.DELETE_DATA_DIR, deleteDataDir); + params.set(CoreAdminParams.DELETE_INSTANCE_DIR, deleteInstanceDir); return params; } @@ -489,11 +503,15 @@ public class CoreAdminRequest extends SolrRequest return unloadCore(name, false, server); } - public static CoreAdminResponse unloadCore( String name, boolean deleteIndex, SolrServer server ) throws SolrServerException, IOException - { + public static CoreAdminResponse unloadCore(String name, boolean deleteIndex, SolrServer server) throws SolrServerException, IOException { + return unloadCore(name, deleteIndex, false, server); + } + + public static CoreAdminResponse unloadCore(String name, boolean deleteIndex, boolean deleteInstanceDir, SolrServer server) throws SolrServerException, IOException { Unload req = new Unload(deleteIndex); - req.setCoreName( name ); - return req.process( server ); + req.setCoreName(name); + req.setDeleteInstanceDir(deleteInstanceDir); + return req.process(server); } public static CoreAdminResponse renameCore(String coreName, String newName, SolrServer server ) throws SolrServerException, IOException From 1e26cb20ba466d8dea84762a072f250e97a3ca85 Mon Sep 17 00:00:00 2001 From: Shalin Shekhar Mangar Date: Sun, 1 Dec 2013 09:09:11 +0000 Subject: [PATCH 149/223] SOLR-5023: Add attribution to issue reporter git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1546795 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 60aa15162b3..d215aebecad 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -110,7 +110,7 @@ New Features (Robert Muir) * SOLR-5023: Add support for deleteInstanceDir to be passed from SolrJ for Core - Unload action. (shalin) + Unload action. (Lyubov Romanchuk, shalin) Bug Fixes ---------------------- From f56bf5b9d06c9d582e58f6861e37777d5bc213e9 Mon Sep 17 00:00:00 2001 From: Shalin Shekhar Mangar Date: Sun, 1 Dec 2013 15:06:42 +0000 Subject: [PATCH 150/223] SOLR-5204: StatsComponent and SpellCheckComponent do not support the shards.tolerant=true parameter git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1546819 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 3 +++ .../component/SpellCheckComponent.java | 11 +++++++- .../handler/component/StatsComponent.java | 11 +++++++- .../apache/solr/TestDistributedSearch.java | 25 +++++++++++++++++-- 4 files changed, 46 insertions(+), 4 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index d215aebecad..29b43f45b8a 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -169,6 +169,9 @@ Bug Fixes * SOLR-5515: NPE when getting stats on date field with empty result on SolrCloud. (Alexander Sagen, shalin) +* SOLR-5204: StatsComponent and SpellCheckComponent do not support the + shards.tolerant=true parameter. (Anca Kopetz, shalin) + Optimizations ---------------------- diff --git a/solr/core/src/java/org/apache/solr/handler/component/SpellCheckComponent.java b/solr/core/src/java/org/apache/solr/handler/component/SpellCheckComponent.java index 35a6c66592f..a2c609e3a9f 100644 --- a/solr/core/src/java/org/apache/solr/handler/component/SpellCheckComponent.java +++ b/solr/core/src/java/org/apache/solr/handler/component/SpellCheckComponent.java @@ -320,7 +320,16 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar if (maxResultsForSuggest==null || !isCorrectlySpelled) { for (ShardRequest sreq : rb.finished) { for (ShardResponse srsp : sreq.responses) { - NamedList nl = (NamedList) srsp.getSolrResponse().getResponse().get("spellcheck"); + NamedList nl = null; + try { + nl = (NamedList) srsp.getSolrResponse().getResponse().get("spellcheck"); + } catch (Exception e) { + if (rb.req.getParams().getBool(ShardParams.SHARDS_TOLERANT, false)) { + continue; // looks like a shard did not return anything + } + throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, + "Unable to read spelling info for shard: " + srsp.getShard(), e); + } LOG.info(srsp.getShard() + " " + nl); if (nl != null) { mergeData.totalNumberShardResponses++; diff --git a/solr/core/src/java/org/apache/solr/handler/component/StatsComponent.java b/solr/core/src/java/org/apache/solr/handler/component/StatsComponent.java index 3af0f62e5b8..34601804370 100644 --- a/solr/core/src/java/org/apache/solr/handler/component/StatsComponent.java +++ b/solr/core/src/java/org/apache/solr/handler/component/StatsComponent.java @@ -102,7 +102,16 @@ public class StatsComponent extends SearchComponent { StatsInfo si = rb._statsInfo; for (ShardResponse srsp : sreq.responses) { - NamedList stats = (NamedList) srsp.getSolrResponse().getResponse().get("stats"); + NamedList stats = null; + try { + stats = (NamedList) srsp.getSolrResponse().getResponse().get("stats"); + } catch (Exception e) { + if (rb.req.getParams().getBool(ShardParams.SHARDS_TOLERANT, false)) { + continue; // looks like a shard did not return anything + } + throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, + "Unable to read stats info for shard: " + srsp.getShard(), e); + } NamedList stats_fields = (NamedList) stats.get("stats_fields"); if (stats_fields != null) { diff --git a/solr/core/src/test/org/apache/solr/TestDistributedSearch.java b/solr/core/src/test/org/apache/solr/TestDistributedSearch.java index 2c6f0232f46..d0887f4f7c8 100644 --- a/solr/core/src/test/org/apache/solr/TestDistributedSearch.java +++ b/solr/core/src/test/org/apache/solr/TestDistributedSearch.java @@ -105,6 +105,8 @@ public class TestDistributedSearch extends BaseDistributedSearchTestCase { t1,"no eggs on wall, lesson learned", oddField, "odd man out"); + indexr(id, "1001", "lowerfilt", "toyota"); // for spellcheck + indexr(id, 14, "SubjectTerms_mfacet", new String[] {"mathematical models", "mathematical analysis"}); indexr(id, 15, "SubjectTerms_mfacet", new String[] {"test 1", "test 2", "test3"}); indexr(id, 16, "SubjectTerms_mfacet", new String[] {"test 1", "test 2", "test3"}); @@ -227,6 +229,9 @@ public class TestDistributedSearch extends BaseDistributedSearchTestCase { query("q","*:*", "fl", "id", "fl",nint, "fl",tint,"sort",i1 + " desc"); query("q","*:*", "fl",nint, "fl", "id", "fl",tint,"sort",i1 + " desc"); + // basic spellcheck testing + query("q", "toyata", "fl", "id,lowerfilt", "spellcheck", true, "spellcheck.q", "toyata", "qt", "spellCheckCompRH_Direct", "shards.qt", "spellCheckCompRH_Direct"); + stress=0; // turn off stress... we want to tex max combos in min time for (int i=0; i<25*RANDOM_MULTIPLIER; i++) { String f = fieldNames[random().nextInt(fieldNames.length)]; @@ -336,7 +341,7 @@ public class TestDistributedSearch extends BaseDistributedSearchTestCase { assertNotNull("missing shard info", sinfo); assertEquals("should have an entry for each shard ["+sinfo+"] "+shards, cnt, sinfo.size()); - + // test shards.tolerant=true for(int numDownServers = 0; numDownServers < jettys.size()-1; numDownServers++) { @@ -383,6 +388,22 @@ public class TestDistributedSearch extends BaseDistributedSearchTestCase { ShardParams.SHARDS_INFO, "true", ShardParams.SHARDS_TOLERANT, "true"); + queryPartialResults(upShards, upClients, + "q", "*:*", + "stats", "true", + "stats.field", i1, + ShardParams.SHARDS_INFO, "true", + ShardParams.SHARDS_TOLERANT, "true"); + + queryPartialResults(upShards, upClients, + "q", "toyata", + "spellcheck", "true", + "spellcheck.q", "toyata", + "qt", "spellCheckCompRH_Direct", + "shards.qt", "spellCheckCompRH_Direct", + ShardParams.SHARDS_INFO, "true", + ShardParams.SHARDS_TOLERANT, "true"); + // restart the jettys for (JettySolrRunner downJetty : downJettys) { downJetty.start(); @@ -409,7 +430,7 @@ public class TestDistributedSearch extends BaseDistributedSearchTestCase { } } - protected void queryPartialResults(final List upShards, + protected void queryPartialResults(final List upShards, final List upClients, Object... q) throws Exception { From bbd4548428bf0f9fa96c1ca63c1480d99fd0abf5 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Sun, 1 Dec 2013 15:52:08 +0000 Subject: [PATCH 151/223] SOLR-5509: Better string ids for these tests git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1546821 13f79535-47bb-0310-9956-ffa450edef68 --- .../cloud/ChaosMonkeyNothingIsSafeTest.java | 35 +++++--- .../solr/cloud/ChaosMonkeySafeLeaderTest.java | 14 ++- .../org/apache/solr/cloud/RecoveryZkTest.java | 16 +++- .../cloud/AbstractFullDistribZkTestBase.java | 90 +++++++++---------- 4 files changed, 94 insertions(+), 61 deletions(-) diff --git a/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java b/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java index a99848742a3..0e2ca87582c 100644 --- a/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java @@ -51,6 +51,7 @@ public class ChaosMonkeyNothingIsSafeTest extends AbstractFullDistribZkTestBase @BeforeClass public static void beforeSuperClass() { + schemaString = "schema15.xml"; // we need a string id SolrCmdDistributor.testing_errorHook = new Diagnostics.Callable() { @Override public void call(Object... data) { @@ -68,6 +69,17 @@ public class ChaosMonkeyNothingIsSafeTest extends AbstractFullDistribZkTestBase SolrCmdDistributor.testing_errorHook = null; } + public static String[] fieldNames = new String[]{"f_i", "f_f", "f_d", "f_l", "f_dt"}; + public static RandVal[] randVals = new RandVal[]{rint, rfloat, rdouble, rlong, rdate}; + + protected String[] getFieldNames() { + return fieldNames; + } + + protected RandVal[] getRandValues() { + return randVals; + } + @Before @Override public void setUp() throws Exception { @@ -115,9 +127,7 @@ public class ChaosMonkeyNothingIsSafeTest extends AbstractFullDistribZkTestBase int threadCount = 1; int i = 0; for (i = 0; i < threadCount; i++) { - // ensure the id start is high enough that threads will not overlap doc ids - StopableIndexingThread indexThread = new StopableIndexingThread( - (i+1) * 25000000, true); + StopableIndexingThread indexThread = new StopableIndexingThread(Integer.toString(i), true); threads.add(indexThread); indexThread.start(); } @@ -134,7 +144,7 @@ public class ChaosMonkeyNothingIsSafeTest extends AbstractFullDistribZkTestBase boolean runFullThrottle = random().nextBoolean(); if (runFullThrottle) { FullThrottleStopableIndexingThread ftIndexThread = new FullThrottleStopableIndexingThread( - clients, (i+1) * 50000, true); + clients, "ft1", true); threads.add(ftIndexThread); ftIndexThread.start(); } @@ -248,8 +258,8 @@ public class ChaosMonkeyNothingIsSafeTest extends AbstractFullDistribZkTestBase private List clients; public FullThrottleStopableIndexingThread(List clients, - int startI, boolean doDeletes) { - super(startI, doDeletes); + String id, boolean doDeletes) { + super(id, doDeletes); setName("FullThrottleStopableIndexingThread"); setDaemon(true); this.clients = clients; @@ -267,18 +277,19 @@ public class ChaosMonkeyNothingIsSafeTest extends AbstractFullDistribZkTestBase @Override public void run() { - int i = startI; + int i = 0; int numDeletes = 0; int numAdds = 0; while (true && !stop) { + String id = this.id + "-" + i; ++i; if (doDeletes && random().nextBoolean() && deletes.size() > 0) { - Integer delete = deletes.remove(0); + String delete = deletes.remove(0); try { numDeletes++; - suss.deleteById(Integer.toString(delete)); + suss.deleteById(delete); } catch (Exception e) { changeUrlOnError(e); //System.err.println("REQUEST FAILED:"); @@ -292,12 +303,10 @@ public class ChaosMonkeyNothingIsSafeTest extends AbstractFullDistribZkTestBase if (numAdds > 4000) continue; SolrInputDocument doc = getDoc( + "id", id, - i, i1, 50, - tlong, - 50, t1, "Saxon heptarchies that used to rip around so in old times and raise Cain. My, you ought to seen old Henry the Eight when he was in bloom. He WAS a blossom. He used to marry a new wife every day, and chop off her head next morning. And he would do it just as indifferent as if "); suss.add(doc); @@ -309,7 +318,7 @@ public class ChaosMonkeyNothingIsSafeTest extends AbstractFullDistribZkTestBase } if (doDeletes && random().nextBoolean()) { - deletes.add(i); + deletes.add(id); } } diff --git a/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeySafeLeaderTest.java b/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeySafeLeaderTest.java index ff09b192fcf..7afe466ed56 100644 --- a/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeySafeLeaderTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeySafeLeaderTest.java @@ -38,6 +38,7 @@ public class ChaosMonkeySafeLeaderTest extends AbstractFullDistribZkTestBase { @BeforeClass public static void beforeSuperClass() { + schemaString = "schema15.xml"; // we need a string id SolrCmdDistributor.testing_errorHook = new Diagnostics.Callable() { @Override public void call(Object... data) { @@ -55,6 +56,17 @@ public class ChaosMonkeySafeLeaderTest extends AbstractFullDistribZkTestBase { SolrCmdDistributor.testing_errorHook = null; } + public static String[] fieldNames = new String[]{"f_i", "f_f", "f_d", "f_l", "f_dt"}; + public static RandVal[] randVals = new RandVal[]{rint, rfloat, rdouble, rlong, rdate}; + + protected String[] getFieldNames() { + return fieldNames; + } + + protected RandVal[] getRandValues() { + return randVals; + } + @Before @Override public void setUp() throws Exception { @@ -94,7 +106,7 @@ public class ChaosMonkeySafeLeaderTest extends AbstractFullDistribZkTestBase { List threads = new ArrayList(); int threadCount = 2; for (int i = 0; i < threadCount; i++) { - StopableIndexingThread indexThread = new StopableIndexingThread(10000 + i*50000, true); + StopableIndexingThread indexThread = new StopableIndexingThread(Integer.toString(i), true); threads.add(indexThread); indexThread.start(); } diff --git a/solr/core/src/test/org/apache/solr/cloud/RecoveryZkTest.java b/solr/core/src/test/org/apache/solr/cloud/RecoveryZkTest.java index 28e473a39bb..6bb1328cfbd 100644 --- a/solr/core/src/test/org/apache/solr/cloud/RecoveryZkTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/RecoveryZkTest.java @@ -40,8 +40,20 @@ public class RecoveryZkTest extends AbstractFullDistribZkTestBase { super(); sliceCount = 1; shardCount = 2; + schemaString = "schema15.xml"; // we need a string id } + public static String[] fieldNames = new String[]{"f_i", "f_f", "f_d", "f_l", "f_dt"}; + public static RandVal[] randVals = new RandVal[]{rint, rfloat, rdouble, rlong, rdate}; + + protected String[] getFieldNames() { + return fieldNames; + } + + protected RandVal[] getRandValues() { + return randVals; + } + @Override public void doTest() throws Exception { handle.clear(); @@ -54,10 +66,10 @@ public class RecoveryZkTest extends AbstractFullDistribZkTestBase { int maxDoc = maxDocList[random().nextInt(maxDocList.length - 1)]; - indexThread = new StopableIndexingThread(0, true, maxDoc); + indexThread = new StopableIndexingThread("1", true, maxDoc); indexThread.start(); - indexThread2 = new StopableIndexingThread(10000, true, maxDoc); + indexThread2 = new StopableIndexingThread("2", true, maxDoc); indexThread2.start(); diff --git a/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java b/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java index 6e15ed7d283..db92d136eb4 100644 --- a/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java +++ b/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java @@ -17,10 +17,29 @@ package org.apache.solr.cloud; * limitations under the License. */ +import static org.apache.solr.cloud.OverseerCollectionProcessor.CREATE_NODE_SET; +import static org.apache.solr.cloud.OverseerCollectionProcessor.MAX_SHARDS_PER_NODE; +import static org.apache.solr.cloud.OverseerCollectionProcessor.NUM_SLICES; +import static org.apache.solr.cloud.OverseerCollectionProcessor.REPLICATION_FACTOR; +import static org.apache.solr.cloud.OverseerCollectionProcessor.SHARDS_PROP; + +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URI; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Random; +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; + import org.apache.commons.io.FilenameUtils; import org.apache.http.params.CoreConnectionPNames; import org.apache.lucene.util.LuceneTestCase.Slow; -import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.SolrRequest; import org.apache.solr.client.solrj.SolrServer; @@ -58,26 +77,6 @@ import org.junit.BeforeClass; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.File; -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URI; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Random; -import java.util.Set; -import java.util.concurrent.atomic.AtomicInteger; - -import static org.apache.solr.cloud.OverseerCollectionProcessor.CREATE_NODE_SET; -import static org.apache.solr.cloud.OverseerCollectionProcessor.MAX_SHARDS_PER_NODE; -import static org.apache.solr.cloud.OverseerCollectionProcessor.NUM_SLICES; -import static org.apache.solr.cloud.OverseerCollectionProcessor.REPLICATION_FACTOR; -import static org.apache.solr.cloud.OverseerCollectionProcessor.SHARDS_PROP; - /** * TODO: we should still test this works as a custom update chain as well as * what we test now - the default update chain @@ -848,23 +847,23 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes } protected void indexAbunchOfDocs() throws Exception { - indexr(id, 2, i1, 50, tlong, 50, t1, "to come to the aid of their country."); - indexr(id, 3, i1, 2, tlong, 2, t1, "how now brown cow"); - indexr(id, 4, i1, -100, tlong, 101, t1, + indexr(id, 2, i1, 50, t1, "to come to the aid of their country."); + indexr(id, 3, i1, 2, t1, "how now brown cow"); + indexr(id, 4, i1, -100, t1, "the quick fox jumped over the lazy dog"); - indexr(id, 5, i1, 500, tlong, 500, t1, + indexr(id, 5, i1, 500, t1, "the quick fox jumped way over the lazy dog"); - indexr(id, 6, i1, -600, tlong, 600, t1, "humpty dumpy sat on a wall"); - indexr(id, 7, i1, 123, tlong, 123, t1, "humpty dumpy had a great fall"); - indexr(id, 8, i1, 876, tlong, 876, t1, + indexr(id, 6, i1, -600, t1, "humpty dumpy sat on a wall"); + indexr(id, 7, i1, 123, t1, "humpty dumpy had a great fall"); + indexr(id, 8, i1, 876, t1, "all the kings horses and all the kings men"); - indexr(id, 9, i1, 7, tlong, 7, t1, "couldn't put humpty together again"); - indexr(id, 10, i1, 4321, tlong, 4321, t1, "this too shall pass"); - indexr(id, 11, i1, -987, tlong, 987, t1, + indexr(id, 9, i1, 7, t1, "couldn't put humpty together again"); + indexr(id, 10, i1, 4321, t1, "this too shall pass"); + indexr(id, 11, i1, -987, t1, "An eye for eye only ends up making the whole world blind."); - indexr(id, 12, i1, 379, tlong, 379, t1, + indexr(id, 12, i1, 379, t1, "Great works are performed, not by strength, but by perseverance."); - indexr(id, 13, i1, 232, tlong, 232, t1, "no eggs on wall, lesson learned", + indexr(id, 13, i1, 232, t1, "no eggs on wall, lesson learned", oddField, "odd man out"); indexr(id, 14, "SubjectTerms_mfacet", new String[] {"mathematical models", @@ -1336,19 +1335,19 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes class StopableIndexingThread extends StopableThread { private volatile boolean stop = false; - protected final int startI; - protected final List deletes = new ArrayList(); + protected final String id; + protected final List deletes = new ArrayList(); protected final AtomicInteger fails = new AtomicInteger(); protected boolean doDeletes; private int numCycles; - public StopableIndexingThread(int startI, boolean doDeletes) { - this(startI, doDeletes, -1); + public StopableIndexingThread(String id, boolean doDeletes) { + this(id, doDeletes, -1); } - public StopableIndexingThread(int startI, boolean doDeletes, int numCycles) { + public StopableIndexingThread(String id, boolean doDeletes, int numCycles) { super("StopableIndexingThread"); - this.startI = startI; + this.id = id; this.doDeletes = doDeletes; this.numCycles = numCycles; setDaemon(true); @@ -1356,7 +1355,7 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes @Override public void run() { - int i = startI; + int i = 0; int numDone = 0; int numDeletes = 0; int numAdds = 0; @@ -1368,19 +1367,20 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes } } ++numDone; + String id = this.id + "-" + i; ++i; boolean addFailed = false; if (doDeletes && random().nextBoolean() && deletes.size() > 0) { - Integer delete = deletes.remove(0); + String delete = deletes.remove(0); try { numDeletes++; UpdateRequest req = new UpdateRequest(); - req.deleteById(Integer.toString(delete)); + req.deleteById(delete); req.setParam("CONTROL", "TRUE"); req.process(controlClient); - cloudClient.deleteById(Integer.toString(delete)); + cloudClient.deleteById(delete); } catch (Exception e) { System.err.println("REQUEST FAILED:"); e.printStackTrace(); @@ -1394,7 +1394,7 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes try { numAdds++; - indexr(id, i, i1, 50, tlong, 50, t1, + indexr("id", id, i1, 50, t1, "to come to the aid of their country."); } catch (Exception e) { addFailed = true; @@ -1408,7 +1408,7 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes } if (!addFailed && doDeletes && random().nextBoolean()) { - deletes.add(i); + deletes.add(id); } try { From 2cc87df6ef44f2ab994728932ca2bff9c6cebc5b Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Sun, 1 Dec 2013 20:15:47 +0000 Subject: [PATCH 152/223] SOLR-5516: Try only waiting if we are a replacement leader and waiting a bit longer. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1546851 13f79535-47bb-0310-9956-ffa450edef68 --- .../java/org/apache/solr/cloud/ElectionContext.java | 11 +++++++++++ .../src/java/org/apache/solr/cloud/SyncStrategy.java | 8 +------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/solr/core/src/java/org/apache/solr/cloud/ElectionContext.java b/solr/core/src/java/org/apache/solr/cloud/ElectionContext.java index 22cb75cab60..314bd1094f6 100644 --- a/solr/core/src/java/org/apache/solr/cloud/ElectionContext.java +++ b/solr/core/src/java/org/apache/solr/cloud/ElectionContext.java @@ -185,6 +185,17 @@ final class ShardLeaderElectionContext extends ShardLeaderElectionContextBase { // we are going to attempt to be the leader // first cancel any current recovery core.getUpdateHandler().getSolrCoreState().cancelRecovery(); + + if (weAreReplacement) { + // wait a moment for any floating updates to finish + try { + Thread.sleep(2500); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new SolrException(ErrorCode.SERVICE_UNAVAILABLE, e); + } + } + boolean success = false; try { success = syncStrategy.sync(zkController, core, leaderProps); diff --git a/solr/core/src/java/org/apache/solr/cloud/SyncStrategy.java b/solr/core/src/java/org/apache/solr/cloud/SyncStrategy.java index 0b5a67a44df..a3c04cfa24c 100644 --- a/solr/core/src/java/org/apache/solr/cloud/SyncStrategy.java +++ b/solr/core/src/java/org/apache/solr/cloud/SyncStrategy.java @@ -94,13 +94,7 @@ public class SyncStrategy { log.error("No UpdateLog found - cannot sync"); return false; } - // wait a second for any floating updates to finish - try { - Thread.sleep(1500); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new SolrException(ErrorCode.SERVICE_UNAVAILABLE, e); - } + success = syncReplicas(zkController, core, leaderProps); } finally { SolrRequestInfo.clearRequestInfo(); From 1e42240e8969342cb4ccceb007d1aa4031239b01 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Sun, 1 Dec 2013 21:58:45 +0000 Subject: [PATCH 153/223] SOLR-5482: add option to simulate hard jetty fails with iptables git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1546863 13f79535-47bb-0310-9956-ffa450edef68 --- .../solr/common/cloud/SolrZooKeeper.java | 5 + .../java/org/apache/solr/SolrTestCaseJ4.java | 3 + .../cloud/AbstractFullDistribZkTestBase.java | 2 +- .../org/apache/solr/cloud/ChaosMonkey.java | 33 ++++- .../java/org/apache/solr/cloud/IpTables.java | 116 ++++++++++++++++++ 5 files changed, 157 insertions(+), 2 deletions(-) create mode 100644 solr/test-framework/src/java/org/apache/solr/cloud/IpTables.java diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/SolrZooKeeper.java b/solr/solrj/src/java/org/apache/solr/common/cloud/SolrZooKeeper.java index 294dba80654..df352cdd7cf 100644 --- a/solr/solrj/src/java/org/apache/solr/common/cloud/SolrZooKeeper.java +++ b/solr/solrj/src/java/org/apache/solr/common/cloud/SolrZooKeeper.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.net.SocketAddress; import java.util.Set; import java.util.concurrent.CopyOnWriteArraySet; @@ -45,6 +46,10 @@ public class SolrZooKeeper extends ZooKeeper { return cnxn; } + public SocketAddress getSocketAddress() { + return testableLocalSocketAddress(); + } + /** * Cause this ZooKeeper object to stop receiving from the ZooKeeperServer * for the given number of milliseconds. diff --git a/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java b/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java index 61f2d1be823..f4d48e4c125 100644 --- a/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java +++ b/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java @@ -47,6 +47,7 @@ import org.apache.lucene.util.LuceneTestCase; import org.apache.lucene.util.QuickPatchThreadsFilter; import org.apache.lucene.util._TestUtil; import org.apache.solr.client.solrj.util.ClientUtils; +import org.apache.solr.cloud.IpTables; import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrDocumentList; import org.apache.solr.common.SolrException; @@ -143,6 +144,8 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase { System.clearProperty("tests.shardhandler.randomSeed"); System.clearProperty("enable.update.log"); System.clearProperty("useCompoundFile"); + + IpTables.unblockAllPorts(); } private static boolean changedFactory = false; diff --git a/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java b/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java index db92d136eb4..9fd762a0a79 100644 --- a/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java +++ b/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java @@ -210,7 +210,7 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes } @AfterClass - public static void afterClass() { + public static void afterClass() throws Exception { System.clearProperty("solrcloud.update.delay"); System.clearProperty("genericCoreNodeNames"); } diff --git a/solr/test-framework/src/java/org/apache/solr/cloud/ChaosMonkey.java b/solr/test-framework/src/java/org/apache/solr/cloud/ChaosMonkey.java index c1128f9bdf0..3e6091740da 100644 --- a/solr/test-framework/src/java/org/apache/solr/cloud/ChaosMonkey.java +++ b/solr/test-framework/src/java/org/apache/solr/cloud/ChaosMonkey.java @@ -17,12 +17,15 @@ package org.apache.solr.cloud; * limitations under the License. */ +import java.net.InetSocketAddress; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Random; import java.util.concurrent.atomic.AtomicInteger; +import javax.servlet.Filter; + import org.apache.lucene.util.LuceneTestCase; import org.apache.solr.client.solrj.SolrServer; import org.apache.solr.client.solrj.embedded.JettySolrRunner; @@ -226,6 +229,21 @@ public class ChaosMonkey { } public static void kill(CloudJettyRunner cjetty) throws Exception { + FilterHolder filterHolder = cjetty.jetty.getDispatchFilter(); + if (filterHolder != null) { + Filter filter = filterHolder.getFilter(); + if (filter != null) { + CoreContainer cores = ((SolrDispatchFilter) filter).getCores(); + if (cores != null) { + int zklocalport = ((InetSocketAddress) cores.getZkController() + .getZkClient().getSolrZooKeeper().getSocketAddress()).getPort(); + IpTables.blockPort(zklocalport); + } + } + } + + IpTables.blockPort(cjetty.jetty.getLocalPort()); + JettySolrRunner jetty = cjetty.jetty; monkeyLog("kill shard! " + jetty.getLocalPort()); @@ -534,7 +552,8 @@ public class ChaosMonkey { } public static boolean start(JettySolrRunner jetty) throws Exception { - + + IpTables.unblockPort(jetty.getLocalPort()); try { jetty.start(); } catch (Exception e) { @@ -555,6 +574,18 @@ public class ChaosMonkey { } } } + FilterHolder filterHolder = jetty.getDispatchFilter(); + if (filterHolder != null) { + Filter filter = filterHolder.getFilter(); + if (filter != null) { + CoreContainer cores = ((SolrDispatchFilter) filter).getCores(); + if (cores != null) { + int zklocalport = ((InetSocketAddress) cores.getZkController() + .getZkClient().getSolrZooKeeper().getSocketAddress()).getPort(); + IpTables.unblockPort(zklocalport); + } + } + } return true; } diff --git a/solr/test-framework/src/java/org/apache/solr/cloud/IpTables.java b/solr/test-framework/src/java/org/apache/solr/cloud/IpTables.java new file mode 100644 index 00000000000..2bdd14d821e --- /dev/null +++ b/solr/test-framework/src/java/org/apache/solr/cloud/IpTables.java @@ -0,0 +1,116 @@ +package org.apache.solr.cloud; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintStream; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * To use, tests must be able to run iptables, eg sudo chmod u+s iptables + */ +public class IpTables { + static final Logger log = LoggerFactory + .getLogger(IpTables.class); + + private static boolean ENABLED = Boolean.getBoolean("solr.tests.use.iptables"); + static class ThreadPumper { + + public ThreadPumper() {} + + public static Thread start(final InputStream from, final OutputStream to, final boolean verbose) { + Thread t = new Thread() { + @Override + public void run() { + try { + byte [] buffer = new byte [1024]; + int len; + while ((len = from.read(buffer)) != -1) { + if (verbose) { + to.write(buffer, 0, len); + } + } + } catch (IOException e) { + System.err.println("Couldn't pipe from the forked process: " + e.toString()); + } + } + }; + t.start(); + return t; + } + } + + private static Set BLOCK_PORTS = Collections.synchronizedSet(new HashSet()); + + public static void blockPort(int port) throws IOException, + InterruptedException { + if (ENABLED) { + log.info("Block port with iptables: " + port); + BLOCK_PORTS.add(port); + runCmd(("iptables -A INPUT -p tcp --dport " + port + " -j DROP") + .split("\\s")); + runCmd(("iptables -A OUTPUT -p tcp --dport " + port + " -j DROP") + .split("\\s")); + } + } + + public static void unblockPort(int port) throws IOException, + InterruptedException { + if (ENABLED) { + log.info("Unblock port with iptables: " + port); + runCmd(("iptables -D INPUT -p tcp --dport " + port + " -j DROP") + .split("\\s")); + runCmd(("iptables -D OUTPUT -p tcp --dport " + port + " -j DROP") + .split("\\s")); + } + } + + public static void unblockAllPorts() throws IOException, InterruptedException { + if (ENABLED) { + log.info("Unblocking any ports previously blocked with iptables..."); + for (Integer port : BLOCK_PORTS) { + IpTables.unblockPort(port); + } + } + } + + private static void runCmd(String[] cmd) throws IOException, InterruptedException { + ProcessBuilder pb = new ProcessBuilder(cmd); + + pb.redirectErrorStream(true); + Process p = pb.start(); + + // We pump everything to stderr. + PrintStream childOut = System.err; + Thread stdoutPumper = ThreadPumper.start(p.getInputStream(), childOut, true); + Thread stderrPumper = ThreadPumper.start(p.getErrorStream(), childOut, true); + if (true) childOut.println(">>> Begin subprocess output"); + p.waitFor(); + stdoutPumper.join(); + stderrPumper.join(); + if (true) childOut.println("<<< End subprocess output"); + } +} From a7f879db7682841539468f9af71f8b28423d9321 Mon Sep 17 00:00:00 2001 From: Noble Paul Date: Mon, 2 Dec 2013 07:25:58 +0000 Subject: [PATCH 154/223] SOLR-5510 git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1546922 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/solr/cloud/ZkController.java | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/solr/core/src/java/org/apache/solr/cloud/ZkController.java b/solr/core/src/java/org/apache/solr/cloud/ZkController.java index a4aac548ddc..d291eb9ba55 100644 --- a/solr/core/src/java/org/apache/solr/cloud/ZkController.java +++ b/solr/core/src/java/org/apache/solr/cloud/ZkController.java @@ -1333,30 +1333,31 @@ public final class ZkController { public void preRegister(CoreDescriptor cd ) { String coreNodeName = getCoreNodeName(cd); - - // make sure the node name is set on the descriptor - if (cd.getCloudDescriptor().getCoreNodeName() == null) { - cd.getCloudDescriptor().setCoreNodeName(coreNodeName); - } - // before becoming available, make sure we are not live and active // this also gets us our assigned shard id if it was not specified try { - if(cd.getCloudDescriptor().getCollectionName() !=null && cd.getCloudDescriptor().getCoreNodeName() != null ) { + CloudDescriptor cloudDesc = cd.getCloudDescriptor(); + if(cd.getCloudDescriptor().getCollectionName() !=null && cloudDesc.getCoreNodeName() != null ) { //we were already registered - if(zkStateReader.getClusterState().hasCollection(cd.getCloudDescriptor().getCollectionName())){ - DocCollection coll = zkStateReader.getClusterState().getCollection(cd.getCloudDescriptor().getCollectionName()); + if(zkStateReader.getClusterState().hasCollection(cloudDesc.getCollectionName())){ + DocCollection coll = zkStateReader.getClusterState().getCollection(cloudDesc.getCollectionName()); if(!"true".equals(coll.getStr("autoCreated"))){ - Slice slice = coll.getSlice(cd.getCloudDescriptor().getShardId()); + Slice slice = coll.getSlice(cloudDesc.getShardId()); if(slice != null){ - if(slice.getReplica(cd.getCloudDescriptor().getCoreNodeName()) == null) { + if(slice.getReplica(cloudDesc.getCoreNodeName()) == null) { log.info("core_removed This core is removed from ZK"); - throw new SolrException(ErrorCode.NOT_FOUND,coreNodeName +" is removed"); + throw new SolrException(ErrorCode.NOT_FOUND,cloudDesc.getCoreNodeName() +" is removed"); } } } } } + + // make sure the node name is set on the descriptor + if (cloudDesc.getCoreNodeName() == null) { + cloudDesc.setCoreNodeName(coreNodeName); + } + publish(cd, ZkStateReader.DOWN, false); } catch (KeeperException e) { log.error("", e); From 4109c6db3365a901de47c97dcb41e673ee62ec95 Mon Sep 17 00:00:00 2001 From: Shalin Shekhar Mangar Date: Mon, 2 Dec 2013 08:33:33 +0000 Subject: [PATCH 155/223] SOLR-1871: The 'map' function query accepts a ValueSource as target and default value git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1546926 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/CHANGES.txt | 3 +++ .../valuesource/RangeMapFloatFunction.java | 25 +++++++++++-------- .../queries/function/TestValueSources.java | 8 ++++-- solr/CHANGES.txt | 3 +++ .../apache/solr/search/ValueSourceParser.java | 4 +-- .../search/function/TestFunctionQuery.java | 3 +++ 6 files changed, 32 insertions(+), 14 deletions(-) diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 9859b412fb5..f16bce3e712 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -73,6 +73,9 @@ New Features (missing the term, weight or payload). (Areek Zillur via Mike McCandless) +* SOLR-1871: The RangeMapFloatFunction accepts an arbitrary ValueSource + as target and default values. (Chris Harris, shalin) + Build * LUCENE-5217: Maven config: get dependencies from Ant+Ivy config; disable diff --git a/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/RangeMapFloatFunction.java b/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/RangeMapFloatFunction.java index 79df9b91411..2402af82fbe 100644 --- a/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/RangeMapFloatFunction.java +++ b/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/RangeMapFloatFunction.java @@ -27,8 +27,8 @@ import java.io.IOException; import java.util.Map; /** - * LinearFloatFunction implements a linear function over - * another {@link org.apache.lucene.queries.function.ValueSource}. + * RangeMapFloatFunction implements a map function over + * another {@link ValueSource} whose values fall within min and max inclusive to target. *
    * Normally Used as an argument to a {@link org.apache.lucene.queries.function.FunctionQuery} * @@ -38,10 +38,14 @@ public class RangeMapFloatFunction extends ValueSource { protected final ValueSource source; protected final float min; protected final float max; - protected final float target; - protected final Float defaultVal; + protected final ValueSource target; + protected final ValueSource defaultVal; public RangeMapFloatFunction(ValueSource source, float min, float max, float target, Float def) { + this(source, min, max, new ConstValueSource(target), def == null ? null : new ConstValueSource(def)); + } + + public RangeMapFloatFunction(ValueSource source, float min, float max, ValueSource target, ValueSource def) { this.source = source; this.min = min; this.max = max; @@ -51,21 +55,23 @@ public class RangeMapFloatFunction extends ValueSource { @Override public String description() { - return "map(" + source.description() + "," + min + "," + max + "," + target + ")"; + return "map(" + source.description() + "," + min + "," + max + "," + target.description() + ")"; } @Override public FunctionValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { final FunctionValues vals = source.getValues(context, readerContext); + final FunctionValues targets = target.getValues(context, readerContext); + final FunctionValues defaults = (this.defaultVal == null) ? null : defaultVal.getValues(context, readerContext); return new FloatDocValues(this) { @Override public float floatVal(int doc) { float val = vals.floatVal(doc); - return (val>=min && val<=max) ? target : (defaultVal == null ? val : defaultVal); + return (val>=min && val<=max) ? targets.floatVal(doc) : (defaultVal == null ? val : defaults.floatVal(doc)); } @Override public String toString(int doc) { - return "map(" + vals.toString(doc) + ",min=" + min + ",max=" + max + ",target=" + target + ")"; + return "map(" + vals.toString(doc) + ",min=" + min + ",max=" + max + ",target=" + targets.toString(doc) + ")"; } }; } @@ -82,8 +88,7 @@ public class RangeMapFloatFunction extends ValueSource { h += Float.floatToIntBits(min); h ^= (h << 14) | (h >>> 19); h += Float.floatToIntBits(max); - h ^= (h << 13) | (h >>> 20); - h += Float.floatToIntBits(target); + h += target.hashCode(); if (defaultVal != null) h += defaultVal.hashCode(); return h; @@ -95,7 +100,7 @@ public class RangeMapFloatFunction extends ValueSource { RangeMapFloatFunction other = (RangeMapFloatFunction)o; return this.min == other.min && this.max == other.max - && this.target == other.target + && this.target.equals(other.target) && this.source.equals(other.source) && (this.defaultVal == other.defaultVal || (this.defaultVal != null && this.defaultVal.equals(other.defaultVal))); } diff --git a/lucene/queries/src/test/org/apache/lucene/queries/function/TestValueSources.java b/lucene/queries/src/test/org/apache/lucene/queries/function/TestValueSources.java index e781b22b419..50f85a84bf2 100644 --- a/lucene/queries/src/test/org/apache/lucene/queries/function/TestValueSources.java +++ b/lucene/queries/src/test/org/apache/lucene/queries/function/TestValueSources.java @@ -276,6 +276,10 @@ public class TestValueSources extends LuceneTestCase { assertHits(new FunctionQuery(new RangeMapFloatFunction(new FloatFieldSource("float"), 5, 6, 1, 0f)), new float[] { 1f, 0f }); + assertHits(new FunctionQuery(new RangeMapFloatFunction(new FloatFieldSource("float"), + 5, 6, new SumFloatFunction(new ValueSource[] {new ConstValueSource(1f), new ConstValueSource(2f)}), + new ConstValueSource(11f))), + new float[] { 3f, 11f }); } public void testReciprocal() throws Exception { @@ -338,8 +342,8 @@ public class TestValueSources extends LuceneTestCase { expectedDocs[i] = i; expected[i] = new ScoreDoc(i, scores[i]); } - TopDocs docs = searcher.search(q, documents.size(), - new Sort(new SortField("id", SortField.Type.STRING))); + TopDocs docs = searcher.search(q, null, documents.size(), + new Sort(new SortField("id", SortField.Type.STRING)), true, false); CheckHits.checkHits(random(), q, "", searcher, expectedDocs); CheckHits.checkHitsQuery(q, expected, docs.scoreDocs, expectedDocs); CheckHits.checkExplanations(q, "", searcher); diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 29b43f45b8a..9189b01c1d7 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -112,6 +112,9 @@ New Features * SOLR-5023: Add support for deleteInstanceDir to be passed from SolrJ for Core Unload action. (Lyubov Romanchuk, shalin) +* SOLR-1871: The 'map' function query accepts a ValueSource as target and + default value. (Chris Harris, shalin) + Bug Fixes ---------------------- diff --git a/solr/core/src/java/org/apache/solr/search/ValueSourceParser.java b/solr/core/src/java/org/apache/solr/search/ValueSourceParser.java index e426b8b8fac..4c6cb941a3b 100644 --- a/solr/core/src/java/org/apache/solr/search/ValueSourceParser.java +++ b/solr/core/src/java/org/apache/solr/search/ValueSourceParser.java @@ -198,8 +198,8 @@ public abstract class ValueSourceParser implements NamedListInitializedPlugin { ValueSource source = fp.parseValueSource(); float min = fp.parseFloat(); float max = fp.parseFloat(); - float target = fp.parseFloat(); - Float def = fp.hasMoreArguments() ? fp.parseFloat() : null; + ValueSource target = fp.parseValueSource(); + ValueSource def = fp.hasMoreArguments() ? fp.parseValueSource() : null; return new RangeMapFloatFunction(source, min, max, target, def); } }); diff --git a/solr/core/src/test/org/apache/solr/search/function/TestFunctionQuery.java b/solr/core/src/test/org/apache/solr/search/function/TestFunctionQuery.java index 7068b1620c9..1ed6dbcf4f3 100644 --- a/solr/core/src/test/org/apache/solr/search/function/TestFunctionQuery.java +++ b/solr/core/src/test/org/apache/solr/search/function/TestFunctionQuery.java @@ -172,6 +172,9 @@ public class TestFunctionQuery extends SolrTestCaseJ4 { singleTest(field,"map(\0,0,0,500)",10,10, -4,-4, 0,500); singleTest(field,"map(\0,-4,5,500)",100,100, -4,500, 0,500, 5,500, 10,10, 25,25); + singleTest(field,"map(\0,0,0,sum(\0,500))",10,10, -4,-4, 0,500); + singleTest(field,"map(\0,0,0,sum(\0,500),sum(\0,1))",10,11, -4,-3, 0,500); + singleTest(field,"map(\0,-4,5,sum(\0,1))",100,100, -4,-3, 0,1, 5,6, 10,10, 25,25); singleTest(field,"scale(\0,-1,1)",-4,-1, 100,1, 0,-0.9230769f); singleTest(field,"scale(\0,-10,1000)",-4,-10, 100,1000, 0,28.846153f); From 7ab2e1f787c252a8e931e40cce2a8d4b5edd7910 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Mon, 2 Dec 2013 18:42:23 +0000 Subject: [PATCH 156/223] SOLR-1301: Add a Solr contrib that allows for building Solr indexes via Hadoop's MapReduce. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1547139 13f79535-47bb-0310-9956-ffa450edef68 --- dev-tools/idea/.idea/ant.xml | 3 + .../Solr_morphlines_cell_library.xml | 10 + .../Solr_morphlines_core_library.xml | 10 + .../Solr_morphlines_core_test_library.xml | 10 + dev-tools/idea/.idea/modules.xml | 3 + dev-tools/idea/.idea/workspace.xml | 34 +- .../solr-morphlines-cell.iml | 28 + .../solr-morphlines-core.iml | 27 + .../idea/solr/contrib/solr-mr/solr-mr.iml | 40 + dev-tools/maven/solr/contrib/pom.xml.template | 3 + .../solr-morphlines-cell/pom.xml.template | 104 + .../solr-morphlines-core/pom.xml.template | 108 + .../solr/contrib/solr-mr/pom.xml.template | 97 + dev-tools/maven/solr/pom.xml.template | 5 + lucene/common-build.xml | 3 +- lucene/ivy-settings.xml | 4 + lucene/ivy-versions.properties | 78 +- lucene/tools/custom-tasks.xml | 2 +- lucene/tools/junit4/tests.policy | 1 + solr/CHANGES.txt | 9 + solr/contrib/extraction/ivy.xml | 8 + .../extraction/SolrContentHandlerFactory.java | 2 +- solr/contrib/solr-morphlines-cell/build.xml | 143 ++ solr/contrib/solr-morphlines-cell/ivy.xml | 36 + .../solr/morphlines/cell/SolrCellBuilder.java | 344 ++++ ...StripNonCharSolrContentHandlerFactory.java | 81 + .../cell/TrimSolrContentHandlerFactory.java | 58 + .../apache/solr/morphlines/cell/package.html | 22 + .../src/java/overview.html | 21 + .../solr/collection1/conf/currency.xml | 67 + .../solr/collection1/conf/elevate.xml | 38 + .../collection1/conf/lang/contractions_ca.txt | 8 + .../collection1/conf/lang/contractions_fr.txt | 9 + .../collection1/conf/lang/contractions_ga.txt | 5 + .../collection1/conf/lang/contractions_it.txt | 23 + .../collection1/conf/lang/hyphenations_ga.txt | 5 + .../collection1/conf/lang/stemdict_nl.txt | 6 + .../collection1/conf/lang/stoptags_ja.txt | 420 ++++ .../collection1/conf/lang/stopwords_ar.txt | 125 ++ .../collection1/conf/lang/stopwords_bg.txt | 193 ++ .../collection1/conf/lang/stopwords_ca.txt | 220 ++ .../collection1/conf/lang/stopwords_cz.txt | 172 ++ .../collection1/conf/lang/stopwords_da.txt | 108 + .../collection1/conf/lang/stopwords_de.txt | 292 +++ .../collection1/conf/lang/stopwords_el.txt | 78 + .../collection1/conf/lang/stopwords_en.txt | 54 + .../collection1/conf/lang/stopwords_es.txt | 354 ++++ .../collection1/conf/lang/stopwords_eu.txt | 99 + .../collection1/conf/lang/stopwords_fa.txt | 313 +++ .../collection1/conf/lang/stopwords_fi.txt | 95 + .../collection1/conf/lang/stopwords_fr.txt | 183 ++ .../collection1/conf/lang/stopwords_ga.txt | 110 + .../collection1/conf/lang/stopwords_gl.txt | 161 ++ .../collection1/conf/lang/stopwords_hi.txt | 235 +++ .../collection1/conf/lang/stopwords_hu.txt | 209 ++ .../collection1/conf/lang/stopwords_hy.txt | 46 + .../collection1/conf/lang/stopwords_id.txt | 359 ++++ .../collection1/conf/lang/stopwords_it.txt | 301 +++ .../collection1/conf/lang/stopwords_ja.txt | 127 ++ .../collection1/conf/lang/stopwords_lv.txt | 172 ++ .../collection1/conf/lang/stopwords_nl.txt | 117 ++ .../collection1/conf/lang/stopwords_no.txt | 192 ++ .../collection1/conf/lang/stopwords_pt.txt | 251 +++ .../collection1/conf/lang/stopwords_ro.txt | 233 +++ .../collection1/conf/lang/stopwords_ru.txt | 241 +++ .../collection1/conf/lang/stopwords_sv.txt | 131 ++ .../collection1/conf/lang/stopwords_th.txt | 119 ++ .../collection1/conf/lang/stopwords_tr.txt | 212 ++ .../collection1/conf/lang/userdict_ja.txt | 29 + .../solr/collection1/conf/protwords.txt | 21 + .../solr/collection1/conf/schema.xml | 947 +++++++++ .../solr/collection1/conf/solrconfig.xml | 1764 ++++++++++++++++ .../solr/collection1/conf/stopwords.txt | 14 + .../solr/collection1/conf/synonyms.txt | 29 + .../test-files/solr/minimr/conf/currency.xml | 67 + .../test-files/solr/minimr/conf/elevate.xml | 38 + .../solr/minimr/conf/lang/contractions_ca.txt | 8 + .../solr/minimr/conf/lang/contractions_fr.txt | 9 + .../solr/minimr/conf/lang/contractions_ga.txt | 5 + .../solr/minimr/conf/lang/contractions_it.txt | 23 + .../solr/minimr/conf/lang/hyphenations_ga.txt | 5 + .../solr/minimr/conf/lang/stemdict_nl.txt | 6 + .../solr/minimr/conf/lang/stoptags_ja.txt | 420 ++++ .../solr/minimr/conf/lang/stopwords_ar.txt | 125 ++ .../solr/minimr/conf/lang/stopwords_bg.txt | 193 ++ .../solr/minimr/conf/lang/stopwords_ca.txt | 220 ++ .../solr/minimr/conf/lang/stopwords_cz.txt | 172 ++ .../solr/minimr/conf/lang/stopwords_da.txt | 108 + .../solr/minimr/conf/lang/stopwords_de.txt | 292 +++ .../solr/minimr/conf/lang/stopwords_el.txt | 78 + .../solr/minimr/conf/lang/stopwords_en.txt | 54 + .../solr/minimr/conf/lang/stopwords_es.txt | 354 ++++ .../solr/minimr/conf/lang/stopwords_eu.txt | 99 + .../solr/minimr/conf/lang/stopwords_fa.txt | 313 +++ .../solr/minimr/conf/lang/stopwords_fi.txt | 95 + .../solr/minimr/conf/lang/stopwords_fr.txt | 183 ++ .../solr/minimr/conf/lang/stopwords_ga.txt | 110 + .../solr/minimr/conf/lang/stopwords_gl.txt | 161 ++ .../solr/minimr/conf/lang/stopwords_hi.txt | 235 +++ .../solr/minimr/conf/lang/stopwords_hu.txt | 209 ++ .../solr/minimr/conf/lang/stopwords_hy.txt | 46 + .../solr/minimr/conf/lang/stopwords_id.txt | 359 ++++ .../solr/minimr/conf/lang/stopwords_it.txt | 301 +++ .../solr/minimr/conf/lang/stopwords_ja.txt | 127 ++ .../solr/minimr/conf/lang/stopwords_lv.txt | 172 ++ .../solr/minimr/conf/lang/stopwords_nl.txt | 117 ++ .../solr/minimr/conf/lang/stopwords_no.txt | 192 ++ .../solr/minimr/conf/lang/stopwords_pt.txt | 251 +++ .../solr/minimr/conf/lang/stopwords_ro.txt | 233 +++ .../solr/minimr/conf/lang/stopwords_ru.txt | 241 +++ .../solr/minimr/conf/lang/stopwords_sv.txt | 131 ++ .../solr/minimr/conf/lang/stopwords_th.txt | 119 ++ .../solr/minimr/conf/lang/stopwords_tr.txt | 212 ++ .../solr/minimr/conf/lang/userdict_ja.txt | 29 + .../test-files/solr/minimr/conf/protwords.txt | 21 + .../test-files/solr/minimr/conf/schema.xml | 961 +++++++++ .../solr/minimr/conf/solrconfig.xml | 1784 ++++++++++++++++ .../test-files/solr/minimr/conf/stopwords.txt | 14 + .../test-files/solr/minimr/conf/synonyms.txt | 29 + .../src/test-files/solr/minimr/solr.xml | 43 + .../test-files/solr/mrunit/conf/currency.xml | 67 + .../test-files/solr/mrunit/conf/elevate.xml | 38 + .../solr/mrunit/conf/lang/contractions_ca.txt | 8 + .../solr/mrunit/conf/lang/contractions_fr.txt | 9 + .../solr/mrunit/conf/lang/contractions_ga.txt | 5 + .../solr/mrunit/conf/lang/contractions_it.txt | 23 + .../solr/mrunit/conf/lang/hyphenations_ga.txt | 5 + .../solr/mrunit/conf/lang/stemdict_nl.txt | 6 + .../solr/mrunit/conf/lang/stoptags_ja.txt | 420 ++++ .../solr/mrunit/conf/lang/stopwords_ar.txt | 125 ++ .../solr/mrunit/conf/lang/stopwords_bg.txt | 193 ++ .../solr/mrunit/conf/lang/stopwords_ca.txt | 220 ++ .../solr/mrunit/conf/lang/stopwords_cz.txt | 172 ++ .../solr/mrunit/conf/lang/stopwords_da.txt | 108 + .../solr/mrunit/conf/lang/stopwords_de.txt | 292 +++ .../solr/mrunit/conf/lang/stopwords_el.txt | 78 + .../solr/mrunit/conf/lang/stopwords_en.txt | 54 + .../solr/mrunit/conf/lang/stopwords_es.txt | 354 ++++ .../solr/mrunit/conf/lang/stopwords_eu.txt | 99 + .../solr/mrunit/conf/lang/stopwords_fa.txt | 313 +++ .../solr/mrunit/conf/lang/stopwords_fi.txt | 95 + .../solr/mrunit/conf/lang/stopwords_fr.txt | 183 ++ .../solr/mrunit/conf/lang/stopwords_ga.txt | 110 + .../solr/mrunit/conf/lang/stopwords_gl.txt | 161 ++ .../solr/mrunit/conf/lang/stopwords_hi.txt | 235 +++ .../solr/mrunit/conf/lang/stopwords_hu.txt | 209 ++ .../solr/mrunit/conf/lang/stopwords_hy.txt | 46 + .../solr/mrunit/conf/lang/stopwords_id.txt | 359 ++++ .../solr/mrunit/conf/lang/stopwords_it.txt | 301 +++ .../solr/mrunit/conf/lang/stopwords_ja.txt | 127 ++ .../solr/mrunit/conf/lang/stopwords_lv.txt | 172 ++ .../solr/mrunit/conf/lang/stopwords_nl.txt | 117 ++ .../solr/mrunit/conf/lang/stopwords_no.txt | 192 ++ .../solr/mrunit/conf/lang/stopwords_pt.txt | 251 +++ .../solr/mrunit/conf/lang/stopwords_ro.txt | 233 +++ .../solr/mrunit/conf/lang/stopwords_ru.txt | 241 +++ .../solr/mrunit/conf/lang/stopwords_sv.txt | 131 ++ .../solr/mrunit/conf/lang/stopwords_th.txt | 119 ++ .../solr/mrunit/conf/lang/stopwords_tr.txt | 212 ++ .../solr/mrunit/conf/lang/userdict_ja.txt | 29 + .../test-files/solr/mrunit/conf/protwords.txt | 21 + .../test-files/solr/mrunit/conf/schema.xml | 961 +++++++++ .../solr/mrunit/conf/solrconfig.xml | 1789 +++++++++++++++++ .../test-files/solr/mrunit/conf/stopwords.txt | 14 + .../test-files/solr/mrunit/conf/synonyms.txt | 29 + .../src/test-files/solr/mrunit/solr.xml | 43 + .../src/test-files/solr/solr.xml | 43 + .../collection1/conf/currency.xml | 67 + .../solrcelltest/collection1/conf/elevate.xml | 38 + .../collection1/conf/lang/contractions_ca.txt | 8 + .../collection1/conf/lang/contractions_fr.txt | 9 + .../collection1/conf/lang/contractions_ga.txt | 5 + .../collection1/conf/lang/contractions_it.txt | 23 + .../collection1/conf/lang/hyphenations_ga.txt | 5 + .../collection1/conf/lang/stemdict_nl.txt | 6 + .../collection1/conf/lang/stoptags_ja.txt | 420 ++++ .../collection1/conf/lang/stopwords_ar.txt | 125 ++ .../collection1/conf/lang/stopwords_bg.txt | 193 ++ .../collection1/conf/lang/stopwords_ca.txt | 220 ++ .../collection1/conf/lang/stopwords_cz.txt | 172 ++ .../collection1/conf/lang/stopwords_da.txt | 108 + .../collection1/conf/lang/stopwords_de.txt | 292 +++ .../collection1/conf/lang/stopwords_el.txt | 78 + .../collection1/conf/lang/stopwords_en.txt | 54 + .../collection1/conf/lang/stopwords_es.txt | 354 ++++ .../collection1/conf/lang/stopwords_eu.txt | 99 + .../collection1/conf/lang/stopwords_fa.txt | 313 +++ .../collection1/conf/lang/stopwords_fi.txt | 95 + .../collection1/conf/lang/stopwords_fr.txt | 183 ++ .../collection1/conf/lang/stopwords_ga.txt | 110 + .../collection1/conf/lang/stopwords_gl.txt | 161 ++ .../collection1/conf/lang/stopwords_hi.txt | 235 +++ .../collection1/conf/lang/stopwords_hu.txt | 209 ++ .../collection1/conf/lang/stopwords_hy.txt | 46 + .../collection1/conf/lang/stopwords_id.txt | 359 ++++ .../collection1/conf/lang/stopwords_it.txt | 301 +++ .../collection1/conf/lang/stopwords_ja.txt | 127 ++ .../collection1/conf/lang/stopwords_lv.txt | 172 ++ .../collection1/conf/lang/stopwords_nl.txt | 117 ++ .../collection1/conf/lang/stopwords_no.txt | 192 ++ .../collection1/conf/lang/stopwords_pt.txt | 251 +++ .../collection1/conf/lang/stopwords_ro.txt | 233 +++ .../collection1/conf/lang/stopwords_ru.txt | 241 +++ .../collection1/conf/lang/stopwords_sv.txt | 131 ++ .../collection1/conf/lang/stopwords_th.txt | 119 ++ .../collection1/conf/lang/stopwords_tr.txt | 212 ++ .../collection1/conf/lang/userdict_ja.txt | 29 + .../collection1/conf/protwords.txt | 21 + .../solrcelltest/collection1/conf/schema.xml | 914 +++++++++ .../collection1/conf/solrconfig.xml | 1764 ++++++++++++++++ .../collection1/conf/stopwords.txt | 14 + .../collection1/conf/synonyms.txt | 29 + .../solr/solrcloud/conf/solrconfig.xml | 1787 ++++++++++++++++ .../cell/SolrCellMorphlineTest.java | 208 ++ solr/contrib/solr-morphlines-core/build.xml | 107 + solr/contrib/solr-morphlines-core/ivy.xml | 122 ++ .../solr/morphlines/solr/DocumentLoader.java | 73 + .../solr/GenerateSolrSequenceKeyBuilder.java | 143 ++ .../solr/morphlines/solr/LoadSolrBuilder.java | 162 ++ .../solr/SafeConcurrentUpdateSolrServer.java | 68 + .../SanitizeUnknownSolrFieldsBuilder.java | 98 + .../solr/morphlines/solr/SolrLocator.java | 270 +++ .../morphlines/solr/SolrMorphlineContext.java | 80 + .../solr/SolrServerDocumentLoader.java | 123 ++ .../morphlines/solr/TokenizeTextBuilder.java | 177 ++ .../morphlines/solr/ZooKeeperDownloader.java | 122 ++ .../apache/solr/morphlines/solr/package.html | 22 + .../src/java/overview.html | 21 + .../src/test-files/README | 21 + .../src/test-files/books_numeric_ids.csv | 11 + .../src/test-files/exampledocs/example.html | 49 + .../src/test-files/exampledocs/example.txt | 3 + .../src/test-files/lib-dirs/README | 18 + .../lib-dirs/a/a1/empty-file-a1.txt | 1 + .../lib-dirs/a/a2/empty-file-a2.txt | 1 + .../lib-dirs/b/b1/empty-file-b1.txt | 1 + .../lib-dirs/b/b2/empty-file-b2.txt | 1 + .../lib-dirs/c/c1/empty-file-c1.txt | 1 + .../lib-dirs/c/c2/empty-file-c2.txt | 1 + .../lib-dirs/d/d1/empty-file-d1.txt | 1 + .../lib-dirs/d/d2/empty-file-d2.txt | 1 + .../src/test-files/log4j.properties | 12 + .../src/test-files/mailing_lists.pdf | 382 ++++ .../test-files/old-solr-example/README.txt | 1 + .../src/test-files/old-solr-example/solr.xml | 53 + .../conf/addfields.updateprocessor.js | 26 + .../conf/analyzingInfixSuggest.txt | 5 + .../solr/collection1/conf/bad-currency.xml | 31 + .../collection1/conf/bad-mp-solrconfig.xml | 34 + .../bad-schema-analyzer-class-and-nested.xml | 40 + .../bad-schema-bogus-analysis-parameters.xml | 32 + .../bad-schema-bogus-field-parameters.xml | 29 + ...bad-schema-codec-global-vs-ft-mismatch.xml | 36 + ...ad-schema-currency-dynamic-multivalued.xml | 36 + ...d-schema-currency-ft-bogus-code-in-xml.xml | 38 + ...-schema-currency-ft-bogus-default-code.xml | 38 + .../bad-schema-currency-ft-multivalued.xml | 34 + .../bad-schema-currency-ft-oer-norates.xml | 37 + .../conf/bad-schema-currency-multivalued.xml | 35 + .../conf/bad-schema-dup-dynamicField.xml | 43 + .../collection1/conf/bad-schema-dup-field.xml | 43 + .../conf/bad-schema-dup-fieldType.xml | 44 + .../bad-schema-dynamicfield-default-val.xml | 34 + .../conf/bad-schema-dynamicfield-required.xml | 34 + .../conf/bad-schema-external-filefield.xml | 27 + ...terisk-copyfield-dest-should-fail-test.xml | 31 + ...risk-copyfield-source-should-fail-test.xml | 31 + ...terisk-copyfield-dest-should-fail-test.xml | 29 + ...risk-copyfield-source-should-fail-test.xml | 29 + ...urce-matching-nothing-should-fail-test.xml | 36 + .../conf/bad-schema-nontext-analyzer.xml | 39 + .../conf/bad-schema-not-indexed-but-norms.xml | 40 + .../conf/bad-schema-not-indexed-but-pos.xml | 40 + .../conf/bad-schema-not-indexed-but-tf.xml | 40 + .../conf/bad-schema-omit-tf-but-not-pos.xml | 41 + .../bad-schema-sim-global-vs-ft-mismatch.xml | 37 + .../conf/bad-schema-sweetspot-both-tf.xml | 48 + .../bad-schema-sweetspot-partial-baseline.xml | 44 + ...ad-schema-sweetspot-partial-hyperbolic.xml | 46 + .../bad-schema-sweetspot-partial-norms.xml | 45 + ...bad-schema-uniquekey-is-copyfield-dest.xml | 36 + .../conf/bad-schema-uniquekey-multivalued.xml | 33 + .../bad-schema-uniquekey-uses-default.xml | 33 + .../conf/bad-schema-unsupported-docValues.xml | 30 + ...bad-solrconfig-bogus-scriptengine-name.xml | 32 + .../bad-solrconfig-invalid-scriptfile.xml | 33 + ...config-managed-schema-named-schema.xml.xml | 30 + .../bad-solrconfig-missing-scriptfile.xml | 31 + .../conf/bad-solrconfig-multiple-cfs.xml | 30 + .../bad-solrconfig-multiple-dirfactory.xml | 34 + .../bad-solrconfig-multiple-indexconfigs.xml | 35 + ...rconfig-schema-mutable-but-not-managed.xml | 32 + ...solrconfig-unexpected-schema-attribute.xml | 32 + .../conf/bad-solrconfig-warmer-no-reopen.xml | 27 + .../solr/collection1/conf/bad_solrconfig.xml | 27 + .../collection1/conf/compoundDictionary.txt | 19 + .../conf/conditional.updateprocessor.js | 25 + .../solr/collection1/conf/currency.xml | 37 + .../solr/collection1/conf/da_UTF8.xml | 1208 +++++++++++ .../conf/da_compoundDictionary.txt | 19 + .../solr/collection1/conf/elevate.xml | 54 + .../solr/collection1/conf/frenchArticles.txt | 24 + .../solr/collection1/conf/fuzzysuggest.txt | 4 + .../solr/collection1/conf/hunspell-test.aff | 13 + .../solr/collection1/conf/hunspell-test.dic | 6 + .../solr/collection1/conf/hyphenation.dtd | 68 + .../solr/collection1/conf/jasuggest.txt | 5 + .../solr/collection1/conf/keep-1.txt | 17 + .../solr/collection1/conf/keep-2.txt | 17 + .../conf/mapping-ISOLatin1Accent.txt | 246 +++ .../conf/missing.functions.updateprocessor.js | 3 + ...ssleading.extension.updateprocessor.js.txt | 23 + .../solr/collection1/conf/old_synonyms.txt | 22 + .../collection1/conf/open-exchange-rates.json | 18 + .../solr/collection1/conf/phrasesuggest.txt | 8 + .../solr/collection1/conf/protwords.txt | 23 + .../conf/regex-boost-processor-test.txt | 10 + ...ema-add-schema-fields-update-processor.xml | 49 + .../solr/collection1/conf/schema-behavior.xml | 121 ++ .../collection1/conf/schema-binaryfield.xml | 97 + .../solr/collection1/conf/schema-bm25.xml | 52 + .../collection1/conf/schema-charfilters.xml | 52 + ...class-name-shortening-on-serialization.xml | 43 + .../solr/collection1/conf/schema-collate.xml | 62 + .../conf/schema-copyfield-test.xml | 482 +++++ .../solr/collection1/conf/schema-dfr.xml | 70 + .../collection1/conf/schema-docValues.xml | 74 + .../conf/schema-docValuesFaceting.xml | 50 + .../conf/schema-docValuesMissing.xml | 88 + .../conf/schema-docValuesMulti.xml | 54 + .../solr/collection1/conf/schema-eff.xml | 45 + .../solr/collection1/conf/schema-folding.xml | 266 +++ .../solr/collection1/conf/schema-ib.xml | 58 + .../schema-id-and-version-fields-only.xml | 29 + .../collection1/conf/schema-lmdirichlet.xml | 51 + .../conf/schema-lmjelinekmercer.xml | 51 + .../conf/schema-luceneMatchVersion.xml | 58 + .../solr/collection1/conf/schema-minimal.xml | 25 + .../conf/schema-not-required-unique-key.xml | 46 + .../solr/collection1/conf/schema-numeric.xml | 75 + ...-one-field-no-dynamic-field-unique-key.xml | 29 + .../schema-one-field-no-dynamic-field.xml | 28 + .../collection1/conf/schema-phrasesuggest.xml | 60 + .../conf/schema-postingshighlight.xml | 51 + .../collection1/conf/schema-replication1.xml | 46 + .../collection1/conf/schema-replication2.xml | 49 + .../conf/schema-required-fields.xml | 436 ++++ .../conf/schema-rest-lucene-match-version.xml | 40 + .../solr/collection1/conf/schema-rest.xml | 624 ++++++ .../solr/collection1/conf/schema-reversed.xml | 88 + .../solr/collection1/conf/schema-sim.xml | 68 + .../collection1/conf/schema-snippet-field.xml | 3 + .../collection1/conf/schema-snippet-type.xml | 3 + .../conf/schema-snippet-types.incl | 19 + .../solr/collection1/conf/schema-spatial.xml | 63 + .../collection1/conf/schema-spellchecker.xml | 87 + .../collection1/conf/schema-stop-keep.xml | 64 + .../collection1/conf/schema-sweetspot.xml | 76 + .../conf/schema-synonym-tokenizer.xml | 43 + .../solr/collection1/conf/schema-tfidf.xml | 50 + .../solr/collection1/conf/schema-tiny.xml | 38 + .../solr/collection1/conf/schema-trie.xml | 332 +++ .../solr/collection1/conf/schema-xinclude.xml | 30 + .../solr/collection1/conf/schema.xml | 712 +++++++ .../solr/collection1/conf/schema11.xml | 387 ++++ .../solr/collection1/conf/schema12.xml | 618 ++++++ .../solr/collection1/conf/schema15.xml | 604 ++++++ .../solr/collection1/conf/schema_codec.xml | 49 + .../solr/collection1/conf/schemasurround.xml | 608 ++++++ .../collection1/conf/solrconfig-SOLR-749.xml | 29 + ...-schema-fields-update-processor-chains.xml | 155 ++ .../conf/solrconfig-altdirectory.xml | 26 + .../collection1/conf/solrconfig-basic.xml | 29 + .../collection1/conf/solrconfig-caching.xml | 39 + .../conf/solrconfig-components-name.xml | 75 + .../collection1/conf/solrconfig-defaults.xml | 43 + .../conf/solrconfig-delpolicy1.xml | 51 + .../conf/solrconfig-delpolicy2.xml | 48 + .../collection1/conf/solrconfig-elevate.xml | 178 ++ .../conf/solrconfig-functionquery.xml | 43 + .../collection1/conf/solrconfig-highlight.xml | 60 + .../conf/solrconfig-implicitproperties.xml | 79 + .../conf/solrconfig-indexconfig.xml | 30 + .../conf/solrconfig-infostream-logging.xml | 27 + .../conf/solrconfig-lazywriter.xml | 28 + .../conf/solrconfig-logmergepolicy.xml | 37 + .../conf/solrconfig-managed-schema.xml | 51 + .../collection1/conf/solrconfig-master.xml | 72 + .../conf/solrconfig-master1-keepOneBackup.xml | 49 + .../collection1/conf/solrconfig-master1.xml | 69 + .../collection1/conf/solrconfig-master2.xml | 69 + .../collection1/conf/solrconfig-master3.xml | 70 + .../conf/solrconfig-mergepolicy-defaults.xml | 32 + .../conf/solrconfig-mergepolicy-legacy.xml | 31 + .../collection1/conf/solrconfig-minimal.xml | 75 + .../collection1/conf/solrconfig-nocache.xml | 41 + .../collection1/conf/solrconfig-noopregen.xml | 36 + ...config-parsing-update-processor-chains.xml | 230 +++ .../conf/solrconfig-phrasesuggest.xml | 272 +++ .../conf/solrconfig-postingshighlight.xml | 34 + .../conf/solrconfig-querysender-noquery.xml | 74 + .../conf/solrconfig-querysender.xml | 70 + .../collection1/conf/solrconfig-repeater.xml | 63 + .../conf/solrconfig-reqHandler.incl | 5 + .../solrconfig-response-log-component.xml | 54 + .../solrconfig-script-updateprocessor.xml | 112 ++ .../collection1/conf/solrconfig-slave.xml | 61 + .../collection1/conf/solrconfig-slave1.xml | 57 + .../conf/solrconfig-snippet-processor.xml | 6 + .../conf/solrconfig-solcoreproperties.xml | 35 + .../conf/solrconfig-spellcheckcomponent.xml | 178 ++ .../conf/solrconfig-spellchecker.xml | 142 ++ .../collection1/conf/solrconfig-test-misc.xml | 52 + .../conf/solrconfig-tieredmergepolicy.xml | 47 + .../solr/collection1/conf/solrconfig-tlog.xml | 120 ++ .../conf/solrconfig-transformers.xml | 84 + .../solrconfig-update-processor-chains.xml | 464 +++++ .../collection1/conf/solrconfig-warmer.xml | 46 + .../collection1/conf/solrconfig-xinclude.xml | 35 + .../solrconfig.snippet.randomindexconfig.xml | 48 + .../solr/collection1/conf/solrconfig.xml | 562 ++++++ .../collection1/conf/solrconfig_codec.xml | 25 + .../solr/collection1/conf/solrconfig_perf.xml | 76 + .../solr/collection1/conf/stemdict.txt | 22 + .../solr/collection1/conf/stop-1.txt | 17 + .../solr/collection1/conf/stop-2.txt | 17 + .../solr/collection1/conf/stop-snowball.txt | 10 + .../solr/collection1/conf/stoptypes-1.txt | 17 + .../solr/collection1/conf/stoptypes-2.txt | 17 + .../solr/collection1/conf/stopwithbom.txt | 1 + .../solr/collection1/conf/stopwords.txt | 58 + .../conf/stopwordsWrongEncoding.txt | 18 + .../solr/collection1/conf/synonyms.txt | 31 + .../throw.error.on.add.updateprocessor.js | 21 + .../conf/trivial.updateprocessor0.js | 59 + .../conf/trivial.updateprocessor1.js | 25 + .../solr/collection1/conf/wdftypes.txt | 32 + .../conf/xslt/dummy-using-include.xsl | 31 + .../solr/collection1/conf/xslt/dummy.xsl | 39 + .../conf/xslt/xsl-update-handler-test.xsl | 49 + .../test-files/solr/collection1/lib/README | 18 + .../lib/classes/empty-file-main-lib.txt | 1 + .../src/test-files/solr/conf/core.properties | 19 + .../test-files/solr/crazy-path-to-config.xml | 59 + .../test-files/solr/crazy-path-to-schema.xml | 46 + .../src/test-files/solr/external_eff | 10 + .../src/test-files/solr/solr-50-all.xml | 52 + .../src/test-files/solr/solr-multicore.xml | 70 + .../src/test-files/solr/solr-no-core.xml | 39 + .../test-files/solr/solr-shardhandler-old.xml | 29 + .../src/test-files/solr/solr-shardhandler.xml | 29 + .../src/test-files/solr/solr-stress-new.xml | 34 + .../src/test-files/solr/solr-stress-old.xml | 59 + .../src/test-files/solr/solr.xml | 43 + .../src/test-files/spellings.txt | 16 + .../solr/AbstractSolrMorphlineTestBase.java | 268 +++ .../solr/AbstractSolrMorphlineZkTestBase.java | 249 +++ .../solr/CollectingDocumentLoader.java | 94 + .../solr/EmbeddedTestSolrServer.java | 46 + .../morphlines/solr/SolrMorphlineTest.java | 66 + .../solr/SolrMorphlineZkAliasTest.java | 127 ++ .../solr/SolrMorphlineZkAvroTest.java | 164 ++ .../morphlines/solr/SolrMorphlineZkTest.java | 98 + solr/contrib/solr-mr/build.xml | 147 ++ solr/contrib/solr-mr/ivy.xml | 37 + .../solr-mr/src/java/assembly/hadoop-job.xml | 39 + .../org/apache/solr/hadoop/BatchWriter.java | 241 +++ .../solr/hadoop/DataInputInputStream.java | 59 + .../solr/hadoop/DataOutputOutputStream.java | 66 + .../solr/hadoop/DryRunDocumentLoader.java | 57 + .../java/org/apache/solr/hadoop/GoLive.java | 212 ++ .../solr/hadoop/HdfsFileFieldNames.java | 41 + .../org/apache/solr/hadoop/HeartBeater.java | 158 ++ .../solr/hadoop/LineRandomizerMapper.java | 66 + .../solr/hadoop/LineRandomizerReducer.java | 47 + .../solr/hadoop/MapReduceIndexerTool.java | 1300 ++++++++++++ .../apache/solr/hadoop/PathArgumentType.java | 233 +++ .../org/apache/solr/hadoop/PathParts.java | 130 ++ .../solr/hadoop/SolrCloudPartitioner.java | 142 ++ .../org/apache/solr/hadoop/SolrCounters.java | 53 + .../hadoop/SolrInputDocumentWritable.java | 66 + .../org/apache/solr/hadoop/SolrMapper.java | 39 + .../apache/solr/hadoop/SolrOutputFormat.java | 278 +++ .../apache/solr/hadoop/SolrRecordWriter.java | 516 +++++ .../org/apache/solr/hadoop/SolrReducer.java | 167 ++ .../solr/hadoop/ToolRunnerHelpFormatter.java | 89 + .../apache/solr/hadoop/TreeMergeMapper.java | 43 + .../solr/hadoop/TreeMergeOutputFormat.java | 167 ++ .../UnbufferedDataInputInputStream.java | 114 ++ .../java/org/apache/solr/hadoop/Utils.java | 53 + .../solr/hadoop/ZooKeeperInspector.java | 198 ++ .../dedup/NoChangeUpdateConflictResolver.java | 36 + .../RejectingUpdateConflictResolver.java | 48 + ...etainMostRecentUpdateConflictResolver.java | 113 ++ .../dedup/SolrInputDocumentComparator.java | 84 + .../dedup/SortingUpdateConflictResolver.java | 79 + .../hadoop/dedup/UpdateConflictResolver.java | 71 + .../org/apache/solr/hadoop/dedup/package.html | 22 + .../hadoop/morphline/MorphlineCounters.java | 47 + .../hadoop/morphline/MorphlineMapRunner.java | 266 +++ .../hadoop/morphline/MorphlineMapper.java | 192 ++ .../apache/solr/hadoop/morphline/package.html | 22 + .../java/org/apache/solr/hadoop/package.html | 22 + solr/contrib/solr-mr/src/java/overview.html | 21 + .../src/test-files/custom-mimetypes.xml | 38 + .../solr/collection1/conf/currency.xml | 67 + .../solr/collection1/conf/elevate.xml | 38 + .../collection1/conf/lang/contractions_ca.txt | 8 + .../collection1/conf/lang/contractions_fr.txt | 9 + .../collection1/conf/lang/contractions_ga.txt | 5 + .../collection1/conf/lang/contractions_it.txt | 23 + .../collection1/conf/lang/hyphenations_ga.txt | 5 + .../collection1/conf/lang/stemdict_nl.txt | 6 + .../collection1/conf/lang/stoptags_ja.txt | 420 ++++ .../collection1/conf/lang/stopwords_ar.txt | 125 ++ .../collection1/conf/lang/stopwords_bg.txt | 193 ++ .../collection1/conf/lang/stopwords_ca.txt | 220 ++ .../collection1/conf/lang/stopwords_cz.txt | 172 ++ .../collection1/conf/lang/stopwords_da.txt | 108 + .../collection1/conf/lang/stopwords_de.txt | 292 +++ .../collection1/conf/lang/stopwords_el.txt | 78 + .../collection1/conf/lang/stopwords_en.txt | 54 + .../collection1/conf/lang/stopwords_es.txt | 354 ++++ .../collection1/conf/lang/stopwords_eu.txt | 99 + .../collection1/conf/lang/stopwords_fa.txt | 313 +++ .../collection1/conf/lang/stopwords_fi.txt | 95 + .../collection1/conf/lang/stopwords_fr.txt | 183 ++ .../collection1/conf/lang/stopwords_ga.txt | 110 + .../collection1/conf/lang/stopwords_gl.txt | 161 ++ .../collection1/conf/lang/stopwords_hi.txt | 235 +++ .../collection1/conf/lang/stopwords_hu.txt | 209 ++ .../collection1/conf/lang/stopwords_hy.txt | 46 + .../collection1/conf/lang/stopwords_id.txt | 359 ++++ .../collection1/conf/lang/stopwords_it.txt | 301 +++ .../collection1/conf/lang/stopwords_ja.txt | 127 ++ .../collection1/conf/lang/stopwords_lv.txt | 172 ++ .../collection1/conf/lang/stopwords_nl.txt | 117 ++ .../collection1/conf/lang/stopwords_no.txt | 192 ++ .../collection1/conf/lang/stopwords_pt.txt | 251 +++ .../collection1/conf/lang/stopwords_ro.txt | 233 +++ .../collection1/conf/lang/stopwords_ru.txt | 241 +++ .../collection1/conf/lang/stopwords_sv.txt | 131 ++ .../collection1/conf/lang/stopwords_th.txt | 119 ++ .../collection1/conf/lang/stopwords_tr.txt | 212 ++ .../collection1/conf/lang/userdict_ja.txt | 29 + .../solr/collection1/conf/protwords.txt | 21 + .../solr/collection1/conf/schema.xml | 947 +++++++++ .../solr/collection1/conf/solrconfig.xml | 1764 ++++++++++++++++ .../solr/collection1/conf/stopwords.txt | 14 + .../solr/collection1/conf/synonyms.txt | 29 + .../test-files/solr/minimr/conf/currency.xml | 67 + .../test-files/solr/minimr/conf/elevate.xml | 38 + .../solr/minimr/conf/lang/contractions_ca.txt | 8 + .../solr/minimr/conf/lang/contractions_fr.txt | 9 + .../solr/minimr/conf/lang/contractions_ga.txt | 5 + .../solr/minimr/conf/lang/contractions_it.txt | 23 + .../solr/minimr/conf/lang/hyphenations_ga.txt | 5 + .../solr/minimr/conf/lang/stemdict_nl.txt | 6 + .../solr/minimr/conf/lang/stoptags_ja.txt | 420 ++++ .../solr/minimr/conf/lang/stopwords_ar.txt | 125 ++ .../solr/minimr/conf/lang/stopwords_bg.txt | 193 ++ .../solr/minimr/conf/lang/stopwords_ca.txt | 220 ++ .../solr/minimr/conf/lang/stopwords_cz.txt | 172 ++ .../solr/minimr/conf/lang/stopwords_da.txt | 108 + .../solr/minimr/conf/lang/stopwords_de.txt | 292 +++ .../solr/minimr/conf/lang/stopwords_el.txt | 78 + .../solr/minimr/conf/lang/stopwords_en.txt | 54 + .../solr/minimr/conf/lang/stopwords_es.txt | 354 ++++ .../solr/minimr/conf/lang/stopwords_eu.txt | 99 + .../solr/minimr/conf/lang/stopwords_fa.txt | 313 +++ .../solr/minimr/conf/lang/stopwords_fi.txt | 95 + .../solr/minimr/conf/lang/stopwords_fr.txt | 183 ++ .../solr/minimr/conf/lang/stopwords_ga.txt | 110 + .../solr/minimr/conf/lang/stopwords_gl.txt | 161 ++ .../solr/minimr/conf/lang/stopwords_hi.txt | 235 +++ .../solr/minimr/conf/lang/stopwords_hu.txt | 209 ++ .../solr/minimr/conf/lang/stopwords_hy.txt | 46 + .../solr/minimr/conf/lang/stopwords_id.txt | 359 ++++ .../solr/minimr/conf/lang/stopwords_it.txt | 301 +++ .../solr/minimr/conf/lang/stopwords_ja.txt | 127 ++ .../solr/minimr/conf/lang/stopwords_lv.txt | 172 ++ .../solr/minimr/conf/lang/stopwords_nl.txt | 117 ++ .../solr/minimr/conf/lang/stopwords_no.txt | 192 ++ .../solr/minimr/conf/lang/stopwords_pt.txt | 251 +++ .../solr/minimr/conf/lang/stopwords_ro.txt | 233 +++ .../solr/minimr/conf/lang/stopwords_ru.txt | 241 +++ .../solr/minimr/conf/lang/stopwords_sv.txt | 131 ++ .../solr/minimr/conf/lang/stopwords_th.txt | 119 ++ .../solr/minimr/conf/lang/stopwords_tr.txt | 212 ++ .../solr/minimr/conf/lang/userdict_ja.txt | 29 + .../test-files/solr/minimr/conf/protwords.txt | 21 + .../test-files/solr/minimr/conf/schema.xml | 961 +++++++++ .../solr/minimr/conf/solrconfig.xml | 1784 ++++++++++++++++ .../test-files/solr/minimr/conf/stopwords.txt | 14 + .../test-files/solr/minimr/conf/synonyms.txt | 29 + .../src/test-files/solr/minimr/solr.xml | 43 + .../test-files/solr/mrunit/conf/currency.xml | 67 + .../test-files/solr/mrunit/conf/elevate.xml | 38 + .../solr/mrunit/conf/lang/contractions_ca.txt | 8 + .../solr/mrunit/conf/lang/contractions_fr.txt | 9 + .../solr/mrunit/conf/lang/contractions_ga.txt | 5 + .../solr/mrunit/conf/lang/contractions_it.txt | 23 + .../solr/mrunit/conf/lang/hyphenations_ga.txt | 5 + .../solr/mrunit/conf/lang/stemdict_nl.txt | 6 + .../solr/mrunit/conf/lang/stoptags_ja.txt | 420 ++++ .../solr/mrunit/conf/lang/stopwords_ar.txt | 125 ++ .../solr/mrunit/conf/lang/stopwords_bg.txt | 193 ++ .../solr/mrunit/conf/lang/stopwords_ca.txt | 220 ++ .../solr/mrunit/conf/lang/stopwords_cz.txt | 172 ++ .../solr/mrunit/conf/lang/stopwords_da.txt | 108 + .../solr/mrunit/conf/lang/stopwords_de.txt | 292 +++ .../solr/mrunit/conf/lang/stopwords_el.txt | 78 + .../solr/mrunit/conf/lang/stopwords_en.txt | 54 + .../solr/mrunit/conf/lang/stopwords_es.txt | 354 ++++ .../solr/mrunit/conf/lang/stopwords_eu.txt | 99 + .../solr/mrunit/conf/lang/stopwords_fa.txt | 313 +++ .../solr/mrunit/conf/lang/stopwords_fi.txt | 95 + .../solr/mrunit/conf/lang/stopwords_fr.txt | 183 ++ .../solr/mrunit/conf/lang/stopwords_ga.txt | 110 + .../solr/mrunit/conf/lang/stopwords_gl.txt | 161 ++ .../solr/mrunit/conf/lang/stopwords_hi.txt | 235 +++ .../solr/mrunit/conf/lang/stopwords_hu.txt | 209 ++ .../solr/mrunit/conf/lang/stopwords_hy.txt | 46 + .../solr/mrunit/conf/lang/stopwords_id.txt | 359 ++++ .../solr/mrunit/conf/lang/stopwords_it.txt | 301 +++ .../solr/mrunit/conf/lang/stopwords_ja.txt | 127 ++ .../solr/mrunit/conf/lang/stopwords_lv.txt | 172 ++ .../solr/mrunit/conf/lang/stopwords_nl.txt | 117 ++ .../solr/mrunit/conf/lang/stopwords_no.txt | 192 ++ .../solr/mrunit/conf/lang/stopwords_pt.txt | 251 +++ .../solr/mrunit/conf/lang/stopwords_ro.txt | 233 +++ .../solr/mrunit/conf/lang/stopwords_ru.txt | 241 +++ .../solr/mrunit/conf/lang/stopwords_sv.txt | 131 ++ .../solr/mrunit/conf/lang/stopwords_th.txt | 119 ++ .../solr/mrunit/conf/lang/stopwords_tr.txt | 212 ++ .../solr/mrunit/conf/lang/userdict_ja.txt | 29 + .../test-files/solr/mrunit/conf/protwords.txt | 21 + .../test-files/solr/mrunit/conf/schema.xml | 961 +++++++++ .../solr/mrunit/conf/solrconfig.xml | 1789 +++++++++++++++++ .../test-files/solr/mrunit/conf/stopwords.txt | 14 + .../test-files/solr/mrunit/conf/synonyms.txt | 29 + .../src/test-files/solr/mrunit/solr.xml | 43 + .../solr-mr/src/test-files/solr/solr.xml | 43 + .../collection1/conf/currency.xml | 67 + .../solrcelltest/collection1/conf/elevate.xml | 38 + .../collection1/conf/lang/contractions_ca.txt | 8 + .../collection1/conf/lang/contractions_fr.txt | 9 + .../collection1/conf/lang/contractions_ga.txt | 5 + .../collection1/conf/lang/contractions_it.txt | 23 + .../collection1/conf/lang/hyphenations_ga.txt | 5 + .../collection1/conf/lang/stemdict_nl.txt | 6 + .../collection1/conf/lang/stoptags_ja.txt | 420 ++++ .../collection1/conf/lang/stopwords_ar.txt | 125 ++ .../collection1/conf/lang/stopwords_bg.txt | 193 ++ .../collection1/conf/lang/stopwords_ca.txt | 220 ++ .../collection1/conf/lang/stopwords_cz.txt | 172 ++ .../collection1/conf/lang/stopwords_da.txt | 108 + .../collection1/conf/lang/stopwords_de.txt | 292 +++ .../collection1/conf/lang/stopwords_el.txt | 78 + .../collection1/conf/lang/stopwords_en.txt | 54 + .../collection1/conf/lang/stopwords_es.txt | 354 ++++ .../collection1/conf/lang/stopwords_eu.txt | 99 + .../collection1/conf/lang/stopwords_fa.txt | 313 +++ .../collection1/conf/lang/stopwords_fi.txt | 95 + .../collection1/conf/lang/stopwords_fr.txt | 183 ++ .../collection1/conf/lang/stopwords_ga.txt | 110 + .../collection1/conf/lang/stopwords_gl.txt | 161 ++ .../collection1/conf/lang/stopwords_hi.txt | 235 +++ .../collection1/conf/lang/stopwords_hu.txt | 209 ++ .../collection1/conf/lang/stopwords_hy.txt | 46 + .../collection1/conf/lang/stopwords_id.txt | 359 ++++ .../collection1/conf/lang/stopwords_it.txt | 301 +++ .../collection1/conf/lang/stopwords_ja.txt | 127 ++ .../collection1/conf/lang/stopwords_lv.txt | 172 ++ .../collection1/conf/lang/stopwords_nl.txt | 117 ++ .../collection1/conf/lang/stopwords_no.txt | 192 ++ .../collection1/conf/lang/stopwords_pt.txt | 251 +++ .../collection1/conf/lang/stopwords_ro.txt | 233 +++ .../collection1/conf/lang/stopwords_ru.txt | 241 +++ .../collection1/conf/lang/stopwords_sv.txt | 131 ++ .../collection1/conf/lang/stopwords_th.txt | 119 ++ .../collection1/conf/lang/stopwords_tr.txt | 212 ++ .../collection1/conf/lang/userdict_ja.txt | 29 + .../collection1/conf/protwords.txt | 21 + .../solrcelltest/collection1/conf/schema.xml | 914 +++++++++ .../collection1/conf/solrconfig.xml | 1764 ++++++++++++++++ .../collection1/conf/stopwords.txt | 14 + .../collection1/conf/synonyms.txt | 29 + .../solr/solrcloud/conf/solrconfig.xml | 1787 ++++++++++++++++ .../test-files/test-documents/NullHeader.docx | Bin 0 -> 4355 bytes .../test-documents/boilerplate.html | 58 + .../test-files/test-documents/complex.mbox | 291 +++ .../src/test-files/test-documents/rsstest.rss | 36 + .../sample-statuses-20120521-100919.avro | Bin 0 -> 3192 bytes .../sample-statuses-20120906-141433 | 4 + ...ample-statuses-20120906-141433-medium.avro | Bin 0 -> 249540 bytes .../sample-statuses-20120906-141433.avro | Bin 0 -> 1208 bytes .../sample-statuses-20120906-141433.bz2 | Bin 0 -> 1054 bytes .../sample-statuses-20120906-141433.gz | Bin 0 -> 907 bytes .../test-documents/test-outlook.msg | Bin 0 -> 19968 bytes .../test-files/test-documents/testAIFF.aif | Bin 0 -> 3894 bytes .../src/test-files/test-documents/testBMP.bmp | Bin 0 -> 22554 bytes .../test-files/test-documents/testBMPfp.txt | 3 + .../test-files/test-documents/testEMLX.emlx | 72 + .../test-files/test-documents/testEXCEL.xls | Bin 0 -> 13824 bytes .../test-files/test-documents/testEXCEL.xlsx | Bin 0 -> 9453 bytes .../test-files/test-documents/testFLAC.flac | Bin 0 -> 10604 bytes .../src/test-files/test-documents/testFLV.flv | Bin 0 -> 90580 bytes .../test-documents/testJPEG_EXIF.jpg | Bin 0 -> 16357 bytes .../test-documents/testJPEG_EXIF.jpg.gz | Bin 0 -> 8595 bytes .../test-documents/testJPEG_EXIF.jpg.tar.gz | Bin 0 -> 8722 bytes .../test-files/test-documents/testMP3i18n.mp3 | Bin 0 -> 40832 bytes .../src/test-files/test-documents/testMP4.m4a | Bin 0 -> 4770 bytes .../src/test-files/test-documents/testPDF.pdf | Bin 0 -> 34824 bytes .../src/test-files/test-documents/testPNG.png | Bin 0 -> 17041 bytes .../test-documents/testPPT_various.ppt | Bin 0 -> 164352 bytes .../test-documents/testPPT_various.pptx | Bin 0 -> 56659 bytes .../src/test-files/test-documents/testPSD.psd | Bin 0 -> 69410 bytes .../test-files/test-documents/testPages.pages | Bin 0 -> 134152 bytes .../test-documents/testRTFVarious.rtf | 329 +++ .../src/test-files/test-documents/testSVG.svg | 23 + .../test-files/test-documents/testTIFF.tif | Bin 0 -> 25584 bytes .../test-files/test-documents/testVISIO.vsd | Bin 0 -> 45568 bytes .../src/test-files/test-documents/testWAV.wav | Bin 0 -> 3884 bytes .../test-documents/testWORD_various.doc | Bin 0 -> 35328 bytes .../src/test-files/test-documents/testXML.xml | 48 + .../test-files/test-documents/testXML2.xml | 22 + .../test-morphlines/loadSolrBasic.conf | 63 + .../solrCellDocumentTypes.conf | 255 +++ .../solrCellJPGCompressed.conf | 135 ++ .../test-morphlines/solrCellXML.conf | 69 + .../test-morphlines/tokenizeText.conf | 34 + .../tutorialReadAvroContainer.conf | 140 ++ .../apache/solr/hadoop/IdentityMapper.java | 37 + .../apache/solr/hadoop/IdentityReducer.java | 36 + .../LineRandomizerMapperReducerTest.java | 94 + .../org/apache/solr/hadoop/MRUnitBase.java | 66 + ...apReduceIndexerToolArgumentParserTest.java | 463 +++++ .../solr/hadoop/MorphlineBasicMiniMRTest.java | 401 ++++ .../hadoop/MorphlineGoLiveMiniMRTest.java | 730 +++++++ .../solr/hadoop/MorphlineMapperTest.java | 58 + .../solr/hadoop/MorphlineReducerTest.java | 112 ++ .../apache/solr/hadoop/PathValidation.java | 51 + .../org/apache/solr/hadoop/UtilsForTests.java | 64 + .../solr/hadoop/hack/MiniMRClientCluster.java | 41 + .../hack/MiniMRClientClusterFactory.java | 88 + .../solr/hadoop/hack/MiniMRCluster.java | 283 +++ .../solr/hadoop/hack/MiniMRYarnCluster.java | 205 ++ .../hadoop/hack/MiniMRYarnClusterAdapter.java | 78 + .../solr/hadoop/hack/MiniYARNCluster.java | 410 ++++ .../apache/solr/store/hdfs/HdfsDirectory.java | 1 - solr/core/src/test-files/log4j.properties | 1 + .../cloud-scripts/log4j.properties | 0 .../{ => scripts}/cloud-scripts/zkcli.bat | 2 +- .../{ => scripts}/cloud-scripts/zkcli.sh | 2 +- solr/example/scripts/solr-mr/solr-mr.bat | 9 + solr/example/scripts/solr-mr/solr-mr.sh | 10 + solr/licenses/Saxon-HE-9.5.1-2.jar.sha1 | 1 + solr/licenses/Saxon-HE-LICENSE-MPL.txt | 108 + solr/licenses/aopalliance-1.0.jar.sha1 | 1 + solr/licenses/aopalliance-LICENSE-PD.txt | 1 + solr/licenses/argparse4j-0.4.0.jar.sha1 | 1 + solr/licenses/argparse4j-LICENSE-MIT.txt | 23 + solr/licenses/asm-3.1.jar.sha1 | 1 + solr/licenses/asm-LICENSE-BSD.txt | 29 + solr/licenses/aspectjrt-1.6.11.jar.sha1 | 1 + solr/licenses/aspectjrt-LICENSE-EPL.txt | 71 + solr/licenses/avro-1.7.4.jar.sha1 | 1 + solr/licenses/avro-LICENSE-ASL.txt | 308 +++ solr/licenses/avro-NOTICE.txt | 9 + .../cdk-morphlines-avro-0.8.1.jar.sha1 | 1 + .../cdk-morphlines-avro-LICENSE-ASL.txt | 202 ++ solr/licenses/cdk-morphlines-avro-NOTICE.txt | 8 + .../cdk-morphlines-core-0.8.1-tests.jar.sha1 | 1 + .../cdk-morphlines-core-0.8.1.jar.sha1 | 1 + .../cdk-morphlines-core-LICENSE-ASL.txt | 202 ++ solr/licenses/cdk-morphlines-core-NOTICE.txt | 8 + ...phlines-hadoop-sequencefile-0.8.1.jar.sha1 | 1 + ...hlines-hadoop-sequencefile-LICENSE-ASL.txt | 202 ++ ...-morphlines-hadoop-sequencefile-NOTICE.txt | 8 + .../cdk-morphlines-json-0.8.1.jar.sha1 | 1 + .../cdk-morphlines-json-LICENSE-ASL.txt | 202 ++ solr/licenses/cdk-morphlines-json-NOTICE.txt | 8 + .../cdk-morphlines-saxon-0.8.1.jar.sha1 | 1 + .../cdk-morphlines-saxon-LICENSE-ASL.txt | 202 ++ solr/licenses/cdk-morphlines-saxon-NOTICE.txt | 8 + .../cdk-morphlines-tika-core-0.8.1.jar.sha1 | 1 + .../cdk-morphlines-tika-core-LICENSE-ASL.txt | 202 ++ .../cdk-morphlines-tika-core-NOTICE.txt | 8 + ...-morphlines-tika-decompress-0.8.1.jar.sha1 | 1 + ...morphlines-tika-decompress-LICENSE-ASL.txt | 202 ++ .../cdk-morphlines-tika-decompress-NOTICE.txt | 8 + .../cdk-morphlines-twitter-0.8.1.jar.sha1 | 1 + .../cdk-morphlines-twitter-LICENSE-ASL.txt | 202 ++ .../cdk-morphlines-twitter-NOTICE.txt | 8 + solr/licenses/config-1.0.2.jar.sha1 | 1 + solr/licenses/config-LICENSE-ASL.txt | 202 ++ solr/licenses/config-NOTICE.txt | 0 solr/licenses/guice-3.0.jar.sha1 | 1 + solr/licenses/guice-LICENSE-ASL.txt | 202 ++ solr/licenses/guice-NOTICE.txt | 0 solr/licenses/guice-servlet-3.0.jar.sha1 | 1 + solr/licenses/guice-servlet-LICENSE-ASL.txt | 202 ++ solr/licenses/guice-servlet-NOTICE.txt | 0 ...hadoop-mapreduce-client-app-2.2.0.jar.sha1 | 1 + ...adoop-mapreduce-client-app-LICENSE-ASL.txt | 244 +++ .../hadoop-mapreduce-client-app-NOTICE.txt | 2 + ...oop-mapreduce-client-common-2.2.0.jar.sha1 | 1 + ...op-mapreduce-client-common-LICENSE-ASL.txt | 244 +++ .../hadoop-mapreduce-client-common-NOTICE.txt | 2 + ...adoop-mapreduce-client-core-2.2.0.jar.sha1 | 1 + ...doop-mapreduce-client-core-LICENSE-ASL.txt | 244 +++ .../hadoop-mapreduce-client-core-NOTICE.txt | 2 + .../hadoop-mapreduce-client-hs-2.2.0.jar.sha1 | 1 + ...hadoop-mapreduce-client-hs-LICENSE-ASL.txt | 244 +++ .../hadoop-mapreduce-client-hs-NOTICE.txt | 2 + ...duce-client-jobclient-2.2.0-tests.jar.sha1 | 1 + ...-mapreduce-client-jobclient-2.2.0.jar.sha1 | 1 + ...mapreduce-client-jobclient-LICENSE-ASL.txt | 244 +++ ...doop-mapreduce-client-jobclient-NOTICE.txt | 2 + ...op-mapreduce-client-shuffle-2.2.0.jar.sha1 | 1 + ...p-mapreduce-client-shuffle-LICENSE-ASL.txt | 244 +++ ...hadoop-mapreduce-client-shuffle-NOTICE.txt | 2 + solr/licenses/hadoop-yarn-api-2.2.0.jar.sha1 | 1 + solr/licenses/hadoop-yarn-api-LICENSE-ASL.txt | 244 +++ solr/licenses/hadoop-yarn-api-NOTICE.txt | 2 + .../hadoop-yarn-client-2.2.0.jar.sha1 | 1 + .../hadoop-yarn-client-LICENSE-ASL.txt | 244 +++ solr/licenses/hadoop-yarn-client-NOTICE.txt | 2 + .../hadoop-yarn-common-2.2.0.jar.sha1 | 1 + .../hadoop-yarn-common-LICENSE-ASL.txt | 244 +++ solr/licenses/hadoop-yarn-common-NOTICE.txt | 2 + .../hadoop-yarn-server-common-2.2.0.jar.sha1 | 1 + .../hadoop-yarn-server-common-LICENSE-ASL.txt | 244 +++ .../hadoop-yarn-server-common-NOTICE.txt | 2 + ...oop-yarn-server-nodemanager-2.2.0.jar.sha1 | 1 + ...op-yarn-server-nodemanager-LICENSE-ASL.txt | 244 +++ .../hadoop-yarn-server-nodemanager-NOTICE.txt | 2 + ...yarn-server-resourcemanager-2.2.0.jar.sha1 | 1 + ...arn-server-resourcemanager-LICENSE-ASL.txt | 244 +++ ...oop-yarn-server-resourcemanager-NOTICE.txt | 2 + ...oop-yarn-server-tests-2.2.0-tests.jar.sha1 | 1 + .../hadoop-yarn-server-tests-LICENSE-ASL.txt | 244 +++ .../hadoop-yarn-server-tests-NOTICE.txt | 2 + ...adoop-yarn-server-web-proxy-2.2.0.jar.sha1 | 1 + ...doop-yarn-server-web-proxy-LICENSE-ASL.txt | 244 +++ .../hadoop-yarn-server-web-proxy-NOTICE.txt | 2 + .../jackson-annotations-2.2.3.jar.sha1 | 1 + .../jackson-annotations-LICENSE-ASL.txt | 8 + solr/licenses/jackson-annotations-NOTICE.txt | 0 solr/licenses/jackson-core-2.2.3.jar.sha1 | 1 + solr/licenses/jackson-core-LICENSE-ASL.txt | 8 + solr/licenses/jackson-core-NOTICE.txt | 20 + .../licenses/jackson-core-asl-1.9.13.jar.sha1 | 1 + solr/licenses/jackson-databind-2.2.3.jar.sha1 | 1 + .../licenses/jackson-databind-LICENSE-ASL.txt | 8 + solr/licenses/jackson-databind-NOTICE.txt | 20 + solr/licenses/jackson-jaxrs-1.9.13.jar.sha1 | 1 + solr/licenses/jackson-jaxrs-LICENSE-ASL.txt | 13 + solr/licenses/jackson-jaxrs-NOTICE.txt | 7 + .../jackson-mapper-asl-1.9.13.jar.sha1 | 1 + solr/licenses/javax.inject-1.jar.sha1 | 1 + solr/licenses/javax.inject-LICENSE-ASL.txt | 202 ++ solr/licenses/javax.inject-NOTICE.txt | 0 solr/licenses/jaxb-impl-2.2.2.jar.sha1 | 1 + solr/licenses/jaxb-impl-LICENSE-CDDL.txt | 263 +++ solr/licenses/jersey-bundle-1.8.jar.sha1 | 1 + solr/licenses/jersey-bundle-LICENSE-CDDL.txt | 85 + solr/licenses/jersey-core-1.8.jar.sha1 | 1 + solr/licenses/jersey-guice-1.8.jar.sha1 | 1 + solr/licenses/jersey-guice-LICENSE-CDDL.txt | 85 + solr/licenses/jersey-json-1.8.jar.sha1 | 1 + solr/licenses/jersey-json-LICENSE-CDDL.txt | 85 + solr/licenses/jersey-server-1.8.jar.sha1 | 1 + solr/licenses/jersey-server-LICENSE-CDDL.txt | 85 + solr/licenses/metrics-core-3.0.1.jar.sha1 | 1 + solr/licenses/metrics-core-LICENSE-ASL.txt | 202 ++ solr/licenses/metrics-core-NOTICE.txt | 11 + .../metrics-healthchecks-3.0.1.jar.sha1 | 1 + .../metrics-healthchecks-LICENSE-ASL.txt | 202 ++ solr/licenses/metrics-healthchecks-NOTICE.txt | 11 + solr/licenses/mockito-core-1.9.5.jar.sha1 | 1 + solr/licenses/mockito-core-LICENSE-MIT.txt | 21 + solr/licenses/mrunit-1.0.0-hadoop2.jar.sha1 | 1 + solr/licenses/mrunit-LICENSE-ASL.txt | 479 +++++ solr/licenses/mrunit-NOTICE.txt | 5 + solr/licenses/netty-3.6.2.Final.jar.sha1 | 1 + solr/licenses/netty-LICENSE-ASL.txt | 202 ++ solr/licenses/netty-NOTICE.txt | 121 ++ solr/licenses/paranamer-2.3.jar.sha1 | 1 + solr/licenses/paranamer-LICENSE-BSD.txt | 28 + solr/licenses/paranamer-NOTICE.txt | 0 solr/licenses/snappy-java-1.0.4.1.jar.sha1 | 1 + solr/licenses/snappy-java-LICENSE-ASL.txt | 201 ++ solr/licenses/snappy-java-NOTICE.txt | 0 solr/licenses/tika-xmp-1.4.jar.sha1 | 1 + solr/licenses/tika-xmp-LICENSE-ASL.txt | 238 +++ solr/licenses/tika-xmp-NOTICE.txt | 15 + solr/licenses/xmpcore-5.1.2.jar.sha1 | 1 + solr/licenses/xmpcore-LICENSE-BSD.txt | 11 + solr/licenses/xmpcore-NOTICE.txt | 0 901 files changed, 115776 insertions(+), 16 deletions(-) create mode 100644 dev-tools/idea/.idea/libraries/Solr_morphlines_cell_library.xml create mode 100644 dev-tools/idea/.idea/libraries/Solr_morphlines_core_library.xml create mode 100644 dev-tools/idea/.idea/libraries/Solr_morphlines_core_test_library.xml create mode 100644 dev-tools/idea/solr/contrib/solr-morphlines-cell/solr-morphlines-cell.iml create mode 100644 dev-tools/idea/solr/contrib/solr-morphlines-core/solr-morphlines-core.iml create mode 100644 dev-tools/idea/solr/contrib/solr-mr/solr-mr.iml create mode 100644 dev-tools/maven/solr/contrib/solr-morphlines-cell/pom.xml.template create mode 100644 dev-tools/maven/solr/contrib/solr-morphlines-core/pom.xml.template create mode 100644 dev-tools/maven/solr/contrib/solr-mr/pom.xml.template create mode 100644 solr/contrib/solr-morphlines-cell/build.xml create mode 100644 solr/contrib/solr-morphlines-cell/ivy.xml create mode 100644 solr/contrib/solr-morphlines-cell/src/java/org/apache/solr/morphlines/cell/SolrCellBuilder.java create mode 100644 solr/contrib/solr-morphlines-cell/src/java/org/apache/solr/morphlines/cell/StripNonCharSolrContentHandlerFactory.java create mode 100644 solr/contrib/solr-morphlines-cell/src/java/org/apache/solr/morphlines/cell/TrimSolrContentHandlerFactory.java create mode 100644 solr/contrib/solr-morphlines-cell/src/java/org/apache/solr/morphlines/cell/package.html create mode 100644 solr/contrib/solr-morphlines-cell/src/java/overview.html create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/currency.xml create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/elevate.xml create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/contractions_ca.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/contractions_fr.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/contractions_ga.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/contractions_it.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/hyphenations_ga.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stemdict_nl.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stoptags_ja.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ar.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_bg.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ca.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_cz.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_da.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_de.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_el.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_en.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_es.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_eu.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_fa.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_fi.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_fr.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ga.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_gl.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_hi.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_hu.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_hy.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_id.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_it.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ja.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_lv.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_nl.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_no.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_pt.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ro.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ru.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_sv.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_th.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_tr.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/userdict_ja.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/protwords.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/schema.xml create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/solrconfig.xml create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/stopwords.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/synonyms.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/currency.xml create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/elevate.xml create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/contractions_ca.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/contractions_fr.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/contractions_ga.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/contractions_it.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/hyphenations_ga.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stemdict_nl.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stoptags_ja.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ar.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_bg.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ca.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_cz.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_da.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_de.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_el.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_en.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_es.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_eu.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_fa.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_fi.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_fr.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ga.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_gl.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_hi.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_hu.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_hy.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_id.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_it.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ja.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_lv.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_nl.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_no.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_pt.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ro.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ru.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_sv.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_th.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_tr.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/userdict_ja.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/protwords.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/schema.xml create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/solrconfig.xml create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/stopwords.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/synonyms.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/solr.xml create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/currency.xml create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/elevate.xml create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/contractions_ca.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/contractions_fr.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/contractions_ga.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/contractions_it.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/hyphenations_ga.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stemdict_nl.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stoptags_ja.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ar.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_bg.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ca.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_cz.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_da.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_de.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_el.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_en.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_es.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_eu.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_fa.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_fi.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_fr.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ga.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_gl.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_hi.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_hu.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_hy.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_id.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_it.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ja.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_lv.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_nl.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_no.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_pt.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ro.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ru.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_sv.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_th.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_tr.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/userdict_ja.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/protwords.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/schema.xml create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/solrconfig.xml create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/stopwords.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/synonyms.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/solr.xml create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solr.xml create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/currency.xml create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/elevate.xml create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_ca.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_fr.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_ga.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_it.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/hyphenations_ga.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stemdict_nl.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stoptags_ja.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ar.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_bg.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ca.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_cz.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_da.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_de.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_el.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_en.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_es.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_eu.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fa.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fi.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fr.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ga.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_gl.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hi.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hu.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hy.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_id.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_it.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ja.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_lv.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_nl.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_no.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_pt.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ro.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ru.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_sv.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_th.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_tr.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/userdict_ja.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/protwords.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/schema.xml create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/solrconfig.xml create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/stopwords.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/synonyms.txt create mode 100644 solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcloud/conf/solrconfig.xml create mode 100644 solr/contrib/solr-morphlines-cell/src/test/org/apache/solr/morphlines/cell/SolrCellMorphlineTest.java create mode 100644 solr/contrib/solr-morphlines-core/build.xml create mode 100644 solr/contrib/solr-morphlines-core/ivy.xml create mode 100644 solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/DocumentLoader.java create mode 100644 solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/GenerateSolrSequenceKeyBuilder.java create mode 100644 solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/LoadSolrBuilder.java create mode 100644 solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/SafeConcurrentUpdateSolrServer.java create mode 100644 solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/SanitizeUnknownSolrFieldsBuilder.java create mode 100644 solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/SolrLocator.java create mode 100644 solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/SolrMorphlineContext.java create mode 100644 solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/SolrServerDocumentLoader.java create mode 100644 solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/TokenizeTextBuilder.java create mode 100644 solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/ZooKeeperDownloader.java create mode 100644 solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/package.html create mode 100644 solr/contrib/solr-morphlines-core/src/java/overview.html create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/README create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/books_numeric_ids.csv create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/exampledocs/example.html create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/exampledocs/example.txt create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/README create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/a/a1/empty-file-a1.txt create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/a/a2/empty-file-a2.txt create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/b/b1/empty-file-b1.txt create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/b/b2/empty-file-b2.txt create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/c/c1/empty-file-c1.txt create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/c/c2/empty-file-c2.txt create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/d/d1/empty-file-d1.txt create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/d/d2/empty-file-d2.txt create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/log4j.properties create mode 100755 solr/contrib/solr-morphlines-core/src/test-files/mailing_lists.pdf create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/old-solr-example/README.txt create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/old-solr-example/solr.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/addfields.updateprocessor.js create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/analyzingInfixSuggest.txt create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-currency.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-mp-solrconfig.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-analyzer-class-and-nested.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-bogus-analysis-parameters.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-bogus-field-parameters.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-codec-global-vs-ft-mismatch.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-dynamic-multivalued.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-ft-bogus-code-in-xml.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-ft-bogus-default-code.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-ft-multivalued.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-ft-oer-norates.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-multivalued.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dup-dynamicField.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dup-field.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dup-fieldType.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dynamicfield-default-val.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dynamicfield-required.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-external-filefield.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-misplaced-asterisk-copyfield-dest-should-fail-test.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-misplaced-asterisk-copyfield-source-should-fail-test.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-multiple-asterisk-copyfield-dest-should-fail-test.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-multiple-asterisk-copyfield-source-should-fail-test.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-non-glob-copyfield-source-matching-nothing-should-fail-test.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-nontext-analyzer.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-not-indexed-but-norms.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-not-indexed-but-pos.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-not-indexed-but-tf.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-omit-tf-but-not-pos.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sim-global-vs-ft-mismatch.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sweetspot-both-tf.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sweetspot-partial-baseline.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sweetspot-partial-hyperbolic.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sweetspot-partial-norms.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-uniquekey-is-copyfield-dest.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-uniquekey-multivalued.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-uniquekey-uses-default.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-unsupported-docValues.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-bogus-scriptengine-name.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-invalid-scriptfile.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-managed-schema-named-schema.xml.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-missing-scriptfile.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-multiple-cfs.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-multiple-dirfactory.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-multiple-indexconfigs.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-schema-mutable-but-not-managed.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-unexpected-schema-attribute.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-warmer-no-reopen.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad_solrconfig.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/compoundDictionary.txt create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/conditional.updateprocessor.js create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/currency.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/da_UTF8.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/da_compoundDictionary.txt create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/elevate.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/frenchArticles.txt create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/fuzzysuggest.txt create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/hunspell-test.aff create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/hunspell-test.dic create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/hyphenation.dtd create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/jasuggest.txt create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/keep-1.txt create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/keep-2.txt create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/mapping-ISOLatin1Accent.txt create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/missing.functions.updateprocessor.js create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/missleading.extension.updateprocessor.js.txt create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/old_synonyms.txt create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/open-exchange-rates.json create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/phrasesuggest.txt create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/protwords.txt create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/regex-boost-processor-test.txt create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-add-schema-fields-update-processor.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-behavior.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-binaryfield.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-bm25.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-charfilters.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-class-name-shortening-on-serialization.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-collate.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-copyfield-test.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-dfr.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-docValues.xml create mode 100755 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-docValuesFaceting.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-docValuesMissing.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-docValuesMulti.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-eff.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-folding.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-ib.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-id-and-version-fields-only.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-lmdirichlet.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-lmjelinekmercer.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-luceneMatchVersion.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-minimal.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-not-required-unique-key.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-numeric.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-one-field-no-dynamic-field-unique-key.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-one-field-no-dynamic-field.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-phrasesuggest.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-postingshighlight.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-replication1.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-replication2.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-required-fields.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-rest-lucene-match-version.xml create mode 100755 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-rest.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-reversed.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-sim.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-snippet-field.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-snippet-type.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-snippet-types.incl create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-spatial.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-spellchecker.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-stop-keep.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-sweetspot.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-synonym-tokenizer.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-tfidf.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-tiny.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-trie.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-xinclude.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema.xml create mode 100755 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema11.xml create mode 100755 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema12.xml create mode 100755 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema15.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema_codec.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schemasurround.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-SOLR-749.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-add-schema-fields-update-processor-chains.xml create mode 100755 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-altdirectory.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-basic.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-caching.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-components-name.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-defaults.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-delpolicy1.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-delpolicy2.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-elevate.xml create mode 100755 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-functionquery.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-highlight.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-implicitproperties.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-indexconfig.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-infostream-logging.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-lazywriter.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-logmergepolicy.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-managed-schema.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master1-keepOneBackup.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master1.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master2.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master3.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-mergepolicy-defaults.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-mergepolicy-legacy.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-minimal.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-nocache.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-noopregen.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-parsing-update-processor-chains.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-phrasesuggest.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-postingshighlight.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-querysender-noquery.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-querysender.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-repeater.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-reqHandler.incl create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-response-log-component.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-script-updateprocessor.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-slave.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-slave1.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-snippet-processor.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-solcoreproperties.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-spellcheckcomponent.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-spellchecker.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-test-misc.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-tieredmergepolicy.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-tlog.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-transformers.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-update-processor-chains.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-warmer.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-xinclude.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig.snippet.randomindexconfig.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig_codec.xml create mode 100755 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig_perf.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stemdict.txt create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stop-1.txt create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stop-2.txt create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stop-snowball.txt create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stoptypes-1.txt create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stoptypes-2.txt create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stopwithbom.txt create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stopwords.txt create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stopwordsWrongEncoding.txt create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/synonyms.txt create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/throw.error.on.add.updateprocessor.js create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/trivial.updateprocessor0.js create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/trivial.updateprocessor1.js create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/wdftypes.txt create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/xslt/dummy-using-include.xsl create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/xslt/dummy.xsl create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/xslt/xsl-update-handler-test.xsl create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/lib/README create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/lib/classes/empty-file-main-lib.txt create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/conf/core.properties create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/crazy-path-to-config.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/crazy-path-to-schema.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/external_eff create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/solr-50-all.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/solr-multicore.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/solr-no-core.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/solr-shardhandler-old.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/solr-shardhandler.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/solr-stress-new.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/solr-stress-old.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/solr/solr.xml create mode 100644 solr/contrib/solr-morphlines-core/src/test-files/spellings.txt create mode 100644 solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/AbstractSolrMorphlineTestBase.java create mode 100644 solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/AbstractSolrMorphlineZkTestBase.java create mode 100644 solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/CollectingDocumentLoader.java create mode 100644 solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/EmbeddedTestSolrServer.java create mode 100644 solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineTest.java create mode 100644 solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkAliasTest.java create mode 100644 solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkAvroTest.java create mode 100644 solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkTest.java create mode 100644 solr/contrib/solr-mr/build.xml create mode 100644 solr/contrib/solr-mr/ivy.xml create mode 100644 solr/contrib/solr-mr/src/java/assembly/hadoop-job.xml create mode 100644 solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/BatchWriter.java create mode 100644 solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/DataInputInputStream.java create mode 100644 solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/DataOutputOutputStream.java create mode 100644 solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/DryRunDocumentLoader.java create mode 100644 solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/GoLive.java create mode 100644 solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/HdfsFileFieldNames.java create mode 100644 solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/HeartBeater.java create mode 100644 solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/LineRandomizerMapper.java create mode 100644 solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/LineRandomizerReducer.java create mode 100644 solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/MapReduceIndexerTool.java create mode 100644 solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/PathArgumentType.java create mode 100644 solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/PathParts.java create mode 100644 solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrCloudPartitioner.java create mode 100644 solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrCounters.java create mode 100644 solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrInputDocumentWritable.java create mode 100644 solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrMapper.java create mode 100644 solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrOutputFormat.java create mode 100644 solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrRecordWriter.java create mode 100644 solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrReducer.java create mode 100644 solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/ToolRunnerHelpFormatter.java create mode 100644 solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/TreeMergeMapper.java create mode 100644 solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/TreeMergeOutputFormat.java create mode 100644 solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/UnbufferedDataInputInputStream.java create mode 100644 solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/Utils.java create mode 100644 solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/ZooKeeperInspector.java create mode 100644 solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/NoChangeUpdateConflictResolver.java create mode 100644 solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/RejectingUpdateConflictResolver.java create mode 100644 solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/RetainMostRecentUpdateConflictResolver.java create mode 100644 solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/SolrInputDocumentComparator.java create mode 100644 solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/SortingUpdateConflictResolver.java create mode 100644 solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/UpdateConflictResolver.java create mode 100644 solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/package.html create mode 100644 solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/morphline/MorphlineCounters.java create mode 100644 solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/morphline/MorphlineMapRunner.java create mode 100644 solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/morphline/MorphlineMapper.java create mode 100644 solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/morphline/package.html create mode 100644 solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/package.html create mode 100644 solr/contrib/solr-mr/src/java/overview.html create mode 100644 solr/contrib/solr-mr/src/test-files/custom-mimetypes.xml create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/currency.xml create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/elevate.xml create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/contractions_ca.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/contractions_fr.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/contractions_ga.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/contractions_it.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/hyphenations_ga.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stemdict_nl.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stoptags_ja.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_ar.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_bg.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_ca.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_cz.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_da.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_de.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_el.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_en.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_es.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_eu.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_fa.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_fi.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_fr.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_ga.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_gl.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_hi.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_hu.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_hy.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_id.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_it.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_ja.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_lv.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_nl.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_no.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_pt.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_ro.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_ru.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_sv.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_th.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_tr.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/userdict_ja.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/protwords.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/schema.xml create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/solrconfig.xml create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/stopwords.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/collection1/conf/synonyms.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/currency.xml create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/elevate.xml create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/contractions_ca.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/contractions_fr.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/contractions_ga.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/contractions_it.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/hyphenations_ga.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stemdict_nl.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stoptags_ja.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_ar.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_bg.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_ca.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_cz.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_da.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_de.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_el.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_en.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_es.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_eu.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_fa.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_fi.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_fr.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_ga.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_gl.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_hi.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_hu.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_hy.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_id.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_it.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_ja.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_lv.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_nl.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_no.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_pt.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_ro.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_ru.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_sv.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_th.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_tr.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/userdict_ja.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/protwords.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/schema.xml create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/solrconfig.xml create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/stopwords.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/conf/synonyms.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/minimr/solr.xml create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/currency.xml create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/elevate.xml create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/contractions_ca.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/contractions_fr.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/contractions_ga.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/contractions_it.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/hyphenations_ga.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stemdict_nl.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stoptags_ja.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_ar.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_bg.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_ca.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_cz.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_da.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_de.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_el.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_en.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_es.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_eu.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_fa.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_fi.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_fr.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_ga.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_gl.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_hi.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_hu.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_hy.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_id.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_it.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_ja.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_lv.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_nl.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_no.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_pt.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_ro.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_ru.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_sv.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_th.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_tr.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/userdict_ja.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/protwords.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/schema.xml create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/solrconfig.xml create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/stopwords.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/synonyms.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/mrunit/solr.xml create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solr.xml create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/currency.xml create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/elevate.xml create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_ca.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_fr.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_ga.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_it.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/hyphenations_ga.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stemdict_nl.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stoptags_ja.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ar.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_bg.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ca.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_cz.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_da.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_de.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_el.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_en.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_es.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_eu.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fa.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fi.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fr.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ga.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_gl.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hi.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hu.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hy.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_id.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_it.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ja.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_lv.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_nl.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_no.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_pt.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ro.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ru.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_sv.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_th.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_tr.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/userdict_ja.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/protwords.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/schema.xml create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/solrconfig.xml create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/stopwords.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/synonyms.txt create mode 100644 solr/contrib/solr-mr/src/test-files/solr/solrcloud/conf/solrconfig.xml create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/NullHeader.docx create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/boilerplate.html create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/complex.mbox create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/rsstest.rss create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/sample-statuses-20120521-100919.avro create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/sample-statuses-20120906-141433 create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/sample-statuses-20120906-141433-medium.avro create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/sample-statuses-20120906-141433.avro create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/sample-statuses-20120906-141433.bz2 create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/sample-statuses-20120906-141433.gz create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/test-outlook.msg create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/testAIFF.aif create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/testBMP.bmp create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/testBMPfp.txt create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/testEMLX.emlx create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/testEXCEL.xls create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/testEXCEL.xlsx create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/testFLAC.flac create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/testFLV.flv create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/testJPEG_EXIF.jpg create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/testJPEG_EXIF.jpg.gz create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/testJPEG_EXIF.jpg.tar.gz create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/testMP3i18n.mp3 create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/testMP4.m4a create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/testPDF.pdf create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/testPNG.png create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/testPPT_various.ppt create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/testPPT_various.pptx create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/testPSD.psd create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/testPages.pages create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/testRTFVarious.rtf create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/testSVG.svg create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/testTIFF.tif create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/testVISIO.vsd create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/testWAV.wav create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/testWORD_various.doc create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/testXML.xml create mode 100644 solr/contrib/solr-mr/src/test-files/test-documents/testXML2.xml create mode 100644 solr/contrib/solr-mr/src/test-files/test-morphlines/loadSolrBasic.conf create mode 100644 solr/contrib/solr-mr/src/test-files/test-morphlines/solrCellDocumentTypes.conf create mode 100644 solr/contrib/solr-mr/src/test-files/test-morphlines/solrCellJPGCompressed.conf create mode 100644 solr/contrib/solr-mr/src/test-files/test-morphlines/solrCellXML.conf create mode 100644 solr/contrib/solr-mr/src/test-files/test-morphlines/tokenizeText.conf create mode 100644 solr/contrib/solr-mr/src/test-files/test-morphlines/tutorialReadAvroContainer.conf create mode 100644 solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/IdentityMapper.java create mode 100644 solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/IdentityReducer.java create mode 100644 solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/LineRandomizerMapperReducerTest.java create mode 100644 solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MRUnitBase.java create mode 100644 solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MapReduceIndexerToolArgumentParserTest.java create mode 100644 solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineBasicMiniMRTest.java create mode 100644 solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineGoLiveMiniMRTest.java create mode 100644 solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineMapperTest.java create mode 100644 solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineReducerTest.java create mode 100644 solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/PathValidation.java create mode 100644 solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/UtilsForTests.java create mode 100644 solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/hack/MiniMRClientCluster.java create mode 100644 solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/hack/MiniMRClientClusterFactory.java create mode 100644 solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/hack/MiniMRCluster.java create mode 100644 solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/hack/MiniMRYarnCluster.java create mode 100644 solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/hack/MiniMRYarnClusterAdapter.java create mode 100644 solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/hack/MiniYARNCluster.java rename solr/example/{ => scripts}/cloud-scripts/log4j.properties (100%) rename solr/example/{ => scripts}/cloud-scripts/zkcli.bat (67%) rename solr/example/{ => scripts}/cloud-scripts/zkcli.sh (62%) create mode 100644 solr/example/scripts/solr-mr/solr-mr.bat create mode 100644 solr/example/scripts/solr-mr/solr-mr.sh create mode 100644 solr/licenses/Saxon-HE-9.5.1-2.jar.sha1 create mode 100644 solr/licenses/Saxon-HE-LICENSE-MPL.txt create mode 100644 solr/licenses/aopalliance-1.0.jar.sha1 create mode 100644 solr/licenses/aopalliance-LICENSE-PD.txt create mode 100644 solr/licenses/argparse4j-0.4.0.jar.sha1 create mode 100644 solr/licenses/argparse4j-LICENSE-MIT.txt create mode 100644 solr/licenses/asm-3.1.jar.sha1 create mode 100644 solr/licenses/asm-LICENSE-BSD.txt create mode 100644 solr/licenses/aspectjrt-1.6.11.jar.sha1 create mode 100644 solr/licenses/aspectjrt-LICENSE-EPL.txt create mode 100644 solr/licenses/avro-1.7.4.jar.sha1 create mode 100644 solr/licenses/avro-LICENSE-ASL.txt create mode 100644 solr/licenses/avro-NOTICE.txt create mode 100644 solr/licenses/cdk-morphlines-avro-0.8.1.jar.sha1 create mode 100644 solr/licenses/cdk-morphlines-avro-LICENSE-ASL.txt create mode 100644 solr/licenses/cdk-morphlines-avro-NOTICE.txt create mode 100644 solr/licenses/cdk-morphlines-core-0.8.1-tests.jar.sha1 create mode 100644 solr/licenses/cdk-morphlines-core-0.8.1.jar.sha1 create mode 100644 solr/licenses/cdk-morphlines-core-LICENSE-ASL.txt create mode 100644 solr/licenses/cdk-morphlines-core-NOTICE.txt create mode 100644 solr/licenses/cdk-morphlines-hadoop-sequencefile-0.8.1.jar.sha1 create mode 100644 solr/licenses/cdk-morphlines-hadoop-sequencefile-LICENSE-ASL.txt create mode 100644 solr/licenses/cdk-morphlines-hadoop-sequencefile-NOTICE.txt create mode 100644 solr/licenses/cdk-morphlines-json-0.8.1.jar.sha1 create mode 100644 solr/licenses/cdk-morphlines-json-LICENSE-ASL.txt create mode 100644 solr/licenses/cdk-morphlines-json-NOTICE.txt create mode 100644 solr/licenses/cdk-morphlines-saxon-0.8.1.jar.sha1 create mode 100644 solr/licenses/cdk-morphlines-saxon-LICENSE-ASL.txt create mode 100644 solr/licenses/cdk-morphlines-saxon-NOTICE.txt create mode 100644 solr/licenses/cdk-morphlines-tika-core-0.8.1.jar.sha1 create mode 100644 solr/licenses/cdk-morphlines-tika-core-LICENSE-ASL.txt create mode 100644 solr/licenses/cdk-morphlines-tika-core-NOTICE.txt create mode 100644 solr/licenses/cdk-morphlines-tika-decompress-0.8.1.jar.sha1 create mode 100644 solr/licenses/cdk-morphlines-tika-decompress-LICENSE-ASL.txt create mode 100644 solr/licenses/cdk-morphlines-tika-decompress-NOTICE.txt create mode 100644 solr/licenses/cdk-morphlines-twitter-0.8.1.jar.sha1 create mode 100644 solr/licenses/cdk-morphlines-twitter-LICENSE-ASL.txt create mode 100644 solr/licenses/cdk-morphlines-twitter-NOTICE.txt create mode 100644 solr/licenses/config-1.0.2.jar.sha1 create mode 100644 solr/licenses/config-LICENSE-ASL.txt create mode 100644 solr/licenses/config-NOTICE.txt create mode 100644 solr/licenses/guice-3.0.jar.sha1 create mode 100644 solr/licenses/guice-LICENSE-ASL.txt create mode 100644 solr/licenses/guice-NOTICE.txt create mode 100644 solr/licenses/guice-servlet-3.0.jar.sha1 create mode 100644 solr/licenses/guice-servlet-LICENSE-ASL.txt create mode 100644 solr/licenses/guice-servlet-NOTICE.txt create mode 100644 solr/licenses/hadoop-mapreduce-client-app-2.2.0.jar.sha1 create mode 100644 solr/licenses/hadoop-mapreduce-client-app-LICENSE-ASL.txt create mode 100644 solr/licenses/hadoop-mapreduce-client-app-NOTICE.txt create mode 100644 solr/licenses/hadoop-mapreduce-client-common-2.2.0.jar.sha1 create mode 100644 solr/licenses/hadoop-mapreduce-client-common-LICENSE-ASL.txt create mode 100644 solr/licenses/hadoop-mapreduce-client-common-NOTICE.txt create mode 100644 solr/licenses/hadoop-mapreduce-client-core-2.2.0.jar.sha1 create mode 100644 solr/licenses/hadoop-mapreduce-client-core-LICENSE-ASL.txt create mode 100644 solr/licenses/hadoop-mapreduce-client-core-NOTICE.txt create mode 100644 solr/licenses/hadoop-mapreduce-client-hs-2.2.0.jar.sha1 create mode 100644 solr/licenses/hadoop-mapreduce-client-hs-LICENSE-ASL.txt create mode 100644 solr/licenses/hadoop-mapreduce-client-hs-NOTICE.txt create mode 100644 solr/licenses/hadoop-mapreduce-client-jobclient-2.2.0-tests.jar.sha1 create mode 100644 solr/licenses/hadoop-mapreduce-client-jobclient-2.2.0.jar.sha1 create mode 100644 solr/licenses/hadoop-mapreduce-client-jobclient-LICENSE-ASL.txt create mode 100644 solr/licenses/hadoop-mapreduce-client-jobclient-NOTICE.txt create mode 100644 solr/licenses/hadoop-mapreduce-client-shuffle-2.2.0.jar.sha1 create mode 100644 solr/licenses/hadoop-mapreduce-client-shuffle-LICENSE-ASL.txt create mode 100644 solr/licenses/hadoop-mapreduce-client-shuffle-NOTICE.txt create mode 100644 solr/licenses/hadoop-yarn-api-2.2.0.jar.sha1 create mode 100644 solr/licenses/hadoop-yarn-api-LICENSE-ASL.txt create mode 100644 solr/licenses/hadoop-yarn-api-NOTICE.txt create mode 100644 solr/licenses/hadoop-yarn-client-2.2.0.jar.sha1 create mode 100644 solr/licenses/hadoop-yarn-client-LICENSE-ASL.txt create mode 100644 solr/licenses/hadoop-yarn-client-NOTICE.txt create mode 100644 solr/licenses/hadoop-yarn-common-2.2.0.jar.sha1 create mode 100644 solr/licenses/hadoop-yarn-common-LICENSE-ASL.txt create mode 100644 solr/licenses/hadoop-yarn-common-NOTICE.txt create mode 100644 solr/licenses/hadoop-yarn-server-common-2.2.0.jar.sha1 create mode 100644 solr/licenses/hadoop-yarn-server-common-LICENSE-ASL.txt create mode 100644 solr/licenses/hadoop-yarn-server-common-NOTICE.txt create mode 100644 solr/licenses/hadoop-yarn-server-nodemanager-2.2.0.jar.sha1 create mode 100644 solr/licenses/hadoop-yarn-server-nodemanager-LICENSE-ASL.txt create mode 100644 solr/licenses/hadoop-yarn-server-nodemanager-NOTICE.txt create mode 100644 solr/licenses/hadoop-yarn-server-resourcemanager-2.2.0.jar.sha1 create mode 100644 solr/licenses/hadoop-yarn-server-resourcemanager-LICENSE-ASL.txt create mode 100644 solr/licenses/hadoop-yarn-server-resourcemanager-NOTICE.txt create mode 100644 solr/licenses/hadoop-yarn-server-tests-2.2.0-tests.jar.sha1 create mode 100644 solr/licenses/hadoop-yarn-server-tests-LICENSE-ASL.txt create mode 100644 solr/licenses/hadoop-yarn-server-tests-NOTICE.txt create mode 100644 solr/licenses/hadoop-yarn-server-web-proxy-2.2.0.jar.sha1 create mode 100644 solr/licenses/hadoop-yarn-server-web-proxy-LICENSE-ASL.txt create mode 100644 solr/licenses/hadoop-yarn-server-web-proxy-NOTICE.txt create mode 100644 solr/licenses/jackson-annotations-2.2.3.jar.sha1 create mode 100644 solr/licenses/jackson-annotations-LICENSE-ASL.txt create mode 100644 solr/licenses/jackson-annotations-NOTICE.txt create mode 100644 solr/licenses/jackson-core-2.2.3.jar.sha1 create mode 100644 solr/licenses/jackson-core-LICENSE-ASL.txt create mode 100644 solr/licenses/jackson-core-NOTICE.txt create mode 100644 solr/licenses/jackson-core-asl-1.9.13.jar.sha1 create mode 100644 solr/licenses/jackson-databind-2.2.3.jar.sha1 create mode 100644 solr/licenses/jackson-databind-LICENSE-ASL.txt create mode 100644 solr/licenses/jackson-databind-NOTICE.txt create mode 100644 solr/licenses/jackson-jaxrs-1.9.13.jar.sha1 create mode 100644 solr/licenses/jackson-jaxrs-LICENSE-ASL.txt create mode 100644 solr/licenses/jackson-jaxrs-NOTICE.txt create mode 100644 solr/licenses/jackson-mapper-asl-1.9.13.jar.sha1 create mode 100644 solr/licenses/javax.inject-1.jar.sha1 create mode 100644 solr/licenses/javax.inject-LICENSE-ASL.txt create mode 100644 solr/licenses/javax.inject-NOTICE.txt create mode 100644 solr/licenses/jaxb-impl-2.2.2.jar.sha1 create mode 100644 solr/licenses/jaxb-impl-LICENSE-CDDL.txt create mode 100644 solr/licenses/jersey-bundle-1.8.jar.sha1 create mode 100644 solr/licenses/jersey-bundle-LICENSE-CDDL.txt create mode 100644 solr/licenses/jersey-core-1.8.jar.sha1 create mode 100644 solr/licenses/jersey-guice-1.8.jar.sha1 create mode 100644 solr/licenses/jersey-guice-LICENSE-CDDL.txt create mode 100644 solr/licenses/jersey-json-1.8.jar.sha1 create mode 100644 solr/licenses/jersey-json-LICENSE-CDDL.txt create mode 100644 solr/licenses/jersey-server-1.8.jar.sha1 create mode 100644 solr/licenses/jersey-server-LICENSE-CDDL.txt create mode 100644 solr/licenses/metrics-core-3.0.1.jar.sha1 create mode 100644 solr/licenses/metrics-core-LICENSE-ASL.txt create mode 100644 solr/licenses/metrics-core-NOTICE.txt create mode 100644 solr/licenses/metrics-healthchecks-3.0.1.jar.sha1 create mode 100644 solr/licenses/metrics-healthchecks-LICENSE-ASL.txt create mode 100644 solr/licenses/metrics-healthchecks-NOTICE.txt create mode 100644 solr/licenses/mockito-core-1.9.5.jar.sha1 create mode 100644 solr/licenses/mockito-core-LICENSE-MIT.txt create mode 100644 solr/licenses/mrunit-1.0.0-hadoop2.jar.sha1 create mode 100644 solr/licenses/mrunit-LICENSE-ASL.txt create mode 100644 solr/licenses/mrunit-NOTICE.txt create mode 100644 solr/licenses/netty-3.6.2.Final.jar.sha1 create mode 100644 solr/licenses/netty-LICENSE-ASL.txt create mode 100644 solr/licenses/netty-NOTICE.txt create mode 100644 solr/licenses/paranamer-2.3.jar.sha1 create mode 100644 solr/licenses/paranamer-LICENSE-BSD.txt create mode 100644 solr/licenses/paranamer-NOTICE.txt create mode 100644 solr/licenses/snappy-java-1.0.4.1.jar.sha1 create mode 100644 solr/licenses/snappy-java-LICENSE-ASL.txt create mode 100644 solr/licenses/snappy-java-NOTICE.txt create mode 100644 solr/licenses/tika-xmp-1.4.jar.sha1 create mode 100644 solr/licenses/tika-xmp-LICENSE-ASL.txt create mode 100644 solr/licenses/tika-xmp-NOTICE.txt create mode 100644 solr/licenses/xmpcore-5.1.2.jar.sha1 create mode 100644 solr/licenses/xmpcore-LICENSE-BSD.txt create mode 100644 solr/licenses/xmpcore-NOTICE.txt diff --git a/dev-tools/idea/.idea/ant.xml b/dev-tools/idea/.idea/ant.xml index e9f3c85bcb6..a8e73f6d0b5 100644 --- a/dev-tools/idea/.idea/ant.xml +++ b/dev-tools/idea/.idea/ant.xml @@ -45,6 +45,9 @@ + + + diff --git a/dev-tools/idea/.idea/libraries/Solr_morphlines_cell_library.xml b/dev-tools/idea/.idea/libraries/Solr_morphlines_cell_library.xml new file mode 100644 index 00000000000..c1a0a6f0b0f --- /dev/null +++ b/dev-tools/idea/.idea/libraries/Solr_morphlines_cell_library.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/dev-tools/idea/.idea/libraries/Solr_morphlines_core_library.xml b/dev-tools/idea/.idea/libraries/Solr_morphlines_core_library.xml new file mode 100644 index 00000000000..25770ed8c4d --- /dev/null +++ b/dev-tools/idea/.idea/libraries/Solr_morphlines_core_library.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/dev-tools/idea/.idea/libraries/Solr_morphlines_core_test_library.xml b/dev-tools/idea/.idea/libraries/Solr_morphlines_core_test_library.xml new file mode 100644 index 00000000000..0ae745a64b8 --- /dev/null +++ b/dev-tools/idea/.idea/libraries/Solr_morphlines_core_test_library.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/dev-tools/idea/.idea/modules.xml b/dev-tools/idea/.idea/modules.xml index 58111cfec1b..b8c9fb4e569 100644 --- a/dev-tools/idea/.idea/modules.xml +++ b/dev-tools/idea/.idea/modules.xml @@ -49,6 +49,9 @@ + + + diff --git a/dev-tools/idea/.idea/workspace.xml b/dev-tools/idea/.idea/workspace.xml index 0c578089bce..e5bdc922f07 100644 --- a/dev-tools/idea/.idea/workspace.xml +++ b/dev-tools/idea/.idea/workspace.xml @@ -235,6 +235,27 @@ + + + + + + + + + + + + - + @@ -281,10 +302,13 @@ - - - - + + + + + + + diff --git a/dev-tools/idea/solr/contrib/solr-morphlines-cell/solr-morphlines-cell.iml b/dev-tools/idea/solr/contrib/solr-morphlines-cell/solr-morphlines-cell.iml new file mode 100644 index 00000000000..e2a4cc3f864 --- /dev/null +++ b/dev-tools/idea/solr/contrib/solr-morphlines-cell/solr-morphlines-cell.iml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev-tools/idea/solr/contrib/solr-morphlines-core/solr-morphlines-core.iml b/dev-tools/idea/solr/contrib/solr-morphlines-core/solr-morphlines-core.iml new file mode 100644 index 00000000000..4942c8565a8 --- /dev/null +++ b/dev-tools/idea/solr/contrib/solr-morphlines-core/solr-morphlines-core.iml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev-tools/idea/solr/contrib/solr-mr/solr-mr.iml b/dev-tools/idea/solr/contrib/solr-mr/solr-mr.iml new file mode 100644 index 00000000000..3e7e3b466e0 --- /dev/null +++ b/dev-tools/idea/solr/contrib/solr-mr/solr-mr.iml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev-tools/maven/solr/contrib/pom.xml.template b/dev-tools/maven/solr/contrib/pom.xml.template index b0f9bc8606c..3873b1d59ab 100644 --- a/dev-tools/maven/solr/contrib/pom.xml.template +++ b/dev-tools/maven/solr/contrib/pom.xml.template @@ -37,6 +37,9 @@ dataimporthandler-extras extraction langid + solr-morphlines-cell + solr-morphlines-core + solr-mr uima velocity diff --git a/dev-tools/maven/solr/contrib/solr-morphlines-cell/pom.xml.template b/dev-tools/maven/solr/contrib/solr-morphlines-cell/pom.xml.template new file mode 100644 index 00000000000..ebd13754c25 --- /dev/null +++ b/dev-tools/maven/solr/contrib/solr-morphlines-cell/pom.xml.template @@ -0,0 +1,104 @@ + + + 4.0.0 + + org.apache.solr + solr-parent + @version@ + ../../pom.xml + + org.apache.solr + solr-morphlines-cell + jar + Apache Solr Cell Morphlines + Apache Solr - Cell Morphlines + + solr/contrib/solr-morphlines-cell + ../../../.. + ${relative-top-level}/${module-directory} + + + scm:svn:${vc-anonymous-base-url}/${module-directory} + scm:svn:${vc-dev-base-url}/${module-directory} + ${vc-browse-base-url}/${module-directory} + + + + + + + org.apache.lucene + lucene-test-framework + test + + + org.apache.solr + solr-test-framework + test + + + org.apache.solr + solr-morphlines-core + ${project.version} + test-jar + test + +@solr-morphlines-cell.internal.dependencies@ +@solr-morphlines-cell.external.dependencies@ +@solr-morphlines-cell.internal.test.dependencies@ +@solr-morphlines-cell.external.test.dependencies@ + + + ${module-path}/src/java + ${module-path}/src/test + + + ${module-path}/src/test-files + + + ${top-level}/dev-tools/maven/solr + + maven.testlogging.properties + + + + + + de.thetaphi + forbiddenapis + + + test-check-forbidden-servlet-api + + + ${top-level}/lucene/tools/forbiddenApis/servlet-api.txt + + + + testCheck + + + + + + + diff --git a/dev-tools/maven/solr/contrib/solr-morphlines-core/pom.xml.template b/dev-tools/maven/solr/contrib/solr-morphlines-core/pom.xml.template new file mode 100644 index 00000000000..92c785c23e5 --- /dev/null +++ b/dev-tools/maven/solr/contrib/solr-morphlines-core/pom.xml.template @@ -0,0 +1,108 @@ + + + 4.0.0 + + org.apache.solr + solr-parent + @version@ + ../../pom.xml + + org.apache.solr + solr-morphlines-core + jar + Apache Solr Morphlines Core + Apache Solr - Morphlines Core + + solr/contrib/solr-morphlines-core + ../../../.. + ${relative-top-level}/${module-directory} + + + scm:svn:${vc-anonymous-base-url}/${module-directory} + scm:svn:${vc-dev-base-url}/${module-directory} + ${vc-browse-base-url}/${module-directory} + + + + + + + org.apache.lucene + lucene-test-framework + test + + + org.apache.solr + solr-test-framework + test + +@solr-morphlines-core.internal.dependencies@ +@solr-morphlines-core.external.dependencies@ +@solr-morphlines-core.internal.test.dependencies@ +@solr-morphlines-core.external.test.dependencies@ + + + ${module-path}/src/java + ${module-path}/src/test + + + ${module-path}/src/test-files + + + ${top-level}/dev-tools/maven/solr + + maven.testlogging.properties + + + + + + de.thetaphi + forbiddenapis + + + test-check-forbidden-servlet-api + + + ${top-level}/lucene/tools/forbiddenApis/servlet-api.txt + + + + testCheck + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + test-jar + + + + + + + diff --git a/dev-tools/maven/solr/contrib/solr-mr/pom.xml.template b/dev-tools/maven/solr/contrib/solr-mr/pom.xml.template new file mode 100644 index 00000000000..1683ef2c586 --- /dev/null +++ b/dev-tools/maven/solr/contrib/solr-mr/pom.xml.template @@ -0,0 +1,97 @@ + + + 4.0.0 + + org.apache.solr + solr-parent + @version@ + ../../pom.xml + + org.apache.solr + solr-mr + jar + Apache Solr map-reduce index construction + Apache Solr - map-reduce index construction + + solr/contrib/solr-mr + ../../../.. + ${relative-top-level}/${module-directory} + + + scm:svn:${vc-anonymous-base-url}/${module-directory} + scm:svn:${vc-dev-base-url}/${module-directory} + ${vc-browse-base-url}/${module-directory} + + + + + + + org.apache.lucene + lucene-test-framework + test + + + org.apache.solr + solr-test-framework + test + +@solr-mr.internal.dependencies@ +@solr-mr.external.dependencies@ +@solr-mr.internal.test.dependencies@ +@solr-mr.external.test.dependencies@ + + + ${module-path}/src/java + ${module-path}/src/test + + + ${module-path}/src/test-files + + + ${top-level}/dev-tools/maven/solr + + maven.testlogging.properties + + + + + + de.thetaphi + forbiddenapis + + + test-check-forbidden-servlet-api + + + ${top-level}/lucene/tools/forbiddenApis/servlet-api.txt + + + + testCheck + + + + + + + diff --git a/dev-tools/maven/solr/pom.xml.template b/dev-tools/maven/solr/pom.xml.template index 7554d6987ff..73ceda700b5 100644 --- a/dev-tools/maven/solr/pom.xml.template +++ b/dev-tools/maven/solr/pom.xml.template @@ -81,6 +81,11 @@ Public online Restlet repository http://maven.restlet.org + + releases.cloudera.com + Cloudera Releases + https://repository.cloudera.com/artifactory/libs-release + diff --git a/lucene/common-build.xml b/lucene/common-build.xml index a99239d135f..938813c536b 100644 --- a/lucene/common-build.xml +++ b/lucene/common-build.xml @@ -355,7 +355,7 @@ - @@ -623,6 +623,7 @@ value="The Apache Software Foundation"/> + diff --git a/lucene/ivy-settings.xml b/lucene/ivy-settings.xml index f7b24ad4562..4b8b8c57a5c 100644 --- a/lucene/ivy-settings.xml +++ b/lucene/ivy-settings.xml @@ -33,6 +33,8 @@ + + @@ -53,6 +55,8 @@ + + diff --git a/lucene/ivy-versions.properties b/lucene/ivy-versions.properties index a71f538dc51..a340d2bbdae 100644 --- a/lucene/ivy-versions.properties +++ b/lucene/ivy-versions.properties @@ -2,23 +2,63 @@ # Blank lines, comment lines, and keys that aren't in /org/name format are ignored # when the lexical sort check is performed by the ant check-lib-versions target. + +/aopalliance/aopalliance = 1.0 +/asm/asm = 3.1 /cglib/cglib-nodep = 2.2 +/com.adobe.xmp/xmpcore = 5.1.2 com.carrotsearch.randomizedtesting.version = 2.0.13 /com.carrotsearch.randomizedtesting/junit4-ant = ${com.carrotsearch.randomizedtesting.version} /com.carrotsearch.randomizedtesting/randomizedtesting-runner = ${com.carrotsearch.randomizedtesting.version} /com.carrotsearch/hppc = 0.5.2 + +com.cloudera.cdk.cdk-morphlines.version = 0.8.1 +/com.cloudera.cdk/cdk-morphlines-avro = ${com.cloudera.cdk.cdk-morphlines.version} +/com.cloudera.cdk/cdk-morphlines-core = ${com.cloudera.cdk.cdk-morphlines.version} +/com.cloudera.cdk/cdk-morphlines-hadoop-sequencefile = ${com.cloudera.cdk.cdk-morphlines.version} +/com.cloudera.cdk/cdk-morphlines-json = ${com.cloudera.cdk.cdk-morphlines.version} +/com.cloudera.cdk/cdk-morphlines-saxon = ${com.cloudera.cdk.cdk-morphlines.version} +/com.cloudera.cdk/cdk-morphlines-tika-core = ${com.cloudera.cdk.cdk-morphlines.version} +/com.cloudera.cdk/cdk-morphlines-tika-decompress = ${com.cloudera.cdk.cdk-morphlines.version} +/com.cloudera.cdk/cdk-morphlines-twitter = ${com.cloudera.cdk.cdk-morphlines.version} + +com.codahale.metrics.version = 3.0.1 +/com.codahale.metrics/metrics-core = ${com.codahale.metrics.version} +/com.codahale.metrics/metrics-healthchecks = ${com.codahale.metrics.version} + /com.cybozu.labs/langdetect = 1.1-20120112 /com.drewnoakes/metadata-extractor = 2.6.2 + +com.fasterxml.jackson.core.version = 2.2.3 +/com.fasterxml.jackson.core/jackson-annotations = ${com.fasterxml.jackson.core.version} +/com.fasterxml.jackson.core/jackson-core = ${com.fasterxml.jackson.core.version} +/com.fasterxml.jackson.core/jackson-databind = ${com.fasterxml.jackson.core.version} + /com.google.guava/guava = 14.0.1 + +com.google.inject.guice.version = 3.0 +/com.google.inject.extensions/guice-servlet = ${com.google.inject.guice.version} +/com.google.inject/guice = ${com.google.inject.guice.version} + /com.google.protobuf/protobuf-java = 2.5.0 /com.googlecode.concurrentlinkedhashmap/concurrentlinkedhashmap-lru = 1.2 /com.googlecode.juniversalchardet/juniversalchardet = 1.0.3 /com.googlecode.mp4parser/isoparser = 1.0-RC-1 /com.ibm.icu/icu4j = 49.1 /com.spatial4j/spatial4j = 0.3 -/com.sun.jersey/jersey-core = 1.16 + +com.sun.jersey.version = 1.8 +/com.sun.jersey.contribs/jersey-guice = ${com.sun.jersey.version} +/com.sun.jersey/jersey-bundle = ${com.sun.jersey.version} +/com.sun.jersey/jersey-core = ${com.sun.jersey.version} +/com.sun.jersey/jersey-json = ${com.sun.jersey.version} +/com.sun.jersey/jersey-server = ${com.sun.jersey.version} + +/com.sun.xml.bind/jaxb-impl = 2.2.2 +/com.thoughtworks.paranamer/paranamer = 2.3 +/com.typesafe/config = 1.0.2 /commons-beanutils/commons-beanutils = 1.7.0 /commons-cli/commons-cli = 1.2 /commons-codec/commons-codec = 1.7 @@ -33,8 +73,10 @@ com.carrotsearch.randomizedtesting.version = 2.0.13 /dom4j/dom4j = 1.6.1 /edu.ucar/netcdf = 4.2-min /hsqldb/hsqldb = 1.8.0.10 +/io.netty/netty = 3.6.2.Final /jakarta-regexp/jakarta-regexp = 1.4 /javax.activation/activation = 1.1 +/javax.inject/javax.inject= 1 /javax.mail/mail = 1.4.1 /javax.servlet/javax.servlet-api = 3.0.1 /javax.servlet/servlet-api = 2.4 @@ -45,9 +87,12 @@ com.carrotsearch.randomizedtesting.version = 2.0.13 /mecab/mecab-ipadic = 2.7.0-20070801 /mecab/mecab-naist-jdic = 0.6.3b-20111013 /net.arnx/jsonic = 1.2.7 +/net.sf.saxon/Saxon-HE = 9.5.1-2 +/net.sourceforge.argparse4j/argparse4j = 0.4.0 /net.sourceforge.nekohtml/nekohtml = 1.9.17 /org.antlr/antlr-runtime = 3.5 /org.apache.ant/ant = 1.8.2 +/org.apache.avro/avro = 1.7.4 /org.apache.commons/commons-compress = 1.4.1 /org.apache.derby/derby = 10.9.1.0 @@ -57,18 +102,35 @@ org.apache.hadoop.version = 2.2.0 /org.apache.hadoop/hadoop-common = ${org.apache.hadoop.version} /org.apache.hadoop/hadoop-hdfs = ${org.apache.hadoop.version} +/org.apache.hadoop/hadoop-mapreduce-client-app = ${org.apache.hadoop.version} +/org.apache.hadoop/hadoop-mapreduce-client-common = ${org.apache.hadoop.version} +/org.apache.hadoop/hadoop-mapreduce-client-core = ${org.apache.hadoop.version} +/org.apache.hadoop/hadoop-mapreduce-client-hs = ${org.apache.hadoop.version} +/org.apache.hadoop/hadoop-mapreduce-client-jobclient = ${org.apache.hadoop.version} +/org.apache.hadoop/hadoop-mapreduce-client-shuffle = ${org.apache.hadoop.version} +/org.apache.hadoop/hadoop-yarn-api = ${org.apache.hadoop.version} +/org.apache.hadoop/hadoop-yarn-client = ${org.apache.hadoop.version} +/org.apache.hadoop/hadoop-yarn-common = ${org.apache.hadoop.version} +/org.apache.hadoop/hadoop-yarn-server = ${org.apache.hadoop.version} +/org.apache.hadoop/hadoop-yarn-server-common = ${org.apache.hadoop.version} +/org.apache.hadoop/hadoop-yarn-server-nodemanager = ${org.apache.hadoop.version} +/org.apache.hadoop/hadoop-yarn-server-resourcemanager = ${org.apache.hadoop.version} +/org.apache.hadoop/hadoop-yarn-server-tests = ${org.apache.hadoop.version} +/org.apache.hadoop/hadoop-yarn-server-web-proxy = ${org.apache.hadoop.version} + # The httpcore version is often different from the httpclient and httpmime versions, # so the httpcore version value should not share the same symbolic name with them. /org.apache.httpcomponents/httpclient = 4.2.6 /org.apache.httpcomponents/httpcore = 4.2.5 /org.apache.httpcomponents/httpmime = 4.2.6 -org.apache.james.apache.mime4j = 0.7.2 -/org.apache.james/apache-mime4j-core = ${org.apache.james.apache.mime4j} -/org.apache.james/apache-mime4j-dom = ${org.apache.james.apache.mime4j} +org.apache.james.apache.mime4j.version = 0.7.2 +/org.apache.james/apache-mime4j-core = ${org.apache.james.apache.mime4j.version} +/org.apache.james/apache-mime4j-dom = ${org.apache.james.apache.mime4j.version} /org.apache.mahout/mahout-collections = 1.0 /org.apache.mahout/mahout-math = 0.6 +/org.apache.mrunit/mrunit = 1.0.0 org.apache.pdfbox.version = 1.8.1 /org.apache.pdfbox/fontbox = ${org.apache.pdfbox.version} @@ -84,6 +146,7 @@ org.apache.poi.version = 3.9 org.apache.tika.version = 1.4 /org.apache.tika/tika-core = ${org.apache.tika.version} /org.apache.tika/tika-parsers = ${org.apache.tika.version} +/org.apache.tika/tika-xmp = ${org.apache.tika.version} org.apache.uima.version = 2.3.1 /org.apache.uima/AlchemyAPIAnnotator = ${org.apache.uima.version} @@ -96,6 +159,7 @@ org.apache.uima.version = 2.3.1 /org.apache.velocity/velocity-tools = 2.0 /org.apache.xmlbeans/xmlbeans = 2.3.0 /org.apache.zookeeper/zookeeper = 3.4.5 +/org.aspectj/aspectjrt = 1.6.11 org.bouncycastle.version = 1.45 /org.bouncycastle/bcmail-jdk15 = ${org.bouncycastle.version} @@ -111,8 +175,9 @@ org.carrot2.morfologik.version = 1.7.1 /org.ccil.cowan.tagsoup/tagsoup = 1.2.1 -org.codehaus.jackson.version = 1.7.4 +org.codehaus.jackson.version = 1.9.13 /org.codehaus.jackson/jackson-core-asl = ${org.codehaus.jackson.version} +/org.codehaus.jackson/jackson-jaxrs = ${org.codehaus.jackson.version} /org.codehaus.jackson/jackson-mapper-asl = ${org.codehaus.jackson.version} /org.codehaus.woodstox/wstx-asl = 3.2.7 @@ -137,6 +202,8 @@ org.gagravarr.vorbis.java.version = 0.1 /org.gagravarr/vorbis-java-core = ${org.gagravarr.vorbis.java.version} /org.gagravarr/vorbis-java-tika = ${org.gagravarr.vorbis.java.version} +/org.mockito/mockito-core = 1.9.5 + org.mortbay.jetty.version = 6.1.26 /org.mortbay.jetty/jetty = ${org.mortbay.jetty.version} /org.mortbay.jetty/jetty-util = ${org.mortbay.jetty.version} @@ -161,5 +228,6 @@ org.slf4j.version = 1.6.6 /org.slf4j/slf4j-log4j12 = ${org.slf4j.version} /org.tukaani/xz = 1.0 +/org.xerial.snappy/snappy-java = 1.0.4.1 /rome/rome = 0.9 /xerces/xercesImpl = 2.9.1 diff --git a/lucene/tools/custom-tasks.xml b/lucene/tools/custom-tasks.xml index e17480b1d3c..e38b0b137a4 100644 --- a/lucene/tools/custom-tasks.xml +++ b/lucene/tools/custom-tasks.xml @@ -45,7 +45,7 @@ - + diff --git a/lucene/tools/junit4/tests.policy b/lucene/tools/junit4/tests.policy index 0933cab39bf..b1c4311e3b0 100644 --- a/lucene/tools/junit4/tests.policy +++ b/lucene/tools/junit4/tests.policy @@ -63,6 +63,7 @@ grant { permission javax.security.auth.PrivateCredentialPermission "org.apache.hadoop.security.Credentials * \"*\"", "read"; permission java.security.SecurityPermission "putProviderProperty.SaslPlainServer"; permission java.security.SecurityPermission "insertProvider.SaslPlainServer"; + permission javax.xml.bind.JAXBPermission "setDatatypeConverter"; // TIKA uses BouncyCastle and that registers new provider for PDF parsing + MSOffice parsing. Maybe report as bug! permission java.security.SecurityPermission "putProviderProperty.BC"; diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 9189b01c1d7..1e5f40d38a9 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -44,6 +44,15 @@ Upgrading from Solr 4.x Detailed Change List ---------------------- +New Features +---------------------- + +* SOLR-1301: Add a Solr contrib that allows for building Solr indexes via + Hadoop's MapReduce. (Matt Revelle, Alexander Kanarsky, Steve Rowe, + Mark Miller, Greg Bowyer, Jason Rutherglen, Kris Jirapinyo, Jason Venner , + Andrzej Bialecki, Patrick Hunt, Wolfgang Hoschek, Roman Shaposhnik, + Eric Wong) + Other Changes ---------------------- diff --git a/solr/contrib/extraction/ivy.xml b/solr/contrib/extraction/ivy.xml index 40e5201f60d..263c48832c9 100644 --- a/solr/contrib/extraction/ivy.xml +++ b/solr/contrib/extraction/ivy.xml @@ -22,6 +22,7 @@ + @@ -44,12 +45,19 @@ + + + + + + + diff --git a/solr/contrib/extraction/src/java/org/apache/solr/handler/extraction/SolrContentHandlerFactory.java b/solr/contrib/extraction/src/java/org/apache/solr/handler/extraction/SolrContentHandlerFactory.java index c91dd47306f..acf94a2d801 100644 --- a/solr/contrib/extraction/src/java/org/apache/solr/handler/extraction/SolrContentHandlerFactory.java +++ b/solr/contrib/extraction/src/java/org/apache/solr/handler/extraction/SolrContentHandlerFactory.java @@ -1,4 +1,4 @@ -/* +/** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. diff --git a/solr/contrib/solr-morphlines-cell/build.xml b/solr/contrib/solr-morphlines-cell/build.xml new file mode 100644 index 00000000000..e0da709634a --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/build.xml @@ -0,0 +1,143 @@ + + + + + + + + Solr Cell Morphline commands. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-cell/ivy.xml b/solr/contrib/solr-morphlines-cell/ivy.xml new file mode 100644 index 00000000000..ee652bd8363 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/ivy.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-cell/src/java/org/apache/solr/morphlines/cell/SolrCellBuilder.java b/solr/contrib/solr-morphlines-cell/src/java/org/apache/solr/morphlines/cell/SolrCellBuilder.java new file mode 100644 index 00000000000..8d5873fe4e3 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/java/org/apache/solr/morphlines/cell/SolrCellBuilder.java @@ -0,0 +1,344 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.morphlines.cell; + +import java.io.IOException; +import java.io.InputStream; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Map.Entry; +import java.util.TreeMap; + +import org.apache.solr.common.SolrInputDocument; +import org.apache.solr.common.SolrInputField; +import org.apache.solr.common.params.MultiMapSolrParams; +import org.apache.solr.common.params.SolrParams; +import org.apache.solr.common.util.DateUtil; +import org.apache.solr.handler.extraction.ExtractingParams; +import org.apache.solr.handler.extraction.SolrContentHandler; +import org.apache.solr.handler.extraction.SolrContentHandlerFactory; +import org.apache.solr.morphlines.solr.SolrLocator; +import org.apache.solr.schema.IndexSchema; +import org.apache.tika.exception.TikaException; +import org.apache.tika.io.TikaInputStream; +import org.apache.tika.metadata.Metadata; +import org.apache.tika.mime.MediaType; +import org.apache.tika.parser.ParseContext; +import org.apache.tika.parser.Parser; +import org.apache.tika.sax.TeeContentHandler; +import org.apache.tika.sax.XHTMLContentHandler; +import org.apache.tika.sax.xpath.Matcher; +import org.apache.tika.sax.xpath.MatchingContentHandler; +import org.apache.tika.sax.xpath.XPathParser; +import org.apache.xml.serialize.OutputFormat; +import org.apache.xml.serialize.XMLSerializer; +import org.xml.sax.ContentHandler; +import org.xml.sax.SAXException; + +import com.cloudera.cdk.morphline.api.Command; +import com.cloudera.cdk.morphline.api.CommandBuilder; +import com.cloudera.cdk.morphline.api.MorphlineCompilationException; +import com.cloudera.cdk.morphline.api.MorphlineContext; +import com.cloudera.cdk.morphline.api.MorphlineRuntimeException; +import com.cloudera.cdk.morphline.api.Record; +import com.cloudera.cdk.morphline.base.Fields; +import com.cloudera.cdk.morphline.stdio.AbstractParser; +import com.google.common.base.Joiner; +import com.google.common.base.Preconditions; +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.ListMultimap; +import com.google.common.io.Closeables; +import com.typesafe.config.Config; + +/** + * Command that pipes the first attachment of a record into one of the given Tika parsers, then maps + * the Tika output back to a record using SolrCell. + *

    + * The Tika parser is chosen from the configurable list of parsers, depending on the MIME type + * specified in the input record. Typically, this requires an upstream DetectMimeTypeBuilder + * in a prior command. + */ +public final class SolrCellBuilder implements CommandBuilder { + + @Override + public Collection getNames() { + return Collections.singletonList("solrCell"); + } + + @Override + public Command build(Config config, Command parent, Command child, MorphlineContext context) { + return new SolrCell(config, parent, child, context); + } + + + /////////////////////////////////////////////////////////////////////////////// + // Nested classes: + /////////////////////////////////////////////////////////////////////////////// + private static final class SolrCell extends AbstractParser { + + private final IndexSchema schema; + private final List dateFormats; + private final String xpathExpr; + private final List parsers = new ArrayList(); + private final SolrContentHandlerFactory solrContentHandlerFactory; + + private final SolrParams solrParams; + private final Map mediaTypeToParserMap; + + private static final XPathParser PARSER = new XPathParser("xhtml", XHTMLContentHandler.XHTML); + + public static final String ADDITIONAL_SUPPORTED_MIME_TYPES = "additionalSupportedMimeTypes"; + + public SolrCell(Config config, Command parent, Command child, MorphlineContext context) { + super(config, parent, child, context); + + Config solrLocatorConfig = getConfigs().getConfig(config, "solrLocator"); + SolrLocator locator = new SolrLocator(solrLocatorConfig, context); + LOG.debug("solrLocator: {}", locator); + this.schema = locator.getIndexSchema(); + Preconditions.checkNotNull(schema); + LOG.trace("Solr schema: \n{}", Joiner.on("\n").join(new TreeMap(schema.getFields()).values())); + + ListMultimap cellParams = ArrayListMultimap.create(); + String uprefix = getConfigs().getString(config, ExtractingParams.UNKNOWN_FIELD_PREFIX, null); + if (uprefix != null) { + cellParams.put(ExtractingParams.UNKNOWN_FIELD_PREFIX, uprefix); + } + for (String capture : getConfigs().getStringList(config, ExtractingParams.CAPTURE_ELEMENTS, Collections.EMPTY_LIST)) { + cellParams.put(ExtractingParams.CAPTURE_ELEMENTS, capture); + } + Config fmapConfig = getConfigs().getConfig(config, "fmap", null); + if (fmapConfig != null) { + for (Map.Entry entry : fmapConfig.root().unwrapped().entrySet()) { + cellParams.put(ExtractingParams.MAP_PREFIX + entry.getKey(), entry.getValue().toString()); + } + } + String captureAttributes = getConfigs().getString(config, ExtractingParams.CAPTURE_ATTRIBUTES, null); + if (captureAttributes != null) { + cellParams.put(ExtractingParams.CAPTURE_ATTRIBUTES, captureAttributes); + } + String lowerNames = getConfigs().getString(config, ExtractingParams.LOWERNAMES, null); + if (lowerNames != null) { + cellParams.put(ExtractingParams.LOWERNAMES, lowerNames); + } + String defaultField = getConfigs().getString(config, ExtractingParams.DEFAULT_FIELD, null); + if (defaultField != null) { + cellParams.put(ExtractingParams.DEFAULT_FIELD, defaultField); + } + xpathExpr = getConfigs().getString(config, ExtractingParams.XPATH_EXPRESSION, null); + if (xpathExpr != null) { + cellParams.put(ExtractingParams.XPATH_EXPRESSION, xpathExpr); + } + + this.dateFormats = getConfigs().getStringList(config, "dateFormats", new ArrayList(DateUtil.DEFAULT_DATE_FORMATS)); + + String handlerStr = getConfigs().getString(config, "solrContentHandlerFactory", TrimSolrContentHandlerFactory.class.getName()); + Class factoryClass; + try { + factoryClass = (Class)Class.forName(handlerStr); + } catch (ClassNotFoundException cnfe) { + throw new MorphlineCompilationException("Could not find class " + + handlerStr + " to use for " + "solrContentHandlerFactory", config, cnfe); + } + this.solrContentHandlerFactory = getSolrContentHandlerFactory(factoryClass, dateFormats, config); + + this.mediaTypeToParserMap = new HashMap(); + //MimeTypes mimeTypes = MimeTypes.getDefaultMimeTypes(); // FIXME getMediaTypeRegistry.normalize() + + List parserConfigs = getConfigs().getConfigList(config, "parsers"); + for (Config parserConfig : parserConfigs) { + String parserClassName = getConfigs().getString(parserConfig, "parser"); + + Object obj; + try { + obj = Class.forName(parserClassName).newInstance(); + } catch (Throwable e) { + throw new MorphlineCompilationException("Cannot instantiate Tika parser: " + parserClassName, config, e); + } + if (!(obj instanceof Parser)) { + throw new MorphlineCompilationException("Tika parser " + obj.getClass().getName() + + " must be an instance of class " + Parser.class.getName(), config); + } + Parser parser = (Parser) obj; + this.parsers.add(parser); + + List mediaTypes = getConfigs().getStringList(parserConfig, SUPPORTED_MIME_TYPES, Collections.EMPTY_LIST); + for (String mediaTypeStr : mediaTypes) { + MediaType mediaType = parseMediaType(mediaTypeStr); + addSupportedMimeType(mediaTypeStr); + this.mediaTypeToParserMap.put(mediaType, parser); + } + + if (!parserConfig.hasPath(SUPPORTED_MIME_TYPES)) { + for (MediaType mediaType : parser.getSupportedTypes(new ParseContext())) { + mediaType = mediaType.getBaseType(); + addSupportedMimeType(mediaType.toString()); + this.mediaTypeToParserMap.put(mediaType, parser); + } + List extras = getConfigs().getStringList(parserConfig, ADDITIONAL_SUPPORTED_MIME_TYPES, Collections.EMPTY_LIST); + for (String mediaTypeStr : extras) { + MediaType mediaType = parseMediaType(mediaTypeStr); + addSupportedMimeType(mediaTypeStr); + this.mediaTypeToParserMap.put(mediaType, parser); + } + } + } + //LOG.info("mediaTypeToParserMap="+mediaTypeToParserMap); + + Map tmp = new HashMap(); + for (Map.Entry> entry : cellParams.asMap().entrySet()) { + tmp.put(entry.getKey(), entry.getValue().toArray(new String[entry.getValue().size()])); + } + this.solrParams = new MultiMapSolrParams(tmp); + validateArguments(); + } + + @Override + protected boolean doProcess(Record record, InputStream inputStream) { + Parser parser = detectParser(record); + if (parser == null) { + return false; + } + + ParseContext parseContext = new ParseContext(); + + // necessary for gzipped files or tar files, etc! copied from TikaCLI + parseContext.set(Parser.class, parser); + + Metadata metadata = new Metadata(); + for (Entry entry : record.getFields().entries()) { + metadata.add(entry.getKey(), entry.getValue().toString()); + } + + SolrContentHandler handler = solrContentHandlerFactory.createSolrContentHandler(metadata, solrParams, schema); + + try { + inputStream = TikaInputStream.get(inputStream); + + ContentHandler parsingHandler = handler; + StringWriter debugWriter = null; + if (LOG.isTraceEnabled()) { + debugWriter = new StringWriter(); + ContentHandler serializer = new XMLSerializer(debugWriter, new OutputFormat("XML", "UTF-8", true)); + parsingHandler = new TeeContentHandler(parsingHandler, serializer); + } + + // String xpathExpr = "/xhtml:html/xhtml:body/xhtml:div/descendant:node()"; + if (xpathExpr != null) { + Matcher matcher = PARSER.parse(xpathExpr); + parsingHandler = new MatchingContentHandler(parsingHandler, matcher); + } + + try { + parser.parse(inputStream, parsingHandler, metadata, parseContext); + } catch (IOException e) { + throw new MorphlineRuntimeException("Cannot parse", e); + } catch (SAXException e) { + throw new MorphlineRuntimeException("Cannot parse", e); + } catch (TikaException e) { + throw new MorphlineRuntimeException("Cannot parse", e); + } + + LOG.trace("debug XML doc: {}", debugWriter); + } finally { + if (inputStream != null) { + Closeables.closeQuietly(inputStream); + } + } + + SolrInputDocument doc = handler.newDocument(); + LOG.debug("solr doc: {}", doc); + Record outputRecord = toRecord(doc); + return getChild().process(outputRecord); + } + + private Parser detectParser(Record record) { + if (!hasAtLeastOneMimeType(record)) { + return null; + } + String mediaTypeStr = (String) record.getFirstValue(Fields.ATTACHMENT_MIME_TYPE); //ExtractingParams.STREAM_TYPE); + assert mediaTypeStr != null; + + MediaType mediaType = parseMediaType(mediaTypeStr).getBaseType(); + Parser parser = mediaTypeToParserMap.get(mediaType); // fast path + if (parser != null) { + return parser; + } + // wildcard matching + for (Map.Entry entry : mediaTypeToParserMap.entrySet()) { + if (isMediaTypeMatch(mediaType, entry.getKey())) { + return entry.getValue(); + } + } + if (LOG.isDebugEnabled()) { + LOG.debug("No supported MIME type parser found for " + Fields.ATTACHMENT_MIME_TYPE + "=" + mediaTypeStr); + } + return null; + } + + private boolean hasAtLeastOneMimeType(Record record) { + if (!record.getFields().containsKey(Fields.ATTACHMENT_MIME_TYPE)) { + LOG.debug("Command failed because of missing MIME type for record: {}", record); + return false; + } + return true; + } + + private MediaType parseMediaType(String mediaTypeStr) { + MediaType mediaType = MediaType.parse(mediaTypeStr.trim().toLowerCase(Locale.ROOT)); + return mediaType.getBaseType(); + }; + + /** Returns true if mediaType falls withing the given range (pattern), false otherwise */ + private boolean isMediaTypeMatch(MediaType mediaType, MediaType rangePattern) { + String WILDCARD = "*"; + String rangePatternType = rangePattern.getType(); + String rangePatternSubtype = rangePattern.getSubtype(); + return (rangePatternType.equals(WILDCARD) || rangePatternType.equals(mediaType.getType())) + && (rangePatternSubtype.equals(WILDCARD) || rangePatternSubtype.equals(mediaType.getSubtype())); + } + + private static SolrContentHandlerFactory getSolrContentHandlerFactory( + Class factoryClass, Collection dateFormats, Config config) { + try { + return factoryClass.getConstructor(Collection.class).newInstance(dateFormats); + } catch (NoSuchMethodException nsme) { + throw new MorphlineCompilationException("Unable to find valid constructor of type " + + factoryClass.getName() + " for creating SolrContentHandler", config, nsme); + } catch (Exception e) { + throw new MorphlineCompilationException("Unexpected exception when trying to create SolrContentHandlerFactory of type " + + factoryClass.getName(), config, e); + } + } + + private Record toRecord(SolrInputDocument doc) { + Record record = new Record(); + for (Entry entry : doc.entrySet()) { + record.getFields().putAll(entry.getKey(), entry.getValue().getValues()); + } + return record; + } + + } + +} diff --git a/solr/contrib/solr-morphlines-cell/src/java/org/apache/solr/morphlines/cell/StripNonCharSolrContentHandlerFactory.java b/solr/contrib/solr-morphlines-cell/src/java/org/apache/solr/morphlines/cell/StripNonCharSolrContentHandlerFactory.java new file mode 100644 index 00000000000..81f49afd4e5 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/java/org/apache/solr/morphlines/cell/StripNonCharSolrContentHandlerFactory.java @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.morphlines.cell; + +import java.util.Collection; + +import org.apache.solr.common.params.SolrParams; +import org.apache.solr.handler.extraction.SolrContentHandler; +import org.apache.solr.handler.extraction.SolrContentHandlerFactory; +import org.apache.solr.schema.IndexSchema; +import org.apache.solr.schema.SchemaField; +import org.apache.tika.metadata.Metadata; + +/** + * {@link SolrContentHandler} and associated factory that strips non-characters and trims on output. + * This prevents exceptions on parsing integer fields inside Solr server. + */ +public class StripNonCharSolrContentHandlerFactory extends SolrContentHandlerFactory { + + public StripNonCharSolrContentHandlerFactory(Collection dateFormats) { + super(dateFormats); + } + + @Override + public SolrContentHandler createSolrContentHandler(Metadata metadata, SolrParams params, IndexSchema schema) { + return new StripNonCharSolrContentHandler(metadata, params, schema, dateFormats); + } + + + /////////////////////////////////////////////////////////////////////////////// + // Nested classes: + /////////////////////////////////////////////////////////////////////////////// + private static final class StripNonCharSolrContentHandler extends SolrContentHandler { + + public StripNonCharSolrContentHandler(Metadata metadata, SolrParams params, IndexSchema schema, Collection dateFormats) { + super(metadata, params, schema, dateFormats); + } + + /** + * Strip all non-characters, which can cause SolrReducer problems if present. + * This is borrowed from Apache Nutch. + */ + private static String stripNonCharCodepoints(String input) { + StringBuilder stripped = new StringBuilder(input.length()); + char ch; + for (int i = 0; i < input.length(); i++) { + ch = input.charAt(i); + // Strip all non-characters http://unicode.org/cldr/utility/list-unicodeset.jsp?a=[:Noncharacter_Code_Point=True:] + // and non-printable control characters except tabulator, new line and carriage return + if (ch % 0x10000 != 0xffff && // 0xffff - 0x10ffff range step 0x10000 + ch % 0x10000 != 0xfffe && // 0xfffe - 0x10fffe range + (ch <= 0xfdd0 || ch >= 0xfdef) && // 0xfdd0 - 0xfdef + (ch > 0x1F || ch == 0x9 || ch == 0xa || ch == 0xd)) { + stripped.append(ch); + } + } + return stripped.toString(); + } + + @Override + protected String transformValue(String val, SchemaField schemaField) { + String ret = super.transformValue(val, schemaField).trim(); + ret = stripNonCharCodepoints(ret); + return ret; + } + } +} diff --git a/solr/contrib/solr-morphlines-cell/src/java/org/apache/solr/morphlines/cell/TrimSolrContentHandlerFactory.java b/solr/contrib/solr-morphlines-cell/src/java/org/apache/solr/morphlines/cell/TrimSolrContentHandlerFactory.java new file mode 100644 index 00000000000..6e7df593ff8 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/java/org/apache/solr/morphlines/cell/TrimSolrContentHandlerFactory.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.morphlines.cell; + +import java.util.Collection; + +import org.apache.solr.common.params.SolrParams; +import org.apache.solr.handler.extraction.SolrContentHandler; +import org.apache.solr.handler.extraction.SolrContentHandlerFactory; +import org.apache.solr.schema.IndexSchema; +import org.apache.solr.schema.SchemaField; +import org.apache.tika.metadata.Metadata; + +/** + * {@link SolrContentHandler} and associated factory that trims field values on output. + * This prevents exceptions on parsing integer fields inside Solr server. + */ +public class TrimSolrContentHandlerFactory extends SolrContentHandlerFactory { + + public TrimSolrContentHandlerFactory(Collection dateFormats) { + super(dateFormats); + } + + @Override + public SolrContentHandler createSolrContentHandler(Metadata metadata, SolrParams params, IndexSchema schema) { + return new TrimSolrContentHandler(metadata, params, schema, dateFormats); + } + + + /////////////////////////////////////////////////////////////////////////////// + // Nested classes: + /////////////////////////////////////////////////////////////////////////////// + private static final class TrimSolrContentHandler extends SolrContentHandler { + + public TrimSolrContentHandler(Metadata metadata, SolrParams params, IndexSchema schema, Collection dateFormats) { + super(metadata, params, schema, dateFormats); + } + + @Override + protected String transformValue(String val, SchemaField schemaField) { + return super.transformValue(val, schemaField).trim(); + } + } +} diff --git a/solr/contrib/solr-morphlines-cell/src/java/org/apache/solr/morphlines/cell/package.html b/solr/contrib/solr-morphlines-cell/src/java/org/apache/solr/morphlines/cell/package.html new file mode 100644 index 00000000000..9d5daec89bb --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/java/org/apache/solr/morphlines/cell/package.html @@ -0,0 +1,22 @@ + + + + +Morphlines Solr Cell related code. + + diff --git a/solr/contrib/solr-morphlines-cell/src/java/overview.html b/solr/contrib/solr-morphlines-cell/src/java/overview.html new file mode 100644 index 00000000000..3e25367d302 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/java/overview.html @@ -0,0 +1,21 @@ + + + +Apache Solr Search Server: Solr Cell Morphline Commands + + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/currency.xml b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/currency.xml new file mode 100644 index 00000000000..3a9c58afee8 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/currency.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/elevate.xml b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/elevate.xml new file mode 100644 index 00000000000..25d5cebe4fb --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/elevate.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/contractions_ca.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/contractions_ca.txt new file mode 100644 index 00000000000..307a85f913d --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/contractions_ca.txt @@ -0,0 +1,8 @@ +# Set of Catalan contractions for ElisionFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +d +l +m +n +s +t diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/contractions_fr.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/contractions_fr.txt new file mode 100644 index 00000000000..722db588333 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/contractions_fr.txt @@ -0,0 +1,9 @@ +# Set of French contractions for ElisionFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +l +m +t +qu +n +s +j diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/contractions_ga.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/contractions_ga.txt new file mode 100644 index 00000000000..9ebe7fa349a --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/contractions_ga.txt @@ -0,0 +1,5 @@ +# Set of Irish contractions for ElisionFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +d +m +b diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/contractions_it.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/contractions_it.txt new file mode 100644 index 00000000000..cac04095372 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/contractions_it.txt @@ -0,0 +1,23 @@ +# Set of Italian contractions for ElisionFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +c +l +all +dall +dell +nell +sull +coll +pell +gl +agl +dagl +degl +negl +sugl +un +m +t +s +v +d diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/hyphenations_ga.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/hyphenations_ga.txt new file mode 100644 index 00000000000..4d2642cc5a3 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/hyphenations_ga.txt @@ -0,0 +1,5 @@ +# Set of Irish hyphenations for StopFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +h +n +t diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stemdict_nl.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stemdict_nl.txt new file mode 100644 index 00000000000..441072971d3 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stemdict_nl.txt @@ -0,0 +1,6 @@ +# Set of overrides for the dutch stemmer +# TODO: load this as a resource from the analyzer and sync it in build.xml +fiets fiets +bromfiets bromfiets +ei eier +kind kinder diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stoptags_ja.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stoptags_ja.txt new file mode 100644 index 00000000000..71b750845e3 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stoptags_ja.txt @@ -0,0 +1,420 @@ +# +# This file defines a Japanese stoptag set for JapanesePartOfSpeechStopFilter. +# +# Any token with a part-of-speech tag that exactly matches those defined in this +# file are removed from the token stream. +# +# Set your own stoptags by uncommenting the lines below. Note that comments are +# not allowed on the same line as a stoptag. See LUCENE-3745 for frequency lists, +# etc. that can be useful for building you own stoptag set. +# +# The entire possible tagset is provided below for convenience. +# +##### +# noun: unclassified nouns +#名詞 +# +# noun-common: Common nouns or nouns where the sub-classification is undefined +#名詞-一般 +# +# noun-proper: Proper nouns where the sub-classification is undefined +#名詞-固有名詞 +# +# noun-proper-misc: miscellaneous proper nouns +#名詞-固有名詞-一般 +# +# noun-proper-person: Personal names where the sub-classification is undefined +#名詞-固有名詞-人名 +# +# noun-proper-person-misc: names that cannot be divided into surname and +# given name; foreign names; names where the surname or given name is unknown. +# e.g. お市の方 +#名詞-固有名詞-人名-一般 +# +# noun-proper-person-surname: Mainly Japanese surnames. +# e.g. 山田 +#名詞-固有名詞-人名-姓 +# +# noun-proper-person-given_name: Mainly Japanese given names. +# e.g. 太郎 +#名詞-固有名詞-人名-名 +# +# noun-proper-organization: Names representing organizations. +# e.g. 通産省, NHK +#名詞-固有名詞-組織 +# +# noun-proper-place: Place names where the sub-classification is undefined +#名詞-固有名詞-地域 +# +# noun-proper-place-misc: Place names excluding countries. +# e.g. アジア, バルセロナ, 京都 +#名詞-固有名詞-地域-一般 +# +# noun-proper-place-country: Country names. +# e.g. 日本, オーストラリア +#名詞-固有名詞-地域-国 +# +# noun-pronoun: Pronouns where the sub-classification is undefined +#名詞-代名詞 +# +# noun-pronoun-misc: miscellaneous pronouns: +# e.g. それ, ここ, あいつ, あなた, あちこち, いくつ, どこか, なに, みなさん, みんな, わたくし, われわれ +#名詞-代名詞-一般 +# +# noun-pronoun-contraction: Spoken language contraction made by combining a +# pronoun and the particle 'wa'. +# e.g. ありゃ, こりゃ, こりゃあ, そりゃ, そりゃあ +#名詞-代名詞-縮約 +# +# noun-adverbial: Temporal nouns such as names of days or months that behave +# like adverbs. Nouns that represent amount or ratios and can be used adverbially, +# e.g. 金曜, 一月, 午後, 少量 +#名詞-副詞可能 +# +# noun-verbal: Nouns that take arguments with case and can appear followed by +# 'suru' and related verbs (する, できる, なさる, くださる) +# e.g. インプット, 愛着, 悪化, 悪戦苦闘, 一安心, 下取り +#名詞-サ変接続 +# +# noun-adjective-base: The base form of adjectives, words that appear before な ("na") +# e.g. 健康, 安易, 駄目, だめ +#名詞-形容動詞語幹 +# +# noun-numeric: Arabic numbers, Chinese numerals, and counters like 何 (回), 数. +# e.g. 0, 1, 2, 何, 数, 幾 +#名詞-数 +# +# noun-affix: noun affixes where the sub-classification is undefined +#名詞-非自立 +# +# noun-affix-misc: Of adnominalizers, the case-marker の ("no"), and words that +# attach to the base form of inflectional words, words that cannot be classified +# into any of the other categories below. This category includes indefinite nouns. +# e.g. あかつき, 暁, かい, 甲斐, 気, きらい, 嫌い, くせ, 癖, こと, 事, ごと, 毎, しだい, 次第, +# 順, せい, 所為, ついで, 序で, つもり, 積もり, 点, どころ, の, はず, 筈, はずみ, 弾み, +# 拍子, ふう, ふり, 振り, ほう, 方, 旨, もの, 物, 者, ゆえ, 故, ゆえん, 所以, わけ, 訳, +# わり, 割り, 割, ん-口語/, もん-口語/ +#名詞-非自立-一般 +# +# noun-affix-adverbial: noun affixes that that can behave as adverbs. +# e.g. あいだ, 間, あげく, 挙げ句, あと, 後, 余り, 以外, 以降, 以後, 以上, 以前, 一方, うえ, +# 上, うち, 内, おり, 折り, かぎり, 限り, きり, っきり, 結果, ころ, 頃, さい, 際, 最中, さなか, +# 最中, じたい, 自体, たび, 度, ため, 為, つど, 都度, とおり, 通り, とき, 時, ところ, 所, +# とたん, 途端, なか, 中, のち, 後, ばあい, 場合, 日, ぶん, 分, ほか, 他, まえ, 前, まま, +# 儘, 侭, みぎり, 矢先 +#名詞-非自立-副詞可能 +# +# noun-affix-aux: noun affixes treated as 助動詞 ("auxiliary verb") in school grammars +# with the stem よう(だ) ("you(da)"). +# e.g. よう, やう, 様 (よう) +#名詞-非自立-助動詞語幹 +# +# noun-affix-adjective-base: noun affixes that can connect to the indeclinable +# connection form な (aux "da"). +# e.g. みたい, ふう +#名詞-非自立-形容動詞語幹 +# +# noun-special: special nouns where the sub-classification is undefined. +#名詞-特殊 +# +# noun-special-aux: The そうだ ("souda") stem form that is used for reporting news, is +# treated as 助動詞 ("auxiliary verb") in school grammars, and attach to the base +# form of inflectional words. +# e.g. そう +#名詞-特殊-助動詞語幹 +# +# noun-suffix: noun suffixes where the sub-classification is undefined. +#名詞-接尾 +# +# noun-suffix-misc: Of the nouns or stem forms of other parts of speech that connect +# to ガル or タイ and can combine into compound nouns, words that cannot be classified into +# any of the other categories below. In general, this category is more inclusive than +# 接尾語 ("suffix") and is usually the last element in a compound noun. +# e.g. おき, かた, 方, 甲斐 (がい), がかり, ぎみ, 気味, ぐるみ, (~した) さ, 次第, 済 (ず) み, +# よう, (でき)っこ, 感, 観, 性, 学, 類, 面, 用 +#名詞-接尾-一般 +# +# noun-suffix-person: Suffixes that form nouns and attach to person names more often +# than other nouns. +# e.g. 君, 様, 著 +#名詞-接尾-人名 +# +# noun-suffix-place: Suffixes that form nouns and attach to place names more often +# than other nouns. +# e.g. 町, 市, 県 +#名詞-接尾-地域 +# +# noun-suffix-verbal: Of the suffixes that attach to nouns and form nouns, those that +# can appear before スル ("suru"). +# e.g. 化, 視, 分け, 入り, 落ち, 買い +#名詞-接尾-サ変接続 +# +# noun-suffix-aux: The stem form of そうだ (様態) that is used to indicate conditions, +# is treated as 助動詞 ("auxiliary verb") in school grammars, and attach to the +# conjunctive form of inflectional words. +# e.g. そう +#名詞-接尾-助動詞語幹 +# +# noun-suffix-adjective-base: Suffixes that attach to other nouns or the conjunctive +# form of inflectional words and appear before the copula だ ("da"). +# e.g. 的, げ, がち +#名詞-接尾-形容動詞語幹 +# +# noun-suffix-adverbial: Suffixes that attach to other nouns and can behave as adverbs. +# e.g. 後 (ご), 以後, 以降, 以前, 前後, 中, 末, 上, 時 (じ) +#名詞-接尾-副詞可能 +# +# noun-suffix-classifier: Suffixes that attach to numbers and form nouns. This category +# is more inclusive than 助数詞 ("classifier") and includes common nouns that attach +# to numbers. +# e.g. 個, つ, 本, 冊, パーセント, cm, kg, カ月, か国, 区画, 時間, 時半 +#名詞-接尾-助数詞 +# +# noun-suffix-special: Special suffixes that mainly attach to inflecting words. +# e.g. (楽し) さ, (考え) 方 +#名詞-接尾-特殊 +# +# noun-suffix-conjunctive: Nouns that behave like conjunctions and join two words +# together. +# e.g. (日本) 対 (アメリカ), 対 (アメリカ), (3) 対 (5), (女優) 兼 (主婦) +#名詞-接続詞的 +# +# noun-verbal_aux: Nouns that attach to the conjunctive particle て ("te") and are +# semantically verb-like. +# e.g. ごらん, ご覧, 御覧, 頂戴 +#名詞-動詞非自立的 +# +# noun-quotation: text that cannot be segmented into words, proverbs, Chinese poetry, +# dialects, English, etc. Currently, the only entry for 名詞 引用文字列 ("noun quotation") +# is いわく ("iwaku"). +#名詞-引用文字列 +# +# noun-nai_adjective: Words that appear before the auxiliary verb ない ("nai") and +# behave like an adjective. +# e.g. 申し訳, 仕方, とんでも, 違い +#名詞-ナイ形容詞語幹 +# +##### +# prefix: unclassified prefixes +#接頭詞 +# +# prefix-nominal: Prefixes that attach to nouns (including adjective stem forms) +# excluding numerical expressions. +# e.g. お (水), 某 (氏), 同 (社), 故 (~氏), 高 (品質), お (見事), ご (立派) +#接頭詞-名詞接続 +# +# prefix-verbal: Prefixes that attach to the imperative form of a verb or a verb +# in conjunctive form followed by なる/なさる/くださる. +# e.g. お (読みなさい), お (座り) +#接頭詞-動詞接続 +# +# prefix-adjectival: Prefixes that attach to adjectives. +# e.g. お (寒いですねえ), バカ (でかい) +#接頭詞-形容詞接続 +# +# prefix-numerical: Prefixes that attach to numerical expressions. +# e.g. 約, およそ, 毎時 +#接頭詞-数接続 +# +##### +# verb: unclassified verbs +#動詞 +# +# verb-main: +#動詞-自立 +# +# verb-auxiliary: +#動詞-非自立 +# +# verb-suffix: +#動詞-接尾 +# +##### +# adjective: unclassified adjectives +#形容詞 +# +# adjective-main: +#形容詞-自立 +# +# adjective-auxiliary: +#形容詞-非自立 +# +# adjective-suffix: +#形容詞-接尾 +# +##### +# adverb: unclassified adverbs +#副詞 +# +# adverb-misc: Words that can be segmented into one unit and where adnominal +# modification is not possible. +# e.g. あいかわらず, 多分 +#副詞-一般 +# +# adverb-particle_conjunction: Adverbs that can be followed by の, は, に, +# な, する, だ, etc. +# e.g. こんなに, そんなに, あんなに, なにか, なんでも +#副詞-助詞類接続 +# +##### +# adnominal: Words that only have noun-modifying forms. +# e.g. この, その, あの, どの, いわゆる, なんらかの, 何らかの, いろんな, こういう, そういう, ああいう, +# どういう, こんな, そんな, あんな, どんな, 大きな, 小さな, おかしな, ほんの, たいした, +# 「(, も) さる (ことながら)」, 微々たる, 堂々たる, 単なる, いかなる, 我が」「同じ, 亡き +#連体詞 +# +##### +# conjunction: Conjunctions that can occur independently. +# e.g. が, けれども, そして, じゃあ, それどころか +接続詞 +# +##### +# particle: unclassified particles. +助詞 +# +# particle-case: case particles where the subclassification is undefined. +助詞-格助詞 +# +# particle-case-misc: Case particles. +# e.g. から, が, で, と, に, へ, より, を, の, にて +助詞-格助詞-一般 +# +# particle-case-quote: the "to" that appears after nouns, a person’s speech, +# quotation marks, expressions of decisions from a meeting, reasons, judgements, +# conjectures, etc. +# e.g. ( だ) と (述べた.), ( である) と (して執行猶予...) +助詞-格助詞-引用 +# +# particle-case-compound: Compounds of particles and verbs that mainly behave +# like case particles. +# e.g. という, といった, とかいう, として, とともに, と共に, でもって, にあたって, に当たって, に当って, +# にあたり, に当たり, に当り, に当たる, にあたる, において, に於いて,に於て, における, に於ける, +# にかけ, にかけて, にかんし, に関し, にかんして, に関して, にかんする, に関する, に際し, +# に際して, にしたがい, に従い, に従う, にしたがって, に従って, にたいし, に対し, にたいして, +# に対して, にたいする, に対する, について, につき, につけ, につけて, につれ, につれて, にとって, +# にとり, にまつわる, によって, に依って, に因って, により, に依り, に因り, による, に依る, に因る, +# にわたって, にわたる, をもって, を以って, を通じ, を通じて, を通して, をめぐって, をめぐり, をめぐる, +# って-口語/, ちゅう-関西弁「という」/, (何) ていう (人)-口語/, っていう-口語/, といふ, とかいふ +助詞-格助詞-連語 +# +# particle-conjunctive: +# e.g. から, からには, が, けれど, けれども, けど, し, つつ, て, で, と, ところが, どころか, とも, ども, +# ながら, なり, ので, のに, ば, ものの, や ( した), やいなや, (ころん) じゃ(いけない)-口語/, +# (行っ) ちゃ(いけない)-口語/, (言っ) たって (しかたがない)-口語/, (それがなく)ったって (平気)-口語/ +助詞-接続助詞 +# +# particle-dependency: +# e.g. こそ, さえ, しか, すら, は, も, ぞ +助詞-係助詞 +# +# particle-adverbial: +# e.g. がてら, かも, くらい, 位, ぐらい, しも, (学校) じゃ(これが流行っている)-口語/, +# (それ)じゃあ (よくない)-口語/, ずつ, (私) なぞ, など, (私) なり (に), (先生) なんか (大嫌い)-口語/, +# (私) なんぞ, (先生) なんて (大嫌い)-口語/, のみ, だけ, (私) だって-口語/, だに, +# (彼)ったら-口語/, (お茶) でも (いかが), 等 (とう), (今後) とも, ばかり, ばっか-口語/, ばっかり-口語/, +# ほど, 程, まで, 迄, (誰) も (が)([助詞-格助詞] および [助詞-係助詞] の前に位置する「も」) +助詞-副助詞 +# +# particle-interjective: particles with interjective grammatical roles. +# e.g. (松島) や +助詞-間投助詞 +# +# particle-coordinate: +# e.g. と, たり, だの, だり, とか, なり, や, やら +助詞-並立助詞 +# +# particle-final: +# e.g. かい, かしら, さ, ぜ, (だ)っけ-口語/, (とまってる) で-方言/, な, ナ, なあ-口語/, ぞ, ね, ネ, +# ねぇ-口語/, ねえ-口語/, ねん-方言/, の, のう-口語/, や, よ, ヨ, よぉ-口語/, わ, わい-口語/ +助詞-終助詞 +# +# particle-adverbial/conjunctive/final: The particle "ka" when unknown whether it is +# adverbial, conjunctive, or sentence final. For example: +# (a) 「A か B か」. Ex:「(国内で運用する) か,(海外で運用する) か (.)」 +# (b) Inside an adverb phrase. Ex:「(幸いという) か (, 死者はいなかった.)」 +# 「(祈りが届いたせい) か (, 試験に合格した.)」 +# (c) 「かのように」. Ex:「(何もなかった) か (のように振る舞った.)」 +# e.g. か +助詞-副助詞/並立助詞/終助詞 +# +# particle-adnominalizer: The "no" that attaches to nouns and modifies +# non-inflectional words. +助詞-連体化 +# +# particle-adnominalizer: The "ni" and "to" that appear following nouns and adverbs +# that are giongo, giseigo, or gitaigo. +# e.g. に, と +助詞-副詞化 +# +# particle-special: A particle that does not fit into one of the above classifications. +# This includes particles that are used in Tanka, Haiku, and other poetry. +# e.g. かな, けむ, ( しただろう) に, (あんた) にゃ(わからん), (俺) ん (家) +助詞-特殊 +# +##### +# auxiliary-verb: +助動詞 +# +##### +# interjection: Greetings and other exclamations. +# e.g. おはよう, おはようございます, こんにちは, こんばんは, ありがとう, どうもありがとう, ありがとうございます, +# いただきます, ごちそうさま, さよなら, さようなら, はい, いいえ, ごめん, ごめんなさい +#感動詞 +# +##### +# symbol: unclassified Symbols. +記号 +# +# symbol-misc: A general symbol not in one of the categories below. +# e.g. [○◎@$〒→+] +記号-一般 +# +# symbol-comma: Commas +# e.g. [,、] +記号-読点 +# +# symbol-period: Periods and full stops. +# e.g. [..。] +記号-句点 +# +# symbol-space: Full-width whitespace. +記号-空白 +# +# symbol-open_bracket: +# e.g. [({‘“『【] +記号-括弧開 +# +# symbol-close_bracket: +# e.g. [)}’”』」】] +記号-括弧閉 +# +# symbol-alphabetic: +#記号-アルファベット +# +##### +# other: unclassified other +#その他 +# +# other-interjection: Words that are hard to classify as noun-suffixes or +# sentence-final particles. +# e.g. (だ)ァ +その他-間投 +# +##### +# filler: Aizuchi that occurs during a conversation or sounds inserted as filler. +# e.g. あの, うんと, えと +フィラー +# +##### +# non-verbal: non-verbal sound. +非言語音 +# +##### +# fragment: +#語断片 +# +##### +# unknown: unknown part of speech. +#未知語 +# +##### End of file diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ar.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ar.txt new file mode 100644 index 00000000000..046829db6a2 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ar.txt @@ -0,0 +1,125 @@ +# This file was created by Jacques Savoy and is distributed under the BSD license. +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# Also see http://www.opensource.org/licenses/bsd-license.html +# Cleaned on October 11, 2009 (not normalized, so use before normalization) +# This means that when modifying this list, you might need to add some +# redundant entries, for example containing forms with both أ and ا +من +ومن +منها +منه +في +وفي +فيها +فيه +و +ف +ثم +او +أو +ب +بها +به +ا +أ +اى +اي +أي +أى +لا +ولا +الا +ألا +إلا +لكن +ما +وما +كما +فما +عن +مع +اذا +إذا +ان +أن +إن +انها +أنها +إنها +انه +أنه +إنه +بان +بأن +فان +فأن +وان +وأن +وإن +التى +التي +الذى +الذي +الذين +الى +الي +إلى +إلي +على +عليها +عليه +اما +أما +إما +ايضا +أيضا +كل +وكل +لم +ولم +لن +ولن +هى +هي +هو +وهى +وهي +وهو +فهى +فهي +فهو +انت +أنت +لك +لها +له +هذه +هذا +تلك +ذلك +هناك +كانت +كان +يكون +تكون +وكانت +وكان +غير +بعض +قد +نحو +بين +بينما +منذ +ضمن +حيث +الان +الآن +خلال +بعد +قبل +حتى +عند +عندما +لدى +جميع diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_bg.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_bg.txt new file mode 100644 index 00000000000..1ae4ba2ae38 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_bg.txt @@ -0,0 +1,193 @@ +# This file was created by Jacques Savoy and is distributed under the BSD license. +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# Also see http://www.opensource.org/licenses/bsd-license.html +а +аз +ако +ала +бе +без +беше +би +бил +била +били +било +близо +бъдат +бъде +бяха +в +вас +ваш +ваша +вероятно +вече +взема +ви +вие +винаги +все +всеки +всички +всичко +всяка +във +въпреки +върху +г +ги +главно +го +д +да +дали +до +докато +докога +дори +досега +доста +е +едва +един +ето +за +зад +заедно +заради +засега +затова +защо +защото +и +из +или +им +има +имат +иска +й +каза +как +каква +какво +както +какъв +като +кога +когато +което +които +кой +който +колко +която +къде +където +към +ли +м +ме +между +мен +ми +мнозина +мога +могат +може +моля +момента +му +н +на +над +назад +най +направи +напред +например +нас +не +него +нея +ни +ние +никой +нито +но +някои +някой +няма +обаче +около +освен +особено +от +отгоре +отново +още +пак +по +повече +повечето +под +поне +поради +после +почти +прави +пред +преди +през +при +пък +първо +с +са +само +се +сега +си +скоро +след +сме +според +сред +срещу +сте +съм +със +също +т +тази +така +такива +такъв +там +твой +те +тези +ти +тн +то +това +тогава +този +той +толкова +точно +трябва +тук +тъй +тя +тях +у +харесва +ч +че +често +чрез +ще +щом +я diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ca.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ca.txt new file mode 100644 index 00000000000..3da65deafe1 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ca.txt @@ -0,0 +1,220 @@ +# Catalan stopwords from http://github.com/vcl/cue.language (Apache 2 Licensed) +a +abans +ací +ah +així +això +al +als +aleshores +algun +alguna +algunes +alguns +alhora +allà +allí +allò +altra +altre +altres +amb +ambdós +ambdues +apa +aquell +aquella +aquelles +aquells +aquest +aquesta +aquestes +aquests +aquí +baix +cada +cadascú +cadascuna +cadascunes +cadascuns +com +contra +d'un +d'una +d'unes +d'uns +dalt +de +del +dels +des +després +dins +dintre +donat +doncs +durant +e +eh +el +els +em +en +encara +ens +entre +érem +eren +éreu +es +és +esta +està +estàvem +estaven +estàveu +esteu +et +etc +ets +fins +fora +gairebé +ha +han +has +havia +he +hem +heu +hi +ho +i +igual +iguals +ja +l'hi +la +les +li +li'n +llavors +m'he +ma +mal +malgrat +mateix +mateixa +mateixes +mateixos +me +mentre +més +meu +meus +meva +meves +molt +molta +moltes +molts +mon +mons +n'he +n'hi +ne +ni +no +nogensmenys +només +nosaltres +nostra +nostre +nostres +o +oh +oi +on +pas +pel +pels +per +però +perquè +poc +poca +pocs +poques +potser +propi +qual +quals +quan +quant +que +què +quelcom +qui +quin +quina +quines +quins +s'ha +s'han +sa +semblant +semblants +ses +seu +seus +seva +seva +seves +si +sobre +sobretot +sóc +solament +sols +son +són +sons +sota +sou +t'ha +t'han +t'he +ta +tal +també +tampoc +tan +tant +tanta +tantes +teu +teus +teva +teves +ton +tons +tot +tota +totes +tots +un +una +unes +uns +us +va +vaig +vam +van +vas +veu +vosaltres +vostra +vostre +vostres diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_cz.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_cz.txt new file mode 100644 index 00000000000..53c6097dac7 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_cz.txt @@ -0,0 +1,172 @@ +a +s +k +o +i +u +v +z +dnes +cz +tímto +budeš +budem +byli +jseš +můj +svým +ta +tomto +tohle +tuto +tyto +jej +zda +proč +máte +tato +kam +tohoto +kdo +kteří +mi +nám +tom +tomuto +mít +nic +proto +kterou +byla +toho +protože +asi +ho +naši +napište +re +což +tím +takže +svých +její +svými +jste +aj +tu +tedy +teto +bylo +kde +ke +pravé +ji +nad +nejsou +či +pod +téma +mezi +přes +ty +pak +vám +ani +když +však +neg +jsem +tento +článku +články +aby +jsme +před +pta +jejich +byl +ještě +až +bez +také +pouze +první +vaše +která +nás +nový +tipy +pokud +může +strana +jeho +své +jiné +zprávy +nové +není +vás +jen +podle +zde +už +být +více +bude +již +než +který +by +které +co +nebo +ten +tak +má +při +od +po +jsou +jak +další +ale +si +se +ve +to +jako +za +zpět +ze +do +pro +je +na +atd +atp +jakmile +přičemž +já +on +ona +ono +oni +ony +my +vy +jí +ji +mě +mne +jemu +tomu +těm +těmu +němu +němuž +jehož +jíž +jelikož +jež +jakož +načež diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_da.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_da.txt new file mode 100644 index 00000000000..a3ff5fe122c --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_da.txt @@ -0,0 +1,108 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/danish/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Danish stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | This is a ranked list (commonest to rarest) of stopwords derived from + | a large text sample. + + +og | and +i | in +jeg | I +det | that (dem. pronoun)/it (pers. pronoun) +at | that (in front of a sentence)/to (with infinitive) +en | a/an +den | it (pers. pronoun)/that (dem. pronoun) +til | to/at/for/until/against/by/of/into, more +er | present tense of "to be" +som | who, as +på | on/upon/in/on/at/to/after/of/with/for, on +de | they +med | with/by/in, along +han | he +af | of/by/from/off/for/in/with/on, off +for | at/for/to/from/by/of/ago, in front/before, because +ikke | not +der | who/which, there/those +var | past tense of "to be" +mig | me/myself +sig | oneself/himself/herself/itself/themselves +men | but +et | a/an/one, one (number), someone/somebody/one +har | present tense of "to have" +om | round/about/for/in/a, about/around/down, if +vi | we +min | my +havde | past tense of "to have" +ham | him +hun | she +nu | now +over | over/above/across/by/beyond/past/on/about, over/past +da | then, when/as/since +fra | from/off/since, off, since +du | you +ud | out +sin | his/her/its/one's +dem | them +os | us/ourselves +op | up +man | you/one +hans | his +hvor | where +eller | or +hvad | what +skal | must/shall etc. +selv | myself/youself/herself/ourselves etc., even +her | here +alle | all/everyone/everybody etc. +vil | will (verb) +blev | past tense of "to stay/to remain/to get/to become" +kunne | could +ind | in +når | when +være | present tense of "to be" +dog | however/yet/after all +noget | something +ville | would +jo | you know/you see (adv), yes +deres | their/theirs +efter | after/behind/according to/for/by/from, later/afterwards +ned | down +skulle | should +denne | this +end | than +dette | this +mit | my/mine +også | also +under | under/beneath/below/during, below/underneath +have | have +dig | you +anden | other +hende | her +mine | my +alt | everything +meget | much/very, plenty of +sit | his, her, its, one's +sine | his, her, its, one's +vor | our +mod | against +disse | these +hvis | if +din | your/yours +nogle | some +hos | by/at +blive | be/become +mange | many +ad | by/through +bliver | present tense of "to be/to become" +hendes | her/hers +været | be +thi | for (conj) +jer | you +sådan | such, like this/like that diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_de.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_de.txt new file mode 100644 index 00000000000..f7703841887 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_de.txt @@ -0,0 +1,292 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/german/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A German stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | The number of forms in this list is reduced significantly by passing it + | through the German stemmer. + + +aber | but + +alle | all +allem +allen +aller +alles + +als | than, as +also | so +am | an + dem +an | at + +ander | other +andere +anderem +anderen +anderer +anderes +anderm +andern +anderr +anders + +auch | also +auf | on +aus | out of +bei | by +bin | am +bis | until +bist | art +da | there +damit | with it +dann | then + +der | the +den +des +dem +die +das + +daß | that + +derselbe | the same +derselben +denselben +desselben +demselben +dieselbe +dieselben +dasselbe + +dazu | to that + +dein | thy +deine +deinem +deinen +deiner +deines + +denn | because + +derer | of those +dessen | of him + +dich | thee +dir | to thee +du | thou + +dies | this +diese +diesem +diesen +dieser +dieses + + +doch | (several meanings) +dort | (over) there + + +durch | through + +ein | a +eine +einem +einen +einer +eines + +einig | some +einige +einigem +einigen +einiger +einiges + +einmal | once + +er | he +ihn | him +ihm | to him + +es | it +etwas | something + +euer | your +eure +eurem +euren +eurer +eures + +für | for +gegen | towards +gewesen | p.p. of sein +hab | have +habe | have +haben | have +hat | has +hatte | had +hatten | had +hier | here +hin | there +hinter | behind + +ich | I +mich | me +mir | to me + + +ihr | you, to her +ihre +ihrem +ihren +ihrer +ihres +euch | to you + +im | in + dem +in | in +indem | while +ins | in + das +ist | is + +jede | each, every +jedem +jeden +jeder +jedes + +jene | that +jenem +jenen +jener +jenes + +jetzt | now +kann | can + +kein | no +keine +keinem +keinen +keiner +keines + +können | can +könnte | could +machen | do +man | one + +manche | some, many a +manchem +manchen +mancher +manches + +mein | my +meine +meinem +meinen +meiner +meines + +mit | with +muss | must +musste | had to +nach | to(wards) +nicht | not +nichts | nothing +noch | still, yet +nun | now +nur | only +ob | whether +oder | or +ohne | without +sehr | very + +sein | his +seine +seinem +seinen +seiner +seines + +selbst | self +sich | herself + +sie | they, she +ihnen | to them + +sind | are +so | so + +solche | such +solchem +solchen +solcher +solches + +soll | shall +sollte | should +sondern | but +sonst | else +über | over +um | about, around +und | and + +uns | us +unse +unsem +unsen +unser +unses + +unter | under +viel | much +vom | von + dem +von | from +vor | before +während | while +war | was +waren | were +warst | wast +was | what +weg | away, off +weil | because +weiter | further + +welche | which +welchem +welchen +welcher +welches + +wenn | when +werde | will +werden | will +wie | how +wieder | again +will | want +wir | we +wird | will +wirst | willst +wo | where +wollen | want +wollte | wanted +würde | would +würden | would +zu | to +zum | zu + dem +zur | zu + der +zwar | indeed +zwischen | between + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_el.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_el.txt new file mode 100644 index 00000000000..232681f5bd6 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_el.txt @@ -0,0 +1,78 @@ +# Lucene Greek Stopwords list +# Note: by default this file is used after GreekLowerCaseFilter, +# so when modifying this file use 'σ' instead of 'ς' +ο +η +το +οι +τα +του +τησ +των +τον +την +και +κι +κ +ειμαι +εισαι +ειναι +ειμαστε +ειστε +στο +στον +στη +στην +μα +αλλα +απο +για +προσ +με +σε +ωσ +παρα +αντι +κατα +μετα +θα +να +δε +δεν +μη +μην +επι +ενω +εαν +αν +τοτε +που +πωσ +ποιοσ +ποια +ποιο +ποιοι +ποιεσ +ποιων +ποιουσ +αυτοσ +αυτη +αυτο +αυτοι +αυτων +αυτουσ +αυτεσ +αυτα +εκεινοσ +εκεινη +εκεινο +εκεινοι +εκεινεσ +εκεινα +εκεινων +εκεινουσ +οπωσ +ομωσ +ισωσ +οσο +οτι diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_en.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_en.txt new file mode 100644 index 00000000000..2c164c0b2a1 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_en.txt @@ -0,0 +1,54 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# a couple of test stopwords to test that the words are really being +# configured from this file: +stopworda +stopwordb + +# Standard english stop words taken from Lucene's StopAnalyzer +a +an +and +are +as +at +be +but +by +for +if +in +into +is +it +no +not +of +on +or +such +that +the +their +then +there +these +they +this +to +was +will +with diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_es.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_es.txt new file mode 100644 index 00000000000..2db14760075 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_es.txt @@ -0,0 +1,354 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/spanish/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Spanish stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + + | The following is a ranked list (commonest to rarest) of stopwords + | deriving from a large sample of text. + + | Extra words have been added at the end. + +de | from, of +la | the, her +que | who, that +el | the +en | in +y | and +a | to +los | the, them +del | de + el +se | himself, from him etc +las | the, them +por | for, by, etc +un | a +para | for +con | with +no | no +una | a +su | his, her +al | a + el + | es from SER +lo | him +como | how +más | more +pero | pero +sus | su plural +le | to him, her +ya | already +o | or + | fue from SER +este | this + | ha from HABER +sí | himself etc +porque | because +esta | this + | son from SER +entre | between + | está from ESTAR +cuando | when +muy | very +sin | without +sobre | on + | ser from SER + | tiene from TENER +también | also +me | me +hasta | until +hay | there is/are +donde | where + | han from HABER +quien | whom, that + | están from ESTAR + | estado from ESTAR +desde | from +todo | all +nos | us +durante | during + | estados from ESTAR +todos | all +uno | a +les | to them +ni | nor +contra | against +otros | other + | fueron from SER +ese | that +eso | that + | había from HABER +ante | before +ellos | they +e | and (variant of y) +esto | this +mí | me +antes | before +algunos | some +qué | what? +unos | a +yo | I +otro | other +otras | other +otra | other +él | he +tanto | so much, many +esa | that +estos | these +mucho | much, many +quienes | who +nada | nothing +muchos | many +cual | who + | sea from SER +poco | few +ella | she +estar | to be + | haber from HABER +estas | these + | estaba from ESTAR + | estamos from ESTAR +algunas | some +algo | something +nosotros | we + + | other forms + +mi | me +mis | mi plural +tú | thou +te | thee +ti | thee +tu | thy +tus | tu plural +ellas | they +nosotras | we +vosotros | you +vosotras | you +os | you +mío | mine +mía | +míos | +mías | +tuyo | thine +tuya | +tuyos | +tuyas | +suyo | his, hers, theirs +suya | +suyos | +suyas | +nuestro | ours +nuestra | +nuestros | +nuestras | +vuestro | yours +vuestra | +vuestros | +vuestras | +esos | those +esas | those + + | forms of estar, to be (not including the infinitive): +estoy +estás +está +estamos +estáis +están +esté +estés +estemos +estéis +estén +estaré +estarás +estará +estaremos +estaréis +estarán +estaría +estarías +estaríamos +estaríais +estarían +estaba +estabas +estábamos +estabais +estaban +estuve +estuviste +estuvo +estuvimos +estuvisteis +estuvieron +estuviera +estuvieras +estuviéramos +estuvierais +estuvieran +estuviese +estuvieses +estuviésemos +estuvieseis +estuviesen +estando +estado +estada +estados +estadas +estad + + | forms of haber, to have (not including the infinitive): +he +has +ha +hemos +habéis +han +haya +hayas +hayamos +hayáis +hayan +habré +habrás +habrá +habremos +habréis +habrán +habría +habrías +habríamos +habríais +habrían +había +habías +habíamos +habíais +habían +hube +hubiste +hubo +hubimos +hubisteis +hubieron +hubiera +hubieras +hubiéramos +hubierais +hubieran +hubiese +hubieses +hubiésemos +hubieseis +hubiesen +habiendo +habido +habida +habidos +habidas + + | forms of ser, to be (not including the infinitive): +soy +eres +es +somos +sois +son +sea +seas +seamos +seáis +sean +seré +serás +será +seremos +seréis +serán +sería +serías +seríamos +seríais +serían +era +eras +éramos +erais +eran +fui +fuiste +fue +fuimos +fuisteis +fueron +fuera +fueras +fuéramos +fuerais +fueran +fuese +fueses +fuésemos +fueseis +fuesen +siendo +sido + | sed also means 'thirst' + + | forms of tener, to have (not including the infinitive): +tengo +tienes +tiene +tenemos +tenéis +tienen +tenga +tengas +tengamos +tengáis +tengan +tendré +tendrás +tendrá +tendremos +tendréis +tendrán +tendría +tendrías +tendríamos +tendríais +tendrían +tenía +tenías +teníamos +teníais +tenían +tuve +tuviste +tuvo +tuvimos +tuvisteis +tuvieron +tuviera +tuvieras +tuviéramos +tuvierais +tuvieran +tuviese +tuvieses +tuviésemos +tuvieseis +tuviesen +teniendo +tenido +tenida +tenidos +tenidas +tened + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_eu.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_eu.txt new file mode 100644 index 00000000000..25f1db93460 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_eu.txt @@ -0,0 +1,99 @@ +# example set of basque stopwords +al +anitz +arabera +asko +baina +bat +batean +batek +bati +batzuei +batzuek +batzuetan +batzuk +bera +beraiek +berau +berauek +bere +berori +beroriek +beste +bezala +da +dago +dira +ditu +du +dute +edo +egin +ere +eta +eurak +ez +gainera +gu +gutxi +guzti +haiei +haiek +haietan +hainbeste +hala +han +handik +hango +hara +hari +hark +hartan +hau +hauei +hauek +hauetan +hemen +hemendik +hemengo +hi +hona +honek +honela +honetan +honi +hor +hori +horiei +horiek +horietan +horko +horra +horrek +horrela +horretan +horri +hortik +hura +izan +ni +noiz +nola +non +nondik +nongo +nor +nora +ze +zein +zen +zenbait +zenbat +zer +zergatik +ziren +zituen +zu +zuek +zuen +zuten diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_fa.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_fa.txt new file mode 100644 index 00000000000..723641c6da7 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_fa.txt @@ -0,0 +1,313 @@ +# This file was created by Jacques Savoy and is distributed under the BSD license. +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# Also see http://www.opensource.org/licenses/bsd-license.html +# Note: by default this file is used after normalization, so when adding entries +# to this file, use the arabic 'ي' instead of 'ی' +انان +نداشته +سراسر +خياه +ايشان +وي +تاكنون +بيشتري +دوم +پس +ناشي +وگو +يا +داشتند +سپس +هنگام +هرگز +پنج +نشان +امسال +ديگر +گروهي +شدند +چطور +ده +و +دو +نخستين +ولي +چرا +چه +وسط +ه +كدام +قابل +يك +رفت +هفت +همچنين +در +هزار +بله +بلي +شايد +اما +شناسي +گرفته +دهد +داشته +دانست +داشتن +خواهيم +ميليارد +وقتيكه +امد +خواهد +جز +اورده +شده +بلكه +خدمات +شدن +برخي +نبود +بسياري +جلوگيري +حق +كردند +نوعي +بعري +نكرده +نظير +نبايد +بوده +بودن +داد +اورد +هست +جايي +شود +دنبال +داده +بايد +سابق +هيچ +همان +انجا +كمتر +كجاست +گردد +كسي +تر +مردم +تان +دادن +بودند +سري +جدا +ندارند +مگر +يكديگر +دارد +دهند +بنابراين +هنگامي +سمت +جا +انچه +خود +دادند +زياد +دارند +اثر +بدون +بهترين +بيشتر +البته +به +براساس +بيرون +كرد +بعضي +گرفت +توي +اي +ميليون +او +جريان +تول +بر +مانند +برابر +باشيم +مدتي +گويند +اكنون +تا +تنها +جديد +چند +بي +نشده +كردن +كردم +گويد +كرده +كنيم +نمي +نزد +روي +قصد +فقط +بالاي +ديگران +اين +ديروز +توسط +سوم +ايم +دانند +سوي +استفاده +شما +كنار +داريم +ساخته +طور +امده +رفته +نخست +بيست +نزديك +طي +كنيد +از +انها +تمامي +داشت +يكي +طريق +اش +چيست +روب +نمايد +گفت +چندين +چيزي +تواند +ام +ايا +با +ان +ايد +ترين +اينكه +ديگري +راه +هايي +بروز +همچنان +پاعين +كس +حدود +مختلف +مقابل +چيز +گيرد +ندارد +ضد +همچون +سازي +شان +مورد +باره +مرسي +خويش +برخوردار +چون +خارج +شش +هنوز +تحت +ضمن +هستيم +گفته +فكر +بسيار +پيش +براي +روزهاي +انكه +نخواهد +بالا +كل +وقتي +كي +چنين +كه +گيري +نيست +است +كجا +كند +نيز +يابد +بندي +حتي +توانند +عقب +خواست +كنند +بين +تمام +همه +ما +باشند +مثل +شد +اري +باشد +اره +طبق +بعد +اگر +صورت +غير +جاي +بيش +ريزي +اند +زيرا +چگونه +بار +لطفا +مي +درباره +من +ديده +همين +گذاري +برداري +علت +گذاشته +هم +فوق +نه +ها +شوند +اباد +همواره +هر +اول +خواهند +چهار +نام +امروز +مان +هاي +قبل +كنم +سعي +تازه +را +هستند +زير +جلوي +عنوان +بود diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_fi.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_fi.txt new file mode 100644 index 00000000000..addad798c4b --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_fi.txt @@ -0,0 +1,95 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/finnish/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + +| forms of BE + +olla +olen +olet +on +olemme +olette +ovat +ole | negative form + +oli +olisi +olisit +olisin +olisimme +olisitte +olisivat +olit +olin +olimme +olitte +olivat +ollut +olleet + +en | negation +et +ei +emme +ette +eivät + +|Nom Gen Acc Part Iness Elat Illat Adess Ablat Allat Ess Trans +minä minun minut minua minussa minusta minuun minulla minulta minulle | I +sinä sinun sinut sinua sinussa sinusta sinuun sinulla sinulta sinulle | you +hän hänen hänet häntä hänessä hänestä häneen hänellä häneltä hänelle | he she +me meidän meidät meitä meissä meistä meihin meillä meiltä meille | we +te teidän teidät teitä teissä teistä teihin teillä teiltä teille | you +he heidän heidät heitä heissä heistä heihin heillä heiltä heille | they + +tämä tämän tätä tässä tästä tähän tallä tältä tälle tänä täksi | this +tuo tuon tuotä tuossa tuosta tuohon tuolla tuolta tuolle tuona tuoksi | that +se sen sitä siinä siitä siihen sillä siltä sille sinä siksi | it +nämä näiden näitä näissä näistä näihin näillä näiltä näille näinä näiksi | these +nuo noiden noita noissa noista noihin noilla noilta noille noina noiksi | those +ne niiden niitä niissä niistä niihin niillä niiltä niille niinä niiksi | they + +kuka kenen kenet ketä kenessä kenestä keneen kenellä keneltä kenelle kenenä keneksi| who +ketkä keiden ketkä keitä keissä keistä keihin keillä keiltä keille keinä keiksi | (pl) +mikä minkä minkä mitä missä mistä mihin millä miltä mille minä miksi | which what +mitkä | (pl) + +joka jonka jota jossa josta johon jolla jolta jolle jona joksi | who which +jotka joiden joita joissa joista joihin joilla joilta joille joina joiksi | (pl) + +| conjunctions + +että | that +ja | and +jos | if +koska | because +kuin | than +mutta | but +niin | so +sekä | and +sillä | for +tai | or +vaan | but +vai | or +vaikka | although + + +| prepositions + +kanssa | with +mukaan | according to +noin | about +poikki | across +yli | over, across + +| other + +kun | when +niin | so +nyt | now +itse | self + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_fr.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_fr.txt new file mode 100644 index 00000000000..c00837ea939 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_fr.txt @@ -0,0 +1,183 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/french/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A French stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + +au | a + le +aux | a + les +avec | with +ce | this +ces | these +dans | with +de | of +des | de + les +du | de + le +elle | she +en | `of them' etc +et | and +eux | them +il | he +je | I +la | the +le | the +leur | their +lui | him +ma | my (fem) +mais | but +me | me +même | same; as in moi-même (myself) etc +mes | me (pl) +moi | me +mon | my (masc) +ne | not +nos | our (pl) +notre | our +nous | we +on | one +ou | where +par | by +pas | not +pour | for +qu | que before vowel +que | that +qui | who +sa | his, her (fem) +se | oneself +ses | his (pl) +son | his, her (masc) +sur | on +ta | thy (fem) +te | thee +tes | thy (pl) +toi | thee +ton | thy (masc) +tu | thou +un | a +une | a +vos | your (pl) +votre | your +vous | you + + | single letter forms + +c | c' +d | d' +j | j' +l | l' +à | to, at +m | m' +n | n' +s | s' +t | t' +y | there + + | forms of être (not including the infinitive): +été +étée +étées +étés +étant +suis +es +est +sommes +êtes +sont +serai +seras +sera +serons +serez +seront +serais +serait +serions +seriez +seraient +étais +était +étions +étiez +étaient +fus +fut +fûmes +fûtes +furent +sois +soit +soyons +soyez +soient +fusse +fusses +fût +fussions +fussiez +fussent + + | forms of avoir (not including the infinitive): +ayant +eu +eue +eues +eus +ai +as +avons +avez +ont +aurai +auras +aura +aurons +aurez +auront +aurais +aurait +aurions +auriez +auraient +avais +avait +avions +aviez +avaient +eut +eûmes +eûtes +eurent +aie +aies +ait +ayons +ayez +aient +eusse +eusses +eût +eussions +eussiez +eussent + + | Later additions (from Jean-Christophe Deschamps) +ceci | this +celà  | that +cet | this +cette | this +ici | here +ils | they +les | the (pl) +leurs | their (pl) +quel | which +quels | which +quelle | which +quelles | which +sans | without +soi | oneself + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ga.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ga.txt new file mode 100644 index 00000000000..9ff88d747e5 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ga.txt @@ -0,0 +1,110 @@ + +a +ach +ag +agus +an +aon +ar +arna +as +b' +ba +beirt +bhúr +caoga +ceathair +ceathrar +chomh +chtó +chuig +chun +cois +céad +cúig +cúigear +d' +daichead +dar +de +deich +deichniúr +den +dhá +do +don +dtí +dá +dár +dó +faoi +faoin +faoina +faoinár +fara +fiche +gach +gan +go +gur +haon +hocht +i +iad +idir +in +ina +ins +inár +is +le +leis +lena +lenár +m' +mar +mo +mé +na +nach +naoi +naonúr +ná +ní +níor +nó +nócha +ocht +ochtar +os +roimh +sa +seacht +seachtar +seachtó +seasca +seisear +siad +sibh +sinn +sna +sé +sí +tar +thar +thú +triúr +trí +trína +trínár +tríocha +tú +um +ár +é +éis +í +ó +ón +óna +ónár diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_gl.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_gl.txt new file mode 100644 index 00000000000..d8760b12c14 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_gl.txt @@ -0,0 +1,161 @@ +# galican stopwords +a +aínda +alí +aquel +aquela +aquelas +aqueles +aquilo +aquí +ao +aos +as +así +á +ben +cando +che +co +coa +comigo +con +connosco +contigo +convosco +coas +cos +cun +cuns +cunha +cunhas +da +dalgunha +dalgunhas +dalgún +dalgúns +das +de +del +dela +delas +deles +desde +deste +do +dos +dun +duns +dunha +dunhas +e +el +ela +elas +eles +en +era +eran +esa +esas +ese +eses +esta +estar +estaba +está +están +este +estes +estiven +estou +eu +é +facer +foi +foron +fun +había +hai +iso +isto +la +las +lle +lles +lo +los +mais +me +meu +meus +min +miña +miñas +moi +na +nas +neste +nin +no +non +nos +nosa +nosas +noso +nosos +nós +nun +nunha +nuns +nunhas +o +os +ou +ó +ós +para +pero +pode +pois +pola +polas +polo +polos +por +que +se +senón +ser +seu +seus +sexa +sido +sobre +súa +súas +tamén +tan +te +ten +teñen +teño +ter +teu +teus +ti +tido +tiña +tiven +túa +túas +un +unha +unhas +uns +vos +vosa +vosas +voso +vosos +vós diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_hi.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_hi.txt new file mode 100644 index 00000000000..86286bb083b --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_hi.txt @@ -0,0 +1,235 @@ +# Also see http://www.opensource.org/licenses/bsd-license.html +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# This file was created by Jacques Savoy and is distributed under the BSD license. +# Note: by default this file also contains forms normalized by HindiNormalizer +# for spelling variation (see section below), such that it can be used whether or +# not you enable that feature. When adding additional entries to this list, +# please add the normalized form as well. +अंदर +अत +अपना +अपनी +अपने +अभी +आदि +आप +इत्यादि +इन +इनका +इन्हीं +इन्हें +इन्हों +इस +इसका +इसकी +इसके +इसमें +इसी +इसे +उन +उनका +उनकी +उनके +उनको +उन्हीं +उन्हें +उन्हों +उस +उसके +उसी +उसे +एक +एवं +एस +ऐसे +और +कई +कर +करता +करते +करना +करने +करें +कहते +कहा +का +काफ़ी +कि +कितना +किन्हें +किन्हों +किया +किर +किस +किसी +किसे +की +कुछ +कुल +के +को +कोई +कौन +कौनसा +गया +घर +जब +जहाँ +जा +जितना +जिन +जिन्हें +जिन्हों +जिस +जिसे +जीधर +जैसा +जैसे +जो +तक +तब +तरह +तिन +तिन्हें +तिन्हों +तिस +तिसे +तो +था +थी +थे +दबारा +दिया +दुसरा +दूसरे +दो +द्वारा +न +नहीं +ना +निहायत +नीचे +ने +पर +पर +पहले +पूरा +पे +फिर +बनी +बही +बहुत +बाद +बाला +बिलकुल +भी +भीतर +मगर +मानो +मे +में +यदि +यह +यहाँ +यही +या +यिह +ये +रखें +रहा +रहे +ऱ्वासा +लिए +लिये +लेकिन +व +वर्ग +वह +वह +वहाँ +वहीं +वाले +वुह +वे +वग़ैरह +संग +सकता +सकते +सबसे +सभी +साथ +साबुत +साभ +सारा +से +सो +ही +हुआ +हुई +हुए +है +हैं +हो +होता +होती +होते +होना +होने +# additional normalized forms of the above +अपनि +जेसे +होति +सभि +तिंहों +इंहों +दवारा +इसि +किंहें +थि +उंहों +ओर +जिंहें +वहिं +अभि +बनि +हि +उंहिं +उंहें +हें +वगेरह +एसे +रवासा +कोन +निचे +काफि +उसि +पुरा +भितर +हे +बहि +वहां +कोइ +यहां +जिंहों +तिंहें +किसि +कइ +यहि +इंहिं +जिधर +इंहें +अदि +इतयादि +हुइ +कोनसा +इसकि +दुसरे +जहां +अप +किंहों +उनकि +भि +वरग +हुअ +जेसा +नहिं diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_hu.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_hu.txt new file mode 100644 index 00000000000..1a96f1db6f2 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_hu.txt @@ -0,0 +1,209 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/hungarian/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + +| Hungarian stop word list +| prepared by Anna Tordai + +a +ahogy +ahol +aki +akik +akkor +alatt +által +általában +amely +amelyek +amelyekben +amelyeket +amelyet +amelynek +ami +amit +amolyan +amíg +amikor +át +abban +ahhoz +annak +arra +arról +az +azok +azon +azt +azzal +azért +aztán +azután +azonban +bár +be +belül +benne +cikk +cikkek +cikkeket +csak +de +e +eddig +egész +egy +egyes +egyetlen +egyéb +egyik +egyre +ekkor +el +elég +ellen +elő +először +előtt +első +én +éppen +ebben +ehhez +emilyen +ennek +erre +ez +ezt +ezek +ezen +ezzel +ezért +és +fel +felé +hanem +hiszen +hogy +hogyan +igen +így +illetve +ill. +ill +ilyen +ilyenkor +ison +ismét +itt +jó +jól +jobban +kell +kellett +keresztül +keressünk +ki +kívül +között +közül +legalább +lehet +lehetett +legyen +lenne +lenni +lesz +lett +maga +magát +majd +majd +már +más +másik +meg +még +mellett +mert +mely +melyek +mi +mit +míg +miért +milyen +mikor +minden +mindent +mindenki +mindig +mint +mintha +mivel +most +nagy +nagyobb +nagyon +ne +néha +nekem +neki +nem +néhány +nélkül +nincs +olyan +ott +össze +ő +ők +őket +pedig +persze +rá +s +saját +sem +semmi +sok +sokat +sokkal +számára +szemben +szerint +szinte +talán +tehát +teljes +tovább +továbbá +több +úgy +ugyanis +új +újabb +újra +után +utána +utolsó +vagy +vagyis +valaki +valami +valamint +való +vagyok +van +vannak +volt +voltam +voltak +voltunk +vissza +vele +viszont +volna diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_hy.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_hy.txt new file mode 100644 index 00000000000..60c1c50fbc8 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_hy.txt @@ -0,0 +1,46 @@ +# example set of Armenian stopwords. +այդ +այլ +այն +այս +դու +դուք +եմ +են +ենք +ես +եք +է +էի +էին +էինք +էիր +էիք +էր +ըստ +թ +ի +ին +իսկ +իր +կամ +համար +հետ +հետո +մենք +մեջ +մի +ն +նա +նաև +նրա +նրանք +որ +որը +որոնք +որպես +ու +ում +պիտի +վրա +և diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_id.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_id.txt new file mode 100644 index 00000000000..4617f83a5c5 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_id.txt @@ -0,0 +1,359 @@ +# from appendix D of: A Study of Stemming Effects on Information +# Retrieval in Bahasa Indonesia +ada +adanya +adalah +adapun +agak +agaknya +agar +akan +akankah +akhirnya +aku +akulah +amat +amatlah +anda +andalah +antar +diantaranya +antara +antaranya +diantara +apa +apaan +mengapa +apabila +apakah +apalagi +apatah +atau +ataukah +ataupun +bagai +bagaikan +sebagai +sebagainya +bagaimana +bagaimanapun +sebagaimana +bagaimanakah +bagi +bahkan +bahwa +bahwasanya +sebaliknya +banyak +sebanyak +beberapa +seberapa +begini +beginian +beginikah +beginilah +sebegini +begitu +begitukah +begitulah +begitupun +sebegitu +belum +belumlah +sebelum +sebelumnya +sebenarnya +berapa +berapakah +berapalah +berapapun +betulkah +sebetulnya +biasa +biasanya +bila +bilakah +bisa +bisakah +sebisanya +boleh +bolehkah +bolehlah +buat +bukan +bukankah +bukanlah +bukannya +cuma +percuma +dahulu +dalam +dan +dapat +dari +daripada +dekat +demi +demikian +demikianlah +sedemikian +dengan +depan +di +dia +dialah +dini +diri +dirinya +terdiri +dong +dulu +enggak +enggaknya +entah +entahlah +terhadap +terhadapnya +hal +hampir +hanya +hanyalah +harus +haruslah +harusnya +seharusnya +hendak +hendaklah +hendaknya +hingga +sehingga +ia +ialah +ibarat +ingin +inginkah +inginkan +ini +inikah +inilah +itu +itukah +itulah +jangan +jangankan +janganlah +jika +jikalau +juga +justru +kala +kalau +kalaulah +kalaupun +kalian +kami +kamilah +kamu +kamulah +kan +kapan +kapankah +kapanpun +dikarenakan +karena +karenanya +ke +kecil +kemudian +kenapa +kepada +kepadanya +ketika +seketika +khususnya +kini +kinilah +kiranya +sekiranya +kita +kitalah +kok +lagi +lagian +selagi +lah +lain +lainnya +melainkan +selaku +lalu +melalui +terlalu +lama +lamanya +selama +selama +selamanya +lebih +terlebih +bermacam +macam +semacam +maka +makanya +makin +malah +malahan +mampu +mampukah +mana +manakala +manalagi +masih +masihkah +semasih +masing +mau +maupun +semaunya +memang +mereka +merekalah +meski +meskipun +semula +mungkin +mungkinkah +nah +namun +nanti +nantinya +nyaris +oleh +olehnya +seorang +seseorang +pada +padanya +padahal +paling +sepanjang +pantas +sepantasnya +sepantasnyalah +para +pasti +pastilah +per +pernah +pula +pun +merupakan +rupanya +serupa +saat +saatnya +sesaat +saja +sajalah +saling +bersama +sama +sesama +sambil +sampai +sana +sangat +sangatlah +saya +sayalah +se +sebab +sebabnya +sebuah +tersebut +tersebutlah +sedang +sedangkan +sedikit +sedikitnya +segala +segalanya +segera +sesegera +sejak +sejenak +sekali +sekalian +sekalipun +sesekali +sekaligus +sekarang +sekarang +sekitar +sekitarnya +sela +selain +selalu +seluruh +seluruhnya +semakin +sementara +sempat +semua +semuanya +sendiri +sendirinya +seolah +seperti +sepertinya +sering +seringnya +serta +siapa +siapakah +siapapun +disini +disinilah +sini +sinilah +sesuatu +sesuatunya +suatu +sesudah +sesudahnya +sudah +sudahkah +sudahlah +supaya +tadi +tadinya +tak +tanpa +setelah +telah +tentang +tentu +tentulah +tentunya +tertentu +seterusnya +tapi +tetapi +setiap +tiap +setidaknya +tidak +tidakkah +tidaklah +toh +waduh +wah +wahai +sewaktu +walau +walaupun +wong +yaitu +yakni +yang diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_it.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_it.txt new file mode 100644 index 00000000000..4cb5b0891b1 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_it.txt @@ -0,0 +1,301 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/italian/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | An Italian stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + +ad | a (to) before vowel +al | a + il +allo | a + lo +ai | a + i +agli | a + gli +all | a + l' +agl | a + gl' +alla | a + la +alle | a + le +con | with +col | con + il +coi | con + i (forms collo, cogli etc are now very rare) +da | from +dal | da + il +dallo | da + lo +dai | da + i +dagli | da + gli +dall | da + l' +dagl | da + gll' +dalla | da + la +dalle | da + le +di | of +del | di + il +dello | di + lo +dei | di + i +degli | di + gli +dell | di + l' +degl | di + gl' +della | di + la +delle | di + le +in | in +nel | in + el +nello | in + lo +nei | in + i +negli | in + gli +nell | in + l' +negl | in + gl' +nella | in + la +nelle | in + le +su | on +sul | su + il +sullo | su + lo +sui | su + i +sugli | su + gli +sull | su + l' +sugl | su + gl' +sulla | su + la +sulle | su + le +per | through, by +tra | among +contro | against +io | I +tu | thou +lui | he +lei | she +noi | we +voi | you +loro | they +mio | my +mia | +miei | +mie | +tuo | +tua | +tuoi | thy +tue | +suo | +sua | +suoi | his, her +sue | +nostro | our +nostra | +nostri | +nostre | +vostro | your +vostra | +vostri | +vostre | +mi | me +ti | thee +ci | us, there +vi | you, there +lo | him, the +la | her, the +li | them +le | them, the +gli | to him, the +ne | from there etc +il | the +un | a +uno | a +una | a +ma | but +ed | and +se | if +perché | why, because +anche | also +come | how +dov | where (as dov') +dove | where +che | who, that +chi | who +cui | whom +non | not +più | more +quale | who, that +quanto | how much +quanti | +quanta | +quante | +quello | that +quelli | +quella | +quelle | +questo | this +questi | +questa | +queste | +si | yes +tutto | all +tutti | all + + | single letter forms: + +a | at +c | as c' for ce or ci +e | and +i | the +l | as l' +o | or + + | forms of avere, to have (not including the infinitive): + +ho +hai +ha +abbiamo +avete +hanno +abbia +abbiate +abbiano +avrò +avrai +avrà +avremo +avrete +avranno +avrei +avresti +avrebbe +avremmo +avreste +avrebbero +avevo +avevi +aveva +avevamo +avevate +avevano +ebbi +avesti +ebbe +avemmo +aveste +ebbero +avessi +avesse +avessimo +avessero +avendo +avuto +avuta +avuti +avute + + | forms of essere, to be (not including the infinitive): +sono +sei +è +siamo +siete +sia +siate +siano +sarò +sarai +sarà +saremo +sarete +saranno +sarei +saresti +sarebbe +saremmo +sareste +sarebbero +ero +eri +era +eravamo +eravate +erano +fui +fosti +fu +fummo +foste +furono +fossi +fosse +fossimo +fossero +essendo + + | forms of fare, to do (not including the infinitive, fa, fat-): +faccio +fai +facciamo +fanno +faccia +facciate +facciano +farò +farai +farà +faremo +farete +faranno +farei +faresti +farebbe +faremmo +fareste +farebbero +facevo +facevi +faceva +facevamo +facevate +facevano +feci +facesti +fece +facemmo +faceste +fecero +facessi +facesse +facessimo +facessero +facendo + + | forms of stare, to be (not including the infinitive): +sto +stai +sta +stiamo +stanno +stia +stiate +stiano +starò +starai +starà +staremo +starete +staranno +starei +staresti +starebbe +staremmo +stareste +starebbero +stavo +stavi +stava +stavamo +stavate +stavano +stetti +stesti +stette +stemmo +steste +stettero +stessi +stesse +stessimo +stessero +stando diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ja.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ja.txt new file mode 100644 index 00000000000..d4321be6b16 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ja.txt @@ -0,0 +1,127 @@ +# +# This file defines a stopword set for Japanese. +# +# This set is made up of hand-picked frequent terms from segmented Japanese Wikipedia. +# Punctuation characters and frequent kanji have mostly been left out. See LUCENE-3745 +# for frequency lists, etc. that can be useful for making your own set (if desired) +# +# Note that there is an overlap between these stopwords and the terms stopped when used +# in combination with the JapanesePartOfSpeechStopFilter. When editing this file, note +# that comments are not allowed on the same line as stopwords. +# +# Also note that stopping is done in a case-insensitive manner. Change your StopFilter +# configuration if you need case-sensitive stopping. Lastly, note that stopping is done +# using the same character width as the entries in this file. Since this StopFilter is +# normally done after a CJKWidthFilter in your chain, you would usually want your romaji +# entries to be in half-width and your kana entries to be in full-width. +# +の +に +は +を +た +が +で +て +と +し +れ +さ +ある +いる +も +する +から +な +こと +として +い +や +れる +など +なっ +ない +この +ため +その +あっ +よう +また +もの +という +あり +まで +られ +なる +へ +か +だ +これ +によって +により +おり +より +による +ず +なり +られる +において +ば +なかっ +なく +しかし +について +せ +だっ +その後 +できる +それ +う +ので +なお +のみ +でき +き +つ +における +および +いう +さらに +でも +ら +たり +その他 +に関する +たち +ます +ん +なら +に対して +特に +せる +及び +これら +とき +では +にて +ほか +ながら +うち +そして +とともに +ただし +かつて +それぞれ +または +お +ほど +ものの +に対する +ほとんど +と共に +といった +です +とも +ところ +ここ +##### End of file diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_lv.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_lv.txt new file mode 100644 index 00000000000..e21a23c06c3 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_lv.txt @@ -0,0 +1,172 @@ +# Set of Latvian stopwords from A Stemming Algorithm for Latvian, Karlis Kreslins +# the original list of over 800 forms was refined: +# pronouns, adverbs, interjections were removed +# +# prepositions +aiz +ap +ar +apakš +ārpus +augšpus +bez +caur +dēļ +gar +iekš +iz +kopš +labad +lejpus +līdz +no +otrpus +pa +par +pār +pēc +pie +pirms +pret +priekš +starp +šaipus +uz +viņpus +virs +virspus +zem +apakšpus +# Conjunctions +un +bet +jo +ja +ka +lai +tomēr +tikko +turpretī +arī +kaut +gan +tādēļ +tā +ne +tikvien +vien +kā +ir +te +vai +kamēr +# Particles +ar +diezin +droši +diemžēl +nebūt +ik +it +taču +nu +pat +tiklab +iekšpus +nedz +tik +nevis +turpretim +jeb +iekam +iekām +iekāms +kolīdz +līdzko +tiklīdz +jebšu +tālab +tāpēc +nekā +itin +jā +jau +jel +nē +nezin +tad +tikai +vis +tak +iekams +vien +# modal verbs +būt +biju +biji +bija +bijām +bijāt +esmu +esi +esam +esat +būšu +būsi +būs +būsim +būsiet +tikt +tiku +tiki +tika +tikām +tikāt +tieku +tiec +tiek +tiekam +tiekat +tikšu +tiks +tiksim +tiksiet +tapt +tapi +tapāt +topat +tapšu +tapsi +taps +tapsim +tapsiet +kļūt +kļuvu +kļuvi +kļuva +kļuvām +kļuvāt +kļūstu +kļūsti +kļūst +kļūstam +kļūstat +kļūšu +kļūsi +kļūs +kļūsim +kļūsiet +# verbs +varēt +varēju +varējām +varēšu +varēsim +var +varēji +varējāt +varēsi +varēsiet +varat +varēja +varēs diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_nl.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_nl.txt new file mode 100644 index 00000000000..f4d61f5092c --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_nl.txt @@ -0,0 +1,117 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/dutch/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Dutch stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | This is a ranked list (commonest to rarest) of stopwords derived from + | a large sample of Dutch text. + + | Dutch stop words frequently exhibit homonym clashes. These are indicated + | clearly below. + +de | the +en | and +van | of, from +ik | I, the ego +te | (1) chez, at etc, (2) to, (3) too +dat | that, which +die | that, those, who, which +in | in, inside +een | a, an, one +hij | he +het | the, it +niet | not, nothing, naught +zijn | (1) to be, being, (2) his, one's, its +is | is +was | (1) was, past tense of all persons sing. of 'zijn' (to be) (2) wax, (3) the washing, (4) rise of river +op | on, upon, at, in, up, used up +aan | on, upon, to (as dative) +met | with, by +als | like, such as, when +voor | (1) before, in front of, (2) furrow +had | had, past tense all persons sing. of 'hebben' (have) +er | there +maar | but, only +om | round, about, for etc +hem | him +dan | then +zou | should/would, past tense all persons sing. of 'zullen' +of | or, whether, if +wat | what, something, anything +mijn | possessive and noun 'mine' +men | people, 'one' +dit | this +zo | so, thus, in this way +door | through by +over | over, across +ze | she, her, they, them +zich | oneself +bij | (1) a bee, (2) by, near, at +ook | also, too +tot | till, until +je | you +mij | me +uit | out of, from +der | Old Dutch form of 'van der' still found in surnames +daar | (1) there, (2) because +haar | (1) her, their, them, (2) hair +naar | (1) unpleasant, unwell etc, (2) towards, (3) as +heb | present first person sing. of 'to have' +hoe | how, why +heeft | present third person sing. of 'to have' +hebben | 'to have' and various parts thereof +deze | this +u | you +want | (1) for, (2) mitten, (3) rigging +nog | yet, still +zal | 'shall', first and third person sing. of verb 'zullen' (will) +me | me +zij | she, they +nu | now +ge | 'thou', still used in Belgium and south Netherlands +geen | none +omdat | because +iets | something, somewhat +worden | to become, grow, get +toch | yet, still +al | all, every, each +waren | (1) 'were' (2) to wander, (3) wares, (3) +veel | much, many +meer | (1) more, (2) lake +doen | to do, to make +toen | then, when +moet | noun 'spot/mote' and present form of 'to must' +ben | (1) am, (2) 'are' in interrogative second person singular of 'to be' +zonder | without +kan | noun 'can' and present form of 'to be able' +hun | their, them +dus | so, consequently +alles | all, everything, anything +onder | under, beneath +ja | yes, of course +eens | once, one day +hier | here +wie | who +werd | imperfect third person sing. of 'become' +altijd | always +doch | yet, but etc +wordt | present third person sing. of 'become' +wezen | (1) to be, (2) 'been' as in 'been fishing', (3) orphans +kunnen | to be able +ons | us/our +zelf | self +tegen | against, towards, at +na | after, near +reeds | already +wil | (1) present tense of 'want', (2) 'will', noun, (3) fender +kon | could; past tense of 'to be able' +niets | nothing +uw | your +iemand | somebody +geweest | been; past participle of 'be' +andere | other diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_no.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_no.txt new file mode 100644 index 00000000000..e76f36e69ed --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_no.txt @@ -0,0 +1,192 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/norwegian/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Norwegian stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | This stop word list is for the dominant bokmål dialect. Words unique + | to nynorsk are marked *. + + | Revised by Jan Bruusgaard , Jan 2005 + +og | and +i | in +jeg | I +det | it/this/that +at | to (w. inf.) +en | a/an +et | a/an +den | it/this/that +til | to +er | is/am/are +som | who/that +på | on +de | they / you(formal) +med | with +han | he +av | of +ikke | not +ikkje | not * +der | there +så | so +var | was/were +meg | me +seg | you +men | but +ett | one +har | have +om | about +vi | we +min | my +mitt | my +ha | have +hadde | had +hun | she +nå | now +over | over +da | when/as +ved | by/know +fra | from +du | you +ut | out +sin | your +dem | them +oss | us +opp | up +man | you/one +kan | can +hans | his +hvor | where +eller | or +hva | what +skal | shall/must +selv | self (reflective) +sjøl | self (reflective) +her | here +alle | all +vil | will +bli | become +ble | became +blei | became * +blitt | have become +kunne | could +inn | in +når | when +være | be +kom | come +noen | some +noe | some +ville | would +dere | you +som | who/which/that +deres | their/theirs +kun | only/just +ja | yes +etter | after +ned | down +skulle | should +denne | this +for | for/because +deg | you +si | hers/his +sine | hers/his +sitt | hers/his +mot | against +å | to +meget | much +hvorfor | why +dette | this +disse | these/those +uten | without +hvordan | how +ingen | none +din | your +ditt | your +blir | become +samme | same +hvilken | which +hvilke | which (plural) +sånn | such a +inni | inside/within +mellom | between +vår | our +hver | each +hvem | who +vors | us/ours +hvis | whose +både | both +bare | only/just +enn | than +fordi | as/because +før | before +mange | many +også | also +slik | just +vært | been +være | to be +båe | both * +begge | both +siden | since +dykk | your * +dykkar | yours * +dei | they * +deira | them * +deires | theirs * +deim | them * +di | your (fem.) * +då | as/when * +eg | I * +ein | a/an * +eit | a/an * +eitt | a/an * +elles | or * +honom | he * +hjå | at * +ho | she * +hoe | she * +henne | her +hennar | her/hers +hennes | hers +hoss | how * +hossen | how * +ikkje | not * +ingi | noone * +inkje | noone * +korleis | how * +korso | how * +kva | what/which * +kvar | where * +kvarhelst | where * +kven | who/whom * +kvi | why * +kvifor | why * +me | we * +medan | while * +mi | my * +mine | my * +mykje | much * +no | now * +nokon | some (masc./neut.) * +noka | some (fem.) * +nokor | some * +noko | some * +nokre | some * +si | his/hers * +sia | since * +sidan | since * +so | so * +somt | some * +somme | some * +um | about* +upp | up * +vere | be * +vore | was * +verte | become * +vort | become * +varte | became * +vart | became * + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_pt.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_pt.txt new file mode 100644 index 00000000000..276c1b446f2 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_pt.txt @@ -0,0 +1,251 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/portuguese/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Portuguese stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + + | The following is a ranked list (commonest to rarest) of stopwords + | deriving from a large sample of text. + + | Extra words have been added at the end. + +de | of, from +a | the; to, at; her +o | the; him +que | who, that +e | and +do | de + o +da | de + a +em | in +um | a +para | for + | é from SER +com | with +não | not, no +uma | a +os | the; them +no | em + o +se | himself etc +na | em + a +por | for +mais | more +as | the; them +dos | de + os +como | as, like +mas | but + | foi from SER +ao | a + o +ele | he +das | de + as + | tem from TER +à | a + a +seu | his +sua | her +ou | or + | ser from SER +quando | when +muito | much + | há from HAV +nos | em + os; us +já | already, now + | está from EST +eu | I +também | also +só | only, just +pelo | per + o +pela | per + a +até | up to +isso | that +ela | he +entre | between + | era from SER +depois | after +sem | without +mesmo | same +aos | a + os + | ter from TER +seus | his +quem | whom +nas | em + as +me | me +esse | that +eles | they + | estão from EST +você | you + | tinha from TER + | foram from SER +essa | that +num | em + um +nem | nor +suas | her +meu | my +às | a + as +minha | my + | têm from TER +numa | em + uma +pelos | per + os +elas | they + | havia from HAV + | seja from SER +qual | which + | será from SER +nós | we + | tenho from TER +lhe | to him, her +deles | of them +essas | those +esses | those +pelas | per + as +este | this + | fosse from SER +dele | of him + + | other words. There are many contractions such as naquele = em+aquele, + | mo = me+o, but they are rare. + | Indefinite article plural forms are also rare. + +tu | thou +te | thee +vocês | you (plural) +vos | you +lhes | to them +meus | my +minhas +teu | thy +tua +teus +tuas +nosso | our +nossa +nossos +nossas + +dela | of her +delas | of them + +esta | this +estes | these +estas | these +aquele | that +aquela | that +aqueles | those +aquelas | those +isto | this +aquilo | that + + | forms of estar, to be (not including the infinitive): +estou +está +estamos +estão +estive +esteve +estivemos +estiveram +estava +estávamos +estavam +estivera +estivéramos +esteja +estejamos +estejam +estivesse +estivéssemos +estivessem +estiver +estivermos +estiverem + + | forms of haver, to have (not including the infinitive): +hei +há +havemos +hão +houve +houvemos +houveram +houvera +houvéramos +haja +hajamos +hajam +houvesse +houvéssemos +houvessem +houver +houvermos +houverem +houverei +houverá +houveremos +houverão +houveria +houveríamos +houveriam + + | forms of ser, to be (not including the infinitive): +sou +somos +são +era +éramos +eram +fui +foi +fomos +foram +fora +fôramos +seja +sejamos +sejam +fosse +fôssemos +fossem +for +formos +forem +serei +será +seremos +serão +seria +seríamos +seriam + + | forms of ter, to have (not including the infinitive): +tenho +tem +temos +tém +tinha +tínhamos +tinham +tive +teve +tivemos +tiveram +tivera +tivéramos +tenha +tenhamos +tenham +tivesse +tivéssemos +tivessem +tiver +tivermos +tiverem +terei +terá +teremos +terão +teria +teríamos +teriam diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ro.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ro.txt new file mode 100644 index 00000000000..4fdee90a5ba --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ro.txt @@ -0,0 +1,233 @@ +# This file was created by Jacques Savoy and is distributed under the BSD license. +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# Also see http://www.opensource.org/licenses/bsd-license.html +acea +aceasta +această +aceea +acei +aceia +acel +acela +acele +acelea +acest +acesta +aceste +acestea +aceşti +aceştia +acolo +acum +ai +aia +aibă +aici +al +ăla +ale +alea +ălea +altceva +altcineva +am +ar +are +aş +aşadar +asemenea +asta +ăsta +astăzi +astea +ăstea +ăştia +asupra +aţi +au +avea +avem +aveţi +azi +bine +bucur +bună +ca +că +căci +când +care +cărei +căror +cărui +cât +câte +câţi +către +câtva +ce +cel +ceva +chiar +cînd +cine +cineva +cît +cîte +cîţi +cîtva +contra +cu +cum +cumva +curând +curînd +da +dă +dacă +dar +datorită +de +deci +deja +deoarece +departe +deşi +din +dinaintea +dintr +dintre +drept +după +ea +ei +el +ele +eram +este +eşti +eu +face +fără +fi +fie +fiecare +fii +fim +fiţi +iar +ieri +îi +îl +îmi +împotriva +în +înainte +înaintea +încât +încît +încotro +între +întrucât +întrucît +îţi +la +lângă +le +li +lîngă +lor +lui +mă +mâine +mea +mei +mele +mereu +meu +mi +mine +mult +multă +mulţi +ne +nicăieri +nici +nimeni +nişte +noastră +noastre +noi +noştri +nostru +nu +ori +oricând +oricare +oricât +orice +oricînd +oricine +oricît +oricum +oriunde +până +pe +pentru +peste +pînă +poate +pot +prea +prima +primul +prin +printr +sa +să +săi +sale +sau +său +se +şi +sînt +sîntem +sînteţi +spre +sub +sunt +suntem +sunteţi +ta +tăi +tale +tău +te +ţi +ţie +tine +toată +toate +tot +toţi +totuşi +tu +un +una +unde +undeva +unei +unele +uneori +unor +vă +vi +voastră +voastre +voi +voştri +vostru +vouă +vreo +vreun diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ru.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ru.txt new file mode 100644 index 00000000000..64307693457 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ru.txt @@ -0,0 +1,241 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/russian/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | a russian stop word list. comments begin with vertical bar. each stop + | word is at the start of a line. + + | this is a ranked list (commonest to rarest) of stopwords derived from + | a large text sample. + + | letter `ё' is translated to `е'. + +и | and +в | in/into +во | alternative form +не | not +что | what/that +он | he +на | on/onto +я | i +с | from +со | alternative form +как | how +а | milder form of `no' (but) +то | conjunction and form of `that' +все | all +она | she +так | so, thus +его | him +но | but +да | yes/and +ты | thou +к | towards, by +у | around, chez +же | intensifier particle +вы | you +за | beyond, behind +бы | conditional/subj. particle +по | up to, along +только | only +ее | her +мне | to me +было | it was +вот | here is/are, particle +от | away from +меня | me +еще | still, yet, more +нет | no, there isnt/arent +о | about +из | out of +ему | to him +теперь | now +когда | when +даже | even +ну | so, well +вдруг | suddenly +ли | interrogative particle +если | if +уже | already, but homonym of `narrower' +или | or +ни | neither +быть | to be +был | he was +него | prepositional form of его +до | up to +вас | you accusative +нибудь | indef. suffix preceded by hyphen +опять | again +уж | already, but homonym of `adder' +вам | to you +сказал | he said +ведь | particle `after all' +там | there +потом | then +себя | oneself +ничего | nothing +ей | to her +может | usually with `быть' as `maybe' +они | they +тут | here +где | where +есть | there is/are +надо | got to, must +ней | prepositional form of ей +для | for +мы | we +тебя | thee +их | them, their +чем | than +была | she was +сам | self +чтоб | in order to +без | without +будто | as if +человек | man, person, one +чего | genitive form of `what' +раз | once +тоже | also +себе | to oneself +под | beneath +жизнь | life +будет | will be +ж | short form of intensifer particle `же' +тогда | then +кто | who +этот | this +говорил | was saying +того | genitive form of `that' +потому | for that reason +этого | genitive form of `this' +какой | which +совсем | altogether +ним | prepositional form of `его', `они' +здесь | here +этом | prepositional form of `этот' +один | one +почти | almost +мой | my +тем | instrumental/dative plural of `тот', `то' +чтобы | full form of `in order that' +нее | her (acc.) +кажется | it seems +сейчас | now +были | they were +куда | where to +зачем | why +сказать | to say +всех | all (acc., gen. preposn. plural) +никогда | never +сегодня | today +можно | possible, one can +при | by +наконец | finally +два | two +об | alternative form of `о', about +другой | another +хоть | even +после | after +над | above +больше | more +тот | that one (masc.) +через | across, in +эти | these +нас | us +про | about +всего | in all, only, of all +них | prepositional form of `они' (they) +какая | which, feminine +много | lots +разве | interrogative particle +сказала | she said +три | three +эту | this, acc. fem. sing. +моя | my, feminine +впрочем | moreover, besides +хорошо | good +свою | ones own, acc. fem. sing. +этой | oblique form of `эта', fem. `this' +перед | in front of +иногда | sometimes +лучше | better +чуть | a little +том | preposn. form of `that one' +нельзя | one must not +такой | such a one +им | to them +более | more +всегда | always +конечно | of course +всю | acc. fem. sing of `all' +между | between + + + | b: some paradigms + | + | personal pronouns + | + | я меня мне мной [мною] + | ты тебя тебе тобой [тобою] + | он его ему им [него, нему, ним] + | она ее эи ею [нее, нэи, нею] + | оно его ему им [него, нему, ним] + | + | мы нас нам нами + | вы вас вам вами + | они их им ими [них, ним, ними] + | + | себя себе собой [собою] + | + | demonstrative pronouns: этот (this), тот (that) + | + | этот эта это эти + | этого эты это эти + | этого этой этого этих + | этому этой этому этим + | этим этой этим [этою] этими + | этом этой этом этих + | + | тот та то те + | того ту то те + | того той того тех + | тому той тому тем + | тем той тем [тою] теми + | том той том тех + | + | determinative pronouns + | + | (a) весь (all) + | + | весь вся все все + | всего всю все все + | всего всей всего всех + | всему всей всему всем + | всем всей всем [всею] всеми + | всем всей всем всех + | + | (b) сам (himself etc) + | + | сам сама само сами + | самого саму само самих + | самого самой самого самих + | самому самой самому самим + | самим самой самим [самою] самими + | самом самой самом самих + | + | stems of verbs `to be', `to have', `to do' and modal + | + | быть бы буд быв есть суть + | име + | дел + | мог мож мочь + | уме + | хоч хот + | долж + | можн + | нужн + | нельзя + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_sv.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_sv.txt new file mode 100644 index 00000000000..22bddfd8cb3 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_sv.txt @@ -0,0 +1,131 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/swedish/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Swedish stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | This is a ranked list (commonest to rarest) of stopwords derived from + | a large text sample. + + | Swedish stop words occasionally exhibit homonym clashes. For example + | så = so, but also seed. These are indicated clearly below. + +och | and +det | it, this/that +att | to (with infinitive) +i | in, at +en | a +jag | I +hon | she +som | who, that +han | he +på | on +den | it, this/that +med | with +var | where, each +sig | him(self) etc +för | for +så | so (also: seed) +till | to +är | is +men | but +ett | a +om | if; around, about +hade | had +de | they, these/those +av | of +icke | not, no +mig | me +du | you +henne | her +då | then, when +sin | his +nu | now +har | have +inte | inte någon = no one +hans | his +honom | him +skulle | 'sake' +hennes | her +där | there +min | my +man | one (pronoun) +ej | nor +vid | at, by, on (also: vast) +kunde | could +något | some etc +från | from, off +ut | out +när | when +efter | after, behind +upp | up +vi | we +dem | them +vara | be +vad | what +över | over +än | than +dig | you +kan | can +sina | his +här | here +ha | have +mot | towards +alla | all +under | under (also: wonder) +någon | some etc +eller | or (else) +allt | all +mycket | much +sedan | since +ju | why +denna | this/that +själv | myself, yourself etc +detta | this/that +åt | to +utan | without +varit | was +hur | how +ingen | no +mitt | my +ni | you +bli | to be, become +blev | from bli +oss | us +din | thy +dessa | these/those +några | some etc +deras | their +blir | from bli +mina | my +samma | (the) same +vilken | who, that +er | you, your +sådan | such a +vår | our +blivit | from bli +dess | its +inom | within +mellan | between +sådant | such a +varför | why +varje | each +vilka | who, that +ditt | thy +vem | who +vilket | who, that +sitta | his +sådana | such a +vart | each +dina | thy +vars | whose +vårt | our +våra | our +ert | your +era | your +vilkas | whose + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_th.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_th.txt new file mode 100644 index 00000000000..07f0fabe692 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_th.txt @@ -0,0 +1,119 @@ +# Thai stopwords from: +# "Opinion Detection in Thai Political News Columns +# Based on Subjectivity Analysis" +# Khampol Sukhum, Supot Nitsuwat, and Choochart Haruechaiyasak +ไว้ +ไม่ +ไป +ได้ +ให้ +ใน +โดย +แห่ง +แล้ว +และ +แรก +แบบ +แต่ +เอง +เห็น +เลย +เริ่ม +เรา +เมื่อ +เพื่อ +เพราะ +เป็นการ +เป็น +เปิดเผย +เปิด +เนื่องจาก +เดียวกัน +เดียว +เช่น +เฉพาะ +เคย +เข้า +เขา +อีก +อาจ +อะไร +ออก +อย่าง +อยู่ +อยาก +หาก +หลาย +หลังจาก +หลัง +หรือ +หนึ่ง +ส่วน +ส่ง +สุด +สําหรับ +ว่า +วัน +ลง +ร่วม +ราย +รับ +ระหว่าง +รวม +ยัง +มี +มาก +มา +พร้อม +พบ +ผ่าน +ผล +บาง +น่า +นี้ +นํา +นั้น +นัก +นอกจาก +ทุก +ที่สุด +ที่ +ทําให้ +ทํา +ทาง +ทั้งนี้ +ทั้ง +ถ้า +ถูก +ถึง +ต้อง +ต่างๆ +ต่าง +ต่อ +ตาม +ตั้งแต่ +ตั้ง +ด้าน +ด้วย +ดัง +ซึ่ง +ช่วง +จึง +จาก +จัด +จะ +คือ +ความ +ครั้ง +คง +ขึ้น +ของ +ขอ +ขณะ +ก่อน +ก็ +การ +กับ +กัน +กว่า +กล่าว diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_tr.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_tr.txt new file mode 100644 index 00000000000..84d9408d4ea --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_tr.txt @@ -0,0 +1,212 @@ +# Turkish stopwords from LUCENE-559 +# merged with the list from "Information Retrieval on Turkish Texts" +# (http://www.users.muohio.edu/canf/papers/JASIST2008offPrint.pdf) +acaba +altmış +altı +ama +ancak +arada +aslında +ayrıca +bana +bazı +belki +ben +benden +beni +benim +beri +beş +bile +bin +bir +birçok +biri +birkaç +birkez +birşey +birşeyi +biz +bize +bizden +bizi +bizim +böyle +böylece +bu +buna +bunda +bundan +bunlar +bunları +bunların +bunu +bunun +burada +çok +çünkü +da +daha +dahi +de +defa +değil +diğer +diye +doksan +dokuz +dolayı +dolayısıyla +dört +edecek +eden +ederek +edilecek +ediliyor +edilmesi +ediyor +eğer +elli +en +etmesi +etti +ettiği +ettiğini +gibi +göre +halen +hangi +hatta +hem +henüz +hep +hepsi +her +herhangi +herkesin +hiç +hiçbir +için +iki +ile +ilgili +ise +işte +itibaren +itibariyle +kadar +karşın +katrilyon +kendi +kendilerine +kendini +kendisi +kendisine +kendisini +kez +ki +kim +kimden +kime +kimi +kimse +kırk +milyar +milyon +mu +mü +mı +nasıl +ne +neden +nedenle +nerde +nerede +nereye +niye +niçin +o +olan +olarak +oldu +olduğu +olduğunu +olduklarını +olmadı +olmadığı +olmak +olması +olmayan +olmaz +olsa +olsun +olup +olur +olursa +oluyor +on +ona +ondan +onlar +onlardan +onları +onların +onu +onun +otuz +oysa +öyle +pek +rağmen +sadece +sanki +sekiz +seksen +sen +senden +seni +senin +siz +sizden +sizi +sizin +şey +şeyden +şeyi +şeyler +şöyle +şu +şuna +şunda +şundan +şunları +şunu +tarafından +trilyon +tüm +üç +üzere +var +vardı +ve +veya +ya +yani +yapacak +yapılan +yapılması +yapıyor +yapmak +yaptı +yaptığı +yaptığını +yaptıkları +yedi +yerine +yetmiş +yine +yirmi +yoksa +yüz +zaten diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/userdict_ja.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/userdict_ja.txt new file mode 100644 index 00000000000..6f0368e4d81 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/userdict_ja.txt @@ -0,0 +1,29 @@ +# +# This is a sample user dictionary for Kuromoji (JapaneseTokenizer) +# +# Add entries to this file in order to override the statistical model in terms +# of segmentation, readings and part-of-speech tags. Notice that entries do +# not have weights since they are always used when found. This is by-design +# in order to maximize ease-of-use. +# +# Entries are defined using the following CSV format: +# , ... , ... , +# +# Notice that a single half-width space separates tokens and readings, and +# that the number tokens and readings must match exactly. +# +# Also notice that multiple entries with the same is undefined. +# +# Whitespace only lines are ignored. Comments are not allowed on entry lines. +# + +# Custom segmentation for kanji compounds +日本経済新聞,日本 経済 新聞,ニホン ケイザイ シンブン,カスタム名詞 +関西国際空港,関西 国際 空港,カンサイ コクサイ クウコウ,カスタム名詞 + +# Custom segmentation for compound katakana +トートバッグ,トート バッグ,トート バッグ,かずカナ名詞 +ショルダーバッグ,ショルダー バッグ,ショルダー バッグ,かずカナ名詞 + +# Custom reading for former sumo wrestler +朝青龍,朝青龍,アサショウリュウ,カスタム人名 diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/protwords.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/protwords.txt new file mode 100644 index 00000000000..1dfc0abecbf --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/protwords.txt @@ -0,0 +1,21 @@ +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#----------------------------------------------------------------------- +# Use a protected word file to protect against the stemmer reducing two +# unrelated words to the same base word. + +# Some non-words that normally won't be encountered, +# just to test that they won't be stemmed. +dontstems +zwhacky + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/schema.xml b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/schema.xml new file mode 100644 index 00000000000..ae2c56d18ae --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/schema.xml @@ -0,0 +1,947 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/solrconfig.xml b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/solrconfig.xml new file mode 100644 index 00000000000..9d9178746cf --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/solrconfig.xml @@ -0,0 +1,1764 @@ + + + + + + + + + LUCENE_43 + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${solr.data.dir:} + + + + + + + + + + + + + + + + ${solr.maxIndexingThreads:8} + + + + + + 128 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${solr.ulog.dir:} + + + + + ${solr.autoCommit.maxTime:60000} + false + + + + + + ${solr.autoSoftCommit.maxTime:1000} + + + + + + + + + + + + + + + + + + + + 1024 + + + + + + + + + + + + + + + + + + + + + + true + + + + + + 20 + + + 200 + + + + + + + + + + + + static firstSearcher warming in solrconfig.xml + + + + + + false + + + 4 + + + + + + + + + + + + + + + + + + + + + + + explicit + 10 + text + + + + + + + + + + + + + + explicit + json + true + text + + + + + + + + true + json + true + + + + + + + + explicit + + + velocity + browse + layout + Solritas + + + edismax + + text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 + title^10.0 description^5.0 keywords^5.0 author^2.0 resourcename^1.0 + + text + 100% + *:* + 10 + *,score + + + text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 + title^10.0 description^5.0 keywords^5.0 author^2.0 resourcename^1.0 + + text,features,name,sku,id,manu,cat,title,description,keywords,author,resourcename + 3 + + + on + cat + manu_exact + content_type + author_s + ipod + GB + 1 + cat,inStock + after + price + 0 + 600 + 50 + popularity + 0 + 10 + 3 + manufacturedate_dt + NOW/YEAR-10YEARS + NOW + +1YEAR + before + after + + + on + content features title name + html + <b> + </b> + 0 + title + 0 + name + 3 + 200 + content + 750 + + + on + false + 5 + 2 + 5 + true + true + 5 + 3 + + + + + spellcheck + + + + + + + + + + + + + + application/json + + + + + application/csv + + + + + + + + + + + + + + + + + + + + + solrpingquery + + + all + + + + + + + + + explicit + true + + + + + + + + + + + + + + + + textSpell + + + + + + default + name + solr.DirectSolrSpellChecker + + internal + + 0.5 + + 2 + + 1 + + 5 + + 4 + + 0.01 + + + + + + wordbreak + solr.WordBreakSolrSpellChecker + name + true + true + 10 + + + + + + + + + + + + + + + + text + + default + wordbreak + on + true + 10 + 5 + 5 + true + true + 10 + 5 + + + spellcheck + + + + + + + + + + text + true + + + tvComponent + + + + + + + + + default + + + org.carrot2.clustering.lingo.LingoClusteringAlgorithm + + + 20 + + + clustering/carrot2 + + + ENGLISH + + + stc + org.carrot2.clustering.stc.STCClusteringAlgorithm + + + + + + + true + default + true + + name + id + + features + + true + + + + false + + edismax + + text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 + + *:* + 10 + *,score + + + clustering + + + + + + + + + + true + + + terms + + + + + + + + string + elevate.xml + + + + + + explicit + text + + + elevator + + + + + + + + + + + 100 + + + + + + + + 70 + + 0.5 + + [-\w ,/\n\"']{20,200} + + + + + + + ]]> + ]]> + + + + + + + + + + + + + + + + + + + + + + + + ,, + ,, + ,, + ,, + ,]]> + ]]> + + + + + + 10 + .,!? + + + + + + + WORD + + + en + US + + + + + + + + + + + + + + + + + + + + + + text/plain; charset=UTF-8 + + + + + + + + + 5 + + + + + + + + + + + + + + + + + + *:* + + + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/stopwords.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/stopwords.txt new file mode 100644 index 00000000000..ae1e83eeb3d --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/stopwords.txt @@ -0,0 +1,14 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/synonyms.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/synonyms.txt new file mode 100644 index 00000000000..7f72128303b --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/synonyms.txt @@ -0,0 +1,29 @@ +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#----------------------------------------------------------------------- +#some test synonym mappings unlikely to appear in real input text +aaafoo => aaabar +bbbfoo => bbbfoo bbbbar +cccfoo => cccbar cccbaz +fooaaa,baraaa,bazaaa + +# Some synonym groups specific to this example +GB,gib,gigabyte,gigabytes +MB,mib,megabyte,megabytes +Television, Televisions, TV, TVs +#notice we use "gib" instead of "GiB" so any WordDelimiterFilter coming +#after us won't split it into two words. + +# Synonym mappings can be used for spelling correction too +pixima => pixma + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/currency.xml b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/currency.xml new file mode 100644 index 00000000000..3a9c58afee8 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/currency.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/elevate.xml b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/elevate.xml new file mode 100644 index 00000000000..25d5cebe4fb --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/elevate.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/contractions_ca.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/contractions_ca.txt new file mode 100644 index 00000000000..307a85f913d --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/contractions_ca.txt @@ -0,0 +1,8 @@ +# Set of Catalan contractions for ElisionFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +d +l +m +n +s +t diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/contractions_fr.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/contractions_fr.txt new file mode 100644 index 00000000000..722db588333 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/contractions_fr.txt @@ -0,0 +1,9 @@ +# Set of French contractions for ElisionFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +l +m +t +qu +n +s +j diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/contractions_ga.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/contractions_ga.txt new file mode 100644 index 00000000000..9ebe7fa349a --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/contractions_ga.txt @@ -0,0 +1,5 @@ +# Set of Irish contractions for ElisionFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +d +m +b diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/contractions_it.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/contractions_it.txt new file mode 100644 index 00000000000..cac04095372 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/contractions_it.txt @@ -0,0 +1,23 @@ +# Set of Italian contractions for ElisionFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +c +l +all +dall +dell +nell +sull +coll +pell +gl +agl +dagl +degl +negl +sugl +un +m +t +s +v +d diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/hyphenations_ga.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/hyphenations_ga.txt new file mode 100644 index 00000000000..4d2642cc5a3 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/hyphenations_ga.txt @@ -0,0 +1,5 @@ +# Set of Irish hyphenations for StopFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +h +n +t diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stemdict_nl.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stemdict_nl.txt new file mode 100644 index 00000000000..441072971d3 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stemdict_nl.txt @@ -0,0 +1,6 @@ +# Set of overrides for the dutch stemmer +# TODO: load this as a resource from the analyzer and sync it in build.xml +fiets fiets +bromfiets bromfiets +ei eier +kind kinder diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stoptags_ja.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stoptags_ja.txt new file mode 100644 index 00000000000..71b750845e3 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stoptags_ja.txt @@ -0,0 +1,420 @@ +# +# This file defines a Japanese stoptag set for JapanesePartOfSpeechStopFilter. +# +# Any token with a part-of-speech tag that exactly matches those defined in this +# file are removed from the token stream. +# +# Set your own stoptags by uncommenting the lines below. Note that comments are +# not allowed on the same line as a stoptag. See LUCENE-3745 for frequency lists, +# etc. that can be useful for building you own stoptag set. +# +# The entire possible tagset is provided below for convenience. +# +##### +# noun: unclassified nouns +#名詞 +# +# noun-common: Common nouns or nouns where the sub-classification is undefined +#名詞-一般 +# +# noun-proper: Proper nouns where the sub-classification is undefined +#名詞-固有名詞 +# +# noun-proper-misc: miscellaneous proper nouns +#名詞-固有名詞-一般 +# +# noun-proper-person: Personal names where the sub-classification is undefined +#名詞-固有名詞-人名 +# +# noun-proper-person-misc: names that cannot be divided into surname and +# given name; foreign names; names where the surname or given name is unknown. +# e.g. お市の方 +#名詞-固有名詞-人名-一般 +# +# noun-proper-person-surname: Mainly Japanese surnames. +# e.g. 山田 +#名詞-固有名詞-人名-姓 +# +# noun-proper-person-given_name: Mainly Japanese given names. +# e.g. 太郎 +#名詞-固有名詞-人名-名 +# +# noun-proper-organization: Names representing organizations. +# e.g. 通産省, NHK +#名詞-固有名詞-組織 +# +# noun-proper-place: Place names where the sub-classification is undefined +#名詞-固有名詞-地域 +# +# noun-proper-place-misc: Place names excluding countries. +# e.g. アジア, バルセロナ, 京都 +#名詞-固有名詞-地域-一般 +# +# noun-proper-place-country: Country names. +# e.g. 日本, オーストラリア +#名詞-固有名詞-地域-国 +# +# noun-pronoun: Pronouns where the sub-classification is undefined +#名詞-代名詞 +# +# noun-pronoun-misc: miscellaneous pronouns: +# e.g. それ, ここ, あいつ, あなた, あちこち, いくつ, どこか, なに, みなさん, みんな, わたくし, われわれ +#名詞-代名詞-一般 +# +# noun-pronoun-contraction: Spoken language contraction made by combining a +# pronoun and the particle 'wa'. +# e.g. ありゃ, こりゃ, こりゃあ, そりゃ, そりゃあ +#名詞-代名詞-縮約 +# +# noun-adverbial: Temporal nouns such as names of days or months that behave +# like adverbs. Nouns that represent amount or ratios and can be used adverbially, +# e.g. 金曜, 一月, 午後, 少量 +#名詞-副詞可能 +# +# noun-verbal: Nouns that take arguments with case and can appear followed by +# 'suru' and related verbs (する, できる, なさる, くださる) +# e.g. インプット, 愛着, 悪化, 悪戦苦闘, 一安心, 下取り +#名詞-サ変接続 +# +# noun-adjective-base: The base form of adjectives, words that appear before な ("na") +# e.g. 健康, 安易, 駄目, だめ +#名詞-形容動詞語幹 +# +# noun-numeric: Arabic numbers, Chinese numerals, and counters like 何 (回), 数. +# e.g. 0, 1, 2, 何, 数, 幾 +#名詞-数 +# +# noun-affix: noun affixes where the sub-classification is undefined +#名詞-非自立 +# +# noun-affix-misc: Of adnominalizers, the case-marker の ("no"), and words that +# attach to the base form of inflectional words, words that cannot be classified +# into any of the other categories below. This category includes indefinite nouns. +# e.g. あかつき, 暁, かい, 甲斐, 気, きらい, 嫌い, くせ, 癖, こと, 事, ごと, 毎, しだい, 次第, +# 順, せい, 所為, ついで, 序で, つもり, 積もり, 点, どころ, の, はず, 筈, はずみ, 弾み, +# 拍子, ふう, ふり, 振り, ほう, 方, 旨, もの, 物, 者, ゆえ, 故, ゆえん, 所以, わけ, 訳, +# わり, 割り, 割, ん-口語/, もん-口語/ +#名詞-非自立-一般 +# +# noun-affix-adverbial: noun affixes that that can behave as adverbs. +# e.g. あいだ, 間, あげく, 挙げ句, あと, 後, 余り, 以外, 以降, 以後, 以上, 以前, 一方, うえ, +# 上, うち, 内, おり, 折り, かぎり, 限り, きり, っきり, 結果, ころ, 頃, さい, 際, 最中, さなか, +# 最中, じたい, 自体, たび, 度, ため, 為, つど, 都度, とおり, 通り, とき, 時, ところ, 所, +# とたん, 途端, なか, 中, のち, 後, ばあい, 場合, 日, ぶん, 分, ほか, 他, まえ, 前, まま, +# 儘, 侭, みぎり, 矢先 +#名詞-非自立-副詞可能 +# +# noun-affix-aux: noun affixes treated as 助動詞 ("auxiliary verb") in school grammars +# with the stem よう(だ) ("you(da)"). +# e.g. よう, やう, 様 (よう) +#名詞-非自立-助動詞語幹 +# +# noun-affix-adjective-base: noun affixes that can connect to the indeclinable +# connection form な (aux "da"). +# e.g. みたい, ふう +#名詞-非自立-形容動詞語幹 +# +# noun-special: special nouns where the sub-classification is undefined. +#名詞-特殊 +# +# noun-special-aux: The そうだ ("souda") stem form that is used for reporting news, is +# treated as 助動詞 ("auxiliary verb") in school grammars, and attach to the base +# form of inflectional words. +# e.g. そう +#名詞-特殊-助動詞語幹 +# +# noun-suffix: noun suffixes where the sub-classification is undefined. +#名詞-接尾 +# +# noun-suffix-misc: Of the nouns or stem forms of other parts of speech that connect +# to ガル or タイ and can combine into compound nouns, words that cannot be classified into +# any of the other categories below. In general, this category is more inclusive than +# 接尾語 ("suffix") and is usually the last element in a compound noun. +# e.g. おき, かた, 方, 甲斐 (がい), がかり, ぎみ, 気味, ぐるみ, (~した) さ, 次第, 済 (ず) み, +# よう, (でき)っこ, 感, 観, 性, 学, 類, 面, 用 +#名詞-接尾-一般 +# +# noun-suffix-person: Suffixes that form nouns and attach to person names more often +# than other nouns. +# e.g. 君, 様, 著 +#名詞-接尾-人名 +# +# noun-suffix-place: Suffixes that form nouns and attach to place names more often +# than other nouns. +# e.g. 町, 市, 県 +#名詞-接尾-地域 +# +# noun-suffix-verbal: Of the suffixes that attach to nouns and form nouns, those that +# can appear before スル ("suru"). +# e.g. 化, 視, 分け, 入り, 落ち, 買い +#名詞-接尾-サ変接続 +# +# noun-suffix-aux: The stem form of そうだ (様態) that is used to indicate conditions, +# is treated as 助動詞 ("auxiliary verb") in school grammars, and attach to the +# conjunctive form of inflectional words. +# e.g. そう +#名詞-接尾-助動詞語幹 +# +# noun-suffix-adjective-base: Suffixes that attach to other nouns or the conjunctive +# form of inflectional words and appear before the copula だ ("da"). +# e.g. 的, げ, がち +#名詞-接尾-形容動詞語幹 +# +# noun-suffix-adverbial: Suffixes that attach to other nouns and can behave as adverbs. +# e.g. 後 (ご), 以後, 以降, 以前, 前後, 中, 末, 上, 時 (じ) +#名詞-接尾-副詞可能 +# +# noun-suffix-classifier: Suffixes that attach to numbers and form nouns. This category +# is more inclusive than 助数詞 ("classifier") and includes common nouns that attach +# to numbers. +# e.g. 個, つ, 本, 冊, パーセント, cm, kg, カ月, か国, 区画, 時間, 時半 +#名詞-接尾-助数詞 +# +# noun-suffix-special: Special suffixes that mainly attach to inflecting words. +# e.g. (楽し) さ, (考え) 方 +#名詞-接尾-特殊 +# +# noun-suffix-conjunctive: Nouns that behave like conjunctions and join two words +# together. +# e.g. (日本) 対 (アメリカ), 対 (アメリカ), (3) 対 (5), (女優) 兼 (主婦) +#名詞-接続詞的 +# +# noun-verbal_aux: Nouns that attach to the conjunctive particle て ("te") and are +# semantically verb-like. +# e.g. ごらん, ご覧, 御覧, 頂戴 +#名詞-動詞非自立的 +# +# noun-quotation: text that cannot be segmented into words, proverbs, Chinese poetry, +# dialects, English, etc. Currently, the only entry for 名詞 引用文字列 ("noun quotation") +# is いわく ("iwaku"). +#名詞-引用文字列 +# +# noun-nai_adjective: Words that appear before the auxiliary verb ない ("nai") and +# behave like an adjective. +# e.g. 申し訳, 仕方, とんでも, 違い +#名詞-ナイ形容詞語幹 +# +##### +# prefix: unclassified prefixes +#接頭詞 +# +# prefix-nominal: Prefixes that attach to nouns (including adjective stem forms) +# excluding numerical expressions. +# e.g. お (水), 某 (氏), 同 (社), 故 (~氏), 高 (品質), お (見事), ご (立派) +#接頭詞-名詞接続 +# +# prefix-verbal: Prefixes that attach to the imperative form of a verb or a verb +# in conjunctive form followed by なる/なさる/くださる. +# e.g. お (読みなさい), お (座り) +#接頭詞-動詞接続 +# +# prefix-adjectival: Prefixes that attach to adjectives. +# e.g. お (寒いですねえ), バカ (でかい) +#接頭詞-形容詞接続 +# +# prefix-numerical: Prefixes that attach to numerical expressions. +# e.g. 約, およそ, 毎時 +#接頭詞-数接続 +# +##### +# verb: unclassified verbs +#動詞 +# +# verb-main: +#動詞-自立 +# +# verb-auxiliary: +#動詞-非自立 +# +# verb-suffix: +#動詞-接尾 +# +##### +# adjective: unclassified adjectives +#形容詞 +# +# adjective-main: +#形容詞-自立 +# +# adjective-auxiliary: +#形容詞-非自立 +# +# adjective-suffix: +#形容詞-接尾 +# +##### +# adverb: unclassified adverbs +#副詞 +# +# adverb-misc: Words that can be segmented into one unit and where adnominal +# modification is not possible. +# e.g. あいかわらず, 多分 +#副詞-一般 +# +# adverb-particle_conjunction: Adverbs that can be followed by の, は, に, +# な, する, だ, etc. +# e.g. こんなに, そんなに, あんなに, なにか, なんでも +#副詞-助詞類接続 +# +##### +# adnominal: Words that only have noun-modifying forms. +# e.g. この, その, あの, どの, いわゆる, なんらかの, 何らかの, いろんな, こういう, そういう, ああいう, +# どういう, こんな, そんな, あんな, どんな, 大きな, 小さな, おかしな, ほんの, たいした, +# 「(, も) さる (ことながら)」, 微々たる, 堂々たる, 単なる, いかなる, 我が」「同じ, 亡き +#連体詞 +# +##### +# conjunction: Conjunctions that can occur independently. +# e.g. が, けれども, そして, じゃあ, それどころか +接続詞 +# +##### +# particle: unclassified particles. +助詞 +# +# particle-case: case particles where the subclassification is undefined. +助詞-格助詞 +# +# particle-case-misc: Case particles. +# e.g. から, が, で, と, に, へ, より, を, の, にて +助詞-格助詞-一般 +# +# particle-case-quote: the "to" that appears after nouns, a person’s speech, +# quotation marks, expressions of decisions from a meeting, reasons, judgements, +# conjectures, etc. +# e.g. ( だ) と (述べた.), ( である) と (して執行猶予...) +助詞-格助詞-引用 +# +# particle-case-compound: Compounds of particles and verbs that mainly behave +# like case particles. +# e.g. という, といった, とかいう, として, とともに, と共に, でもって, にあたって, に当たって, に当って, +# にあたり, に当たり, に当り, に当たる, にあたる, において, に於いて,に於て, における, に於ける, +# にかけ, にかけて, にかんし, に関し, にかんして, に関して, にかんする, に関する, に際し, +# に際して, にしたがい, に従い, に従う, にしたがって, に従って, にたいし, に対し, にたいして, +# に対して, にたいする, に対する, について, につき, につけ, につけて, につれ, につれて, にとって, +# にとり, にまつわる, によって, に依って, に因って, により, に依り, に因り, による, に依る, に因る, +# にわたって, にわたる, をもって, を以って, を通じ, を通じて, を通して, をめぐって, をめぐり, をめぐる, +# って-口語/, ちゅう-関西弁「という」/, (何) ていう (人)-口語/, っていう-口語/, といふ, とかいふ +助詞-格助詞-連語 +# +# particle-conjunctive: +# e.g. から, からには, が, けれど, けれども, けど, し, つつ, て, で, と, ところが, どころか, とも, ども, +# ながら, なり, ので, のに, ば, ものの, や ( した), やいなや, (ころん) じゃ(いけない)-口語/, +# (行っ) ちゃ(いけない)-口語/, (言っ) たって (しかたがない)-口語/, (それがなく)ったって (平気)-口語/ +助詞-接続助詞 +# +# particle-dependency: +# e.g. こそ, さえ, しか, すら, は, も, ぞ +助詞-係助詞 +# +# particle-adverbial: +# e.g. がてら, かも, くらい, 位, ぐらい, しも, (学校) じゃ(これが流行っている)-口語/, +# (それ)じゃあ (よくない)-口語/, ずつ, (私) なぞ, など, (私) なり (に), (先生) なんか (大嫌い)-口語/, +# (私) なんぞ, (先生) なんて (大嫌い)-口語/, のみ, だけ, (私) だって-口語/, だに, +# (彼)ったら-口語/, (お茶) でも (いかが), 等 (とう), (今後) とも, ばかり, ばっか-口語/, ばっかり-口語/, +# ほど, 程, まで, 迄, (誰) も (が)([助詞-格助詞] および [助詞-係助詞] の前に位置する「も」) +助詞-副助詞 +# +# particle-interjective: particles with interjective grammatical roles. +# e.g. (松島) や +助詞-間投助詞 +# +# particle-coordinate: +# e.g. と, たり, だの, だり, とか, なり, や, やら +助詞-並立助詞 +# +# particle-final: +# e.g. かい, かしら, さ, ぜ, (だ)っけ-口語/, (とまってる) で-方言/, な, ナ, なあ-口語/, ぞ, ね, ネ, +# ねぇ-口語/, ねえ-口語/, ねん-方言/, の, のう-口語/, や, よ, ヨ, よぉ-口語/, わ, わい-口語/ +助詞-終助詞 +# +# particle-adverbial/conjunctive/final: The particle "ka" when unknown whether it is +# adverbial, conjunctive, or sentence final. For example: +# (a) 「A か B か」. Ex:「(国内で運用する) か,(海外で運用する) か (.)」 +# (b) Inside an adverb phrase. Ex:「(幸いという) か (, 死者はいなかった.)」 +# 「(祈りが届いたせい) か (, 試験に合格した.)」 +# (c) 「かのように」. Ex:「(何もなかった) か (のように振る舞った.)」 +# e.g. か +助詞-副助詞/並立助詞/終助詞 +# +# particle-adnominalizer: The "no" that attaches to nouns and modifies +# non-inflectional words. +助詞-連体化 +# +# particle-adnominalizer: The "ni" and "to" that appear following nouns and adverbs +# that are giongo, giseigo, or gitaigo. +# e.g. に, と +助詞-副詞化 +# +# particle-special: A particle that does not fit into one of the above classifications. +# This includes particles that are used in Tanka, Haiku, and other poetry. +# e.g. かな, けむ, ( しただろう) に, (あんた) にゃ(わからん), (俺) ん (家) +助詞-特殊 +# +##### +# auxiliary-verb: +助動詞 +# +##### +# interjection: Greetings and other exclamations. +# e.g. おはよう, おはようございます, こんにちは, こんばんは, ありがとう, どうもありがとう, ありがとうございます, +# いただきます, ごちそうさま, さよなら, さようなら, はい, いいえ, ごめん, ごめんなさい +#感動詞 +# +##### +# symbol: unclassified Symbols. +記号 +# +# symbol-misc: A general symbol not in one of the categories below. +# e.g. [○◎@$〒→+] +記号-一般 +# +# symbol-comma: Commas +# e.g. [,、] +記号-読点 +# +# symbol-period: Periods and full stops. +# e.g. [..。] +記号-句点 +# +# symbol-space: Full-width whitespace. +記号-空白 +# +# symbol-open_bracket: +# e.g. [({‘“『【] +記号-括弧開 +# +# symbol-close_bracket: +# e.g. [)}’”』」】] +記号-括弧閉 +# +# symbol-alphabetic: +#記号-アルファベット +# +##### +# other: unclassified other +#その他 +# +# other-interjection: Words that are hard to classify as noun-suffixes or +# sentence-final particles. +# e.g. (だ)ァ +その他-間投 +# +##### +# filler: Aizuchi that occurs during a conversation or sounds inserted as filler. +# e.g. あの, うんと, えと +フィラー +# +##### +# non-verbal: non-verbal sound. +非言語音 +# +##### +# fragment: +#語断片 +# +##### +# unknown: unknown part of speech. +#未知語 +# +##### End of file diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ar.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ar.txt new file mode 100644 index 00000000000..046829db6a2 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ar.txt @@ -0,0 +1,125 @@ +# This file was created by Jacques Savoy and is distributed under the BSD license. +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# Also see http://www.opensource.org/licenses/bsd-license.html +# Cleaned on October 11, 2009 (not normalized, so use before normalization) +# This means that when modifying this list, you might need to add some +# redundant entries, for example containing forms with both أ and ا +من +ومن +منها +منه +في +وفي +فيها +فيه +و +ف +ثم +او +أو +ب +بها +به +ا +أ +اى +اي +أي +أى +لا +ولا +الا +ألا +إلا +لكن +ما +وما +كما +فما +عن +مع +اذا +إذا +ان +أن +إن +انها +أنها +إنها +انه +أنه +إنه +بان +بأن +فان +فأن +وان +وأن +وإن +التى +التي +الذى +الذي +الذين +الى +الي +إلى +إلي +على +عليها +عليه +اما +أما +إما +ايضا +أيضا +كل +وكل +لم +ولم +لن +ولن +هى +هي +هو +وهى +وهي +وهو +فهى +فهي +فهو +انت +أنت +لك +لها +له +هذه +هذا +تلك +ذلك +هناك +كانت +كان +يكون +تكون +وكانت +وكان +غير +بعض +قد +نحو +بين +بينما +منذ +ضمن +حيث +الان +الآن +خلال +بعد +قبل +حتى +عند +عندما +لدى +جميع diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_bg.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_bg.txt new file mode 100644 index 00000000000..1ae4ba2ae38 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_bg.txt @@ -0,0 +1,193 @@ +# This file was created by Jacques Savoy and is distributed under the BSD license. +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# Also see http://www.opensource.org/licenses/bsd-license.html +а +аз +ако +ала +бе +без +беше +би +бил +била +били +било +близо +бъдат +бъде +бяха +в +вас +ваш +ваша +вероятно +вече +взема +ви +вие +винаги +все +всеки +всички +всичко +всяка +във +въпреки +върху +г +ги +главно +го +д +да +дали +до +докато +докога +дори +досега +доста +е +едва +един +ето +за +зад +заедно +заради +засега +затова +защо +защото +и +из +или +им +има +имат +иска +й +каза +как +каква +какво +както +какъв +като +кога +когато +което +които +кой +който +колко +която +къде +където +към +ли +м +ме +между +мен +ми +мнозина +мога +могат +може +моля +момента +му +н +на +над +назад +най +направи +напред +например +нас +не +него +нея +ни +ние +никой +нито +но +някои +някой +няма +обаче +около +освен +особено +от +отгоре +отново +още +пак +по +повече +повечето +под +поне +поради +после +почти +прави +пред +преди +през +при +пък +първо +с +са +само +се +сега +си +скоро +след +сме +според +сред +срещу +сте +съм +със +също +т +тази +така +такива +такъв +там +твой +те +тези +ти +тн +то +това +тогава +този +той +толкова +точно +трябва +тук +тъй +тя +тях +у +харесва +ч +че +често +чрез +ще +щом +я diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ca.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ca.txt new file mode 100644 index 00000000000..3da65deafe1 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ca.txt @@ -0,0 +1,220 @@ +# Catalan stopwords from http://github.com/vcl/cue.language (Apache 2 Licensed) +a +abans +ací +ah +així +això +al +als +aleshores +algun +alguna +algunes +alguns +alhora +allà +allí +allò +altra +altre +altres +amb +ambdós +ambdues +apa +aquell +aquella +aquelles +aquells +aquest +aquesta +aquestes +aquests +aquí +baix +cada +cadascú +cadascuna +cadascunes +cadascuns +com +contra +d'un +d'una +d'unes +d'uns +dalt +de +del +dels +des +després +dins +dintre +donat +doncs +durant +e +eh +el +els +em +en +encara +ens +entre +érem +eren +éreu +es +és +esta +està +estàvem +estaven +estàveu +esteu +et +etc +ets +fins +fora +gairebé +ha +han +has +havia +he +hem +heu +hi +ho +i +igual +iguals +ja +l'hi +la +les +li +li'n +llavors +m'he +ma +mal +malgrat +mateix +mateixa +mateixes +mateixos +me +mentre +més +meu +meus +meva +meves +molt +molta +moltes +molts +mon +mons +n'he +n'hi +ne +ni +no +nogensmenys +només +nosaltres +nostra +nostre +nostres +o +oh +oi +on +pas +pel +pels +per +però +perquè +poc +poca +pocs +poques +potser +propi +qual +quals +quan +quant +que +què +quelcom +qui +quin +quina +quines +quins +s'ha +s'han +sa +semblant +semblants +ses +seu +seus +seva +seva +seves +si +sobre +sobretot +sóc +solament +sols +son +són +sons +sota +sou +t'ha +t'han +t'he +ta +tal +també +tampoc +tan +tant +tanta +tantes +teu +teus +teva +teves +ton +tons +tot +tota +totes +tots +un +una +unes +uns +us +va +vaig +vam +van +vas +veu +vosaltres +vostra +vostre +vostres diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_cz.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_cz.txt new file mode 100644 index 00000000000..53c6097dac7 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_cz.txt @@ -0,0 +1,172 @@ +a +s +k +o +i +u +v +z +dnes +cz +tímto +budeš +budem +byli +jseš +můj +svým +ta +tomto +tohle +tuto +tyto +jej +zda +proč +máte +tato +kam +tohoto +kdo +kteří +mi +nám +tom +tomuto +mít +nic +proto +kterou +byla +toho +protože +asi +ho +naši +napište +re +což +tím +takže +svých +její +svými +jste +aj +tu +tedy +teto +bylo +kde +ke +pravé +ji +nad +nejsou +či +pod +téma +mezi +přes +ty +pak +vám +ani +když +však +neg +jsem +tento +článku +články +aby +jsme +před +pta +jejich +byl +ještě +až +bez +také +pouze +první +vaše +která +nás +nový +tipy +pokud +může +strana +jeho +své +jiné +zprávy +nové +není +vás +jen +podle +zde +už +být +více +bude +již +než +který +by +které +co +nebo +ten +tak +má +při +od +po +jsou +jak +další +ale +si +se +ve +to +jako +za +zpět +ze +do +pro +je +na +atd +atp +jakmile +přičemž +já +on +ona +ono +oni +ony +my +vy +jí +ji +mě +mne +jemu +tomu +těm +těmu +němu +němuž +jehož +jíž +jelikož +jež +jakož +načež diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_da.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_da.txt new file mode 100644 index 00000000000..a3ff5fe122c --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_da.txt @@ -0,0 +1,108 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/danish/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Danish stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | This is a ranked list (commonest to rarest) of stopwords derived from + | a large text sample. + + +og | and +i | in +jeg | I +det | that (dem. pronoun)/it (pers. pronoun) +at | that (in front of a sentence)/to (with infinitive) +en | a/an +den | it (pers. pronoun)/that (dem. pronoun) +til | to/at/for/until/against/by/of/into, more +er | present tense of "to be" +som | who, as +på | on/upon/in/on/at/to/after/of/with/for, on +de | they +med | with/by/in, along +han | he +af | of/by/from/off/for/in/with/on, off +for | at/for/to/from/by/of/ago, in front/before, because +ikke | not +der | who/which, there/those +var | past tense of "to be" +mig | me/myself +sig | oneself/himself/herself/itself/themselves +men | but +et | a/an/one, one (number), someone/somebody/one +har | present tense of "to have" +om | round/about/for/in/a, about/around/down, if +vi | we +min | my +havde | past tense of "to have" +ham | him +hun | she +nu | now +over | over/above/across/by/beyond/past/on/about, over/past +da | then, when/as/since +fra | from/off/since, off, since +du | you +ud | out +sin | his/her/its/one's +dem | them +os | us/ourselves +op | up +man | you/one +hans | his +hvor | where +eller | or +hvad | what +skal | must/shall etc. +selv | myself/youself/herself/ourselves etc., even +her | here +alle | all/everyone/everybody etc. +vil | will (verb) +blev | past tense of "to stay/to remain/to get/to become" +kunne | could +ind | in +når | when +være | present tense of "to be" +dog | however/yet/after all +noget | something +ville | would +jo | you know/you see (adv), yes +deres | their/theirs +efter | after/behind/according to/for/by/from, later/afterwards +ned | down +skulle | should +denne | this +end | than +dette | this +mit | my/mine +også | also +under | under/beneath/below/during, below/underneath +have | have +dig | you +anden | other +hende | her +mine | my +alt | everything +meget | much/very, plenty of +sit | his, her, its, one's +sine | his, her, its, one's +vor | our +mod | against +disse | these +hvis | if +din | your/yours +nogle | some +hos | by/at +blive | be/become +mange | many +ad | by/through +bliver | present tense of "to be/to become" +hendes | her/hers +været | be +thi | for (conj) +jer | you +sådan | such, like this/like that diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_de.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_de.txt new file mode 100644 index 00000000000..f7703841887 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_de.txt @@ -0,0 +1,292 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/german/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A German stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | The number of forms in this list is reduced significantly by passing it + | through the German stemmer. + + +aber | but + +alle | all +allem +allen +aller +alles + +als | than, as +also | so +am | an + dem +an | at + +ander | other +andere +anderem +anderen +anderer +anderes +anderm +andern +anderr +anders + +auch | also +auf | on +aus | out of +bei | by +bin | am +bis | until +bist | art +da | there +damit | with it +dann | then + +der | the +den +des +dem +die +das + +daß | that + +derselbe | the same +derselben +denselben +desselben +demselben +dieselbe +dieselben +dasselbe + +dazu | to that + +dein | thy +deine +deinem +deinen +deiner +deines + +denn | because + +derer | of those +dessen | of him + +dich | thee +dir | to thee +du | thou + +dies | this +diese +diesem +diesen +dieser +dieses + + +doch | (several meanings) +dort | (over) there + + +durch | through + +ein | a +eine +einem +einen +einer +eines + +einig | some +einige +einigem +einigen +einiger +einiges + +einmal | once + +er | he +ihn | him +ihm | to him + +es | it +etwas | something + +euer | your +eure +eurem +euren +eurer +eures + +für | for +gegen | towards +gewesen | p.p. of sein +hab | have +habe | have +haben | have +hat | has +hatte | had +hatten | had +hier | here +hin | there +hinter | behind + +ich | I +mich | me +mir | to me + + +ihr | you, to her +ihre +ihrem +ihren +ihrer +ihres +euch | to you + +im | in + dem +in | in +indem | while +ins | in + das +ist | is + +jede | each, every +jedem +jeden +jeder +jedes + +jene | that +jenem +jenen +jener +jenes + +jetzt | now +kann | can + +kein | no +keine +keinem +keinen +keiner +keines + +können | can +könnte | could +machen | do +man | one + +manche | some, many a +manchem +manchen +mancher +manches + +mein | my +meine +meinem +meinen +meiner +meines + +mit | with +muss | must +musste | had to +nach | to(wards) +nicht | not +nichts | nothing +noch | still, yet +nun | now +nur | only +ob | whether +oder | or +ohne | without +sehr | very + +sein | his +seine +seinem +seinen +seiner +seines + +selbst | self +sich | herself + +sie | they, she +ihnen | to them + +sind | are +so | so + +solche | such +solchem +solchen +solcher +solches + +soll | shall +sollte | should +sondern | but +sonst | else +über | over +um | about, around +und | and + +uns | us +unse +unsem +unsen +unser +unses + +unter | under +viel | much +vom | von + dem +von | from +vor | before +während | while +war | was +waren | were +warst | wast +was | what +weg | away, off +weil | because +weiter | further + +welche | which +welchem +welchen +welcher +welches + +wenn | when +werde | will +werden | will +wie | how +wieder | again +will | want +wir | we +wird | will +wirst | willst +wo | where +wollen | want +wollte | wanted +würde | would +würden | would +zu | to +zum | zu + dem +zur | zu + der +zwar | indeed +zwischen | between + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_el.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_el.txt new file mode 100644 index 00000000000..232681f5bd6 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_el.txt @@ -0,0 +1,78 @@ +# Lucene Greek Stopwords list +# Note: by default this file is used after GreekLowerCaseFilter, +# so when modifying this file use 'σ' instead of 'ς' +ο +η +το +οι +τα +του +τησ +των +τον +την +και +κι +κ +ειμαι +εισαι +ειναι +ειμαστε +ειστε +στο +στον +στη +στην +μα +αλλα +απο +για +προσ +με +σε +ωσ +παρα +αντι +κατα +μετα +θα +να +δε +δεν +μη +μην +επι +ενω +εαν +αν +τοτε +που +πωσ +ποιοσ +ποια +ποιο +ποιοι +ποιεσ +ποιων +ποιουσ +αυτοσ +αυτη +αυτο +αυτοι +αυτων +αυτουσ +αυτεσ +αυτα +εκεινοσ +εκεινη +εκεινο +εκεινοι +εκεινεσ +εκεινα +εκεινων +εκεινουσ +οπωσ +ομωσ +ισωσ +οσο +οτι diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_en.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_en.txt new file mode 100644 index 00000000000..2c164c0b2a1 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_en.txt @@ -0,0 +1,54 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# a couple of test stopwords to test that the words are really being +# configured from this file: +stopworda +stopwordb + +# Standard english stop words taken from Lucene's StopAnalyzer +a +an +and +are +as +at +be +but +by +for +if +in +into +is +it +no +not +of +on +or +such +that +the +their +then +there +these +they +this +to +was +will +with diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_es.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_es.txt new file mode 100644 index 00000000000..2db14760075 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_es.txt @@ -0,0 +1,354 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/spanish/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Spanish stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + + | The following is a ranked list (commonest to rarest) of stopwords + | deriving from a large sample of text. + + | Extra words have been added at the end. + +de | from, of +la | the, her +que | who, that +el | the +en | in +y | and +a | to +los | the, them +del | de + el +se | himself, from him etc +las | the, them +por | for, by, etc +un | a +para | for +con | with +no | no +una | a +su | his, her +al | a + el + | es from SER +lo | him +como | how +más | more +pero | pero +sus | su plural +le | to him, her +ya | already +o | or + | fue from SER +este | this + | ha from HABER +sí | himself etc +porque | because +esta | this + | son from SER +entre | between + | está from ESTAR +cuando | when +muy | very +sin | without +sobre | on + | ser from SER + | tiene from TENER +también | also +me | me +hasta | until +hay | there is/are +donde | where + | han from HABER +quien | whom, that + | están from ESTAR + | estado from ESTAR +desde | from +todo | all +nos | us +durante | during + | estados from ESTAR +todos | all +uno | a +les | to them +ni | nor +contra | against +otros | other + | fueron from SER +ese | that +eso | that + | había from HABER +ante | before +ellos | they +e | and (variant of y) +esto | this +mí | me +antes | before +algunos | some +qué | what? +unos | a +yo | I +otro | other +otras | other +otra | other +él | he +tanto | so much, many +esa | that +estos | these +mucho | much, many +quienes | who +nada | nothing +muchos | many +cual | who + | sea from SER +poco | few +ella | she +estar | to be + | haber from HABER +estas | these + | estaba from ESTAR + | estamos from ESTAR +algunas | some +algo | something +nosotros | we + + | other forms + +mi | me +mis | mi plural +tú | thou +te | thee +ti | thee +tu | thy +tus | tu plural +ellas | they +nosotras | we +vosotros | you +vosotras | you +os | you +mío | mine +mía | +míos | +mías | +tuyo | thine +tuya | +tuyos | +tuyas | +suyo | his, hers, theirs +suya | +suyos | +suyas | +nuestro | ours +nuestra | +nuestros | +nuestras | +vuestro | yours +vuestra | +vuestros | +vuestras | +esos | those +esas | those + + | forms of estar, to be (not including the infinitive): +estoy +estás +está +estamos +estáis +están +esté +estés +estemos +estéis +estén +estaré +estarás +estará +estaremos +estaréis +estarán +estaría +estarías +estaríamos +estaríais +estarían +estaba +estabas +estábamos +estabais +estaban +estuve +estuviste +estuvo +estuvimos +estuvisteis +estuvieron +estuviera +estuvieras +estuviéramos +estuvierais +estuvieran +estuviese +estuvieses +estuviésemos +estuvieseis +estuviesen +estando +estado +estada +estados +estadas +estad + + | forms of haber, to have (not including the infinitive): +he +has +ha +hemos +habéis +han +haya +hayas +hayamos +hayáis +hayan +habré +habrás +habrá +habremos +habréis +habrán +habría +habrías +habríamos +habríais +habrían +había +habías +habíamos +habíais +habían +hube +hubiste +hubo +hubimos +hubisteis +hubieron +hubiera +hubieras +hubiéramos +hubierais +hubieran +hubiese +hubieses +hubiésemos +hubieseis +hubiesen +habiendo +habido +habida +habidos +habidas + + | forms of ser, to be (not including the infinitive): +soy +eres +es +somos +sois +son +sea +seas +seamos +seáis +sean +seré +serás +será +seremos +seréis +serán +sería +serías +seríamos +seríais +serían +era +eras +éramos +erais +eran +fui +fuiste +fue +fuimos +fuisteis +fueron +fuera +fueras +fuéramos +fuerais +fueran +fuese +fueses +fuésemos +fueseis +fuesen +siendo +sido + | sed also means 'thirst' + + | forms of tener, to have (not including the infinitive): +tengo +tienes +tiene +tenemos +tenéis +tienen +tenga +tengas +tengamos +tengáis +tengan +tendré +tendrás +tendrá +tendremos +tendréis +tendrán +tendría +tendrías +tendríamos +tendríais +tendrían +tenía +tenías +teníamos +teníais +tenían +tuve +tuviste +tuvo +tuvimos +tuvisteis +tuvieron +tuviera +tuvieras +tuviéramos +tuvierais +tuvieran +tuviese +tuvieses +tuviésemos +tuvieseis +tuviesen +teniendo +tenido +tenida +tenidos +tenidas +tened + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_eu.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_eu.txt new file mode 100644 index 00000000000..25f1db93460 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_eu.txt @@ -0,0 +1,99 @@ +# example set of basque stopwords +al +anitz +arabera +asko +baina +bat +batean +batek +bati +batzuei +batzuek +batzuetan +batzuk +bera +beraiek +berau +berauek +bere +berori +beroriek +beste +bezala +da +dago +dira +ditu +du +dute +edo +egin +ere +eta +eurak +ez +gainera +gu +gutxi +guzti +haiei +haiek +haietan +hainbeste +hala +han +handik +hango +hara +hari +hark +hartan +hau +hauei +hauek +hauetan +hemen +hemendik +hemengo +hi +hona +honek +honela +honetan +honi +hor +hori +horiei +horiek +horietan +horko +horra +horrek +horrela +horretan +horri +hortik +hura +izan +ni +noiz +nola +non +nondik +nongo +nor +nora +ze +zein +zen +zenbait +zenbat +zer +zergatik +ziren +zituen +zu +zuek +zuen +zuten diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_fa.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_fa.txt new file mode 100644 index 00000000000..723641c6da7 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_fa.txt @@ -0,0 +1,313 @@ +# This file was created by Jacques Savoy and is distributed under the BSD license. +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# Also see http://www.opensource.org/licenses/bsd-license.html +# Note: by default this file is used after normalization, so when adding entries +# to this file, use the arabic 'ي' instead of 'ی' +انان +نداشته +سراسر +خياه +ايشان +وي +تاكنون +بيشتري +دوم +پس +ناشي +وگو +يا +داشتند +سپس +هنگام +هرگز +پنج +نشان +امسال +ديگر +گروهي +شدند +چطور +ده +و +دو +نخستين +ولي +چرا +چه +وسط +ه +كدام +قابل +يك +رفت +هفت +همچنين +در +هزار +بله +بلي +شايد +اما +شناسي +گرفته +دهد +داشته +دانست +داشتن +خواهيم +ميليارد +وقتيكه +امد +خواهد +جز +اورده +شده +بلكه +خدمات +شدن +برخي +نبود +بسياري +جلوگيري +حق +كردند +نوعي +بعري +نكرده +نظير +نبايد +بوده +بودن +داد +اورد +هست +جايي +شود +دنبال +داده +بايد +سابق +هيچ +همان +انجا +كمتر +كجاست +گردد +كسي +تر +مردم +تان +دادن +بودند +سري +جدا +ندارند +مگر +يكديگر +دارد +دهند +بنابراين +هنگامي +سمت +جا +انچه +خود +دادند +زياد +دارند +اثر +بدون +بهترين +بيشتر +البته +به +براساس +بيرون +كرد +بعضي +گرفت +توي +اي +ميليون +او +جريان +تول +بر +مانند +برابر +باشيم +مدتي +گويند +اكنون +تا +تنها +جديد +چند +بي +نشده +كردن +كردم +گويد +كرده +كنيم +نمي +نزد +روي +قصد +فقط +بالاي +ديگران +اين +ديروز +توسط +سوم +ايم +دانند +سوي +استفاده +شما +كنار +داريم +ساخته +طور +امده +رفته +نخست +بيست +نزديك +طي +كنيد +از +انها +تمامي +داشت +يكي +طريق +اش +چيست +روب +نمايد +گفت +چندين +چيزي +تواند +ام +ايا +با +ان +ايد +ترين +اينكه +ديگري +راه +هايي +بروز +همچنان +پاعين +كس +حدود +مختلف +مقابل +چيز +گيرد +ندارد +ضد +همچون +سازي +شان +مورد +باره +مرسي +خويش +برخوردار +چون +خارج +شش +هنوز +تحت +ضمن +هستيم +گفته +فكر +بسيار +پيش +براي +روزهاي +انكه +نخواهد +بالا +كل +وقتي +كي +چنين +كه +گيري +نيست +است +كجا +كند +نيز +يابد +بندي +حتي +توانند +عقب +خواست +كنند +بين +تمام +همه +ما +باشند +مثل +شد +اري +باشد +اره +طبق +بعد +اگر +صورت +غير +جاي +بيش +ريزي +اند +زيرا +چگونه +بار +لطفا +مي +درباره +من +ديده +همين +گذاري +برداري +علت +گذاشته +هم +فوق +نه +ها +شوند +اباد +همواره +هر +اول +خواهند +چهار +نام +امروز +مان +هاي +قبل +كنم +سعي +تازه +را +هستند +زير +جلوي +عنوان +بود diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_fi.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_fi.txt new file mode 100644 index 00000000000..addad798c4b --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_fi.txt @@ -0,0 +1,95 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/finnish/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + +| forms of BE + +olla +olen +olet +on +olemme +olette +ovat +ole | negative form + +oli +olisi +olisit +olisin +olisimme +olisitte +olisivat +olit +olin +olimme +olitte +olivat +ollut +olleet + +en | negation +et +ei +emme +ette +eivät + +|Nom Gen Acc Part Iness Elat Illat Adess Ablat Allat Ess Trans +minä minun minut minua minussa minusta minuun minulla minulta minulle | I +sinä sinun sinut sinua sinussa sinusta sinuun sinulla sinulta sinulle | you +hän hänen hänet häntä hänessä hänestä häneen hänellä häneltä hänelle | he she +me meidän meidät meitä meissä meistä meihin meillä meiltä meille | we +te teidän teidät teitä teissä teistä teihin teillä teiltä teille | you +he heidän heidät heitä heissä heistä heihin heillä heiltä heille | they + +tämä tämän tätä tässä tästä tähän tallä tältä tälle tänä täksi | this +tuo tuon tuotä tuossa tuosta tuohon tuolla tuolta tuolle tuona tuoksi | that +se sen sitä siinä siitä siihen sillä siltä sille sinä siksi | it +nämä näiden näitä näissä näistä näihin näillä näiltä näille näinä näiksi | these +nuo noiden noita noissa noista noihin noilla noilta noille noina noiksi | those +ne niiden niitä niissä niistä niihin niillä niiltä niille niinä niiksi | they + +kuka kenen kenet ketä kenessä kenestä keneen kenellä keneltä kenelle kenenä keneksi| who +ketkä keiden ketkä keitä keissä keistä keihin keillä keiltä keille keinä keiksi | (pl) +mikä minkä minkä mitä missä mistä mihin millä miltä mille minä miksi | which what +mitkä | (pl) + +joka jonka jota jossa josta johon jolla jolta jolle jona joksi | who which +jotka joiden joita joissa joista joihin joilla joilta joille joina joiksi | (pl) + +| conjunctions + +että | that +ja | and +jos | if +koska | because +kuin | than +mutta | but +niin | so +sekä | and +sillä | for +tai | or +vaan | but +vai | or +vaikka | although + + +| prepositions + +kanssa | with +mukaan | according to +noin | about +poikki | across +yli | over, across + +| other + +kun | when +niin | so +nyt | now +itse | self + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_fr.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_fr.txt new file mode 100644 index 00000000000..c00837ea939 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_fr.txt @@ -0,0 +1,183 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/french/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A French stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + +au | a + le +aux | a + les +avec | with +ce | this +ces | these +dans | with +de | of +des | de + les +du | de + le +elle | she +en | `of them' etc +et | and +eux | them +il | he +je | I +la | the +le | the +leur | their +lui | him +ma | my (fem) +mais | but +me | me +même | same; as in moi-même (myself) etc +mes | me (pl) +moi | me +mon | my (masc) +ne | not +nos | our (pl) +notre | our +nous | we +on | one +ou | where +par | by +pas | not +pour | for +qu | que before vowel +que | that +qui | who +sa | his, her (fem) +se | oneself +ses | his (pl) +son | his, her (masc) +sur | on +ta | thy (fem) +te | thee +tes | thy (pl) +toi | thee +ton | thy (masc) +tu | thou +un | a +une | a +vos | your (pl) +votre | your +vous | you + + | single letter forms + +c | c' +d | d' +j | j' +l | l' +à | to, at +m | m' +n | n' +s | s' +t | t' +y | there + + | forms of être (not including the infinitive): +été +étée +étées +étés +étant +suis +es +est +sommes +êtes +sont +serai +seras +sera +serons +serez +seront +serais +serait +serions +seriez +seraient +étais +était +étions +étiez +étaient +fus +fut +fûmes +fûtes +furent +sois +soit +soyons +soyez +soient +fusse +fusses +fût +fussions +fussiez +fussent + + | forms of avoir (not including the infinitive): +ayant +eu +eue +eues +eus +ai +as +avons +avez +ont +aurai +auras +aura +aurons +aurez +auront +aurais +aurait +aurions +auriez +auraient +avais +avait +avions +aviez +avaient +eut +eûmes +eûtes +eurent +aie +aies +ait +ayons +ayez +aient +eusse +eusses +eût +eussions +eussiez +eussent + + | Later additions (from Jean-Christophe Deschamps) +ceci | this +celà  | that +cet | this +cette | this +ici | here +ils | they +les | the (pl) +leurs | their (pl) +quel | which +quels | which +quelle | which +quelles | which +sans | without +soi | oneself + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ga.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ga.txt new file mode 100644 index 00000000000..9ff88d747e5 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ga.txt @@ -0,0 +1,110 @@ + +a +ach +ag +agus +an +aon +ar +arna +as +b' +ba +beirt +bhúr +caoga +ceathair +ceathrar +chomh +chtó +chuig +chun +cois +céad +cúig +cúigear +d' +daichead +dar +de +deich +deichniúr +den +dhá +do +don +dtí +dá +dár +dó +faoi +faoin +faoina +faoinár +fara +fiche +gach +gan +go +gur +haon +hocht +i +iad +idir +in +ina +ins +inár +is +le +leis +lena +lenár +m' +mar +mo +mé +na +nach +naoi +naonúr +ná +ní +níor +nó +nócha +ocht +ochtar +os +roimh +sa +seacht +seachtar +seachtó +seasca +seisear +siad +sibh +sinn +sna +sé +sí +tar +thar +thú +triúr +trí +trína +trínár +tríocha +tú +um +ár +é +éis +í +ó +ón +óna +ónár diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_gl.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_gl.txt new file mode 100644 index 00000000000..d8760b12c14 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_gl.txt @@ -0,0 +1,161 @@ +# galican stopwords +a +aínda +alí +aquel +aquela +aquelas +aqueles +aquilo +aquí +ao +aos +as +así +á +ben +cando +che +co +coa +comigo +con +connosco +contigo +convosco +coas +cos +cun +cuns +cunha +cunhas +da +dalgunha +dalgunhas +dalgún +dalgúns +das +de +del +dela +delas +deles +desde +deste +do +dos +dun +duns +dunha +dunhas +e +el +ela +elas +eles +en +era +eran +esa +esas +ese +eses +esta +estar +estaba +está +están +este +estes +estiven +estou +eu +é +facer +foi +foron +fun +había +hai +iso +isto +la +las +lle +lles +lo +los +mais +me +meu +meus +min +miña +miñas +moi +na +nas +neste +nin +no +non +nos +nosa +nosas +noso +nosos +nós +nun +nunha +nuns +nunhas +o +os +ou +ó +ós +para +pero +pode +pois +pola +polas +polo +polos +por +que +se +senón +ser +seu +seus +sexa +sido +sobre +súa +súas +tamén +tan +te +ten +teñen +teño +ter +teu +teus +ti +tido +tiña +tiven +túa +túas +un +unha +unhas +uns +vos +vosa +vosas +voso +vosos +vós diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_hi.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_hi.txt new file mode 100644 index 00000000000..86286bb083b --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_hi.txt @@ -0,0 +1,235 @@ +# Also see http://www.opensource.org/licenses/bsd-license.html +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# This file was created by Jacques Savoy and is distributed under the BSD license. +# Note: by default this file also contains forms normalized by HindiNormalizer +# for spelling variation (see section below), such that it can be used whether or +# not you enable that feature. When adding additional entries to this list, +# please add the normalized form as well. +अंदर +अत +अपना +अपनी +अपने +अभी +आदि +आप +इत्यादि +इन +इनका +इन्हीं +इन्हें +इन्हों +इस +इसका +इसकी +इसके +इसमें +इसी +इसे +उन +उनका +उनकी +उनके +उनको +उन्हीं +उन्हें +उन्हों +उस +उसके +उसी +उसे +एक +एवं +एस +ऐसे +और +कई +कर +करता +करते +करना +करने +करें +कहते +कहा +का +काफ़ी +कि +कितना +किन्हें +किन्हों +किया +किर +किस +किसी +किसे +की +कुछ +कुल +के +को +कोई +कौन +कौनसा +गया +घर +जब +जहाँ +जा +जितना +जिन +जिन्हें +जिन्हों +जिस +जिसे +जीधर +जैसा +जैसे +जो +तक +तब +तरह +तिन +तिन्हें +तिन्हों +तिस +तिसे +तो +था +थी +थे +दबारा +दिया +दुसरा +दूसरे +दो +द्वारा +न +नहीं +ना +निहायत +नीचे +ने +पर +पर +पहले +पूरा +पे +फिर +बनी +बही +बहुत +बाद +बाला +बिलकुल +भी +भीतर +मगर +मानो +मे +में +यदि +यह +यहाँ +यही +या +यिह +ये +रखें +रहा +रहे +ऱ्वासा +लिए +लिये +लेकिन +व +वर्ग +वह +वह +वहाँ +वहीं +वाले +वुह +वे +वग़ैरह +संग +सकता +सकते +सबसे +सभी +साथ +साबुत +साभ +सारा +से +सो +ही +हुआ +हुई +हुए +है +हैं +हो +होता +होती +होते +होना +होने +# additional normalized forms of the above +अपनि +जेसे +होति +सभि +तिंहों +इंहों +दवारा +इसि +किंहें +थि +उंहों +ओर +जिंहें +वहिं +अभि +बनि +हि +उंहिं +उंहें +हें +वगेरह +एसे +रवासा +कोन +निचे +काफि +उसि +पुरा +भितर +हे +बहि +वहां +कोइ +यहां +जिंहों +तिंहें +किसि +कइ +यहि +इंहिं +जिधर +इंहें +अदि +इतयादि +हुइ +कोनसा +इसकि +दुसरे +जहां +अप +किंहों +उनकि +भि +वरग +हुअ +जेसा +नहिं diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_hu.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_hu.txt new file mode 100644 index 00000000000..1a96f1db6f2 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_hu.txt @@ -0,0 +1,209 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/hungarian/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + +| Hungarian stop word list +| prepared by Anna Tordai + +a +ahogy +ahol +aki +akik +akkor +alatt +által +általában +amely +amelyek +amelyekben +amelyeket +amelyet +amelynek +ami +amit +amolyan +amíg +amikor +át +abban +ahhoz +annak +arra +arról +az +azok +azon +azt +azzal +azért +aztán +azután +azonban +bár +be +belül +benne +cikk +cikkek +cikkeket +csak +de +e +eddig +egész +egy +egyes +egyetlen +egyéb +egyik +egyre +ekkor +el +elég +ellen +elő +először +előtt +első +én +éppen +ebben +ehhez +emilyen +ennek +erre +ez +ezt +ezek +ezen +ezzel +ezért +és +fel +felé +hanem +hiszen +hogy +hogyan +igen +így +illetve +ill. +ill +ilyen +ilyenkor +ison +ismét +itt +jó +jól +jobban +kell +kellett +keresztül +keressünk +ki +kívül +között +közül +legalább +lehet +lehetett +legyen +lenne +lenni +lesz +lett +maga +magát +majd +majd +már +más +másik +meg +még +mellett +mert +mely +melyek +mi +mit +míg +miért +milyen +mikor +minden +mindent +mindenki +mindig +mint +mintha +mivel +most +nagy +nagyobb +nagyon +ne +néha +nekem +neki +nem +néhány +nélkül +nincs +olyan +ott +össze +ő +ők +őket +pedig +persze +rá +s +saját +sem +semmi +sok +sokat +sokkal +számára +szemben +szerint +szinte +talán +tehát +teljes +tovább +továbbá +több +úgy +ugyanis +új +újabb +újra +után +utána +utolsó +vagy +vagyis +valaki +valami +valamint +való +vagyok +van +vannak +volt +voltam +voltak +voltunk +vissza +vele +viszont +volna diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_hy.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_hy.txt new file mode 100644 index 00000000000..60c1c50fbc8 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_hy.txt @@ -0,0 +1,46 @@ +# example set of Armenian stopwords. +այդ +այլ +այն +այս +դու +դուք +եմ +են +ենք +ես +եք +է +էի +էին +էինք +էիր +էիք +էր +ըստ +թ +ի +ին +իսկ +իր +կամ +համար +հետ +հետո +մենք +մեջ +մի +ն +նա +նաև +նրա +նրանք +որ +որը +որոնք +որպես +ու +ում +պիտի +վրա +և diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_id.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_id.txt new file mode 100644 index 00000000000..4617f83a5c5 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_id.txt @@ -0,0 +1,359 @@ +# from appendix D of: A Study of Stemming Effects on Information +# Retrieval in Bahasa Indonesia +ada +adanya +adalah +adapun +agak +agaknya +agar +akan +akankah +akhirnya +aku +akulah +amat +amatlah +anda +andalah +antar +diantaranya +antara +antaranya +diantara +apa +apaan +mengapa +apabila +apakah +apalagi +apatah +atau +ataukah +ataupun +bagai +bagaikan +sebagai +sebagainya +bagaimana +bagaimanapun +sebagaimana +bagaimanakah +bagi +bahkan +bahwa +bahwasanya +sebaliknya +banyak +sebanyak +beberapa +seberapa +begini +beginian +beginikah +beginilah +sebegini +begitu +begitukah +begitulah +begitupun +sebegitu +belum +belumlah +sebelum +sebelumnya +sebenarnya +berapa +berapakah +berapalah +berapapun +betulkah +sebetulnya +biasa +biasanya +bila +bilakah +bisa +bisakah +sebisanya +boleh +bolehkah +bolehlah +buat +bukan +bukankah +bukanlah +bukannya +cuma +percuma +dahulu +dalam +dan +dapat +dari +daripada +dekat +demi +demikian +demikianlah +sedemikian +dengan +depan +di +dia +dialah +dini +diri +dirinya +terdiri +dong +dulu +enggak +enggaknya +entah +entahlah +terhadap +terhadapnya +hal +hampir +hanya +hanyalah +harus +haruslah +harusnya +seharusnya +hendak +hendaklah +hendaknya +hingga +sehingga +ia +ialah +ibarat +ingin +inginkah +inginkan +ini +inikah +inilah +itu +itukah +itulah +jangan +jangankan +janganlah +jika +jikalau +juga +justru +kala +kalau +kalaulah +kalaupun +kalian +kami +kamilah +kamu +kamulah +kan +kapan +kapankah +kapanpun +dikarenakan +karena +karenanya +ke +kecil +kemudian +kenapa +kepada +kepadanya +ketika +seketika +khususnya +kini +kinilah +kiranya +sekiranya +kita +kitalah +kok +lagi +lagian +selagi +lah +lain +lainnya +melainkan +selaku +lalu +melalui +terlalu +lama +lamanya +selama +selama +selamanya +lebih +terlebih +bermacam +macam +semacam +maka +makanya +makin +malah +malahan +mampu +mampukah +mana +manakala +manalagi +masih +masihkah +semasih +masing +mau +maupun +semaunya +memang +mereka +merekalah +meski +meskipun +semula +mungkin +mungkinkah +nah +namun +nanti +nantinya +nyaris +oleh +olehnya +seorang +seseorang +pada +padanya +padahal +paling +sepanjang +pantas +sepantasnya +sepantasnyalah +para +pasti +pastilah +per +pernah +pula +pun +merupakan +rupanya +serupa +saat +saatnya +sesaat +saja +sajalah +saling +bersama +sama +sesama +sambil +sampai +sana +sangat +sangatlah +saya +sayalah +se +sebab +sebabnya +sebuah +tersebut +tersebutlah +sedang +sedangkan +sedikit +sedikitnya +segala +segalanya +segera +sesegera +sejak +sejenak +sekali +sekalian +sekalipun +sesekali +sekaligus +sekarang +sekarang +sekitar +sekitarnya +sela +selain +selalu +seluruh +seluruhnya +semakin +sementara +sempat +semua +semuanya +sendiri +sendirinya +seolah +seperti +sepertinya +sering +seringnya +serta +siapa +siapakah +siapapun +disini +disinilah +sini +sinilah +sesuatu +sesuatunya +suatu +sesudah +sesudahnya +sudah +sudahkah +sudahlah +supaya +tadi +tadinya +tak +tanpa +setelah +telah +tentang +tentu +tentulah +tentunya +tertentu +seterusnya +tapi +tetapi +setiap +tiap +setidaknya +tidak +tidakkah +tidaklah +toh +waduh +wah +wahai +sewaktu +walau +walaupun +wong +yaitu +yakni +yang diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_it.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_it.txt new file mode 100644 index 00000000000..4cb5b0891b1 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_it.txt @@ -0,0 +1,301 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/italian/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | An Italian stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + +ad | a (to) before vowel +al | a + il +allo | a + lo +ai | a + i +agli | a + gli +all | a + l' +agl | a + gl' +alla | a + la +alle | a + le +con | with +col | con + il +coi | con + i (forms collo, cogli etc are now very rare) +da | from +dal | da + il +dallo | da + lo +dai | da + i +dagli | da + gli +dall | da + l' +dagl | da + gll' +dalla | da + la +dalle | da + le +di | of +del | di + il +dello | di + lo +dei | di + i +degli | di + gli +dell | di + l' +degl | di + gl' +della | di + la +delle | di + le +in | in +nel | in + el +nello | in + lo +nei | in + i +negli | in + gli +nell | in + l' +negl | in + gl' +nella | in + la +nelle | in + le +su | on +sul | su + il +sullo | su + lo +sui | su + i +sugli | su + gli +sull | su + l' +sugl | su + gl' +sulla | su + la +sulle | su + le +per | through, by +tra | among +contro | against +io | I +tu | thou +lui | he +lei | she +noi | we +voi | you +loro | they +mio | my +mia | +miei | +mie | +tuo | +tua | +tuoi | thy +tue | +suo | +sua | +suoi | his, her +sue | +nostro | our +nostra | +nostri | +nostre | +vostro | your +vostra | +vostri | +vostre | +mi | me +ti | thee +ci | us, there +vi | you, there +lo | him, the +la | her, the +li | them +le | them, the +gli | to him, the +ne | from there etc +il | the +un | a +uno | a +una | a +ma | but +ed | and +se | if +perché | why, because +anche | also +come | how +dov | where (as dov') +dove | where +che | who, that +chi | who +cui | whom +non | not +più | more +quale | who, that +quanto | how much +quanti | +quanta | +quante | +quello | that +quelli | +quella | +quelle | +questo | this +questi | +questa | +queste | +si | yes +tutto | all +tutti | all + + | single letter forms: + +a | at +c | as c' for ce or ci +e | and +i | the +l | as l' +o | or + + | forms of avere, to have (not including the infinitive): + +ho +hai +ha +abbiamo +avete +hanno +abbia +abbiate +abbiano +avrò +avrai +avrà +avremo +avrete +avranno +avrei +avresti +avrebbe +avremmo +avreste +avrebbero +avevo +avevi +aveva +avevamo +avevate +avevano +ebbi +avesti +ebbe +avemmo +aveste +ebbero +avessi +avesse +avessimo +avessero +avendo +avuto +avuta +avuti +avute + + | forms of essere, to be (not including the infinitive): +sono +sei +è +siamo +siete +sia +siate +siano +sarò +sarai +sarà +saremo +sarete +saranno +sarei +saresti +sarebbe +saremmo +sareste +sarebbero +ero +eri +era +eravamo +eravate +erano +fui +fosti +fu +fummo +foste +furono +fossi +fosse +fossimo +fossero +essendo + + | forms of fare, to do (not including the infinitive, fa, fat-): +faccio +fai +facciamo +fanno +faccia +facciate +facciano +farò +farai +farà +faremo +farete +faranno +farei +faresti +farebbe +faremmo +fareste +farebbero +facevo +facevi +faceva +facevamo +facevate +facevano +feci +facesti +fece +facemmo +faceste +fecero +facessi +facesse +facessimo +facessero +facendo + + | forms of stare, to be (not including the infinitive): +sto +stai +sta +stiamo +stanno +stia +stiate +stiano +starò +starai +starà +staremo +starete +staranno +starei +staresti +starebbe +staremmo +stareste +starebbero +stavo +stavi +stava +stavamo +stavate +stavano +stetti +stesti +stette +stemmo +steste +stettero +stessi +stesse +stessimo +stessero +stando diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ja.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ja.txt new file mode 100644 index 00000000000..d4321be6b16 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ja.txt @@ -0,0 +1,127 @@ +# +# This file defines a stopword set for Japanese. +# +# This set is made up of hand-picked frequent terms from segmented Japanese Wikipedia. +# Punctuation characters and frequent kanji have mostly been left out. See LUCENE-3745 +# for frequency lists, etc. that can be useful for making your own set (if desired) +# +# Note that there is an overlap between these stopwords and the terms stopped when used +# in combination with the JapanesePartOfSpeechStopFilter. When editing this file, note +# that comments are not allowed on the same line as stopwords. +# +# Also note that stopping is done in a case-insensitive manner. Change your StopFilter +# configuration if you need case-sensitive stopping. Lastly, note that stopping is done +# using the same character width as the entries in this file. Since this StopFilter is +# normally done after a CJKWidthFilter in your chain, you would usually want your romaji +# entries to be in half-width and your kana entries to be in full-width. +# +の +に +は +を +た +が +で +て +と +し +れ +さ +ある +いる +も +する +から +な +こと +として +い +や +れる +など +なっ +ない +この +ため +その +あっ +よう +また +もの +という +あり +まで +られ +なる +へ +か +だ +これ +によって +により +おり +より +による +ず +なり +られる +において +ば +なかっ +なく +しかし +について +せ +だっ +その後 +できる +それ +う +ので +なお +のみ +でき +き +つ +における +および +いう +さらに +でも +ら +たり +その他 +に関する +たち +ます +ん +なら +に対して +特に +せる +及び +これら +とき +では +にて +ほか +ながら +うち +そして +とともに +ただし +かつて +それぞれ +または +お +ほど +ものの +に対する +ほとんど +と共に +といった +です +とも +ところ +ここ +##### End of file diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_lv.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_lv.txt new file mode 100644 index 00000000000..e21a23c06c3 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_lv.txt @@ -0,0 +1,172 @@ +# Set of Latvian stopwords from A Stemming Algorithm for Latvian, Karlis Kreslins +# the original list of over 800 forms was refined: +# pronouns, adverbs, interjections were removed +# +# prepositions +aiz +ap +ar +apakš +ārpus +augšpus +bez +caur +dēļ +gar +iekš +iz +kopš +labad +lejpus +līdz +no +otrpus +pa +par +pār +pēc +pie +pirms +pret +priekš +starp +šaipus +uz +viņpus +virs +virspus +zem +apakšpus +# Conjunctions +un +bet +jo +ja +ka +lai +tomēr +tikko +turpretī +arī +kaut +gan +tādēļ +tā +ne +tikvien +vien +kā +ir +te +vai +kamēr +# Particles +ar +diezin +droši +diemžēl +nebūt +ik +it +taču +nu +pat +tiklab +iekšpus +nedz +tik +nevis +turpretim +jeb +iekam +iekām +iekāms +kolīdz +līdzko +tiklīdz +jebšu +tālab +tāpēc +nekā +itin +jā +jau +jel +nē +nezin +tad +tikai +vis +tak +iekams +vien +# modal verbs +būt +biju +biji +bija +bijām +bijāt +esmu +esi +esam +esat +būšu +būsi +būs +būsim +būsiet +tikt +tiku +tiki +tika +tikām +tikāt +tieku +tiec +tiek +tiekam +tiekat +tikšu +tiks +tiksim +tiksiet +tapt +tapi +tapāt +topat +tapšu +tapsi +taps +tapsim +tapsiet +kļūt +kļuvu +kļuvi +kļuva +kļuvām +kļuvāt +kļūstu +kļūsti +kļūst +kļūstam +kļūstat +kļūšu +kļūsi +kļūs +kļūsim +kļūsiet +# verbs +varēt +varēju +varējām +varēšu +varēsim +var +varēji +varējāt +varēsi +varēsiet +varat +varēja +varēs diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_nl.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_nl.txt new file mode 100644 index 00000000000..f4d61f5092c --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_nl.txt @@ -0,0 +1,117 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/dutch/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Dutch stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | This is a ranked list (commonest to rarest) of stopwords derived from + | a large sample of Dutch text. + + | Dutch stop words frequently exhibit homonym clashes. These are indicated + | clearly below. + +de | the +en | and +van | of, from +ik | I, the ego +te | (1) chez, at etc, (2) to, (3) too +dat | that, which +die | that, those, who, which +in | in, inside +een | a, an, one +hij | he +het | the, it +niet | not, nothing, naught +zijn | (1) to be, being, (2) his, one's, its +is | is +was | (1) was, past tense of all persons sing. of 'zijn' (to be) (2) wax, (3) the washing, (4) rise of river +op | on, upon, at, in, up, used up +aan | on, upon, to (as dative) +met | with, by +als | like, such as, when +voor | (1) before, in front of, (2) furrow +had | had, past tense all persons sing. of 'hebben' (have) +er | there +maar | but, only +om | round, about, for etc +hem | him +dan | then +zou | should/would, past tense all persons sing. of 'zullen' +of | or, whether, if +wat | what, something, anything +mijn | possessive and noun 'mine' +men | people, 'one' +dit | this +zo | so, thus, in this way +door | through by +over | over, across +ze | she, her, they, them +zich | oneself +bij | (1) a bee, (2) by, near, at +ook | also, too +tot | till, until +je | you +mij | me +uit | out of, from +der | Old Dutch form of 'van der' still found in surnames +daar | (1) there, (2) because +haar | (1) her, their, them, (2) hair +naar | (1) unpleasant, unwell etc, (2) towards, (3) as +heb | present first person sing. of 'to have' +hoe | how, why +heeft | present third person sing. of 'to have' +hebben | 'to have' and various parts thereof +deze | this +u | you +want | (1) for, (2) mitten, (3) rigging +nog | yet, still +zal | 'shall', first and third person sing. of verb 'zullen' (will) +me | me +zij | she, they +nu | now +ge | 'thou', still used in Belgium and south Netherlands +geen | none +omdat | because +iets | something, somewhat +worden | to become, grow, get +toch | yet, still +al | all, every, each +waren | (1) 'were' (2) to wander, (3) wares, (3) +veel | much, many +meer | (1) more, (2) lake +doen | to do, to make +toen | then, when +moet | noun 'spot/mote' and present form of 'to must' +ben | (1) am, (2) 'are' in interrogative second person singular of 'to be' +zonder | without +kan | noun 'can' and present form of 'to be able' +hun | their, them +dus | so, consequently +alles | all, everything, anything +onder | under, beneath +ja | yes, of course +eens | once, one day +hier | here +wie | who +werd | imperfect third person sing. of 'become' +altijd | always +doch | yet, but etc +wordt | present third person sing. of 'become' +wezen | (1) to be, (2) 'been' as in 'been fishing', (3) orphans +kunnen | to be able +ons | us/our +zelf | self +tegen | against, towards, at +na | after, near +reeds | already +wil | (1) present tense of 'want', (2) 'will', noun, (3) fender +kon | could; past tense of 'to be able' +niets | nothing +uw | your +iemand | somebody +geweest | been; past participle of 'be' +andere | other diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_no.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_no.txt new file mode 100644 index 00000000000..e76f36e69ed --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_no.txt @@ -0,0 +1,192 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/norwegian/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Norwegian stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | This stop word list is for the dominant bokmål dialect. Words unique + | to nynorsk are marked *. + + | Revised by Jan Bruusgaard , Jan 2005 + +og | and +i | in +jeg | I +det | it/this/that +at | to (w. inf.) +en | a/an +et | a/an +den | it/this/that +til | to +er | is/am/are +som | who/that +på | on +de | they / you(formal) +med | with +han | he +av | of +ikke | not +ikkje | not * +der | there +så | so +var | was/were +meg | me +seg | you +men | but +ett | one +har | have +om | about +vi | we +min | my +mitt | my +ha | have +hadde | had +hun | she +nå | now +over | over +da | when/as +ved | by/know +fra | from +du | you +ut | out +sin | your +dem | them +oss | us +opp | up +man | you/one +kan | can +hans | his +hvor | where +eller | or +hva | what +skal | shall/must +selv | self (reflective) +sjøl | self (reflective) +her | here +alle | all +vil | will +bli | become +ble | became +blei | became * +blitt | have become +kunne | could +inn | in +når | when +være | be +kom | come +noen | some +noe | some +ville | would +dere | you +som | who/which/that +deres | their/theirs +kun | only/just +ja | yes +etter | after +ned | down +skulle | should +denne | this +for | for/because +deg | you +si | hers/his +sine | hers/his +sitt | hers/his +mot | against +å | to +meget | much +hvorfor | why +dette | this +disse | these/those +uten | without +hvordan | how +ingen | none +din | your +ditt | your +blir | become +samme | same +hvilken | which +hvilke | which (plural) +sånn | such a +inni | inside/within +mellom | between +vår | our +hver | each +hvem | who +vors | us/ours +hvis | whose +både | both +bare | only/just +enn | than +fordi | as/because +før | before +mange | many +også | also +slik | just +vært | been +være | to be +båe | both * +begge | both +siden | since +dykk | your * +dykkar | yours * +dei | they * +deira | them * +deires | theirs * +deim | them * +di | your (fem.) * +då | as/when * +eg | I * +ein | a/an * +eit | a/an * +eitt | a/an * +elles | or * +honom | he * +hjå | at * +ho | she * +hoe | she * +henne | her +hennar | her/hers +hennes | hers +hoss | how * +hossen | how * +ikkje | not * +ingi | noone * +inkje | noone * +korleis | how * +korso | how * +kva | what/which * +kvar | where * +kvarhelst | where * +kven | who/whom * +kvi | why * +kvifor | why * +me | we * +medan | while * +mi | my * +mine | my * +mykje | much * +no | now * +nokon | some (masc./neut.) * +noka | some (fem.) * +nokor | some * +noko | some * +nokre | some * +si | his/hers * +sia | since * +sidan | since * +so | so * +somt | some * +somme | some * +um | about* +upp | up * +vere | be * +vore | was * +verte | become * +vort | become * +varte | became * +vart | became * + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_pt.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_pt.txt new file mode 100644 index 00000000000..276c1b446f2 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_pt.txt @@ -0,0 +1,251 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/portuguese/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Portuguese stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + + | The following is a ranked list (commonest to rarest) of stopwords + | deriving from a large sample of text. + + | Extra words have been added at the end. + +de | of, from +a | the; to, at; her +o | the; him +que | who, that +e | and +do | de + o +da | de + a +em | in +um | a +para | for + | é from SER +com | with +não | not, no +uma | a +os | the; them +no | em + o +se | himself etc +na | em + a +por | for +mais | more +as | the; them +dos | de + os +como | as, like +mas | but + | foi from SER +ao | a + o +ele | he +das | de + as + | tem from TER +à | a + a +seu | his +sua | her +ou | or + | ser from SER +quando | when +muito | much + | há from HAV +nos | em + os; us +já | already, now + | está from EST +eu | I +também | also +só | only, just +pelo | per + o +pela | per + a +até | up to +isso | that +ela | he +entre | between + | era from SER +depois | after +sem | without +mesmo | same +aos | a + os + | ter from TER +seus | his +quem | whom +nas | em + as +me | me +esse | that +eles | they + | estão from EST +você | you + | tinha from TER + | foram from SER +essa | that +num | em + um +nem | nor +suas | her +meu | my +às | a + as +minha | my + | têm from TER +numa | em + uma +pelos | per + os +elas | they + | havia from HAV + | seja from SER +qual | which + | será from SER +nós | we + | tenho from TER +lhe | to him, her +deles | of them +essas | those +esses | those +pelas | per + as +este | this + | fosse from SER +dele | of him + + | other words. There are many contractions such as naquele = em+aquele, + | mo = me+o, but they are rare. + | Indefinite article plural forms are also rare. + +tu | thou +te | thee +vocês | you (plural) +vos | you +lhes | to them +meus | my +minhas +teu | thy +tua +teus +tuas +nosso | our +nossa +nossos +nossas + +dela | of her +delas | of them + +esta | this +estes | these +estas | these +aquele | that +aquela | that +aqueles | those +aquelas | those +isto | this +aquilo | that + + | forms of estar, to be (not including the infinitive): +estou +está +estamos +estão +estive +esteve +estivemos +estiveram +estava +estávamos +estavam +estivera +estivéramos +esteja +estejamos +estejam +estivesse +estivéssemos +estivessem +estiver +estivermos +estiverem + + | forms of haver, to have (not including the infinitive): +hei +há +havemos +hão +houve +houvemos +houveram +houvera +houvéramos +haja +hajamos +hajam +houvesse +houvéssemos +houvessem +houver +houvermos +houverem +houverei +houverá +houveremos +houverão +houveria +houveríamos +houveriam + + | forms of ser, to be (not including the infinitive): +sou +somos +são +era +éramos +eram +fui +foi +fomos +foram +fora +fôramos +seja +sejamos +sejam +fosse +fôssemos +fossem +for +formos +forem +serei +será +seremos +serão +seria +seríamos +seriam + + | forms of ter, to have (not including the infinitive): +tenho +tem +temos +tém +tinha +tínhamos +tinham +tive +teve +tivemos +tiveram +tivera +tivéramos +tenha +tenhamos +tenham +tivesse +tivéssemos +tivessem +tiver +tivermos +tiverem +terei +terá +teremos +terão +teria +teríamos +teriam diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ro.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ro.txt new file mode 100644 index 00000000000..4fdee90a5ba --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ro.txt @@ -0,0 +1,233 @@ +# This file was created by Jacques Savoy and is distributed under the BSD license. +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# Also see http://www.opensource.org/licenses/bsd-license.html +acea +aceasta +această +aceea +acei +aceia +acel +acela +acele +acelea +acest +acesta +aceste +acestea +aceşti +aceştia +acolo +acum +ai +aia +aibă +aici +al +ăla +ale +alea +ălea +altceva +altcineva +am +ar +are +aş +aşadar +asemenea +asta +ăsta +astăzi +astea +ăstea +ăştia +asupra +aţi +au +avea +avem +aveţi +azi +bine +bucur +bună +ca +că +căci +când +care +cărei +căror +cărui +cât +câte +câţi +către +câtva +ce +cel +ceva +chiar +cînd +cine +cineva +cît +cîte +cîţi +cîtva +contra +cu +cum +cumva +curând +curînd +da +dă +dacă +dar +datorită +de +deci +deja +deoarece +departe +deşi +din +dinaintea +dintr +dintre +drept +după +ea +ei +el +ele +eram +este +eşti +eu +face +fără +fi +fie +fiecare +fii +fim +fiţi +iar +ieri +îi +îl +îmi +împotriva +în +înainte +înaintea +încât +încît +încotro +între +întrucât +întrucît +îţi +la +lângă +le +li +lîngă +lor +lui +mă +mâine +mea +mei +mele +mereu +meu +mi +mine +mult +multă +mulţi +ne +nicăieri +nici +nimeni +nişte +noastră +noastre +noi +noştri +nostru +nu +ori +oricând +oricare +oricât +orice +oricînd +oricine +oricît +oricum +oriunde +până +pe +pentru +peste +pînă +poate +pot +prea +prima +primul +prin +printr +sa +să +săi +sale +sau +său +se +şi +sînt +sîntem +sînteţi +spre +sub +sunt +suntem +sunteţi +ta +tăi +tale +tău +te +ţi +ţie +tine +toată +toate +tot +toţi +totuşi +tu +un +una +unde +undeva +unei +unele +uneori +unor +vă +vi +voastră +voastre +voi +voştri +vostru +vouă +vreo +vreun diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ru.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ru.txt new file mode 100644 index 00000000000..64307693457 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ru.txt @@ -0,0 +1,241 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/russian/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | a russian stop word list. comments begin with vertical bar. each stop + | word is at the start of a line. + + | this is a ranked list (commonest to rarest) of stopwords derived from + | a large text sample. + + | letter `ё' is translated to `е'. + +и | and +в | in/into +во | alternative form +не | not +что | what/that +он | he +на | on/onto +я | i +с | from +со | alternative form +как | how +а | milder form of `no' (but) +то | conjunction and form of `that' +все | all +она | she +так | so, thus +его | him +но | but +да | yes/and +ты | thou +к | towards, by +у | around, chez +же | intensifier particle +вы | you +за | beyond, behind +бы | conditional/subj. particle +по | up to, along +только | only +ее | her +мне | to me +было | it was +вот | here is/are, particle +от | away from +меня | me +еще | still, yet, more +нет | no, there isnt/arent +о | about +из | out of +ему | to him +теперь | now +когда | when +даже | even +ну | so, well +вдруг | suddenly +ли | interrogative particle +если | if +уже | already, but homonym of `narrower' +или | or +ни | neither +быть | to be +был | he was +него | prepositional form of его +до | up to +вас | you accusative +нибудь | indef. suffix preceded by hyphen +опять | again +уж | already, but homonym of `adder' +вам | to you +сказал | he said +ведь | particle `after all' +там | there +потом | then +себя | oneself +ничего | nothing +ей | to her +может | usually with `быть' as `maybe' +они | they +тут | here +где | where +есть | there is/are +надо | got to, must +ней | prepositional form of ей +для | for +мы | we +тебя | thee +их | them, their +чем | than +была | she was +сам | self +чтоб | in order to +без | without +будто | as if +человек | man, person, one +чего | genitive form of `what' +раз | once +тоже | also +себе | to oneself +под | beneath +жизнь | life +будет | will be +ж | short form of intensifer particle `же' +тогда | then +кто | who +этот | this +говорил | was saying +того | genitive form of `that' +потому | for that reason +этого | genitive form of `this' +какой | which +совсем | altogether +ним | prepositional form of `его', `они' +здесь | here +этом | prepositional form of `этот' +один | one +почти | almost +мой | my +тем | instrumental/dative plural of `тот', `то' +чтобы | full form of `in order that' +нее | her (acc.) +кажется | it seems +сейчас | now +были | they were +куда | where to +зачем | why +сказать | to say +всех | all (acc., gen. preposn. plural) +никогда | never +сегодня | today +можно | possible, one can +при | by +наконец | finally +два | two +об | alternative form of `о', about +другой | another +хоть | even +после | after +над | above +больше | more +тот | that one (masc.) +через | across, in +эти | these +нас | us +про | about +всего | in all, only, of all +них | prepositional form of `они' (they) +какая | which, feminine +много | lots +разве | interrogative particle +сказала | she said +три | three +эту | this, acc. fem. sing. +моя | my, feminine +впрочем | moreover, besides +хорошо | good +свою | ones own, acc. fem. sing. +этой | oblique form of `эта', fem. `this' +перед | in front of +иногда | sometimes +лучше | better +чуть | a little +том | preposn. form of `that one' +нельзя | one must not +такой | such a one +им | to them +более | more +всегда | always +конечно | of course +всю | acc. fem. sing of `all' +между | between + + + | b: some paradigms + | + | personal pronouns + | + | я меня мне мной [мною] + | ты тебя тебе тобой [тобою] + | он его ему им [него, нему, ним] + | она ее эи ею [нее, нэи, нею] + | оно его ему им [него, нему, ним] + | + | мы нас нам нами + | вы вас вам вами + | они их им ими [них, ним, ними] + | + | себя себе собой [собою] + | + | demonstrative pronouns: этот (this), тот (that) + | + | этот эта это эти + | этого эты это эти + | этого этой этого этих + | этому этой этому этим + | этим этой этим [этою] этими + | этом этой этом этих + | + | тот та то те + | того ту то те + | того той того тех + | тому той тому тем + | тем той тем [тою] теми + | том той том тех + | + | determinative pronouns + | + | (a) весь (all) + | + | весь вся все все + | всего всю все все + | всего всей всего всех + | всему всей всему всем + | всем всей всем [всею] всеми + | всем всей всем всех + | + | (b) сам (himself etc) + | + | сам сама само сами + | самого саму само самих + | самого самой самого самих + | самому самой самому самим + | самим самой самим [самою] самими + | самом самой самом самих + | + | stems of verbs `to be', `to have', `to do' and modal + | + | быть бы буд быв есть суть + | име + | дел + | мог мож мочь + | уме + | хоч хот + | долж + | можн + | нужн + | нельзя + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_sv.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_sv.txt new file mode 100644 index 00000000000..22bddfd8cb3 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_sv.txt @@ -0,0 +1,131 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/swedish/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Swedish stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | This is a ranked list (commonest to rarest) of stopwords derived from + | a large text sample. + + | Swedish stop words occasionally exhibit homonym clashes. For example + | så = so, but also seed. These are indicated clearly below. + +och | and +det | it, this/that +att | to (with infinitive) +i | in, at +en | a +jag | I +hon | she +som | who, that +han | he +på | on +den | it, this/that +med | with +var | where, each +sig | him(self) etc +för | for +så | so (also: seed) +till | to +är | is +men | but +ett | a +om | if; around, about +hade | had +de | they, these/those +av | of +icke | not, no +mig | me +du | you +henne | her +då | then, when +sin | his +nu | now +har | have +inte | inte någon = no one +hans | his +honom | him +skulle | 'sake' +hennes | her +där | there +min | my +man | one (pronoun) +ej | nor +vid | at, by, on (also: vast) +kunde | could +något | some etc +från | from, off +ut | out +när | when +efter | after, behind +upp | up +vi | we +dem | them +vara | be +vad | what +över | over +än | than +dig | you +kan | can +sina | his +här | here +ha | have +mot | towards +alla | all +under | under (also: wonder) +någon | some etc +eller | or (else) +allt | all +mycket | much +sedan | since +ju | why +denna | this/that +själv | myself, yourself etc +detta | this/that +åt | to +utan | without +varit | was +hur | how +ingen | no +mitt | my +ni | you +bli | to be, become +blev | from bli +oss | us +din | thy +dessa | these/those +några | some etc +deras | their +blir | from bli +mina | my +samma | (the) same +vilken | who, that +er | you, your +sådan | such a +vår | our +blivit | from bli +dess | its +inom | within +mellan | between +sådant | such a +varför | why +varje | each +vilka | who, that +ditt | thy +vem | who +vilket | who, that +sitta | his +sådana | such a +vart | each +dina | thy +vars | whose +vårt | our +våra | our +ert | your +era | your +vilkas | whose + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_th.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_th.txt new file mode 100644 index 00000000000..07f0fabe692 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_th.txt @@ -0,0 +1,119 @@ +# Thai stopwords from: +# "Opinion Detection in Thai Political News Columns +# Based on Subjectivity Analysis" +# Khampol Sukhum, Supot Nitsuwat, and Choochart Haruechaiyasak +ไว้ +ไม่ +ไป +ได้ +ให้ +ใน +โดย +แห่ง +แล้ว +และ +แรก +แบบ +แต่ +เอง +เห็น +เลย +เริ่ม +เรา +เมื่อ +เพื่อ +เพราะ +เป็นการ +เป็น +เปิดเผย +เปิด +เนื่องจาก +เดียวกัน +เดียว +เช่น +เฉพาะ +เคย +เข้า +เขา +อีก +อาจ +อะไร +ออก +อย่าง +อยู่ +อยาก +หาก +หลาย +หลังจาก +หลัง +หรือ +หนึ่ง +ส่วน +ส่ง +สุด +สําหรับ +ว่า +วัน +ลง +ร่วม +ราย +รับ +ระหว่าง +รวม +ยัง +มี +มาก +มา +พร้อม +พบ +ผ่าน +ผล +บาง +น่า +นี้ +นํา +นั้น +นัก +นอกจาก +ทุก +ที่สุด +ที่ +ทําให้ +ทํา +ทาง +ทั้งนี้ +ทั้ง +ถ้า +ถูก +ถึง +ต้อง +ต่างๆ +ต่าง +ต่อ +ตาม +ตั้งแต่ +ตั้ง +ด้าน +ด้วย +ดัง +ซึ่ง +ช่วง +จึง +จาก +จัด +จะ +คือ +ความ +ครั้ง +คง +ขึ้น +ของ +ขอ +ขณะ +ก่อน +ก็ +การ +กับ +กัน +กว่า +กล่าว diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_tr.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_tr.txt new file mode 100644 index 00000000000..84d9408d4ea --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_tr.txt @@ -0,0 +1,212 @@ +# Turkish stopwords from LUCENE-559 +# merged with the list from "Information Retrieval on Turkish Texts" +# (http://www.users.muohio.edu/canf/papers/JASIST2008offPrint.pdf) +acaba +altmış +altı +ama +ancak +arada +aslında +ayrıca +bana +bazı +belki +ben +benden +beni +benim +beri +beş +bile +bin +bir +birçok +biri +birkaç +birkez +birşey +birşeyi +biz +bize +bizden +bizi +bizim +böyle +böylece +bu +buna +bunda +bundan +bunlar +bunları +bunların +bunu +bunun +burada +çok +çünkü +da +daha +dahi +de +defa +değil +diğer +diye +doksan +dokuz +dolayı +dolayısıyla +dört +edecek +eden +ederek +edilecek +ediliyor +edilmesi +ediyor +eğer +elli +en +etmesi +etti +ettiği +ettiğini +gibi +göre +halen +hangi +hatta +hem +henüz +hep +hepsi +her +herhangi +herkesin +hiç +hiçbir +için +iki +ile +ilgili +ise +işte +itibaren +itibariyle +kadar +karşın +katrilyon +kendi +kendilerine +kendini +kendisi +kendisine +kendisini +kez +ki +kim +kimden +kime +kimi +kimse +kırk +milyar +milyon +mu +mü +mı +nasıl +ne +neden +nedenle +nerde +nerede +nereye +niye +niçin +o +olan +olarak +oldu +olduğu +olduğunu +olduklarını +olmadı +olmadığı +olmak +olması +olmayan +olmaz +olsa +olsun +olup +olur +olursa +oluyor +on +ona +ondan +onlar +onlardan +onları +onların +onu +onun +otuz +oysa +öyle +pek +rağmen +sadece +sanki +sekiz +seksen +sen +senden +seni +senin +siz +sizden +sizi +sizin +şey +şeyden +şeyi +şeyler +şöyle +şu +şuna +şunda +şundan +şunları +şunu +tarafından +trilyon +tüm +üç +üzere +var +vardı +ve +veya +ya +yani +yapacak +yapılan +yapılması +yapıyor +yapmak +yaptı +yaptığı +yaptığını +yaptıkları +yedi +yerine +yetmiş +yine +yirmi +yoksa +yüz +zaten diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/userdict_ja.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/userdict_ja.txt new file mode 100644 index 00000000000..6f0368e4d81 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/userdict_ja.txt @@ -0,0 +1,29 @@ +# +# This is a sample user dictionary for Kuromoji (JapaneseTokenizer) +# +# Add entries to this file in order to override the statistical model in terms +# of segmentation, readings and part-of-speech tags. Notice that entries do +# not have weights since they are always used when found. This is by-design +# in order to maximize ease-of-use. +# +# Entries are defined using the following CSV format: +# , ... , ... , +# +# Notice that a single half-width space separates tokens and readings, and +# that the number tokens and readings must match exactly. +# +# Also notice that multiple entries with the same is undefined. +# +# Whitespace only lines are ignored. Comments are not allowed on entry lines. +# + +# Custom segmentation for kanji compounds +日本経済新聞,日本 経済 新聞,ニホン ケイザイ シンブン,カスタム名詞 +関西国際空港,関西 国際 空港,カンサイ コクサイ クウコウ,カスタム名詞 + +# Custom segmentation for compound katakana +トートバッグ,トート バッグ,トート バッグ,かずカナ名詞 +ショルダーバッグ,ショルダー バッグ,ショルダー バッグ,かずカナ名詞 + +# Custom reading for former sumo wrestler +朝青龍,朝青龍,アサショウリュウ,カスタム人名 diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/protwords.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/protwords.txt new file mode 100644 index 00000000000..1dfc0abecbf --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/protwords.txt @@ -0,0 +1,21 @@ +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#----------------------------------------------------------------------- +# Use a protected word file to protect against the stemmer reducing two +# unrelated words to the same base word. + +# Some non-words that normally won't be encountered, +# just to test that they won't be stemmed. +dontstems +zwhacky + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/schema.xml b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/schema.xml new file mode 100644 index 00000000000..65192efe442 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/schema.xml @@ -0,0 +1,961 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/solrconfig.xml b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/solrconfig.xml new file mode 100644 index 00000000000..beff1b2af0a --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/solrconfig.xml @@ -0,0 +1,1784 @@ + + + + + + + + + LUCENE_43 + + + + + + + + + + + + + + + + + + + + + + + + ${solr.data.dir:} + + + + + ${solr.hdfs.home:} + ${solr.hdfs.confdir:} + ${solr.hdfs.blockcache.enabled:true} + ${solr.hdfs.blockcache.slab.count:1} + ${solr.hdfs.blockcache.direct.memory.allocation:true} + ${solr.hdfs.blockcache.blocksperbank:16384} + ${solr.hdfs.blockcache.read.enabled:true} + ${solr.hdfs.blockcache.write.enabled:true} + ${solr.hdfs.nrtcachingdirectory.enable:true} + ${solr.hdfs.nrtcachingdirectory.maxmergesizemb:16} + ${solr.hdfs.nrtcachingdirectory.maxcachedmb:192} + + + + + + + + + + + + + ${solr.maxIndexingThreads:8} + + + + + + 128 + + + + + + + + + + + + + ${solr.lock.type:hdfs} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${solr.ulog.dir:} + + + + + ${solr.autoCommit.maxTime:60000} + false + + + + + ${solr.autoSoftCommit.maxTime:1000} + + + + + + + + + + + + + + + + + + + 1024 + + + + + + + + + + + + + + + + + + + + + + true + + + + + + 20 + + + 200 + + + + + + + + + + + + static firstSearcher warming in solrconfig.xml + + + + + + false + + + 4 + + + + + + + + + + + + + + + + + + + + + + + explicit + 10 + text + + + + + + + + + + + + + + explicit + json + true + text + + + + + + + + true + json + true + + + + + + + + explicit + + + velocity + browse + layout + Solritas + + + edismax + + text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 + title^10.0 description^5.0 keywords^5.0 author^2.0 resourcename^1.0 + + text + 100% + *:* + 10 + *,score + + + text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 + title^10.0 description^5.0 keywords^5.0 author^2.0 resourcename^1.0 + + text,features,name,sku,id,manu,cat,title,description,keywords,author,resourcename + 3 + + + on + cat + manu_exact + content_type + author_s + ipod + GB + 1 + cat,inStock + after + price + 0 + 600 + 50 + popularity + 0 + 10 + 3 + manufacturedate_dt + NOW/YEAR-10YEARS + NOW + +1YEAR + before + after + + + on + content features title name + html + <b> + </b> + 0 + title + 0 + name + 3 + 200 + content + 750 + + + on + false + 5 + 2 + 5 + true + true + 5 + 3 + + + + + spellcheck + + + + + + + + + + + + + + application/json + + + + + application/csv + + + + + + + + + + + + + + + + + + + + + solrpingquery + + + all + + + + + + + + + explicit + true + + + + + + + + + + + + + + + + text_general + + + + + + default + text + solr.DirectSolrSpellChecker + + internal + + 0.5 + + 2 + + 1 + + 5 + + 4 + + 0.01 + + + + + + wordbreak + solr.WordBreakSolrSpellChecker + name + true + true + 10 + + + + + + + + + + + + + + + + text + + default + wordbreak + on + true + 10 + 5 + 5 + true + true + 10 + 5 + + + spellcheck + + + + + + + + + + text + true + + + tvComponent + + + + + + + + + default + + + org.carrot2.clustering.lingo.LingoClusteringAlgorithm + + + 20 + + + clustering/carrot2 + + + ENGLISH + + + stc + org.carrot2.clustering.stc.STCClusteringAlgorithm + + + + + + + true + default + true + + name + id + + features + + true + + + + false + + edismax + + text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 + + *:* + 10 + *,score + + + clustering + + + + + + + + + + true + false + + + terms + + + + + + + + string + elevate.xml + + + + + + explicit + text + + + elevator + + + + + + + + + + + 100 + + + + + + + + 70 + + 0.5 + + [-\w ,/\n\"']{20,200} + + + + + + + ]]> + ]]> + + + + + + + + + + + + + + + + + + + + + + + + ,, + ,, + ,, + ,, + ,]]> + ]]> + + + + + + 10 + .,!? + + + + + + + WORD + + + en + US + + + + + + + + + + + + + + + + + + + + + + text/plain; charset=UTF-8 + + + + + + + + + 5 + + + + + + + + + + + + + + + + + + *:* + + + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/stopwords.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/stopwords.txt new file mode 100644 index 00000000000..ae1e83eeb3d --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/stopwords.txt @@ -0,0 +1,14 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/synonyms.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/synonyms.txt new file mode 100644 index 00000000000..7f72128303b --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/synonyms.txt @@ -0,0 +1,29 @@ +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#----------------------------------------------------------------------- +#some test synonym mappings unlikely to appear in real input text +aaafoo => aaabar +bbbfoo => bbbfoo bbbbar +cccfoo => cccbar cccbaz +fooaaa,baraaa,bazaaa + +# Some synonym groups specific to this example +GB,gib,gigabyte,gigabytes +MB,mib,megabyte,megabytes +Television, Televisions, TV, TVs +#notice we use "gib" instead of "GiB" so any WordDelimiterFilter coming +#after us won't split it into two words. + +# Synonym mappings can be used for spelling correction too +pixima => pixma + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/solr.xml b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/solr.xml new file mode 100644 index 00000000000..6c8b43f75ed --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/solr.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + ${socketTimeout:120000} + ${connTimeout:15000} + + + + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/currency.xml b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/currency.xml new file mode 100644 index 00000000000..3a9c58afee8 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/currency.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/elevate.xml b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/elevate.xml new file mode 100644 index 00000000000..25d5cebe4fb --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/elevate.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/contractions_ca.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/contractions_ca.txt new file mode 100644 index 00000000000..307a85f913d --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/contractions_ca.txt @@ -0,0 +1,8 @@ +# Set of Catalan contractions for ElisionFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +d +l +m +n +s +t diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/contractions_fr.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/contractions_fr.txt new file mode 100644 index 00000000000..722db588333 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/contractions_fr.txt @@ -0,0 +1,9 @@ +# Set of French contractions for ElisionFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +l +m +t +qu +n +s +j diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/contractions_ga.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/contractions_ga.txt new file mode 100644 index 00000000000..9ebe7fa349a --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/contractions_ga.txt @@ -0,0 +1,5 @@ +# Set of Irish contractions for ElisionFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +d +m +b diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/contractions_it.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/contractions_it.txt new file mode 100644 index 00000000000..cac04095372 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/contractions_it.txt @@ -0,0 +1,23 @@ +# Set of Italian contractions for ElisionFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +c +l +all +dall +dell +nell +sull +coll +pell +gl +agl +dagl +degl +negl +sugl +un +m +t +s +v +d diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/hyphenations_ga.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/hyphenations_ga.txt new file mode 100644 index 00000000000..4d2642cc5a3 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/hyphenations_ga.txt @@ -0,0 +1,5 @@ +# Set of Irish hyphenations for StopFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +h +n +t diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stemdict_nl.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stemdict_nl.txt new file mode 100644 index 00000000000..441072971d3 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stemdict_nl.txt @@ -0,0 +1,6 @@ +# Set of overrides for the dutch stemmer +# TODO: load this as a resource from the analyzer and sync it in build.xml +fiets fiets +bromfiets bromfiets +ei eier +kind kinder diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stoptags_ja.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stoptags_ja.txt new file mode 100644 index 00000000000..71b750845e3 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stoptags_ja.txt @@ -0,0 +1,420 @@ +# +# This file defines a Japanese stoptag set for JapanesePartOfSpeechStopFilter. +# +# Any token with a part-of-speech tag that exactly matches those defined in this +# file are removed from the token stream. +# +# Set your own stoptags by uncommenting the lines below. Note that comments are +# not allowed on the same line as a stoptag. See LUCENE-3745 for frequency lists, +# etc. that can be useful for building you own stoptag set. +# +# The entire possible tagset is provided below for convenience. +# +##### +# noun: unclassified nouns +#名詞 +# +# noun-common: Common nouns or nouns where the sub-classification is undefined +#名詞-一般 +# +# noun-proper: Proper nouns where the sub-classification is undefined +#名詞-固有名詞 +# +# noun-proper-misc: miscellaneous proper nouns +#名詞-固有名詞-一般 +# +# noun-proper-person: Personal names where the sub-classification is undefined +#名詞-固有名詞-人名 +# +# noun-proper-person-misc: names that cannot be divided into surname and +# given name; foreign names; names where the surname or given name is unknown. +# e.g. お市の方 +#名詞-固有名詞-人名-一般 +# +# noun-proper-person-surname: Mainly Japanese surnames. +# e.g. 山田 +#名詞-固有名詞-人名-姓 +# +# noun-proper-person-given_name: Mainly Japanese given names. +# e.g. 太郎 +#名詞-固有名詞-人名-名 +# +# noun-proper-organization: Names representing organizations. +# e.g. 通産省, NHK +#名詞-固有名詞-組織 +# +# noun-proper-place: Place names where the sub-classification is undefined +#名詞-固有名詞-地域 +# +# noun-proper-place-misc: Place names excluding countries. +# e.g. アジア, バルセロナ, 京都 +#名詞-固有名詞-地域-一般 +# +# noun-proper-place-country: Country names. +# e.g. 日本, オーストラリア +#名詞-固有名詞-地域-国 +# +# noun-pronoun: Pronouns where the sub-classification is undefined +#名詞-代名詞 +# +# noun-pronoun-misc: miscellaneous pronouns: +# e.g. それ, ここ, あいつ, あなた, あちこち, いくつ, どこか, なに, みなさん, みんな, わたくし, われわれ +#名詞-代名詞-一般 +# +# noun-pronoun-contraction: Spoken language contraction made by combining a +# pronoun and the particle 'wa'. +# e.g. ありゃ, こりゃ, こりゃあ, そりゃ, そりゃあ +#名詞-代名詞-縮約 +# +# noun-adverbial: Temporal nouns such as names of days or months that behave +# like adverbs. Nouns that represent amount or ratios and can be used adverbially, +# e.g. 金曜, 一月, 午後, 少量 +#名詞-副詞可能 +# +# noun-verbal: Nouns that take arguments with case and can appear followed by +# 'suru' and related verbs (する, できる, なさる, くださる) +# e.g. インプット, 愛着, 悪化, 悪戦苦闘, 一安心, 下取り +#名詞-サ変接続 +# +# noun-adjective-base: The base form of adjectives, words that appear before な ("na") +# e.g. 健康, 安易, 駄目, だめ +#名詞-形容動詞語幹 +# +# noun-numeric: Arabic numbers, Chinese numerals, and counters like 何 (回), 数. +# e.g. 0, 1, 2, 何, 数, 幾 +#名詞-数 +# +# noun-affix: noun affixes where the sub-classification is undefined +#名詞-非自立 +# +# noun-affix-misc: Of adnominalizers, the case-marker の ("no"), and words that +# attach to the base form of inflectional words, words that cannot be classified +# into any of the other categories below. This category includes indefinite nouns. +# e.g. あかつき, 暁, かい, 甲斐, 気, きらい, 嫌い, くせ, 癖, こと, 事, ごと, 毎, しだい, 次第, +# 順, せい, 所為, ついで, 序で, つもり, 積もり, 点, どころ, の, はず, 筈, はずみ, 弾み, +# 拍子, ふう, ふり, 振り, ほう, 方, 旨, もの, 物, 者, ゆえ, 故, ゆえん, 所以, わけ, 訳, +# わり, 割り, 割, ん-口語/, もん-口語/ +#名詞-非自立-一般 +# +# noun-affix-adverbial: noun affixes that that can behave as adverbs. +# e.g. あいだ, 間, あげく, 挙げ句, あと, 後, 余り, 以外, 以降, 以後, 以上, 以前, 一方, うえ, +# 上, うち, 内, おり, 折り, かぎり, 限り, きり, っきり, 結果, ころ, 頃, さい, 際, 最中, さなか, +# 最中, じたい, 自体, たび, 度, ため, 為, つど, 都度, とおり, 通り, とき, 時, ところ, 所, +# とたん, 途端, なか, 中, のち, 後, ばあい, 場合, 日, ぶん, 分, ほか, 他, まえ, 前, まま, +# 儘, 侭, みぎり, 矢先 +#名詞-非自立-副詞可能 +# +# noun-affix-aux: noun affixes treated as 助動詞 ("auxiliary verb") in school grammars +# with the stem よう(だ) ("you(da)"). +# e.g. よう, やう, 様 (よう) +#名詞-非自立-助動詞語幹 +# +# noun-affix-adjective-base: noun affixes that can connect to the indeclinable +# connection form な (aux "da"). +# e.g. みたい, ふう +#名詞-非自立-形容動詞語幹 +# +# noun-special: special nouns where the sub-classification is undefined. +#名詞-特殊 +# +# noun-special-aux: The そうだ ("souda") stem form that is used for reporting news, is +# treated as 助動詞 ("auxiliary verb") in school grammars, and attach to the base +# form of inflectional words. +# e.g. そう +#名詞-特殊-助動詞語幹 +# +# noun-suffix: noun suffixes where the sub-classification is undefined. +#名詞-接尾 +# +# noun-suffix-misc: Of the nouns or stem forms of other parts of speech that connect +# to ガル or タイ and can combine into compound nouns, words that cannot be classified into +# any of the other categories below. In general, this category is more inclusive than +# 接尾語 ("suffix") and is usually the last element in a compound noun. +# e.g. おき, かた, 方, 甲斐 (がい), がかり, ぎみ, 気味, ぐるみ, (~した) さ, 次第, 済 (ず) み, +# よう, (でき)っこ, 感, 観, 性, 学, 類, 面, 用 +#名詞-接尾-一般 +# +# noun-suffix-person: Suffixes that form nouns and attach to person names more often +# than other nouns. +# e.g. 君, 様, 著 +#名詞-接尾-人名 +# +# noun-suffix-place: Suffixes that form nouns and attach to place names more often +# than other nouns. +# e.g. 町, 市, 県 +#名詞-接尾-地域 +# +# noun-suffix-verbal: Of the suffixes that attach to nouns and form nouns, those that +# can appear before スル ("suru"). +# e.g. 化, 視, 分け, 入り, 落ち, 買い +#名詞-接尾-サ変接続 +# +# noun-suffix-aux: The stem form of そうだ (様態) that is used to indicate conditions, +# is treated as 助動詞 ("auxiliary verb") in school grammars, and attach to the +# conjunctive form of inflectional words. +# e.g. そう +#名詞-接尾-助動詞語幹 +# +# noun-suffix-adjective-base: Suffixes that attach to other nouns or the conjunctive +# form of inflectional words and appear before the copula だ ("da"). +# e.g. 的, げ, がち +#名詞-接尾-形容動詞語幹 +# +# noun-suffix-adverbial: Suffixes that attach to other nouns and can behave as adverbs. +# e.g. 後 (ご), 以後, 以降, 以前, 前後, 中, 末, 上, 時 (じ) +#名詞-接尾-副詞可能 +# +# noun-suffix-classifier: Suffixes that attach to numbers and form nouns. This category +# is more inclusive than 助数詞 ("classifier") and includes common nouns that attach +# to numbers. +# e.g. 個, つ, 本, 冊, パーセント, cm, kg, カ月, か国, 区画, 時間, 時半 +#名詞-接尾-助数詞 +# +# noun-suffix-special: Special suffixes that mainly attach to inflecting words. +# e.g. (楽し) さ, (考え) 方 +#名詞-接尾-特殊 +# +# noun-suffix-conjunctive: Nouns that behave like conjunctions and join two words +# together. +# e.g. (日本) 対 (アメリカ), 対 (アメリカ), (3) 対 (5), (女優) 兼 (主婦) +#名詞-接続詞的 +# +# noun-verbal_aux: Nouns that attach to the conjunctive particle て ("te") and are +# semantically verb-like. +# e.g. ごらん, ご覧, 御覧, 頂戴 +#名詞-動詞非自立的 +# +# noun-quotation: text that cannot be segmented into words, proverbs, Chinese poetry, +# dialects, English, etc. Currently, the only entry for 名詞 引用文字列 ("noun quotation") +# is いわく ("iwaku"). +#名詞-引用文字列 +# +# noun-nai_adjective: Words that appear before the auxiliary verb ない ("nai") and +# behave like an adjective. +# e.g. 申し訳, 仕方, とんでも, 違い +#名詞-ナイ形容詞語幹 +# +##### +# prefix: unclassified prefixes +#接頭詞 +# +# prefix-nominal: Prefixes that attach to nouns (including adjective stem forms) +# excluding numerical expressions. +# e.g. お (水), 某 (氏), 同 (社), 故 (~氏), 高 (品質), お (見事), ご (立派) +#接頭詞-名詞接続 +# +# prefix-verbal: Prefixes that attach to the imperative form of a verb or a verb +# in conjunctive form followed by なる/なさる/くださる. +# e.g. お (読みなさい), お (座り) +#接頭詞-動詞接続 +# +# prefix-adjectival: Prefixes that attach to adjectives. +# e.g. お (寒いですねえ), バカ (でかい) +#接頭詞-形容詞接続 +# +# prefix-numerical: Prefixes that attach to numerical expressions. +# e.g. 約, およそ, 毎時 +#接頭詞-数接続 +# +##### +# verb: unclassified verbs +#動詞 +# +# verb-main: +#動詞-自立 +# +# verb-auxiliary: +#動詞-非自立 +# +# verb-suffix: +#動詞-接尾 +# +##### +# adjective: unclassified adjectives +#形容詞 +# +# adjective-main: +#形容詞-自立 +# +# adjective-auxiliary: +#形容詞-非自立 +# +# adjective-suffix: +#形容詞-接尾 +# +##### +# adverb: unclassified adverbs +#副詞 +# +# adverb-misc: Words that can be segmented into one unit and where adnominal +# modification is not possible. +# e.g. あいかわらず, 多分 +#副詞-一般 +# +# adverb-particle_conjunction: Adverbs that can be followed by の, は, に, +# な, する, だ, etc. +# e.g. こんなに, そんなに, あんなに, なにか, なんでも +#副詞-助詞類接続 +# +##### +# adnominal: Words that only have noun-modifying forms. +# e.g. この, その, あの, どの, いわゆる, なんらかの, 何らかの, いろんな, こういう, そういう, ああいう, +# どういう, こんな, そんな, あんな, どんな, 大きな, 小さな, おかしな, ほんの, たいした, +# 「(, も) さる (ことながら)」, 微々たる, 堂々たる, 単なる, いかなる, 我が」「同じ, 亡き +#連体詞 +# +##### +# conjunction: Conjunctions that can occur independently. +# e.g. が, けれども, そして, じゃあ, それどころか +接続詞 +# +##### +# particle: unclassified particles. +助詞 +# +# particle-case: case particles where the subclassification is undefined. +助詞-格助詞 +# +# particle-case-misc: Case particles. +# e.g. から, が, で, と, に, へ, より, を, の, にて +助詞-格助詞-一般 +# +# particle-case-quote: the "to" that appears after nouns, a person’s speech, +# quotation marks, expressions of decisions from a meeting, reasons, judgements, +# conjectures, etc. +# e.g. ( だ) と (述べた.), ( である) と (して執行猶予...) +助詞-格助詞-引用 +# +# particle-case-compound: Compounds of particles and verbs that mainly behave +# like case particles. +# e.g. という, といった, とかいう, として, とともに, と共に, でもって, にあたって, に当たって, に当って, +# にあたり, に当たり, に当り, に当たる, にあたる, において, に於いて,に於て, における, に於ける, +# にかけ, にかけて, にかんし, に関し, にかんして, に関して, にかんする, に関する, に際し, +# に際して, にしたがい, に従い, に従う, にしたがって, に従って, にたいし, に対し, にたいして, +# に対して, にたいする, に対する, について, につき, につけ, につけて, につれ, につれて, にとって, +# にとり, にまつわる, によって, に依って, に因って, により, に依り, に因り, による, に依る, に因る, +# にわたって, にわたる, をもって, を以って, を通じ, を通じて, を通して, をめぐって, をめぐり, をめぐる, +# って-口語/, ちゅう-関西弁「という」/, (何) ていう (人)-口語/, っていう-口語/, といふ, とかいふ +助詞-格助詞-連語 +# +# particle-conjunctive: +# e.g. から, からには, が, けれど, けれども, けど, し, つつ, て, で, と, ところが, どころか, とも, ども, +# ながら, なり, ので, のに, ば, ものの, や ( した), やいなや, (ころん) じゃ(いけない)-口語/, +# (行っ) ちゃ(いけない)-口語/, (言っ) たって (しかたがない)-口語/, (それがなく)ったって (平気)-口語/ +助詞-接続助詞 +# +# particle-dependency: +# e.g. こそ, さえ, しか, すら, は, も, ぞ +助詞-係助詞 +# +# particle-adverbial: +# e.g. がてら, かも, くらい, 位, ぐらい, しも, (学校) じゃ(これが流行っている)-口語/, +# (それ)じゃあ (よくない)-口語/, ずつ, (私) なぞ, など, (私) なり (に), (先生) なんか (大嫌い)-口語/, +# (私) なんぞ, (先生) なんて (大嫌い)-口語/, のみ, だけ, (私) だって-口語/, だに, +# (彼)ったら-口語/, (お茶) でも (いかが), 等 (とう), (今後) とも, ばかり, ばっか-口語/, ばっかり-口語/, +# ほど, 程, まで, 迄, (誰) も (が)([助詞-格助詞] および [助詞-係助詞] の前に位置する「も」) +助詞-副助詞 +# +# particle-interjective: particles with interjective grammatical roles. +# e.g. (松島) や +助詞-間投助詞 +# +# particle-coordinate: +# e.g. と, たり, だの, だり, とか, なり, や, やら +助詞-並立助詞 +# +# particle-final: +# e.g. かい, かしら, さ, ぜ, (だ)っけ-口語/, (とまってる) で-方言/, な, ナ, なあ-口語/, ぞ, ね, ネ, +# ねぇ-口語/, ねえ-口語/, ねん-方言/, の, のう-口語/, や, よ, ヨ, よぉ-口語/, わ, わい-口語/ +助詞-終助詞 +# +# particle-adverbial/conjunctive/final: The particle "ka" when unknown whether it is +# adverbial, conjunctive, or sentence final. For example: +# (a) 「A か B か」. Ex:「(国内で運用する) か,(海外で運用する) か (.)」 +# (b) Inside an adverb phrase. Ex:「(幸いという) か (, 死者はいなかった.)」 +# 「(祈りが届いたせい) か (, 試験に合格した.)」 +# (c) 「かのように」. Ex:「(何もなかった) か (のように振る舞った.)」 +# e.g. か +助詞-副助詞/並立助詞/終助詞 +# +# particle-adnominalizer: The "no" that attaches to nouns and modifies +# non-inflectional words. +助詞-連体化 +# +# particle-adnominalizer: The "ni" and "to" that appear following nouns and adverbs +# that are giongo, giseigo, or gitaigo. +# e.g. に, と +助詞-副詞化 +# +# particle-special: A particle that does not fit into one of the above classifications. +# This includes particles that are used in Tanka, Haiku, and other poetry. +# e.g. かな, けむ, ( しただろう) に, (あんた) にゃ(わからん), (俺) ん (家) +助詞-特殊 +# +##### +# auxiliary-verb: +助動詞 +# +##### +# interjection: Greetings and other exclamations. +# e.g. おはよう, おはようございます, こんにちは, こんばんは, ありがとう, どうもありがとう, ありがとうございます, +# いただきます, ごちそうさま, さよなら, さようなら, はい, いいえ, ごめん, ごめんなさい +#感動詞 +# +##### +# symbol: unclassified Symbols. +記号 +# +# symbol-misc: A general symbol not in one of the categories below. +# e.g. [○◎@$〒→+] +記号-一般 +# +# symbol-comma: Commas +# e.g. [,、] +記号-読点 +# +# symbol-period: Periods and full stops. +# e.g. [..。] +記号-句点 +# +# symbol-space: Full-width whitespace. +記号-空白 +# +# symbol-open_bracket: +# e.g. [({‘“『【] +記号-括弧開 +# +# symbol-close_bracket: +# e.g. [)}’”』」】] +記号-括弧閉 +# +# symbol-alphabetic: +#記号-アルファベット +# +##### +# other: unclassified other +#その他 +# +# other-interjection: Words that are hard to classify as noun-suffixes or +# sentence-final particles. +# e.g. (だ)ァ +その他-間投 +# +##### +# filler: Aizuchi that occurs during a conversation or sounds inserted as filler. +# e.g. あの, うんと, えと +フィラー +# +##### +# non-verbal: non-verbal sound. +非言語音 +# +##### +# fragment: +#語断片 +# +##### +# unknown: unknown part of speech. +#未知語 +# +##### End of file diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ar.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ar.txt new file mode 100644 index 00000000000..046829db6a2 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ar.txt @@ -0,0 +1,125 @@ +# This file was created by Jacques Savoy and is distributed under the BSD license. +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# Also see http://www.opensource.org/licenses/bsd-license.html +# Cleaned on October 11, 2009 (not normalized, so use before normalization) +# This means that when modifying this list, you might need to add some +# redundant entries, for example containing forms with both أ and ا +من +ومن +منها +منه +في +وفي +فيها +فيه +و +ف +ثم +او +أو +ب +بها +به +ا +أ +اى +اي +أي +أى +لا +ولا +الا +ألا +إلا +لكن +ما +وما +كما +فما +عن +مع +اذا +إذا +ان +أن +إن +انها +أنها +إنها +انه +أنه +إنه +بان +بأن +فان +فأن +وان +وأن +وإن +التى +التي +الذى +الذي +الذين +الى +الي +إلى +إلي +على +عليها +عليه +اما +أما +إما +ايضا +أيضا +كل +وكل +لم +ولم +لن +ولن +هى +هي +هو +وهى +وهي +وهو +فهى +فهي +فهو +انت +أنت +لك +لها +له +هذه +هذا +تلك +ذلك +هناك +كانت +كان +يكون +تكون +وكانت +وكان +غير +بعض +قد +نحو +بين +بينما +منذ +ضمن +حيث +الان +الآن +خلال +بعد +قبل +حتى +عند +عندما +لدى +جميع diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_bg.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_bg.txt new file mode 100644 index 00000000000..1ae4ba2ae38 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_bg.txt @@ -0,0 +1,193 @@ +# This file was created by Jacques Savoy and is distributed under the BSD license. +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# Also see http://www.opensource.org/licenses/bsd-license.html +а +аз +ако +ала +бе +без +беше +би +бил +била +били +било +близо +бъдат +бъде +бяха +в +вас +ваш +ваша +вероятно +вече +взема +ви +вие +винаги +все +всеки +всички +всичко +всяка +във +въпреки +върху +г +ги +главно +го +д +да +дали +до +докато +докога +дори +досега +доста +е +едва +един +ето +за +зад +заедно +заради +засега +затова +защо +защото +и +из +или +им +има +имат +иска +й +каза +как +каква +какво +както +какъв +като +кога +когато +което +които +кой +който +колко +която +къде +където +към +ли +м +ме +между +мен +ми +мнозина +мога +могат +може +моля +момента +му +н +на +над +назад +най +направи +напред +например +нас +не +него +нея +ни +ние +никой +нито +но +някои +някой +няма +обаче +около +освен +особено +от +отгоре +отново +още +пак +по +повече +повечето +под +поне +поради +после +почти +прави +пред +преди +през +при +пък +първо +с +са +само +се +сега +си +скоро +след +сме +според +сред +срещу +сте +съм +със +също +т +тази +така +такива +такъв +там +твой +те +тези +ти +тн +то +това +тогава +този +той +толкова +точно +трябва +тук +тъй +тя +тях +у +харесва +ч +че +често +чрез +ще +щом +я diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ca.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ca.txt new file mode 100644 index 00000000000..3da65deafe1 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ca.txt @@ -0,0 +1,220 @@ +# Catalan stopwords from http://github.com/vcl/cue.language (Apache 2 Licensed) +a +abans +ací +ah +així +això +al +als +aleshores +algun +alguna +algunes +alguns +alhora +allà +allí +allò +altra +altre +altres +amb +ambdós +ambdues +apa +aquell +aquella +aquelles +aquells +aquest +aquesta +aquestes +aquests +aquí +baix +cada +cadascú +cadascuna +cadascunes +cadascuns +com +contra +d'un +d'una +d'unes +d'uns +dalt +de +del +dels +des +després +dins +dintre +donat +doncs +durant +e +eh +el +els +em +en +encara +ens +entre +érem +eren +éreu +es +és +esta +està +estàvem +estaven +estàveu +esteu +et +etc +ets +fins +fora +gairebé +ha +han +has +havia +he +hem +heu +hi +ho +i +igual +iguals +ja +l'hi +la +les +li +li'n +llavors +m'he +ma +mal +malgrat +mateix +mateixa +mateixes +mateixos +me +mentre +més +meu +meus +meva +meves +molt +molta +moltes +molts +mon +mons +n'he +n'hi +ne +ni +no +nogensmenys +només +nosaltres +nostra +nostre +nostres +o +oh +oi +on +pas +pel +pels +per +però +perquè +poc +poca +pocs +poques +potser +propi +qual +quals +quan +quant +que +què +quelcom +qui +quin +quina +quines +quins +s'ha +s'han +sa +semblant +semblants +ses +seu +seus +seva +seva +seves +si +sobre +sobretot +sóc +solament +sols +son +són +sons +sota +sou +t'ha +t'han +t'he +ta +tal +també +tampoc +tan +tant +tanta +tantes +teu +teus +teva +teves +ton +tons +tot +tota +totes +tots +un +una +unes +uns +us +va +vaig +vam +van +vas +veu +vosaltres +vostra +vostre +vostres diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_cz.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_cz.txt new file mode 100644 index 00000000000..53c6097dac7 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_cz.txt @@ -0,0 +1,172 @@ +a +s +k +o +i +u +v +z +dnes +cz +tímto +budeš +budem +byli +jseš +můj +svým +ta +tomto +tohle +tuto +tyto +jej +zda +proč +máte +tato +kam +tohoto +kdo +kteří +mi +nám +tom +tomuto +mít +nic +proto +kterou +byla +toho +protože +asi +ho +naši +napište +re +což +tím +takže +svých +její +svými +jste +aj +tu +tedy +teto +bylo +kde +ke +pravé +ji +nad +nejsou +či +pod +téma +mezi +přes +ty +pak +vám +ani +když +však +neg +jsem +tento +článku +články +aby +jsme +před +pta +jejich +byl +ještě +až +bez +také +pouze +první +vaše +která +nás +nový +tipy +pokud +může +strana +jeho +své +jiné +zprávy +nové +není +vás +jen +podle +zde +už +být +více +bude +již +než +který +by +které +co +nebo +ten +tak +má +při +od +po +jsou +jak +další +ale +si +se +ve +to +jako +za +zpět +ze +do +pro +je +na +atd +atp +jakmile +přičemž +já +on +ona +ono +oni +ony +my +vy +jí +ji +mě +mne +jemu +tomu +těm +těmu +němu +němuž +jehož +jíž +jelikož +jež +jakož +načež diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_da.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_da.txt new file mode 100644 index 00000000000..a3ff5fe122c --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_da.txt @@ -0,0 +1,108 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/danish/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Danish stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | This is a ranked list (commonest to rarest) of stopwords derived from + | a large text sample. + + +og | and +i | in +jeg | I +det | that (dem. pronoun)/it (pers. pronoun) +at | that (in front of a sentence)/to (with infinitive) +en | a/an +den | it (pers. pronoun)/that (dem. pronoun) +til | to/at/for/until/against/by/of/into, more +er | present tense of "to be" +som | who, as +på | on/upon/in/on/at/to/after/of/with/for, on +de | they +med | with/by/in, along +han | he +af | of/by/from/off/for/in/with/on, off +for | at/for/to/from/by/of/ago, in front/before, because +ikke | not +der | who/which, there/those +var | past tense of "to be" +mig | me/myself +sig | oneself/himself/herself/itself/themselves +men | but +et | a/an/one, one (number), someone/somebody/one +har | present tense of "to have" +om | round/about/for/in/a, about/around/down, if +vi | we +min | my +havde | past tense of "to have" +ham | him +hun | she +nu | now +over | over/above/across/by/beyond/past/on/about, over/past +da | then, when/as/since +fra | from/off/since, off, since +du | you +ud | out +sin | his/her/its/one's +dem | them +os | us/ourselves +op | up +man | you/one +hans | his +hvor | where +eller | or +hvad | what +skal | must/shall etc. +selv | myself/youself/herself/ourselves etc., even +her | here +alle | all/everyone/everybody etc. +vil | will (verb) +blev | past tense of "to stay/to remain/to get/to become" +kunne | could +ind | in +når | when +være | present tense of "to be" +dog | however/yet/after all +noget | something +ville | would +jo | you know/you see (adv), yes +deres | their/theirs +efter | after/behind/according to/for/by/from, later/afterwards +ned | down +skulle | should +denne | this +end | than +dette | this +mit | my/mine +også | also +under | under/beneath/below/during, below/underneath +have | have +dig | you +anden | other +hende | her +mine | my +alt | everything +meget | much/very, plenty of +sit | his, her, its, one's +sine | his, her, its, one's +vor | our +mod | against +disse | these +hvis | if +din | your/yours +nogle | some +hos | by/at +blive | be/become +mange | many +ad | by/through +bliver | present tense of "to be/to become" +hendes | her/hers +været | be +thi | for (conj) +jer | you +sådan | such, like this/like that diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_de.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_de.txt new file mode 100644 index 00000000000..f7703841887 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_de.txt @@ -0,0 +1,292 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/german/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A German stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | The number of forms in this list is reduced significantly by passing it + | through the German stemmer. + + +aber | but + +alle | all +allem +allen +aller +alles + +als | than, as +also | so +am | an + dem +an | at + +ander | other +andere +anderem +anderen +anderer +anderes +anderm +andern +anderr +anders + +auch | also +auf | on +aus | out of +bei | by +bin | am +bis | until +bist | art +da | there +damit | with it +dann | then + +der | the +den +des +dem +die +das + +daß | that + +derselbe | the same +derselben +denselben +desselben +demselben +dieselbe +dieselben +dasselbe + +dazu | to that + +dein | thy +deine +deinem +deinen +deiner +deines + +denn | because + +derer | of those +dessen | of him + +dich | thee +dir | to thee +du | thou + +dies | this +diese +diesem +diesen +dieser +dieses + + +doch | (several meanings) +dort | (over) there + + +durch | through + +ein | a +eine +einem +einen +einer +eines + +einig | some +einige +einigem +einigen +einiger +einiges + +einmal | once + +er | he +ihn | him +ihm | to him + +es | it +etwas | something + +euer | your +eure +eurem +euren +eurer +eures + +für | for +gegen | towards +gewesen | p.p. of sein +hab | have +habe | have +haben | have +hat | has +hatte | had +hatten | had +hier | here +hin | there +hinter | behind + +ich | I +mich | me +mir | to me + + +ihr | you, to her +ihre +ihrem +ihren +ihrer +ihres +euch | to you + +im | in + dem +in | in +indem | while +ins | in + das +ist | is + +jede | each, every +jedem +jeden +jeder +jedes + +jene | that +jenem +jenen +jener +jenes + +jetzt | now +kann | can + +kein | no +keine +keinem +keinen +keiner +keines + +können | can +könnte | could +machen | do +man | one + +manche | some, many a +manchem +manchen +mancher +manches + +mein | my +meine +meinem +meinen +meiner +meines + +mit | with +muss | must +musste | had to +nach | to(wards) +nicht | not +nichts | nothing +noch | still, yet +nun | now +nur | only +ob | whether +oder | or +ohne | without +sehr | very + +sein | his +seine +seinem +seinen +seiner +seines + +selbst | self +sich | herself + +sie | they, she +ihnen | to them + +sind | are +so | so + +solche | such +solchem +solchen +solcher +solches + +soll | shall +sollte | should +sondern | but +sonst | else +über | over +um | about, around +und | and + +uns | us +unse +unsem +unsen +unser +unses + +unter | under +viel | much +vom | von + dem +von | from +vor | before +während | while +war | was +waren | were +warst | wast +was | what +weg | away, off +weil | because +weiter | further + +welche | which +welchem +welchen +welcher +welches + +wenn | when +werde | will +werden | will +wie | how +wieder | again +will | want +wir | we +wird | will +wirst | willst +wo | where +wollen | want +wollte | wanted +würde | would +würden | would +zu | to +zum | zu + dem +zur | zu + der +zwar | indeed +zwischen | between + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_el.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_el.txt new file mode 100644 index 00000000000..232681f5bd6 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_el.txt @@ -0,0 +1,78 @@ +# Lucene Greek Stopwords list +# Note: by default this file is used after GreekLowerCaseFilter, +# so when modifying this file use 'σ' instead of 'ς' +ο +η +το +οι +τα +του +τησ +των +τον +την +και +κι +κ +ειμαι +εισαι +ειναι +ειμαστε +ειστε +στο +στον +στη +στην +μα +αλλα +απο +για +προσ +με +σε +ωσ +παρα +αντι +κατα +μετα +θα +να +δε +δεν +μη +μην +επι +ενω +εαν +αν +τοτε +που +πωσ +ποιοσ +ποια +ποιο +ποιοι +ποιεσ +ποιων +ποιουσ +αυτοσ +αυτη +αυτο +αυτοι +αυτων +αυτουσ +αυτεσ +αυτα +εκεινοσ +εκεινη +εκεινο +εκεινοι +εκεινεσ +εκεινα +εκεινων +εκεινουσ +οπωσ +ομωσ +ισωσ +οσο +οτι diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_en.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_en.txt new file mode 100644 index 00000000000..2c164c0b2a1 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_en.txt @@ -0,0 +1,54 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# a couple of test stopwords to test that the words are really being +# configured from this file: +stopworda +stopwordb + +# Standard english stop words taken from Lucene's StopAnalyzer +a +an +and +are +as +at +be +but +by +for +if +in +into +is +it +no +not +of +on +or +such +that +the +their +then +there +these +they +this +to +was +will +with diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_es.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_es.txt new file mode 100644 index 00000000000..2db14760075 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_es.txt @@ -0,0 +1,354 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/spanish/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Spanish stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + + | The following is a ranked list (commonest to rarest) of stopwords + | deriving from a large sample of text. + + | Extra words have been added at the end. + +de | from, of +la | the, her +que | who, that +el | the +en | in +y | and +a | to +los | the, them +del | de + el +se | himself, from him etc +las | the, them +por | for, by, etc +un | a +para | for +con | with +no | no +una | a +su | his, her +al | a + el + | es from SER +lo | him +como | how +más | more +pero | pero +sus | su plural +le | to him, her +ya | already +o | or + | fue from SER +este | this + | ha from HABER +sí | himself etc +porque | because +esta | this + | son from SER +entre | between + | está from ESTAR +cuando | when +muy | very +sin | without +sobre | on + | ser from SER + | tiene from TENER +también | also +me | me +hasta | until +hay | there is/are +donde | where + | han from HABER +quien | whom, that + | están from ESTAR + | estado from ESTAR +desde | from +todo | all +nos | us +durante | during + | estados from ESTAR +todos | all +uno | a +les | to them +ni | nor +contra | against +otros | other + | fueron from SER +ese | that +eso | that + | había from HABER +ante | before +ellos | they +e | and (variant of y) +esto | this +mí | me +antes | before +algunos | some +qué | what? +unos | a +yo | I +otro | other +otras | other +otra | other +él | he +tanto | so much, many +esa | that +estos | these +mucho | much, many +quienes | who +nada | nothing +muchos | many +cual | who + | sea from SER +poco | few +ella | she +estar | to be + | haber from HABER +estas | these + | estaba from ESTAR + | estamos from ESTAR +algunas | some +algo | something +nosotros | we + + | other forms + +mi | me +mis | mi plural +tú | thou +te | thee +ti | thee +tu | thy +tus | tu plural +ellas | they +nosotras | we +vosotros | you +vosotras | you +os | you +mío | mine +mía | +míos | +mías | +tuyo | thine +tuya | +tuyos | +tuyas | +suyo | his, hers, theirs +suya | +suyos | +suyas | +nuestro | ours +nuestra | +nuestros | +nuestras | +vuestro | yours +vuestra | +vuestros | +vuestras | +esos | those +esas | those + + | forms of estar, to be (not including the infinitive): +estoy +estás +está +estamos +estáis +están +esté +estés +estemos +estéis +estén +estaré +estarás +estará +estaremos +estaréis +estarán +estaría +estarías +estaríamos +estaríais +estarían +estaba +estabas +estábamos +estabais +estaban +estuve +estuviste +estuvo +estuvimos +estuvisteis +estuvieron +estuviera +estuvieras +estuviéramos +estuvierais +estuvieran +estuviese +estuvieses +estuviésemos +estuvieseis +estuviesen +estando +estado +estada +estados +estadas +estad + + | forms of haber, to have (not including the infinitive): +he +has +ha +hemos +habéis +han +haya +hayas +hayamos +hayáis +hayan +habré +habrás +habrá +habremos +habréis +habrán +habría +habrías +habríamos +habríais +habrían +había +habías +habíamos +habíais +habían +hube +hubiste +hubo +hubimos +hubisteis +hubieron +hubiera +hubieras +hubiéramos +hubierais +hubieran +hubiese +hubieses +hubiésemos +hubieseis +hubiesen +habiendo +habido +habida +habidos +habidas + + | forms of ser, to be (not including the infinitive): +soy +eres +es +somos +sois +son +sea +seas +seamos +seáis +sean +seré +serás +será +seremos +seréis +serán +sería +serías +seríamos +seríais +serían +era +eras +éramos +erais +eran +fui +fuiste +fue +fuimos +fuisteis +fueron +fuera +fueras +fuéramos +fuerais +fueran +fuese +fueses +fuésemos +fueseis +fuesen +siendo +sido + | sed also means 'thirst' + + | forms of tener, to have (not including the infinitive): +tengo +tienes +tiene +tenemos +tenéis +tienen +tenga +tengas +tengamos +tengáis +tengan +tendré +tendrás +tendrá +tendremos +tendréis +tendrán +tendría +tendrías +tendríamos +tendríais +tendrían +tenía +tenías +teníamos +teníais +tenían +tuve +tuviste +tuvo +tuvimos +tuvisteis +tuvieron +tuviera +tuvieras +tuviéramos +tuvierais +tuvieran +tuviese +tuvieses +tuviésemos +tuvieseis +tuviesen +teniendo +tenido +tenida +tenidos +tenidas +tened + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_eu.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_eu.txt new file mode 100644 index 00000000000..25f1db93460 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_eu.txt @@ -0,0 +1,99 @@ +# example set of basque stopwords +al +anitz +arabera +asko +baina +bat +batean +batek +bati +batzuei +batzuek +batzuetan +batzuk +bera +beraiek +berau +berauek +bere +berori +beroriek +beste +bezala +da +dago +dira +ditu +du +dute +edo +egin +ere +eta +eurak +ez +gainera +gu +gutxi +guzti +haiei +haiek +haietan +hainbeste +hala +han +handik +hango +hara +hari +hark +hartan +hau +hauei +hauek +hauetan +hemen +hemendik +hemengo +hi +hona +honek +honela +honetan +honi +hor +hori +horiei +horiek +horietan +horko +horra +horrek +horrela +horretan +horri +hortik +hura +izan +ni +noiz +nola +non +nondik +nongo +nor +nora +ze +zein +zen +zenbait +zenbat +zer +zergatik +ziren +zituen +zu +zuek +zuen +zuten diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_fa.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_fa.txt new file mode 100644 index 00000000000..723641c6da7 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_fa.txt @@ -0,0 +1,313 @@ +# This file was created by Jacques Savoy and is distributed under the BSD license. +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# Also see http://www.opensource.org/licenses/bsd-license.html +# Note: by default this file is used after normalization, so when adding entries +# to this file, use the arabic 'ي' instead of 'ی' +انان +نداشته +سراسر +خياه +ايشان +وي +تاكنون +بيشتري +دوم +پس +ناشي +وگو +يا +داشتند +سپس +هنگام +هرگز +پنج +نشان +امسال +ديگر +گروهي +شدند +چطور +ده +و +دو +نخستين +ولي +چرا +چه +وسط +ه +كدام +قابل +يك +رفت +هفت +همچنين +در +هزار +بله +بلي +شايد +اما +شناسي +گرفته +دهد +داشته +دانست +داشتن +خواهيم +ميليارد +وقتيكه +امد +خواهد +جز +اورده +شده +بلكه +خدمات +شدن +برخي +نبود +بسياري +جلوگيري +حق +كردند +نوعي +بعري +نكرده +نظير +نبايد +بوده +بودن +داد +اورد +هست +جايي +شود +دنبال +داده +بايد +سابق +هيچ +همان +انجا +كمتر +كجاست +گردد +كسي +تر +مردم +تان +دادن +بودند +سري +جدا +ندارند +مگر +يكديگر +دارد +دهند +بنابراين +هنگامي +سمت +جا +انچه +خود +دادند +زياد +دارند +اثر +بدون +بهترين +بيشتر +البته +به +براساس +بيرون +كرد +بعضي +گرفت +توي +اي +ميليون +او +جريان +تول +بر +مانند +برابر +باشيم +مدتي +گويند +اكنون +تا +تنها +جديد +چند +بي +نشده +كردن +كردم +گويد +كرده +كنيم +نمي +نزد +روي +قصد +فقط +بالاي +ديگران +اين +ديروز +توسط +سوم +ايم +دانند +سوي +استفاده +شما +كنار +داريم +ساخته +طور +امده +رفته +نخست +بيست +نزديك +طي +كنيد +از +انها +تمامي +داشت +يكي +طريق +اش +چيست +روب +نمايد +گفت +چندين +چيزي +تواند +ام +ايا +با +ان +ايد +ترين +اينكه +ديگري +راه +هايي +بروز +همچنان +پاعين +كس +حدود +مختلف +مقابل +چيز +گيرد +ندارد +ضد +همچون +سازي +شان +مورد +باره +مرسي +خويش +برخوردار +چون +خارج +شش +هنوز +تحت +ضمن +هستيم +گفته +فكر +بسيار +پيش +براي +روزهاي +انكه +نخواهد +بالا +كل +وقتي +كي +چنين +كه +گيري +نيست +است +كجا +كند +نيز +يابد +بندي +حتي +توانند +عقب +خواست +كنند +بين +تمام +همه +ما +باشند +مثل +شد +اري +باشد +اره +طبق +بعد +اگر +صورت +غير +جاي +بيش +ريزي +اند +زيرا +چگونه +بار +لطفا +مي +درباره +من +ديده +همين +گذاري +برداري +علت +گذاشته +هم +فوق +نه +ها +شوند +اباد +همواره +هر +اول +خواهند +چهار +نام +امروز +مان +هاي +قبل +كنم +سعي +تازه +را +هستند +زير +جلوي +عنوان +بود diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_fi.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_fi.txt new file mode 100644 index 00000000000..addad798c4b --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_fi.txt @@ -0,0 +1,95 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/finnish/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + +| forms of BE + +olla +olen +olet +on +olemme +olette +ovat +ole | negative form + +oli +olisi +olisit +olisin +olisimme +olisitte +olisivat +olit +olin +olimme +olitte +olivat +ollut +olleet + +en | negation +et +ei +emme +ette +eivät + +|Nom Gen Acc Part Iness Elat Illat Adess Ablat Allat Ess Trans +minä minun minut minua minussa minusta minuun minulla minulta minulle | I +sinä sinun sinut sinua sinussa sinusta sinuun sinulla sinulta sinulle | you +hän hänen hänet häntä hänessä hänestä häneen hänellä häneltä hänelle | he she +me meidän meidät meitä meissä meistä meihin meillä meiltä meille | we +te teidän teidät teitä teissä teistä teihin teillä teiltä teille | you +he heidän heidät heitä heissä heistä heihin heillä heiltä heille | they + +tämä tämän tätä tässä tästä tähän tallä tältä tälle tänä täksi | this +tuo tuon tuotä tuossa tuosta tuohon tuolla tuolta tuolle tuona tuoksi | that +se sen sitä siinä siitä siihen sillä siltä sille sinä siksi | it +nämä näiden näitä näissä näistä näihin näillä näiltä näille näinä näiksi | these +nuo noiden noita noissa noista noihin noilla noilta noille noina noiksi | those +ne niiden niitä niissä niistä niihin niillä niiltä niille niinä niiksi | they + +kuka kenen kenet ketä kenessä kenestä keneen kenellä keneltä kenelle kenenä keneksi| who +ketkä keiden ketkä keitä keissä keistä keihin keillä keiltä keille keinä keiksi | (pl) +mikä minkä minkä mitä missä mistä mihin millä miltä mille minä miksi | which what +mitkä | (pl) + +joka jonka jota jossa josta johon jolla jolta jolle jona joksi | who which +jotka joiden joita joissa joista joihin joilla joilta joille joina joiksi | (pl) + +| conjunctions + +että | that +ja | and +jos | if +koska | because +kuin | than +mutta | but +niin | so +sekä | and +sillä | for +tai | or +vaan | but +vai | or +vaikka | although + + +| prepositions + +kanssa | with +mukaan | according to +noin | about +poikki | across +yli | over, across + +| other + +kun | when +niin | so +nyt | now +itse | self + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_fr.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_fr.txt new file mode 100644 index 00000000000..c00837ea939 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_fr.txt @@ -0,0 +1,183 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/french/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A French stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + +au | a + le +aux | a + les +avec | with +ce | this +ces | these +dans | with +de | of +des | de + les +du | de + le +elle | she +en | `of them' etc +et | and +eux | them +il | he +je | I +la | the +le | the +leur | their +lui | him +ma | my (fem) +mais | but +me | me +même | same; as in moi-même (myself) etc +mes | me (pl) +moi | me +mon | my (masc) +ne | not +nos | our (pl) +notre | our +nous | we +on | one +ou | where +par | by +pas | not +pour | for +qu | que before vowel +que | that +qui | who +sa | his, her (fem) +se | oneself +ses | his (pl) +son | his, her (masc) +sur | on +ta | thy (fem) +te | thee +tes | thy (pl) +toi | thee +ton | thy (masc) +tu | thou +un | a +une | a +vos | your (pl) +votre | your +vous | you + + | single letter forms + +c | c' +d | d' +j | j' +l | l' +à | to, at +m | m' +n | n' +s | s' +t | t' +y | there + + | forms of être (not including the infinitive): +été +étée +étées +étés +étant +suis +es +est +sommes +êtes +sont +serai +seras +sera +serons +serez +seront +serais +serait +serions +seriez +seraient +étais +était +étions +étiez +étaient +fus +fut +fûmes +fûtes +furent +sois +soit +soyons +soyez +soient +fusse +fusses +fût +fussions +fussiez +fussent + + | forms of avoir (not including the infinitive): +ayant +eu +eue +eues +eus +ai +as +avons +avez +ont +aurai +auras +aura +aurons +aurez +auront +aurais +aurait +aurions +auriez +auraient +avais +avait +avions +aviez +avaient +eut +eûmes +eûtes +eurent +aie +aies +ait +ayons +ayez +aient +eusse +eusses +eût +eussions +eussiez +eussent + + | Later additions (from Jean-Christophe Deschamps) +ceci | this +celà  | that +cet | this +cette | this +ici | here +ils | they +les | the (pl) +leurs | their (pl) +quel | which +quels | which +quelle | which +quelles | which +sans | without +soi | oneself + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ga.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ga.txt new file mode 100644 index 00000000000..9ff88d747e5 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ga.txt @@ -0,0 +1,110 @@ + +a +ach +ag +agus +an +aon +ar +arna +as +b' +ba +beirt +bhúr +caoga +ceathair +ceathrar +chomh +chtó +chuig +chun +cois +céad +cúig +cúigear +d' +daichead +dar +de +deich +deichniúr +den +dhá +do +don +dtí +dá +dár +dó +faoi +faoin +faoina +faoinár +fara +fiche +gach +gan +go +gur +haon +hocht +i +iad +idir +in +ina +ins +inár +is +le +leis +lena +lenár +m' +mar +mo +mé +na +nach +naoi +naonúr +ná +ní +níor +nó +nócha +ocht +ochtar +os +roimh +sa +seacht +seachtar +seachtó +seasca +seisear +siad +sibh +sinn +sna +sé +sí +tar +thar +thú +triúr +trí +trína +trínár +tríocha +tú +um +ár +é +éis +í +ó +ón +óna +ónár diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_gl.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_gl.txt new file mode 100644 index 00000000000..d8760b12c14 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_gl.txt @@ -0,0 +1,161 @@ +# galican stopwords +a +aínda +alí +aquel +aquela +aquelas +aqueles +aquilo +aquí +ao +aos +as +así +á +ben +cando +che +co +coa +comigo +con +connosco +contigo +convosco +coas +cos +cun +cuns +cunha +cunhas +da +dalgunha +dalgunhas +dalgún +dalgúns +das +de +del +dela +delas +deles +desde +deste +do +dos +dun +duns +dunha +dunhas +e +el +ela +elas +eles +en +era +eran +esa +esas +ese +eses +esta +estar +estaba +está +están +este +estes +estiven +estou +eu +é +facer +foi +foron +fun +había +hai +iso +isto +la +las +lle +lles +lo +los +mais +me +meu +meus +min +miña +miñas +moi +na +nas +neste +nin +no +non +nos +nosa +nosas +noso +nosos +nós +nun +nunha +nuns +nunhas +o +os +ou +ó +ós +para +pero +pode +pois +pola +polas +polo +polos +por +que +se +senón +ser +seu +seus +sexa +sido +sobre +súa +súas +tamén +tan +te +ten +teñen +teño +ter +teu +teus +ti +tido +tiña +tiven +túa +túas +un +unha +unhas +uns +vos +vosa +vosas +voso +vosos +vós diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_hi.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_hi.txt new file mode 100644 index 00000000000..86286bb083b --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_hi.txt @@ -0,0 +1,235 @@ +# Also see http://www.opensource.org/licenses/bsd-license.html +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# This file was created by Jacques Savoy and is distributed under the BSD license. +# Note: by default this file also contains forms normalized by HindiNormalizer +# for spelling variation (see section below), such that it can be used whether or +# not you enable that feature. When adding additional entries to this list, +# please add the normalized form as well. +अंदर +अत +अपना +अपनी +अपने +अभी +आदि +आप +इत्यादि +इन +इनका +इन्हीं +इन्हें +इन्हों +इस +इसका +इसकी +इसके +इसमें +इसी +इसे +उन +उनका +उनकी +उनके +उनको +उन्हीं +उन्हें +उन्हों +उस +उसके +उसी +उसे +एक +एवं +एस +ऐसे +और +कई +कर +करता +करते +करना +करने +करें +कहते +कहा +का +काफ़ी +कि +कितना +किन्हें +किन्हों +किया +किर +किस +किसी +किसे +की +कुछ +कुल +के +को +कोई +कौन +कौनसा +गया +घर +जब +जहाँ +जा +जितना +जिन +जिन्हें +जिन्हों +जिस +जिसे +जीधर +जैसा +जैसे +जो +तक +तब +तरह +तिन +तिन्हें +तिन्हों +तिस +तिसे +तो +था +थी +थे +दबारा +दिया +दुसरा +दूसरे +दो +द्वारा +न +नहीं +ना +निहायत +नीचे +ने +पर +पर +पहले +पूरा +पे +फिर +बनी +बही +बहुत +बाद +बाला +बिलकुल +भी +भीतर +मगर +मानो +मे +में +यदि +यह +यहाँ +यही +या +यिह +ये +रखें +रहा +रहे +ऱ्वासा +लिए +लिये +लेकिन +व +वर्ग +वह +वह +वहाँ +वहीं +वाले +वुह +वे +वग़ैरह +संग +सकता +सकते +सबसे +सभी +साथ +साबुत +साभ +सारा +से +सो +ही +हुआ +हुई +हुए +है +हैं +हो +होता +होती +होते +होना +होने +# additional normalized forms of the above +अपनि +जेसे +होति +सभि +तिंहों +इंहों +दवारा +इसि +किंहें +थि +उंहों +ओर +जिंहें +वहिं +अभि +बनि +हि +उंहिं +उंहें +हें +वगेरह +एसे +रवासा +कोन +निचे +काफि +उसि +पुरा +भितर +हे +बहि +वहां +कोइ +यहां +जिंहों +तिंहें +किसि +कइ +यहि +इंहिं +जिधर +इंहें +अदि +इतयादि +हुइ +कोनसा +इसकि +दुसरे +जहां +अप +किंहों +उनकि +भि +वरग +हुअ +जेसा +नहिं diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_hu.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_hu.txt new file mode 100644 index 00000000000..1a96f1db6f2 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_hu.txt @@ -0,0 +1,209 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/hungarian/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + +| Hungarian stop word list +| prepared by Anna Tordai + +a +ahogy +ahol +aki +akik +akkor +alatt +által +általában +amely +amelyek +amelyekben +amelyeket +amelyet +amelynek +ami +amit +amolyan +amíg +amikor +át +abban +ahhoz +annak +arra +arról +az +azok +azon +azt +azzal +azért +aztán +azután +azonban +bár +be +belül +benne +cikk +cikkek +cikkeket +csak +de +e +eddig +egész +egy +egyes +egyetlen +egyéb +egyik +egyre +ekkor +el +elég +ellen +elő +először +előtt +első +én +éppen +ebben +ehhez +emilyen +ennek +erre +ez +ezt +ezek +ezen +ezzel +ezért +és +fel +felé +hanem +hiszen +hogy +hogyan +igen +így +illetve +ill. +ill +ilyen +ilyenkor +ison +ismét +itt +jó +jól +jobban +kell +kellett +keresztül +keressünk +ki +kívül +között +közül +legalább +lehet +lehetett +legyen +lenne +lenni +lesz +lett +maga +magát +majd +majd +már +más +másik +meg +még +mellett +mert +mely +melyek +mi +mit +míg +miért +milyen +mikor +minden +mindent +mindenki +mindig +mint +mintha +mivel +most +nagy +nagyobb +nagyon +ne +néha +nekem +neki +nem +néhány +nélkül +nincs +olyan +ott +össze +ő +ők +őket +pedig +persze +rá +s +saját +sem +semmi +sok +sokat +sokkal +számára +szemben +szerint +szinte +talán +tehát +teljes +tovább +továbbá +több +úgy +ugyanis +új +újabb +újra +után +utána +utolsó +vagy +vagyis +valaki +valami +valamint +való +vagyok +van +vannak +volt +voltam +voltak +voltunk +vissza +vele +viszont +volna diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_hy.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_hy.txt new file mode 100644 index 00000000000..60c1c50fbc8 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_hy.txt @@ -0,0 +1,46 @@ +# example set of Armenian stopwords. +այդ +այլ +այն +այս +դու +դուք +եմ +են +ենք +ես +եք +է +էի +էին +էինք +էիր +էիք +էր +ըստ +թ +ի +ին +իսկ +իր +կամ +համար +հետ +հետո +մենք +մեջ +մի +ն +նա +նաև +նրա +նրանք +որ +որը +որոնք +որպես +ու +ում +պիտի +վրա +և diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_id.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_id.txt new file mode 100644 index 00000000000..4617f83a5c5 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_id.txt @@ -0,0 +1,359 @@ +# from appendix D of: A Study of Stemming Effects on Information +# Retrieval in Bahasa Indonesia +ada +adanya +adalah +adapun +agak +agaknya +agar +akan +akankah +akhirnya +aku +akulah +amat +amatlah +anda +andalah +antar +diantaranya +antara +antaranya +diantara +apa +apaan +mengapa +apabila +apakah +apalagi +apatah +atau +ataukah +ataupun +bagai +bagaikan +sebagai +sebagainya +bagaimana +bagaimanapun +sebagaimana +bagaimanakah +bagi +bahkan +bahwa +bahwasanya +sebaliknya +banyak +sebanyak +beberapa +seberapa +begini +beginian +beginikah +beginilah +sebegini +begitu +begitukah +begitulah +begitupun +sebegitu +belum +belumlah +sebelum +sebelumnya +sebenarnya +berapa +berapakah +berapalah +berapapun +betulkah +sebetulnya +biasa +biasanya +bila +bilakah +bisa +bisakah +sebisanya +boleh +bolehkah +bolehlah +buat +bukan +bukankah +bukanlah +bukannya +cuma +percuma +dahulu +dalam +dan +dapat +dari +daripada +dekat +demi +demikian +demikianlah +sedemikian +dengan +depan +di +dia +dialah +dini +diri +dirinya +terdiri +dong +dulu +enggak +enggaknya +entah +entahlah +terhadap +terhadapnya +hal +hampir +hanya +hanyalah +harus +haruslah +harusnya +seharusnya +hendak +hendaklah +hendaknya +hingga +sehingga +ia +ialah +ibarat +ingin +inginkah +inginkan +ini +inikah +inilah +itu +itukah +itulah +jangan +jangankan +janganlah +jika +jikalau +juga +justru +kala +kalau +kalaulah +kalaupun +kalian +kami +kamilah +kamu +kamulah +kan +kapan +kapankah +kapanpun +dikarenakan +karena +karenanya +ke +kecil +kemudian +kenapa +kepada +kepadanya +ketika +seketika +khususnya +kini +kinilah +kiranya +sekiranya +kita +kitalah +kok +lagi +lagian +selagi +lah +lain +lainnya +melainkan +selaku +lalu +melalui +terlalu +lama +lamanya +selama +selama +selamanya +lebih +terlebih +bermacam +macam +semacam +maka +makanya +makin +malah +malahan +mampu +mampukah +mana +manakala +manalagi +masih +masihkah +semasih +masing +mau +maupun +semaunya +memang +mereka +merekalah +meski +meskipun +semula +mungkin +mungkinkah +nah +namun +nanti +nantinya +nyaris +oleh +olehnya +seorang +seseorang +pada +padanya +padahal +paling +sepanjang +pantas +sepantasnya +sepantasnyalah +para +pasti +pastilah +per +pernah +pula +pun +merupakan +rupanya +serupa +saat +saatnya +sesaat +saja +sajalah +saling +bersama +sama +sesama +sambil +sampai +sana +sangat +sangatlah +saya +sayalah +se +sebab +sebabnya +sebuah +tersebut +tersebutlah +sedang +sedangkan +sedikit +sedikitnya +segala +segalanya +segera +sesegera +sejak +sejenak +sekali +sekalian +sekalipun +sesekali +sekaligus +sekarang +sekarang +sekitar +sekitarnya +sela +selain +selalu +seluruh +seluruhnya +semakin +sementara +sempat +semua +semuanya +sendiri +sendirinya +seolah +seperti +sepertinya +sering +seringnya +serta +siapa +siapakah +siapapun +disini +disinilah +sini +sinilah +sesuatu +sesuatunya +suatu +sesudah +sesudahnya +sudah +sudahkah +sudahlah +supaya +tadi +tadinya +tak +tanpa +setelah +telah +tentang +tentu +tentulah +tentunya +tertentu +seterusnya +tapi +tetapi +setiap +tiap +setidaknya +tidak +tidakkah +tidaklah +toh +waduh +wah +wahai +sewaktu +walau +walaupun +wong +yaitu +yakni +yang diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_it.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_it.txt new file mode 100644 index 00000000000..4cb5b0891b1 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_it.txt @@ -0,0 +1,301 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/italian/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | An Italian stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + +ad | a (to) before vowel +al | a + il +allo | a + lo +ai | a + i +agli | a + gli +all | a + l' +agl | a + gl' +alla | a + la +alle | a + le +con | with +col | con + il +coi | con + i (forms collo, cogli etc are now very rare) +da | from +dal | da + il +dallo | da + lo +dai | da + i +dagli | da + gli +dall | da + l' +dagl | da + gll' +dalla | da + la +dalle | da + le +di | of +del | di + il +dello | di + lo +dei | di + i +degli | di + gli +dell | di + l' +degl | di + gl' +della | di + la +delle | di + le +in | in +nel | in + el +nello | in + lo +nei | in + i +negli | in + gli +nell | in + l' +negl | in + gl' +nella | in + la +nelle | in + le +su | on +sul | su + il +sullo | su + lo +sui | su + i +sugli | su + gli +sull | su + l' +sugl | su + gl' +sulla | su + la +sulle | su + le +per | through, by +tra | among +contro | against +io | I +tu | thou +lui | he +lei | she +noi | we +voi | you +loro | they +mio | my +mia | +miei | +mie | +tuo | +tua | +tuoi | thy +tue | +suo | +sua | +suoi | his, her +sue | +nostro | our +nostra | +nostri | +nostre | +vostro | your +vostra | +vostri | +vostre | +mi | me +ti | thee +ci | us, there +vi | you, there +lo | him, the +la | her, the +li | them +le | them, the +gli | to him, the +ne | from there etc +il | the +un | a +uno | a +una | a +ma | but +ed | and +se | if +perché | why, because +anche | also +come | how +dov | where (as dov') +dove | where +che | who, that +chi | who +cui | whom +non | not +più | more +quale | who, that +quanto | how much +quanti | +quanta | +quante | +quello | that +quelli | +quella | +quelle | +questo | this +questi | +questa | +queste | +si | yes +tutto | all +tutti | all + + | single letter forms: + +a | at +c | as c' for ce or ci +e | and +i | the +l | as l' +o | or + + | forms of avere, to have (not including the infinitive): + +ho +hai +ha +abbiamo +avete +hanno +abbia +abbiate +abbiano +avrò +avrai +avrà +avremo +avrete +avranno +avrei +avresti +avrebbe +avremmo +avreste +avrebbero +avevo +avevi +aveva +avevamo +avevate +avevano +ebbi +avesti +ebbe +avemmo +aveste +ebbero +avessi +avesse +avessimo +avessero +avendo +avuto +avuta +avuti +avute + + | forms of essere, to be (not including the infinitive): +sono +sei +è +siamo +siete +sia +siate +siano +sarò +sarai +sarà +saremo +sarete +saranno +sarei +saresti +sarebbe +saremmo +sareste +sarebbero +ero +eri +era +eravamo +eravate +erano +fui +fosti +fu +fummo +foste +furono +fossi +fosse +fossimo +fossero +essendo + + | forms of fare, to do (not including the infinitive, fa, fat-): +faccio +fai +facciamo +fanno +faccia +facciate +facciano +farò +farai +farà +faremo +farete +faranno +farei +faresti +farebbe +faremmo +fareste +farebbero +facevo +facevi +faceva +facevamo +facevate +facevano +feci +facesti +fece +facemmo +faceste +fecero +facessi +facesse +facessimo +facessero +facendo + + | forms of stare, to be (not including the infinitive): +sto +stai +sta +stiamo +stanno +stia +stiate +stiano +starò +starai +starà +staremo +starete +staranno +starei +staresti +starebbe +staremmo +stareste +starebbero +stavo +stavi +stava +stavamo +stavate +stavano +stetti +stesti +stette +stemmo +steste +stettero +stessi +stesse +stessimo +stessero +stando diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ja.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ja.txt new file mode 100644 index 00000000000..d4321be6b16 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ja.txt @@ -0,0 +1,127 @@ +# +# This file defines a stopword set for Japanese. +# +# This set is made up of hand-picked frequent terms from segmented Japanese Wikipedia. +# Punctuation characters and frequent kanji have mostly been left out. See LUCENE-3745 +# for frequency lists, etc. that can be useful for making your own set (if desired) +# +# Note that there is an overlap between these stopwords and the terms stopped when used +# in combination with the JapanesePartOfSpeechStopFilter. When editing this file, note +# that comments are not allowed on the same line as stopwords. +# +# Also note that stopping is done in a case-insensitive manner. Change your StopFilter +# configuration if you need case-sensitive stopping. Lastly, note that stopping is done +# using the same character width as the entries in this file. Since this StopFilter is +# normally done after a CJKWidthFilter in your chain, you would usually want your romaji +# entries to be in half-width and your kana entries to be in full-width. +# +の +に +は +を +た +が +で +て +と +し +れ +さ +ある +いる +も +する +から +な +こと +として +い +や +れる +など +なっ +ない +この +ため +その +あっ +よう +また +もの +という +あり +まで +られ +なる +へ +か +だ +これ +によって +により +おり +より +による +ず +なり +られる +において +ば +なかっ +なく +しかし +について +せ +だっ +その後 +できる +それ +う +ので +なお +のみ +でき +き +つ +における +および +いう +さらに +でも +ら +たり +その他 +に関する +たち +ます +ん +なら +に対して +特に +せる +及び +これら +とき +では +にて +ほか +ながら +うち +そして +とともに +ただし +かつて +それぞれ +または +お +ほど +ものの +に対する +ほとんど +と共に +といった +です +とも +ところ +ここ +##### End of file diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_lv.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_lv.txt new file mode 100644 index 00000000000..e21a23c06c3 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_lv.txt @@ -0,0 +1,172 @@ +# Set of Latvian stopwords from A Stemming Algorithm for Latvian, Karlis Kreslins +# the original list of over 800 forms was refined: +# pronouns, adverbs, interjections were removed +# +# prepositions +aiz +ap +ar +apakš +ārpus +augšpus +bez +caur +dēļ +gar +iekš +iz +kopš +labad +lejpus +līdz +no +otrpus +pa +par +pār +pēc +pie +pirms +pret +priekš +starp +šaipus +uz +viņpus +virs +virspus +zem +apakšpus +# Conjunctions +un +bet +jo +ja +ka +lai +tomēr +tikko +turpretī +arī +kaut +gan +tādēļ +tā +ne +tikvien +vien +kā +ir +te +vai +kamēr +# Particles +ar +diezin +droši +diemžēl +nebūt +ik +it +taču +nu +pat +tiklab +iekšpus +nedz +tik +nevis +turpretim +jeb +iekam +iekām +iekāms +kolīdz +līdzko +tiklīdz +jebšu +tālab +tāpēc +nekā +itin +jā +jau +jel +nē +nezin +tad +tikai +vis +tak +iekams +vien +# modal verbs +būt +biju +biji +bija +bijām +bijāt +esmu +esi +esam +esat +būšu +būsi +būs +būsim +būsiet +tikt +tiku +tiki +tika +tikām +tikāt +tieku +tiec +tiek +tiekam +tiekat +tikšu +tiks +tiksim +tiksiet +tapt +tapi +tapāt +topat +tapšu +tapsi +taps +tapsim +tapsiet +kļūt +kļuvu +kļuvi +kļuva +kļuvām +kļuvāt +kļūstu +kļūsti +kļūst +kļūstam +kļūstat +kļūšu +kļūsi +kļūs +kļūsim +kļūsiet +# verbs +varēt +varēju +varējām +varēšu +varēsim +var +varēji +varējāt +varēsi +varēsiet +varat +varēja +varēs diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_nl.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_nl.txt new file mode 100644 index 00000000000..f4d61f5092c --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_nl.txt @@ -0,0 +1,117 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/dutch/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Dutch stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | This is a ranked list (commonest to rarest) of stopwords derived from + | a large sample of Dutch text. + + | Dutch stop words frequently exhibit homonym clashes. These are indicated + | clearly below. + +de | the +en | and +van | of, from +ik | I, the ego +te | (1) chez, at etc, (2) to, (3) too +dat | that, which +die | that, those, who, which +in | in, inside +een | a, an, one +hij | he +het | the, it +niet | not, nothing, naught +zijn | (1) to be, being, (2) his, one's, its +is | is +was | (1) was, past tense of all persons sing. of 'zijn' (to be) (2) wax, (3) the washing, (4) rise of river +op | on, upon, at, in, up, used up +aan | on, upon, to (as dative) +met | with, by +als | like, such as, when +voor | (1) before, in front of, (2) furrow +had | had, past tense all persons sing. of 'hebben' (have) +er | there +maar | but, only +om | round, about, for etc +hem | him +dan | then +zou | should/would, past tense all persons sing. of 'zullen' +of | or, whether, if +wat | what, something, anything +mijn | possessive and noun 'mine' +men | people, 'one' +dit | this +zo | so, thus, in this way +door | through by +over | over, across +ze | she, her, they, them +zich | oneself +bij | (1) a bee, (2) by, near, at +ook | also, too +tot | till, until +je | you +mij | me +uit | out of, from +der | Old Dutch form of 'van der' still found in surnames +daar | (1) there, (2) because +haar | (1) her, their, them, (2) hair +naar | (1) unpleasant, unwell etc, (2) towards, (3) as +heb | present first person sing. of 'to have' +hoe | how, why +heeft | present third person sing. of 'to have' +hebben | 'to have' and various parts thereof +deze | this +u | you +want | (1) for, (2) mitten, (3) rigging +nog | yet, still +zal | 'shall', first and third person sing. of verb 'zullen' (will) +me | me +zij | she, they +nu | now +ge | 'thou', still used in Belgium and south Netherlands +geen | none +omdat | because +iets | something, somewhat +worden | to become, grow, get +toch | yet, still +al | all, every, each +waren | (1) 'were' (2) to wander, (3) wares, (3) +veel | much, many +meer | (1) more, (2) lake +doen | to do, to make +toen | then, when +moet | noun 'spot/mote' and present form of 'to must' +ben | (1) am, (2) 'are' in interrogative second person singular of 'to be' +zonder | without +kan | noun 'can' and present form of 'to be able' +hun | their, them +dus | so, consequently +alles | all, everything, anything +onder | under, beneath +ja | yes, of course +eens | once, one day +hier | here +wie | who +werd | imperfect third person sing. of 'become' +altijd | always +doch | yet, but etc +wordt | present third person sing. of 'become' +wezen | (1) to be, (2) 'been' as in 'been fishing', (3) orphans +kunnen | to be able +ons | us/our +zelf | self +tegen | against, towards, at +na | after, near +reeds | already +wil | (1) present tense of 'want', (2) 'will', noun, (3) fender +kon | could; past tense of 'to be able' +niets | nothing +uw | your +iemand | somebody +geweest | been; past participle of 'be' +andere | other diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_no.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_no.txt new file mode 100644 index 00000000000..e76f36e69ed --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_no.txt @@ -0,0 +1,192 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/norwegian/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Norwegian stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | This stop word list is for the dominant bokmål dialect. Words unique + | to nynorsk are marked *. + + | Revised by Jan Bruusgaard , Jan 2005 + +og | and +i | in +jeg | I +det | it/this/that +at | to (w. inf.) +en | a/an +et | a/an +den | it/this/that +til | to +er | is/am/are +som | who/that +på | on +de | they / you(formal) +med | with +han | he +av | of +ikke | not +ikkje | not * +der | there +så | so +var | was/were +meg | me +seg | you +men | but +ett | one +har | have +om | about +vi | we +min | my +mitt | my +ha | have +hadde | had +hun | she +nå | now +over | over +da | when/as +ved | by/know +fra | from +du | you +ut | out +sin | your +dem | them +oss | us +opp | up +man | you/one +kan | can +hans | his +hvor | where +eller | or +hva | what +skal | shall/must +selv | self (reflective) +sjøl | self (reflective) +her | here +alle | all +vil | will +bli | become +ble | became +blei | became * +blitt | have become +kunne | could +inn | in +når | when +være | be +kom | come +noen | some +noe | some +ville | would +dere | you +som | who/which/that +deres | their/theirs +kun | only/just +ja | yes +etter | after +ned | down +skulle | should +denne | this +for | for/because +deg | you +si | hers/his +sine | hers/his +sitt | hers/his +mot | against +å | to +meget | much +hvorfor | why +dette | this +disse | these/those +uten | without +hvordan | how +ingen | none +din | your +ditt | your +blir | become +samme | same +hvilken | which +hvilke | which (plural) +sånn | such a +inni | inside/within +mellom | between +vår | our +hver | each +hvem | who +vors | us/ours +hvis | whose +både | both +bare | only/just +enn | than +fordi | as/because +før | before +mange | many +også | also +slik | just +vært | been +være | to be +båe | both * +begge | both +siden | since +dykk | your * +dykkar | yours * +dei | they * +deira | them * +deires | theirs * +deim | them * +di | your (fem.) * +då | as/when * +eg | I * +ein | a/an * +eit | a/an * +eitt | a/an * +elles | or * +honom | he * +hjå | at * +ho | she * +hoe | she * +henne | her +hennar | her/hers +hennes | hers +hoss | how * +hossen | how * +ikkje | not * +ingi | noone * +inkje | noone * +korleis | how * +korso | how * +kva | what/which * +kvar | where * +kvarhelst | where * +kven | who/whom * +kvi | why * +kvifor | why * +me | we * +medan | while * +mi | my * +mine | my * +mykje | much * +no | now * +nokon | some (masc./neut.) * +noka | some (fem.) * +nokor | some * +noko | some * +nokre | some * +si | his/hers * +sia | since * +sidan | since * +so | so * +somt | some * +somme | some * +um | about* +upp | up * +vere | be * +vore | was * +verte | become * +vort | become * +varte | became * +vart | became * + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_pt.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_pt.txt new file mode 100644 index 00000000000..276c1b446f2 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_pt.txt @@ -0,0 +1,251 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/portuguese/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Portuguese stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + + | The following is a ranked list (commonest to rarest) of stopwords + | deriving from a large sample of text. + + | Extra words have been added at the end. + +de | of, from +a | the; to, at; her +o | the; him +que | who, that +e | and +do | de + o +da | de + a +em | in +um | a +para | for + | é from SER +com | with +não | not, no +uma | a +os | the; them +no | em + o +se | himself etc +na | em + a +por | for +mais | more +as | the; them +dos | de + os +como | as, like +mas | but + | foi from SER +ao | a + o +ele | he +das | de + as + | tem from TER +à | a + a +seu | his +sua | her +ou | or + | ser from SER +quando | when +muito | much + | há from HAV +nos | em + os; us +já | already, now + | está from EST +eu | I +também | also +só | only, just +pelo | per + o +pela | per + a +até | up to +isso | that +ela | he +entre | between + | era from SER +depois | after +sem | without +mesmo | same +aos | a + os + | ter from TER +seus | his +quem | whom +nas | em + as +me | me +esse | that +eles | they + | estão from EST +você | you + | tinha from TER + | foram from SER +essa | that +num | em + um +nem | nor +suas | her +meu | my +às | a + as +minha | my + | têm from TER +numa | em + uma +pelos | per + os +elas | they + | havia from HAV + | seja from SER +qual | which + | será from SER +nós | we + | tenho from TER +lhe | to him, her +deles | of them +essas | those +esses | those +pelas | per + as +este | this + | fosse from SER +dele | of him + + | other words. There are many contractions such as naquele = em+aquele, + | mo = me+o, but they are rare. + | Indefinite article plural forms are also rare. + +tu | thou +te | thee +vocês | you (plural) +vos | you +lhes | to them +meus | my +minhas +teu | thy +tua +teus +tuas +nosso | our +nossa +nossos +nossas + +dela | of her +delas | of them + +esta | this +estes | these +estas | these +aquele | that +aquela | that +aqueles | those +aquelas | those +isto | this +aquilo | that + + | forms of estar, to be (not including the infinitive): +estou +está +estamos +estão +estive +esteve +estivemos +estiveram +estava +estávamos +estavam +estivera +estivéramos +esteja +estejamos +estejam +estivesse +estivéssemos +estivessem +estiver +estivermos +estiverem + + | forms of haver, to have (not including the infinitive): +hei +há +havemos +hão +houve +houvemos +houveram +houvera +houvéramos +haja +hajamos +hajam +houvesse +houvéssemos +houvessem +houver +houvermos +houverem +houverei +houverá +houveremos +houverão +houveria +houveríamos +houveriam + + | forms of ser, to be (not including the infinitive): +sou +somos +são +era +éramos +eram +fui +foi +fomos +foram +fora +fôramos +seja +sejamos +sejam +fosse +fôssemos +fossem +for +formos +forem +serei +será +seremos +serão +seria +seríamos +seriam + + | forms of ter, to have (not including the infinitive): +tenho +tem +temos +tém +tinha +tínhamos +tinham +tive +teve +tivemos +tiveram +tivera +tivéramos +tenha +tenhamos +tenham +tivesse +tivéssemos +tivessem +tiver +tivermos +tiverem +terei +terá +teremos +terão +teria +teríamos +teriam diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ro.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ro.txt new file mode 100644 index 00000000000..4fdee90a5ba --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ro.txt @@ -0,0 +1,233 @@ +# This file was created by Jacques Savoy and is distributed under the BSD license. +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# Also see http://www.opensource.org/licenses/bsd-license.html +acea +aceasta +această +aceea +acei +aceia +acel +acela +acele +acelea +acest +acesta +aceste +acestea +aceşti +aceştia +acolo +acum +ai +aia +aibă +aici +al +ăla +ale +alea +ălea +altceva +altcineva +am +ar +are +aş +aşadar +asemenea +asta +ăsta +astăzi +astea +ăstea +ăştia +asupra +aţi +au +avea +avem +aveţi +azi +bine +bucur +bună +ca +că +căci +când +care +cărei +căror +cărui +cât +câte +câţi +către +câtva +ce +cel +ceva +chiar +cînd +cine +cineva +cît +cîte +cîţi +cîtva +contra +cu +cum +cumva +curând +curînd +da +dă +dacă +dar +datorită +de +deci +deja +deoarece +departe +deşi +din +dinaintea +dintr +dintre +drept +după +ea +ei +el +ele +eram +este +eşti +eu +face +fără +fi +fie +fiecare +fii +fim +fiţi +iar +ieri +îi +îl +îmi +împotriva +în +înainte +înaintea +încât +încît +încotro +între +întrucât +întrucît +îţi +la +lângă +le +li +lîngă +lor +lui +mă +mâine +mea +mei +mele +mereu +meu +mi +mine +mult +multă +mulţi +ne +nicăieri +nici +nimeni +nişte +noastră +noastre +noi +noştri +nostru +nu +ori +oricând +oricare +oricât +orice +oricînd +oricine +oricît +oricum +oriunde +până +pe +pentru +peste +pînă +poate +pot +prea +prima +primul +prin +printr +sa +să +săi +sale +sau +său +se +şi +sînt +sîntem +sînteţi +spre +sub +sunt +suntem +sunteţi +ta +tăi +tale +tău +te +ţi +ţie +tine +toată +toate +tot +toţi +totuşi +tu +un +una +unde +undeva +unei +unele +uneori +unor +vă +vi +voastră +voastre +voi +voştri +vostru +vouă +vreo +vreun diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ru.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ru.txt new file mode 100644 index 00000000000..64307693457 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ru.txt @@ -0,0 +1,241 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/russian/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | a russian stop word list. comments begin with vertical bar. each stop + | word is at the start of a line. + + | this is a ranked list (commonest to rarest) of stopwords derived from + | a large text sample. + + | letter `ё' is translated to `е'. + +и | and +в | in/into +во | alternative form +не | not +что | what/that +он | he +на | on/onto +я | i +с | from +со | alternative form +как | how +а | milder form of `no' (but) +то | conjunction and form of `that' +все | all +она | she +так | so, thus +его | him +но | but +да | yes/and +ты | thou +к | towards, by +у | around, chez +же | intensifier particle +вы | you +за | beyond, behind +бы | conditional/subj. particle +по | up to, along +только | only +ее | her +мне | to me +было | it was +вот | here is/are, particle +от | away from +меня | me +еще | still, yet, more +нет | no, there isnt/arent +о | about +из | out of +ему | to him +теперь | now +когда | when +даже | even +ну | so, well +вдруг | suddenly +ли | interrogative particle +если | if +уже | already, but homonym of `narrower' +или | or +ни | neither +быть | to be +был | he was +него | prepositional form of его +до | up to +вас | you accusative +нибудь | indef. suffix preceded by hyphen +опять | again +уж | already, but homonym of `adder' +вам | to you +сказал | he said +ведь | particle `after all' +там | there +потом | then +себя | oneself +ничего | nothing +ей | to her +может | usually with `быть' as `maybe' +они | they +тут | here +где | where +есть | there is/are +надо | got to, must +ней | prepositional form of ей +для | for +мы | we +тебя | thee +их | them, their +чем | than +была | she was +сам | self +чтоб | in order to +без | without +будто | as if +человек | man, person, one +чего | genitive form of `what' +раз | once +тоже | also +себе | to oneself +под | beneath +жизнь | life +будет | will be +ж | short form of intensifer particle `же' +тогда | then +кто | who +этот | this +говорил | was saying +того | genitive form of `that' +потому | for that reason +этого | genitive form of `this' +какой | which +совсем | altogether +ним | prepositional form of `его', `они' +здесь | here +этом | prepositional form of `этот' +один | one +почти | almost +мой | my +тем | instrumental/dative plural of `тот', `то' +чтобы | full form of `in order that' +нее | her (acc.) +кажется | it seems +сейчас | now +были | they were +куда | where to +зачем | why +сказать | to say +всех | all (acc., gen. preposn. plural) +никогда | never +сегодня | today +можно | possible, one can +при | by +наконец | finally +два | two +об | alternative form of `о', about +другой | another +хоть | even +после | after +над | above +больше | more +тот | that one (masc.) +через | across, in +эти | these +нас | us +про | about +всего | in all, only, of all +них | prepositional form of `они' (they) +какая | which, feminine +много | lots +разве | interrogative particle +сказала | she said +три | three +эту | this, acc. fem. sing. +моя | my, feminine +впрочем | moreover, besides +хорошо | good +свою | ones own, acc. fem. sing. +этой | oblique form of `эта', fem. `this' +перед | in front of +иногда | sometimes +лучше | better +чуть | a little +том | preposn. form of `that one' +нельзя | one must not +такой | such a one +им | to them +более | more +всегда | always +конечно | of course +всю | acc. fem. sing of `all' +между | between + + + | b: some paradigms + | + | personal pronouns + | + | я меня мне мной [мною] + | ты тебя тебе тобой [тобою] + | он его ему им [него, нему, ним] + | она ее эи ею [нее, нэи, нею] + | оно его ему им [него, нему, ним] + | + | мы нас нам нами + | вы вас вам вами + | они их им ими [них, ним, ними] + | + | себя себе собой [собою] + | + | demonstrative pronouns: этот (this), тот (that) + | + | этот эта это эти + | этого эты это эти + | этого этой этого этих + | этому этой этому этим + | этим этой этим [этою] этими + | этом этой этом этих + | + | тот та то те + | того ту то те + | того той того тех + | тому той тому тем + | тем той тем [тою] теми + | том той том тех + | + | determinative pronouns + | + | (a) весь (all) + | + | весь вся все все + | всего всю все все + | всего всей всего всех + | всему всей всему всем + | всем всей всем [всею] всеми + | всем всей всем всех + | + | (b) сам (himself etc) + | + | сам сама само сами + | самого саму само самих + | самого самой самого самих + | самому самой самому самим + | самим самой самим [самою] самими + | самом самой самом самих + | + | stems of verbs `to be', `to have', `to do' and modal + | + | быть бы буд быв есть суть + | име + | дел + | мог мож мочь + | уме + | хоч хот + | долж + | можн + | нужн + | нельзя + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_sv.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_sv.txt new file mode 100644 index 00000000000..22bddfd8cb3 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_sv.txt @@ -0,0 +1,131 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/swedish/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Swedish stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | This is a ranked list (commonest to rarest) of stopwords derived from + | a large text sample. + + | Swedish stop words occasionally exhibit homonym clashes. For example + | så = so, but also seed. These are indicated clearly below. + +och | and +det | it, this/that +att | to (with infinitive) +i | in, at +en | a +jag | I +hon | she +som | who, that +han | he +på | on +den | it, this/that +med | with +var | where, each +sig | him(self) etc +för | for +så | so (also: seed) +till | to +är | is +men | but +ett | a +om | if; around, about +hade | had +de | they, these/those +av | of +icke | not, no +mig | me +du | you +henne | her +då | then, when +sin | his +nu | now +har | have +inte | inte någon = no one +hans | his +honom | him +skulle | 'sake' +hennes | her +där | there +min | my +man | one (pronoun) +ej | nor +vid | at, by, on (also: vast) +kunde | could +något | some etc +från | from, off +ut | out +när | when +efter | after, behind +upp | up +vi | we +dem | them +vara | be +vad | what +över | over +än | than +dig | you +kan | can +sina | his +här | here +ha | have +mot | towards +alla | all +under | under (also: wonder) +någon | some etc +eller | or (else) +allt | all +mycket | much +sedan | since +ju | why +denna | this/that +själv | myself, yourself etc +detta | this/that +åt | to +utan | without +varit | was +hur | how +ingen | no +mitt | my +ni | you +bli | to be, become +blev | from bli +oss | us +din | thy +dessa | these/those +några | some etc +deras | their +blir | from bli +mina | my +samma | (the) same +vilken | who, that +er | you, your +sådan | such a +vår | our +blivit | from bli +dess | its +inom | within +mellan | between +sådant | such a +varför | why +varje | each +vilka | who, that +ditt | thy +vem | who +vilket | who, that +sitta | his +sådana | such a +vart | each +dina | thy +vars | whose +vårt | our +våra | our +ert | your +era | your +vilkas | whose + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_th.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_th.txt new file mode 100644 index 00000000000..07f0fabe692 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_th.txt @@ -0,0 +1,119 @@ +# Thai stopwords from: +# "Opinion Detection in Thai Political News Columns +# Based on Subjectivity Analysis" +# Khampol Sukhum, Supot Nitsuwat, and Choochart Haruechaiyasak +ไว้ +ไม่ +ไป +ได้ +ให้ +ใน +โดย +แห่ง +แล้ว +และ +แรก +แบบ +แต่ +เอง +เห็น +เลย +เริ่ม +เรา +เมื่อ +เพื่อ +เพราะ +เป็นการ +เป็น +เปิดเผย +เปิด +เนื่องจาก +เดียวกัน +เดียว +เช่น +เฉพาะ +เคย +เข้า +เขา +อีก +อาจ +อะไร +ออก +อย่าง +อยู่ +อยาก +หาก +หลาย +หลังจาก +หลัง +หรือ +หนึ่ง +ส่วน +ส่ง +สุด +สําหรับ +ว่า +วัน +ลง +ร่วม +ราย +รับ +ระหว่าง +รวม +ยัง +มี +มาก +มา +พร้อม +พบ +ผ่าน +ผล +บาง +น่า +นี้ +นํา +นั้น +นัก +นอกจาก +ทุก +ที่สุด +ที่ +ทําให้ +ทํา +ทาง +ทั้งนี้ +ทั้ง +ถ้า +ถูก +ถึง +ต้อง +ต่างๆ +ต่าง +ต่อ +ตาม +ตั้งแต่ +ตั้ง +ด้าน +ด้วย +ดัง +ซึ่ง +ช่วง +จึง +จาก +จัด +จะ +คือ +ความ +ครั้ง +คง +ขึ้น +ของ +ขอ +ขณะ +ก่อน +ก็ +การ +กับ +กัน +กว่า +กล่าว diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_tr.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_tr.txt new file mode 100644 index 00000000000..84d9408d4ea --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_tr.txt @@ -0,0 +1,212 @@ +# Turkish stopwords from LUCENE-559 +# merged with the list from "Information Retrieval on Turkish Texts" +# (http://www.users.muohio.edu/canf/papers/JASIST2008offPrint.pdf) +acaba +altmış +altı +ama +ancak +arada +aslında +ayrıca +bana +bazı +belki +ben +benden +beni +benim +beri +beş +bile +bin +bir +birçok +biri +birkaç +birkez +birşey +birşeyi +biz +bize +bizden +bizi +bizim +böyle +böylece +bu +buna +bunda +bundan +bunlar +bunları +bunların +bunu +bunun +burada +çok +çünkü +da +daha +dahi +de +defa +değil +diğer +diye +doksan +dokuz +dolayı +dolayısıyla +dört +edecek +eden +ederek +edilecek +ediliyor +edilmesi +ediyor +eğer +elli +en +etmesi +etti +ettiği +ettiğini +gibi +göre +halen +hangi +hatta +hem +henüz +hep +hepsi +her +herhangi +herkesin +hiç +hiçbir +için +iki +ile +ilgili +ise +işte +itibaren +itibariyle +kadar +karşın +katrilyon +kendi +kendilerine +kendini +kendisi +kendisine +kendisini +kez +ki +kim +kimden +kime +kimi +kimse +kırk +milyar +milyon +mu +mü +mı +nasıl +ne +neden +nedenle +nerde +nerede +nereye +niye +niçin +o +olan +olarak +oldu +olduğu +olduğunu +olduklarını +olmadı +olmadığı +olmak +olması +olmayan +olmaz +olsa +olsun +olup +olur +olursa +oluyor +on +ona +ondan +onlar +onlardan +onları +onların +onu +onun +otuz +oysa +öyle +pek +rağmen +sadece +sanki +sekiz +seksen +sen +senden +seni +senin +siz +sizden +sizi +sizin +şey +şeyden +şeyi +şeyler +şöyle +şu +şuna +şunda +şundan +şunları +şunu +tarafından +trilyon +tüm +üç +üzere +var +vardı +ve +veya +ya +yani +yapacak +yapılan +yapılması +yapıyor +yapmak +yaptı +yaptığı +yaptığını +yaptıkları +yedi +yerine +yetmiş +yine +yirmi +yoksa +yüz +zaten diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/userdict_ja.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/userdict_ja.txt new file mode 100644 index 00000000000..6f0368e4d81 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/userdict_ja.txt @@ -0,0 +1,29 @@ +# +# This is a sample user dictionary for Kuromoji (JapaneseTokenizer) +# +# Add entries to this file in order to override the statistical model in terms +# of segmentation, readings and part-of-speech tags. Notice that entries do +# not have weights since they are always used when found. This is by-design +# in order to maximize ease-of-use. +# +# Entries are defined using the following CSV format: +# , ... , ... , +# +# Notice that a single half-width space separates tokens and readings, and +# that the number tokens and readings must match exactly. +# +# Also notice that multiple entries with the same is undefined. +# +# Whitespace only lines are ignored. Comments are not allowed on entry lines. +# + +# Custom segmentation for kanji compounds +日本経済新聞,日本 経済 新聞,ニホン ケイザイ シンブン,カスタム名詞 +関西国際空港,関西 国際 空港,カンサイ コクサイ クウコウ,カスタム名詞 + +# Custom segmentation for compound katakana +トートバッグ,トート バッグ,トート バッグ,かずカナ名詞 +ショルダーバッグ,ショルダー バッグ,ショルダー バッグ,かずカナ名詞 + +# Custom reading for former sumo wrestler +朝青龍,朝青龍,アサショウリュウ,カスタム人名 diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/protwords.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/protwords.txt new file mode 100644 index 00000000000..1dfc0abecbf --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/protwords.txt @@ -0,0 +1,21 @@ +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#----------------------------------------------------------------------- +# Use a protected word file to protect against the stemmer reducing two +# unrelated words to the same base word. + +# Some non-words that normally won't be encountered, +# just to test that they won't be stemmed. +dontstems +zwhacky + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/schema.xml b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/schema.xml new file mode 100644 index 00000000000..b133c135f31 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/schema.xml @@ -0,0 +1,961 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/solrconfig.xml b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/solrconfig.xml new file mode 100644 index 00000000000..f9683b27db7 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/solrconfig.xml @@ -0,0 +1,1789 @@ + + + + + + + + + LUCENE_43 + + + + + + + + + + + + + + + + + + + + + + + + ${solr.data.dir:} + + + + + ${solr.hdfs.home:} + ${solr.hdfs.confdir:} + ${solr.hdfs.security.kerberos.enabled:false} + ${solr.hdfs.security.kerberos.keytabfile:} + ${solr.hdfs.security.kerberos.principal:} + ${solr.hdfs.blockcache.enabled:true} + ${solr.hdfs.blockcache.slab.count:1} + ${solr.hdfs.blockcache.direct.memory.allocation:true} + ${solr.hdfs.blockcache.blocksperbank:16384} + ${solr.hdfs.blockcache.read.enabled:true} + ${solr.hdfs.blockcache.write.enabled:true} + ${solr.hdfs.nrtcachingdirectory.enable:true} + ${solr.hdfs.nrtcachingdirectory.maxmergesizemb:16} + ${solr.hdfs.nrtcachingdirectory.maxcachedmb:192} + + + + + + + + + + + + + ${solr.maxIndexingThreads:8} + + + + + + 128 + + + + + + + + + + + + + ${solr.lock.type:hdfs} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${solr.autoCommit.maxTime:60000} + false + + + + + ${solr.autoSoftCommit.maxTime:1000} + + + + + + + + + + + + + + + + + + + 1024 + + + + + + + + + + + + + + + + + + + + + + true + + + + + + 20 + + + 200 + + + + + + + + + + + + static firstSearcher warming in solrconfig.xml + + + + + + false + + + 4 + + + + + + + + + + + + + + + + + + + + + + + explicit + 10 + text + + + + + + + + + + + + + + explicit + json + true + text + + + + + + + + true + json + true + + + + + + + + explicit + + + velocity + browse + layout + Solritas + + + edismax + + text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 + title^10.0 description^5.0 keywords^5.0 author^2.0 resourcename^1.0 + + text + 100% + *:* + 10 + *,score + + + text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 + title^10.0 description^5.0 keywords^5.0 author^2.0 resourcename^1.0 + + text,features,name,sku,id,manu,cat,title,description,keywords,author,resourcename + 3 + + + on + cat + manu_exact + content_type + author_s + ipod + GB + 1 + cat,inStock + after + price + 0 + 600 + 50 + popularity + 0 + 10 + 3 + manufacturedate_dt + NOW/YEAR-10YEARS + NOW + +1YEAR + before + after + + + on + content features title name + html + <b> + </b> + 0 + title + 0 + name + 3 + 200 + content + 750 + + + on + false + 5 + 2 + 5 + true + true + 5 + 3 + + + + + spellcheck + + + + + + + + + + + + + + application/json + + + + + application/csv + + + + + + + + + + + + + + + + + + + + + solrpingquery + + + all + + + + + + + + + explicit + true + + + + + + + + + + + + + + + + text_general + + + + + + default + text + solr.DirectSolrSpellChecker + + internal + + 0.5 + + 2 + + 1 + + 5 + + 4 + + 0.01 + + + + + + wordbreak + solr.WordBreakSolrSpellChecker + name + true + true + 10 + + + + + + + + + + + + + + + + text + + default + wordbreak + on + true + 10 + 5 + 5 + true + true + 10 + 5 + + + spellcheck + + + + + + + + + + text + true + + + tvComponent + + + + + + + + + default + + + org.carrot2.clustering.lingo.LingoClusteringAlgorithm + + + 20 + + + clustering/carrot2 + + + ENGLISH + + + stc + org.carrot2.clustering.stc.STCClusteringAlgorithm + + + + + + + true + default + true + + name + id + + features + + true + + + + false + + edismax + + text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 + + *:* + 10 + *,score + + + clustering + + + + + + + + + + true + false + + + terms + + + + + + + + string + elevate.xml + + + + + + explicit + text + + + elevator + + + + + + + + + + + 100 + + + + + + + + 70 + + 0.5 + + [-\w ,/\n\"']{20,200} + + + + + + + ]]> + ]]> + + + + + + + + + + + + + + + + + + + + + + + + ,, + ,, + ,, + ,, + ,]]> + ]]> + + + + + + 10 + .,!? + + + + + + + WORD + + + en + US + + + + + + + + + + + + + + + + + + + + + + text/plain; charset=UTF-8 + + + + + + + + + 5 + + + + + + + + + + + + + + + + + + *:* + + + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/stopwords.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/stopwords.txt new file mode 100644 index 00000000000..ae1e83eeb3d --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/stopwords.txt @@ -0,0 +1,14 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/synonyms.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/synonyms.txt new file mode 100644 index 00000000000..7f72128303b --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/synonyms.txt @@ -0,0 +1,29 @@ +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#----------------------------------------------------------------------- +#some test synonym mappings unlikely to appear in real input text +aaafoo => aaabar +bbbfoo => bbbfoo bbbbar +cccfoo => cccbar cccbaz +fooaaa,baraaa,bazaaa + +# Some synonym groups specific to this example +GB,gib,gigabyte,gigabytes +MB,mib,megabyte,megabytes +Television, Televisions, TV, TVs +#notice we use "gib" instead of "GiB" so any WordDelimiterFilter coming +#after us won't split it into two words. + +# Synonym mappings can be used for spelling correction too +pixima => pixma + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/solr.xml b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/solr.xml new file mode 100644 index 00000000000..6c8b43f75ed --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/solr.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + ${socketTimeout:120000} + ${connTimeout:15000} + + + + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solr.xml b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solr.xml new file mode 100644 index 00000000000..4604f60476f --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solr.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + ${socketTimeout:120000} + ${connTimeout:15000} + + + + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/currency.xml b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/currency.xml new file mode 100644 index 00000000000..3a9c58afee8 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/currency.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/elevate.xml b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/elevate.xml new file mode 100644 index 00000000000..25d5cebe4fb --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/elevate.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_ca.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_ca.txt new file mode 100644 index 00000000000..307a85f913d --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_ca.txt @@ -0,0 +1,8 @@ +# Set of Catalan contractions for ElisionFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +d +l +m +n +s +t diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_fr.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_fr.txt new file mode 100644 index 00000000000..722db588333 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_fr.txt @@ -0,0 +1,9 @@ +# Set of French contractions for ElisionFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +l +m +t +qu +n +s +j diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_ga.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_ga.txt new file mode 100644 index 00000000000..9ebe7fa349a --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_ga.txt @@ -0,0 +1,5 @@ +# Set of Irish contractions for ElisionFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +d +m +b diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_it.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_it.txt new file mode 100644 index 00000000000..cac04095372 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_it.txt @@ -0,0 +1,23 @@ +# Set of Italian contractions for ElisionFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +c +l +all +dall +dell +nell +sull +coll +pell +gl +agl +dagl +degl +negl +sugl +un +m +t +s +v +d diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/hyphenations_ga.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/hyphenations_ga.txt new file mode 100644 index 00000000000..4d2642cc5a3 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/hyphenations_ga.txt @@ -0,0 +1,5 @@ +# Set of Irish hyphenations for StopFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +h +n +t diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stemdict_nl.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stemdict_nl.txt new file mode 100644 index 00000000000..441072971d3 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stemdict_nl.txt @@ -0,0 +1,6 @@ +# Set of overrides for the dutch stemmer +# TODO: load this as a resource from the analyzer and sync it in build.xml +fiets fiets +bromfiets bromfiets +ei eier +kind kinder diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stoptags_ja.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stoptags_ja.txt new file mode 100644 index 00000000000..71b750845e3 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stoptags_ja.txt @@ -0,0 +1,420 @@ +# +# This file defines a Japanese stoptag set for JapanesePartOfSpeechStopFilter. +# +# Any token with a part-of-speech tag that exactly matches those defined in this +# file are removed from the token stream. +# +# Set your own stoptags by uncommenting the lines below. Note that comments are +# not allowed on the same line as a stoptag. See LUCENE-3745 for frequency lists, +# etc. that can be useful for building you own stoptag set. +# +# The entire possible tagset is provided below for convenience. +# +##### +# noun: unclassified nouns +#名詞 +# +# noun-common: Common nouns or nouns where the sub-classification is undefined +#名詞-一般 +# +# noun-proper: Proper nouns where the sub-classification is undefined +#名詞-固有名詞 +# +# noun-proper-misc: miscellaneous proper nouns +#名詞-固有名詞-一般 +# +# noun-proper-person: Personal names where the sub-classification is undefined +#名詞-固有名詞-人名 +# +# noun-proper-person-misc: names that cannot be divided into surname and +# given name; foreign names; names where the surname or given name is unknown. +# e.g. お市の方 +#名詞-固有名詞-人名-一般 +# +# noun-proper-person-surname: Mainly Japanese surnames. +# e.g. 山田 +#名詞-固有名詞-人名-姓 +# +# noun-proper-person-given_name: Mainly Japanese given names. +# e.g. 太郎 +#名詞-固有名詞-人名-名 +# +# noun-proper-organization: Names representing organizations. +# e.g. 通産省, NHK +#名詞-固有名詞-組織 +# +# noun-proper-place: Place names where the sub-classification is undefined +#名詞-固有名詞-地域 +# +# noun-proper-place-misc: Place names excluding countries. +# e.g. アジア, バルセロナ, 京都 +#名詞-固有名詞-地域-一般 +# +# noun-proper-place-country: Country names. +# e.g. 日本, オーストラリア +#名詞-固有名詞-地域-国 +# +# noun-pronoun: Pronouns where the sub-classification is undefined +#名詞-代名詞 +# +# noun-pronoun-misc: miscellaneous pronouns: +# e.g. それ, ここ, あいつ, あなた, あちこち, いくつ, どこか, なに, みなさん, みんな, わたくし, われわれ +#名詞-代名詞-一般 +# +# noun-pronoun-contraction: Spoken language contraction made by combining a +# pronoun and the particle 'wa'. +# e.g. ありゃ, こりゃ, こりゃあ, そりゃ, そりゃあ +#名詞-代名詞-縮約 +# +# noun-adverbial: Temporal nouns such as names of days or months that behave +# like adverbs. Nouns that represent amount or ratios and can be used adverbially, +# e.g. 金曜, 一月, 午後, 少量 +#名詞-副詞可能 +# +# noun-verbal: Nouns that take arguments with case and can appear followed by +# 'suru' and related verbs (する, できる, なさる, くださる) +# e.g. インプット, 愛着, 悪化, 悪戦苦闘, 一安心, 下取り +#名詞-サ変接続 +# +# noun-adjective-base: The base form of adjectives, words that appear before な ("na") +# e.g. 健康, 安易, 駄目, だめ +#名詞-形容動詞語幹 +# +# noun-numeric: Arabic numbers, Chinese numerals, and counters like 何 (回), 数. +# e.g. 0, 1, 2, 何, 数, 幾 +#名詞-数 +# +# noun-affix: noun affixes where the sub-classification is undefined +#名詞-非自立 +# +# noun-affix-misc: Of adnominalizers, the case-marker の ("no"), and words that +# attach to the base form of inflectional words, words that cannot be classified +# into any of the other categories below. This category includes indefinite nouns. +# e.g. あかつき, 暁, かい, 甲斐, 気, きらい, 嫌い, くせ, 癖, こと, 事, ごと, 毎, しだい, 次第, +# 順, せい, 所為, ついで, 序で, つもり, 積もり, 点, どころ, の, はず, 筈, はずみ, 弾み, +# 拍子, ふう, ふり, 振り, ほう, 方, 旨, もの, 物, 者, ゆえ, 故, ゆえん, 所以, わけ, 訳, +# わり, 割り, 割, ん-口語/, もん-口語/ +#名詞-非自立-一般 +# +# noun-affix-adverbial: noun affixes that that can behave as adverbs. +# e.g. あいだ, 間, あげく, 挙げ句, あと, 後, 余り, 以外, 以降, 以後, 以上, 以前, 一方, うえ, +# 上, うち, 内, おり, 折り, かぎり, 限り, きり, っきり, 結果, ころ, 頃, さい, 際, 最中, さなか, +# 最中, じたい, 自体, たび, 度, ため, 為, つど, 都度, とおり, 通り, とき, 時, ところ, 所, +# とたん, 途端, なか, 中, のち, 後, ばあい, 場合, 日, ぶん, 分, ほか, 他, まえ, 前, まま, +# 儘, 侭, みぎり, 矢先 +#名詞-非自立-副詞可能 +# +# noun-affix-aux: noun affixes treated as 助動詞 ("auxiliary verb") in school grammars +# with the stem よう(だ) ("you(da)"). +# e.g. よう, やう, 様 (よう) +#名詞-非自立-助動詞語幹 +# +# noun-affix-adjective-base: noun affixes that can connect to the indeclinable +# connection form な (aux "da"). +# e.g. みたい, ふう +#名詞-非自立-形容動詞語幹 +# +# noun-special: special nouns where the sub-classification is undefined. +#名詞-特殊 +# +# noun-special-aux: The そうだ ("souda") stem form that is used for reporting news, is +# treated as 助動詞 ("auxiliary verb") in school grammars, and attach to the base +# form of inflectional words. +# e.g. そう +#名詞-特殊-助動詞語幹 +# +# noun-suffix: noun suffixes where the sub-classification is undefined. +#名詞-接尾 +# +# noun-suffix-misc: Of the nouns or stem forms of other parts of speech that connect +# to ガル or タイ and can combine into compound nouns, words that cannot be classified into +# any of the other categories below. In general, this category is more inclusive than +# 接尾語 ("suffix") and is usually the last element in a compound noun. +# e.g. おき, かた, 方, 甲斐 (がい), がかり, ぎみ, 気味, ぐるみ, (~した) さ, 次第, 済 (ず) み, +# よう, (でき)っこ, 感, 観, 性, 学, 類, 面, 用 +#名詞-接尾-一般 +# +# noun-suffix-person: Suffixes that form nouns and attach to person names more often +# than other nouns. +# e.g. 君, 様, 著 +#名詞-接尾-人名 +# +# noun-suffix-place: Suffixes that form nouns and attach to place names more often +# than other nouns. +# e.g. 町, 市, 県 +#名詞-接尾-地域 +# +# noun-suffix-verbal: Of the suffixes that attach to nouns and form nouns, those that +# can appear before スル ("suru"). +# e.g. 化, 視, 分け, 入り, 落ち, 買い +#名詞-接尾-サ変接続 +# +# noun-suffix-aux: The stem form of そうだ (様態) that is used to indicate conditions, +# is treated as 助動詞 ("auxiliary verb") in school grammars, and attach to the +# conjunctive form of inflectional words. +# e.g. そう +#名詞-接尾-助動詞語幹 +# +# noun-suffix-adjective-base: Suffixes that attach to other nouns or the conjunctive +# form of inflectional words and appear before the copula だ ("da"). +# e.g. 的, げ, がち +#名詞-接尾-形容動詞語幹 +# +# noun-suffix-adverbial: Suffixes that attach to other nouns and can behave as adverbs. +# e.g. 後 (ご), 以後, 以降, 以前, 前後, 中, 末, 上, 時 (じ) +#名詞-接尾-副詞可能 +# +# noun-suffix-classifier: Suffixes that attach to numbers and form nouns. This category +# is more inclusive than 助数詞 ("classifier") and includes common nouns that attach +# to numbers. +# e.g. 個, つ, 本, 冊, パーセント, cm, kg, カ月, か国, 区画, 時間, 時半 +#名詞-接尾-助数詞 +# +# noun-suffix-special: Special suffixes that mainly attach to inflecting words. +# e.g. (楽し) さ, (考え) 方 +#名詞-接尾-特殊 +# +# noun-suffix-conjunctive: Nouns that behave like conjunctions and join two words +# together. +# e.g. (日本) 対 (アメリカ), 対 (アメリカ), (3) 対 (5), (女優) 兼 (主婦) +#名詞-接続詞的 +# +# noun-verbal_aux: Nouns that attach to the conjunctive particle て ("te") and are +# semantically verb-like. +# e.g. ごらん, ご覧, 御覧, 頂戴 +#名詞-動詞非自立的 +# +# noun-quotation: text that cannot be segmented into words, proverbs, Chinese poetry, +# dialects, English, etc. Currently, the only entry for 名詞 引用文字列 ("noun quotation") +# is いわく ("iwaku"). +#名詞-引用文字列 +# +# noun-nai_adjective: Words that appear before the auxiliary verb ない ("nai") and +# behave like an adjective. +# e.g. 申し訳, 仕方, とんでも, 違い +#名詞-ナイ形容詞語幹 +# +##### +# prefix: unclassified prefixes +#接頭詞 +# +# prefix-nominal: Prefixes that attach to nouns (including adjective stem forms) +# excluding numerical expressions. +# e.g. お (水), 某 (氏), 同 (社), 故 (~氏), 高 (品質), お (見事), ご (立派) +#接頭詞-名詞接続 +# +# prefix-verbal: Prefixes that attach to the imperative form of a verb or a verb +# in conjunctive form followed by なる/なさる/くださる. +# e.g. お (読みなさい), お (座り) +#接頭詞-動詞接続 +# +# prefix-adjectival: Prefixes that attach to adjectives. +# e.g. お (寒いですねえ), バカ (でかい) +#接頭詞-形容詞接続 +# +# prefix-numerical: Prefixes that attach to numerical expressions. +# e.g. 約, およそ, 毎時 +#接頭詞-数接続 +# +##### +# verb: unclassified verbs +#動詞 +# +# verb-main: +#動詞-自立 +# +# verb-auxiliary: +#動詞-非自立 +# +# verb-suffix: +#動詞-接尾 +# +##### +# adjective: unclassified adjectives +#形容詞 +# +# adjective-main: +#形容詞-自立 +# +# adjective-auxiliary: +#形容詞-非自立 +# +# adjective-suffix: +#形容詞-接尾 +# +##### +# adverb: unclassified adverbs +#副詞 +# +# adverb-misc: Words that can be segmented into one unit and where adnominal +# modification is not possible. +# e.g. あいかわらず, 多分 +#副詞-一般 +# +# adverb-particle_conjunction: Adverbs that can be followed by の, は, に, +# な, する, だ, etc. +# e.g. こんなに, そんなに, あんなに, なにか, なんでも +#副詞-助詞類接続 +# +##### +# adnominal: Words that only have noun-modifying forms. +# e.g. この, その, あの, どの, いわゆる, なんらかの, 何らかの, いろんな, こういう, そういう, ああいう, +# どういう, こんな, そんな, あんな, どんな, 大きな, 小さな, おかしな, ほんの, たいした, +# 「(, も) さる (ことながら)」, 微々たる, 堂々たる, 単なる, いかなる, 我が」「同じ, 亡き +#連体詞 +# +##### +# conjunction: Conjunctions that can occur independently. +# e.g. が, けれども, そして, じゃあ, それどころか +接続詞 +# +##### +# particle: unclassified particles. +助詞 +# +# particle-case: case particles where the subclassification is undefined. +助詞-格助詞 +# +# particle-case-misc: Case particles. +# e.g. から, が, で, と, に, へ, より, を, の, にて +助詞-格助詞-一般 +# +# particle-case-quote: the "to" that appears after nouns, a person’s speech, +# quotation marks, expressions of decisions from a meeting, reasons, judgements, +# conjectures, etc. +# e.g. ( だ) と (述べた.), ( である) と (して執行猶予...) +助詞-格助詞-引用 +# +# particle-case-compound: Compounds of particles and verbs that mainly behave +# like case particles. +# e.g. という, といった, とかいう, として, とともに, と共に, でもって, にあたって, に当たって, に当って, +# にあたり, に当たり, に当り, に当たる, にあたる, において, に於いて,に於て, における, に於ける, +# にかけ, にかけて, にかんし, に関し, にかんして, に関して, にかんする, に関する, に際し, +# に際して, にしたがい, に従い, に従う, にしたがって, に従って, にたいし, に対し, にたいして, +# に対して, にたいする, に対する, について, につき, につけ, につけて, につれ, につれて, にとって, +# にとり, にまつわる, によって, に依って, に因って, により, に依り, に因り, による, に依る, に因る, +# にわたって, にわたる, をもって, を以って, を通じ, を通じて, を通して, をめぐって, をめぐり, をめぐる, +# って-口語/, ちゅう-関西弁「という」/, (何) ていう (人)-口語/, っていう-口語/, といふ, とかいふ +助詞-格助詞-連語 +# +# particle-conjunctive: +# e.g. から, からには, が, けれど, けれども, けど, し, つつ, て, で, と, ところが, どころか, とも, ども, +# ながら, なり, ので, のに, ば, ものの, や ( した), やいなや, (ころん) じゃ(いけない)-口語/, +# (行っ) ちゃ(いけない)-口語/, (言っ) たって (しかたがない)-口語/, (それがなく)ったって (平気)-口語/ +助詞-接続助詞 +# +# particle-dependency: +# e.g. こそ, さえ, しか, すら, は, も, ぞ +助詞-係助詞 +# +# particle-adverbial: +# e.g. がてら, かも, くらい, 位, ぐらい, しも, (学校) じゃ(これが流行っている)-口語/, +# (それ)じゃあ (よくない)-口語/, ずつ, (私) なぞ, など, (私) なり (に), (先生) なんか (大嫌い)-口語/, +# (私) なんぞ, (先生) なんて (大嫌い)-口語/, のみ, だけ, (私) だって-口語/, だに, +# (彼)ったら-口語/, (お茶) でも (いかが), 等 (とう), (今後) とも, ばかり, ばっか-口語/, ばっかり-口語/, +# ほど, 程, まで, 迄, (誰) も (が)([助詞-格助詞] および [助詞-係助詞] の前に位置する「も」) +助詞-副助詞 +# +# particle-interjective: particles with interjective grammatical roles. +# e.g. (松島) や +助詞-間投助詞 +# +# particle-coordinate: +# e.g. と, たり, だの, だり, とか, なり, や, やら +助詞-並立助詞 +# +# particle-final: +# e.g. かい, かしら, さ, ぜ, (だ)っけ-口語/, (とまってる) で-方言/, な, ナ, なあ-口語/, ぞ, ね, ネ, +# ねぇ-口語/, ねえ-口語/, ねん-方言/, の, のう-口語/, や, よ, ヨ, よぉ-口語/, わ, わい-口語/ +助詞-終助詞 +# +# particle-adverbial/conjunctive/final: The particle "ka" when unknown whether it is +# adverbial, conjunctive, or sentence final. For example: +# (a) 「A か B か」. Ex:「(国内で運用する) か,(海外で運用する) か (.)」 +# (b) Inside an adverb phrase. Ex:「(幸いという) か (, 死者はいなかった.)」 +# 「(祈りが届いたせい) か (, 試験に合格した.)」 +# (c) 「かのように」. Ex:「(何もなかった) か (のように振る舞った.)」 +# e.g. か +助詞-副助詞/並立助詞/終助詞 +# +# particle-adnominalizer: The "no" that attaches to nouns and modifies +# non-inflectional words. +助詞-連体化 +# +# particle-adnominalizer: The "ni" and "to" that appear following nouns and adverbs +# that are giongo, giseigo, or gitaigo. +# e.g. に, と +助詞-副詞化 +# +# particle-special: A particle that does not fit into one of the above classifications. +# This includes particles that are used in Tanka, Haiku, and other poetry. +# e.g. かな, けむ, ( しただろう) に, (あんた) にゃ(わからん), (俺) ん (家) +助詞-特殊 +# +##### +# auxiliary-verb: +助動詞 +# +##### +# interjection: Greetings and other exclamations. +# e.g. おはよう, おはようございます, こんにちは, こんばんは, ありがとう, どうもありがとう, ありがとうございます, +# いただきます, ごちそうさま, さよなら, さようなら, はい, いいえ, ごめん, ごめんなさい +#感動詞 +# +##### +# symbol: unclassified Symbols. +記号 +# +# symbol-misc: A general symbol not in one of the categories below. +# e.g. [○◎@$〒→+] +記号-一般 +# +# symbol-comma: Commas +# e.g. [,、] +記号-読点 +# +# symbol-period: Periods and full stops. +# e.g. [..。] +記号-句点 +# +# symbol-space: Full-width whitespace. +記号-空白 +# +# symbol-open_bracket: +# e.g. [({‘“『【] +記号-括弧開 +# +# symbol-close_bracket: +# e.g. [)}’”』」】] +記号-括弧閉 +# +# symbol-alphabetic: +#記号-アルファベット +# +##### +# other: unclassified other +#その他 +# +# other-interjection: Words that are hard to classify as noun-suffixes or +# sentence-final particles. +# e.g. (だ)ァ +その他-間投 +# +##### +# filler: Aizuchi that occurs during a conversation or sounds inserted as filler. +# e.g. あの, うんと, えと +フィラー +# +##### +# non-verbal: non-verbal sound. +非言語音 +# +##### +# fragment: +#語断片 +# +##### +# unknown: unknown part of speech. +#未知語 +# +##### End of file diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ar.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ar.txt new file mode 100644 index 00000000000..046829db6a2 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ar.txt @@ -0,0 +1,125 @@ +# This file was created by Jacques Savoy and is distributed under the BSD license. +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# Also see http://www.opensource.org/licenses/bsd-license.html +# Cleaned on October 11, 2009 (not normalized, so use before normalization) +# This means that when modifying this list, you might need to add some +# redundant entries, for example containing forms with both أ and ا +من +ومن +منها +منه +في +وفي +فيها +فيه +و +ف +ثم +او +أو +ب +بها +به +ا +أ +اى +اي +أي +أى +لا +ولا +الا +ألا +إلا +لكن +ما +وما +كما +فما +عن +مع +اذا +إذا +ان +أن +إن +انها +أنها +إنها +انه +أنه +إنه +بان +بأن +فان +فأن +وان +وأن +وإن +التى +التي +الذى +الذي +الذين +الى +الي +إلى +إلي +على +عليها +عليه +اما +أما +إما +ايضا +أيضا +كل +وكل +لم +ولم +لن +ولن +هى +هي +هو +وهى +وهي +وهو +فهى +فهي +فهو +انت +أنت +لك +لها +له +هذه +هذا +تلك +ذلك +هناك +كانت +كان +يكون +تكون +وكانت +وكان +غير +بعض +قد +نحو +بين +بينما +منذ +ضمن +حيث +الان +الآن +خلال +بعد +قبل +حتى +عند +عندما +لدى +جميع diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_bg.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_bg.txt new file mode 100644 index 00000000000..1ae4ba2ae38 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_bg.txt @@ -0,0 +1,193 @@ +# This file was created by Jacques Savoy and is distributed under the BSD license. +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# Also see http://www.opensource.org/licenses/bsd-license.html +а +аз +ако +ала +бе +без +беше +би +бил +била +били +било +близо +бъдат +бъде +бяха +в +вас +ваш +ваша +вероятно +вече +взема +ви +вие +винаги +все +всеки +всички +всичко +всяка +във +въпреки +върху +г +ги +главно +го +д +да +дали +до +докато +докога +дори +досега +доста +е +едва +един +ето +за +зад +заедно +заради +засега +затова +защо +защото +и +из +или +им +има +имат +иска +й +каза +как +каква +какво +както +какъв +като +кога +когато +което +които +кой +който +колко +която +къде +където +към +ли +м +ме +между +мен +ми +мнозина +мога +могат +може +моля +момента +му +н +на +над +назад +най +направи +напред +например +нас +не +него +нея +ни +ние +никой +нито +но +някои +някой +няма +обаче +около +освен +особено +от +отгоре +отново +още +пак +по +повече +повечето +под +поне +поради +после +почти +прави +пред +преди +през +при +пък +първо +с +са +само +се +сега +си +скоро +след +сме +според +сред +срещу +сте +съм +със +също +т +тази +така +такива +такъв +там +твой +те +тези +ти +тн +то +това +тогава +този +той +толкова +точно +трябва +тук +тъй +тя +тях +у +харесва +ч +че +често +чрез +ще +щом +я diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ca.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ca.txt new file mode 100644 index 00000000000..3da65deafe1 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ca.txt @@ -0,0 +1,220 @@ +# Catalan stopwords from http://github.com/vcl/cue.language (Apache 2 Licensed) +a +abans +ací +ah +així +això +al +als +aleshores +algun +alguna +algunes +alguns +alhora +allà +allí +allò +altra +altre +altres +amb +ambdós +ambdues +apa +aquell +aquella +aquelles +aquells +aquest +aquesta +aquestes +aquests +aquí +baix +cada +cadascú +cadascuna +cadascunes +cadascuns +com +contra +d'un +d'una +d'unes +d'uns +dalt +de +del +dels +des +després +dins +dintre +donat +doncs +durant +e +eh +el +els +em +en +encara +ens +entre +érem +eren +éreu +es +és +esta +està +estàvem +estaven +estàveu +esteu +et +etc +ets +fins +fora +gairebé +ha +han +has +havia +he +hem +heu +hi +ho +i +igual +iguals +ja +l'hi +la +les +li +li'n +llavors +m'he +ma +mal +malgrat +mateix +mateixa +mateixes +mateixos +me +mentre +més +meu +meus +meva +meves +molt +molta +moltes +molts +mon +mons +n'he +n'hi +ne +ni +no +nogensmenys +només +nosaltres +nostra +nostre +nostres +o +oh +oi +on +pas +pel +pels +per +però +perquè +poc +poca +pocs +poques +potser +propi +qual +quals +quan +quant +que +què +quelcom +qui +quin +quina +quines +quins +s'ha +s'han +sa +semblant +semblants +ses +seu +seus +seva +seva +seves +si +sobre +sobretot +sóc +solament +sols +son +són +sons +sota +sou +t'ha +t'han +t'he +ta +tal +també +tampoc +tan +tant +tanta +tantes +teu +teus +teva +teves +ton +tons +tot +tota +totes +tots +un +una +unes +uns +us +va +vaig +vam +van +vas +veu +vosaltres +vostra +vostre +vostres diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_cz.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_cz.txt new file mode 100644 index 00000000000..53c6097dac7 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_cz.txt @@ -0,0 +1,172 @@ +a +s +k +o +i +u +v +z +dnes +cz +tímto +budeš +budem +byli +jseš +můj +svým +ta +tomto +tohle +tuto +tyto +jej +zda +proč +máte +tato +kam +tohoto +kdo +kteří +mi +nám +tom +tomuto +mít +nic +proto +kterou +byla +toho +protože +asi +ho +naši +napište +re +což +tím +takže +svých +její +svými +jste +aj +tu +tedy +teto +bylo +kde +ke +pravé +ji +nad +nejsou +či +pod +téma +mezi +přes +ty +pak +vám +ani +když +však +neg +jsem +tento +článku +články +aby +jsme +před +pta +jejich +byl +ještě +až +bez +také +pouze +první +vaše +která +nás +nový +tipy +pokud +může +strana +jeho +své +jiné +zprávy +nové +není +vás +jen +podle +zde +už +být +více +bude +již +než +který +by +které +co +nebo +ten +tak +má +při +od +po +jsou +jak +další +ale +si +se +ve +to +jako +za +zpět +ze +do +pro +je +na +atd +atp +jakmile +přičemž +já +on +ona +ono +oni +ony +my +vy +jí +ji +mě +mne +jemu +tomu +těm +těmu +němu +němuž +jehož +jíž +jelikož +jež +jakož +načež diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_da.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_da.txt new file mode 100644 index 00000000000..a3ff5fe122c --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_da.txt @@ -0,0 +1,108 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/danish/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Danish stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | This is a ranked list (commonest to rarest) of stopwords derived from + | a large text sample. + + +og | and +i | in +jeg | I +det | that (dem. pronoun)/it (pers. pronoun) +at | that (in front of a sentence)/to (with infinitive) +en | a/an +den | it (pers. pronoun)/that (dem. pronoun) +til | to/at/for/until/against/by/of/into, more +er | present tense of "to be" +som | who, as +på | on/upon/in/on/at/to/after/of/with/for, on +de | they +med | with/by/in, along +han | he +af | of/by/from/off/for/in/with/on, off +for | at/for/to/from/by/of/ago, in front/before, because +ikke | not +der | who/which, there/those +var | past tense of "to be" +mig | me/myself +sig | oneself/himself/herself/itself/themselves +men | but +et | a/an/one, one (number), someone/somebody/one +har | present tense of "to have" +om | round/about/for/in/a, about/around/down, if +vi | we +min | my +havde | past tense of "to have" +ham | him +hun | she +nu | now +over | over/above/across/by/beyond/past/on/about, over/past +da | then, when/as/since +fra | from/off/since, off, since +du | you +ud | out +sin | his/her/its/one's +dem | them +os | us/ourselves +op | up +man | you/one +hans | his +hvor | where +eller | or +hvad | what +skal | must/shall etc. +selv | myself/youself/herself/ourselves etc., even +her | here +alle | all/everyone/everybody etc. +vil | will (verb) +blev | past tense of "to stay/to remain/to get/to become" +kunne | could +ind | in +når | when +være | present tense of "to be" +dog | however/yet/after all +noget | something +ville | would +jo | you know/you see (adv), yes +deres | their/theirs +efter | after/behind/according to/for/by/from, later/afterwards +ned | down +skulle | should +denne | this +end | than +dette | this +mit | my/mine +også | also +under | under/beneath/below/during, below/underneath +have | have +dig | you +anden | other +hende | her +mine | my +alt | everything +meget | much/very, plenty of +sit | his, her, its, one's +sine | his, her, its, one's +vor | our +mod | against +disse | these +hvis | if +din | your/yours +nogle | some +hos | by/at +blive | be/become +mange | many +ad | by/through +bliver | present tense of "to be/to become" +hendes | her/hers +været | be +thi | for (conj) +jer | you +sådan | such, like this/like that diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_de.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_de.txt new file mode 100644 index 00000000000..f7703841887 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_de.txt @@ -0,0 +1,292 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/german/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A German stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | The number of forms in this list is reduced significantly by passing it + | through the German stemmer. + + +aber | but + +alle | all +allem +allen +aller +alles + +als | than, as +also | so +am | an + dem +an | at + +ander | other +andere +anderem +anderen +anderer +anderes +anderm +andern +anderr +anders + +auch | also +auf | on +aus | out of +bei | by +bin | am +bis | until +bist | art +da | there +damit | with it +dann | then + +der | the +den +des +dem +die +das + +daß | that + +derselbe | the same +derselben +denselben +desselben +demselben +dieselbe +dieselben +dasselbe + +dazu | to that + +dein | thy +deine +deinem +deinen +deiner +deines + +denn | because + +derer | of those +dessen | of him + +dich | thee +dir | to thee +du | thou + +dies | this +diese +diesem +diesen +dieser +dieses + + +doch | (several meanings) +dort | (over) there + + +durch | through + +ein | a +eine +einem +einen +einer +eines + +einig | some +einige +einigem +einigen +einiger +einiges + +einmal | once + +er | he +ihn | him +ihm | to him + +es | it +etwas | something + +euer | your +eure +eurem +euren +eurer +eures + +für | for +gegen | towards +gewesen | p.p. of sein +hab | have +habe | have +haben | have +hat | has +hatte | had +hatten | had +hier | here +hin | there +hinter | behind + +ich | I +mich | me +mir | to me + + +ihr | you, to her +ihre +ihrem +ihren +ihrer +ihres +euch | to you + +im | in + dem +in | in +indem | while +ins | in + das +ist | is + +jede | each, every +jedem +jeden +jeder +jedes + +jene | that +jenem +jenen +jener +jenes + +jetzt | now +kann | can + +kein | no +keine +keinem +keinen +keiner +keines + +können | can +könnte | could +machen | do +man | one + +manche | some, many a +manchem +manchen +mancher +manches + +mein | my +meine +meinem +meinen +meiner +meines + +mit | with +muss | must +musste | had to +nach | to(wards) +nicht | not +nichts | nothing +noch | still, yet +nun | now +nur | only +ob | whether +oder | or +ohne | without +sehr | very + +sein | his +seine +seinem +seinen +seiner +seines + +selbst | self +sich | herself + +sie | they, she +ihnen | to them + +sind | are +so | so + +solche | such +solchem +solchen +solcher +solches + +soll | shall +sollte | should +sondern | but +sonst | else +über | over +um | about, around +und | and + +uns | us +unse +unsem +unsen +unser +unses + +unter | under +viel | much +vom | von + dem +von | from +vor | before +während | while +war | was +waren | were +warst | wast +was | what +weg | away, off +weil | because +weiter | further + +welche | which +welchem +welchen +welcher +welches + +wenn | when +werde | will +werden | will +wie | how +wieder | again +will | want +wir | we +wird | will +wirst | willst +wo | where +wollen | want +wollte | wanted +würde | would +würden | would +zu | to +zum | zu + dem +zur | zu + der +zwar | indeed +zwischen | between + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_el.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_el.txt new file mode 100644 index 00000000000..232681f5bd6 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_el.txt @@ -0,0 +1,78 @@ +# Lucene Greek Stopwords list +# Note: by default this file is used after GreekLowerCaseFilter, +# so when modifying this file use 'σ' instead of 'ς' +ο +η +το +οι +τα +του +τησ +των +τον +την +και +κι +κ +ειμαι +εισαι +ειναι +ειμαστε +ειστε +στο +στον +στη +στην +μα +αλλα +απο +για +προσ +με +σε +ωσ +παρα +αντι +κατα +μετα +θα +να +δε +δεν +μη +μην +επι +ενω +εαν +αν +τοτε +που +πωσ +ποιοσ +ποια +ποιο +ποιοι +ποιεσ +ποιων +ποιουσ +αυτοσ +αυτη +αυτο +αυτοι +αυτων +αυτουσ +αυτεσ +αυτα +εκεινοσ +εκεινη +εκεινο +εκεινοι +εκεινεσ +εκεινα +εκεινων +εκεινουσ +οπωσ +ομωσ +ισωσ +οσο +οτι diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_en.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_en.txt new file mode 100644 index 00000000000..2c164c0b2a1 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_en.txt @@ -0,0 +1,54 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# a couple of test stopwords to test that the words are really being +# configured from this file: +stopworda +stopwordb + +# Standard english stop words taken from Lucene's StopAnalyzer +a +an +and +are +as +at +be +but +by +for +if +in +into +is +it +no +not +of +on +or +such +that +the +their +then +there +these +they +this +to +was +will +with diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_es.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_es.txt new file mode 100644 index 00000000000..2db14760075 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_es.txt @@ -0,0 +1,354 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/spanish/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Spanish stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + + | The following is a ranked list (commonest to rarest) of stopwords + | deriving from a large sample of text. + + | Extra words have been added at the end. + +de | from, of +la | the, her +que | who, that +el | the +en | in +y | and +a | to +los | the, them +del | de + el +se | himself, from him etc +las | the, them +por | for, by, etc +un | a +para | for +con | with +no | no +una | a +su | his, her +al | a + el + | es from SER +lo | him +como | how +más | more +pero | pero +sus | su plural +le | to him, her +ya | already +o | or + | fue from SER +este | this + | ha from HABER +sí | himself etc +porque | because +esta | this + | son from SER +entre | between + | está from ESTAR +cuando | when +muy | very +sin | without +sobre | on + | ser from SER + | tiene from TENER +también | also +me | me +hasta | until +hay | there is/are +donde | where + | han from HABER +quien | whom, that + | están from ESTAR + | estado from ESTAR +desde | from +todo | all +nos | us +durante | during + | estados from ESTAR +todos | all +uno | a +les | to them +ni | nor +contra | against +otros | other + | fueron from SER +ese | that +eso | that + | había from HABER +ante | before +ellos | they +e | and (variant of y) +esto | this +mí | me +antes | before +algunos | some +qué | what? +unos | a +yo | I +otro | other +otras | other +otra | other +él | he +tanto | so much, many +esa | that +estos | these +mucho | much, many +quienes | who +nada | nothing +muchos | many +cual | who + | sea from SER +poco | few +ella | she +estar | to be + | haber from HABER +estas | these + | estaba from ESTAR + | estamos from ESTAR +algunas | some +algo | something +nosotros | we + + | other forms + +mi | me +mis | mi plural +tú | thou +te | thee +ti | thee +tu | thy +tus | tu plural +ellas | they +nosotras | we +vosotros | you +vosotras | you +os | you +mío | mine +mía | +míos | +mías | +tuyo | thine +tuya | +tuyos | +tuyas | +suyo | his, hers, theirs +suya | +suyos | +suyas | +nuestro | ours +nuestra | +nuestros | +nuestras | +vuestro | yours +vuestra | +vuestros | +vuestras | +esos | those +esas | those + + | forms of estar, to be (not including the infinitive): +estoy +estás +está +estamos +estáis +están +esté +estés +estemos +estéis +estén +estaré +estarás +estará +estaremos +estaréis +estarán +estaría +estarías +estaríamos +estaríais +estarían +estaba +estabas +estábamos +estabais +estaban +estuve +estuviste +estuvo +estuvimos +estuvisteis +estuvieron +estuviera +estuvieras +estuviéramos +estuvierais +estuvieran +estuviese +estuvieses +estuviésemos +estuvieseis +estuviesen +estando +estado +estada +estados +estadas +estad + + | forms of haber, to have (not including the infinitive): +he +has +ha +hemos +habéis +han +haya +hayas +hayamos +hayáis +hayan +habré +habrás +habrá +habremos +habréis +habrán +habría +habrías +habríamos +habríais +habrían +había +habías +habíamos +habíais +habían +hube +hubiste +hubo +hubimos +hubisteis +hubieron +hubiera +hubieras +hubiéramos +hubierais +hubieran +hubiese +hubieses +hubiésemos +hubieseis +hubiesen +habiendo +habido +habida +habidos +habidas + + | forms of ser, to be (not including the infinitive): +soy +eres +es +somos +sois +son +sea +seas +seamos +seáis +sean +seré +serás +será +seremos +seréis +serán +sería +serías +seríamos +seríais +serían +era +eras +éramos +erais +eran +fui +fuiste +fue +fuimos +fuisteis +fueron +fuera +fueras +fuéramos +fuerais +fueran +fuese +fueses +fuésemos +fueseis +fuesen +siendo +sido + | sed also means 'thirst' + + | forms of tener, to have (not including the infinitive): +tengo +tienes +tiene +tenemos +tenéis +tienen +tenga +tengas +tengamos +tengáis +tengan +tendré +tendrás +tendrá +tendremos +tendréis +tendrán +tendría +tendrías +tendríamos +tendríais +tendrían +tenía +tenías +teníamos +teníais +tenían +tuve +tuviste +tuvo +tuvimos +tuvisteis +tuvieron +tuviera +tuvieras +tuviéramos +tuvierais +tuvieran +tuviese +tuvieses +tuviésemos +tuvieseis +tuviesen +teniendo +tenido +tenida +tenidos +tenidas +tened + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_eu.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_eu.txt new file mode 100644 index 00000000000..25f1db93460 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_eu.txt @@ -0,0 +1,99 @@ +# example set of basque stopwords +al +anitz +arabera +asko +baina +bat +batean +batek +bati +batzuei +batzuek +batzuetan +batzuk +bera +beraiek +berau +berauek +bere +berori +beroriek +beste +bezala +da +dago +dira +ditu +du +dute +edo +egin +ere +eta +eurak +ez +gainera +gu +gutxi +guzti +haiei +haiek +haietan +hainbeste +hala +han +handik +hango +hara +hari +hark +hartan +hau +hauei +hauek +hauetan +hemen +hemendik +hemengo +hi +hona +honek +honela +honetan +honi +hor +hori +horiei +horiek +horietan +horko +horra +horrek +horrela +horretan +horri +hortik +hura +izan +ni +noiz +nola +non +nondik +nongo +nor +nora +ze +zein +zen +zenbait +zenbat +zer +zergatik +ziren +zituen +zu +zuek +zuen +zuten diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fa.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fa.txt new file mode 100644 index 00000000000..723641c6da7 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fa.txt @@ -0,0 +1,313 @@ +# This file was created by Jacques Savoy and is distributed under the BSD license. +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# Also see http://www.opensource.org/licenses/bsd-license.html +# Note: by default this file is used after normalization, so when adding entries +# to this file, use the arabic 'ي' instead of 'ی' +انان +نداشته +سراسر +خياه +ايشان +وي +تاكنون +بيشتري +دوم +پس +ناشي +وگو +يا +داشتند +سپس +هنگام +هرگز +پنج +نشان +امسال +ديگر +گروهي +شدند +چطور +ده +و +دو +نخستين +ولي +چرا +چه +وسط +ه +كدام +قابل +يك +رفت +هفت +همچنين +در +هزار +بله +بلي +شايد +اما +شناسي +گرفته +دهد +داشته +دانست +داشتن +خواهيم +ميليارد +وقتيكه +امد +خواهد +جز +اورده +شده +بلكه +خدمات +شدن +برخي +نبود +بسياري +جلوگيري +حق +كردند +نوعي +بعري +نكرده +نظير +نبايد +بوده +بودن +داد +اورد +هست +جايي +شود +دنبال +داده +بايد +سابق +هيچ +همان +انجا +كمتر +كجاست +گردد +كسي +تر +مردم +تان +دادن +بودند +سري +جدا +ندارند +مگر +يكديگر +دارد +دهند +بنابراين +هنگامي +سمت +جا +انچه +خود +دادند +زياد +دارند +اثر +بدون +بهترين +بيشتر +البته +به +براساس +بيرون +كرد +بعضي +گرفت +توي +اي +ميليون +او +جريان +تول +بر +مانند +برابر +باشيم +مدتي +گويند +اكنون +تا +تنها +جديد +چند +بي +نشده +كردن +كردم +گويد +كرده +كنيم +نمي +نزد +روي +قصد +فقط +بالاي +ديگران +اين +ديروز +توسط +سوم +ايم +دانند +سوي +استفاده +شما +كنار +داريم +ساخته +طور +امده +رفته +نخست +بيست +نزديك +طي +كنيد +از +انها +تمامي +داشت +يكي +طريق +اش +چيست +روب +نمايد +گفت +چندين +چيزي +تواند +ام +ايا +با +ان +ايد +ترين +اينكه +ديگري +راه +هايي +بروز +همچنان +پاعين +كس +حدود +مختلف +مقابل +چيز +گيرد +ندارد +ضد +همچون +سازي +شان +مورد +باره +مرسي +خويش +برخوردار +چون +خارج +شش +هنوز +تحت +ضمن +هستيم +گفته +فكر +بسيار +پيش +براي +روزهاي +انكه +نخواهد +بالا +كل +وقتي +كي +چنين +كه +گيري +نيست +است +كجا +كند +نيز +يابد +بندي +حتي +توانند +عقب +خواست +كنند +بين +تمام +همه +ما +باشند +مثل +شد +اري +باشد +اره +طبق +بعد +اگر +صورت +غير +جاي +بيش +ريزي +اند +زيرا +چگونه +بار +لطفا +مي +درباره +من +ديده +همين +گذاري +برداري +علت +گذاشته +هم +فوق +نه +ها +شوند +اباد +همواره +هر +اول +خواهند +چهار +نام +امروز +مان +هاي +قبل +كنم +سعي +تازه +را +هستند +زير +جلوي +عنوان +بود diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fi.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fi.txt new file mode 100644 index 00000000000..addad798c4b --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fi.txt @@ -0,0 +1,95 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/finnish/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + +| forms of BE + +olla +olen +olet +on +olemme +olette +ovat +ole | negative form + +oli +olisi +olisit +olisin +olisimme +olisitte +olisivat +olit +olin +olimme +olitte +olivat +ollut +olleet + +en | negation +et +ei +emme +ette +eivät + +|Nom Gen Acc Part Iness Elat Illat Adess Ablat Allat Ess Trans +minä minun minut minua minussa minusta minuun minulla minulta minulle | I +sinä sinun sinut sinua sinussa sinusta sinuun sinulla sinulta sinulle | you +hän hänen hänet häntä hänessä hänestä häneen hänellä häneltä hänelle | he she +me meidän meidät meitä meissä meistä meihin meillä meiltä meille | we +te teidän teidät teitä teissä teistä teihin teillä teiltä teille | you +he heidän heidät heitä heissä heistä heihin heillä heiltä heille | they + +tämä tämän tätä tässä tästä tähän tallä tältä tälle tänä täksi | this +tuo tuon tuotä tuossa tuosta tuohon tuolla tuolta tuolle tuona tuoksi | that +se sen sitä siinä siitä siihen sillä siltä sille sinä siksi | it +nämä näiden näitä näissä näistä näihin näillä näiltä näille näinä näiksi | these +nuo noiden noita noissa noista noihin noilla noilta noille noina noiksi | those +ne niiden niitä niissä niistä niihin niillä niiltä niille niinä niiksi | they + +kuka kenen kenet ketä kenessä kenestä keneen kenellä keneltä kenelle kenenä keneksi| who +ketkä keiden ketkä keitä keissä keistä keihin keillä keiltä keille keinä keiksi | (pl) +mikä minkä minkä mitä missä mistä mihin millä miltä mille minä miksi | which what +mitkä | (pl) + +joka jonka jota jossa josta johon jolla jolta jolle jona joksi | who which +jotka joiden joita joissa joista joihin joilla joilta joille joina joiksi | (pl) + +| conjunctions + +että | that +ja | and +jos | if +koska | because +kuin | than +mutta | but +niin | so +sekä | and +sillä | for +tai | or +vaan | but +vai | or +vaikka | although + + +| prepositions + +kanssa | with +mukaan | according to +noin | about +poikki | across +yli | over, across + +| other + +kun | when +niin | so +nyt | now +itse | self + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fr.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fr.txt new file mode 100644 index 00000000000..c00837ea939 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fr.txt @@ -0,0 +1,183 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/french/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A French stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + +au | a + le +aux | a + les +avec | with +ce | this +ces | these +dans | with +de | of +des | de + les +du | de + le +elle | she +en | `of them' etc +et | and +eux | them +il | he +je | I +la | the +le | the +leur | their +lui | him +ma | my (fem) +mais | but +me | me +même | same; as in moi-même (myself) etc +mes | me (pl) +moi | me +mon | my (masc) +ne | not +nos | our (pl) +notre | our +nous | we +on | one +ou | where +par | by +pas | not +pour | for +qu | que before vowel +que | that +qui | who +sa | his, her (fem) +se | oneself +ses | his (pl) +son | his, her (masc) +sur | on +ta | thy (fem) +te | thee +tes | thy (pl) +toi | thee +ton | thy (masc) +tu | thou +un | a +une | a +vos | your (pl) +votre | your +vous | you + + | single letter forms + +c | c' +d | d' +j | j' +l | l' +à | to, at +m | m' +n | n' +s | s' +t | t' +y | there + + | forms of être (not including the infinitive): +été +étée +étées +étés +étant +suis +es +est +sommes +êtes +sont +serai +seras +sera +serons +serez +seront +serais +serait +serions +seriez +seraient +étais +était +étions +étiez +étaient +fus +fut +fûmes +fûtes +furent +sois +soit +soyons +soyez +soient +fusse +fusses +fût +fussions +fussiez +fussent + + | forms of avoir (not including the infinitive): +ayant +eu +eue +eues +eus +ai +as +avons +avez +ont +aurai +auras +aura +aurons +aurez +auront +aurais +aurait +aurions +auriez +auraient +avais +avait +avions +aviez +avaient +eut +eûmes +eûtes +eurent +aie +aies +ait +ayons +ayez +aient +eusse +eusses +eût +eussions +eussiez +eussent + + | Later additions (from Jean-Christophe Deschamps) +ceci | this +celà  | that +cet | this +cette | this +ici | here +ils | they +les | the (pl) +leurs | their (pl) +quel | which +quels | which +quelle | which +quelles | which +sans | without +soi | oneself + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ga.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ga.txt new file mode 100644 index 00000000000..9ff88d747e5 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ga.txt @@ -0,0 +1,110 @@ + +a +ach +ag +agus +an +aon +ar +arna +as +b' +ba +beirt +bhúr +caoga +ceathair +ceathrar +chomh +chtó +chuig +chun +cois +céad +cúig +cúigear +d' +daichead +dar +de +deich +deichniúr +den +dhá +do +don +dtí +dá +dár +dó +faoi +faoin +faoina +faoinár +fara +fiche +gach +gan +go +gur +haon +hocht +i +iad +idir +in +ina +ins +inár +is +le +leis +lena +lenár +m' +mar +mo +mé +na +nach +naoi +naonúr +ná +ní +níor +nó +nócha +ocht +ochtar +os +roimh +sa +seacht +seachtar +seachtó +seasca +seisear +siad +sibh +sinn +sna +sé +sí +tar +thar +thú +triúr +trí +trína +trínár +tríocha +tú +um +ár +é +éis +í +ó +ón +óna +ónár diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_gl.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_gl.txt new file mode 100644 index 00000000000..d8760b12c14 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_gl.txt @@ -0,0 +1,161 @@ +# galican stopwords +a +aínda +alí +aquel +aquela +aquelas +aqueles +aquilo +aquí +ao +aos +as +así +á +ben +cando +che +co +coa +comigo +con +connosco +contigo +convosco +coas +cos +cun +cuns +cunha +cunhas +da +dalgunha +dalgunhas +dalgún +dalgúns +das +de +del +dela +delas +deles +desde +deste +do +dos +dun +duns +dunha +dunhas +e +el +ela +elas +eles +en +era +eran +esa +esas +ese +eses +esta +estar +estaba +está +están +este +estes +estiven +estou +eu +é +facer +foi +foron +fun +había +hai +iso +isto +la +las +lle +lles +lo +los +mais +me +meu +meus +min +miña +miñas +moi +na +nas +neste +nin +no +non +nos +nosa +nosas +noso +nosos +nós +nun +nunha +nuns +nunhas +o +os +ou +ó +ós +para +pero +pode +pois +pola +polas +polo +polos +por +que +se +senón +ser +seu +seus +sexa +sido +sobre +súa +súas +tamén +tan +te +ten +teñen +teño +ter +teu +teus +ti +tido +tiña +tiven +túa +túas +un +unha +unhas +uns +vos +vosa +vosas +voso +vosos +vós diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hi.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hi.txt new file mode 100644 index 00000000000..86286bb083b --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hi.txt @@ -0,0 +1,235 @@ +# Also see http://www.opensource.org/licenses/bsd-license.html +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# This file was created by Jacques Savoy and is distributed under the BSD license. +# Note: by default this file also contains forms normalized by HindiNormalizer +# for spelling variation (see section below), such that it can be used whether or +# not you enable that feature. When adding additional entries to this list, +# please add the normalized form as well. +अंदर +अत +अपना +अपनी +अपने +अभी +आदि +आप +इत्यादि +इन +इनका +इन्हीं +इन्हें +इन्हों +इस +इसका +इसकी +इसके +इसमें +इसी +इसे +उन +उनका +उनकी +उनके +उनको +उन्हीं +उन्हें +उन्हों +उस +उसके +उसी +उसे +एक +एवं +एस +ऐसे +और +कई +कर +करता +करते +करना +करने +करें +कहते +कहा +का +काफ़ी +कि +कितना +किन्हें +किन्हों +किया +किर +किस +किसी +किसे +की +कुछ +कुल +के +को +कोई +कौन +कौनसा +गया +घर +जब +जहाँ +जा +जितना +जिन +जिन्हें +जिन्हों +जिस +जिसे +जीधर +जैसा +जैसे +जो +तक +तब +तरह +तिन +तिन्हें +तिन्हों +तिस +तिसे +तो +था +थी +थे +दबारा +दिया +दुसरा +दूसरे +दो +द्वारा +न +नहीं +ना +निहायत +नीचे +ने +पर +पर +पहले +पूरा +पे +फिर +बनी +बही +बहुत +बाद +बाला +बिलकुल +भी +भीतर +मगर +मानो +मे +में +यदि +यह +यहाँ +यही +या +यिह +ये +रखें +रहा +रहे +ऱ्वासा +लिए +लिये +लेकिन +व +वर्ग +वह +वह +वहाँ +वहीं +वाले +वुह +वे +वग़ैरह +संग +सकता +सकते +सबसे +सभी +साथ +साबुत +साभ +सारा +से +सो +ही +हुआ +हुई +हुए +है +हैं +हो +होता +होती +होते +होना +होने +# additional normalized forms of the above +अपनि +जेसे +होति +सभि +तिंहों +इंहों +दवारा +इसि +किंहें +थि +उंहों +ओर +जिंहें +वहिं +अभि +बनि +हि +उंहिं +उंहें +हें +वगेरह +एसे +रवासा +कोन +निचे +काफि +उसि +पुरा +भितर +हे +बहि +वहां +कोइ +यहां +जिंहों +तिंहें +किसि +कइ +यहि +इंहिं +जिधर +इंहें +अदि +इतयादि +हुइ +कोनसा +इसकि +दुसरे +जहां +अप +किंहों +उनकि +भि +वरग +हुअ +जेसा +नहिं diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hu.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hu.txt new file mode 100644 index 00000000000..1a96f1db6f2 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hu.txt @@ -0,0 +1,209 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/hungarian/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + +| Hungarian stop word list +| prepared by Anna Tordai + +a +ahogy +ahol +aki +akik +akkor +alatt +által +általában +amely +amelyek +amelyekben +amelyeket +amelyet +amelynek +ami +amit +amolyan +amíg +amikor +át +abban +ahhoz +annak +arra +arról +az +azok +azon +azt +azzal +azért +aztán +azután +azonban +bár +be +belül +benne +cikk +cikkek +cikkeket +csak +de +e +eddig +egész +egy +egyes +egyetlen +egyéb +egyik +egyre +ekkor +el +elég +ellen +elő +először +előtt +első +én +éppen +ebben +ehhez +emilyen +ennek +erre +ez +ezt +ezek +ezen +ezzel +ezért +és +fel +felé +hanem +hiszen +hogy +hogyan +igen +így +illetve +ill. +ill +ilyen +ilyenkor +ison +ismét +itt +jó +jól +jobban +kell +kellett +keresztül +keressünk +ki +kívül +között +közül +legalább +lehet +lehetett +legyen +lenne +lenni +lesz +lett +maga +magát +majd +majd +már +más +másik +meg +még +mellett +mert +mely +melyek +mi +mit +míg +miért +milyen +mikor +minden +mindent +mindenki +mindig +mint +mintha +mivel +most +nagy +nagyobb +nagyon +ne +néha +nekem +neki +nem +néhány +nélkül +nincs +olyan +ott +össze +ő +ők +őket +pedig +persze +rá +s +saját +sem +semmi +sok +sokat +sokkal +számára +szemben +szerint +szinte +talán +tehát +teljes +tovább +továbbá +több +úgy +ugyanis +új +újabb +újra +után +utána +utolsó +vagy +vagyis +valaki +valami +valamint +való +vagyok +van +vannak +volt +voltam +voltak +voltunk +vissza +vele +viszont +volna diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hy.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hy.txt new file mode 100644 index 00000000000..60c1c50fbc8 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hy.txt @@ -0,0 +1,46 @@ +# example set of Armenian stopwords. +այդ +այլ +այն +այս +դու +դուք +եմ +են +ենք +ես +եք +է +էի +էին +էինք +էիր +էիք +էր +ըստ +թ +ի +ին +իսկ +իր +կամ +համար +հետ +հետո +մենք +մեջ +մի +ն +նա +նաև +նրա +նրանք +որ +որը +որոնք +որպես +ու +ում +պիտի +վրա +և diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_id.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_id.txt new file mode 100644 index 00000000000..4617f83a5c5 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_id.txt @@ -0,0 +1,359 @@ +# from appendix D of: A Study of Stemming Effects on Information +# Retrieval in Bahasa Indonesia +ada +adanya +adalah +adapun +agak +agaknya +agar +akan +akankah +akhirnya +aku +akulah +amat +amatlah +anda +andalah +antar +diantaranya +antara +antaranya +diantara +apa +apaan +mengapa +apabila +apakah +apalagi +apatah +atau +ataukah +ataupun +bagai +bagaikan +sebagai +sebagainya +bagaimana +bagaimanapun +sebagaimana +bagaimanakah +bagi +bahkan +bahwa +bahwasanya +sebaliknya +banyak +sebanyak +beberapa +seberapa +begini +beginian +beginikah +beginilah +sebegini +begitu +begitukah +begitulah +begitupun +sebegitu +belum +belumlah +sebelum +sebelumnya +sebenarnya +berapa +berapakah +berapalah +berapapun +betulkah +sebetulnya +biasa +biasanya +bila +bilakah +bisa +bisakah +sebisanya +boleh +bolehkah +bolehlah +buat +bukan +bukankah +bukanlah +bukannya +cuma +percuma +dahulu +dalam +dan +dapat +dari +daripada +dekat +demi +demikian +demikianlah +sedemikian +dengan +depan +di +dia +dialah +dini +diri +dirinya +terdiri +dong +dulu +enggak +enggaknya +entah +entahlah +terhadap +terhadapnya +hal +hampir +hanya +hanyalah +harus +haruslah +harusnya +seharusnya +hendak +hendaklah +hendaknya +hingga +sehingga +ia +ialah +ibarat +ingin +inginkah +inginkan +ini +inikah +inilah +itu +itukah +itulah +jangan +jangankan +janganlah +jika +jikalau +juga +justru +kala +kalau +kalaulah +kalaupun +kalian +kami +kamilah +kamu +kamulah +kan +kapan +kapankah +kapanpun +dikarenakan +karena +karenanya +ke +kecil +kemudian +kenapa +kepada +kepadanya +ketika +seketika +khususnya +kini +kinilah +kiranya +sekiranya +kita +kitalah +kok +lagi +lagian +selagi +lah +lain +lainnya +melainkan +selaku +lalu +melalui +terlalu +lama +lamanya +selama +selama +selamanya +lebih +terlebih +bermacam +macam +semacam +maka +makanya +makin +malah +malahan +mampu +mampukah +mana +manakala +manalagi +masih +masihkah +semasih +masing +mau +maupun +semaunya +memang +mereka +merekalah +meski +meskipun +semula +mungkin +mungkinkah +nah +namun +nanti +nantinya +nyaris +oleh +olehnya +seorang +seseorang +pada +padanya +padahal +paling +sepanjang +pantas +sepantasnya +sepantasnyalah +para +pasti +pastilah +per +pernah +pula +pun +merupakan +rupanya +serupa +saat +saatnya +sesaat +saja +sajalah +saling +bersama +sama +sesama +sambil +sampai +sana +sangat +sangatlah +saya +sayalah +se +sebab +sebabnya +sebuah +tersebut +tersebutlah +sedang +sedangkan +sedikit +sedikitnya +segala +segalanya +segera +sesegera +sejak +sejenak +sekali +sekalian +sekalipun +sesekali +sekaligus +sekarang +sekarang +sekitar +sekitarnya +sela +selain +selalu +seluruh +seluruhnya +semakin +sementara +sempat +semua +semuanya +sendiri +sendirinya +seolah +seperti +sepertinya +sering +seringnya +serta +siapa +siapakah +siapapun +disini +disinilah +sini +sinilah +sesuatu +sesuatunya +suatu +sesudah +sesudahnya +sudah +sudahkah +sudahlah +supaya +tadi +tadinya +tak +tanpa +setelah +telah +tentang +tentu +tentulah +tentunya +tertentu +seterusnya +tapi +tetapi +setiap +tiap +setidaknya +tidak +tidakkah +tidaklah +toh +waduh +wah +wahai +sewaktu +walau +walaupun +wong +yaitu +yakni +yang diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_it.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_it.txt new file mode 100644 index 00000000000..4cb5b0891b1 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_it.txt @@ -0,0 +1,301 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/italian/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | An Italian stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + +ad | a (to) before vowel +al | a + il +allo | a + lo +ai | a + i +agli | a + gli +all | a + l' +agl | a + gl' +alla | a + la +alle | a + le +con | with +col | con + il +coi | con + i (forms collo, cogli etc are now very rare) +da | from +dal | da + il +dallo | da + lo +dai | da + i +dagli | da + gli +dall | da + l' +dagl | da + gll' +dalla | da + la +dalle | da + le +di | of +del | di + il +dello | di + lo +dei | di + i +degli | di + gli +dell | di + l' +degl | di + gl' +della | di + la +delle | di + le +in | in +nel | in + el +nello | in + lo +nei | in + i +negli | in + gli +nell | in + l' +negl | in + gl' +nella | in + la +nelle | in + le +su | on +sul | su + il +sullo | su + lo +sui | su + i +sugli | su + gli +sull | su + l' +sugl | su + gl' +sulla | su + la +sulle | su + le +per | through, by +tra | among +contro | against +io | I +tu | thou +lui | he +lei | she +noi | we +voi | you +loro | they +mio | my +mia | +miei | +mie | +tuo | +tua | +tuoi | thy +tue | +suo | +sua | +suoi | his, her +sue | +nostro | our +nostra | +nostri | +nostre | +vostro | your +vostra | +vostri | +vostre | +mi | me +ti | thee +ci | us, there +vi | you, there +lo | him, the +la | her, the +li | them +le | them, the +gli | to him, the +ne | from there etc +il | the +un | a +uno | a +una | a +ma | but +ed | and +se | if +perché | why, because +anche | also +come | how +dov | where (as dov') +dove | where +che | who, that +chi | who +cui | whom +non | not +più | more +quale | who, that +quanto | how much +quanti | +quanta | +quante | +quello | that +quelli | +quella | +quelle | +questo | this +questi | +questa | +queste | +si | yes +tutto | all +tutti | all + + | single letter forms: + +a | at +c | as c' for ce or ci +e | and +i | the +l | as l' +o | or + + | forms of avere, to have (not including the infinitive): + +ho +hai +ha +abbiamo +avete +hanno +abbia +abbiate +abbiano +avrò +avrai +avrà +avremo +avrete +avranno +avrei +avresti +avrebbe +avremmo +avreste +avrebbero +avevo +avevi +aveva +avevamo +avevate +avevano +ebbi +avesti +ebbe +avemmo +aveste +ebbero +avessi +avesse +avessimo +avessero +avendo +avuto +avuta +avuti +avute + + | forms of essere, to be (not including the infinitive): +sono +sei +è +siamo +siete +sia +siate +siano +sarò +sarai +sarà +saremo +sarete +saranno +sarei +saresti +sarebbe +saremmo +sareste +sarebbero +ero +eri +era +eravamo +eravate +erano +fui +fosti +fu +fummo +foste +furono +fossi +fosse +fossimo +fossero +essendo + + | forms of fare, to do (not including the infinitive, fa, fat-): +faccio +fai +facciamo +fanno +faccia +facciate +facciano +farò +farai +farà +faremo +farete +faranno +farei +faresti +farebbe +faremmo +fareste +farebbero +facevo +facevi +faceva +facevamo +facevate +facevano +feci +facesti +fece +facemmo +faceste +fecero +facessi +facesse +facessimo +facessero +facendo + + | forms of stare, to be (not including the infinitive): +sto +stai +sta +stiamo +stanno +stia +stiate +stiano +starò +starai +starà +staremo +starete +staranno +starei +staresti +starebbe +staremmo +stareste +starebbero +stavo +stavi +stava +stavamo +stavate +stavano +stetti +stesti +stette +stemmo +steste +stettero +stessi +stesse +stessimo +stessero +stando diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ja.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ja.txt new file mode 100644 index 00000000000..d4321be6b16 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ja.txt @@ -0,0 +1,127 @@ +# +# This file defines a stopword set for Japanese. +# +# This set is made up of hand-picked frequent terms from segmented Japanese Wikipedia. +# Punctuation characters and frequent kanji have mostly been left out. See LUCENE-3745 +# for frequency lists, etc. that can be useful for making your own set (if desired) +# +# Note that there is an overlap between these stopwords and the terms stopped when used +# in combination with the JapanesePartOfSpeechStopFilter. When editing this file, note +# that comments are not allowed on the same line as stopwords. +# +# Also note that stopping is done in a case-insensitive manner. Change your StopFilter +# configuration if you need case-sensitive stopping. Lastly, note that stopping is done +# using the same character width as the entries in this file. Since this StopFilter is +# normally done after a CJKWidthFilter in your chain, you would usually want your romaji +# entries to be in half-width and your kana entries to be in full-width. +# +の +に +は +を +た +が +で +て +と +し +れ +さ +ある +いる +も +する +から +な +こと +として +い +や +れる +など +なっ +ない +この +ため +その +あっ +よう +また +もの +という +あり +まで +られ +なる +へ +か +だ +これ +によって +により +おり +より +による +ず +なり +られる +において +ば +なかっ +なく +しかし +について +せ +だっ +その後 +できる +それ +う +ので +なお +のみ +でき +き +つ +における +および +いう +さらに +でも +ら +たり +その他 +に関する +たち +ます +ん +なら +に対して +特に +せる +及び +これら +とき +では +にて +ほか +ながら +うち +そして +とともに +ただし +かつて +それぞれ +または +お +ほど +ものの +に対する +ほとんど +と共に +といった +です +とも +ところ +ここ +##### End of file diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_lv.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_lv.txt new file mode 100644 index 00000000000..e21a23c06c3 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_lv.txt @@ -0,0 +1,172 @@ +# Set of Latvian stopwords from A Stemming Algorithm for Latvian, Karlis Kreslins +# the original list of over 800 forms was refined: +# pronouns, adverbs, interjections were removed +# +# prepositions +aiz +ap +ar +apakš +ārpus +augšpus +bez +caur +dēļ +gar +iekš +iz +kopš +labad +lejpus +līdz +no +otrpus +pa +par +pār +pēc +pie +pirms +pret +priekš +starp +šaipus +uz +viņpus +virs +virspus +zem +apakšpus +# Conjunctions +un +bet +jo +ja +ka +lai +tomēr +tikko +turpretī +arī +kaut +gan +tādēļ +tā +ne +tikvien +vien +kā +ir +te +vai +kamēr +# Particles +ar +diezin +droši +diemžēl +nebūt +ik +it +taču +nu +pat +tiklab +iekšpus +nedz +tik +nevis +turpretim +jeb +iekam +iekām +iekāms +kolīdz +līdzko +tiklīdz +jebšu +tālab +tāpēc +nekā +itin +jā +jau +jel +nē +nezin +tad +tikai +vis +tak +iekams +vien +# modal verbs +būt +biju +biji +bija +bijām +bijāt +esmu +esi +esam +esat +būšu +būsi +būs +būsim +būsiet +tikt +tiku +tiki +tika +tikām +tikāt +tieku +tiec +tiek +tiekam +tiekat +tikšu +tiks +tiksim +tiksiet +tapt +tapi +tapāt +topat +tapšu +tapsi +taps +tapsim +tapsiet +kļūt +kļuvu +kļuvi +kļuva +kļuvām +kļuvāt +kļūstu +kļūsti +kļūst +kļūstam +kļūstat +kļūšu +kļūsi +kļūs +kļūsim +kļūsiet +# verbs +varēt +varēju +varējām +varēšu +varēsim +var +varēji +varējāt +varēsi +varēsiet +varat +varēja +varēs diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_nl.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_nl.txt new file mode 100644 index 00000000000..f4d61f5092c --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_nl.txt @@ -0,0 +1,117 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/dutch/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Dutch stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | This is a ranked list (commonest to rarest) of stopwords derived from + | a large sample of Dutch text. + + | Dutch stop words frequently exhibit homonym clashes. These are indicated + | clearly below. + +de | the +en | and +van | of, from +ik | I, the ego +te | (1) chez, at etc, (2) to, (3) too +dat | that, which +die | that, those, who, which +in | in, inside +een | a, an, one +hij | he +het | the, it +niet | not, nothing, naught +zijn | (1) to be, being, (2) his, one's, its +is | is +was | (1) was, past tense of all persons sing. of 'zijn' (to be) (2) wax, (3) the washing, (4) rise of river +op | on, upon, at, in, up, used up +aan | on, upon, to (as dative) +met | with, by +als | like, such as, when +voor | (1) before, in front of, (2) furrow +had | had, past tense all persons sing. of 'hebben' (have) +er | there +maar | but, only +om | round, about, for etc +hem | him +dan | then +zou | should/would, past tense all persons sing. of 'zullen' +of | or, whether, if +wat | what, something, anything +mijn | possessive and noun 'mine' +men | people, 'one' +dit | this +zo | so, thus, in this way +door | through by +over | over, across +ze | she, her, they, them +zich | oneself +bij | (1) a bee, (2) by, near, at +ook | also, too +tot | till, until +je | you +mij | me +uit | out of, from +der | Old Dutch form of 'van der' still found in surnames +daar | (1) there, (2) because +haar | (1) her, their, them, (2) hair +naar | (1) unpleasant, unwell etc, (2) towards, (3) as +heb | present first person sing. of 'to have' +hoe | how, why +heeft | present third person sing. of 'to have' +hebben | 'to have' and various parts thereof +deze | this +u | you +want | (1) for, (2) mitten, (3) rigging +nog | yet, still +zal | 'shall', first and third person sing. of verb 'zullen' (will) +me | me +zij | she, they +nu | now +ge | 'thou', still used in Belgium and south Netherlands +geen | none +omdat | because +iets | something, somewhat +worden | to become, grow, get +toch | yet, still +al | all, every, each +waren | (1) 'were' (2) to wander, (3) wares, (3) +veel | much, many +meer | (1) more, (2) lake +doen | to do, to make +toen | then, when +moet | noun 'spot/mote' and present form of 'to must' +ben | (1) am, (2) 'are' in interrogative second person singular of 'to be' +zonder | without +kan | noun 'can' and present form of 'to be able' +hun | their, them +dus | so, consequently +alles | all, everything, anything +onder | under, beneath +ja | yes, of course +eens | once, one day +hier | here +wie | who +werd | imperfect third person sing. of 'become' +altijd | always +doch | yet, but etc +wordt | present third person sing. of 'become' +wezen | (1) to be, (2) 'been' as in 'been fishing', (3) orphans +kunnen | to be able +ons | us/our +zelf | self +tegen | against, towards, at +na | after, near +reeds | already +wil | (1) present tense of 'want', (2) 'will', noun, (3) fender +kon | could; past tense of 'to be able' +niets | nothing +uw | your +iemand | somebody +geweest | been; past participle of 'be' +andere | other diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_no.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_no.txt new file mode 100644 index 00000000000..e76f36e69ed --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_no.txt @@ -0,0 +1,192 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/norwegian/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Norwegian stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | This stop word list is for the dominant bokmål dialect. Words unique + | to nynorsk are marked *. + + | Revised by Jan Bruusgaard , Jan 2005 + +og | and +i | in +jeg | I +det | it/this/that +at | to (w. inf.) +en | a/an +et | a/an +den | it/this/that +til | to +er | is/am/are +som | who/that +på | on +de | they / you(formal) +med | with +han | he +av | of +ikke | not +ikkje | not * +der | there +så | so +var | was/were +meg | me +seg | you +men | but +ett | one +har | have +om | about +vi | we +min | my +mitt | my +ha | have +hadde | had +hun | she +nå | now +over | over +da | when/as +ved | by/know +fra | from +du | you +ut | out +sin | your +dem | them +oss | us +opp | up +man | you/one +kan | can +hans | his +hvor | where +eller | or +hva | what +skal | shall/must +selv | self (reflective) +sjøl | self (reflective) +her | here +alle | all +vil | will +bli | become +ble | became +blei | became * +blitt | have become +kunne | could +inn | in +når | when +være | be +kom | come +noen | some +noe | some +ville | would +dere | you +som | who/which/that +deres | their/theirs +kun | only/just +ja | yes +etter | after +ned | down +skulle | should +denne | this +for | for/because +deg | you +si | hers/his +sine | hers/his +sitt | hers/his +mot | against +å | to +meget | much +hvorfor | why +dette | this +disse | these/those +uten | without +hvordan | how +ingen | none +din | your +ditt | your +blir | become +samme | same +hvilken | which +hvilke | which (plural) +sånn | such a +inni | inside/within +mellom | between +vår | our +hver | each +hvem | who +vors | us/ours +hvis | whose +både | both +bare | only/just +enn | than +fordi | as/because +før | before +mange | many +også | also +slik | just +vært | been +være | to be +båe | both * +begge | both +siden | since +dykk | your * +dykkar | yours * +dei | they * +deira | them * +deires | theirs * +deim | them * +di | your (fem.) * +då | as/when * +eg | I * +ein | a/an * +eit | a/an * +eitt | a/an * +elles | or * +honom | he * +hjå | at * +ho | she * +hoe | she * +henne | her +hennar | her/hers +hennes | hers +hoss | how * +hossen | how * +ikkje | not * +ingi | noone * +inkje | noone * +korleis | how * +korso | how * +kva | what/which * +kvar | where * +kvarhelst | where * +kven | who/whom * +kvi | why * +kvifor | why * +me | we * +medan | while * +mi | my * +mine | my * +mykje | much * +no | now * +nokon | some (masc./neut.) * +noka | some (fem.) * +nokor | some * +noko | some * +nokre | some * +si | his/hers * +sia | since * +sidan | since * +so | so * +somt | some * +somme | some * +um | about* +upp | up * +vere | be * +vore | was * +verte | become * +vort | become * +varte | became * +vart | became * + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_pt.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_pt.txt new file mode 100644 index 00000000000..276c1b446f2 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_pt.txt @@ -0,0 +1,251 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/portuguese/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Portuguese stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + + | The following is a ranked list (commonest to rarest) of stopwords + | deriving from a large sample of text. + + | Extra words have been added at the end. + +de | of, from +a | the; to, at; her +o | the; him +que | who, that +e | and +do | de + o +da | de + a +em | in +um | a +para | for + | é from SER +com | with +não | not, no +uma | a +os | the; them +no | em + o +se | himself etc +na | em + a +por | for +mais | more +as | the; them +dos | de + os +como | as, like +mas | but + | foi from SER +ao | a + o +ele | he +das | de + as + | tem from TER +à | a + a +seu | his +sua | her +ou | or + | ser from SER +quando | when +muito | much + | há from HAV +nos | em + os; us +já | already, now + | está from EST +eu | I +também | also +só | only, just +pelo | per + o +pela | per + a +até | up to +isso | that +ela | he +entre | between + | era from SER +depois | after +sem | without +mesmo | same +aos | a + os + | ter from TER +seus | his +quem | whom +nas | em + as +me | me +esse | that +eles | they + | estão from EST +você | you + | tinha from TER + | foram from SER +essa | that +num | em + um +nem | nor +suas | her +meu | my +às | a + as +minha | my + | têm from TER +numa | em + uma +pelos | per + os +elas | they + | havia from HAV + | seja from SER +qual | which + | será from SER +nós | we + | tenho from TER +lhe | to him, her +deles | of them +essas | those +esses | those +pelas | per + as +este | this + | fosse from SER +dele | of him + + | other words. There are many contractions such as naquele = em+aquele, + | mo = me+o, but they are rare. + | Indefinite article plural forms are also rare. + +tu | thou +te | thee +vocês | you (plural) +vos | you +lhes | to them +meus | my +minhas +teu | thy +tua +teus +tuas +nosso | our +nossa +nossos +nossas + +dela | of her +delas | of them + +esta | this +estes | these +estas | these +aquele | that +aquela | that +aqueles | those +aquelas | those +isto | this +aquilo | that + + | forms of estar, to be (not including the infinitive): +estou +está +estamos +estão +estive +esteve +estivemos +estiveram +estava +estávamos +estavam +estivera +estivéramos +esteja +estejamos +estejam +estivesse +estivéssemos +estivessem +estiver +estivermos +estiverem + + | forms of haver, to have (not including the infinitive): +hei +há +havemos +hão +houve +houvemos +houveram +houvera +houvéramos +haja +hajamos +hajam +houvesse +houvéssemos +houvessem +houver +houvermos +houverem +houverei +houverá +houveremos +houverão +houveria +houveríamos +houveriam + + | forms of ser, to be (not including the infinitive): +sou +somos +são +era +éramos +eram +fui +foi +fomos +foram +fora +fôramos +seja +sejamos +sejam +fosse +fôssemos +fossem +for +formos +forem +serei +será +seremos +serão +seria +seríamos +seriam + + | forms of ter, to have (not including the infinitive): +tenho +tem +temos +tém +tinha +tínhamos +tinham +tive +teve +tivemos +tiveram +tivera +tivéramos +tenha +tenhamos +tenham +tivesse +tivéssemos +tivessem +tiver +tivermos +tiverem +terei +terá +teremos +terão +teria +teríamos +teriam diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ro.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ro.txt new file mode 100644 index 00000000000..4fdee90a5ba --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ro.txt @@ -0,0 +1,233 @@ +# This file was created by Jacques Savoy and is distributed under the BSD license. +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# Also see http://www.opensource.org/licenses/bsd-license.html +acea +aceasta +această +aceea +acei +aceia +acel +acela +acele +acelea +acest +acesta +aceste +acestea +aceşti +aceştia +acolo +acum +ai +aia +aibă +aici +al +ăla +ale +alea +ălea +altceva +altcineva +am +ar +are +aş +aşadar +asemenea +asta +ăsta +astăzi +astea +ăstea +ăştia +asupra +aţi +au +avea +avem +aveţi +azi +bine +bucur +bună +ca +că +căci +când +care +cărei +căror +cărui +cât +câte +câţi +către +câtva +ce +cel +ceva +chiar +cînd +cine +cineva +cît +cîte +cîţi +cîtva +contra +cu +cum +cumva +curând +curînd +da +dă +dacă +dar +datorită +de +deci +deja +deoarece +departe +deşi +din +dinaintea +dintr +dintre +drept +după +ea +ei +el +ele +eram +este +eşti +eu +face +fără +fi +fie +fiecare +fii +fim +fiţi +iar +ieri +îi +îl +îmi +împotriva +în +înainte +înaintea +încât +încît +încotro +între +întrucât +întrucît +îţi +la +lângă +le +li +lîngă +lor +lui +mă +mâine +mea +mei +mele +mereu +meu +mi +mine +mult +multă +mulţi +ne +nicăieri +nici +nimeni +nişte +noastră +noastre +noi +noştri +nostru +nu +ori +oricând +oricare +oricât +orice +oricînd +oricine +oricît +oricum +oriunde +până +pe +pentru +peste +pînă +poate +pot +prea +prima +primul +prin +printr +sa +să +săi +sale +sau +său +se +şi +sînt +sîntem +sînteţi +spre +sub +sunt +suntem +sunteţi +ta +tăi +tale +tău +te +ţi +ţie +tine +toată +toate +tot +toţi +totuşi +tu +un +una +unde +undeva +unei +unele +uneori +unor +vă +vi +voastră +voastre +voi +voştri +vostru +vouă +vreo +vreun diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ru.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ru.txt new file mode 100644 index 00000000000..64307693457 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ru.txt @@ -0,0 +1,241 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/russian/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | a russian stop word list. comments begin with vertical bar. each stop + | word is at the start of a line. + + | this is a ranked list (commonest to rarest) of stopwords derived from + | a large text sample. + + | letter `ё' is translated to `е'. + +и | and +в | in/into +во | alternative form +не | not +что | what/that +он | he +на | on/onto +я | i +с | from +со | alternative form +как | how +а | milder form of `no' (but) +то | conjunction and form of `that' +все | all +она | she +так | so, thus +его | him +но | but +да | yes/and +ты | thou +к | towards, by +у | around, chez +же | intensifier particle +вы | you +за | beyond, behind +бы | conditional/subj. particle +по | up to, along +только | only +ее | her +мне | to me +было | it was +вот | here is/are, particle +от | away from +меня | me +еще | still, yet, more +нет | no, there isnt/arent +о | about +из | out of +ему | to him +теперь | now +когда | when +даже | even +ну | so, well +вдруг | suddenly +ли | interrogative particle +если | if +уже | already, but homonym of `narrower' +или | or +ни | neither +быть | to be +был | he was +него | prepositional form of его +до | up to +вас | you accusative +нибудь | indef. suffix preceded by hyphen +опять | again +уж | already, but homonym of `adder' +вам | to you +сказал | he said +ведь | particle `after all' +там | there +потом | then +себя | oneself +ничего | nothing +ей | to her +может | usually with `быть' as `maybe' +они | they +тут | here +где | where +есть | there is/are +надо | got to, must +ней | prepositional form of ей +для | for +мы | we +тебя | thee +их | them, their +чем | than +была | she was +сам | self +чтоб | in order to +без | without +будто | as if +человек | man, person, one +чего | genitive form of `what' +раз | once +тоже | also +себе | to oneself +под | beneath +жизнь | life +будет | will be +ж | short form of intensifer particle `же' +тогда | then +кто | who +этот | this +говорил | was saying +того | genitive form of `that' +потому | for that reason +этого | genitive form of `this' +какой | which +совсем | altogether +ним | prepositional form of `его', `они' +здесь | here +этом | prepositional form of `этот' +один | one +почти | almost +мой | my +тем | instrumental/dative plural of `тот', `то' +чтобы | full form of `in order that' +нее | her (acc.) +кажется | it seems +сейчас | now +были | they were +куда | where to +зачем | why +сказать | to say +всех | all (acc., gen. preposn. plural) +никогда | never +сегодня | today +можно | possible, one can +при | by +наконец | finally +два | two +об | alternative form of `о', about +другой | another +хоть | even +после | after +над | above +больше | more +тот | that one (masc.) +через | across, in +эти | these +нас | us +про | about +всего | in all, only, of all +них | prepositional form of `они' (they) +какая | which, feminine +много | lots +разве | interrogative particle +сказала | she said +три | three +эту | this, acc. fem. sing. +моя | my, feminine +впрочем | moreover, besides +хорошо | good +свою | ones own, acc. fem. sing. +этой | oblique form of `эта', fem. `this' +перед | in front of +иногда | sometimes +лучше | better +чуть | a little +том | preposn. form of `that one' +нельзя | one must not +такой | such a one +им | to them +более | more +всегда | always +конечно | of course +всю | acc. fem. sing of `all' +между | between + + + | b: some paradigms + | + | personal pronouns + | + | я меня мне мной [мною] + | ты тебя тебе тобой [тобою] + | он его ему им [него, нему, ним] + | она ее эи ею [нее, нэи, нею] + | оно его ему им [него, нему, ним] + | + | мы нас нам нами + | вы вас вам вами + | они их им ими [них, ним, ними] + | + | себя себе собой [собою] + | + | demonstrative pronouns: этот (this), тот (that) + | + | этот эта это эти + | этого эты это эти + | этого этой этого этих + | этому этой этому этим + | этим этой этим [этою] этими + | этом этой этом этих + | + | тот та то те + | того ту то те + | того той того тех + | тому той тому тем + | тем той тем [тою] теми + | том той том тех + | + | determinative pronouns + | + | (a) весь (all) + | + | весь вся все все + | всего всю все все + | всего всей всего всех + | всему всей всему всем + | всем всей всем [всею] всеми + | всем всей всем всех + | + | (b) сам (himself etc) + | + | сам сама само сами + | самого саму само самих + | самого самой самого самих + | самому самой самому самим + | самим самой самим [самою] самими + | самом самой самом самих + | + | stems of verbs `to be', `to have', `to do' and modal + | + | быть бы буд быв есть суть + | име + | дел + | мог мож мочь + | уме + | хоч хот + | долж + | можн + | нужн + | нельзя + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_sv.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_sv.txt new file mode 100644 index 00000000000..22bddfd8cb3 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_sv.txt @@ -0,0 +1,131 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/swedish/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Swedish stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | This is a ranked list (commonest to rarest) of stopwords derived from + | a large text sample. + + | Swedish stop words occasionally exhibit homonym clashes. For example + | så = so, but also seed. These are indicated clearly below. + +och | and +det | it, this/that +att | to (with infinitive) +i | in, at +en | a +jag | I +hon | she +som | who, that +han | he +på | on +den | it, this/that +med | with +var | where, each +sig | him(self) etc +för | for +så | so (also: seed) +till | to +är | is +men | but +ett | a +om | if; around, about +hade | had +de | they, these/those +av | of +icke | not, no +mig | me +du | you +henne | her +då | then, when +sin | his +nu | now +har | have +inte | inte någon = no one +hans | his +honom | him +skulle | 'sake' +hennes | her +där | there +min | my +man | one (pronoun) +ej | nor +vid | at, by, on (also: vast) +kunde | could +något | some etc +från | from, off +ut | out +när | when +efter | after, behind +upp | up +vi | we +dem | them +vara | be +vad | what +över | over +än | than +dig | you +kan | can +sina | his +här | here +ha | have +mot | towards +alla | all +under | under (also: wonder) +någon | some etc +eller | or (else) +allt | all +mycket | much +sedan | since +ju | why +denna | this/that +själv | myself, yourself etc +detta | this/that +åt | to +utan | without +varit | was +hur | how +ingen | no +mitt | my +ni | you +bli | to be, become +blev | from bli +oss | us +din | thy +dessa | these/those +några | some etc +deras | their +blir | from bli +mina | my +samma | (the) same +vilken | who, that +er | you, your +sådan | such a +vår | our +blivit | from bli +dess | its +inom | within +mellan | between +sådant | such a +varför | why +varje | each +vilka | who, that +ditt | thy +vem | who +vilket | who, that +sitta | his +sådana | such a +vart | each +dina | thy +vars | whose +vårt | our +våra | our +ert | your +era | your +vilkas | whose + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_th.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_th.txt new file mode 100644 index 00000000000..07f0fabe692 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_th.txt @@ -0,0 +1,119 @@ +# Thai stopwords from: +# "Opinion Detection in Thai Political News Columns +# Based on Subjectivity Analysis" +# Khampol Sukhum, Supot Nitsuwat, and Choochart Haruechaiyasak +ไว้ +ไม่ +ไป +ได้ +ให้ +ใน +โดย +แห่ง +แล้ว +และ +แรก +แบบ +แต่ +เอง +เห็น +เลย +เริ่ม +เรา +เมื่อ +เพื่อ +เพราะ +เป็นการ +เป็น +เปิดเผย +เปิด +เนื่องจาก +เดียวกัน +เดียว +เช่น +เฉพาะ +เคย +เข้า +เขา +อีก +อาจ +อะไร +ออก +อย่าง +อยู่ +อยาก +หาก +หลาย +หลังจาก +หลัง +หรือ +หนึ่ง +ส่วน +ส่ง +สุด +สําหรับ +ว่า +วัน +ลง +ร่วม +ราย +รับ +ระหว่าง +รวม +ยัง +มี +มาก +มา +พร้อม +พบ +ผ่าน +ผล +บาง +น่า +นี้ +นํา +นั้น +นัก +นอกจาก +ทุก +ที่สุด +ที่ +ทําให้ +ทํา +ทาง +ทั้งนี้ +ทั้ง +ถ้า +ถูก +ถึง +ต้อง +ต่างๆ +ต่าง +ต่อ +ตาม +ตั้งแต่ +ตั้ง +ด้าน +ด้วย +ดัง +ซึ่ง +ช่วง +จึง +จาก +จัด +จะ +คือ +ความ +ครั้ง +คง +ขึ้น +ของ +ขอ +ขณะ +ก่อน +ก็ +การ +กับ +กัน +กว่า +กล่าว diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_tr.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_tr.txt new file mode 100644 index 00000000000..84d9408d4ea --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_tr.txt @@ -0,0 +1,212 @@ +# Turkish stopwords from LUCENE-559 +# merged with the list from "Information Retrieval on Turkish Texts" +# (http://www.users.muohio.edu/canf/papers/JASIST2008offPrint.pdf) +acaba +altmış +altı +ama +ancak +arada +aslında +ayrıca +bana +bazı +belki +ben +benden +beni +benim +beri +beş +bile +bin +bir +birçok +biri +birkaç +birkez +birşey +birşeyi +biz +bize +bizden +bizi +bizim +böyle +böylece +bu +buna +bunda +bundan +bunlar +bunları +bunların +bunu +bunun +burada +çok +çünkü +da +daha +dahi +de +defa +değil +diğer +diye +doksan +dokuz +dolayı +dolayısıyla +dört +edecek +eden +ederek +edilecek +ediliyor +edilmesi +ediyor +eğer +elli +en +etmesi +etti +ettiği +ettiğini +gibi +göre +halen +hangi +hatta +hem +henüz +hep +hepsi +her +herhangi +herkesin +hiç +hiçbir +için +iki +ile +ilgili +ise +işte +itibaren +itibariyle +kadar +karşın +katrilyon +kendi +kendilerine +kendini +kendisi +kendisine +kendisini +kez +ki +kim +kimden +kime +kimi +kimse +kırk +milyar +milyon +mu +mü +mı +nasıl +ne +neden +nedenle +nerde +nerede +nereye +niye +niçin +o +olan +olarak +oldu +olduğu +olduğunu +olduklarını +olmadı +olmadığı +olmak +olması +olmayan +olmaz +olsa +olsun +olup +olur +olursa +oluyor +on +ona +ondan +onlar +onlardan +onları +onların +onu +onun +otuz +oysa +öyle +pek +rağmen +sadece +sanki +sekiz +seksen +sen +senden +seni +senin +siz +sizden +sizi +sizin +şey +şeyden +şeyi +şeyler +şöyle +şu +şuna +şunda +şundan +şunları +şunu +tarafından +trilyon +tüm +üç +üzere +var +vardı +ve +veya +ya +yani +yapacak +yapılan +yapılması +yapıyor +yapmak +yaptı +yaptığı +yaptığını +yaptıkları +yedi +yerine +yetmiş +yine +yirmi +yoksa +yüz +zaten diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/userdict_ja.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/userdict_ja.txt new file mode 100644 index 00000000000..6f0368e4d81 --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/userdict_ja.txt @@ -0,0 +1,29 @@ +# +# This is a sample user dictionary for Kuromoji (JapaneseTokenizer) +# +# Add entries to this file in order to override the statistical model in terms +# of segmentation, readings and part-of-speech tags. Notice that entries do +# not have weights since they are always used when found. This is by-design +# in order to maximize ease-of-use. +# +# Entries are defined using the following CSV format: +# , ... , ... , +# +# Notice that a single half-width space separates tokens and readings, and +# that the number tokens and readings must match exactly. +# +# Also notice that multiple entries with the same is undefined. +# +# Whitespace only lines are ignored. Comments are not allowed on entry lines. +# + +# Custom segmentation for kanji compounds +日本経済新聞,日本 経済 新聞,ニホン ケイザイ シンブン,カスタム名詞 +関西国際空港,関西 国際 空港,カンサイ コクサイ クウコウ,カスタム名詞 + +# Custom segmentation for compound katakana +トートバッグ,トート バッグ,トート バッグ,かずカナ名詞 +ショルダーバッグ,ショルダー バッグ,ショルダー バッグ,かずカナ名詞 + +# Custom reading for former sumo wrestler +朝青龍,朝青龍,アサショウリュウ,カスタム人名 diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/protwords.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/protwords.txt new file mode 100644 index 00000000000..1dfc0abecbf --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/protwords.txt @@ -0,0 +1,21 @@ +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#----------------------------------------------------------------------- +# Use a protected word file to protect against the stemmer reducing two +# unrelated words to the same base word. + +# Some non-words that normally won't be encountered, +# just to test that they won't be stemmed. +dontstems +zwhacky + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/schema.xml b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/schema.xml new file mode 100644 index 00000000000..83080dfa40c --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/schema.xml @@ -0,0 +1,914 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + id + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/solrconfig.xml b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/solrconfig.xml new file mode 100644 index 00000000000..9d9178746cf --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/solrconfig.xml @@ -0,0 +1,1764 @@ + + + + + + + + + LUCENE_43 + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${solr.data.dir:} + + + + + + + + + + + + + + + + ${solr.maxIndexingThreads:8} + + + + + + 128 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${solr.ulog.dir:} + + + + + ${solr.autoCommit.maxTime:60000} + false + + + + + + ${solr.autoSoftCommit.maxTime:1000} + + + + + + + + + + + + + + + + + + + + 1024 + + + + + + + + + + + + + + + + + + + + + + true + + + + + + 20 + + + 200 + + + + + + + + + + + + static firstSearcher warming in solrconfig.xml + + + + + + false + + + 4 + + + + + + + + + + + + + + + + + + + + + + + explicit + 10 + text + + + + + + + + + + + + + + explicit + json + true + text + + + + + + + + true + json + true + + + + + + + + explicit + + + velocity + browse + layout + Solritas + + + edismax + + text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 + title^10.0 description^5.0 keywords^5.0 author^2.0 resourcename^1.0 + + text + 100% + *:* + 10 + *,score + + + text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 + title^10.0 description^5.0 keywords^5.0 author^2.0 resourcename^1.0 + + text,features,name,sku,id,manu,cat,title,description,keywords,author,resourcename + 3 + + + on + cat + manu_exact + content_type + author_s + ipod + GB + 1 + cat,inStock + after + price + 0 + 600 + 50 + popularity + 0 + 10 + 3 + manufacturedate_dt + NOW/YEAR-10YEARS + NOW + +1YEAR + before + after + + + on + content features title name + html + <b> + </b> + 0 + title + 0 + name + 3 + 200 + content + 750 + + + on + false + 5 + 2 + 5 + true + true + 5 + 3 + + + + + spellcheck + + + + + + + + + + + + + + application/json + + + + + application/csv + + + + + + + + + + + + + + + + + + + + + solrpingquery + + + all + + + + + + + + + explicit + true + + + + + + + + + + + + + + + + textSpell + + + + + + default + name + solr.DirectSolrSpellChecker + + internal + + 0.5 + + 2 + + 1 + + 5 + + 4 + + 0.01 + + + + + + wordbreak + solr.WordBreakSolrSpellChecker + name + true + true + 10 + + + + + + + + + + + + + + + + text + + default + wordbreak + on + true + 10 + 5 + 5 + true + true + 10 + 5 + + + spellcheck + + + + + + + + + + text + true + + + tvComponent + + + + + + + + + default + + + org.carrot2.clustering.lingo.LingoClusteringAlgorithm + + + 20 + + + clustering/carrot2 + + + ENGLISH + + + stc + org.carrot2.clustering.stc.STCClusteringAlgorithm + + + + + + + true + default + true + + name + id + + features + + true + + + + false + + edismax + + text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 + + *:* + 10 + *,score + + + clustering + + + + + + + + + + true + + + terms + + + + + + + + string + elevate.xml + + + + + + explicit + text + + + elevator + + + + + + + + + + + 100 + + + + + + + + 70 + + 0.5 + + [-\w ,/\n\"']{20,200} + + + + + + + ]]> + ]]> + + + + + + + + + + + + + + + + + + + + + + + + ,, + ,, + ,, + ,, + ,]]> + ]]> + + + + + + 10 + .,!? + + + + + + + WORD + + + en + US + + + + + + + + + + + + + + + + + + + + + + text/plain; charset=UTF-8 + + + + + + + + + 5 + + + + + + + + + + + + + + + + + + *:* + + + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/stopwords.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/stopwords.txt new file mode 100644 index 00000000000..ae1e83eeb3d --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/stopwords.txt @@ -0,0 +1,14 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/synonyms.txt b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/synonyms.txt new file mode 100644 index 00000000000..7f72128303b --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/synonyms.txt @@ -0,0 +1,29 @@ +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#----------------------------------------------------------------------- +#some test synonym mappings unlikely to appear in real input text +aaafoo => aaabar +bbbfoo => bbbfoo bbbbar +cccfoo => cccbar cccbaz +fooaaa,baraaa,bazaaa + +# Some synonym groups specific to this example +GB,gib,gigabyte,gigabytes +MB,mib,megabyte,megabytes +Television, Televisions, TV, TVs +#notice we use "gib" instead of "GiB" so any WordDelimiterFilter coming +#after us won't split it into two words. + +# Synonym mappings can be used for spelling correction too +pixima => pixma + diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcloud/conf/solrconfig.xml b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcloud/conf/solrconfig.xml new file mode 100644 index 00000000000..a37ab12ecfe --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcloud/conf/solrconfig.xml @@ -0,0 +1,1787 @@ + + + + + + + + + LUCENE_43 + + + + + + + + + + + + + + + + + + + + + + + + ${solr.data.dir:} + + + + + ${solr.hdfs.home:} + ${solr.hdfs.confdir:} + ${solr.hdfs.security.kerberos.enabled:false} + ${solr.hdfs.security.kerberos.keytabfile:} + ${solr.hdfs.security.kerberos.principal:} + ${solr.hdfs.blockcache.enabled:true} + ${solr.hdfs.blockcache.slab.count:1} + ${solr.hdfs.blockcache.direct.memory.allocation:true} + ${solr.hdfs.blockcache.blocksperbank:16384} + ${solr.hdfs.blockcache.read.enabled:true} + ${solr.hdfs.blockcache.write.enabled:true} + ${solr.hdfs.nrtcachingdirectory.enable:true} + ${solr.hdfs.nrtcachingdirectory.maxmergesizemb:16} + ${solr.hdfs.nrtcachingdirectory.maxcachedmb:192} + + + + + + + + + + + + + ${solr.maxIndexingThreads:8} + + + + + + 128 + + + + + + + + + + + + + ${solr.lock.type:hdfs} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${solr.ulog.dir:} + + + + + ${solr.autoCommit.maxTime:60000} + false + + + + + ${solr.autoSoftCommit.maxTime:1000} + + + + + + + + + + + + + + + + + + + 1024 + + + + + + + + + + + + + + + + + + + + + + true + + + + + + 20 + + + 200 + + + + + + + + + + + + static firstSearcher warming in solrconfig.xml + + + + + + false + + + 4 + + + + + + + + + + + + + + + + + + + + + + + explicit + 10 + text + + + + + + + + + + + + + + explicit + json + true + text + + + + + + + + true + json + true + + + + + + + + explicit + + + velocity + browse + layout + Solritas + + + edismax + + text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 + title^10.0 description^5.0 keywords^5.0 author^2.0 resourcename^1.0 + + text + 100% + *:* + 10 + *,score + + + text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 + title^10.0 description^5.0 keywords^5.0 author^2.0 resourcename^1.0 + + text,features,name,sku,id,manu,cat,title,description,keywords,author,resourcename + 3 + + + on + cat + manu_exact + content_type + author_s + ipod + GB + 1 + cat,inStock + after + price + 0 + 600 + 50 + popularity + 0 + 10 + 3 + manufacturedate_dt + NOW/YEAR-10YEARS + NOW + +1YEAR + before + after + + + on + content features title name + html + <b> + </b> + 0 + title + 0 + name + 3 + 200 + content + 750 + + + on + false + 5 + 2 + 5 + true + true + 5 + 3 + + + + + spellcheck + + + + + + + + + + + + + + application/json + + + + + application/csv + + + + + + + + + + + + + + + + + + + + + solrpingquery + + + all + + + + + + + + + explicit + true + + + + + + + + + + + + + + + + text_general + + + + + + default + text + solr.DirectSolrSpellChecker + + internal + + 0.5 + + 2 + + 1 + + 5 + + 4 + + 0.01 + + + + + + wordbreak + solr.WordBreakSolrSpellChecker + name + true + true + 10 + + + + + + + + + + + + + + + + text + + default + wordbreak + on + true + 10 + 5 + 5 + true + true + 10 + 5 + + + spellcheck + + + + + + + + + + text + true + + + tvComponent + + + + + + + + + default + + + org.carrot2.clustering.lingo.LingoClusteringAlgorithm + + + 20 + + + clustering/carrot2 + + + ENGLISH + + + stc + org.carrot2.clustering.stc.STCClusteringAlgorithm + + + + + + + true + default + true + + name + id + + features + + true + + + + false + + edismax + + text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 + + *:* + 10 + *,score + + + clustering + + + + + + + + + + true + false + + + terms + + + + + + + + string + elevate.xml + + + + + + explicit + text + + + elevator + + + + + + + + + + + 100 + + + + + + + + 70 + + 0.5 + + [-\w ,/\n\"']{20,200} + + + + + + + ]]> + ]]> + + + + + + + + + + + + + + + + + + + + + + + + ,, + ,, + ,, + ,, + ,]]> + ]]> + + + + + + 10 + .,!? + + + + + + + WORD + + + en + US + + + + + + + + + + + + + + + + + + + + + + text/plain; charset=UTF-8 + + + + + + + + + 5 + + + + + + + + + + + + + + + + + + *:* + + + diff --git a/solr/contrib/solr-morphlines-cell/src/test/org/apache/solr/morphlines/cell/SolrCellMorphlineTest.java b/solr/contrib/solr-morphlines-cell/src/test/org/apache/solr/morphlines/cell/SolrCellMorphlineTest.java new file mode 100644 index 00000000000..80d2d43499c --- /dev/null +++ b/solr/contrib/solr-morphlines-cell/src/test/org/apache/solr/morphlines/cell/SolrCellMorphlineTest.java @@ -0,0 +1,208 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.morphlines.cell; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.io.FileUtils; +import org.apache.solr.common.SolrInputDocument; +import org.apache.solr.common.params.MapSolrParams; +import org.apache.solr.common.util.DateUtil; +import org.apache.solr.handler.extraction.SolrContentHandler; +import org.apache.solr.morphlines.solr.AbstractSolrMorphlineTestBase; +import org.apache.solr.schema.IndexSchema; +import org.apache.tika.metadata.Metadata; +import org.junit.Before; +import org.junit.Test; + + +public class SolrCellMorphlineTest extends AbstractSolrMorphlineTestBase { + + private Map expectedRecords = new HashMap(); + + + @Before + public void setUp() throws Exception { + super.setUp(); + String path = RESOURCES_DIR + "/test-documents"; + expectedRecords.put(path + "/sample-statuses-20120906-141433.avro", 2); + expectedRecords.put(path + "/sample-statuses-20120906-141433", 2); + expectedRecords.put(path + "/sample-statuses-20120906-141433.gz", 2); + expectedRecords.put(path + "/sample-statuses-20120906-141433.bz2", 2); + expectedRecords.put(path + "/cars.csv", 5); + expectedRecords.put(path + "/cars.csv.gz", 5); + expectedRecords.put(path + "/cars.tar.gz", 4); + expectedRecords.put(path + "/cars.tsv", 5); + expectedRecords.put(path + "/cars.ssv", 5); + expectedRecords.put(path + "/test-documents.7z", 9); + expectedRecords.put(path + "/test-documents.cpio", 9); + expectedRecords.put(path + "/test-documents.tar", 9); + expectedRecords.put(path + "/test-documents.tbz2", 9); + expectedRecords.put(path + "/test-documents.tgz", 9); + expectedRecords.put(path + "/test-documents.zip", 9); + expectedRecords.put(path + "/multiline-stacktrace.log", 4); + + FileUtils.copyFile(new File(RESOURCES_DIR + "/custom-mimetypes.xml"), new File(tempDir + "/custom-mimetypes.xml")); + } + + @Test + public void testSolrCellJPGCompressed() throws Exception { + + morphline = createMorphline("test-morphlines/solrCellJPGCompressed"); + String path = RESOURCES_DIR + "/test-documents"; + String[] files = new String[] { + path + "/testJPEG_EXIF.jpg", + path + "/testJPEG_EXIF.jpg.gz", + path + "/testJPEG_EXIF.jpg.tar.gz", + //path + "/jpeg2000.jp2", + }; + testDocumentTypesInternal(files, expectedRecords); + } + + @Test + public void testSolrCellXML() throws Exception { + morphline = createMorphline("test-morphlines/solrCellXML"); + String path = RESOURCES_DIR + "/test-documents"; + String[] files = new String[] { + path + "/testXML2.xml", + }; + testDocumentTypesInternal(files, expectedRecords); + } + + @Test + public void testSolrCellDocumentTypes() throws Exception { + + morphline = createMorphline("test-morphlines/solrCellDocumentTypes"); + String path = RESOURCES_DIR + "/test-documents"; + String[] files = new String[] { + path + "/testBMPfp.txt", + path + "/boilerplate.html", + path + "/NullHeader.docx", + path + "/testWORD_various.doc", + path + "/testPDF.pdf", + path + "/testJPEG_EXIF.jpg", + path + "/testJPEG_EXIF.jpg.gz", + path + "/testJPEG_EXIF.jpg.tar.gz", + path + "/testXML.xml", +// path + "/cars.csv", +// path + "/cars.tsv", +// path + "/cars.ssv", +// path + "/cars.csv.gz", +// path + "/cars.tar.gz", + path + "/sample-statuses-20120906-141433.avro", + path + "/sample-statuses-20120906-141433", + path + "/sample-statuses-20120906-141433.gz", + path + "/sample-statuses-20120906-141433.bz2", + }; + testDocumentTypesInternal(files, expectedRecords); + } + + @Test + public void testSolrCellDocumentTypes2() throws Exception { + morphline = createMorphline("test-morphlines/solrCellDocumentTypes"); + String path = RESOURCES_DIR + "/test-documents"; + String[] files = new String[] { + path + "/testPPT_various.ppt", + path + "/testPPT_various.pptx", + path + "/testEXCEL.xlsx", + path + "/testEXCEL.xls", + path + "/testPages.pages", + //path + "/testNumbers.numbers", + //path + "/testKeynote.key", + + path + "/testRTFVarious.rtf", + path + "/complex.mbox", + path + "/test-outlook.msg", + path + "/testEMLX.emlx", +// path + "/testRFC822", + path + "/rsstest.rss", +// path + "/testDITA.dita", + + path + "/testMP3i18n.mp3", + path + "/testAIFF.aif", + path + "/testFLAC.flac", +// path + "/testFLAC.oga", +// path + "/testVORBIS.ogg", + path + "/testMP4.m4a", + path + "/testWAV.wav", +// path + "/testWMA.wma", + + path + "/testFLV.flv", +// path + "/testWMV.wmv", + + path + "/testBMP.bmp", + path + "/testPNG.png", + path + "/testPSD.psd", + path + "/testSVG.svg", + path + "/testTIFF.tif", + +// path + "/test-documents.7z", +// path + "/test-documents.cpio", +// path + "/test-documents.tar", +// path + "/test-documents.tbz2", +// path + "/test-documents.tgz", +// path + "/test-documents.zip", +// path + "/test-zip-of-zip.zip", +// path + "/testJAR.jar", + +// path + "/testKML.kml", +// path + "/testRDF.rdf", + path + "/testVISIO.vsd", +// path + "/testWAR.war", +// path + "/testWindows-x86-32.exe", +// path + "/testWINMAIL.dat", +// path + "/testWMF.wmf", + }; + testDocumentTypesInternal(files, expectedRecords); + } + + /** + * Test that the ContentHandler properly strips the illegal characters + */ + @Test + public void testTransformValue() { + String fieldName = "user_name"; + assertFalse("foobar".equals(getFoobarWithNonChars())); + + Metadata metadata = new Metadata(); + // load illegal char string into a metadata field and generate a new document, + // which will cause the ContentHandler to be invoked. + metadata.set(fieldName, getFoobarWithNonChars()); + StripNonCharSolrContentHandlerFactory contentHandlerFactory = + new StripNonCharSolrContentHandlerFactory(DateUtil.DEFAULT_DATE_FORMATS); + IndexSchema schema = h.getCore().getLatestSchema(); + SolrContentHandler contentHandler = + contentHandlerFactory.createSolrContentHandler(metadata, new MapSolrParams(new HashMap()), schema); + SolrInputDocument doc = contentHandler.newDocument(); + String foobar = doc.getFieldValue(fieldName).toString(); + assertTrue("foobar".equals(foobar)); + } + + /** + * Returns string "foobar" with illegal characters interspersed. + */ + private String getFoobarWithNonChars() { + char illegalChar = '\uffff'; + StringBuilder builder = new StringBuilder(); + builder.append(illegalChar).append(illegalChar).append("foo").append(illegalChar) + .append(illegalChar).append("bar").append(illegalChar).append(illegalChar); + return builder.toString(); + } + +} diff --git a/solr/contrib/solr-morphlines-core/build.xml b/solr/contrib/solr-morphlines-core/build.xml new file mode 100644 index 00000000000..ad11be1226c --- /dev/null +++ b/solr/contrib/solr-morphlines-core/build.xml @@ -0,0 +1,107 @@ + + + + + + + + Solr Morphlines commands. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/ivy.xml b/solr/contrib/solr-morphlines-core/ivy.xml new file mode 100644 index 00000000000..290460d27cb --- /dev/null +++ b/solr/contrib/solr-morphlines-core/ivy.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/DocumentLoader.java b/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/DocumentLoader.java new file mode 100644 index 00000000000..f3030247065 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/DocumentLoader.java @@ -0,0 +1,73 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.morphlines.solr; + +import java.io.IOException; + +import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.client.solrj.response.SolrPingResponse; +import org.apache.solr.client.solrj.response.UpdateResponse; +import org.apache.solr.common.SolrInputDocument; + +/** + * A vehicle to load a list of Solr documents into some kind of destination, + * such as a SolrServer or MapReduce RecordWriter. + */ +public interface DocumentLoader { + + /** Begins a transaction */ + public void beginTransaction() throws IOException, SolrServerException; + + /** Loads the given document into the destination */ + public void load(SolrInputDocument doc) throws IOException, SolrServerException; + + /** + * Sends any outstanding documents to the destination and waits for a positive + * or negative ack (i.e. exception). Depending on the outcome the caller + * should then commit or rollback the current flume transaction + * correspondingly. + * + * @throws IOException + * If there is a low-level I/O error. + */ + public void commitTransaction() throws IOException, SolrServerException; + + /** + * Performs a rollback of all non-committed documents pending. + *

    + * Note that this is not a true rollback as in databases. Content you have + * previously added may have already been committed due to autoCommit, buffer + * full, other client performing a commit etc. So this is only a best-effort + * rollback. + * + * @throws IOException + * If there is a low-level I/O error. + */ + public UpdateResponse rollbackTransaction() throws IOException, SolrServerException; + + /** Releases allocated resources */ + public void shutdown() throws IOException, SolrServerException; + + /** + * Issues a ping request to check if the server is alive + * + * @throws IOException + * If there is a low-level I/O error. + */ + public SolrPingResponse ping() throws IOException, SolrServerException; + +} diff --git a/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/GenerateSolrSequenceKeyBuilder.java b/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/GenerateSolrSequenceKeyBuilder.java new file mode 100644 index 00000000000..251d016634c --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/GenerateSolrSequenceKeyBuilder.java @@ -0,0 +1,143 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.morphlines.solr; + +import java.security.SecureRandom; +import java.util.Arrays; +import java.util.Collection; +import java.util.Random; + +import org.apache.solr.schema.IndexSchema; +import org.apache.solr.schema.SchemaField; + +import com.cloudera.cdk.morphline.api.Command; +import com.cloudera.cdk.morphline.api.CommandBuilder; +import com.cloudera.cdk.morphline.api.MorphlineContext; +import com.cloudera.cdk.morphline.api.MorphlineRuntimeException; +import com.cloudera.cdk.morphline.api.Record; +import com.cloudera.cdk.morphline.base.AbstractCommand; +import com.cloudera.cdk.morphline.base.Fields; +import com.cloudera.cdk.morphline.base.Notifications; +import com.typesafe.config.Config; + +/** + * A command that assigns a record unique key that is the concatenation of the given + * baseIdField record field, followed by a running count of the record number within + * the current session. The count is reset to zero whenever a "startSession" notification is + * received. + *

    + * For example, assume a CSV file containing multiple records but no unique ids, and the + * baseIdField field is the filesystem path of the file. Now this command can be used + * to assign the following record values to Solr's unique key field: + * $path#0, $path#1, ... $path#N. + *

    + * The name of the unique key field is fetched from Solr's schema.xml file, as directed by the + * solrLocator configuration parameter. + */ +public final class GenerateSolrSequenceKeyBuilder implements CommandBuilder { + + @Override + public Collection getNames() { + return Arrays.asList( + "generateSolrSequenceKey", + "sanitizeUniqueSolrKey" // old name (retained for backwards compatibility) + ); + } + + @Override + public Command build(Config config, Command parent, Command child, MorphlineContext context) { + return new GenerateSolrSequenceKey(config, parent, child, context); + } + + + /////////////////////////////////////////////////////////////////////////////// + // Nested classes: + /////////////////////////////////////////////////////////////////////////////// + private static final class GenerateSolrSequenceKey extends AbstractCommand { + + private final boolean preserveExisting; + private final String baseIdFieldName; + private final String uniqueKeyName; + private long recordCounter = 0; + + private final String idPrefix; // for load testing only; enables adding same document many times with a different unique key + private final Random randomIdPrefix; // for load testing only; enables adding same document many times with a different unique key + + public GenerateSolrSequenceKey(Config config, Command parent, Command child, MorphlineContext context) { + super(config, parent, child, context); + this.baseIdFieldName = getConfigs().getString(config, "baseIdField", Fields.BASE_ID); + this.preserveExisting = getConfigs().getBoolean(config, "preserveExisting", true); + + Config solrLocatorConfig = getConfigs().getConfig(config, "solrLocator"); + SolrLocator locator = new SolrLocator(solrLocatorConfig, context); + LOG.debug("solrLocator: {}", locator); + IndexSchema schema = locator.getIndexSchema(); + SchemaField uniqueKey = schema.getUniqueKeyField(); + uniqueKeyName = uniqueKey == null ? null : uniqueKey.getName(); + + String tmpIdPrefix = getConfigs().getString(config, "idPrefix", null); // for load testing only + Random tmpRandomIdPrefx = null; + if ("random".equals(tmpIdPrefix)) { // for load testing only + tmpRandomIdPrefx = new Random(new SecureRandom().nextLong()); + tmpIdPrefix = null; + } + idPrefix = tmpIdPrefix; + randomIdPrefix = tmpRandomIdPrefx; + validateArguments(); + } + + @Override + protected boolean doProcess(Record doc) { + long num = recordCounter++; + // LOG.debug("record #{} id before sanitizing doc: {}", num, doc); + if (uniqueKeyName == null || (preserveExisting && doc.getFields().containsKey(uniqueKeyName))) { + ; // we must preserve the existing id + } else { + Object baseId = doc.getFirstValue(baseIdFieldName); + if (baseId == null) { + throw new MorphlineRuntimeException("Record field " + baseIdFieldName + + " must not be null as it is needed as a basis for a unique key for solr doc: " + doc); + } + doc.replaceValues(uniqueKeyName, baseId.toString() + "#" + num); + } + + // for load testing only; enables adding same document many times with a different unique key + if (idPrefix != null) { + String id = doc.getFirstValue(uniqueKeyName).toString(); + id = idPrefix + id; + doc.replaceValues(uniqueKeyName, id); + } else if (randomIdPrefix != null) { + String id = doc.getFirstValue(uniqueKeyName).toString(); + id = String.valueOf(Math.abs(randomIdPrefix.nextInt())) + "#" + id; + doc.replaceValues(uniqueKeyName, id); + } + + LOG.debug("record #{} unique key sanitized to this: {}", num, doc); + + return super.doProcess(doc); + } + + @Override + protected void doNotify(Record notification) { + if (Notifications.containsLifecycleEvent(notification, Notifications.LifecycleEvent.START_SESSION)) { + recordCounter = 0; // reset + } + super.doNotify(notification); + } + + } +} diff --git a/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/LoadSolrBuilder.java b/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/LoadSolrBuilder.java new file mode 100644 index 00000000000..019dfcf0f52 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/LoadSolrBuilder.java @@ -0,0 +1,162 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.morphlines.solr; + +import java.io.IOException; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.common.SolrInputDocument; + +import com.cloudera.cdk.morphline.api.Command; +import com.cloudera.cdk.morphline.api.CommandBuilder; +import com.cloudera.cdk.morphline.api.MorphlineContext; +import com.cloudera.cdk.morphline.api.MorphlineRuntimeException; +import com.cloudera.cdk.morphline.api.Record; +import com.cloudera.cdk.morphline.base.AbstractCommand; +import com.cloudera.cdk.morphline.base.Metrics; +import com.cloudera.cdk.morphline.base.Notifications; +import com.codahale.metrics.Timer; +import com.typesafe.config.Config; +import com.typesafe.config.ConfigFactory; + +/** + * A command that loads a record into a SolrServer or MapReduce SolrOutputFormat. + */ +public final class LoadSolrBuilder implements CommandBuilder { + + @Override + public Collection getNames() { + return Collections.singletonList("loadSolr"); + } + + @Override + public Command build(Config config, Command parent, Command child, MorphlineContext context) { + return new LoadSolr(config, parent, child, context); + } + + + /////////////////////////////////////////////////////////////////////////////// + // Nested classes: + /////////////////////////////////////////////////////////////////////////////// + private static final class LoadSolr extends AbstractCommand { + + private final DocumentLoader loader; + private final Map boosts = new HashMap(); + private final Timer elapsedTime; + + public LoadSolr(Config config, Command parent, Command child, MorphlineContext context) { + super(config, parent, child, context); + Config solrLocatorConfig = getConfigs().getConfig(config, "solrLocator"); + SolrLocator locator = new SolrLocator(solrLocatorConfig, context); + LOG.debug("solrLocator: {}", locator); + this.loader = locator.getLoader(); + Config boostsConfig = getConfigs().getConfig(config, "boosts", ConfigFactory.empty()); + for (Map.Entry entry : boostsConfig.root().unwrapped().entrySet()) { + String fieldName = entry.getKey(); + float boost = Float.parseFloat(entry.getValue().toString().trim()); + boosts.put(fieldName, boost); + } + validateArguments(); + this.elapsedTime = getTimer(Metrics.ELAPSED_TIME); + } + + @Override + protected void doNotify(Record notification) { + for (Object event : Notifications.getLifecycleEvents(notification)) { + if (event == Notifications.LifecycleEvent.BEGIN_TRANSACTION) { + try { + loader.beginTransaction(); + } catch (SolrServerException e) { + throw new MorphlineRuntimeException(e); + } catch (IOException e) { + throw new MorphlineRuntimeException(e); + } + } else if (event == Notifications.LifecycleEvent.COMMIT_TRANSACTION) { + try { + loader.commitTransaction(); + } catch (SolrServerException e) { + throw new MorphlineRuntimeException(e); + } catch (IOException e) { + throw new MorphlineRuntimeException(e); + } + } + else if (event == Notifications.LifecycleEvent.ROLLBACK_TRANSACTION) { + try { + loader.rollbackTransaction(); + } catch (SolrServerException e) { + throw new MorphlineRuntimeException(e); + } catch (IOException e) { + throw new MorphlineRuntimeException(e); + } + } + else if (event == Notifications.LifecycleEvent.SHUTDOWN) { + try { + loader.shutdown(); + } catch (SolrServerException e) { + throw new MorphlineRuntimeException(e); + } catch (IOException e) { + throw new MorphlineRuntimeException(e); + } + } + } + super.doNotify(notification); + } + + @Override + protected boolean doProcess(Record record) { + Timer.Context timerContext = elapsedTime.time(); + SolrInputDocument doc = convert(record); + try { + loader.load(doc); + } catch (IOException e) { + throw new MorphlineRuntimeException(e); + } catch (SolrServerException e) { + throw new MorphlineRuntimeException(e); + } finally { + timerContext.stop(); + } + + // pass record to next command in chain: + return super.doProcess(record); + } + + private SolrInputDocument convert(Record record) { + Map> map = record.getFields().asMap(); + SolrInputDocument doc = new SolrInputDocument(new HashMap(2 * map.size())); + for (Map.Entry> entry : map.entrySet()) { + String key = entry.getKey(); + doc.setField(key, entry.getValue(), getBoost(key)); + } + return doc; + } + + private float getBoost(String key) { + if (boosts.size() > 0) { + Float boost = boosts.get(key); + if (boost != null) { + return boost.floatValue(); + } + } + return 1.0f; + } + + } +} diff --git a/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/SafeConcurrentUpdateSolrServer.java b/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/SafeConcurrentUpdateSolrServer.java new file mode 100644 index 00000000000..f98eeb25016 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/SafeConcurrentUpdateSolrServer.java @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.morphlines.solr; + +import org.apache.http.client.HttpClient; +import org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrServer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * ConcurrentUpdateSolrServer that propagates exceptions up to the submitter of + * requests on blockUntilFinished() + */ +final class SafeConcurrentUpdateSolrServer extends ConcurrentUpdateSolrServer { + + private Throwable currentException = null; + private final Object myLock = new Object(); + + private static final Logger LOGGER = LoggerFactory.getLogger(SafeConcurrentUpdateSolrServer.class); + + public SafeConcurrentUpdateSolrServer(String solrServerUrl, int queueSize, int threadCount) { + this(solrServerUrl, null, queueSize, threadCount); + } + + public SafeConcurrentUpdateSolrServer(String solrServerUrl, HttpClient client, int queueSize, int threadCount) { + super(solrServerUrl, client, queueSize, threadCount); + } + + @Override + public void handleError(Throwable ex) { + assert ex != null; + synchronized (myLock) { + currentException = ex; + } + LOGGER.error("handleError", ex); + } + + @Override + public void blockUntilFinished() { + super.blockUntilFinished(); + synchronized (myLock) { + if (currentException != null) { + throw new RuntimeException(currentException); + } + } + } + + public void clearException() { + synchronized (myLock) { + currentException = null; + } + } + +} diff --git a/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/SanitizeUnknownSolrFieldsBuilder.java b/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/SanitizeUnknownSolrFieldsBuilder.java new file mode 100644 index 00000000000..fbc8de21bda --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/SanitizeUnknownSolrFieldsBuilder.java @@ -0,0 +1,98 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.morphlines.solr; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.TreeMap; + +import org.apache.solr.schema.IndexSchema; + +import com.cloudera.cdk.morphline.api.Command; +import com.cloudera.cdk.morphline.api.CommandBuilder; +import com.cloudera.cdk.morphline.api.MorphlineContext; +import com.cloudera.cdk.morphline.api.Record; +import com.cloudera.cdk.morphline.base.AbstractCommand; +import com.google.common.base.Joiner; +import com.google.common.base.Preconditions; +import com.typesafe.config.Config; + +/** + * Command that sanitizes record fields that are unknown to Solr schema.xml by either deleting them + * (renameToPrefix is absent or a zero length string), or by moving them to a field prefixed with + * the given renameToPrefix (e.g. renameToPrefix = "ignored_" to use typical dynamic Solr fields). + *

    + * Recall that Solr throws an exception on any attempt to load a document that contains a field that + * isn't specified in schema.xml. + */ +public final class SanitizeUnknownSolrFieldsBuilder implements CommandBuilder { + + @Override + public Collection getNames() { + return Collections.singletonList("sanitizeUnknownSolrFields"); + } + + @Override + public Command build(Config config, Command parent, Command child, MorphlineContext context) { + return new SanitizeUnknownSolrFields(config, parent, child, context); + } + + + /////////////////////////////////////////////////////////////////////////////// + // Nested classes: + /////////////////////////////////////////////////////////////////////////////// + private static final class SanitizeUnknownSolrFields extends AbstractCommand { + + private final IndexSchema schema; + private final String renameToPrefix; + + public SanitizeUnknownSolrFields(Config config, Command parent, Command child, MorphlineContext context) { + super(config, parent, child, context); + + Config solrLocatorConfig = getConfigs().getConfig(config, "solrLocator"); + SolrLocator locator = new SolrLocator(solrLocatorConfig, context); + LOG.debug("solrLocator: {}", locator); + this.schema = locator.getIndexSchema(); + Preconditions.checkNotNull(schema); + LOG.trace("Solr schema: \n{}", Joiner.on("\n").join(new TreeMap(schema.getFields()).values())); + + String str = getConfigs().getString(config, "renameToPrefix", "").trim(); + this.renameToPrefix = str.length() > 0 ? str : null; + validateArguments(); + } + + @Override + protected boolean doProcess(Record record) { + Collection entries = new ArrayList(record.getFields().asMap().entrySet()); + for (Map.Entry> entry : entries) { + String key = entry.getKey(); + if (schema.getFieldOrNull(key) == null) { + LOG.debug("Sanitizing unknown Solr field: {}", key); + Collection values = entry.getValue(); + if (renameToPrefix != null) { + record.getFields().putAll(renameToPrefix + key, values); + } + values.clear(); // implicitly removes key from record + } + } + return super.doProcess(record); + } + + } +} diff --git a/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/SolrLocator.java b/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/SolrLocator.java new file mode 100644 index 00000000000..2381a08b082 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/SolrLocator.java @@ -0,0 +1,270 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.morphlines.solr; + +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; + +import javax.xml.parsers.ParserConfigurationException; + +import org.apache.solr.client.solrj.SolrServer; +import org.apache.solr.client.solrj.impl.CloudSolrServer; +import org.apache.solr.common.cloud.SolrZkClient; +import org.apache.solr.core.SolrConfig; +import org.apache.solr.core.SolrResourceLoader; +import org.apache.solr.schema.IndexSchema; +import org.apache.solr.util.SystemIdResolver; +import org.apache.zookeeper.KeeperException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +import com.cloudera.cdk.morphline.api.MorphlineCompilationException; +import com.cloudera.cdk.morphline.api.MorphlineContext; +import com.cloudera.cdk.morphline.api.MorphlineRuntimeException; +import com.cloudera.cdk.morphline.base.Configs; +import com.google.common.base.Preconditions; +import com.typesafe.config.Config; +import com.typesafe.config.ConfigFactory; +import com.typesafe.config.ConfigRenderOptions; +import com.typesafe.config.ConfigUtil; + +/** + * Set of configuration parameters that identify the location and schema of a Solr server or + * SolrCloud; Based on this information this class can return the schema and a corresponding + * {@link DocumentLoader}. + */ +public class SolrLocator { + + private Config config; + private MorphlineContext context; + private String collectionName; + private String zkHost; + private String solrUrl; + private String solrHomeDir; + private int batchSize = 1000; + + private static final String SOLR_HOME_PROPERTY_NAME = "solr.solr.home"; + + private static final Logger LOG = LoggerFactory.getLogger(SolrLocator.class); + + protected SolrLocator(MorphlineContext context) { + Preconditions.checkNotNull(context); + this.context = context; + } + + public SolrLocator(Config config, MorphlineContext context) { + this(context); + this.config = config; + Configs configs = new Configs(); + collectionName = configs.getString(config, "collection", null); + zkHost = configs.getString(config, "zkHost", null); + solrHomeDir = configs.getString(config, "solrHomeDir", null); + solrUrl = configs.getString(config, "solrUrl", null); + batchSize = configs.getInt(config, "batchSize", batchSize); + LOG.trace("Constructed solrLocator: {}", this); + configs.validateArguments(config); + } + + public DocumentLoader getLoader() { + if (context instanceof SolrMorphlineContext) { + DocumentLoader loader = ((SolrMorphlineContext)context).getDocumentLoader(); + if (loader != null) { + return loader; + } + } + + if (zkHost != null && zkHost.length() > 0) { + if (collectionName == null || collectionName.length() == 0) { + throw new MorphlineCompilationException("Parameter 'zkHost' requires that you also pass parameter 'collection'", config); + } + try { + CloudSolrServer cloudSolrServer = new CloudSolrServer(zkHost); + cloudSolrServer.setDefaultCollection(collectionName); + cloudSolrServer.connect(); + return new SolrServerDocumentLoader(cloudSolrServer, batchSize); + } catch (MalformedURLException e) { + throw new MorphlineRuntimeException(e); + } + } else { + if (solrUrl == null || solrUrl.length() == 0) { + throw new MorphlineCompilationException("Missing parameter 'solrUrl'", config); + } + int solrServerNumThreads = 2; + int solrServerQueueLength = solrServerNumThreads; + SolrServer server = new SafeConcurrentUpdateSolrServer(solrUrl, solrServerQueueLength, solrServerNumThreads); + // SolrServer server = new HttpSolrServer(solrServerUrl); + // SolrServer server = new ConcurrentUpdateSolrServer(solrServerUrl, solrServerQueueLength, solrServerNumThreads); + // server.setParser(new XMLResponseParser()); // binary parser is used by default + return new SolrServerDocumentLoader(server, batchSize); + } + } + + public IndexSchema getIndexSchema() { + if (context instanceof SolrMorphlineContext) { + IndexSchema schema = ((SolrMorphlineContext)context).getIndexSchema(); + if (schema != null) { + validateSchema(schema); + return schema; + } + } + + // If solrHomeDir isn't defined and zkHost and collectionName are defined + // then download schema.xml and solrconfig.xml, etc from zk and use that as solrHomeDir + String oldSolrHomeDir = null; + String mySolrHomeDir = solrHomeDir; + if (solrHomeDir == null || solrHomeDir.length() == 0) { + if (zkHost == null || zkHost.length() == 0) { + // TODO: implement download from solrUrl if specified + throw new MorphlineCompilationException( + "Downloading a Solr schema requires either parameter 'solrHomeDir' or parameters 'zkHost' and 'collection'", + config); + } + if (collectionName == null || collectionName.length() == 0) { + throw new MorphlineCompilationException( + "Parameter 'zkHost' requires that you also pass parameter 'collection'", config); + } + ZooKeeperDownloader zki = new ZooKeeperDownloader(); + SolrZkClient zkClient = zki.getZkClient(zkHost); + try { + String configName = zki.readConfigName(zkClient, collectionName); + File downloadedSolrHomeDir = zki.downloadConfigDir(zkClient, configName); + mySolrHomeDir = downloadedSolrHomeDir.getAbsolutePath(); + } catch (KeeperException e) { + throw new MorphlineCompilationException("Cannot download schema.xml from ZooKeeper", config, e); + } catch (InterruptedException e) { + throw new MorphlineCompilationException("Cannot download schema.xml from ZooKeeper", config, e); + } catch (IOException e) { + throw new MorphlineCompilationException("Cannot download schema.xml from ZooKeeper", config, e); + } finally { + zkClient.close(); + } + } + + oldSolrHomeDir = System.setProperty(SOLR_HOME_PROPERTY_NAME, mySolrHomeDir); + try { + SolrConfig solrConfig = new SolrConfig(); // TODO use SolrResourceLoader ala TikaMapper? + // SolrConfig solrConfig = new SolrConfig("solrconfig.xml"); + // SolrConfig solrConfig = new + // SolrConfig("/cloud/apache-solr-4.0.0-BETA/example/solr/collection1", + // "solrconfig.xml", null); + // SolrConfig solrConfig = new + // SolrConfig("/cloud/apache-solr-4.0.0-BETA/example/solr/collection1/conf/solrconfig.xml"); + SolrResourceLoader loader = solrConfig.getResourceLoader(); + + InputSource is = new InputSource(loader.openSchema("schema.xml")); + is.setSystemId(SystemIdResolver.createSystemIdFromResourceName("schema.xml")); + + IndexSchema schema = new IndexSchema(solrConfig, "schema.xml", is); + validateSchema(schema); + return schema; + } catch (ParserConfigurationException e) { + throw new MorphlineRuntimeException(e); + } catch (IOException e) { + throw new MorphlineRuntimeException(e); + } catch (SAXException e) { + throw new MorphlineRuntimeException(e); + } finally { // restore old global state + if (solrHomeDir != null) { + if (oldSolrHomeDir == null) { + System.clearProperty(SOLR_HOME_PROPERTY_NAME); + } else { + System.setProperty(SOLR_HOME_PROPERTY_NAME, oldSolrHomeDir); + } + } + } + } + + private void validateSchema(IndexSchema schema) { + if (schema.getUniqueKeyField() == null) { + throw new MorphlineCompilationException("Solr schema.xml is missing unique key field", config); + } + if (!schema.getUniqueKeyField().isRequired()) { + throw new MorphlineCompilationException("Solr schema.xml must contain a required unique key field", config); + } + } + + @Override + public String toString() { + return toConfig(null).root().render(ConfigRenderOptions.concise()); + } + + public Config toConfig(String key) { + String json = ""; + if (key != null) { + json = toJson(key) + " : "; + } + json += + "{" + + " collection : " + toJson(collectionName) + ", " + + " zkHost : " + toJson(zkHost) + ", " + + " solrUrl : " + toJson(solrUrl) + ", " + + " solrHomeDir : " + toJson(solrHomeDir) + ", " + + " batchSize : " + toJson(batchSize) + " " + + "}"; + return ConfigFactory.parseString(json); + } + + private String toJson(Object key) { + String str = key == null ? "" : key.toString(); + str = ConfigUtil.quoteString(str); + return str; + } + + public String getCollectionName() { + return this.collectionName; + } + + public void setCollectionName(String collectionName) { + this.collectionName = collectionName; + } + + public String getZkHost() { + return this.zkHost; + } + + public void setZkHost(String zkHost) { + this.zkHost = zkHost; + } + + public String getSolrHomeDir() { + return this.solrHomeDir; + } + + public void setSolrHomeDir(String solrHomeDir) { + this.solrHomeDir = solrHomeDir; + } + + public String getServerUrl() { + return this.solrUrl; + } + + public void setServerUrl(String solrUrl) { + this.solrUrl = solrUrl; + } + + public int getBatchSize() { + return this.batchSize; + } + + public void setBatchSize(int batchSize) { + this.batchSize = batchSize; + } + +} diff --git a/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/SolrMorphlineContext.java b/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/SolrMorphlineContext.java new file mode 100644 index 00000000000..56d6e39227c --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/SolrMorphlineContext.java @@ -0,0 +1,80 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.morphlines.solr; + +import org.apache.solr.schema.IndexSchema; + +import com.cloudera.cdk.morphline.api.MorphlineContext; + +/** + * A context that is specific to Solr. + */ +public class SolrMorphlineContext extends MorphlineContext { + + private DocumentLoader loader; + private IndexSchema schema; + + /** For public access use {@link Builder#build()} instead */ + protected SolrMorphlineContext() {} + + public DocumentLoader getDocumentLoader() { + return loader; + } + + public IndexSchema getIndexSchema() { + return schema; + } + + + /////////////////////////////////////////////////////////////////////////////// + // Nested classes: + /////////////////////////////////////////////////////////////////////////////// + /** + * Helper to construct a {@link SolrMorphlineContext} instance. + */ + public static class Builder extends MorphlineContext.Builder { + + private DocumentLoader loader; + private IndexSchema schema; + + public Builder() {} + + public Builder setDocumentLoader(DocumentLoader loader) { + this.loader = loader; + return this; + } + + public Builder setIndexSchema(IndexSchema schema) { + this.schema = schema; + return this; + } + + @Override + public SolrMorphlineContext build() { + ((SolrMorphlineContext)context).loader = loader; + ((SolrMorphlineContext)context).schema = schema; + return (SolrMorphlineContext) super.build(); + } + + @Override + protected SolrMorphlineContext create() { + return new SolrMorphlineContext(); + } + + } + +} diff --git a/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/SolrServerDocumentLoader.java b/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/SolrServerDocumentLoader.java new file mode 100644 index 00000000000..d343230fcba --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/SolrServerDocumentLoader.java @@ -0,0 +1,123 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.morphlines.solr; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.apache.solr.client.solrj.SolrServer; +import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.client.solrj.impl.CloudSolrServer; +import org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrServer; +import org.apache.solr.client.solrj.response.SolrPingResponse; +import org.apache.solr.client.solrj.response.UpdateResponse; +import org.apache.solr.common.SolrInputDocument; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A vehicle to load a list of Solr documents into a local or remote {@link SolrServer}. + */ +public class SolrServerDocumentLoader implements DocumentLoader { + + private final SolrServer server; // proxy to local or remote solr server + private long numLoadedDocs = 0; // number of documents loaded in the current transaction + private final int batchSize; + private final List batch = new ArrayList(); + + private static final Logger LOGGER = LoggerFactory.getLogger(SolrServerDocumentLoader.class); + + public SolrServerDocumentLoader(SolrServer server, int batchSize) { + if (server == null) { + throw new IllegalArgumentException("solr server must not be null"); + } + this.server = server; + if (batchSize <= 0) { + throw new IllegalArgumentException("batchSize must be a positive number: " + batchSize); + } + this.batchSize = batchSize; + } + + @Override + public void beginTransaction() { + LOGGER.trace("beginTransaction"); + batch.clear(); + numLoadedDocs = 0; + if (server instanceof SafeConcurrentUpdateSolrServer) { + ((SafeConcurrentUpdateSolrServer) server).clearException(); + } + } + + @Override + public void load(SolrInputDocument doc) throws IOException, SolrServerException { + LOGGER.trace("load doc: {}", doc); + batch.add(doc); + if (batch.size() >= batchSize) { + loadBatch(); + } + } + + @Override + public void commitTransaction() throws SolrServerException, IOException { + LOGGER.trace("commitTransaction"); + if (batch.size() > 0) { + loadBatch(); + } + if (numLoadedDocs > 0) { + if (server instanceof ConcurrentUpdateSolrServer) { + ((ConcurrentUpdateSolrServer) server).blockUntilFinished(); + } + } + } + + private void loadBatch() throws SolrServerException, IOException { + numLoadedDocs += batch.size(); + try { + UpdateResponse rsp = server.add(batch); + } finally { + batch.clear(); + } + } + + @Override + public UpdateResponse rollbackTransaction() throws SolrServerException, IOException { + LOGGER.trace("rollback"); + if (!(server instanceof CloudSolrServer)) { + return server.rollback(); + } else { + return new UpdateResponse(); + } + } + + @Override + public void shutdown() { + LOGGER.trace("shutdown"); + server.shutdown(); + } + + @Override + public SolrPingResponse ping() throws SolrServerException, IOException { + LOGGER.trace("ping"); + return server.ping(); + } + + public SolrServer getSolrServer() { + return server; + } + +} diff --git a/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/TokenizeTextBuilder.java b/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/TokenizeTextBuilder.java new file mode 100644 index 00000000000..58c1bb5536c --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/TokenizeTextBuilder.java @@ -0,0 +1,177 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.morphlines.solr; + +import java.io.IOException; +import java.io.Reader; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.apache.lucene.analysis.Analyzer; +import org.apache.lucene.analysis.TokenStream; +import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; +import org.apache.solr.schema.FieldType; +import org.apache.solr.schema.IndexSchema; + +import com.cloudera.cdk.morphline.api.Command; +import com.cloudera.cdk.morphline.api.CommandBuilder; +import com.cloudera.cdk.morphline.api.MorphlineCompilationException; +import com.cloudera.cdk.morphline.api.MorphlineContext; +import com.cloudera.cdk.morphline.api.MorphlineRuntimeException; +import com.cloudera.cdk.morphline.api.Record; +import com.cloudera.cdk.morphline.base.AbstractCommand; +import com.google.common.base.Preconditions; +import com.typesafe.config.Config; + +/** + * A command that uses the embedded Solr/Lucene Analyzer library to generate tokens from a text + * string, without sending data to a Solr server. + */ +public final class TokenizeTextBuilder implements CommandBuilder { + + @Override + public Collection getNames() { + return Collections.singletonList("tokenizeText"); + } + + @Override + public Command build(Config config, Command parent, Command child, MorphlineContext context) { + return new TokenizeText(config, parent, child, context); + } + + + /////////////////////////////////////////////////////////////////////////////// + // Nested classes: + /////////////////////////////////////////////////////////////////////////////// + private static final class TokenizeText extends AbstractCommand { + + private final String inputFieldName; + private final String outputFieldName; + private final Analyzer analyzer; + private final CharTermAttribute token; // cached + private final ReusableStringReader reader = new ReusableStringReader(); // cached + + public TokenizeText(Config config, Command parent, Command child, MorphlineContext context) { + super(config, parent, child, context); + this.inputFieldName = getConfigs().getString(config, "inputField"); + this.outputFieldName = getConfigs().getString(config, "outputField"); + String solrFieldType = getConfigs().getString(config, "solrFieldType"); + Config solrLocatorConfig = getConfigs().getConfig(config, "solrLocator"); + SolrLocator locator = new SolrLocator(solrLocatorConfig, context); + LOG.debug("solrLocator: {}", locator); + IndexSchema schema = locator.getIndexSchema(); + FieldType fieldType = schema.getFieldTypeByName(solrFieldType); + if (fieldType == null) { + throw new MorphlineCompilationException("Missing Solr field type in schema.xml for name: " + solrFieldType, config); + } + this.analyzer = fieldType.getAnalyzer(); + Preconditions.checkNotNull(analyzer); + try { // register CharTermAttribute for later (implicit) reuse + this.token = analyzer.tokenStream("content", reader).addAttribute(CharTermAttribute.class); + } catch (IOException e) { + throw new MorphlineCompilationException("Cannot create token stream", config, e); + } + Preconditions.checkNotNull(token); + validateArguments(); + } + + @Override + protected boolean doProcess(Record record) { + try { + List outputValues = record.get(outputFieldName); + for (Object value : record.get(inputFieldName)) { + reader.setValue(value.toString()); + TokenStream tokenStream = analyzer.tokenStream("content", reader); + tokenStream.reset(); + while (tokenStream.incrementToken()) { + if (token.length() > 0) { // incrementToken() updates the token! + String tokenStr = new String(token.buffer(), 0, token.length()); + outputValues.add(tokenStr); + } + } + tokenStream.end(); + tokenStream.close(); + } + } catch (IOException e) { + throw new MorphlineRuntimeException(e); + } + + // pass record to next command in chain: + return super.doProcess(record); + } + + } + + + // Copied from org.apache.lucene.document.Field.java from lucene-4.3.0 + /* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + private static final class ReusableStringReader extends Reader { + private int pos = 0, size = 0; + private String s = null; + + void setValue(String s) { + this.s = s; + this.size = s.length(); + this.pos = 0; + } + + @Override + public int read() { + if (pos < size) { + return s.charAt(pos++); + } else { + s = null; + return -1; + } + } + + @Override + public int read(char[] c, int off, int len) { + if (pos < size) { + len = Math.min(len, size-pos); + s.getChars(pos, pos+len, c, off); + pos += len; + return len; + } else { + s = null; + return -1; + } + } + + @Override + public void close() { + pos = size; // this prevents NPE when reading after close! + s = null; + } + } +} diff --git a/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/ZooKeeperDownloader.java b/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/ZooKeeperDownloader.java new file mode 100644 index 00000000000..68cb6270139 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/ZooKeeperDownloader.java @@ -0,0 +1,122 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.morphlines.solr; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +import org.apache.solr.cloud.ZkController; +import org.apache.solr.common.cloud.Aliases; +import org.apache.solr.common.cloud.ClusterState; +import org.apache.solr.common.cloud.SolrZkClient; +import org.apache.solr.common.cloud.ZkNodeProps; +import org.apache.solr.common.cloud.ZkStateReader; +import org.apache.solr.common.util.StrUtils; +import org.apache.zookeeper.KeeperException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.io.Files; + +/** + * Downloads SolrCloud information from ZooKeeper. + */ +final class ZooKeeperDownloader { + + private static final Logger LOG = LoggerFactory.getLogger(ZooKeeperDownloader.class); + + public SolrZkClient getZkClient(String zkHost) { + if (zkHost == null) { + throw new IllegalArgumentException("zkHost must not be null"); + } + + SolrZkClient zkClient; + try { + zkClient = new SolrZkClient(zkHost, 30000); + } catch (Exception e) { + throw new IllegalArgumentException("Cannot connect to ZooKeeper: " + zkHost, e); + } + return zkClient; + } + + /** + * Returns config value given collection name + * Borrowed heavily from Solr's ZKController. + */ + public String readConfigName(SolrZkClient zkClient, String collection) + throws KeeperException, InterruptedException { + if (collection == null) { + throw new IllegalArgumentException("collection must not be null"); + } + String configName = null; + + // first check for alias + byte[] aliasData = zkClient.getData(ZkStateReader.ALIASES, null, null, true); + Aliases aliases = ClusterState.load(aliasData); + String alias = aliases.getCollectionAlias(collection); + if (alias != null) { + List aliasList = StrUtils.splitSmart(alias, ",", true); + if (aliasList.size() > 1) { + throw new IllegalArgumentException("collection cannot be an alias that maps to multiple collections"); + } + collection = aliasList.get(0); + } + + String path = ZkStateReader.COLLECTIONS_ZKNODE + "/" + collection; + if (LOG.isInfoEnabled()) { + LOG.info("Load collection config from:" + path); + } + byte[] data = zkClient.getData(path, null, null, true); + + if(data != null) { + ZkNodeProps props = ZkNodeProps.load(data); + configName = props.getStr(ZkController.CONFIGNAME_PROP); + } + + if (configName != null && !zkClient.exists(ZkController.CONFIGS_ZKNODE + "/" + configName, true)) { + LOG.error("Specified config does not exist in ZooKeeper:" + configName); + throw new IllegalArgumentException("Specified config does not exist in ZooKeeper:" + + configName); + } + + return configName; + } + + /** + * Download and return the config directory from ZK + */ + public File downloadConfigDir(SolrZkClient zkClient, String configName) + throws IOException, InterruptedException, KeeperException { + File dir = Files.createTempDir(); + dir.deleteOnExit(); + ZkController.downloadConfigDir(zkClient, configName, dir); + File confDir = new File(dir, "conf"); + if (!confDir.isDirectory()) { + // create a temporary directory with "conf" subdir and mv the config in there. This is + // necessary because of CDH-11188; solrctl does not generate nor accept directories with e.g. + // conf/solrconfig.xml which is necessary for proper solr operation. This should work + // even if solrctl changes. + confDir = new File(Files.createTempDir().getAbsolutePath(), "conf"); + confDir.getParentFile().deleteOnExit(); + Files.move(dir, confDir); + dir = confDir.getParentFile(); + } + return dir; + } + +} diff --git a/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/package.html b/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/package.html new file mode 100644 index 00000000000..ecec1bdf4d8 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/package.html @@ -0,0 +1,22 @@ + + + + +Morphlines Solr related code. + + diff --git a/solr/contrib/solr-morphlines-core/src/java/overview.html b/solr/contrib/solr-morphlines-core/src/java/overview.html new file mode 100644 index 00000000000..7f8ad137a34 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/java/overview.html @@ -0,0 +1,21 @@ + + + +Apache Solr Search Server: Solr Core Morphline Commands + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/README b/solr/contrib/solr-morphlines-core/src/test-files/README new file mode 100644 index 00000000000..10f878acccb --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/README @@ -0,0 +1,21 @@ + + +This directory is where any non-transient, non-java files needed +for the execution of tests should live. + +It is used as the CWD when running JUnit tests. diff --git a/solr/contrib/solr-morphlines-core/src/test-files/books_numeric_ids.csv b/solr/contrib/solr-morphlines-core/src/test-files/books_numeric_ids.csv new file mode 100644 index 00000000000..817e8b769cf --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/books_numeric_ids.csv @@ -0,0 +1,11 @@ +id,cat,name,price,inStock,author_t,series_t,sequence_i,genre_s +0553573403,book,A Game of Thrones,7.99,true,George R.R. Martin,"A Song of Ice and Fire",1,fantasy +0553579908,book,A Clash of Kings,7.99,true,George R.R. Martin,"A Song of Ice and Fire",2,fantasy +0553573429,book,A Storm of Swords,7.99,true,George R.R. Martin,"A Song of Ice and Fire",3,fantasy +0553293354,book,Foundation,7.99,true,Isaac Asimov,Foundation Novels,1,scifi +0812521390,book,The Black Company,6.99,false,Glen Cook,The Chronicles of The Black Company,1,fantasy +0812550706,book,Ender's Game,6.99,true,Orson Scott Card,Ender,1,scifi +0441385532,book,Jhereg,7.95,false,Steven Brust,Vlad Taltos,1,fantasy +0380014300,book,Nine Princes In Amber,6.99,true,Roger Zelazny,the Chronicles of Amber,1,fantasy +0805080481,book,The Book of Three,5.99,true,Lloyd Alexander,The Chronicles of Prydain,1,fantasy +0805080499,book,The Black Cauldron,5.99,true,Lloyd Alexander,The Chronicles of Prydain,2,fantasy diff --git a/solr/contrib/solr-morphlines-core/src/test-files/exampledocs/example.html b/solr/contrib/solr-morphlines-core/src/test-files/exampledocs/example.html new file mode 100644 index 00000000000..5732f6214bc --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/exampledocs/example.html @@ -0,0 +1,49 @@ + + + Welcome to Solr + + +

    + Here is some text +

    +
    Here is some text in a div
    +
    This has a link.
    +News + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/exampledocs/example.txt b/solr/contrib/solr-morphlines-core/src/test-files/exampledocs/example.txt new file mode 100644 index 00000000000..0c9928b9e26 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/exampledocs/example.txt @@ -0,0 +1,3 @@ +Example text document + +This is a simple example for a plain text document, indexed to Solr \ No newline at end of file diff --git a/solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/README b/solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/README new file mode 100644 index 00000000000..b7ca5b834f4 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/README @@ -0,0 +1,18 @@ + + +Items under this directory are used by TestConfig.testLibs() diff --git a/solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/a/a1/empty-file-a1.txt b/solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/a/a1/empty-file-a1.txt new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/a/a1/empty-file-a1.txt @@ -0,0 +1 @@ + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/a/a2/empty-file-a2.txt b/solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/a/a2/empty-file-a2.txt new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/a/a2/empty-file-a2.txt @@ -0,0 +1 @@ + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/b/b1/empty-file-b1.txt b/solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/b/b1/empty-file-b1.txt new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/b/b1/empty-file-b1.txt @@ -0,0 +1 @@ + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/b/b2/empty-file-b2.txt b/solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/b/b2/empty-file-b2.txt new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/b/b2/empty-file-b2.txt @@ -0,0 +1 @@ + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/c/c1/empty-file-c1.txt b/solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/c/c1/empty-file-c1.txt new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/c/c1/empty-file-c1.txt @@ -0,0 +1 @@ + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/c/c2/empty-file-c2.txt b/solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/c/c2/empty-file-c2.txt new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/c/c2/empty-file-c2.txt @@ -0,0 +1 @@ + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/d/d1/empty-file-d1.txt b/solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/d/d1/empty-file-d1.txt new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/d/d1/empty-file-d1.txt @@ -0,0 +1 @@ + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/d/d2/empty-file-d2.txt b/solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/d/d2/empty-file-d2.txt new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/d/d2/empty-file-d2.txt @@ -0,0 +1 @@ + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/log4j.properties b/solr/contrib/solr-morphlines-core/src/test-files/log4j.properties new file mode 100644 index 00000000000..fb0577130bb --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/log4j.properties @@ -0,0 +1,12 @@ +# Logging level +log4j.rootLogger=INFO, CONSOLE + +log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender +log4j.appender.CONSOLE.Target=System.err +log4j.appender.CONSOLE.layout=org.apache.solr.util.SolrLogLayout +log4j.appender.CONSOLE.layout.ConversionPattern=%-5p - %d{yyyy-MM-dd HH:mm:ss.SSS}; %C; %m\n + +log4j.logger.org.apache.zookeeper=WARN +log4j.logger.org.apache.hadoop=WARN +#log4j.logger.org.apache.solr=WARN +log4j.logger.org.apache.solr.hadoop=INFO \ No newline at end of file diff --git a/solr/contrib/solr-morphlines-core/src/test-files/mailing_lists.pdf b/solr/contrib/solr-morphlines-core/src/test-files/mailing_lists.pdf new file mode 100755 index 00000000000..33b819f0649 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/mailing_lists.pdf @@ -0,0 +1,382 @@ +%PDF-1.3 +% +4 0 obj +<< /Type /Info +/Producer (FOP 0.20.5) >> +endobj +5 0 obj +<< /Length 425 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gb!$BYuAO_'ZTnF'lQbNnGsdiUK'C#3dAWc3lI>k\P#:a@Qja<+itJa;R]7&ni\$9pOi?T._;3m?jT+q7>,P^70oB=!nr]%k%\U^KVqaF4*Z`$VJ7Gs`T5OO`(tY]Q1`-5*m;!--h%?*_0SbIU\BV=OFg<#%YcH_YI$(sDCIJts'M2*drjRrJE!OM7HP!^-&EW>B\:RYFnaY.m[$s5f"XG0>^fduHe6/++D0fY3@AWR@HYabmQ5jDQ.c0>I.uQX&(lA@VLm_s_9XnBh7%"*/%^]AO3eTI!BTo'pF?%''A*PDU*NW%d`2@p'@:D@U??4PP08m[K4N,8,(e`N+\7n+a>ac%q#,D8DRQ*3l]MS>'gn3lWNGmRAtQ7n]eDnLPrD!?DEdB/hNarb_7$B7U-H7!['nXLkV_no5AHq`>6~> +endstream +endobj +6 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 5 0 R +/Annots 7 0 R +>> +endobj +7 0 obj +[ +8 0 R +10 0 R +12 0 R +] +endobj +8 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 102.0 559.666 137.324 547.666 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 9 0 R +/H /I +>> +endobj +10 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 102.0 541.466 164.648 529.466 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 11 0 R +/H /I +>> +endobj +12 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 102.0 523.266 154.016 511.266 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A 13 0 R +/H /I +>> +endobj +14 0 obj +<< /Length 2197 /Filter [ /ASCII85Decode /FlateDecode ] + >> +stream +Gb"/)9lo&I&A@C2n5a2!7YkueV^?,ABrC@*[F.^sK-J\u-^*\VZ9A3]?'#&sU^3,]d[;/F9HjMs^A"j:!rHNC?7rs!0)f1q`$?\lOaRt/g/f.>-Am[t'`RUrGL7Uk8K90.i-up;qeIYfjWZ2&ki:[3`TuXFj]`a&Hbo8r&P(RZ+M_>&eY.T4jXOI%UHbq1GnF>g$KgW%R24nBkc\[qA$(koU$isG(W7`PE,nMam;U4(ZC8,Ca!_P2VYf>\V0gK0g;-.E[Y(&s=+&g6ms""'Ip>0b/D!>a&PX9eo_tuueR:b=r@6Q5LM],XbK;&L$0WubNX9c"=FM$543G_>rAQ_%2/dW<)/"U1&]l:AZ&\Mif8sF`r5>b<$lqK"2t]maZ*oDb!^$Zn6OC'%XkI];&*rkLP1BMGI@$,0fK(=gC-3q7n7d4EQ4DepBc'^Q^A%e?19a(`S*FHTN*RNjP&P%2`6%jpOU\DBUN)cnMYa3PQ!sYETiGJi'q>>m*e;[,.1l\rZo3K;>$K"a1:s3pU>o+:'7fND!+6GV@2G;qf`\`=J#WkOjSke<1f>VfbcUtXM"1jGN:@Ptec8Mc-hmS5S>q/nAY%[4%7BCI![NA:We(41]ld_`pU80;+e`1DbG.RQ:'#GQJAL2![aIWY'A*Y_>mF7>2S0IWM%nLg3%%;7r5=;3!7]05r?Ft-6I]9n9C\fUUF6R\9bPEVSutd9LFTpaoaP7Iuus-S#S.3;sVu-*T/:&2Ld]&g0oHoo`TmR'b]ps6hq9s&f+6_5c(k"m96-f:YA!:)K:q+(Hl=t`:+"<lQm6B=K&/r/Ep6Y]EG.T/34(fT0=6_m5PA-7PVo:"r)W'.mX>1A8Yg9kfa?"Qp+ta7Hb$FM`*OP^>3Sg)P[?jIXd]i]"h)Tdjnm[6@=kmEBkP1/K[bg`"7U:BWk^=!+3\ANTnN75*Rh_<-UA*!&rr#KW/7EXkeJU9GF5RA,#kqJ5aC9Ra5,PsiI`uF23/B"nkPHe2Q;B@pBXGM-i;<'oOM,dc3'qL)Ne,OV2.*f^Bt;0P#roPn?h]@-63,-9lQSF!dic13Ag\_]m=7Llb\*&C+>\+o6)Y,C._?+X1Qok%j>f[#T!,CD2T4cL'.Nb_Vit&M]!j7j6LHB.g9AQre&be$gJhbAg68kDJf@XZ7'2791RD*qAP]u")(lEjX)\-#O$aK(E]jq*3XbL:3q:o&9gcZLl?:E-l'-dHf;;_hhH3m/Q3]9jJRn>Z8]1Gt6PAVJ[r2gsg=4$!6I$RQ@Y6;H(U>,LWdW>Z5iTYZ'tAcSfoN,U=/fIoA::l8X^fXIa4m3-]9$Zc\E0H^!pmfeMjW3#p1J)pbH^VZML"NZ$U,Yg;f[AVrZRhlRCC[)D*>K0IRWR98A=<>dPSd)@Ec)OXGjK01hM%!FhVR[I<5Va3V,I"YuQZb-,XEM!Gk_-r<9T0W#M!!;RX!]MtBdJ0ah'FCoNF1r"gmU>Rb4aE:Z'I)d-f_1:B0gfmnM?K9ljY>R%*Fc9oYiohHndi(!dK+]ElID:'g:PKq6fKKHdO>bmG-2]ZmVcqs+ef-EWR(1Da)F&CoL[['3)UZ^!fo+Ua2NSC7m5oIXlLoF)+cWUr/MaMP@shSN$gD*jB=:/ru]MF>3-m'j6_-'>(Uq'PN4Fl*XC8ABmg\b`kmI@<0Sh)bkNopK]E6S7,V*o!<)infW?).%mtC2S8!kqh$BpiWu=4)>.Wm+Mt.YPC"ZlO^Ge*Y5)8QlX2 +endstream +endobj +15 0 obj +<< /Type /Page +/Parent 1 0 R +/MediaBox [ 0 0 612 792 ] +/Resources 3 0 R +/Contents 14 0 R +/Annots 16 0 R +>> +endobj +16 0 obj +[ +17 0 R +18 0 R +19 0 R +20 0 R +21 0 R +22 0 R +23 0 R +24 0 R +25 0 R +26 0 R +27 0 R +28 0 R +29 0 R +] +endobj +17 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 232.344 608.466 372.012 596.466 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A << /URI (mailto:solr-user@lucene.apache.org) +/S /URI >> +/H /I +>> +endobj +18 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 108.0 591.266 189.336 579.266 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A << /URI (mailto:solr-user-subscribe@lucene.apache.org) +/S /URI >> +/H /I +>> +endobj +19 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 108.0 578.066 215.988 566.066 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A << /URI (mailto:solr-user-unsubscribe@lucene.apache.org) +/S /URI >> +/H /I +>> +endobj +20 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 108.0 564.866 197.316 552.866 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A << /URI (http://mail-archives.apache.org/mod_mbox/lucene-solr-user/) +/S /URI >> +/H /I +>> +endobj +21 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 453.924 564.866 475.26 552.866 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A << /URI (http://wiki.apache.org/solr/SolrResources) +/S /URI >> +/H /I +>> +endobj +22 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 259.668 441.722 396.672 429.722 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A << /URI (mailto:solr-dev@lucene.apache.org) +/S /URI >> +/H /I +>> +endobj +23 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 108.0 424.522 189.336 412.522 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A << /URI (mailto:solr-dev-subscribe@lucene.apache.org) +/S /URI >> +/H /I +>> +endobj +24 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 108.0 411.322 215.988 399.322 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A << /URI (mailto:solr-dev-unsubscribe@lucene.apache.org) +/S /URI >> +/H /I +>> +endobj +25 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 108.0 398.122 197.316 386.122 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A << /URI (http://mail-archives.apache.org/mod_mbox/lucene-solr-dev/) +/S /URI >> +/H /I +>> +endobj +26 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 453.924 398.122 475.26 386.122 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A << /URI (http://wiki.apache.org/solr/SolrResources) +/S /URI >> +/H /I +>> +endobj +27 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 294.624 296.178 403.284 284.178 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A << /URI (version_control.html) +/S /URI >> +/H /I +>> +endobj +28 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 108.0 265.778 189.336 253.778 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A << /URI (mailto:solr-commits-subscribe@lucene.apache.org) +/S /URI >> +/H /I +>> +endobj +29 0 obj +<< /Type /Annot +/Subtype /Link +/Rect [ 108.0 252.578 215.988 240.578 ] +/C [ 0 0 0 ] +/Border [ 0 0 0 ] +/A << /URI (mailto:solr-commits-unsubscribe@lucene.apache.org) +/S /URI >> +/H /I +>> +endobj +31 0 obj +<< + /Title (\376\377\0\61\0\40\0\125\0\163\0\145\0\162\0\163) + /Parent 30 0 R + /Next 32 0 R + /A 9 0 R +>> endobj +32 0 obj +<< + /Title (\376\377\0\62\0\40\0\104\0\145\0\166\0\145\0\154\0\157\0\160\0\145\0\162\0\163) + /Parent 30 0 R + /Prev 31 0 R + /Next 33 0 R + /A 11 0 R +>> endobj +33 0 obj +<< + /Title (\376\377\0\63\0\40\0\103\0\157\0\155\0\155\0\151\0\164\0\163) + /Parent 30 0 R + /Prev 32 0 R + /A 13 0 R +>> endobj +34 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F3 +/BaseFont /Helvetica-Bold +/Encoding /WinAnsiEncoding >> +endobj +35 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F5 +/BaseFont /Times-Roman +/Encoding /WinAnsiEncoding >> +endobj +36 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F1 +/BaseFont /Helvetica +/Encoding /WinAnsiEncoding >> +endobj +37 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F2 +/BaseFont /Helvetica-Oblique +/Encoding /WinAnsiEncoding >> +endobj +38 0 obj +<< /Type /Font +/Subtype /Type1 +/Name /F7 +/BaseFont /Times-Bold +/Encoding /WinAnsiEncoding >> +endobj +1 0 obj +<< /Type /Pages +/Count 2 +/Kids [6 0 R 15 0 R ] >> +endobj +2 0 obj +<< /Type /Catalog +/Pages 1 0 R + /Outlines 30 0 R + /PageMode /UseOutlines + >> +endobj +3 0 obj +<< +/Font << /F3 34 0 R /F5 35 0 R /F1 36 0 R /F2 37 0 R /F7 38 0 R >> +/ProcSet [ /PDF /ImageC /Text ] >> +endobj +9 0 obj +<< +/S /GoTo +/D [15 0 R /XYZ 85.0 659.0 null] +>> +endobj +11 0 obj +<< +/S /GoTo +/D [15 0 R /XYZ 85.0 492.256 null] +>> +endobj +13 0 obj +<< +/S /GoTo +/D [15 0 R /XYZ 85.0 325.512 null] +>> +endobj +30 0 obj +<< + /First 31 0 R + /Last 33 0 R +>> endobj +xref +0 39 +0000000000 65535 f +0000007198 00000 n +0000007263 00000 n +0000007355 00000 n +0000000015 00000 n +0000000071 00000 n +0000000587 00000 n +0000000707 00000 n +0000000746 00000 n +0000007478 00000 n +0000000881 00000 n +0000007541 00000 n +0000001018 00000 n +0000007607 00000 n +0000001155 00000 n +0000003445 00000 n +0000003568 00000 n +0000003679 00000 n +0000003867 00000 n +0000004063 00000 n +0000004261 00000 n +0000004471 00000 n +0000004665 00000 n +0000004852 00000 n +0000005047 00000 n +0000005244 00000 n +0000005453 00000 n +0000005647 00000 n +0000005821 00000 n +0000006020 00000 n +0000007673 00000 n +0000006221 00000 n +0000006342 00000 n +0000006508 00000 n +0000006642 00000 n +0000006755 00000 n +0000006865 00000 n +0000006973 00000 n +0000007089 00000 n +trailer +<< +/Size 39 +/Root 2 0 R +/Info 4 0 R +>> +startxref +7724 +%%EOF diff --git a/solr/contrib/solr-morphlines-core/src/test-files/old-solr-example/README.txt b/solr/contrib/solr-morphlines-core/src/test-files/old-solr-example/README.txt new file mode 100644 index 00000000000..6242cff237b --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/old-solr-example/README.txt @@ -0,0 +1 @@ +This is around for back compat testing purposes and should be able to be removed in Solr 5.0 \ No newline at end of file diff --git a/solr/contrib/solr-morphlines-core/src/test-files/old-solr-example/solr.xml b/solr/contrib/solr-morphlines-core/src/test-files/old-solr-example/solr.xml new file mode 100644 index 00000000000..75da88a52f1 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/old-solr-example/solr.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/addfields.updateprocessor.js b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/addfields.updateprocessor.js new file mode 100644 index 00000000000..1b3c9fc2d6e --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/addfields.updateprocessor.js @@ -0,0 +1,26 @@ +function processAdd(cmd) { + // Integer.valueOf is needed here to get a tru java object, because + // all javascript numbers are floating point (ie: java.lang.Double) + cmd.getSolrInputDocument().addField("script_added_i", + java.lang.Integer.valueOf(42)); + cmd.getSolrInputDocument().addField("script_added_d", 42.3); + +} + +// // // + +function processDelete() { + // NOOP +} +function processCommit() { + // NOOP +} +function processRollback() { + // NOOP +} +function processMergeIndexes() { + // NOOP +} +function finish() { + // NOOP +} diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/analyzingInfixSuggest.txt b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/analyzingInfixSuggest.txt new file mode 100644 index 00000000000..6d276c33a16 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/analyzingInfixSuggest.txt @@ -0,0 +1,5 @@ +# simple AnalyzingInfix suggest phrase dictionary for testing +Japanese Autocomplete and Japanese Highlighter broken +Add Japanese Kanji number normalization to Kuromoji +Add decompose compound Japanese Katakana token capability to Kuromoji +This is just another entry! \ No newline at end of file diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-currency.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-currency.xml new file mode 100644 index 00000000000..d7aeeeb2331 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-currency.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-mp-solrconfig.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-mp-solrconfig.xml new file mode 100644 index 00000000000..af5d8fbb155 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-mp-solrconfig.xml @@ -0,0 +1,34 @@ + + + + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + 8 + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-analyzer-class-and-nested.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-analyzer-class-and-nested.xml new file mode 100644 index 00000000000..16796361c66 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-analyzer-class-and-nested.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + id + id + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-bogus-analysis-parameters.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-bogus-analysis-parameters.xml new file mode 100644 index 00000000000..3f8e224ce1b --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-bogus-analysis-parameters.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-bogus-field-parameters.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-bogus-field-parameters.xml new file mode 100644 index 00000000000..3575c438c72 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-bogus-field-parameters.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-codec-global-vs-ft-mismatch.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-codec-global-vs-ft-mismatch.xml new file mode 100644 index 00000000000..9a704fdd731 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-codec-global-vs-ft-mismatch.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + pulsing1text + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-dynamic-multivalued.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-dynamic-multivalued.xml new file mode 100644 index 00000000000..a71b361c956 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-dynamic-multivalued.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + id + id + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-ft-bogus-code-in-xml.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-ft-bogus-code-in-xml.xml new file mode 100644 index 00000000000..6339ae25eab --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-ft-bogus-code-in-xml.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + id + id + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-ft-bogus-default-code.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-ft-bogus-default-code.xml new file mode 100644 index 00000000000..1f92977760e --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-ft-bogus-default-code.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + id + id + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-ft-multivalued.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-ft-multivalued.xml new file mode 100644 index 00000000000..a1b788e628e --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-ft-multivalued.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + id + id + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-ft-oer-norates.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-ft-oer-norates.xml new file mode 100644 index 00000000000..bd23933b270 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-ft-oer-norates.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + id + id + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-multivalued.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-multivalued.xml new file mode 100644 index 00000000000..84bfaea141d --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-multivalued.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + id + id + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dup-dynamicField.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dup-dynamicField.xml new file mode 100644 index 00000000000..460fbda8ba2 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dup-dynamicField.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + id + id + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dup-field.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dup-field.xml new file mode 100644 index 00000000000..4272362a3f4 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dup-field.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + id + id + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dup-fieldType.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dup-fieldType.xml new file mode 100644 index 00000000000..34ef44bcc73 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dup-fieldType.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + id + id + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dynamicfield-default-val.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dynamicfield-default-val.xml new file mode 100644 index 00000000000..0e3595d75cb --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dynamicfield-default-val.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + id + id + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dynamicfield-required.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dynamicfield-required.xml new file mode 100644 index 00000000000..c372afd44a4 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dynamicfield-required.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + id + id + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-external-filefield.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-external-filefield.xml new file mode 100644 index 00000000000..e7874c88d25 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-external-filefield.xml @@ -0,0 +1,27 @@ + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-misplaced-asterisk-copyfield-dest-should-fail-test.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-misplaced-asterisk-copyfield-dest-should-fail-test.xml new file mode 100644 index 00000000000..5b32376751c --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-misplaced-asterisk-copyfield-dest-should-fail-test.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-misplaced-asterisk-copyfield-source-should-fail-test.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-misplaced-asterisk-copyfield-source-should-fail-test.xml new file mode 100644 index 00000000000..ddc9f4dc685 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-misplaced-asterisk-copyfield-source-should-fail-test.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-multiple-asterisk-copyfield-dest-should-fail-test.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-multiple-asterisk-copyfield-dest-should-fail-test.xml new file mode 100644 index 00000000000..fb3ddbe5c41 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-multiple-asterisk-copyfield-dest-should-fail-test.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-multiple-asterisk-copyfield-source-should-fail-test.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-multiple-asterisk-copyfield-source-should-fail-test.xml new file mode 100644 index 00000000000..b3ca6ae3096 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-multiple-asterisk-copyfield-source-should-fail-test.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-non-glob-copyfield-source-matching-nothing-should-fail-test.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-non-glob-copyfield-source-matching-nothing-should-fail-test.xml new file mode 100644 index 00000000000..86e80a4555e --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-non-glob-copyfield-source-matching-nothing-should-fail-test.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-nontext-analyzer.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-nontext-analyzer.xml new file mode 100644 index 00000000000..06a689a8298 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-nontext-analyzer.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + id + id + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-not-indexed-but-norms.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-not-indexed-but-norms.xml new file mode 100644 index 00000000000..f7c4e9b2d80 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-not-indexed-but-norms.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + id + id + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-not-indexed-but-pos.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-not-indexed-but-pos.xml new file mode 100644 index 00000000000..774d58755f4 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-not-indexed-but-pos.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + id + id + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-not-indexed-but-tf.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-not-indexed-but-tf.xml new file mode 100644 index 00000000000..d153793830a --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-not-indexed-but-tf.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + id + id + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-omit-tf-but-not-pos.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-omit-tf-but-not-pos.xml new file mode 100644 index 00000000000..116f116a176 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-omit-tf-but-not-pos.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + id + id + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sim-global-vs-ft-mismatch.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sim-global-vs-ft-mismatch.xml new file mode 100644 index 00000000000..a776d105541 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sim-global-vs-ft-mismatch.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + sim1text + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sweetspot-both-tf.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sweetspot-both-tf.xml new file mode 100644 index 00000000000..99028c18a7c --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sweetspot-both-tf.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + 6.0 + 1.5 + 3.3 + 7.7 + 5.0 + 5.0 + + + + + + + + + + + id + id + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sweetspot-partial-baseline.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sweetspot-partial-baseline.xml new file mode 100644 index 00000000000..cf34ec8e21b --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sweetspot-partial-baseline.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + 6.0 + + + + + + + + + + + + id + id + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sweetspot-partial-hyperbolic.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sweetspot-partial-hyperbolic.xml new file mode 100644 index 00000000000..61e18ad73c7 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sweetspot-partial-hyperbolic.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + 3.3 + + 5.0 + 5.0 + + + + + + + + + + + id + id + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sweetspot-partial-norms.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sweetspot-partial-norms.xml new file mode 100644 index 00000000000..ef4e8042b3c --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sweetspot-partial-norms.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + 3 + + 0.5 + + + + + + + + + + + id + id + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-uniquekey-is-copyfield-dest.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-uniquekey-is-copyfield-dest.xml new file mode 100644 index 00000000000..bf1d53212e4 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-uniquekey-is-copyfield-dest.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + id + id + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-uniquekey-multivalued.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-uniquekey-multivalued.xml new file mode 100644 index 00000000000..81ce319eb86 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-uniquekey-multivalued.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + id + id + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-uniquekey-uses-default.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-uniquekey-uses-default.xml new file mode 100644 index 00000000000..026b529a942 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-uniquekey-uses-default.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + id + id + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-unsupported-docValues.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-unsupported-docValues.xml new file mode 100644 index 00000000000..5f4d69a31a7 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-unsupported-docValues.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-bogus-scriptengine-name.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-bogus-scriptengine-name.xml new file mode 100644 index 00000000000..fc9e108bee3 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-bogus-scriptengine-name.xml @@ -0,0 +1,32 @@ + + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + giberish + missleading.extension.updateprocessor.js.txt + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-invalid-scriptfile.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-invalid-scriptfile.xml new file mode 100644 index 00000000000..dbadbb5c2c0 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-invalid-scriptfile.xml @@ -0,0 +1,33 @@ + + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + javascript + + currency.xml + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-managed-schema-named-schema.xml.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-managed-schema-named-schema.xml.xml new file mode 100644 index 00000000000..a15c0ac1d6e --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-managed-schema-named-schema.xml.xml @@ -0,0 +1,30 @@ + + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + false + schema.xml + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-missing-scriptfile.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-missing-scriptfile.xml new file mode 100644 index 00000000000..4dee70ce08f --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-missing-scriptfile.xml @@ -0,0 +1,31 @@ + + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + a-file-name-that-does-not-exist.js + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-multiple-cfs.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-multiple-cfs.xml new file mode 100644 index 00000000000..f13acb3f6b0 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-multiple-cfs.xml @@ -0,0 +1,30 @@ + + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + true + false + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-multiple-dirfactory.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-multiple-dirfactory.xml new file mode 100644 index 00000000000..4da2a002f40 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-multiple-dirfactory.xml @@ -0,0 +1,34 @@ + + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-multiple-indexconfigs.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-multiple-indexconfigs.xml new file mode 100644 index 00000000000..00dd08c36fe --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-multiple-indexconfigs.xml @@ -0,0 +1,35 @@ + + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + true + false + + + + ${useCompoundFile:false} + true + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-schema-mutable-but-not-managed.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-schema-mutable-but-not-managed.xml new file mode 100644 index 00000000000..9fe2e89e037 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-schema-mutable-but-not-managed.xml @@ -0,0 +1,32 @@ + + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + + false + schema.xml + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-unexpected-schema-attribute.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-unexpected-schema-attribute.xml new file mode 100644 index 00000000000..d07cb0d1c11 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-unexpected-schema-attribute.xml @@ -0,0 +1,32 @@ + + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + false + managed-schema + bogusValue + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-warmer-no-reopen.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-warmer-no-reopen.xml new file mode 100644 index 00000000000..9c9c96402ec --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-warmer-no-reopen.xml @@ -0,0 +1,27 @@ + + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + false + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad_solrconfig.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad_solrconfig.xml new file mode 100644 index 00000000000..ed07d9afdea --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad_solrconfig.xml @@ -0,0 +1,27 @@ + + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + ${unset.sys.property} + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/compoundDictionary.txt b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/compoundDictionary.txt new file mode 100644 index 00000000000..f4977b5df72 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/compoundDictionary.txt @@ -0,0 +1,19 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# A set of words for testing the DictionaryCompound factory +soft +ball +team diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/conditional.updateprocessor.js b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/conditional.updateprocessor.js new file mode 100644 index 00000000000..5ec9487c150 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/conditional.updateprocessor.js @@ -0,0 +1,25 @@ +function processAdd(cmd) { + if (req.getParams().getBool("go-for-it",false)) { + cmd.getSolrInputDocument().addField("script_added_s", "i went for it"); + return true; + } + return false; +} + +// // // + +function processDelete() { + // NOOP +} +function processCommit() { + // NOOP +} +function processRollback() { + // NOOP +} +function processMergeIndexes() { + // NOOP +} +function finish() { + // NOOP +} diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/currency.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/currency.xml new file mode 100644 index 00000000000..6a12b32b2a8 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/currency.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/da_UTF8.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/da_UTF8.xml new file mode 100644 index 00000000000..2c8d203be68 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/da_UTF8.xml @@ -0,0 +1,1208 @@ + + + + + + + + + + +aA +bB +cC +dD +eE +fF +gG +hH +iI +jJ +kK +lL +mM +nN +oO +pP +qQ +rR +sS +tT +uU +vV +wW +xX +yY +zZ +æÆ +øØ +åÅ + + + +.ae3 +.an3k +.an1s +.be5la +.be1t +.bi4tr +.der3i +.diagno5 +.her3 +.hoved3 +.ne4t5 +.om1 +.ove4 +.po1 +.til3 +.yd5r +ab5le +3abst +a3c +ade5la +5adg +a1e +5afg +5a4f1l +af3r +af4ri +5afs +a4gef +a4gi +ag5in +ag5si +3agti +a4gy +a3h +ais5t +a3j +a5ka +a3ke +a5kr +aku5 +a3la +a1le +a1li +al3k +4alkv +a1lo +al5si +a3lu +a1ly +am4pa +3analy +an4k5r +a3nu +3anv +a5o +a5pe +a3pi +a5po +a1ra +ar5af +1arb +a1re +5arg +a1ri +a3ro +a3sa +a3sc +a1si +a3sk +a3so +3a3sp +a3ste +a3sti +a1ta1 +a1te +a1ti +a4t5in +a1to +ato5v +a5tr +a1tu +a5va +a1ve +a5z +1ba +ba4ti +4bd +1be +be1k +be3ro +be5ru +be1s4 +be1tr +1bi +bi5sk +b1j +4b1n +1bo +bo4gr +bo3ra +bo5re +1br4 +4bs +bs5k +b3so +b1st +b5t +3bu +bu4s5tr +b5w +1by +by5s +4c1c +1ce +ce5ro +3ch +4ch. +ci4o +ck3 +5cy +3da +4d3af +d5anta +da4s +d1b +d1d4 +1de +de5d +4de4lem +der5eri +de4rig +de5sk +d1f +d1g +d3h +1di +di1e +di5l +d3j +d1k +d1l +d1m +4d1n +3do +4dop +d5ov +d1p +4drett +5d4reve +3drif +3driv +d5ros +d5ru +ds5an +ds5in +d1ski +d4sm +d4su +dsu5l +ds5vi +d3ta +d1te +dt5o +d5tr +dt5u +1du +dub5 +d1v +3dy +e5ad +e3af +e5ag +e3ak +e1al +ea4la +e3an +e5ap +e3at +e3bl +ebs3 +e1ci +ed5ar +edde4 +eddel5 +e4do +ed5ra +ed3re +ed3rin +ed4str +e3e +3eff +e3fr +3eft +e3gu +e1h +e3in +ei5s +e3je +e4j5el +e1ka +e3ke +e3kl +4e1ko +e5kr +ek5sa +3eksem +3eksp +e3ku +e1kv +e5ky +e3lad +el3ak +el3ar +e1las +e3le +e4lek +3elem +e1li +5elim +e3lo +el5sa +e5lu +e3ly +e4mad +em4p5le +em1s +en5ak +e4nan +4enn +e4no +en3so +e5nu +e5ol +e3op +e1or +e3ov +epi3 +e1pr +e3ra +er3af +e4rag +e4rak +e1re +e4ref +er5ege +5erhv +e1ri +e4rib +er1k +ero5d +er5ov +er3s +er5tr +e3rum +er5un +e5ry +e1ta +e1te +etek4s +e1ti +e3tj +e1to +e3tr +e3tu +e1ty +e3um +e3un +3eur +e1va +e3ve +e4v3erf +e1vi +e5x +1fa +fa4ce +fags3 +f1b +f1d +1fe +fej4 +fejl1 +f1f +f1g +f1h +1fi +f1k +3fl +1fo +for1en +fo4ri +f1p +f1s4 +4ft +f3ta +f1te +f1ti +f5to +f5tvi +1fu +f1v +3fy +1ga +g3art +g1b +g1d +1ge +4g5enden +ger3in +ge3s +g3f +g1g +g1h +1gi +gi4b +gi3st +5gj +g3k +g1l +g1m +3go +4g5om +g5ov +g3p +1gr +gs1a +gsde4len +g4se +gsha4 +g5sla +gs3or +gs1p +g5s4tide +g4str +gs1v +g3ta +g1te +g1ti +g5to +g3tr +gt4s +g3ud +gun5 +g3v +1gy +g5yd +4ha. +heds3 +he5s +4het +hi4e +hi4n5 +hi3s +ho5ko +ho5ve +4h3t +hun4 +hund3 +hvo4 +i1a +i3b +i4ble +i1c +i3dr +ids5k +i1el +i1en +i3er +i3et. +if3r +i3gu +i3h +i5i +i5j +i1ka +i1ke +ik1l +i5ko +ik3re +ik5ri +iks5t +ik4tu +i3ku +ik3v +i3lag +il3eg +il5ej +il5el +i3li +i4l5id +il3k +i1lo +il5u +i3mu +ind3t +5inf +ings1 +in3s +in4sv +inter1 +i3nu +i3od +i3og +i5ok +i3ol +ion4 +ions1 +i5o5r +i3ot +i5pi +i3pli +i5pr +i3re +i3ri +ir5t +i3sc +i3si +i4sm +is3p +i1ster +i3sti +i5sua +i1ta +i1te +i1ti +i3to +i3tr +it5re. +i1tu +i3ty +i1u +i1va +i1ve +i1vi +j3ag +jde4rer +jds1 +jek4to +4j5en. +j5k +j3le +j3li +jlmeld5 +jlmel4di +j3r +jre5 +ju3s +5kap +k5au +5kav +k5b +kel5s +ke3sk +ke5st +ke4t5a +k3h +ki3e +ki3st +k1k +k5lak +k1le +3klu +k4ny +5kod +1kon +ko3ra +3kort +ko3v +1kra +5kry +ks3an +k1si +ks3k +ks1p +k3ste +k5stu +ks5v +k1t +k4tar +k4terh +kti4e +kt5re +kt5s +3kur +1kus +3kut +k4vo +k4vu +5lab +lad3r +5lagd +la4g3r +5lam +1lat +l1b +ldiagnos5 +l3dr +ld3st +1le. +5led +4lele +le4mo +3len +1ler +1les +4leu +l1f +lfin4 +lfind5 +l1go1 +l3h +li4ga +4l5ins +4l3int +li5o +l3j +l1ke +l1ko +l3ky +l1l +l5mu +lo4du +l3op +4l5or +3lov +4l3p +l4ps +l3r +4ls +lses1 +ls5in +l5sj +l1ta +l4taf +l1te +l4t5erf +l3ti +lt3o +l3tr +l3tu +lu5l +l3ve +l3vi +1ma +m1b +m3d +1me +4m5ej +m3f +m1g +m3h +1mi +mi3k +m5ing +mi4o +mi5sty +m3k +m1l +m1m +mmen5 +m1n +3mo +mo4da +4mop +4m5ov +m1pe +m3pi +m3pl +m1po +m3pr +m1r +mse5s +ms5in +m5sk +ms3p +m3ste +ms5v +m3ta +m3te +m3ti +m3tr +m1ud +1mul +mu1li +3my +3na +4nak +1nal +n1b +n1c +4nd +n3dr +nd5si +nd5sk +nd5sp +1ne +ne5a +ne4da +nemen4 +nement5e +neo4 +n3erk +n5erl +ne5sl +ne5st +n1f +n4go +4n1h +1ni +4nim +ni5o +ni3st +n1ke +n1ko +n3kr +n3ku +n5kv +4n1l +n1m +n1n +1no +n3ord +n5p +n3r +4ns +n3si +n1sku +ns3po +n1sta +n5sti +n1ta +nta4le +n1te +n1ti +ntiali4 +n3to +n1tr +nt4s5t +nt4su +n3tu +n3ty +4n1v +3ny +n3z +o3a +o4as +ob3li +o1c +o4din +od5ri +od5s +od5un +o1e +of5r +o4gek +o4gel +o4g5o +og5re +og5sk +o5h +o5in +oi6s5e +o1j +o3ka +o1ke +o3ku +o3la +o3le +o1li +o1lo +o3lu +o5ly +1omr +on3k +ook5 +o3or +o5ov +o3pi +op3l +op3r +op3s +3opta +4or. +or1an +3ordn +ord5s +o3re. +o3reg +o3rek +o3rer +o3re3s +o3ret +o3ri +3orient +or5im +o4r5in +or3k +or5o +or3sl +or3st +o3si +o3so +o3t +o1te +o5un +ov4s +3pa +pa5gh +p5anl +p3d +4pec +3pen +1per +pe1ra +pe5s +pe3u +p3f +4p5h +1pla +p4lan +4ple. +4pler +4ples +p3m +p3n +5pok +4po3re +3pot +4p5p4 +p4ro +1proc +p3sk +p5so +ps4p +p3st +p1t +1pu +pu5b +p5ule +p5v +5py3 +qu4 +4raf +ra5is +4rarb +r1b +r4d5ar +r3dr +rd4s3 +4reks +1rel +re5la +r5enss +5rese +re5spo +4ress +re3st +re5s4u +5rett +r1f +r1gu +r1h +ri1e +ri5la +4rimo +r4ing +ringse4 +ringso4r +4rinp +4rint +r3ka +r1ke +r1ki +rk3so +r3ku +r1l +rmo4 +r5mu +r1n +ro1b +ro3p +r3or +r3p +r1r +rre5s +rro4n5 +r1sa +r1si +r5skr +r4sk5v +rs4n +r3sp +r5stu +r5su +r3sv +r5tal +r1te +r4teli +r1ti +r3to +r4t5or +rt5rat +rt3re +r5tri +r5tro +rt3s +r5ty +r3ud +run4da +5rut +r3va +r1ve +r3vi +ry4s +s3af +1sam +sa4ma +s3ap +s1ar +1sat +4s1b +s1d +sdy4 +1se +s4ed +5s4er +se4se +s1f +4s1g4 +4s3h +si4bl +1sig +s5int +5sis +5sit +5siu +s5ju +4sk. +1skab +1ske +s3kl +sk5s4 +5sky +s1le +s1li +slo3 +5slu +s5ly +s1m +s4my +4snin +s4nit +so5k +5sol +5som. +3somm +s5oms +5somt +3son +4s1op +sp4 +3spec +4sper +3s4pi +s1pl +3sprog. +s5r4 +s1s4 +4st. +5s4tam +1stan +st5as +3stat +1stav +1ste. +1sted +3stel +5stemo +1sten +5step +3ster. +3stes +5stet +5stj +3sto +st5om +1str +s1ud +3sul +s3un +3sur +s3ve +3s4y +1sy1s +5ta. +1tag +tands3 +4tanv +4tb +tede4l +teds5 +3teg +5tekn +teo1 +5term +te5ro +4t1f +6t3g +t1h +tialis5t +3tid +ti4en +ti3st +4t3k +4t1l +tli4s5 +t1m +t1n +to5ra +to1re +to1ri +tor4m +4t3p +t4ra +4tres +tro5v +1try +4ts +t3si +ts4pa +ts5pr +t3st +ts5ul +4t1t +t5uds +5tur +t5ve +1typ +u1a +5udl +ud5r +ud3s +3udv +u1e +ue4t5 +uge4ri +ugs3 +u5gu +u3i +u5kl +uk4ta +uk4tr +u1la +u1le +u5ly +u5pe +up5l +u5q +u3ra +u3re +u4r3eg +u1rer +u3ro +us5a +u3si +u5ska +u5so +us5v +u1te +u1ti +u1to +ut5r +ut5s4 +5u5v +va5d +3varm +1ved +ve4l5e +ve4reg +ve3s +5vet +v5h +vi4l3in +1vis +v5j +v5k +vl4 +v3le +v5li +vls1 +1vo +4v5om +v5p +v5re +v3st +v5su +v5t +3vu +y3a +y5dr +y3e +y3ke +y5ki +yk3li +y3ko +yk4s5 +y3kv +y5li +y5lo +y5mu +yns5 +y5o +y1pe +y3pi +y3re +yr3ek +y3ri +y3si +y3ti +y5t3r +y5ve +zi5o + +.så3 +.ær5i +.øv3r +a3tø +a5væ +brød3 +5bæ +5drøv +dstå4 +3dæ +3dø +e3læ +e3lø +e3rø +er5øn +e5tæ +e5tø +e1væ +e3æ +e5å +3fæ +3fø +fø4r5en +giø4 +g4sø +g5så +3gæ +3gø1 +3gå +i5tæ +i3ø +3kø +3kå +lingeniø4 +l3væ +5løs +m5tå +1mæ +3mø +3må +n3kæ +n5tæ +3næ +4n5æb +5nø +o5læ +or3ø +o5å +5præ +5pæd +på3 +r5kæ +r5tæ +r5tø +r3væ +r5æl +4røn +5rør +3råd +r5år +s4kå +3slå +s4næ +5stø +1stå +1sæ +4s5æn +1sø +s5øk +så4r5 +ti4ø +3træk. +t4sø +t5så +t3væ +u3læ +3værd +1værk +5vå +y5væ +æb3l +æ3c +æ3e +æg5a +æ4gek +æ4g5r +ægs5 +æ5i +æ5kv +ælle4 +æn1dr +æ5o +æ1re +ær4g5r +æ3ri +ær4ma +ær4mo +ær5s +æ5si +æ3so +æ3ste +æ3ve +øde5 +ø3e +ø1je +ø3ke +ø3le +øms5 +øn3st +øn4t3 +ø1re +ø3ri +ørne3 +ør5o +ø1ve +å1d +å1e +å5h +å3l +å3re +års5t +å5sk +å3t + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/da_compoundDictionary.txt b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/da_compoundDictionary.txt new file mode 100644 index 00000000000..9a14f40c5f9 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/da_compoundDictionary.txt @@ -0,0 +1,19 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# A set of words for testing the HyphenationCompound factory, +# in conjunction with the danish hyphenation grammar. +læse +hest diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/elevate.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/elevate.xml new file mode 100644 index 00000000000..1befc5443e7 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/elevate.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/frenchArticles.txt b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/frenchArticles.txt new file mode 100644 index 00000000000..914161185f7 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/frenchArticles.txt @@ -0,0 +1,24 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# A set of articles for testing the French Elision filter. +# Requiring a text file is a bit weird here... +l +m +t +qu +n +s +j diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/fuzzysuggest.txt b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/fuzzysuggest.txt new file mode 100644 index 00000000000..94e2152160a --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/fuzzysuggest.txt @@ -0,0 +1,4 @@ +# simple fuzzy suggest phrase dictionary for testing +change 1.0 +charge 1.0 +chance 1.0 \ No newline at end of file diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/hunspell-test.aff b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/hunspell-test.aff new file mode 100644 index 00000000000..d035ad18001 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/hunspell-test.aff @@ -0,0 +1,13 @@ +SET UTF-8 +TRY abcdefghijklmopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + +SFX A Y 2 +SFX A 0 e n +SFX A 0 e t + +SFX C Y 2 +SFX C 0 d/C c +SFX C 0 c b + +PFX B Y 1 +PFX B 0 s o \ No newline at end of file diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/hunspell-test.dic b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/hunspell-test.dic new file mode 100644 index 00000000000..92c35d2b6ab --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/hunspell-test.dic @@ -0,0 +1,6 @@ +5 +lucen/A +lucene +mahout/A +olr/B +ab/C \ No newline at end of file diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/hyphenation.dtd b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/hyphenation.dtd new file mode 100644 index 00000000000..083c2bd8e80 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/hyphenation.dtd @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/jasuggest.txt b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/jasuggest.txt new file mode 100644 index 00000000000..6df149de61a --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/jasuggest.txt @@ -0,0 +1,5 @@ +# simple auto-suggest phrase dictionary for testing +# note this uses tabs as separator! +北海道 1.0 +今夜 3.0 +話した 6.0 \ No newline at end of file diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/keep-1.txt b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/keep-1.txt new file mode 100644 index 00000000000..8dfe80902d2 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/keep-1.txt @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +foo +bar \ No newline at end of file diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/keep-2.txt b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/keep-2.txt new file mode 100644 index 00000000000..646b7ff4ddb --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/keep-2.txt @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +junk +more \ No newline at end of file diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/mapping-ISOLatin1Accent.txt b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/mapping-ISOLatin1Accent.txt new file mode 100644 index 00000000000..ede7742581b --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/mapping-ISOLatin1Accent.txt @@ -0,0 +1,246 @@ +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Syntax: +# "source" => "target" +# "source".length() > 0 (source cannot be empty.) +# "target".length() >= 0 (target can be empty.) + +# example: +# "À" => "A" +# "\u00C0" => "A" +# "\u00C0" => "\u0041" +# "ß" => "ss" +# "\t" => " " +# "\n" => "" + +# À => A +"\u00C0" => "A" + +# Á => A +"\u00C1" => "A" + +#  => A +"\u00C2" => "A" + +# à => A +"\u00C3" => "A" + +# Ä => A +"\u00C4" => "A" + +# Å => A +"\u00C5" => "A" + +# Æ => AE +"\u00C6" => "AE" + +# Ç => C +"\u00C7" => "C" + +# È => E +"\u00C8" => "E" + +# É => E +"\u00C9" => "E" + +# Ê => E +"\u00CA" => "E" + +# Ë => E +"\u00CB" => "E" + +# Ì => I +"\u00CC" => "I" + +# Í => I +"\u00CD" => "I" + +# Î => I +"\u00CE" => "I" + +# Ï => I +"\u00CF" => "I" + +# IJ => IJ +"\u0132" => "IJ" + +# Ð => D +"\u00D0" => "D" + +# Ñ => N +"\u00D1" => "N" + +# Ò => O +"\u00D2" => "O" + +# Ó => O +"\u00D3" => "O" + +# Ô => O +"\u00D4" => "O" + +# Õ => O +"\u00D5" => "O" + +# Ö => O +"\u00D6" => "O" + +# Ø => O +"\u00D8" => "O" + +# Œ => OE +"\u0152" => "OE" + +# Þ +"\u00DE" => "TH" + +# Ù => U +"\u00D9" => "U" + +# Ú => U +"\u00DA" => "U" + +# Û => U +"\u00DB" => "U" + +# Ü => U +"\u00DC" => "U" + +# Ý => Y +"\u00DD" => "Y" + +# Ÿ => Y +"\u0178" => "Y" + +# à => a +"\u00E0" => "a" + +# á => a +"\u00E1" => "a" + +# â => a +"\u00E2" => "a" + +# ã => a +"\u00E3" => "a" + +# ä => a +"\u00E4" => "a" + +# å => a +"\u00E5" => "a" + +# æ => ae +"\u00E6" => "ae" + +# ç => c +"\u00E7" => "c" + +# è => e +"\u00E8" => "e" + +# é => e +"\u00E9" => "e" + +# ê => e +"\u00EA" => "e" + +# ë => e +"\u00EB" => "e" + +# ì => i +"\u00EC" => "i" + +# í => i +"\u00ED" => "i" + +# î => i +"\u00EE" => "i" + +# ï => i +"\u00EF" => "i" + +# ij => ij +"\u0133" => "ij" + +# ð => d +"\u00F0" => "d" + +# ñ => n +"\u00F1" => "n" + +# ò => o +"\u00F2" => "o" + +# ó => o +"\u00F3" => "o" + +# ô => o +"\u00F4" => "o" + +# õ => o +"\u00F5" => "o" + +# ö => o +"\u00F6" => "o" + +# ø => o +"\u00F8" => "o" + +# œ => oe +"\u0153" => "oe" + +# ß => ss +"\u00DF" => "ss" + +# þ => th +"\u00FE" => "th" + +# ù => u +"\u00F9" => "u" + +# ú => u +"\u00FA" => "u" + +# û => u +"\u00FB" => "u" + +# ü => u +"\u00FC" => "u" + +# ý => y +"\u00FD" => "y" + +# ÿ => y +"\u00FF" => "y" + +# ff => ff +"\uFB00" => "ff" + +# fi => fi +"\uFB01" => "fi" + +# fl => fl +"\uFB02" => "fl" + +# ffi => ffi +"\uFB03" => "ffi" + +# ffl => ffl +"\uFB04" => "ffl" + +# ſt => ft +"\uFB05" => "ft" + +# st => st +"\uFB06" => "st" diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/missing.functions.updateprocessor.js b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/missing.functions.updateprocessor.js new file mode 100644 index 00000000000..6e8728a0d77 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/missing.functions.updateprocessor.js @@ -0,0 +1,3 @@ +function doSomeStuff() { + return "This script doesn't contain any update processor functions"; +} diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/missleading.extension.updateprocessor.js.txt b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/missleading.extension.updateprocessor.js.txt new file mode 100644 index 00000000000..984e1d82f10 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/missleading.extension.updateprocessor.js.txt @@ -0,0 +1,23 @@ +function processAdd(cmd) { + // Integer.valueOf is needed here to get a tru java object, because + // all javascript numbers are floating point (ie: java.lang.Double) + cmd.getSolrInputDocument().addField("script_added_i", + java.lang.Integer.valueOf(42)); + cmd.getSolrInputDocument().addField("script_added_d", 42.3); + +} +function processDelete() { + // NOOP +} +function processCommit() { + // NOOP +} +function processRollback() { + // NOOP +} +function processMergeIndexes() { + // NOOP +} +function finish() { + // NOOP +} diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/old_synonyms.txt b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/old_synonyms.txt new file mode 100644 index 00000000000..a7624f0597d --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/old_synonyms.txt @@ -0,0 +1,22 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +a => aa +b => b1 b2 +c => c1,c2 +a\=>a => b\=>b +a\,a => b\,b +foo,bar,baz + +Television,TV,Televisions diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/open-exchange-rates.json b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/open-exchange-rates.json new file mode 100644 index 00000000000..8fbc217f6e9 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/open-exchange-rates.json @@ -0,0 +1,18 @@ +{ + "disclaimer": "This data is not real, it was synthetically created to match currency.xml. It is modeled after the data format available from openexchangerates.org. See https://openexchangerates.org/documentation for details", + "license": "http://www.apache.org/licenses/LICENSE-2.0", + "timestamp": 1332070464, + + + "IMPORTANT NOTE": "In order for tests to work, this data must be kept in sync with ./currency.xml", + + + "base": "USD", + "rates": { + "USD": 1, + "JPY": 81.29, + "EUR": 2.5, + "GBP": 0.5, + "MXN": 2.0 + } +} diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/phrasesuggest.txt b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/phrasesuggest.txt new file mode 100644 index 00000000000..fd4984d70b8 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/phrasesuggest.txt @@ -0,0 +1,8 @@ +# simple auto-suggest phrase dictionary for testing +# note this uses tabs as separator! +the first phrase 1.0 +the second phrase 2.0 +testing 1234 3.0 +foo 5.0 +the fifth phrase 2.0 +the final phrase 4.0 diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/protwords.txt b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/protwords.txt new file mode 100644 index 00000000000..ab7e3e2470e --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/protwords.txt @@ -0,0 +1,23 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#use a protected word file to avoid stemming two +#unrelated words to the same base word. +#to test, we will use words that would normally obviously be stemmed. +cats +ridding +c# +c++ +.net diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/regex-boost-processor-test.txt b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/regex-boost-processor-test.txt new file mode 100644 index 00000000000..1dc0537c72b --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/regex-boost-processor-test.txt @@ -0,0 +1,10 @@ +# Sample config file for RegexBoostProcessor +# This example applies boost on the "url" field to boost or deboost certain urls +# All rules are evaluated, and if several of them match, the boosts are multiplied. +# If for example one rule with boost 2.0 and one rule with boost 0.1 match, the resulting urlboost=0.2 + +https?://[^/]+/old/.* 0.1 #Comments are removed +https?://[^/]+/.*index\([0-9]\).html$ 0.5 + +# Prioritize certain sites over others +https?://www.mydomain.no/.* 1.5 \ No newline at end of file diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-add-schema-fields-update-processor.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-add-schema-fields-update-processor.xml new file mode 100644 index 00000000000..2b59472f5f0 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-add-schema-fields-update-processor.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-behavior.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-behavior.xml new file mode 100644 index 00000000000..20b5a3533b9 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-behavior.xml @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-binaryfield.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-binaryfield.xml new file mode 100644 index 00000000000..1f9312e61d0 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-binaryfield.xml @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-bm25.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-bm25.xml new file mode 100644 index 00000000000..54bdc0566aa --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-bm25.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + 1.2 + 0.76 + + + + + + + + + + + + text + id + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-charfilters.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-charfilters.xml new file mode 100644 index 00000000000..5eaab1f19e5 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-charfilters.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + content + id + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-class-name-shortening-on-serialization.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-class-name-shortening-on-serialization.xml new file mode 100644 index 00000000000..46a1321260c --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-class-name-shortening-on-serialization.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-collate.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-collate.xml new file mode 100644 index 00000000000..7feb73a3015 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-collate.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text + id + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-copyfield-test.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-copyfield-test.xml new file mode 100644 index 00000000000..3ab7837284f --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-copyfield-test.xml @@ -0,0 +1,482 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text + id + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-dfr.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-dfr.xml new file mode 100644 index 00000000000..c4f7d8331dd --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-dfr.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + I(F) + B + H2 + + + + + + + + I(F) + B + H3 + 900 + + + + + + + + P + L + H2 + 7 + + + + + + + + + + + + + text + id + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-docValues.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-docValues.xml new file mode 100644 index 00000000000..63d87997402 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-docValues.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-docValuesFaceting.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-docValuesFaceting.xml new file mode 100755 index 00000000000..0e3116d0797 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-docValuesFaceting.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + id + id + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-docValuesMissing.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-docValuesMissing.xml new file mode 100644 index 00000000000..3e39c2c40ac --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-docValuesMissing.xml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-docValuesMulti.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-docValuesMulti.xml new file mode 100644 index 00000000000..6d58feda4e5 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-docValuesMulti.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-eff.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-eff.xml new file mode 100644 index 00000000000..60cab4f8601 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-eff.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + id + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-folding.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-folding.xml new file mode 100644 index 00000000000..c2a0e60f3ed --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-folding.xml @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + content + id + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-ib.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-ib.xml new file mode 100644 index 00000000000..3d55b2ac70b --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-ib.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + SPL + DF + H2 + + + + + + + + LL + TTF + H3 + 900 + + + + + + + + + + + + text + id + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-id-and-version-fields-only.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-id-and-version-fields-only.xml new file mode 100644 index 00000000000..9f5059f26c1 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-id-and-version-fields-only.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + id + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-lmdirichlet.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-lmdirichlet.xml new file mode 100644 index 00000000000..f39922f7c45 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-lmdirichlet.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + 1000 + + + + + + + + + + + + text + id + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-lmjelinekmercer.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-lmjelinekmercer.xml new file mode 100644 index 00000000000..49b692e8d90 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-lmjelinekmercer.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + 0.4 + + + + + + + + + + + + text + id + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-luceneMatchVersion.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-luceneMatchVersion.xml new file mode 100644 index 00000000000..3bb2b491b3b --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-luceneMatchVersion.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-minimal.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-minimal.xml new file mode 100644 index 00000000000..9e2f9471026 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-minimal.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-not-required-unique-key.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-not-required-unique-key.xml new file mode 100644 index 00000000000..b3869812375 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-not-required-unique-key.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + subject + id + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-numeric.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-numeric.xml new file mode 100644 index 00000000000..d00545ed102 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-numeric.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-one-field-no-dynamic-field-unique-key.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-one-field-no-dynamic-field-unique-key.xml new file mode 100644 index 00000000000..783ae77c958 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-one-field-no-dynamic-field-unique-key.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + str + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-one-field-no-dynamic-field.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-one-field-no-dynamic-field.xml new file mode 100644 index 00000000000..035f975d6b2 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-one-field-no-dynamic-field.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-phrasesuggest.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-phrasesuggest.xml new file mode 100644 index 00000000000..f5ed9155e66 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-phrasesuggest.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text + id + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-postingshighlight.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-postingshighlight.xml new file mode 100644 index 00000000000..e58b2e82eaf --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-postingshighlight.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text + id + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-replication1.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-replication1.xml new file mode 100644 index 00000000000..fe123dfa6d0 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-replication1.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + id + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-replication2.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-replication2.xml new file mode 100644 index 00000000000..a2409459aa7 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-replication2.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + id + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-required-fields.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-required-fields.xml new file mode 100644 index 00000000000..8dea7914549 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-required-fields.xml @@ -0,0 +1,436 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text + id + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-rest-lucene-match-version.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-rest-lucene-match-version.xml new file mode 100644 index 00000000000..15caf81c67d --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-rest-lucene-match-version.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-rest.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-rest.xml new file mode 100755 index 00000000000..a735e434bc7 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-rest.xml @@ -0,0 +1,624 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text + id + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-reversed.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-reversed.xml new file mode 100644 index 00000000000..40fc0e8e2f5 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-reversed.xml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + one + id + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-sim.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-sim.xml new file mode 100644 index 00000000000..ca2bd788b38 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-sim.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + is there an echo? + + + + + + + + + + + + + + + + + + + + + + + + sim1text + id + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-snippet-field.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-snippet-field.xml new file mode 100644 index 00000000000..9e0d29f3e20 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-snippet-field.xml @@ -0,0 +1,3 @@ + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-snippet-type.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-snippet-type.xml new file mode 100644 index 00000000000..bfbd3334204 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-snippet-type.xml @@ -0,0 +1,3 @@ + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-snippet-types.incl b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-snippet-types.incl new file mode 100644 index 00000000000..fe9fd6d7a7b --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-snippet-types.incl @@ -0,0 +1,19 @@ + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-spatial.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-spatial.xml new file mode 100644 index 00000000000..d1ca1f701cd --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-spatial.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-spellchecker.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-spellchecker.xml new file mode 100644 index 00000000000..7124065626d --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-spellchecker.xml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id + + + text + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-stop-keep.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-stop-keep.xml new file mode 100644 index 00000000000..831539ee8be --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-stop-keep.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + one + id + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-sweetspot.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-sweetspot.xml new file mode 100644 index 00000000000..350e2e90851 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-sweetspot.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + 6.0 + 1.5 + + 3 + 5 + 0.5 + + + + + + + + 3.3 + 7.7 + 2.718281828459045 + 5.0 + + 1 + 5 + 0.2 + + + + + + + + + + + + + text + id + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-synonym-tokenizer.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-synonym-tokenizer.xml new file mode 100644 index 00000000000..0906a13bfb5 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-synonym-tokenizer.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + text + id + \ No newline at end of file diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-tfidf.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-tfidf.xml new file mode 100644 index 00000000000..eacea9009a8 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-tfidf.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + text + id + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-tiny.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-tiny.xml new file mode 100644 index 00000000000..08e0aebc42f --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-tiny.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + id + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-trie.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-trie.xml new file mode 100644 index 00000000000..1819bfa9020 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-trie.xml @@ -0,0 +1,332 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id + + + text + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-xinclude.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-xinclude.xml new file mode 100644 index 00000000000..94194df6192 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-xinclude.xml @@ -0,0 +1,30 @@ + + +]> + + + + + + &schema_entity_include; + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema.xml new file mode 100644 index 00000000000..a22844de0c4 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema.xml @@ -0,0 +1,712 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text + id + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + I am your default sim + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema11.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema11.xml new file mode 100755 index 00000000000..a993cbd6f61 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema11.xml @@ -0,0 +1,387 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id + + + text + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema12.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema12.xml new file mode 100755 index 00000000000..506e08d787a --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema12.xml @@ -0,0 +1,618 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text + id + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema15.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema15.xml new file mode 100755 index 00000000000..b05e1a7ce9e --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema15.xml @@ -0,0 +1,604 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text + id + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema_codec.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema_codec.xml new file mode 100644 index 00000000000..4e49dce953e --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema_codec.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + string_f + string_f + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schemasurround.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schemasurround.xml new file mode 100644 index 00000000000..04e90e33678 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schemasurround.xml @@ -0,0 +1,608 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text + id + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-SOLR-749.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-SOLR-749.xml new file mode 100644 index 00000000000..1fabd5c202f --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-SOLR-749.xml @@ -0,0 +1,29 @@ + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-add-schema-fields-update-processor-chains.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-add-schema-fields-update-processor-chains.xml new file mode 100644 index 00000000000..9a59d90820a --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-add-schema-fields-update-processor-chains.xml @@ -0,0 +1,155 @@ + + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + + true + managed-schema + + + + + text + + java.lang.Boolean + boolean + + + java.lang.Integer + tint + + + java.lang.Float + tfloat + + + java.util.Date + tdate + + + java.lang.Long + java.lang.Integer + tlong + + + + java.lang.Double + java.lang.Float + + tdouble + + + + + + + text + + java.lang.Boolean + boolean + + + java.lang.Integer + tint + + + java.lang.Float + tfloat + + + java.util.Date + tdate + + + java.lang.Long + java.lang.Integer + tlong + + + java.lang.Number + tdouble + + + + + + + + + + + + yyyy-MM-dd'T'HH:mm:ss.SSSZ + yyyy-MM-dd'T'HH:mm:ss,SSSZ + yyyy-MM-dd'T'HH:mm:ss.SSS + yyyy-MM-dd'T'HH:mm:ss,SSS + yyyy-MM-dd'T'HH:mm:ssZ + yyyy-MM-dd'T'HH:mm:ss + yyyy-MM-dd'T'HH:mmZ + yyyy-MM-dd'T'HH:mm + yyyy-MM-dd HH:mm:ss.SSSZ + yyyy-MM-dd HH:mm:ss,SSSZ + yyyy-MM-dd HH:mm:ss.SSS + yyyy-MM-dd HH:mm:ss,SSS + yyyy-MM-dd HH:mm:ssZ + yyyy-MM-dd HH:mm:ss + yyyy-MM-dd HH:mmZ + yyyy-MM-dd HH:mm + yyyy-MM-dd + + + + text + + java.lang.Boolean + boolean + + + java.lang.Integer + tint + + + java.lang.Float + tfloat + + + java.util.Date + tdate + + + java.lang.Long + java.lang.Integer + tlong + + + java.lang.Number + tdouble + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-altdirectory.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-altdirectory.xml new file mode 100755 index 00000000000..3105baf5157 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-altdirectory.xml @@ -0,0 +1,26 @@ + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-basic.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-basic.xml new file mode 100644 index 00000000000..03963023ae1 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-basic.xml @@ -0,0 +1,29 @@ + + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + ${solr.data.dir:} + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-caching.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-caching.xml new file mode 100644 index 00000000000..0de6f9412f7 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-caching.xml @@ -0,0 +1,39 @@ + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-components-name.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-components-name.xml new file mode 100644 index 00000000000..b5501d85508 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-components-name.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + ${solr.data.dir:} + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + + + + true + + component1 + + + component2 + + + + + + + + + + max-age=30, public + + + + + solr + solrconfig.xml schema.xml admin-extra.html + + + + foo + + + bar + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-defaults.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-defaults.xml new file mode 100644 index 00000000000..fe39eef6a3e --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-defaults.xml @@ -0,0 +1,43 @@ + + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-delpolicy1.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-delpolicy1.xml new file mode 100644 index 00000000000..5cd0e7edf1a --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-delpolicy1.xml @@ -0,0 +1,51 @@ + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + + + + + + ${useCompoundFile:false} + + ${solr.tests.maxBufferedDocs} + ${solr.tests.maxIndexingThreads} + ${solr.tests.ramBufferSizeMB} + + + + single + + + + true + 3 + 100MILLISECONDS + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-delpolicy2.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-delpolicy2.xml new file mode 100644 index 00000000000..9925a1e1b69 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-delpolicy2.xml @@ -0,0 +1,48 @@ + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + + + ${useCompoundFile:false} + + ${solr.tests.maxBufferedDocs} + ${solr.tests.maxIndexingThreads} + ${solr.tests.ramBufferSizeMB} + + + + single + + + value1 + value2 + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-elevate.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-elevate.xml new file mode 100644 index 00000000000..b7dc855a0c5 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-elevate.xml @@ -0,0 +1,178 @@ + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + ${solr.data.dir:} + + + + + + + + + + + + + + + + + + + 1024 + + + + + + + + + + true + + 10 + + + + + + + + + + + + + + string + ${elevate.file:elevate.xml} + + + + + + string + ${elevate.data.file:elevate-data.xml} + + + + + explicit + + + elevate + + + + + + explicit + + + dataElevate + + + + + + + + + + max-age=30, public + + + + + solr + solrconfig.xml schema.xml admin-extra.html + + + + prefix-${solr.test.sys.prop2}-suffix + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-functionquery.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-functionquery.xml new file mode 100755 index 00000000000..1a1a4ffca62 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-functionquery.xml @@ -0,0 +1,43 @@ + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + + + + + + + + + + + + + 0.0 + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-highlight.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-highlight.xml new file mode 100644 index 00000000000..7d55cc2adef --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-highlight.xml @@ -0,0 +1,60 @@ + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + + + + + + + + + + + + + + 100 + + + + + + 70 + + + + + + + ]]> + ]]> + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-implicitproperties.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-implicitproperties.xml new file mode 100644 index 00000000000..a54168c38cd --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-implicitproperties.xml @@ -0,0 +1,79 @@ + + + + + + + LUCENE_41 + + ${solr.data.dir:} + + + + + + + + + + + + true + 20 + 20 + + true + + 1 + + + + + + + + + + + + all + text + ${solr.core.name} + ${solr.core.dataDir} + ${solr.core.config} + ${solr.core.schema} + ${solr.core.transient} + + + + + + + + + text/plain; charset=UTF-8 + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-indexconfig.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-indexconfig.xml new file mode 100644 index 00000000000..066f8632e96 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-indexconfig.xml @@ -0,0 +1,30 @@ + + + + + ${solr.data.dir:} + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + ${useCompoundFile:false} + 123 + true + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-infostream-logging.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-infostream-logging.xml new file mode 100644 index 00000000000..722f5e42265 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-infostream-logging.xml @@ -0,0 +1,27 @@ + + + + + ${solr.data.dir:} + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + true + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-lazywriter.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-lazywriter.xml new file mode 100644 index 00000000000..0636a1dcfac --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-lazywriter.xml @@ -0,0 +1,28 @@ + + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-logmergepolicy.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-logmergepolicy.xml new file mode 100644 index 00000000000..371bfb5638d --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-logmergepolicy.xml @@ -0,0 +1,37 @@ + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + + -1 + -1 + -1 + + 11 + 456 + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-managed-schema.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-managed-schema.xml new file mode 100644 index 00000000000..fc49a7b1c8c --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-managed-schema.xml @@ -0,0 +1,51 @@ + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + + ${managed.schema.mutable} + managed-schema + + + + + + + ${solr.ulog.dir:} + + + + + true + + + + + true + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master.xml new file mode 100644 index 00000000000..9118bef45f0 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master.xml @@ -0,0 +1,72 @@ + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + ${solr.data.dir:} + + + + + + + + true + + + + + commit + + schema.xml,xslt/dummy.xsl + + + + + + + 4 + true + text,name,subject,title,whitetok + + + + + + + 4 + true + text,name,subject,title,whitetok + + + + + + + + + + max-age=30, public + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master1-keepOneBackup.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master1-keepOneBackup.xml new file mode 100644 index 00000000000..30b4e3b7cb6 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master1-keepOneBackup.xml @@ -0,0 +1,49 @@ + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + ${solr.data.dir:} + + + + + + + + + + + + commit + schema-replication2.xml:schema.xml + + 1 + + + + + + + + + max-age=30, public + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master1.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master1.xml new file mode 100644 index 00000000000..2e9885f4478 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master1.xml @@ -0,0 +1,69 @@ + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + ${solr.data.dir:} + + + + + + + + + true + + + + + commit + schema-replication2.xml:schema.xml + + + + + + + 4 + true + text,name,subject,title,whitetok + + + + + + + 4 + true + text,name,subject,title,whitetok + + + + + + + + + + max-age=30, public + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master2.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master2.xml new file mode 100644 index 00000000000..21d38a3af94 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master2.xml @@ -0,0 +1,69 @@ + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + ${solr.data.dir:} + + + + + + + + + true + + + + + startup + schema.xml + + + + + + + 4 + true + text,name,subject,title,whitetok + + + + + + + 4 + true + text,name,subject,title,whitetok + + + + + + + + + + max-age=30, public + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master3.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master3.xml new file mode 100644 index 00000000000..b19073ba0ef --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master3.xml @@ -0,0 +1,70 @@ + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + ${solr.data.dir:} + + + + + + + + + true + + + + + commit + startup + schema.xml + + + + + + + 4 + true + text,name,subject,title,whitetok + + + + + + + 4 + true + text,name,subject,title,whitetok + + + + + + + + + + max-age=30, public + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-mergepolicy-defaults.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-mergepolicy-defaults.xml new file mode 100644 index 00000000000..9d2a99aff4d --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-mergepolicy-defaults.xml @@ -0,0 +1,32 @@ + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-mergepolicy-legacy.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-mergepolicy-legacy.xml new file mode 100644 index 00000000000..00c77ae5e78 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-mergepolicy-legacy.xml @@ -0,0 +1,31 @@ + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + 7 + ${useCompoundFile:false} + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-minimal.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-minimal.xml new file mode 100644 index 00000000000..78a4eb711d3 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-minimal.xml @@ -0,0 +1,75 @@ + + + + + + + LUCENE_41 + + ${solr.data.dir:} + + + + + + + + + + + + true + 20 + 20 + + true + + 1 + + + + + + + + + + + explicit + json + true + text + + + + + + + + + text/plain; charset=UTF-8 + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-nocache.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-nocache.xml new file mode 100644 index 00000000000..ee27d0c49de --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-nocache.xml @@ -0,0 +1,41 @@ + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + + + ${solr.data.dir:} + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-noopregen.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-noopregen.xml new file mode 100644 index 00000000000..4537724b433 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-noopregen.xml @@ -0,0 +1,36 @@ + + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + ${solr.data.dir:} + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-parsing-update-processor-chains.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-parsing-update-processor-chains.xml new file mode 100644 index 00000000000..3c41f507158 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-parsing-update-processor-chains.xml @@ -0,0 +1,230 @@ + + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + + + yyyy-MM-dd'T'HH:mm:ss.SSSZ + + + + + + + yyyy-MM-dd'T'HH:mm:ss.SSSZ + + + + + + false + yyyy-MM-dd'T'HH:mm:ss.SSSZ + + + + + + solr.DateField + solr.TrieDateField + yyyy-MM-dd'T'HH:mm:ss.SSSZ + + + + + + America/New_York + en_US + yyyy-MM-dd'T'HH:mm:ss.SSSZ + yyyy-MM-dd'T'HH:mm:ss.SSS + + + + + + + America/Los_Angeles + + MM/dd/yyyy + + + + + + + UTC + en_US + + yyyy-MM-dd'T'HH:mm:ss.SSSZ + yyyy-MM-dd'T'HH:mm:ss,SSSZ + yyyy-MM-dd'T'HH:mm:ss.SSS + yyyy-MM-dd'T'HH:mm:ss,SSS + yyyy-MM-dd'T'HH:mm:ssZ + yyyy-MM-dd'T'HH:mm:ss + yyyy-MM-dd'T'HH:mmZ + yyyy-MM-dd'T'HH:mm + yyyy-MM-dd HH:mm:ss.SSSZ + yyyy-MM-dd HH:mm:ss,SSSZ + yyyy-MM-dd HH:mm:ss.SSS + yyyy-MM-dd HH:mm:ss,SSS + yyyy-MM-dd HH:mm:ssZ + yyyy-MM-dd HH:mm:ss + yyyy-MM-dd HH:mmZ + yyyy-MM-dd HH:mm + yyyy-MM-dd hh:mm a + yyyy-MM-dd hh:mma + yyyy-MM-dd + EEE MMM dd HH:mm:ss Z yyyy + EEE MMM dd HH:mm:ss yyyy Z + EEE MMM dd HH:mm:ss yyyy + EEE, dd MMM yyyy HH:mm:ss Z + EEEE, dd-MMM-yy HH:mm:ss Z + EEEE, MMMM dd, yyyy + MMMM dd, yyyy + MMM. dd, yyyy + + + + + + + UTC + fr + 'le' EEEE dd MMMM yyyy + + + + + + + + + + + + + + + ru_RU + + + + + + + + + + + + + + + ru_RU + + + + + + + + + + + + + + + fr_FR + + + + + + + + + + + + + + + fr_FR + + + + + + + + + + + + + + + false + + true + YES + on + + + false + no + oFF + + + + + + + yup + nope + + + + + + + + + + + + + + + + yyyy-MM-dd + yyyy-MM-dd'T'HH:mm:ss.SSSZ + yyyy-MM-dd'T'HH:mm + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-phrasesuggest.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-phrasesuggest.xml new file mode 100644 index 00000000000..b4f560ed32f --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-phrasesuggest.xml @@ -0,0 +1,272 @@ + + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + ${solr.data.dir:} + + + + + + + suggest_wfst + org.apache.solr.spelling.suggest.Suggester + org.apache.solr.spelling.suggest.fst.WFSTLookupFactory + suggest_wfst + false + + + true + + phrasesuggest.txt + + + + phrase_suggest + + + + + + suggest_analyzing + org.apache.solr.spelling.suggest.Suggester + org.apache.solr.spelling.suggest.fst.AnalyzingLookupFactory + suggest_analyzing + false + + + true + ja_suggest + false + + jasuggest.txt + + + + phrase_suggest + + + + + + infix_suggest_analyzing + org.apache.solr.spelling.suggest.Suggester + org.apache.solr.spelling.suggest.fst.AnalyzingInfixLookupFactory + false + + + text + + analyzingInfixSuggest.txt + + + + phrase_suggest + + + + + + fuzzy_suggest_analyzing + org.apache.solr.spelling.suggest.Suggester + org.apache.solr.spelling.suggest.fst.FuzzyLookupFactory + fuzzy_suggest_analyzing + false + + + true + text + false + + fuzzysuggest.txt + + + + phrase_suggest + + + + + + fuzzy_suggest_analyzing_with_max_edit_2 + org.apache.solr.spelling.suggest.Suggester + org.apache.solr.spelling.suggest.fst.FuzzyLookupFactory + fuzzy_suggest_analyzing_with_max_edit_2 + false + + + true + text + false + 2 + + fuzzysuggest.txt + + + + phrase_suggest + + + + + + fuzzy_suggest_analyzing_with_non_fuzzy_prefix_4 + org.apache.solr.spelling.suggest.Suggester + org.apache.solr.spelling.suggest.fst.FuzzyLookupFactory + fuzzy_suggest_analyzing_with_non_fuzzy_prefix_4 + false + + + true + text + false + 4 + + fuzzysuggest.txt + + + + phrase_suggest + + + + + + fuzzy_suggest_analyzing_with_min_fuzzy_length_2 + org.apache.solr.spelling.suggest.Suggester + org.apache.solr.spelling.suggest.fst.FuzzyLookupFactory + fuzzy_suggest_analyzing_with_min_fuzzy_length_2 + false + + + true + text + false + 2 + + fuzzysuggest.txt + + + + phrase_suggest + + + + + + + + + true + suggest_wfst + false + + true + + + suggest_wfst + + + + + + + true + suggest_analyzing + false + + true + + + suggest_analyzing + + + + + + + true + infix_suggest_analyzing + false + + true + + + infix_suggest_analyzing + + + + + + true + fuzzy_suggest_analyzing + false + + true + + + fuzzy_suggest_analyzing + + + + + + + true + fuzzy_suggest_analyzing_with_max_edit_2 + false + + true + + + fuzzy_suggest_analyzing_with_max_edit_2 + + + + + + + true + fuzzy_suggest_analyzing_with_non_fuzzy_prefix_4 + false + + true + + + fuzzy_suggest_analyzing_with_non_fuzzy_prefix_4 + + + + + + + true + fuzzy_suggest_analyzing_with_min_fuzzy_length_2 + false + + true + + + fuzzy_suggest_analyzing_with_min_fuzzy_length_2 + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-postingshighlight.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-postingshighlight.xml new file mode 100644 index 00000000000..c3d9d544e1f --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-postingshighlight.xml @@ -0,0 +1,34 @@ + + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + ${solr.data.dir:} + + + + + false + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-querysender-noquery.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-querysender-noquery.xml new file mode 100644 index 00000000000..af6cc75112d --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-querysender-noquery.xml @@ -0,0 +1,74 @@ + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-querysender.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-querysender.xml new file mode 100644 index 00000000000..12252c06b6f --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-querysender.xml @@ -0,0 +1,70 @@ + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + + + + + + + + + + + + + + solr 0 10 mock + rocks 0 10 mock + + + + + + + + fast_warm 0 10 + mock + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-repeater.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-repeater.xml new file mode 100644 index 00000000000..5ec8e5920b3 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-repeater.xml @@ -0,0 +1,63 @@ + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + ${solr.data.dir:} + + + + + + + + true + + + + + + + + + + + + + + + + commit + schema.xml + + + http://127.0.0.1:TEST_PORT/solr/replication + + + + + + + + max-age=30, public + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-reqHandler.incl b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-reqHandler.incl new file mode 100644 index 00000000000..03f236fccf7 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-reqHandler.incl @@ -0,0 +1,5 @@ + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-response-log-component.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-response-log-component.xml new file mode 100644 index 00000000000..859883d52f0 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-response-log-component.xml @@ -0,0 +1,54 @@ + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + + ${solr.data.dir:} + + + + + + + + + + dismax + + + responselog + + + + + + dismax + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-script-updateprocessor.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-script-updateprocessor.xml new file mode 100644 index 00000000000..43fbc2873da --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-script-updateprocessor.xml @@ -0,0 +1,112 @@ + + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + + + + javascript + missleading.extension.updateprocessor.js.txt + + + + + + + + + + + + trivial.updateprocessor0.js + + true + 1 + + + + + + + + + trivial.updateprocessor0.js + trivial.updateprocessor1.js + + + true + 1 + + + + + + + + trivial.updateprocessor0.js + trivial.updateprocessor1.js + + true + 1 + + + + + + + + + conditional.updateprocessor.js + addfields.updateprocessor.js + + + + + + + conditional.updateprocessor.js + + + addfields.updateprocessor.js + + + + + + throw.error.on.add.updateprocessor.js + + + + + missing.functions.updateprocessor.js + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-slave.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-slave.xml new file mode 100644 index 00000000000..ac2e59ee56e --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-slave.xml @@ -0,0 +1,61 @@ + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + ${solr.data.dir:} + + + + + + + + true + + + + + + + + + + + + + + + + http://127.0.0.1:TEST_PORT/solr + 00:00:01 + COMPRESSION + + + + + + + + max-age=30, public + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-slave1.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-slave1.xml new file mode 100644 index 00000000000..36d6d92e146 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-slave1.xml @@ -0,0 +1,57 @@ + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + ${solr.data.dir:} + + + + + + + + + true + + + + + + + + + + + + + + + + + + + + + + max-age=30, public + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-snippet-processor.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-snippet-processor.xml new file mode 100644 index 00000000000..8c76857f32b --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-snippet-processor.xml @@ -0,0 +1,6 @@ + + + field-included + x + x_x + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-solcoreproperties.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-solcoreproperties.xml new file mode 100644 index 00000000000..3a1547f1b1c --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-solcoreproperties.xml @@ -0,0 +1,35 @@ + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + ${solr.data.dir:} + + + + + + + + ${foo.foo1} + ${foo.foo2} + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-spellcheckcomponent.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-spellcheckcomponent.xml new file mode 100644 index 00000000000..9092a5875a8 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-spellcheckcomponent.xml @@ -0,0 +1,178 @@ + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + + ${solr.data.dir:} + + + + + + + lowerpunctfilt + + + default + lowerfilt + spellchecker1 + true + + + default_teststop + default_teststop + true + teststop + + + direct + solr.DirectSolrSpellChecker + 3 + 100 + teststop + + + direct_lowerfilt + solr.DirectSolrSpellChecker + 3 + 100 + lowerfilt + + + wordbreak + solr.WordBreakSolrSpellChecker + lowerfilt + true + true + MAX_FREQ + 10 + + + threshold + lowerfilt + spellcheckerThreshold + true + .29 + + + threshold_direct + solr.DirectSolrSpellChecker + lowerfilt + spellcheckerThreshold + true + .29 + + + multipleFields + lowerfilt1and2 + spellcheckerMultipleFields + true + + + + jarowinkler + lowerfilt + + org.apache.lucene.search.spell.JaroWinklerDistance + spellchecker2 + + + + solr.FileBasedSpellChecker + external + spellings.txt + UTF-8 + spellchecker3 + + + + freq + lowerfilt + spellcheckerFreq + + freq + true + + + fqcn + lowerfilt + spellcheckerFQCN + org.apache.solr.spelling.SampleComparator + true + + + perDict + org.apache.solr.handler.component.DummyCustomParamSpellChecker + lowerfilt + + + + + + + + + + false + + false + + 1 + + + spellcheck + + + + + dismax + lowerfilt1^1 + + + spellcheck + + + + + default + wordbreak + 20 + + + spellcheck + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-spellchecker.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-spellchecker.xml new file mode 100644 index 00000000000..e6744cb3944 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-spellchecker.xml @@ -0,0 +1,142 @@ + + + + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + + + + + + + suggest + org.apache.solr.spelling.suggest.Suggester + org.apache.solr.spelling.suggest.jaspell.JaspellLookup + suggest + suggest + true + + + 0.0 + + + + + + + suggest_tst + org.apache.solr.spelling.suggest.Suggester + org.apache.solr.spelling.suggest.tst.TSTLookup + suggest + suggest_tst + true + + + 0.0 + + + + + + + suggest_fst + org.apache.solr.spelling.suggest.Suggester + org.apache.solr.spelling.suggest.fst.FSTLookup + suggest + suggest_fst + true + + + 5 + true + + + + + + + suggest_wfst + org.apache.solr.spelling.suggest.Suggester + org.apache.solr.spelling.suggest.fst.WFSTLookupFactory + suggest + suggest_wfst + true + + + true + + + + + + + true + suggest + true + + + suggest_jaspell + + + + + + + true + suggest_tst + true + + + suggest_tst + + + + + + + true + suggest_fst + false + + + suggest_fst + + + + + + + true + suggest_wfst + false + + + suggest_wfst + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-test-misc.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-test-misc.xml new file mode 100644 index 00000000000..fdca7893d92 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-test-misc.xml @@ -0,0 +1,52 @@ + + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + + + solr + solrconfig.xml schema.xml admin-extra.html + + + + + + + + + + prefix-${solr.test.sys.prop2}-suffix + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-tieredmergepolicy.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-tieredmergepolicy.xml new file mode 100644 index 00000000000..86a79fbf8fc --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-tieredmergepolicy.xml @@ -0,0 +1,47 @@ + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + 7 + + 19 + 9 + 0.1 + + + ${useCompoundFile:false} + + + + 987 + 42 + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-tlog.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-tlog.xml new file mode 100644 index 00000000000..d55845c13d0 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-tlog.xml @@ -0,0 +1,120 @@ + + + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + ${solr.hdfs.blockcache.enabled:true} + ${solr.hdfs.blockcache.blocksperbank:1024} + ${solr.hdfs.home:} + ${solr.hdfs.confdir:} + + + ${solr.data.dir:} + + + + + + + + + + + + + + + true + + + + + + + + + + ${solr.ulog.dir:} + + + + + + true + true + v_t,t_field + org.apache.solr.update.processor.TextProfileSignature + + + + + + + true + non_indexed_signature_sS + false + v_t,t_field + org.apache.solr.update.processor.TextProfileSignature + + + + + + + + + + regex_dup_A_s + x + x_x + + + + regex_dup_B_s + x + x_x + + + + + + + + regex_dup_A_s + x + x_x + + + regex_dup_B_s + x + x_x + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-transformers.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-transformers.xml new file mode 100644 index 00000000000..ecaaf1146d5 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-transformers.xml @@ -0,0 +1,84 @@ + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + + + + + + x1 + x2 + + + + 100 + + + + x1 + x2 + + + + + xA + xA + + + + + + + + 88 + 99 + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-update-processor-chains.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-update-processor-chains.xml new file mode 100644 index 00000000000..1b99f61dc36 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-update-processor-chains.xml @@ -0,0 +1,464 @@ + + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + + + + + solr.TrieIntField + solr.TrieLongField + + + + min_foo_l + + + max_foo_l + + + ; + + primary_author_s1 + + + + primary_author_s1 + first_foo_l + + + + + + + + + + + + + foo_t + + + + + + + + foo_t + + + + + + foo.* + bar.* + + .*HOSS.* + + + + + + foo.* + bar.* + + + solr.DateField + + + .*HOSS.* + + + + + + foo.* + bar.* + + + solr.DateField + .*HOSS.* + + + + + + + name + foo_t + + + + + + name + foo_t + + + + + + + foo.* + bar.*_s + + + + + + nametext + text_sw + + + + + + solr.DateField + solr.StrField + + + + + + solr.DateField + solr.StrField + + foo.* + + + + + + + + + + + + + + + + + + foo.* + yak.* + + + + + + + + + + + foo_s + + + + + string + ; + + + + + + foo_s + bar_s + + + + + foo_s + bar_s + + + + + foo_i + foo_s + bar_s + + + + + foo_i + foo_s + bar_s + + + + + + html_s + + + + + + + trunc + 5 + + + + + + count_field + + + + + + + + + + false + + + + + + true + + + + + + foo.* + false + + + + + + foo.* + + false + + + + + + + false + + + + + + true + + + + + + .*_raw + + + + + + source1_s + dest_s + + + + + source1_s + source2_s + dest_s + + + + + + + source1_s + source2_s + + dest_s + + + + + + + source\d_.* + + source0_.* + + + dest_s + + + + + + field1 + toField + + + toField + 3 + + + + + + field1 + toField + + + field1 + + + + + + toField + + + field1 + toField + + + + + + field1 + field2 + toField + + + ; + toField + + + + + + + category + category_s + + + + authors + editors + + contributors + + + + .*_price + + list_price + + + all_prices + + + + + + category + category_count + + + category_count + + + category_count + 0 + + + + + + content + title + \s+ + X + + + + + + processor_default_s + X + + + processor_default_i + 42 + + + uuid + + + timestamp + + + + + + uniq_.* + + + + + + subject + title + teststop + nonexistent + ssto + sind + simple + + + + + + + subject + title + teststop + nonexistent + ssto + sind + json + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-warmer.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-warmer.xml new file mode 100644 index 00000000000..3f187f34d9d --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-warmer.xml @@ -0,0 +1,46 @@ + + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + ${solr.data.dir:} + + + + + + + + + ${useCompoundFile} + ${solr.tests.maxBufferedDocs} + ${solr.tests.maxIndexingThreads} + ${solr.tests.ramBufferSizeMB} + + 1000 + 10000 + single + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-xinclude.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-xinclude.xml new file mode 100644 index 00000000000..230a1ebf2f6 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-xinclude.xml @@ -0,0 +1,35 @@ + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig.snippet.randomindexconfig.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig.snippet.randomindexconfig.xml new file mode 100644 index 00000000000..055f3d7faeb --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig.snippet.randomindexconfig.xml @@ -0,0 +1,48 @@ + + + + + + + + + ${useCompoundFile:false} + + ${solr.tests.maxBufferedDocs} + ${solr.tests.maxIndexingThreads} + ${solr.tests.ramBufferSizeMB} + + + ${solr.tests.nrtMode:true} + + 1000 + 10000 + + + ${solr.tests.lockType:single} + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig.xml new file mode 100644 index 00000000000..810aa1d312e --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig.xml @@ -0,0 +1,562 @@ + + + + + + + + + + + + ${solr.data.dir:} + + + + 1000000 + 2000000 + 3000000 + 4000000 + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + + + + + + + + + + ${solr.ulog.dir:} + + + + ${solr.commitwithin.softcommit:true} + + + + + + + 1024 + + + + + + + + + + + + true + + + + + + 10 + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + true + + + + + + dismax + *:* + 0.01 + + text^0.5 features_t^1.0 subject^1.4 title_stemmed^2.0 + + + text^0.2 features_t^1.1 subject^1.4 title_stemmed^2.0 title^1.5 + + + ord(weight)^0.5 recip(rord(iind),1,1000,1000)^0.3 + + + 3<-1 5<-2 6<90% + + 100 + + + + + + + + + + + 4 + true + text,name,subject,title,whitetok + + + + + + + 4 + true + text,name,subject,title,whitetok + + + + + + + + lowerpunctfilt + + + default + lowerfilt + spellchecker1 + false + + + direct + DirectSolrSpellChecker + lowerfilt + 3 + + + wordbreak + solr.WordBreakSolrSpellChecker + lowerfilt + true + true + 10 + + + multipleFields + lowerfilt1and2 + spellcheckerMultipleFields + false + + + + jarowinkler + lowerfilt + + org.apache.lucene.search.spell.JaroWinklerDistance + spellchecker2 + + + + solr.FileBasedSpellChecker + external + spellings.txt + UTF-8 + spellchecker3 + + + + freq + lowerfilt + spellcheckerFreq + + freq + false + + + fqcn + lowerfilt + spellcheckerFQCN + org.apache.solr.spelling.SampleComparator + false + + + perDict + org.apache.solr.handler.component.DummyCustomParamSpellChecker + lowerfilt + + + + + + + + termsComp + + + + + + + + + false + + false + + 1 + + + spellcheck + + + + + direct + false + false + 1 + + + spellcheck + + + + + default + wordbreak + 20 + + + spellcheck + + + + + direct + wordbreak + 20 + + + spellcheck + + + + + dismax + lowerfilt1^1 + + + spellcheck + + + + + + + + + + + + + + + tvComponent + + + + + + + + + + + + 100 + + + + + + 70 + + + + + + + ]]> + ]]> + + + + + + + + + + + + + 10 + .,!? + + + + + + WORD + en + US + + + + + + + + + + max-age=30, public + + + + + + + explicit + true + + + + + solr + solrconfig.xml schema.xml admin-extra.html + + + + prefix-${solr.test.sys.prop2}-suffix + + + + + + false + true + v_t,t_field + org.apache.solr.update.processor.TextProfileSignature + + + + + + false + false + id + + org.apache.solr.update.processor.Lookup3Signature + + + + + + + true + non_indexed_signature_sS + false + v_t,t_field + org.apache.solr.update.processor.TextProfileSignature + + + + + + + uniq + uniq2 + uniq3 + + + + + + + + + regex_dup_A_s + x + x_x + + + + regex_dup_B_s + x + x_x + + + + + + + + regex_dup_A_s + x + x_x + + + regex_dup_B_s + x + x_x + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig_codec.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig_codec.xml new file mode 100644 index 00000000000..c5cc04cfe9d --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig_codec.xml @@ -0,0 +1,25 @@ + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig_perf.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig_perf.xml new file mode 100755 index 00000000000..172fc953f37 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig_perf.xml @@ -0,0 +1,76 @@ + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + ${solr.data.dir:} + + + + + + + + + + + + + + + + + true + 20 + 200 + false + 2 + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stemdict.txt b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stemdict.txt new file mode 100644 index 00000000000..f57a4ad490f --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stemdict.txt @@ -0,0 +1,22 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#----------------------------------------------------------------------- +# test that we can override the stemming algorithm with our own mappings +# these must be tab-separated +monkeys monkey +otters otter +# some crazy ones that a stemmer would never do +dogs cat diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stop-1.txt b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stop-1.txt new file mode 100644 index 00000000000..8dfe80902d2 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stop-1.txt @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +foo +bar \ No newline at end of file diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stop-2.txt b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stop-2.txt new file mode 100644 index 00000000000..646b7ff4ddb --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stop-2.txt @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +junk +more \ No newline at end of file diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stop-snowball.txt b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stop-snowball.txt new file mode 100644 index 00000000000..1c0c6f51142 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stop-snowball.txt @@ -0,0 +1,10 @@ + | This is a file in snowball format, empty lines are ignored, '|' is a comment + | Additionally, multiple words can be on the same line, allowing stopwords to be + | arranged in tables (useful in some languages where they might inflect) + + | fictitious table below + +|third person singular +|Subject Object Possessive Reflexive +he him his himself| masculine +she her hers herself| feminine diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stoptypes-1.txt b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stoptypes-1.txt new file mode 100644 index 00000000000..456348ea9dc --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stoptypes-1.txt @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stoptypes-2.txt b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stoptypes-2.txt new file mode 100644 index 00000000000..d8a3810c26c --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stoptypes-2.txt @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stopwithbom.txt b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stopwithbom.txt new file mode 100644 index 00000000000..eb5f6e1c0f8 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stopwithbom.txt @@ -0,0 +1 @@ +BOMsAreEvil diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stopwords.txt b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stopwords.txt new file mode 100644 index 00000000000..b5824da3263 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stopwords.txt @@ -0,0 +1,58 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#----------------------------------------------------------------------- +# a couple of test stopwords to test that the words are really being +# configured from this file: +stopworda +stopwordb + +#Standard english stop words taken from Lucene's StopAnalyzer +a +an +and +are +as +at +be +but +by +for +if +in +into +is +it +no +not +of +on +or +s +such +t +that +the +their +then +there +these +they +this +to +was +will +with + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stopwordsWrongEncoding.txt b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stopwordsWrongEncoding.txt new file mode 100644 index 00000000000..0d305c88c59 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stopwordsWrongEncoding.txt @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# stopwords in the wrong encoding (ISO-8859-1). +# tests resourceloader's ability to report wrongly encoded files. +baadores diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/synonyms.txt b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/synonyms.txt new file mode 100644 index 00000000000..b0e31cb7ec8 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/synonyms.txt @@ -0,0 +1,31 @@ +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#----------------------------------------------------------------------- +#some test synonym mappings unlikely to appear in real input text +aaa => aaaa +bbb => bbbb1 bbbb2 +ccc => cccc1,cccc2 +a\=>a => b\=>b +a\,a => b\,b +fooaaa,baraaa,bazaaa + +# Some synonym groups specific to this example +GB,gib,gigabyte,gigabytes +MB,mib,megabyte,megabytes +Television, Televisions, TV, TVs +#notice we use "gib" instead of "GiB" so any WordDelimiterFilter coming +#after us won't split it into two words. + +# Synonym mappings can be used for spelling correction too +pixima => pixma + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/throw.error.on.add.updateprocessor.js b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/throw.error.on.add.updateprocessor.js new file mode 100644 index 00000000000..ca56fe35cfe --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/throw.error.on.add.updateprocessor.js @@ -0,0 +1,21 @@ +function processAdd() { + throw "guess what? no-soup-fo-you !!!"; +} + +// // // + +function processDelete() { + // NOOP +} +function processCommit() { + // NOOP +} +function processRollback() { + // NOOP +} +function processMergeIndexes() { + // NOOP +} +function finish() { + // NOOP +} diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/trivial.updateprocessor0.js b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/trivial.updateprocessor0.js new file mode 100644 index 00000000000..b1856b15d85 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/trivial.updateprocessor0.js @@ -0,0 +1,59 @@ +var Assert = Packages.org.junit.Assert; + +function processAdd(cmd) { + functionMessages.add("processAdd0"); + Assert.assertNotNull(req); + Assert.assertNotNull(rsp); + Assert.assertNotNull(logger); + Assert.assertNotNull(cmd); + Assert.assertNotNull(params); + Assert.assertTrue(1 == params.get('intValue').intValue()); // had issues with assertTrue(1, params.get('intValue').intValue()) casting to wrong variant + Assert.assertTrue(params.get('boolValue').booleanValue()); + + // Integer.valueOf is needed here to get a tru java object, because + // all javascript numbers are floating point (ie: java.lang.Double) + cmd.getSolrInputDocument().addField("script_added_i", + java.lang.Integer.valueOf(42)); + cmd.getSolrInputDocument().addField("script_added_d", 42.3); + +} + +function processDelete(cmd) { + functionMessages.add("processDelete0"); + Assert.assertNotNull(req); + Assert.assertNotNull(rsp); + Assert.assertNotNull(logger); + Assert.assertNotNull(cmd); +} + +function processMergeIndexes(cmd) { + functionMessages.add("processMergeIndexes0"); + Assert.assertNotNull(req); + Assert.assertNotNull(rsp); + Assert.assertNotNull(logger); + Assert.assertNotNull(cmd); +} + +function processCommit(cmd) { + functionMessages.add("processCommit0"); + Assert.assertNotNull(req); + Assert.assertNotNull(rsp); + Assert.assertNotNull(logger); + Assert.assertNotNull(cmd); +} + +function processRollback(cmd) { + functionMessages.add("processRollback0"); + Assert.assertNotNull(req); + Assert.assertNotNull(rsp); + Assert.assertNotNull(logger); + Assert.assertNotNull(cmd); +} + +function finish() { + functionMessages.add("finish0"); + Assert.assertNotNull(req); + Assert.assertNotNull(rsp); + Assert.assertNotNull(logger); +} + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/trivial.updateprocessor1.js b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/trivial.updateprocessor1.js new file mode 100644 index 00000000000..98bdf2ab060 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/trivial.updateprocessor1.js @@ -0,0 +1,25 @@ +function processAdd(cmd) { + functionMessages.add("processAdd1"); + +} + +function processDelete(cmd) { + functionMessages.add("processDelete1"); +} + +function processMergeIndexes(cmd) { + functionMessages.add("processMergeIndexes1"); +} + +function processCommit(cmd) { + functionMessages.add("processCommit1"); +} + +function processRollback(cmd) { + functionMessages.add("processRollback1"); +} + +function finish() { + functionMessages.add("finish1"); +} + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/wdftypes.txt b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/wdftypes.txt new file mode 100644 index 00000000000..7378b0802e7 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/wdftypes.txt @@ -0,0 +1,32 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# A customized type mapping for WordDelimiterFilterFactory +# the allowable types are: LOWER, UPPER, ALPHA, DIGIT, ALPHANUM, SUBWORD_DELIM +# +# the default for any character without a mapping is always computed from +# Unicode character properties + +# Map the $, %, '.', and ',' characters to DIGIT +# This might be useful for financial data. +$ => DIGIT +% => DIGIT +. => DIGIT +\u002C => DIGIT + +# in some cases you might not want to split on ZWJ +# this also tests the case where we need a bigger byte[] +# see http://en.wikipedia.org/wiki/Zero-width_joiner +\u200D => ALPHANUM diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/xslt/dummy-using-include.xsl b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/xslt/dummy-using-include.xsl new file mode 100644 index 00000000000..f10cfbf9330 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/xslt/dummy-using-include.xsl @@ -0,0 +1,31 @@ + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/xslt/dummy.xsl b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/xslt/dummy.xsl new file mode 100644 index 00000000000..fbbd8f745cd --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/xslt/dummy.xsl @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/xslt/xsl-update-handler-test.xsl b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/xslt/xsl-update-handler-test.xsl new file mode 100644 index 00000000000..2e7359a62b6 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/xslt/xsl-update-handler-test.xsl @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/lib/README b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/lib/README new file mode 100644 index 00000000000..b7ca5b834f4 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/lib/README @@ -0,0 +1,18 @@ + + +Items under this directory are used by TestConfig.testLibs() diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/lib/classes/empty-file-main-lib.txt b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/lib/classes/empty-file-main-lib.txt new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/lib/classes/empty-file-main-lib.txt @@ -0,0 +1 @@ + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/conf/core.properties b/solr/contrib/solr-morphlines-core/src/test-files/solr/conf/core.properties new file mode 100644 index 00000000000..65df5e6114f --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/conf/core.properties @@ -0,0 +1,19 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +schema=schema-tiny.xml +config=solrconfig-minimal.xml +transient=true +loadOnStartup=false + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/crazy-path-to-config.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/crazy-path-to-config.xml new file mode 100644 index 00000000000..55801c4faf1 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/crazy-path-to-config.xml @@ -0,0 +1,59 @@ + + + + + + ${tests.luceneMatchVersion:LUCENE_CURRENT} + + + + + 0 + + + + 1024 + true + 10 + + + + + + + + implicit + + + + + + + + + + + solr + solrconfig.xml schema.xml + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/crazy-path-to-schema.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/crazy-path-to-schema.xml new file mode 100644 index 00000000000..a2216ddfa99 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/crazy-path-to-schema.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + subject + id + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/external_eff b/solr/contrib/solr-morphlines-core/src/test-files/solr/external_eff new file mode 100644 index 00000000000..a23f9b554bd --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/external_eff @@ -0,0 +1,10 @@ +1=0.354 +2=0.975 +3=0.001 +4=100.35 +5=53.9 +6=70 +7=3.957 +8=1400 +9=24 +10=450 \ No newline at end of file diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/solr-50-all.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/solr-50-all.xml new file mode 100644 index 00000000000..886e4434631 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/solr-50-all.xml @@ -0,0 +1,52 @@ + + + + testAdminHandler + 11 + ${coreRootDirectory:testCoreRootDirectory} + testManagementPath + testSharedLib + ${shareSchema:testShareSchema} + 66 + + + 22 + 33 + 55 + testHost + testHostContext + ${hostPort:44} + 77 + testZkHost + + + + testLoggingClass + testLoggingEnabled + + 88 + 99 + + + + + ${socketTimeout:100} + ${connTimeout:110} + + + \ No newline at end of file diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/solr-multicore.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/solr-multicore.xml new file mode 100644 index 00000000000..abb308ec997 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/solr-multicore.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/solr-no-core.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/solr-no-core.xml new file mode 100644 index 00000000000..476b5bc7a10 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/solr-no-core.xml @@ -0,0 +1,39 @@ + + + + + + ${shareSchema:false} + + + 127.0.0.1 + ${hostContext:solr} + ${hostPort:8983} + ${solr.zkclienttimeout:30000} + ${genericCoreNodeNames:true} + ${distribUpdateConnTimeout:15000} + ${distribUpdateSoTimeout:120000} + + + + ${socketTimeout:120000} + ${connTimeout:15000} + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/solr-shardhandler-old.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/solr-shardhandler-old.xml new file mode 100644 index 00000000000..70aaa56faa0 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/solr-shardhandler-old.xml @@ -0,0 +1,29 @@ + + + + + + + + myMagicRequiredValue + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/solr-shardhandler.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/solr-shardhandler.xml new file mode 100644 index 00000000000..f5d24fe931d --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/solr-shardhandler.xml @@ -0,0 +1,29 @@ + + + + + + + + myMagicRequiredValue + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/solr-stress-new.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/solr-stress-new.xml new file mode 100644 index 00000000000..3f8b213eab5 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/solr-stress-new.xml @@ -0,0 +1,34 @@ + + + + + + + 127.0.0.1 + 8983 + ${hostContext:solr} + + + + ${socketTimeout:120000} + ${connTimeout:15000} + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/solr-stress-old.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/solr-stress-old.xml new file mode 100644 index 00000000000..6bc1c35e888 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/solr-stress-old.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${socketTimeout:120000} + ${connTimeout:15000} + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/solr.xml b/solr/contrib/solr-morphlines-core/src/test-files/solr/solr.xml new file mode 100644 index 00000000000..4604f60476f --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/solr/solr.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + ${socketTimeout:120000} + ${connTimeout:15000} + + + + diff --git a/solr/contrib/solr-morphlines-core/src/test-files/spellings.txt b/solr/contrib/solr-morphlines-core/src/test-files/spellings.txt new file mode 100644 index 00000000000..2d2472e340a --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test-files/spellings.txt @@ -0,0 +1,16 @@ +foo +bar +Solr +junk +foo +bar +Solr +junk +foo +bar +Solr +junk +foo +bar +Solr +junk \ No newline at end of file diff --git a/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/AbstractSolrMorphlineTestBase.java b/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/AbstractSolrMorphlineTestBase.java new file mode 100644 index 00000000000..e5e1d3cce67 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/AbstractSolrMorphlineTestBase.java @@ -0,0 +1,268 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.morphlines.solr; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.atomic.AtomicInteger; + +import org.apache.commons.io.FileUtils; +import org.apache.solr.SolrTestCaseJ4; +import org.apache.solr.client.solrj.SolrQuery; +import org.apache.solr.client.solrj.SolrServer; +import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.client.solrj.impl.HttpSolrServer; +import org.apache.solr.client.solrj.impl.XMLResponseParser; +import org.apache.solr.client.solrj.response.QueryResponse; +import org.apache.solr.common.SolrDocument; +import org.apache.solr.util.ExternalPaths; +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.cloudera.cdk.morphline.api.Collector; +import com.cloudera.cdk.morphline.api.Command; +import com.cloudera.cdk.morphline.api.MorphlineContext; +import com.cloudera.cdk.morphline.api.Record; +import com.cloudera.cdk.morphline.base.Compiler; +import com.cloudera.cdk.morphline.base.FaultTolerance; +import com.cloudera.cdk.morphline.base.Fields; +import com.cloudera.cdk.morphline.base.Notifications; +import com.cloudera.cdk.morphline.stdlib.PipeBuilder; +import com.codahale.metrics.MetricRegistry; +import com.google.common.io.Files; +import com.typesafe.config.Config; + +public class AbstractSolrMorphlineTestBase extends SolrTestCaseJ4 { + + protected Collector collector; + protected Command morphline; + protected SolrServer solrServer; + protected DocumentLoader testServer; + + protected static final boolean TEST_WITH_EMBEDDED_SOLR_SERVER = true; + protected static final String EXTERNAL_SOLR_SERVER_URL = System.getProperty("externalSolrServer"); +// protected static final String EXTERNAL_SOLR_SERVER_URL = "http://127.0.0.1:8983/solr"; + + protected static final String RESOURCES_DIR = ExternalPaths.SOURCE_HOME + "/contrib/solr-mr/src/test-files"; + protected static final String DEFAULT_BASE_DIR = "solr"; + protected static final AtomicInteger SEQ_NUM = new AtomicInteger(); + protected static final AtomicInteger SEQ_NUM2 = new AtomicInteger(); + + private static final Logger LOGGER = LoggerFactory.getLogger(AbstractSolrMorphlineTestBase.class); + + protected String tempDir; + + @BeforeClass + public static void beforeClass() throws Exception { + myInitCore(DEFAULT_BASE_DIR); + } + + protected static void myInitCore(String baseDirName) throws Exception { + initCore( + RESOURCES_DIR + "/" + baseDirName + "/collection1/conf/solrconfig.xml", + RESOURCES_DIR + "/" + baseDirName + "/collection1/conf/schema.xml", + RESOURCES_DIR + "/" + baseDirName + ); + } + + @Before + public void setUp() throws Exception { + super.setUp(); + collector = new Collector(); + + if (EXTERNAL_SOLR_SERVER_URL != null) { + //solrServer = new ConcurrentUpdateSolrServer(EXTERNAL_SOLR_SERVER_URL, 2, 2); + //solrServer = new SafeConcurrentUpdateSolrServer(EXTERNAL_SOLR_SERVER_URL, 2, 2); + solrServer = new HttpSolrServer(EXTERNAL_SOLR_SERVER_URL); + ((HttpSolrServer)solrServer).setParser(new XMLResponseParser()); + } else { + if (TEST_WITH_EMBEDDED_SOLR_SERVER) { + solrServer = new EmbeddedTestSolrServer(h.getCoreContainer(), ""); + } else { + throw new RuntimeException("Not yet implemented"); + //solrServer = new TestSolrServer(getSolrServer()); + } + } + + int batchSize = SEQ_NUM2.incrementAndGet() % 2 == 0 ? 100 : 1; //SolrInspector.DEFAULT_SOLR_SERVER_BATCH_SIZE : 1; + testServer = new SolrServerDocumentLoader(solrServer, batchSize); + deleteAllDocuments(); + + tempDir = TEMP_DIR + "/test-morphlines-" + System.currentTimeMillis(); + new File(tempDir).mkdirs(); + } + + @After + public void tearDown() throws Exception { + collector = null; + solrServer = null; + super.tearDown(); + } + + protected void testDocumentTypesInternal(String[] files, Map expectedRecords) throws Exception { + deleteAllDocuments(); + int numDocs = 0; + for (int i = 0; i < 1; i++) { + + for (String file : files) { + File f = new File(file); + byte[] body = Files.toByteArray(f); + Record event = new Record(); + //event.put(Fields.ID, docId++); + event.getFields().put(Fields.ATTACHMENT_BODY, new ByteArrayInputStream(body)); + event.getFields().put(Fields.ATTACHMENT_NAME, f.getName()); + event.getFields().put(Fields.BASE_ID, f.getName()); + load(event); + Integer count = expectedRecords.get(file); + if (count != null) { + numDocs += count; + } else { + numDocs++; + } + assertEquals("unexpected results in " + file, numDocs, queryResultSetSize("*:*")); + } + } + assertEquals(numDocs, queryResultSetSize("*:*")); + } + + private boolean load(Record record) { + Notifications.notifyStartSession(morphline); + return morphline.process(record); + } + + protected int queryResultSetSize(String query) { +// return collector.getRecords().size(); + try { + testServer.commitTransaction(); + solrServer.commit(false, true, true); + QueryResponse rsp = solrServer.query(new SolrQuery(query).setRows(Integer.MAX_VALUE)); + LOGGER.debug("rsp: {}", rsp); + int i = 0; + for (SolrDocument doc : rsp.getResults()) { + LOGGER.debug("rspDoc #{}: {}", i++, doc); + } + int size = rsp.getResults().size(); + return size; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private void deleteAllDocuments() throws SolrServerException, IOException { + collector.reset(); + SolrServer s = solrServer; + s.deleteByQuery("*:*"); // delete everything! + s.commit(); + } + + + public static void setupMorphline(String tempDir, String file) throws IOException { + String morphlineText = FileUtils.readFileToString(new File(RESOURCES_DIR + "/" + file + ".conf"), "UTF-8"); + morphlineText = morphlineText.replaceAll("RESOURCES_DIR", new File(tempDir).getAbsolutePath()); + + FileUtils.writeStringToFile(new File(tempDir + "/" + file + ".conf"), morphlineText, "UTF-8"); + } + + protected Command createMorphline(String file) throws IOException { + setupMorphline(tempDir, file); + + return new PipeBuilder().build(parse(file), null, collector, createMorphlineContext()); + } + + private MorphlineContext createMorphlineContext() { + return new SolrMorphlineContext.Builder() + .setDocumentLoader(testServer) +// .setDocumentLoader(new CollectingDocumentLoader(100)) + .setExceptionHandler(new FaultTolerance(false, false, SolrServerException.class.getName())) + .setMetricRegistry(new MetricRegistry()) + .build(); + } + + private Config parse(String file) throws IOException { + SolrLocator locator = new SolrLocator(createMorphlineContext()); + locator.setSolrHomeDir(testSolrHome + "/collection1"); + Config config = new Compiler().parse(new File(tempDir + "/" + file + ".conf"), locator.toConfig("SOLR_LOCATOR")); + config = config.getConfigList("morphlines").get(0); + return config; + } + + protected void startSession() { + Notifications.notifyStartSession(morphline); + } + + protected void testDocumentContent(HashMap expectedResultMap) + throws Exception { + QueryResponse rsp = solrServer.query(new SolrQuery("*:*").setRows(Integer.MAX_VALUE)); + // Check that every expected field/values shows up in the actual query + for (Entry current : expectedResultMap.entrySet()) { + String field = current.getKey(); + for (String expectedFieldValue : current.getValue().getFieldValues()) { + ExpectedResult.CompareType compareType = current.getValue().getCompareType(); + boolean foundField = false; + + for (SolrDocument doc : rsp.getResults()) { + Collection actualFieldValues = doc.getFieldValues(field); + if (compareType == ExpectedResult.CompareType.equals) { + if (actualFieldValues != null && actualFieldValues.contains(expectedFieldValue)) { + foundField = true; + break; + } + } + else { + for (Iterator it = actualFieldValues.iterator(); it.hasNext(); ) { + String actualValue = it.next().toString(); // test only supports string comparison + if (actualFieldValues != null && actualValue.contains(expectedFieldValue)) { + foundField = true; + break; + } + } + } + } + assert(foundField); // didn't find expected field/value in query + } + } + } + + /** + * Representation of the expected output of a SolrQuery. + */ + protected static class ExpectedResult { + private HashSet fieldValues; + public enum CompareType { + equals, // Compare with equals, i.e. actual.equals(expected) + contains; // Compare with contains, i.e. actual.contains(expected) + } + private CompareType compareType; + + public ExpectedResult(HashSet fieldValues, CompareType compareType) { + this.fieldValues = fieldValues; + this.compareType = compareType; + } + public HashSet getFieldValues() { return fieldValues; } + public CompareType getCompareType() { return compareType; } + } +} diff --git a/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/AbstractSolrMorphlineZkTestBase.java b/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/AbstractSolrMorphlineZkTestBase.java new file mode 100644 index 00000000000..62cf325d5a7 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/AbstractSolrMorphlineZkTestBase.java @@ -0,0 +1,249 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.morphlines.solr; + +import java.io.File; +import java.io.IOException; +import java.util.Iterator; + +import org.apache.commons.io.FileUtils; +import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.client.solrj.embedded.JettySolrRunner; +import org.apache.solr.cloud.AbstractFullDistribZkTestBase; +import org.apache.solr.cloud.AbstractZkTestCase; +import org.apache.solr.common.SolrDocument; +import org.apache.solr.common.cloud.SolrZkClient; +import org.apache.solr.util.ExternalPaths; +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.cloudera.cdk.morphline.api.Command; +import com.cloudera.cdk.morphline.api.Collector; +import com.cloudera.cdk.morphline.api.MorphlineContext; +import com.cloudera.cdk.morphline.api.Record; +import com.cloudera.cdk.morphline.base.Compiler; +import com.cloudera.cdk.morphline.base.FaultTolerance; +import com.cloudera.cdk.morphline.base.Notifications; +import com.cloudera.cdk.morphline.stdlib.PipeBuilder; +import com.codahale.metrics.MetricRegistry; +import com.google.common.collect.ListMultimap; +import com.typesafe.config.Config; + +public abstract class AbstractSolrMorphlineZkTestBase extends AbstractFullDistribZkTestBase { + private static final File solrHomeDirectory = new File(TEMP_DIR, AbstractSolrMorphlineZkTestBase.class.getName()); + + protected static final String RESOURCES_DIR = ExternalPaths.SOURCE_HOME + "/contrib/solr-mr/src/test-files"; + private static final File SOLR_INSTANCE_DIR = new File(RESOURCES_DIR + "/solr"); + private static final File SOLR_CONF_DIR = new File(RESOURCES_DIR + "/solr/collection1"); + + protected Collector collector; + protected Command morphline; + + @Override + public String getSolrHome() { + return solrHomeDirectory.getPath(); + } + + public AbstractSolrMorphlineZkTestBase() { + fixShardCount = true; + sliceCount = 3; + shardCount = 3; + } + + @BeforeClass + public static void setupClass() throws Exception { + AbstractZkTestCase.SOLRHOME = solrHomeDirectory; + FileUtils.copyDirectory(SOLR_INSTANCE_DIR, solrHomeDirectory); + createTempDir(); + } + + @Override + @Before + public void setUp() throws Exception { + super.setUp(); + System.setProperty("host", "127.0.0.1"); + System.setProperty("numShards", Integer.toString(sliceCount)); + uploadConfFiles(); + collector = new Collector(); + } + + @Override + @After + public void tearDown() throws Exception { + super.tearDown(); + System.clearProperty("host"); + System.clearProperty("numShards"); + } + + @Test + @Override + public void testDistribSearch() throws Exception { + super.testDistribSearch(); + } + + @Override + protected void commit() throws Exception { + Notifications.notifyCommitTransaction(morphline); + super.commit(); + } + + protected Command parse(String file) throws IOException { + return parse(file, "collection1"); + } + + protected Command parse(String file, String collection) throws IOException { + SolrLocator locator = new SolrLocator(createMorphlineContext()); + locator.setCollectionName(collection); + locator.setZkHost(zkServer.getZkAddress()); + //locator.setServerUrl(cloudJettys.get(0).url); // TODO: download IndexSchema from solrUrl not yet implemented + //locator.setSolrHomeDir(SOLR_HOME_DIR.getPath()); + Config config = new Compiler().parse(new File(RESOURCES_DIR + "/" + file + ".conf"), locator.toConfig("SOLR_LOCATOR")); + config = config.getConfigList("morphlines").get(0); + return createMorphline(config); + } + + private Command createMorphline(Config config) { + return new PipeBuilder().build(config, null, collector, createMorphlineContext()); + } + + private MorphlineContext createMorphlineContext() { + return new MorphlineContext.Builder() + .setExceptionHandler(new FaultTolerance(false, false, SolrServerException.class.getName())) + .setMetricRegistry(new MetricRegistry()) + .build(); + } + + protected void startSession() { + Notifications.notifyStartSession(morphline); + } + + protected ListMultimap next(Iterator iter) { + SolrDocument doc = iter.next(); + Record record = toRecord(doc); + record.removeAll("_version_"); // the values of this field are unknown and internal to solr + return record.getFields(); + } + + private Record toRecord(SolrDocument doc) { + Record record = new Record(); + for (String key : doc.keySet()) { + record.getFields().replaceValues(key, doc.getFieldValues(key)); + } + return record; + } + + @Override + public JettySolrRunner createJetty(File solrHome, String dataDir, + String shardList, String solrConfigOverride, String schemaOverride) + throws Exception { + + JettySolrRunner jetty = new JettySolrRunner(solrHome.getAbsolutePath(), + context, 0, solrConfigOverride, schemaOverride); + + jetty.setShards(shardList); + + if (System.getProperty("collection") == null) { + System.setProperty("collection", "collection1"); + } + + jetty.start(); + + System.clearProperty("collection"); + + return jetty; + } + + private static void putConfig(SolrZkClient zkClient, File solrhome, String name) throws Exception { + putConfig(zkClient, solrhome, name, name); + } + + private static void putConfig(SolrZkClient zkClient, File solrhome, String srcName, String destName) + throws Exception { + + File file = new File(solrhome, "conf" + File.separator + srcName); + if (!file.exists()) { + // LOG.info("skipping " + file.getAbsolutePath() + + // " because it doesn't exist"); + return; + } + + String destPath = "/configs/conf1/" + destName; + // LOG.info("put " + file.getAbsolutePath() + " to " + destPath); + zkClient.makePath(destPath, file, false, true); + } + + private void uploadConfFiles() throws Exception { + // upload our own config files + SolrZkClient zkClient = new SolrZkClient(zkServer.getZkAddress(), 10000); + putConfig(zkClient, SOLR_CONF_DIR, "solrconfig.xml"); + putConfig(zkClient, SOLR_CONF_DIR, "schema.xml"); + putConfig(zkClient, SOLR_CONF_DIR, "elevate.xml"); + putConfig(zkClient, SOLR_CONF_DIR, "lang/stopwords_en.txt"); + putConfig(zkClient, SOLR_CONF_DIR, "lang/stopwords_ar.txt"); + + putConfig(zkClient, SOLR_CONF_DIR, "lang/stopwords_bg.txt"); + putConfig(zkClient, SOLR_CONF_DIR, "lang/stopwords_ca.txt"); + putConfig(zkClient, SOLR_CONF_DIR, "lang/stopwords_cz.txt"); + putConfig(zkClient, SOLR_CONF_DIR, "lang/stopwords_da.txt"); + putConfig(zkClient, SOLR_CONF_DIR, "lang/stopwords_el.txt"); + putConfig(zkClient, SOLR_CONF_DIR, "lang/stopwords_es.txt"); + putConfig(zkClient, SOLR_CONF_DIR, "lang/stopwords_eu.txt"); + putConfig(zkClient, SOLR_CONF_DIR, "lang/stopwords_de.txt"); + putConfig(zkClient, SOLR_CONF_DIR, "lang/stopwords_fa.txt"); + putConfig(zkClient, SOLR_CONF_DIR, "lang/stopwords_fi.txt"); + putConfig(zkClient, SOLR_CONF_DIR, "lang/stopwords_fr.txt"); + putConfig(zkClient, SOLR_CONF_DIR, "lang/stopwords_ga.txt"); + putConfig(zkClient, SOLR_CONF_DIR, "lang/stopwords_gl.txt"); + putConfig(zkClient, SOLR_CONF_DIR, "lang/stopwords_hi.txt"); + putConfig(zkClient, SOLR_CONF_DIR, "lang/stopwords_hu.txt"); + putConfig(zkClient, SOLR_CONF_DIR, "lang/stopwords_hy.txt"); + putConfig(zkClient, SOLR_CONF_DIR, "lang/stopwords_id.txt"); + putConfig(zkClient, SOLR_CONF_DIR, "lang/stopwords_it.txt"); + putConfig(zkClient, SOLR_CONF_DIR, "lang/stopwords_ja.txt"); + putConfig(zkClient, SOLR_CONF_DIR, "lang/stopwords_lv.txt"); + putConfig(zkClient, SOLR_CONF_DIR, "lang/stopwords_nl.txt"); + putConfig(zkClient, SOLR_CONF_DIR, "lang/stopwords_no.txt"); + putConfig(zkClient, SOLR_CONF_DIR, "lang/stopwords_pt.txt"); + putConfig(zkClient, SOLR_CONF_DIR, "lang/stopwords_ro.txt"); + putConfig(zkClient, SOLR_CONF_DIR, "lang/stopwords_ru.txt"); + putConfig(zkClient, SOLR_CONF_DIR, "lang/stopwords_sv.txt"); + putConfig(zkClient, SOLR_CONF_DIR, "lang/stopwords_th.txt"); + putConfig(zkClient, SOLR_CONF_DIR, "lang/stopwords_tr.txt"); + + putConfig(zkClient, SOLR_CONF_DIR, "lang/contractions_ca.txt"); + putConfig(zkClient, SOLR_CONF_DIR, "lang/contractions_fr.txt"); + putConfig(zkClient, SOLR_CONF_DIR, "lang/contractions_ga.txt"); + putConfig(zkClient, SOLR_CONF_DIR, "lang/contractions_it.txt"); + + putConfig(zkClient, SOLR_CONF_DIR, "lang/stemdict_nl.txt"); + + putConfig(zkClient, SOLR_CONF_DIR, "lang/hyphenations_ga.txt"); + + putConfig(zkClient, SOLR_CONF_DIR, "stopwords.txt"); + putConfig(zkClient, SOLR_CONF_DIR, "protwords.txt"); + putConfig(zkClient, SOLR_CONF_DIR, "currency.xml"); + putConfig(zkClient, SOLR_CONF_DIR, "open-exchange-rates.json"); + putConfig(zkClient, SOLR_CONF_DIR, "mapping-ISOLatin1Accent.txt"); + putConfig(zkClient, SOLR_CONF_DIR, "old_synonyms.txt"); + putConfig(zkClient, SOLR_CONF_DIR, "synonyms.txt"); + zkClient.close(); + } + +} diff --git a/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/CollectingDocumentLoader.java b/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/CollectingDocumentLoader.java new file mode 100644 index 00000000000..ed58cffff6e --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/CollectingDocumentLoader.java @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.morphlines.solr; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.solr.client.solrj.response.SolrPingResponse; +import org.apache.solr.client.solrj.response.UpdateResponse; +import org.apache.solr.common.SolrInputDocument; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A mockup DocumentLoader implementation for unit tests; collects all documents into a main memory list. + */ +class CollectingDocumentLoader implements DocumentLoader { + + private final int batchSize; + private final List batch = new ArrayList (); + private List results = new ArrayList (); + + private static final Logger LOGGER = LoggerFactory.getLogger(CollectingDocumentLoader.class); + + public CollectingDocumentLoader(int batchSize) { + if (batchSize <= 0) { + throw new IllegalArgumentException("batchSize must be a positive number: " + batchSize); + } + this.batchSize = batchSize; + } + + @Override + public void beginTransaction() { + LOGGER.trace("beginTransaction"); + batch.clear(); + } + + @Override + public void load(SolrInputDocument doc) { + LOGGER.trace("load doc: {}", doc); + batch.add(doc); + if (batch.size() >= batchSize) { + loadBatch(); + } + } + + @Override + public void commitTransaction() { + LOGGER.trace("commitTransaction"); + if (batch.size() > 0) { + loadBatch(); + } + } + + private void loadBatch() { + try { + results.addAll(batch); + } finally { + batch.clear(); + } + } + + @Override + public UpdateResponse rollbackTransaction() { + LOGGER.trace("rollback"); + return new UpdateResponse(); + } + + @Override + public void shutdown() { + LOGGER.trace("shutdown"); + } + + @Override + public SolrPingResponse ping() { + LOGGER.trace("ping"); + return new SolrPingResponse(); + } + +} diff --git a/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/EmbeddedTestSolrServer.java b/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/EmbeddedTestSolrServer.java new file mode 100644 index 00000000000..1f747f3d2d8 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/EmbeddedTestSolrServer.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.morphlines.solr; + +import java.io.IOException; + +import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer; +import org.apache.solr.client.solrj.response.UpdateResponse; +import org.apache.solr.core.CoreContainer; + +/** + * An EmbeddedSolrServer that supresses shutdown and rollback requests as + * necessary for testing + */ +public class EmbeddedTestSolrServer extends EmbeddedSolrServer { + + public EmbeddedTestSolrServer(CoreContainer coreContainer, String coreName) { + super(coreContainer, coreName); + } + + @Override + public void shutdown() { + ; // NOP + } + + @Override + public UpdateResponse rollback() throws SolrServerException, IOException { + return new UpdateResponse(); + } + +} diff --git a/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineTest.java b/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineTest.java new file mode 100644 index 00000000000..126eef34979 --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineTest.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.morphlines.solr; + +import java.util.Arrays; + +import org.junit.Test; + +import com.cloudera.cdk.morphline.api.Record; +import com.cloudera.cdk.morphline.base.Fields; +import com.cloudera.cdk.morphline.base.Notifications; + +public class SolrMorphlineTest extends AbstractSolrMorphlineTestBase { + + @Test + public void testLoadSolrBasic() throws Exception { + //System.setProperty("ENV_SOLR_HOME", testSolrHome + "/collection1"); + morphline = createMorphline("test-morphlines/loadSolrBasic"); + //System.clearProperty("ENV_SOLR_HOME"); + Record record = new Record(); + record.put(Fields.ID, "id0"); + record.put("first_name", "Nadja"); // will be sanitized + startSession(); + Notifications.notifyBeginTransaction(morphline); + assertTrue(morphline.process(record)); + assertEquals(1, collector.getNumStartEvents()); + Notifications.notifyCommitTransaction(morphline); + Record expected = new Record(); + expected.put(Fields.ID, "id0"); + assertEquals(Arrays.asList(expected), collector.getRecords()); + assertEquals(1, queryResultSetSize("*:*")); + Notifications.notifyRollbackTransaction(morphline); + Notifications.notifyShutdown(morphline); + } + + @Test + public void testTokenizeText() throws Exception { + morphline = createMorphline("test-morphlines/tokenizeText"); + Record record = new Record(); + record.put(Fields.MESSAGE, "Hello World!"); + record.put(Fields.MESSAGE, "\nFoo@Bar.com #%()123"); + Record expected = record.copy(); + expected.getFields().putAll("tokens", Arrays.asList("hello", "world", "foo", "bar.com", "123")); + startSession(); + Notifications.notifyBeginTransaction(morphline); + assertTrue(morphline.process(record)); + assertEquals(1, collector.getNumStartEvents()); + Notifications.notifyCommitTransaction(morphline); + assertEquals(expected, collector.getFirstRecord()); + } + +} diff --git a/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkAliasTest.java b/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkAliasTest.java new file mode 100644 index 00000000000..2fce297b34d --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkAliasTest.java @@ -0,0 +1,127 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.morphlines.solr; + +import java.io.IOException; +import java.util.Iterator; + +import org.apache.lucene.util.LuceneTestCase.Slow; +import org.apache.lucene.util.LuceneTestCase.SuppressCodecs; +import org.apache.solr.client.solrj.SolrQuery; +import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.client.solrj.request.QueryRequest; +import org.apache.solr.client.solrj.response.QueryResponse; +import org.apache.solr.common.SolrDocument; +import org.apache.solr.common.params.CollectionParams.CollectionAction; +import org.apache.solr.common.params.ModifiableSolrParams; +import org.apache.solr.common.util.NamedList; + +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakAction; +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakAction.Action; +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakLingering; +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope; +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope.Scope; +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakZombies; +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakZombies.Consequence; +import com.cloudera.cdk.morphline.api.Record; +import com.cloudera.cdk.morphline.base.Fields; +import com.cloudera.cdk.morphline.base.Notifications; + +@ThreadLeakAction({Action.WARN}) +@ThreadLeakLingering(linger = 0) +@ThreadLeakZombies(Consequence.CONTINUE) +@ThreadLeakScope(Scope.NONE) +@SuppressCodecs({"Lucene3x", "Lucene40"}) +@Slow +public class SolrMorphlineZkAliasTest extends AbstractSolrMorphlineZkTestBase { + + @Override + public void doTest() throws Exception { + + waitForRecoveriesToFinish(false); + + createAlias("aliascollection", "collection1"); + + morphline = parse("test-morphlines/loadSolrBasic", "aliascollection"); + Record record = new Record(); + record.put(Fields.ID, "id0-innsbruck"); + record.put("text", "mytext"); + record.put("user_screen_name", "foo"); + record.put("first_name", "Nadja"); // will be sanitized + startSession(); + assertEquals(1, collector.getNumStartEvents()); + Notifications.notifyBeginTransaction(morphline); + assertTrue(morphline.process(record)); + + record = new Record(); + record.put(Fields.ID, "id1-innsbruck"); + record.put("text", "mytext1"); + record.put("user_screen_name", "foo1"); + record.put("first_name", "Nadja1"); // will be sanitized + assertTrue(morphline.process(record)); + + Record expected = new Record(); + expected.put(Fields.ID, "id0-innsbruck"); + expected.put("text", "mytext"); + expected.put("user_screen_name", "foo"); + Iterator citer = collector.getRecords().iterator(); + assertEquals(expected, citer.next()); + + Record expected2 = new Record(); + expected2.put(Fields.ID, "id1-innsbruck"); + expected2.put("text", "mytext1"); + expected2.put("user_screen_name", "foo1"); + assertEquals(expected2, citer.next()); + + assertFalse(citer.hasNext()); + + commit(); + + QueryResponse rsp = cloudClient.query(new SolrQuery("*:*").setRows(100000).addSort(Fields.ID, SolrQuery.ORDER.asc)); + //System.out.println(rsp); + Iterator iter = rsp.getResults().iterator(); + assertEquals(expected.getFields(), next(iter)); + assertEquals(expected2.getFields(), next(iter)); + assertFalse(iter.hasNext()); + + Notifications.notifyRollbackTransaction(morphline); + Notifications.notifyShutdown(morphline); + + + createAlias("aliascollection", "collection1,collection2"); + + try { + parse("test-morphlines/loadSolrBasic", "aliascollection"); + fail("Expected IAE because update alias maps to multiple collections"); + } catch (IllegalArgumentException e) { + + } + + cloudClient.shutdown(); + } + + private NamedList createAlias(String alias, String collections) throws SolrServerException, IOException { + ModifiableSolrParams params = new ModifiableSolrParams(); + params.set("collections", collections); + params.set("name", alias); + params.set("action", CollectionAction.CREATEALIAS.toString()); + QueryRequest request = new QueryRequest(params); + request.setPath("/admin/collections"); + return cloudClient.request(request); + } + +} diff --git a/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkAvroTest.java b/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkAvroTest.java new file mode 100644 index 00000000000..4e082cc260f --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkAvroTest.java @@ -0,0 +1,164 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.morphlines.solr; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; + +import org.apache.avro.Schema.Field; +import org.apache.avro.file.DataFileReader; +import org.apache.avro.file.FileReader; +import org.apache.avro.generic.GenericData; +import org.apache.avro.generic.GenericDatumReader; +import org.apache.lucene.util.LuceneTestCase.Slow; +import org.apache.lucene.util.LuceneTestCase.SuppressCodecs; +import org.apache.solr.client.solrj.SolrQuery; +import org.apache.solr.client.solrj.response.QueryResponse; +import org.apache.solr.common.SolrDocument; + +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakAction; +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakAction.Action; +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakLingering; +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope; +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope.Scope; +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakZombies; +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakZombies.Consequence; +import com.cloudera.cdk.morphline.api.Record; +import com.cloudera.cdk.morphline.base.Fields; +import com.cloudera.cdk.morphline.base.Notifications; +import com.google.common.base.Preconditions; +import com.google.common.io.Files; + +@ThreadLeakAction({Action.WARN}) +@ThreadLeakLingering(linger = 0) +@ThreadLeakZombies(Consequence.CONTINUE) +@ThreadLeakScope(Scope.NONE) +@SuppressCodecs({"Lucene3x", "Lucene40"}) +@Slow +public class SolrMorphlineZkAvroTest extends AbstractSolrMorphlineZkTestBase { + + @Override + public void doTest() throws Exception { + File file = new File(RESOURCES_DIR + "/test-documents/sample-statuses-20120906-141433-medium.avro"); + + waitForRecoveriesToFinish(false); + + // load avro records via morphline and zk into solr + morphline = parse("test-morphlines/tutorialReadAvroContainer"); + Record record = new Record(); + byte[] body = Files.toByteArray(file); + record.put(Fields.ATTACHMENT_BODY, body); + startSession(); + Notifications.notifyBeginTransaction(morphline); + assertTrue(morphline.process(record)); + assertEquals(1, collector.getNumStartEvents()); + + commit(); + + // fetch sorted result set from solr + QueryResponse rsp = cloudClient.query(new SolrQuery("*:*").setRows(100000).addSort("id", SolrQuery.ORDER.asc)); + assertEquals(2104, collector.getRecords().size()); + assertEquals(collector.getRecords().size(), rsp.getResults().size()); + + Collections.sort(collector.getRecords(), new Comparator() { + @Override + public int compare(Record r1, Record r2) { + return r1.get("id").toString().compareTo(r2.get("id").toString()); + } + }); + + // fetch test input data and sort like solr result set + List records = new ArrayList(); + FileReader reader = new DataFileReader(file, new GenericDatumReader()); + while (reader.hasNext()) { + GenericData.Record expected = reader.next(); + records.add(expected); + } + assertEquals(collector.getRecords().size(), records.size()); + Collections.sort(records, new Comparator() { + @Override + public int compare(GenericData.Record r1, GenericData.Record r2) { + return r1.get("id").toString().compareTo(r2.get("id").toString()); + } + }); + + Object lastId = null; + for (int i = 0; i < records.size(); i++) { + //System.out.println("myrec" + i + ":" + records.get(i)); + Object id = records.get(i); + if (id != null && id.equals(lastId)) { + throw new IllegalStateException("Detected duplicate id. Test input data must not contain duplicate ids!"); + } + lastId = id; + } + + for (int i = 0; i < records.size(); i++) { + //System.out.println("myrsp" + i + ":" + rsp.getResults().get(i)); + } + + Iterator rspIter = rsp.getResults().iterator(); + for (int i = 0; i < records.size(); i++) { + // verify morphline spat out expected data + Record actual = collector.getRecords().get(i); + GenericData.Record expected = records.get(i); + Preconditions.checkNotNull(expected); + assertTweetEquals(expected, actual, i); + + // verify Solr result set contains expected data + actual = new Record(); + actual.getFields().putAll(next(rspIter)); + assertTweetEquals(expected, actual, i); + } + + Notifications.notifyRollbackTransaction(morphline); + Notifications.notifyShutdown(morphline); + cloudClient.shutdown(); + } + + private void assertTweetEquals(GenericData.Record expected, Record actual, int i) { + Preconditions.checkNotNull(expected); + Preconditions.checkNotNull(actual); +// System.out.println("\n\nexpected: " + toString(expected)); +// System.out.println("actual: " + actual); + String[] fieldNames = new String[] { + "id", + "in_reply_to_status_id", + "in_reply_to_user_id", + "retweet_count", + "text", + }; + for (String fieldName : fieldNames) { + assertEquals( + i + " fieldName: " + fieldName, + expected.get(fieldName).toString(), + actual.getFirstValue(fieldName).toString()); + } + } + + private String toString(GenericData.Record avroRecord) { + Record record = new Record(); + for (Field field : avroRecord.getSchema().getFields()) { + record.put(field.name(), avroRecord.get(field.pos())); + } + return record.toString(); // prints sorted by key for human readability + } + +} diff --git a/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkTest.java b/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkTest.java new file mode 100644 index 00000000000..0537c2e23ab --- /dev/null +++ b/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkTest.java @@ -0,0 +1,98 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.morphlines.solr; + +import java.util.Iterator; + +import org.apache.lucene.util.LuceneTestCase.Slow; +import org.apache.lucene.util.LuceneTestCase.SuppressCodecs; +import org.apache.solr.client.solrj.SolrQuery; +import org.apache.solr.client.solrj.response.QueryResponse; +import org.apache.solr.common.SolrDocument; + +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakAction; +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakAction.Action; +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakLingering; +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope; +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope.Scope; +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakZombies; +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakZombies.Consequence; +import com.cloudera.cdk.morphline.api.Record; +import com.cloudera.cdk.morphline.base.Fields; +import com.cloudera.cdk.morphline.base.Notifications; + +@ThreadLeakAction({Action.WARN}) +@ThreadLeakLingering(linger = 0) +@ThreadLeakZombies(Consequence.CONTINUE) +@ThreadLeakScope(Scope.NONE) +@SuppressCodecs({"Lucene3x", "Lucene40"}) +@Slow +public class SolrMorphlineZkTest extends AbstractSolrMorphlineZkTestBase { + + @Override + public void doTest() throws Exception { + + waitForRecoveriesToFinish(false); + + morphline = parse("test-morphlines/loadSolrBasic"); + Record record = new Record(); + record.put(Fields.ID, "id0-innsbruck"); + record.put("text", "mytext"); + record.put("user_screen_name", "foo"); + record.put("first_name", "Nadja"); // will be sanitized + startSession(); + assertEquals(1, collector.getNumStartEvents()); + Notifications.notifyBeginTransaction(morphline); + assertTrue(morphline.process(record)); + + record = new Record(); + record.put(Fields.ID, "id1-innsbruck"); + record.put("text", "mytext1"); + record.put("user_screen_name", "foo1"); + record.put("first_name", "Nadja1"); // will be sanitized + assertTrue(morphline.process(record)); + + Record expected = new Record(); + expected.put(Fields.ID, "id0-innsbruck"); + expected.put("text", "mytext"); + expected.put("user_screen_name", "foo"); + Iterator citer = collector.getRecords().iterator(); + assertEquals(expected, citer.next()); + + Record expected2 = new Record(); + expected2.put(Fields.ID, "id1-innsbruck"); + expected2.put("text", "mytext1"); + expected2.put("user_screen_name", "foo1"); + assertEquals(expected2, citer.next()); + + assertFalse(citer.hasNext()); + + commit(); + + QueryResponse rsp = cloudClient.query(new SolrQuery("*:*").setRows(100000).addSort(Fields.ID, SolrQuery.ORDER.asc)); + //System.out.println(rsp); + Iterator iter = rsp.getResults().iterator(); + assertEquals(expected.getFields(), next(iter)); + assertEquals(expected2.getFields(), next(iter)); + assertFalse(iter.hasNext()); + + Notifications.notifyRollbackTransaction(morphline); + Notifications.notifyShutdown(morphline); + cloudClient.shutdown(); + } + +} diff --git a/solr/contrib/solr-mr/build.xml b/solr/contrib/solr-mr/build.xml new file mode 100644 index 00000000000..d9f1f72a26b --- /dev/null +++ b/solr/contrib/solr-mr/build.xml @@ -0,0 +1,147 @@ + + + + + + + + Solr map-reduce index construction. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-mr/ivy.xml b/solr/contrib/solr-mr/ivy.xml new file mode 100644 index 00000000000..d51fd3b020e --- /dev/null +++ b/solr/contrib/solr-mr/ivy.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-mr/src/java/assembly/hadoop-job.xml b/solr/contrib/solr-mr/src/java/assembly/hadoop-job.xml new file mode 100644 index 00000000000..1640b6ff72e --- /dev/null +++ b/solr/contrib/solr-mr/src/java/assembly/hadoop-job.xml @@ -0,0 +1,39 @@ + + + + + + job + + jar + + false + + + false + runtime + lib + + ${groupId}:${artifactId} + + + + true + + ${groupId}:${artifactId} + + + + diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/BatchWriter.java b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/BatchWriter.java new file mode 100644 index 00000000000..6b650b6cc7b --- /dev/null +++ b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/BatchWriter.java @@ -0,0 +1,241 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Locale; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import org.apache.hadoop.mapreduce.TaskAttemptContext; +import org.apache.hadoop.mapreduce.TaskID; +import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer; +import org.apache.solr.client.solrj.response.UpdateResponse; +import org.apache.solr.common.SolrInputDocument; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Enables adding batches of documents to an EmbeddedSolrServer. + */ +class BatchWriter { + + private final EmbeddedSolrServer solr; + private volatile Exception batchWriteException = null; + + private static final Logger LOG = LoggerFactory.getLogger(BatchWriter.class); + + public Exception getBatchWriteException() { + return batchWriteException; + } + + public void setBatchWriteException(Exception batchWriteException) { + this.batchWriteException = batchWriteException; + } + + /** The number of writing threads. */ + final int writerThreads; + + /** Queue Size */ + final int queueSize; + + private final ThreadPoolExecutor batchPool; + + private TaskID taskId = null; + + /** + * The number of in progress batches, must be zero before the close can + * actually start closing + */ + AtomicInteger executingBatches = new AtomicInteger(0); + + /** + * Create the batch writer object, set the thread to daemon mode, and start + * it. + * + */ + + final class Batch implements Runnable { + + private List documents; + private UpdateResponse result; + + public Batch(Collection batch) { + documents = new ArrayList(batch); + } + + public void run() { + try { + executingBatches.getAndIncrement(); + result = runUpdate(documents); + } finally { + executingBatches.getAndDecrement(); + } + } + + protected List getDocuments() { + return documents; + } + + protected void setDocuments(List documents) { + this.documents = documents; + } + + protected UpdateResponse getResult() { + return result; + } + + protected void setResult(UpdateResponse result) { + this.result = result; + } + + protected void reset(List documents) { + if (this.documents == null) { + this.documents = new ArrayList(documents); + } else { + this.documents.clear(); + this.documents.addAll(documents); + } + result = null; + } + + protected void reset(SolrInputDocument document) { + if (this.documents == null) { + this.documents = new ArrayList(); + } else { + this.documents.clear(); + } + this.documents.add(document); + result = null; + } + } + + protected UpdateResponse runUpdate(List batchToWrite) { + try { + UpdateResponse result = solr.add(batchToWrite); + SolrRecordWriter.incrementCounter(taskId, SolrCounters.class.getName(), SolrCounters.BATCHES_WRITTEN.toString(), 1); + SolrRecordWriter.incrementCounter(taskId, SolrCounters.class.getName(), SolrCounters.DOCUMENTS_WRITTEN.toString(), batchToWrite.size()); + if (LOG.isDebugEnabled()) { + SolrRecordWriter.incrementCounter(taskId, SolrCounters.class.getName(), SolrCounters.BATCH_WRITE_TIME.toString(), result.getElapsedTime()); + } + return result; + } catch (Throwable e) { + if (e instanceof Exception) { + setBatchWriteException((Exception) e); + } else { + setBatchWriteException(new Exception(e)); + } + SolrRecordWriter.incrementCounter(taskId, getClass().getName() + ".errors", e.getClass().getName(), 1); + LOG.error("Unable to process batch", e); + return null; + } + } + + + public BatchWriter(EmbeddedSolrServer solr, int batchSize, TaskID tid, + int writerThreads, int queueSize) { + this.solr = solr; + this.writerThreads = writerThreads; + this.queueSize = queueSize; + taskId = tid; + + // we need to obtain the settings before the constructor + if (writerThreads != 0) { + batchPool = new ThreadPoolExecutor(writerThreads, writerThreads, 5, + TimeUnit.SECONDS, new LinkedBlockingQueue(queueSize), + new ThreadPoolExecutor.CallerRunsPolicy()); + } else { // single threaded case + batchPool = null; + } + } + + public void queueBatch(Collection batch) + throws IOException, SolrServerException { + + throwIf(); + Batch b = new Batch(batch); + if (batchPool != null) { + batchPool.execute(b); + } else { // single threaded case + b.run(); + throwIf(); + } + } + + public synchronized void close(TaskAttemptContext context) + throws InterruptedException, SolrServerException, IOException { + + if (batchPool != null) { + context.setStatus("Waiting for batches to complete"); + batchPool.shutdown(); + + while (!batchPool.isTerminated()) { + LOG.info(String.format(Locale.ENGLISH, + "Waiting for %d items and %d threads to finish executing", batchPool + .getQueue().size(), batchPool.getActiveCount())); + batchPool.awaitTermination(5, TimeUnit.SECONDS); + } + } + //reporter.setStatus("Committing Solr"); + //solr.commit(true, false); + context.setStatus("Optimizing Solr"); + int maxSegments = context.getConfiguration().getInt(SolrOutputFormat.SOLR_RECORD_WRITER_MAX_SEGMENTS, 1); + LOG.info("Optimizing Solr: forcing merge down to {} segments", maxSegments); + long start = System.currentTimeMillis(); + solr.optimize(true, false, maxSegments); + context.getCounter(SolrCounters.class.getName(), SolrCounters.PHYSICAL_REDUCER_MERGE_TIME.toString()).increment(System.currentTimeMillis() - start); + float secs = (System.currentTimeMillis() - start) / 1000.0f; + LOG.info("Optimizing Solr: done forcing merge down to {} segments in {} secs", maxSegments, secs); + context.setStatus("Shutting down Solr"); + // TODO is core close needed? - according to TestEmbeddedSolrServer it's not... + //core.close(); + solr.shutdown(); + } + + /** + * Throw a legal exception if a previous batch write had an exception. The + * previous state is cleared. Uses {@link #batchWriteException} for the state + * from the last exception. + * + * This will loose individual exceptions if the exceptions happen rapidly. + * + * @throws IOException On low level IO error + * @throws SolrServerException On Solr Exception + */ + private void throwIf() throws IOException, SolrServerException { + + final Exception last = batchWriteException; + batchWriteException = null; + + if (last == null) { + return; + } + if (last instanceof SolrServerException) { + throw (SolrServerException) last; + } + if (last instanceof IOException) { + throw (IOException) last; + } + throw new IOException("Batch Write Failure", last); + } +} diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/DataInputInputStream.java b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/DataInputInputStream.java new file mode 100644 index 00000000000..33f609f1f2d --- /dev/null +++ b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/DataInputInputStream.java @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.hadoop; + +import java.io.DataInput; +import java.io.IOException; +import java.io.InputStream; + +import org.apache.hadoop.classification.InterfaceAudience; + +/** + * An InputStream that wraps a DataInput. + * @see DataOutputOutputStream + */ +@InterfaceAudience.Private +public class DataInputInputStream extends InputStream { + + private DataInput in; + + /** + * Construct an InputStream from the given DataInput. If 'in' + * is already an InputStream, simply returns it. Otherwise, wraps + * it in an InputStream. + * @param in the DataInput to wrap + * @return an InputStream instance that reads from 'in' + */ + public static InputStream constructInputStream(DataInput in) { + if (in instanceof InputStream) { + return (InputStream)in; + } else { + return new DataInputInputStream(in); + } + } + + + public DataInputInputStream(DataInput in) { + this.in = in; + } + + @Override + public int read() throws IOException { + return in.readUnsignedByte(); + } +} diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/DataOutputOutputStream.java b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/DataOutputOutputStream.java new file mode 100644 index 00000000000..389c52a577d --- /dev/null +++ b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/DataOutputOutputStream.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop; + +import java.io.DataOutput; +import java.io.IOException; +import java.io.OutputStream; + +import org.apache.hadoop.classification.InterfaceAudience; + +/** + * OutputStream implementation that wraps a DataOutput. + */ +@InterfaceAudience.Private +public class DataOutputOutputStream extends OutputStream { + + private final DataOutput out; + + /** + * Construct an OutputStream from the given DataOutput. If 'out' + * is already an OutputStream, simply returns it. Otherwise, wraps + * it in an OutputStream. + * @param out the DataOutput to wrap + * @return an OutputStream instance that outputs to 'out' + */ + public static OutputStream constructOutputStream(DataOutput out) { + if (out instanceof OutputStream) { + return (OutputStream)out; + } else { + return new DataOutputOutputStream(out); + } + } + + private DataOutputOutputStream(DataOutput out) { + this.out = out; + } + + @Override + public void write(int b) throws IOException { + out.writeByte(b); + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + out.write(b, off, len); + } + + @Override + public void write(byte[] b) throws IOException { + out.write(b); + } +} diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/DryRunDocumentLoader.java b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/DryRunDocumentLoader.java new file mode 100644 index 00000000000..bacf1d0e1fc --- /dev/null +++ b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/DryRunDocumentLoader.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop; + +import org.apache.solr.client.solrj.response.SolrPingResponse; +import org.apache.solr.client.solrj.response.UpdateResponse; +import org.apache.solr.common.SolrInputDocument; +import org.apache.solr.morphlines.solr.DocumentLoader; + +/** + * Prints documents to stdout instead of loading them into Solr for quicker turnaround during early + * trial & debug sessions. + */ +final class DryRunDocumentLoader implements DocumentLoader { + + @Override + public void beginTransaction() { + } + + @Override + public void load(SolrInputDocument doc) { + System.out.println("dryrun: " + doc); + } + + @Override + public void commitTransaction() { + } + + @Override + public UpdateResponse rollbackTransaction() { + return new UpdateResponse(); + } + + @Override + public void shutdown() { + } + + @Override + public SolrPingResponse ping() { + return new SolrPingResponse(); + } + +} diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/GoLive.java b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/GoLive.java new file mode 100644 index 00000000000..a7e4f7dda9d --- /dev/null +++ b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/GoLive.java @@ -0,0 +1,212 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop; + +import java.io.IOException; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.Callable; +import java.util.concurrent.CompletionService; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorCompletionService; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +import org.apache.hadoop.fs.FileStatus; +import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.client.solrj.impl.CloudSolrServer; +import org.apache.solr.client.solrj.impl.HttpSolrServer; +import org.apache.solr.client.solrj.request.CoreAdminRequest; +import org.apache.solr.hadoop.MapReduceIndexerTool.Options; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The optional (parallel) GoLive phase merges the output shards of the previous + * phase into a set of live customer facing Solr servers, typically a SolrCloud. + */ +class GoLive { + + private static final Logger LOG = LoggerFactory.getLogger(GoLive.class); + + // TODO: handle clusters with replicas + public boolean goLive(Options options, FileStatus[] outDirs) { + LOG.info("Live merging of output shards into Solr cluster..."); + boolean success = false; + long start = System.currentTimeMillis(); + int concurrentMerges = options.goLiveThreads; + ThreadPoolExecutor executor = new ThreadPoolExecutor(concurrentMerges, + concurrentMerges, 1, TimeUnit.SECONDS, + new LinkedBlockingQueue()); + + try { + CompletionService completionService = new ExecutorCompletionService(executor); + Set> pending = new HashSet>(); + int cnt = -1; + for (final FileStatus dir : outDirs) { + + LOG.debug("processing: " + dir.getPath()); + + cnt++; + List urls = options.shardUrls.get(cnt); + + for (String url : urls) { + + String baseUrl = url; + if (baseUrl.endsWith("/")) { + baseUrl = baseUrl.substring(0, baseUrl.length() - 1); + } + + int lastPathIndex = baseUrl.lastIndexOf("/"); + if (lastPathIndex == -1) { + LOG.error("Found unexpected shardurl, live merge failed: " + baseUrl); + return false; + } + + final String name = baseUrl.substring(lastPathIndex + 1); + baseUrl = baseUrl.substring(0, lastPathIndex); + final String mergeUrl = baseUrl; + + Callable task = new Callable() { + @Override + public Request call() { + Request req = new Request(); + LOG.info("Live merge " + dir.getPath() + " into " + mergeUrl); + final HttpSolrServer server = new HttpSolrServer(mergeUrl); + try { + CoreAdminRequest.MergeIndexes mergeRequest = new CoreAdminRequest.MergeIndexes(); + mergeRequest.setCoreName(name); + mergeRequest.setIndexDirs(Arrays.asList(dir.getPath().toString() + "/data/index")); + try { + mergeRequest.process(server); + req.success = true; + } catch (SolrServerException e) { + req.e = e; + return req; + } catch (IOException e) { + req.e = e; + return req; + } + } finally { + server.shutdown(); + } + return req; + } + }; + pending.add(completionService.submit(task)); + } + } + + while (pending != null && pending.size() > 0) { + try { + Future future = completionService.take(); + if (future == null) break; + pending.remove(future); + + try { + Request req = future.get(); + + if (!req.success) { + // failed + LOG.error("A live merge command failed", req.e); + return false; + } + + } catch (ExecutionException e) { + LOG.error("Error sending live merge command", e); + return false; + } + + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + LOG.error("Live merge process interrupted", e); + return false; + } + } + + cnt = -1; + + + try { + LOG.info("Committing live merge..."); + if (options.zkHost != null) { + CloudSolrServer server = new CloudSolrServer(options.zkHost); + server.setDefaultCollection(options.collection); + server.commit(); + server.shutdown(); + } else { + for (List urls : options.shardUrls) { + for (String url : urls) { + // TODO: we should do these concurrently + HttpSolrServer server = new HttpSolrServer(url); + server.commit(); + server.shutdown(); + } + } + } + LOG.info("Done committing live merge"); + } catch (Exception e) { + LOG.error("Error sending commits to live Solr cluster", e); + return false; + } + + success = true; + return true; + } finally { + shutdownNowAndAwaitTermination(executor); + float secs = (System.currentTimeMillis() - start) / 1000.0f; + LOG.info("Live merging of index shards into Solr cluster took " + secs + " secs"); + if (success) { + LOG.info("Live merging completed successfully"); + } else { + LOG.info("Live merging failed"); + } + } + + // if an output dir does not exist, we should fail and do no merge? + } + + private void shutdownNowAndAwaitTermination(ExecutorService pool) { + pool.shutdown(); // Disable new tasks from being submitted + pool.shutdownNow(); // Cancel currently executing tasks + boolean shutdown = false; + while (!shutdown) { + try { + // Wait a while for existing tasks to terminate + shutdown = pool.awaitTermination(5, TimeUnit.SECONDS); + } catch (InterruptedException ie) { + // Preserve interrupt status + Thread.currentThread().interrupt(); + } + if (!shutdown) { + pool.shutdownNow(); // Cancel currently executing tasks + } + } + } + + + private static final class Request { + Exception e; + boolean success = false; + } + +} diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/HdfsFileFieldNames.java b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/HdfsFileFieldNames.java new file mode 100644 index 00000000000..c9eaef6c9e9 --- /dev/null +++ b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/HdfsFileFieldNames.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop; + + +/** + * Solr field names for metadata of an HDFS file. + */ +public interface HdfsFileFieldNames { + + public static final String FILE_UPLOAD_URL = "file_upload_url"; + public static final String FILE_DOWNLOAD_URL = "file_download_url"; + public static final String FILE_SCHEME = "file_scheme"; + public static final String FILE_HOST = "file_host"; + public static final String FILE_PORT = "file_port"; + public static final String FILE_PATH = "file_path"; + public static final String FILE_NAME = "file_name"; + public static final String FILE_LENGTH = "file_length"; + public static final String FILE_LAST_MODIFIED = "file_last_modified"; + public static final String FILE_OWNER = "file_owner"; + public static final String FILE_GROUP = "file_group"; + public static final String FILE_PERMISSIONS_USER = "file_permissions_user"; + public static final String FILE_PERMISSIONS_GROUP = "file_permissions_group"; + public static final String FILE_PERMISSIONS_OTHER = "file_permissions_other"; + public static final String FILE_PERMISSIONS_STICKYBIT = "file_permissions_stickybit"; + +} diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/HeartBeater.java b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/HeartBeater.java new file mode 100644 index 00000000000..229235b96b6 --- /dev/null +++ b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/HeartBeater.java @@ -0,0 +1,158 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop; + +import java.util.Locale; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import org.apache.hadoop.mapreduce.TaskInputOutputContext; +import org.apache.hadoop.util.Progressable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class runs a background thread that once every 60 seconds checks to see if + * a progress report is needed. If a report is needed it is issued. + * + * A simple counter {@link #threadsNeedingHeartBeat} handles the number of + * threads requesting a heart beat. + * + * The expected usage pattern is + * + *
    + *  try {
    + *       heartBeater.needHeartBeat();
    + *       do something that may take a while
    + *    } finally {
    + *       heartBeater.cancelHeartBeat();
    + *    }
    + * 
    + * + * + */ +public class HeartBeater extends Thread { + + public static Logger LOG = LoggerFactory.getLogger(HeartBeater.class); + + /** + * count of threads asking for heart beat, at 0 no heart beat done. This could + * be an atomic long but then missmatches in need/cancel could result in + * negative counts. + */ + private volatile int threadsNeedingHeartBeat = 0; + + private Progressable progress; + + /** + * The amount of time to wait between checks for the need to issue a heart + * beat. In milliseconds. + */ + private final long waitTimeMs = TimeUnit.MILLISECONDS.convert(60, TimeUnit.SECONDS); + + private final CountDownLatch isClosing = new CountDownLatch(1); + + /** + * Create the heart beat object thread set it to daemon priority and start the + * thread. When the count in {@link #threadsNeedingHeartBeat} is positive, the + * heart beat will be issued on the progress object every 60 seconds. + */ + public HeartBeater(Progressable progress) { + setDaemon(true); + this.progress = progress; + LOG.info("Heart beat reporting class is " + progress.getClass().getName()); + start(); + } + + public Progressable getProgress() { + return progress; + } + + public void setProgress(Progressable progress) { + this.progress = progress; + } + + @Override + public void run() { + LOG.info("HeartBeat thread running"); + while (true) { + try { + synchronized (this) { + if (threadsNeedingHeartBeat > 0) { + progress.progress(); + if (LOG.isInfoEnabled()) { + LOG.info(String.format(Locale.ENGLISH, "Issuing heart beat for %d threads", + threadsNeedingHeartBeat)); + } + } else { + if (LOG.isInfoEnabled()) { + LOG.info(String.format(Locale.ENGLISH, "heartbeat skipped count %d", + threadsNeedingHeartBeat)); + } + } + } + if (isClosing.await(waitTimeMs, TimeUnit.MILLISECONDS)) { + return; + } + } catch (Throwable e) { + LOG.error("HeartBeat throwable", e); + } + } + } + + /** + * inform the background thread that heartbeats are to be issued. Issue a + * heart beat also + */ + public synchronized void needHeartBeat() { + threadsNeedingHeartBeat++; + // Issue a progress report right away, + // just in case the the cancel comes before the background thread issues a + // report. + // If enough cases like this happen the 600 second timeout can occur + progress.progress(); + if (threadsNeedingHeartBeat == 1) { + // this.notify(); // wake up the heartbeater + } + } + + /** + * inform the background thread that this heartbeat request is not needed. + * This must be called at some point after each {@link #needHeartBeat()} + * request. + */ + public synchronized void cancelHeartBeat() { + if (threadsNeedingHeartBeat > 0) { + threadsNeedingHeartBeat--; + } else { + Exception e = new Exception("Dummy"); + e.fillInStackTrace(); + LOG.warn("extra call to cancelHeartBeat", e); + } + } + + public void setStatus(String status) { + if (progress instanceof TaskInputOutputContext) { + ((TaskInputOutputContext) progress).setStatus(status); + } + } + + /** Releases any resources */ + public void close() { + isClosing.countDown(); + } +} diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/LineRandomizerMapper.java b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/LineRandomizerMapper.java new file mode 100644 index 00000000000..5d65fa306df --- /dev/null +++ b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/LineRandomizerMapper.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop; + +import java.io.IOException; +import java.util.Random; + +import org.apache.hadoop.io.LongWritable; +import org.apache.hadoop.io.Text; +import org.apache.hadoop.mapreduce.Mapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * MR Mapper that randomizing a list of URLs. + * + * Mapper input is (offset, URL) pairs. Each such pair indicates a file to + * index. + * + * Mapper output is (randomPosition, URL) pairs. The reducer receives these + * pairs sorted by randomPosition. + */ +public class LineRandomizerMapper extends Mapper { + + private Random random; + + private static final Logger LOGGER = LoggerFactory.getLogger(LineRandomizerMapper.class); + + @Override + protected void setup(Context context) throws IOException, InterruptedException { + super.setup(context); + random = createRandom(context); + } + + @Override + protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { + LOGGER.debug("map key: {}, value: {}", key, value); + context.write(new LongWritable(random.nextLong()), value); + } + + private Random createRandom(Context context) { + long taskId = 0; + if (context.getTaskAttemptID() != null) { // MRUnit returns null + LOGGER.debug("context.getTaskAttemptID().getId(): {}", context.getTaskAttemptID().getId()); + LOGGER.debug("context.getTaskAttemptID().getTaskID().getId(): {}", context.getTaskAttemptID().getTaskID().getId()); + taskId = context.getTaskAttemptID().getTaskID().getId(); // taskId = 0, 1, ..., N + } + // create a good random seed, yet ensure deterministic PRNG sequence for easy reproducability + return new Random(421439783L * (taskId + 1)); + } + +} \ No newline at end of file diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/LineRandomizerReducer.java b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/LineRandomizerReducer.java new file mode 100644 index 00000000000..af7759e9f90 --- /dev/null +++ b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/LineRandomizerReducer.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop; + +import java.io.IOException; + +import org.apache.hadoop.io.LongWritable; +import org.apache.hadoop.io.NullWritable; +import org.apache.hadoop.io.Text; +import org.apache.hadoop.mapreduce.Reducer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * MR Reducer that randomizing a list of URLs. + * + * Reducer input is (randomPosition, URL) pairs. Each such pair indicates a file + * to index. + * + * Reducer output is a list of URLs, each URL in a random position. + */ +public class LineRandomizerReducer extends Reducer { + + private static final Logger LOGGER = LoggerFactory.getLogger(LineRandomizerReducer.class); + + @Override + protected void reduce(LongWritable key, Iterable values, Context context) throws IOException, InterruptedException { + for (Text value : values) { + LOGGER.debug("reduce key: {}, value: {}", key, value); + context.write(value, NullWritable.get()); + } + } +} \ No newline at end of file diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/MapReduceIndexerTool.java b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/MapReduceIndexerTool.java new file mode 100644 index 00000000000..e0e3e62709f --- /dev/null +++ b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/MapReduceIndexerTool.java @@ -0,0 +1,1300 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop; + + +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.io.UnsupportedEncodingException; +import java.io.Writer; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import net.sourceforge.argparse4j.ArgumentParsers; +import net.sourceforge.argparse4j.impl.Arguments; +import net.sourceforge.argparse4j.impl.action.HelpArgumentAction; +import net.sourceforge.argparse4j.impl.choice.RangeArgumentChoice; +import net.sourceforge.argparse4j.impl.type.FileArgumentType; +import net.sourceforge.argparse4j.inf.Argument; +import net.sourceforge.argparse4j.inf.ArgumentGroup; +import net.sourceforge.argparse4j.inf.ArgumentParser; +import net.sourceforge.argparse4j.inf.ArgumentParserException; +import net.sourceforge.argparse4j.inf.FeatureControl; +import net.sourceforge.argparse4j.inf.Namespace; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.conf.Configured; +import org.apache.hadoop.fs.FSDataOutputStream; +import org.apache.hadoop.fs.FileStatus; +import org.apache.hadoop.fs.FileSystem; +import org.apache.hadoop.fs.Path; +import org.apache.hadoop.fs.PathFilter; +import org.apache.hadoop.io.LongWritable; +import org.apache.hadoop.io.NullWritable; +import org.apache.hadoop.io.Text; +import org.apache.hadoop.mapred.JobClient; +import org.apache.hadoop.mapreduce.Job; +import org.apache.hadoop.mapreduce.JobContext; +import org.apache.hadoop.mapreduce.lib.input.NLineInputFormat; +import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; +import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat; +import org.apache.hadoop.util.GenericOptionsParser; +import org.apache.hadoop.util.Tool; +import org.apache.hadoop.util.ToolRunner; +import org.apache.log4j.PropertyConfigurator; +import org.apache.solr.common.cloud.SolrZkClient; +import org.apache.solr.hadoop.dedup.RetainMostRecentUpdateConflictResolver; +import org.apache.solr.hadoop.morphline.MorphlineMapRunner; +import org.apache.solr.hadoop.morphline.MorphlineMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.cloudera.cdk.morphline.base.Fields; + + +/** + * Public API for a MapReduce batch job driver that creates a set of Solr index shards from a set of + * input files and writes the indexes into HDFS, in a flexible, scalable and fault-tolerant manner. + * Also supports merging the output shards into a set of live customer facing Solr servers, + * typically a SolrCloud. + */ +public class MapReduceIndexerTool extends Configured implements Tool { + + Job job; // visible for testing only + + public static final String RESULTS_DIR = "results"; + + static final String MAIN_MEMORY_RANDOMIZATION_THRESHOLD = + MapReduceIndexerTool.class.getName() + ".mainMemoryRandomizationThreshold"; + + private static final String FULL_INPUT_LIST = "full-input-list.txt"; + + private static final Logger LOG = LoggerFactory.getLogger(MapReduceIndexerTool.class); + + + /** + * See http://argparse4j.sourceforge.net and for details see http://argparse4j.sourceforge.net/usage.html + */ + static final class MyArgumentParser { + + /** + * Parses the given command line arguments. + * + * @return exitCode null indicates the caller shall proceed with processing, + * non-null indicates the caller shall exit the program with the + * given exit status code. + */ + public Integer parseArgs(String[] args, Configuration conf, Options opts) { + assert args != null; + assert conf != null; + assert opts != null; + + if (args.length == 0) { + args = new String[] { "--help" }; + } + + ArgumentParser parser = ArgumentParsers + .newArgumentParser("hadoop [GenericOptions]... jar search-mr-*-job.jar " + MapReduceIndexerTool.class.getName(), false) + .defaultHelp(true) + .description( + "MapReduce batch job driver that takes a morphline and creates a set of Solr index shards from a set of input files " + + "and writes the indexes into HDFS, in a flexible, scalable and fault-tolerant manner. " + + "It also supports merging the output shards into a set of live customer facing Solr servers, " + + "typically a SolrCloud. The program proceeds in several consecutive MapReduce based phases, as follows:" + + "\n\n" + + "1) Randomization phase: This (parallel) phase randomizes the list of input files in order to spread " + + "indexing load more evenly among the mappers of the subsequent phase." + + "\n\n" + + "2) Mapper phase: This (parallel) phase takes the input files, extracts the relevant content, transforms it " + + "and hands SolrInputDocuments to a set of reducers. " + + "The ETL functionality is flexible and " + + "customizable using chains of arbitrary morphline commands that pipe records from one transformation command to another. " + + "Commands to parse and transform a set of standard data formats such as Avro, CSV, Text, HTML, XML, " + + "PDF, Word, Excel, etc. are provided out of the box, and additional custom commands and parsers for additional " + + "file or data formats can be added as morphline plugins. " + + "This is done by implementing a simple Java interface that consumes a record (e.g. a file in the form of an InputStream " + + "plus some headers plus contextual metadata) and generates as output zero or more records. " + + "Any kind of data format can be indexed and any Solr documents for any kind of Solr schema can be generated, " + + "and any custom ETL logic can be registered and executed.\n" + + "Record fields, including MIME types, can also explicitly be passed by force from the CLI to the morphline, for example: " + + "hadoop ... -D " + MorphlineMapRunner.MORPHLINE_FIELD_PREFIX + Fields.ATTACHMENT_MIME_TYPE + "=text/csv" + + "\n\n" + + "3) Reducer phase: This (parallel) phase loads the mapper's SolrInputDocuments into one EmbeddedSolrServer per reducer. " + + "Each such reducer and Solr server can be seen as a (micro) shard. The Solr servers store their " + + "data in HDFS." + + "\n\n" + + "4) Mapper-only merge phase: This (parallel) phase merges the set of reducer shards into the number of solr " + + "shards expected by the user, using a mapper-only job. This phase is omitted if the number " + + "of shards is already equal to the number of shards expected by the user. " + + "\n\n" + + "5) Go-live phase: This optional (parallel) phase merges the output shards of the previous phase into a set of " + + "live customer facing Solr servers, typically a SolrCloud. " + + "If this phase is omitted you can explicitly point each Solr server to one of the HDFS output shard directories." + + "\n\n" + + "Fault Tolerance: Mapper and reducer task attempts are retried on failure per the standard MapReduce semantics. " + + "On program startup all data in the --output-dir is deleted if that output directory already exists. " + + "If the whole job fails you can retry simply by rerunning the program again using the same arguments." + ); + + parser.addArgument("--help", "-help", "-h") + .help("Show this help message and exit") + .action(new HelpArgumentAction() { + @Override + public void run(ArgumentParser parser, Argument arg, Map attrs, String flag, Object value) throws ArgumentParserException { + try { + parser.printHelp(new PrintWriter(new OutputStreamWriter(System.out, "UTF-8"))); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException("Won't Happen for UTF-8"); + } + System.out.println(); + System.out.print(ToolRunnerHelpFormatter.getGenericCommandUsage()); + //ToolRunner.printGenericCommandUsage(System.out); + System.out.println( + "Examples: \n\n" + + + "# (Re)index an Avro based Twitter tweet file:\n" + + "sudo -u hdfs hadoop \\\n" + + " --config /etc/hadoop/conf.cloudera.mapreduce1 \\\n" + + " jar target/search-mr-*-job.jar " + MapReduceIndexerTool.class.getName() + " \\\n" + + " -D 'mapred.child.java.opts=-Xmx500m' \\\n" + +// " -D 'mapreduce.child.java.opts=-Xmx500m' \\\n" + + " --log4j src/test/resources/log4j.properties \\\n" + + " --morphline-file ../search-core/src/test/resources/test-morphlines/tutorialReadAvroContainer.conf \\\n" + + " --solr-home-dir src/test/resources/solr/minimr \\\n" + + " --output-dir hdfs://c2202.mycompany.com/user/$USER/test \\\n" + + " --shards 1 \\\n" + + " hdfs:///user/$USER/test-documents/sample-statuses-20120906-141433.avro\n" + + "\n" + + "# (Re)index all files that match all of the following conditions:\n" + + "# 1) File is contained in dir tree hdfs:///user/$USER/solrloadtest/twitter/tweets\n" + + "# 2) file name matches the glob pattern 'sample-statuses*.gz'\n" + + "# 3) file was last modified less than 100000 minutes ago\n" + + "# 4) file size is between 1 MB and 1 GB\n" + + "# Also include extra library jar file containing JSON tweet Java parser:\n" + + "hadoop jar target/search-mr-*-job.jar " + "com.cloudera.cdk.morphline.hadoop.find.HdfsFindTool" + " \\\n" + + " -find hdfs:///user/$USER/solrloadtest/twitter/tweets \\\n" + + " -type f \\\n" + + " -name 'sample-statuses*.gz' \\\n" + + " -mmin -1000000 \\\n" + + " -size -100000000c \\\n" + + " -size +1000000c \\\n" + + "| sudo -u hdfs hadoop \\\n" + + " --config /etc/hadoop/conf.cloudera.mapreduce1 \\\n" + + " jar target/search-mr-*-job.jar " + MapReduceIndexerTool.class.getName() + " \\\n" + + " -D 'mapred.child.java.opts=-Xmx500m' \\\n" + +// " -D 'mapreduce.child.java.opts=-Xmx500m' \\\n" + + " --log4j src/test/resources/log4j.properties \\\n" + + " --morphline-file ../search-core/src/test/resources/test-morphlines/tutorialReadJsonTestTweets.conf \\\n" + + " --solr-home-dir src/test/resources/solr/minimr \\\n" + + " --output-dir hdfs://c2202.mycompany.com/user/$USER/test \\\n" + + " --shards 100 \\\n" + + " --input-list -\n" + + "\n" + + "# Go live by merging resulting index shards into a live Solr cluster\n" + + "# (explicitly specify Solr URLs - for a SolrCloud cluster see next example):\n" + + "sudo -u hdfs hadoop \\\n" + + " --config /etc/hadoop/conf.cloudera.mapreduce1 \\\n" + + " jar target/search-mr-*-job.jar " + MapReduceIndexerTool.class.getName() + " \\\n" + + " -D 'mapred.child.java.opts=-Xmx500m' \\\n" + +// " -D 'mapreduce.child.java.opts=-Xmx500m' \\\n" + + " --log4j src/test/resources/log4j.properties \\\n" + + " --morphline-file ../search-core/src/test/resources/test-morphlines/tutorialReadAvroContainer.conf \\\n" + + " --solr-home-dir src/test/resources/solr/minimr \\\n" + + " --output-dir hdfs://c2202.mycompany.com/user/$USER/test \\\n" + + " --shard-url http://solr001.mycompany.com:8983/solr/collection1 \\\n" + + " --shard-url http://solr002.mycompany.com:8983/solr/collection1 \\\n" + + " --go-live \\\n" + + " hdfs:///user/foo/indir\n" + + "\n" + + "# Go live by merging resulting index shards into a live SolrCloud cluster\n" + + "# (discover shards and Solr URLs through ZooKeeper):\n" + + "sudo -u hdfs hadoop \\\n" + + " --config /etc/hadoop/conf.cloudera.mapreduce1 \\\n" + + " jar target/search-mr-*-job.jar " + MapReduceIndexerTool.class.getName() + " \\\n" + + " -D 'mapred.child.java.opts=-Xmx500m' \\\n" + +// " -D 'mapreduce.child.java.opts=-Xmx500m' \\\n" + + " --log4j src/test/resources/log4j.properties \\\n" + + " --morphline-file ../search-core/src/test/resources/test-morphlines/tutorialReadAvroContainer.conf \\\n" + + " --output-dir hdfs://c2202.mycompany.com/user/$USER/test \\\n" + + " --zk-host zk01.mycompany.com:2181/solr \\\n" + + " --collection collection1 \\\n" + + " --go-live \\\n" + + " hdfs:///user/foo/indir\n" + ); + throw new FoundHelpArgument(); // Trick to prevent processing of any remaining arguments + } + }); + + ArgumentGroup requiredGroup = parser.addArgumentGroup("Required arguments"); + + Argument outputDirArg = requiredGroup.addArgument("--output-dir") + .metavar("HDFS_URI") + .type(new PathArgumentType(conf) { + @Override + public Path convert(ArgumentParser parser, Argument arg, String value) throws ArgumentParserException { + Path path = super.convert(parser, arg, value); + if ("hdfs".equals(path.toUri().getScheme()) && path.toUri().getAuthority() == null) { + // TODO: consider defaulting to hadoop's fs.default.name here or in SolrRecordWriter.createEmbeddedSolrServer() + throw new ArgumentParserException("Missing authority in path URI: " + path, parser); + } + return path; + } + }.verifyHasScheme().verifyIsAbsolute().verifyCanWriteParent()) + .required(true) + .help("HDFS directory to write Solr indexes to. Inside there one output directory per shard will be generated. " + + "Example: hdfs://c2202.mycompany.com/user/$USER/test"); + + Argument inputListArg = parser.addArgument("--input-list") + .action(Arguments.append()) + .metavar("URI") + // .type(new PathArgumentType(fs).verifyExists().verifyCanRead()) + .type(Path.class) + .help("Local URI or HDFS URI of a UTF-8 encoded file containing a list of HDFS URIs to index, " + + "one URI per line in the file. If '-' is specified, URIs are read from the standard input. " + + "Multiple --input-list arguments can be specified."); + + Argument morphlineFileArg = requiredGroup.addArgument("--morphline-file") + .metavar("FILE") + .type(new FileArgumentType().verifyExists().verifyIsFile().verifyCanRead()) + .required(true) + .help("Relative or absolute path to a local config file that contains one or more morphlines. " + + "The file must be UTF-8 encoded. Example: /path/to/morphline.conf"); + + Argument morphlineIdArg = parser.addArgument("--morphline-id") + .metavar("STRING") + .type(String.class) + .help("The identifier of the morphline that shall be executed within the morphline config file " + + "specified by --morphline-file. If the --morphline-id option is ommitted the first (i.e. " + + "top-most) morphline within the config file is used. Example: morphline1"); + + Argument solrHomeDirArg = parser.addArgument("--solr-home-dir") + .metavar("DIR") + .type(new FileArgumentType() { + @Override + public File convert(ArgumentParser parser, Argument arg, String value) throws ArgumentParserException { + File solrHomeDir = super.convert(parser, arg, value); + File solrConfigFile = new File(new File(solrHomeDir, "conf"), "solrconfig.xml"); + new FileArgumentType().verifyExists().verifyIsFile().verifyCanRead().convert( + parser, arg, solrConfigFile.getPath()); + return solrHomeDir; + } + }.verifyIsDirectory().verifyCanRead()) + .required(false) + .help("Relative or absolute path to a local dir containing Solr conf/ dir and in particular " + + "conf/solrconfig.xml and optionally also lib/ dir. This directory will be uploaded to each MR task. " + + "Example: src/test/resources/solr/minimr"); + + Argument updateConflictResolverArg = parser.addArgument("--update-conflict-resolver") + .metavar("FQCN") + .type(String.class) + .setDefault(RetainMostRecentUpdateConflictResolver.class.getName()) + .help("Fully qualified class name of a Java class that implements the UpdateConflictResolver interface. " + + "This enables deduplication and ordering of a series of document updates for the same unique document " + + "key. For example, a MapReduce batch job might index multiple files in the same job where some of the " + + "files contain old and new versions of the very same document, using the same unique document key.\n" + + "Typically, implementations of this interface forbid collisions by throwing an exception, or ignore all but " + + "the most recent document version, or, in the general case, order colliding updates ascending from least " + + "recent to most recent (partial) update. The caller of this interface (i.e. the Hadoop Reducer) will then " + + "apply the updates to Solr in the order returned by the orderUpdates() method.\n" + + "The default RetainMostRecentUpdateConflictResolver implementation ignores all but the most recent document " + + "version, based on a configurable numeric Solr field, which defaults to the file_last_modified timestamp"); + + Argument mappersArg = parser.addArgument("--mappers") + .metavar("INTEGER") + .type(Integer.class) + .choices(new RangeArgumentChoice(-1, Integer.MAX_VALUE)) // TODO: also support X% syntax where X is an integer + .setDefault(-1) + .help("Tuning knob that indicates the maximum number of MR mapper tasks to use. -1 indicates use all map slots " + + "available on the cluster."); + + Argument reducersArg = parser.addArgument("--reducers") + .metavar("INTEGER") + .type(Integer.class) + .choices(new RangeArgumentChoice(-1, Integer.MAX_VALUE)) // TODO: also support X% syntax where X is an integer + .setDefault(-1) + .help("Tuning knob that indicates the number of reducers to index into. " + + "-1 indicates use all reduce slots available on the cluster. " + + "0 indicates use one reducer per output shard, which disables the mtree merge MR algorithm. " + + "The mtree merge MR algorithm improves scalability by spreading load " + + "(in particular CPU load) among a number of parallel reducers that can be much larger than the number " + + "of solr shards expected by the user. It can be seen as an extension of concurrent lucene merges " + + "and tiered lucene merges to the clustered case. The subsequent mapper-only phase " + + "merges the output of said large number of reducers to the number of shards expected by the user, " + + "again by utilizing more available parallelism on the cluster."); + + Argument fanoutArg = parser.addArgument("--fanout") + .metavar("INTEGER") + .type(Integer.class) + .choices(new RangeArgumentChoice(2, Integer.MAX_VALUE)) + .setDefault(Integer.MAX_VALUE) + .help(FeatureControl.SUPPRESS); + + Argument maxSegmentsArg = parser.addArgument("--max-segments") + .metavar("INTEGER") + .type(Integer.class) + .choices(new RangeArgumentChoice(1, Integer.MAX_VALUE)) + .setDefault(1) + .help("Tuning knob that indicates the maximum number of segments to be contained on output in the index of " + + "each reducer shard. After a reducer has built its output index it applies a merge policy to merge segments " + + "until there are <= maxSegments lucene segments left in this index. " + + "Merging segments involves reading and rewriting all data in all these segment files, " + + "potentially multiple times, which is very I/O intensive and time consuming. " + + "However, an index with fewer segments can later be merged faster, " + + "and it can later be queried faster once deployed to a live Solr serving shard. " + + "Set maxSegments to 1 to optimize the index for low query latency. " + + "In a nutshell, a small maxSegments value trades indexing latency for subsequently improved query latency. " + + "This can be a reasonable trade-off for batch indexing systems."); + + Argument fairSchedulerPoolArg = parser.addArgument("--fair-scheduler-pool") + .metavar("STRING") + .help("Optional tuning knob that indicates the name of the fair scheduler pool to submit jobs to. " + + "The Fair Scheduler is a pluggable MapReduce scheduler that provides a way to share large clusters. " + + "Fair scheduling is a method of assigning resources to jobs such that all jobs get, on average, an " + + "equal share of resources over time. When there is a single job running, that job uses the entire " + + "cluster. When other jobs are submitted, tasks slots that free up are assigned to the new jobs, so " + + "that each job gets roughly the same amount of CPU time. Unlike the default Hadoop scheduler, which " + + "forms a queue of jobs, this lets short jobs finish in reasonable time while not starving long jobs. " + + "It is also an easy way to share a cluster between multiple of users. Fair sharing can also work with " + + "job priorities - the priorities are used as weights to determine the fraction of total compute time " + + "that each job gets."); + + Argument dryRunArg = parser.addArgument("--dry-run") + .action(Arguments.storeTrue()) + .help("Run in local mode and print documents to stdout instead of loading them into Solr. This executes " + + "the morphline in the client process (without submitting a job to MR) for quicker turnaround during " + + "early trial & debug sessions."); + + Argument log4jConfigFileArg = parser.addArgument("--log4j") + .metavar("FILE") + .type(new FileArgumentType().verifyExists().verifyIsFile().verifyCanRead()) + .help("Relative or absolute path to a log4j.properties config file on the local file system. This file " + + "will be uploaded to each MR task. Example: /path/to/log4j.properties"); + + Argument verboseArg = parser.addArgument("--verbose", "-v") + .action(Arguments.storeTrue()) + .help("Turn on verbose output."); + + ArgumentGroup clusterInfoGroup = parser + .addArgumentGroup("Cluster arguments") + .description( + "Arguments that provide information about your Solr cluster. " + + "If you are not using --go-live, pass the --shards argument. If you are building shards for " + + "a Non-SolrCloud cluster, pass the --shard-url argument one or more times. To build indexes for" + + " a replicated cluster with --shard-url, pass replica urls consecutively and also pass --shards. " + + "If you are building shards for a SolrCloud cluster, pass the --zk-host argument. " + + "Using --go-live requires either --shard-url or --zk-host."); + + Argument shardUrlsArg = clusterInfoGroup.addArgument("--shard-url") + .metavar("URL") + .type(String.class) + .action(Arguments.append()) + .help("Solr URL to merge resulting shard into if using --go-live. " + + "Example: http://solr001.mycompany.com:8983/solr/collection1. " + + "Multiple --shard-url arguments can be specified, one for each desired shard. " + + "If you are merging shards into a SolrCloud cluster, use --zk-host instead."); + + Argument zkHostArg = clusterInfoGroup.addArgument("--zk-host") + .metavar("STRING") + .type(String.class) + .help("The address of a ZooKeeper ensemble being used by a SolrCloud cluster. " + + "This ZooKeeper ensemble will be examined to determine the number of output " + + "shards to create as well as the Solr URLs to merge the output shards into when using the --go-live option. " + + "Requires that you also pass the --collection to merge the shards into.\n" + + "\n" + + "The --zk-host option implements the same partitioning semantics as the standard SolrCloud " + + "Near-Real-Time (NRT) API. This enables to mix batch updates from MapReduce ingestion with " + + "updates from standard Solr NRT ingestion on the same SolrCloud cluster, " + + "using identical unique document keys.\n" + + "\n" + + "Format is: a list of comma separated host:port pairs, each corresponding to a zk " + + "server. Example: '127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183' If " + + "the optional chroot suffix is used the example would look " + + "like: '127.0.0.1:2181/solr,127.0.0.1:2182/solr,127.0.0.1:2183/solr' " + + "where the client would be rooted at '/solr' and all paths " + + "would be relative to this root - i.e. getting/setting/etc... " + + "'/foo/bar' would result in operations being run on " + + "'/solr/foo/bar' (from the server perspective).\n" + + "\n" + + "If --solr-home-dir is not specified, the Solr home directory for the collection " + + "will be downloaded from this ZooKeeper ensemble."); + + Argument shardsArg = clusterInfoGroup.addArgument("--shards") + .metavar("INTEGER") + .type(Integer.class) + .choices(new RangeArgumentChoice(1, Integer.MAX_VALUE)) + .help("Number of output shards to generate."); + + ArgumentGroup goLiveGroup = parser.addArgumentGroup("Go live arguments") + .description("Arguments for merging the shards that are built into a live Solr cluster. " + + "Also see the Cluster arguments."); + + Argument goLiveArg = goLiveGroup.addArgument("--go-live") + .action(Arguments.storeTrue()) + .help("Allows you to optionally merge the final index shards into a live Solr cluster after they are built. " + + "You can pass the ZooKeeper address with --zk-host and the relevant cluster information will be auto detected. " + + "If you are not using a SolrCloud cluster, --shard-url arguments can be used to specify each SolrCore to merge " + + "each shard into."); + + Argument collectionArg = goLiveGroup.addArgument("--collection") + .metavar("STRING") + .help("The SolrCloud collection to merge shards into when using --go-live and --zk-host. Example: collection1"); + + Argument goLiveThreadsArg = goLiveGroup.addArgument("--go-live-threads") + .metavar("INTEGER") + .type(Integer.class) + .choices(new RangeArgumentChoice(1, Integer.MAX_VALUE)) + .setDefault(1000) + .help("Tuning knob that indicates the maximum number of live merges to run in parallel at one time."); + + // trailing positional arguments + Argument inputFilesArg = parser.addArgument("input-files") + .metavar("HDFS_URI") + .type(new PathArgumentType(conf).verifyHasScheme().verifyExists().verifyCanRead()) + .nargs("*") + .setDefault() + .help("HDFS URI of file or directory tree to index."); + + Namespace ns; + try { + ns = parser.parseArgs(args); + } catch (FoundHelpArgument e) { + return 0; + } catch (ArgumentParserException e) { + parser.handleError(e); + return 1; + } + + opts.log4jConfigFile = (File) ns.get(log4jConfigFileArg.getDest()); + if (opts.log4jConfigFile != null) { + PropertyConfigurator.configure(opts.log4jConfigFile.getPath()); + } + LOG.debug("Parsed command line args: {}", ns); + + opts.inputLists = ns.getList(inputListArg.getDest()); + if (opts.inputLists == null) { + opts.inputLists = Collections.EMPTY_LIST; + } + opts.inputFiles = ns.getList(inputFilesArg.getDest()); + opts.outputDir = (Path) ns.get(outputDirArg.getDest()); + opts.mappers = ns.getInt(mappersArg.getDest()); + opts.reducers = ns.getInt(reducersArg.getDest()); + opts.updateConflictResolver = ns.getString(updateConflictResolverArg.getDest()); + opts.fanout = ns.getInt(fanoutArg.getDest()); + opts.maxSegments = ns.getInt(maxSegmentsArg.getDest()); + opts.morphlineFile = (File) ns.get(morphlineFileArg.getDest()); + opts.morphlineId = ns.getString(morphlineIdArg.getDest()); + opts.solrHomeDir = (File) ns.get(solrHomeDirArg.getDest()); + opts.fairSchedulerPool = ns.getString(fairSchedulerPoolArg.getDest()); + opts.isDryRun = ns.getBoolean(dryRunArg.getDest()); + opts.isVerbose = ns.getBoolean(verboseArg.getDest()); + opts.zkHost = ns.getString(zkHostArg.getDest()); + opts.shards = ns.getInt(shardsArg.getDest()); + opts.shardUrls = buildShardUrls(ns.getList(shardUrlsArg.getDest()), opts.shards); + opts.goLive = ns.getBoolean(goLiveArg.getDest()); + opts.goLiveThreads = ns.getInt(goLiveThreadsArg.getDest()); + opts.collection = ns.getString(collectionArg.getDest()); + + try { + verifyGoLiveArgs(opts, parser); + } catch (ArgumentParserException e) { + parser.handleError(e); + return 1; + } + + if (opts.inputLists.isEmpty() && opts.inputFiles.isEmpty()) { + LOG.info("No input files specified - nothing to process"); + return 0; // nothing to process + } + return null; + } + + /** Marker trick to prevent processing of any remaining arguments once --help option has been parsed */ + private static final class FoundHelpArgument extends RuntimeException { + } + } + // END OF INNER CLASS + + static List> buildShardUrls(List urls, Integer numShards) { + if (urls == null) return null; + List> shardUrls = new ArrayList>(urls.size()); + List list = null; + + int sz; + if (numShards == null) { + numShards = urls.size(); + } + sz = (int) Math.ceil(urls.size() / (float)numShards); + for (int i = 0; i < urls.size(); i++) { + if (i % sz == 0) { + list = new ArrayList(); + shardUrls.add(list); + } + list.add((String) urls.get(i)); + } + + return shardUrls; + } + + static final class Options { + boolean goLive; + String collection; + String zkHost; + Integer goLiveThreads; + List> shardUrls; + List inputLists; + List inputFiles; + Path outputDir; + int mappers; + int reducers; + String updateConflictResolver; + int fanout; + Integer shards; + int maxSegments; + File morphlineFile; + String morphlineId; + File solrHomeDir; + String fairSchedulerPool; + boolean isDryRun; + File log4jConfigFile; + boolean isVerbose; + } + // END OF INNER CLASS + + + /** API for command line clients */ + public static void main(String[] args) throws Exception { + int res = ToolRunner.run(new Configuration(), new MapReduceIndexerTool(), args); + System.exit(res); + } + + public MapReduceIndexerTool() {} + + @Override + public int run(String[] args) throws Exception { + Options opts = new Options(); + Integer exitCode = new MyArgumentParser().parseArgs(args, getConf(), opts); + if (exitCode != null) { + return exitCode; + } + return run(opts); + } + + /** API for Java clients; visible for testing; may become a public API eventually */ + int run(Options options) throws Exception { + + if ("local".equals(getConf().get("mapred.job.tracker"))) { + throw new IllegalStateException( + "Running with LocalJobRunner (i.e. all of Hadoop inside a single JVM) is not supported " + + "because LocalJobRunner does not (yet) implement the Hadoop Distributed Cache feature, " + + "which is required for passing files via --files and --libjars"); + } + + long programStartTime = System.currentTimeMillis(); + if (options.fairSchedulerPool != null) { + getConf().set("mapred.fairscheduler.pool", options.fairSchedulerPool); + } + getConf().setInt(SolrOutputFormat.SOLR_RECORD_WRITER_MAX_SEGMENTS, options.maxSegments); + + // switch off a false warning about allegedly not implementing Tool + // also see http://hadoop.6.n7.nabble.com/GenericOptionsParser-warning-td8103.html + // also see https://issues.apache.org/jira/browse/HADOOP-8183 + getConf().setBoolean("mapred.used.genericoptionsparser", true); + + if (options.log4jConfigFile != null) { + Utils.setLogConfigFile(options.log4jConfigFile, getConf()); + addDistributedCacheFile(options.log4jConfigFile, getConf()); + } + + job = Job.getInstance(getConf()); + job.setJarByClass(getClass()); + + if (options.morphlineFile == null) { + throw new ArgumentParserException("Argument --morphline-file is required", null); + } + verifyGoLiveArgs(options, null); + verifyZKStructure(options, null); + + int mappers = new JobClient(job.getConfiguration()).getClusterStatus().getMaxMapTasks(); // MR1 + //int mappers = job.getCluster().getClusterStatus().getMapSlotCapacity(); // Yarn only + LOG.info("Cluster reports {} mapper slots", mappers); + + if (options.mappers == -1) { + mappers = 8 * mappers; // better accomodate stragglers + } else { + mappers = options.mappers; + } + if (mappers <= 0) { + throw new IllegalStateException("Illegal number of mappers: " + mappers); + } + options.mappers = mappers; + + FileSystem fs = options.outputDir.getFileSystem(job.getConfiguration()); + if (fs.exists(options.outputDir) && !delete(options.outputDir, true, fs)) { + return -1; + } + Path outputResultsDir = new Path(options.outputDir, RESULTS_DIR); + Path outputReduceDir = new Path(options.outputDir, "reducers"); + Path outputStep1Dir = new Path(options.outputDir, "tmp1"); + Path outputStep2Dir = new Path(options.outputDir, "tmp2"); + Path outputTreeMergeStep = new Path(options.outputDir, "mtree-merge-output"); + Path fullInputList = new Path(outputStep1Dir, FULL_INPUT_LIST); + + LOG.debug("Creating list of input files for mappers: {}", fullInputList); + long numFiles = addInputFiles(options.inputFiles, options.inputLists, fullInputList, job.getConfiguration()); + if (numFiles == 0) { + LOG.info("No input files found - nothing to process"); + return 0; + } + int numLinesPerSplit = (int) ceilDivide(numFiles, mappers); + if (numLinesPerSplit < 0) { // numeric overflow from downcasting long to int? + numLinesPerSplit = Integer.MAX_VALUE; + } + numLinesPerSplit = Math.max(1, numLinesPerSplit); + + int realMappers = Math.min(mappers, (int) ceilDivide(numFiles, numLinesPerSplit)); + calculateNumReducers(options, realMappers); + int reducers = options.reducers; + LOG.info("Using these parameters: " + + "numFiles: {}, mappers: {}, realMappers: {}, reducers: {}, shards: {}, fanout: {}, maxSegments: {}", + new Object[] {numFiles, mappers, realMappers, reducers, options.shards, options.fanout, options.maxSegments}); + + + LOG.info("Randomizing list of {} input files to spread indexing load more evenly among mappers", numFiles); + long startTime = System.currentTimeMillis(); + if (numFiles < job.getConfiguration().getInt(MAIN_MEMORY_RANDOMIZATION_THRESHOLD, 100001)) { + // If there are few input files reduce latency by directly running main memory randomization + // instead of launching a high latency MapReduce job + randomizeFewInputFiles(fs, outputStep2Dir, fullInputList); + } else { + // Randomize using a MapReduce job. Use sequential algorithm below a certain threshold because there's no + // benefit in using many parallel mapper tasks just to randomize the order of a few lines each + int numLinesPerRandomizerSplit = Math.max(10 * 1000 * 1000, numLinesPerSplit); + Job randomizerJob = randomizeManyInputFiles(getConf(), fullInputList, outputStep2Dir, numLinesPerRandomizerSplit); + if (!waitForCompletion(randomizerJob, options.isVerbose)) { + return -1; // job failed + } + } + float secs = (System.currentTimeMillis() - startTime) / 1000.0f; + LOG.info("Done. Randomizing list of {} input files took {} secs", numFiles, secs); + + + job.setInputFormatClass(NLineInputFormat.class); + NLineInputFormat.addInputPath(job, outputStep2Dir); + NLineInputFormat.setNumLinesPerSplit(job, numLinesPerSplit); + FileOutputFormat.setOutputPath(job, outputReduceDir); + + String mapperClass = job.getConfiguration().get(JobContext.MAP_CLASS_ATTR); + if (mapperClass == null) { // enable customization + Class clazz = MorphlineMapper.class; + mapperClass = clazz.getName(); + job.setMapperClass(clazz); + } + job.setJobName(getClass().getName() + "/" + Utils.getShortClassName(mapperClass)); + + if (job.getConfiguration().get(JobContext.REDUCE_CLASS_ATTR) == null) { // enable customization + job.setReducerClass(SolrReducer.class); + } + if (options.updateConflictResolver == null) { + throw new IllegalArgumentException("updateConflictResolver must not be null"); + } + job.getConfiguration().set(SolrReducer.UPDATE_CONFLICT_RESOLVER, options.updateConflictResolver); + + if (options.zkHost != null) { + assert options.collection != null; + /* + * MapReduce partitioner that partitions the Mapper output such that each + * SolrInputDocument gets sent to the SolrCloud shard that it would have + * been sent to if the document were ingested via the standard SolrCloud + * Near Real Time (NRT) API. + * + * In other words, this class implements the same partitioning semantics + * as the standard SolrCloud NRT API. This enables to mix batch updates + * from MapReduce ingestion with updates from standard NRT ingestion on + * the same SolrCloud cluster, using identical unique document keys. + */ + if (job.getConfiguration().get(JobContext.PARTITIONER_CLASS_ATTR) == null) { // enable customization + job.setPartitionerClass(SolrCloudPartitioner.class); + } + job.getConfiguration().set(SolrCloudPartitioner.ZKHOST, options.zkHost); + job.getConfiguration().set(SolrCloudPartitioner.COLLECTION, options.collection); + } + job.getConfiguration().setInt(SolrCloudPartitioner.SHARDS, options.shards); + + job.setOutputFormatClass(SolrOutputFormat.class); + if (options.solrHomeDir != null) { + SolrOutputFormat.setupSolrHomeCache(options.solrHomeDir, job); + } else { + assert options.zkHost != null; + // use the config that this collection uses for the SolrHomeCache. + ZooKeeperInspector zki = new ZooKeeperInspector(); + SolrZkClient zkClient = zki.getZkClient(options.zkHost); + try { + String configName = zki.readConfigName(zkClient, options.collection); + File tmpSolrHomeDir = zki.downloadConfigDir(zkClient, configName); + SolrOutputFormat.setupSolrHomeCache(tmpSolrHomeDir, job); + options.solrHomeDir = tmpSolrHomeDir; + } finally { + zkClient.close(); + } + } + + MorphlineMapRunner runner = setupMorphline(options); + if (options.isDryRun && runner != null) { + LOG.info("Indexing {} files in dryrun mode", numFiles); + startTime = System.currentTimeMillis(); + dryRun(runner, fs, fullInputList); + secs = (System.currentTimeMillis() - startTime) / 1000.0f; + LOG.info("Done. Indexing {} files in dryrun mode took {} secs", numFiles, secs); + goodbye(null, programStartTime); + return 0; + } + job.getConfiguration().set(MorphlineMapRunner.MORPHLINE_FILE_PARAM, options.morphlineFile.getName()); + + job.setNumReduceTasks(reducers); + job.setOutputKeyClass(Text.class); + job.setOutputValueClass(SolrInputDocumentWritable.class); + LOG.info("Indexing {} files using {} real mappers into {} reducers", new Object[] {numFiles, realMappers, reducers}); + startTime = System.currentTimeMillis(); + if (!waitForCompletion(job, true)) { + return -1; // job failed + } + + secs = (System.currentTimeMillis() - startTime) / 1000.0f; + LOG.info("Done. Indexing {} files using {} real mappers into {} reducers took {} secs", new Object[] {numFiles, realMappers, reducers, secs}); + + int mtreeMergeIterations = 0; + if (reducers > options.shards) { + mtreeMergeIterations = (int) Math.round(log(options.fanout, reducers / options.shards)); + } + LOG.debug("MTree merge iterations to do: {}", mtreeMergeIterations); + int mtreeMergeIteration = 1; + while (reducers > options.shards) { // run a mtree merge iteration + job = Job.getInstance(getConf()); + job.setJarByClass(getClass()); + job.setJobName(getClass().getName() + "/" + Utils.getShortClassName(TreeMergeMapper.class)); + job.setMapperClass(TreeMergeMapper.class); + job.setOutputFormatClass(TreeMergeOutputFormat.class); + job.setNumReduceTasks(0); + job.setOutputKeyClass(Text.class); + job.setOutputValueClass(NullWritable.class); + job.setInputFormatClass(NLineInputFormat.class); + + Path inputStepDir = new Path(options.outputDir, "mtree-merge-input-iteration" + mtreeMergeIteration); + fullInputList = new Path(inputStepDir, FULL_INPUT_LIST); + LOG.debug("MTree merge iteration {}/{}: Creating input list file for mappers {}", new Object[] {mtreeMergeIteration, mtreeMergeIterations, fullInputList}); + numFiles = createTreeMergeInputDirList(outputReduceDir, fs, fullInputList); + if (numFiles != reducers) { + throw new IllegalStateException("Not same reducers: " + reducers + ", numFiles: " + numFiles); + } + NLineInputFormat.addInputPath(job, fullInputList); + NLineInputFormat.setNumLinesPerSplit(job, options.fanout); + FileOutputFormat.setOutputPath(job, outputTreeMergeStep); + + LOG.info("MTree merge iteration {}/{}: Merging {} shards into {} shards using fanout {}", new Object[] { + mtreeMergeIteration, mtreeMergeIterations, reducers, (reducers / options.fanout), options.fanout}); + startTime = System.currentTimeMillis(); + if (!waitForCompletion(job, options.isVerbose)) { + return -1; // job failed + } + secs = (System.currentTimeMillis() - startTime) / 1000.0f; + LOG.info("MTree merge iteration {}/{}: Done. Merging {} shards into {} shards using fanout {} took {} secs", + new Object[] {mtreeMergeIteration, mtreeMergeIterations, reducers, (reducers / options.fanout), options.fanout, secs}); + + if (!delete(outputReduceDir, true, fs)) { + return -1; + } + if (!rename(outputTreeMergeStep, outputReduceDir, fs)) { + return -1; + } + assert reducers % options.fanout == 0; + reducers = reducers / options.fanout; + mtreeMergeIteration++; + } + assert reducers == options.shards; + + // normalize output shard dir prefix, i.e. + // rename part-r-00000 to part-00000 (stems from zero tree merge iterations) + // rename part-m-00000 to part-00000 (stems from > 0 tree merge iterations) + for (FileStatus stats : fs.listStatus(outputReduceDir)) { + String dirPrefix = SolrOutputFormat.getOutputName(job); + Path srcPath = stats.getPath(); + if (stats.isDirectory() && srcPath.getName().startsWith(dirPrefix)) { + String dstName = dirPrefix + srcPath.getName().substring(dirPrefix.length() + "-m".length()); + Path dstPath = new Path(srcPath.getParent(), dstName); + if (!rename(srcPath, dstPath, fs)) { + return -1; + } + } + }; + + // publish results dir + if (!rename(outputReduceDir, outputResultsDir, fs)) { + return -1; + } + + if (options.goLive && !new GoLive().goLive(options, listSortedOutputShardDirs(outputResultsDir, fs))) { + return -1; + } + + goodbye(job, programStartTime); + return 0; + } + + private void calculateNumReducers(Options options, int realMappers) throws IOException { + if (options.shards <= 0) { + throw new IllegalStateException("Illegal number of shards: " + options.shards); + } + if (options.fanout <= 1) { + throw new IllegalStateException("Illegal fanout: " + options.fanout); + } + if (realMappers <= 0) { + throw new IllegalStateException("Illegal realMappers: " + realMappers); + } + + + int reducers = new JobClient(job.getConfiguration()).getClusterStatus().getMaxReduceTasks(); // MR1 + //reducers = job.getCluster().getClusterStatus().getReduceSlotCapacity(); // Yarn only + LOG.info("Cluster reports {} reduce slots", reducers); + + if (options.reducers == 0) { + reducers = options.shards; + } else if (options.reducers == -1) { + reducers = Math.min(reducers, realMappers); // no need to use many reducers when using few mappers + } else { + reducers = options.reducers; + } + reducers = Math.max(reducers, options.shards); + + if (reducers != options.shards) { + // Ensure fanout isn't misconfigured. fanout can't meaningfully be larger than what would be + // required to merge all leaf shards in one single tree merge iteration into root shards + options.fanout = Math.min(options.fanout, (int) ceilDivide(reducers, options.shards)); + + // Ensure invariant reducers == options.shards * (fanout ^ N) where N is an integer >= 1. + // N is the number of mtree merge iterations. + // This helps to evenly spread docs among root shards and simplifies the impl of the mtree merge algorithm. + int s = options.shards; + while (s < reducers) { + s = s * options.fanout; + } + reducers = s; + assert reducers % options.fanout == 0; + } + options.reducers = reducers; + } + + private long addInputFiles(List inputFiles, List inputLists, Path fullInputList, Configuration conf) + throws IOException { + + long numFiles = 0; + FileSystem fs = fullInputList.getFileSystem(conf); + FSDataOutputStream out = fs.create(fullInputList); + try { + Writer writer = new BufferedWriter(new OutputStreamWriter(out, "UTF-8")); + + for (Path inputFile : inputFiles) { + FileSystem inputFileFs = inputFile.getFileSystem(conf); + if (inputFileFs.exists(inputFile)) { + PathFilter pathFilter = new PathFilter() { + @Override + public boolean accept(Path path) { + return !path.getName().startsWith("."); // ignore "hidden" files and dirs + } + }; + numFiles += addInputFilesRecursively(inputFile, writer, inputFileFs, pathFilter); + } + } + + for (Path inputList : inputLists) { + InputStream in; + if (inputList.toString().equals("-")) { + in = System.in; + } else if (inputList.isAbsoluteAndSchemeAuthorityNull()) { + in = new BufferedInputStream(new FileInputStream(inputList.toString())); + } else { + in = inputList.getFileSystem(conf).open(inputList); + } + try { + BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8")); + String line; + while ((line = reader.readLine()) != null) { + writer.write(line + "\n"); + numFiles++; + } + reader.close(); + } finally { + in.close(); + } + } + + writer.close(); + } finally { + out.close(); + } + return numFiles; + } + + /** + * Add the specified file to the input set, if path is a directory then + * add the files contained therein. + */ + private long addInputFilesRecursively(Path path, Writer writer, FileSystem fs, PathFilter pathFilter) throws IOException { + long numFiles = 0; + for (FileStatus stat : fs.listStatus(path, pathFilter)) { + LOG.debug("Adding path {}", stat.getPath()); + if (stat.isDirectory()) { + numFiles += addInputFilesRecursively(stat.getPath(), writer, fs, pathFilter); + } else { + writer.write(stat.getPath().toString() + "\n"); + numFiles++; + } + } + return numFiles; + } + + private void randomizeFewInputFiles(FileSystem fs, Path outputStep2Dir, Path fullInputList) throws IOException { + List lines = new ArrayList(); + BufferedReader reader = new BufferedReader(new InputStreamReader(fs.open(fullInputList), "UTF-8")); + try { + String line; + while ((line = reader.readLine()) != null) { + lines.add(line); + } + } finally { + reader.close(); + } + + Collections.shuffle(lines, new Random(421439783L)); // constant seed for reproducability + + FSDataOutputStream out = fs.create(new Path(outputStep2Dir, FULL_INPUT_LIST)); + Writer writer = new BufferedWriter(new OutputStreamWriter(out, "UTF-8")); + try { + for (String line : lines) { + writer.write(line + "\n"); + } + } finally { + writer.close(); + } + } + + /** + * To uniformly spread load across all mappers we randomize fullInputList + * with a separate small Mapper & Reducer preprocessing step. This way + * each input line ends up on a random position in the output file list. + * Each mapper indexes a disjoint consecutive set of files such that each + * set has roughly the same size, at least from a probabilistic + * perspective. + * + * For example an input file with the following input list of URLs: + * + * A + * B + * C + * D + * + * might be randomized into the following output list of URLs: + * + * C + * A + * D + * B + * + * The implementation sorts the list of lines by randomly generated numbers. + */ + private Job randomizeManyInputFiles(Configuration baseConfig, Path fullInputList, Path outputStep2Dir, int numLinesPerSplit) + throws IOException { + + Job job2 = Job.getInstance(baseConfig); + job2.setJarByClass(getClass()); + job2.setJobName(getClass().getName() + "/" + Utils.getShortClassName(LineRandomizerMapper.class)); + job2.setInputFormatClass(NLineInputFormat.class); + NLineInputFormat.addInputPath(job2, fullInputList); + NLineInputFormat.setNumLinesPerSplit(job2, numLinesPerSplit); + job2.setMapperClass(LineRandomizerMapper.class); + job2.setReducerClass(LineRandomizerReducer.class); + job2.setOutputFormatClass(TextOutputFormat.class); + FileOutputFormat.setOutputPath(job2, outputStep2Dir); + job2.setNumReduceTasks(1); + job2.setOutputKeyClass(LongWritable.class); + job2.setOutputValueClass(Text.class); + return job2; + } + + // do the same as if the user had typed 'hadoop ... --files ' + private void addDistributedCacheFile(File file, Configuration conf) throws IOException { + String HADOOP_TMP_FILES = "tmpfiles"; // see Hadoop's GenericOptionsParser + String tmpFiles = conf.get(HADOOP_TMP_FILES, ""); + if (tmpFiles.length() > 0) { // already present? + tmpFiles = tmpFiles + ","; + } + GenericOptionsParser parser = new GenericOptionsParser( + new Configuration(conf), + new String[] { "--files", file.getCanonicalPath() }); + String additionalTmpFiles = parser.getConfiguration().get(HADOOP_TMP_FILES); + assert additionalTmpFiles != null; + assert additionalTmpFiles.length() > 0; + tmpFiles += additionalTmpFiles; + conf.set(HADOOP_TMP_FILES, tmpFiles); + } + + private MorphlineMapRunner setupMorphline(Options options) throws IOException, URISyntaxException { + if (options.morphlineId != null) { + job.getConfiguration().set(MorphlineMapRunner.MORPHLINE_ID_PARAM, options.morphlineId); + } + addDistributedCacheFile(options.morphlineFile, job.getConfiguration()); + if (!options.isDryRun) { + return null; + } + + /* + * Ensure scripting support for Java via morphline "java" command works even in dryRun mode, + * i.e. when executed in the client side driver JVM. To do so, collect all classpath URLs from + * the class loaders chain that org.apache.hadoop.util.RunJar (hadoop jar xyz-job.jar) and + * org.apache.hadoop.util.GenericOptionsParser (--libjars) have installed, then tell + * FastJavaScriptEngine.parse() where to find classes that JavaBuilder scripts might depend on. + * This ensures that scripts that reference external java classes compile without exceptions + * like this: + * + * ... caused by compilation failed: mfm:///MyJavaClass1.java:2: package + * com.cloudera.cdk.morphline.api does not exist + */ + LOG.trace("dryRun: java.class.path: {}", System.getProperty("java.class.path")); + String fullClassPath = ""; + ClassLoader loader = Thread.currentThread().getContextClassLoader(); // see org.apache.hadoop.util.RunJar + while (loader != null) { // walk class loaders, collect all classpath URLs + if (loader instanceof URLClassLoader) { + URL[] classPathPartURLs = ((URLClassLoader) loader).getURLs(); // see org.apache.hadoop.util.RunJar + LOG.trace("dryRun: classPathPartURLs: {}", Arrays.asList(classPathPartURLs)); + StringBuilder classPathParts = new StringBuilder(); + for (URL url : classPathPartURLs) { + File file = new File(url.toURI()); + if (classPathPartURLs.length > 0) { + classPathParts.append(File.pathSeparator); + } + classPathParts.append(file.getPath()); + } + LOG.trace("dryRun: classPathParts: {}", classPathParts); + String separator = File.pathSeparator; + if (fullClassPath.length() == 0 || classPathParts.length() == 0) { + separator = ""; + } + fullClassPath = classPathParts + separator + fullClassPath; + } + loader = loader.getParent(); + } + + // tell FastJavaScriptEngine.parse() where to find the classes that the script might depend on + if (fullClassPath.length() > 0) { + assert System.getProperty("java.class.path") != null; + fullClassPath = System.getProperty("java.class.path") + File.pathSeparator + fullClassPath; + LOG.trace("dryRun: fullClassPath: {}", fullClassPath); + System.setProperty("java.class.path", fullClassPath); // see FastJavaScriptEngine.parse() + } + + job.getConfiguration().set(MorphlineMapRunner.MORPHLINE_FILE_PARAM, options.morphlineFile.getPath()); + return new MorphlineMapRunner( + job.getConfiguration(), new DryRunDocumentLoader(), options.solrHomeDir.getPath()); + } + + /* + * Executes the morphline in the current process (without submitting a job to MR) for quicker + * turnaround during trial & debug sessions + */ + private void dryRun(MorphlineMapRunner runner, FileSystem fs, Path fullInputList) throws IOException { + BufferedReader reader = new BufferedReader(new InputStreamReader(fs.open(fullInputList), "UTF-8")); + try { + String line; + while ((line = reader.readLine()) != null) { + runner.map(line, job.getConfiguration(), null); + } + runner.cleanup(); + } finally { + reader.close(); + } + } + + private int createTreeMergeInputDirList(Path outputReduceDir, FileSystem fs, Path fullInputList) + throws FileNotFoundException, IOException { + + FileStatus[] dirs = listSortedOutputShardDirs(outputReduceDir, fs); + int numFiles = 0; + FSDataOutputStream out = fs.create(fullInputList); + try { + Writer writer = new BufferedWriter(new OutputStreamWriter(out, "UTF-8")); + for (FileStatus stat : dirs) { + LOG.debug("Adding path {}", stat.getPath()); + Path dir = new Path(stat.getPath(), "data/index"); + if (!fs.isDirectory(dir)) { + throw new IllegalStateException("Not a directory: " + dir); + } + writer.write(dir.toString() + "\n"); + numFiles++; + } + writer.close(); + } finally { + out.close(); + } + return numFiles; + } + + private FileStatus[] listSortedOutputShardDirs(Path outputReduceDir, FileSystem fs) throws FileNotFoundException, + IOException { + + final String dirPrefix = SolrOutputFormat.getOutputName(job); + FileStatus[] dirs = fs.listStatus(outputReduceDir, new PathFilter() { + @Override + public boolean accept(Path path) { + return path.getName().startsWith(dirPrefix); + } + }); + for (FileStatus dir : dirs) { + if (!dir.isDirectory()) { + throw new IllegalStateException("Not a directory: " + dir.getPath()); + } + } + Arrays.sort(dirs); // FIXME: handle more than 99999 shards (need numeric sort rather than lexicographical sort) + return dirs; + } + + private static void verifyGoLiveArgs(Options opts, ArgumentParser parser) throws ArgumentParserException { + if (opts.zkHost == null && opts.solrHomeDir == null) { + throw new ArgumentParserException("At least one of --zk-host or --solr-home-dir is required", parser); + } + if (opts.goLive && opts.zkHost == null && opts.shardUrls == null) { + throw new ArgumentParserException("--go-live requires that you also pass --shard-url or --zk-host", parser); + } + + if (opts.zkHost != null && opts.collection == null) { + throw new ArgumentParserException("--zk-host requires that you also pass --collection", parser); + } + + if (opts.zkHost != null) { + return; + // verify structure of ZK directory later, to avoid checking run-time errors during parsing. + } else if (opts.shardUrls != null) { + if (opts.shardUrls.size() == 0) { + throw new ArgumentParserException("--shard-url requires at least one URL", parser); + } + } else if (opts.shards != null) { + if (opts.shards <= 0) { + throw new ArgumentParserException("--shards must be a positive number: " + opts.shards, parser); + } + } else { + throw new ArgumentParserException("You must specify one of the following (mutually exclusive) arguments: " + + "--zk-host or --shard-url or --shards", parser); + } + + if (opts.shardUrls != null) { + opts.shards = opts.shardUrls.size(); + } + + assert opts.shards != null; + assert opts.shards > 0; + } + + private static void verifyZKStructure(Options opts, ArgumentParser parser) throws ArgumentParserException { + if (opts.zkHost != null) { + assert opts.collection != null; + ZooKeeperInspector zki = new ZooKeeperInspector(); + try { + opts.shardUrls = zki.extractShardUrls(opts.zkHost, opts.collection); + } catch (Exception e) { + LOG.debug("Cannot extract SolrCloud shard URLs from ZooKeeper", e); + throw new ArgumentParserException(e, parser); + } + assert opts.shardUrls != null; + if (opts.shardUrls.size() == 0) { + throw new ArgumentParserException("--zk-host requires ZooKeeper " + opts.zkHost + + " to contain at least one SolrCore for collection: " + opts.collection, parser); + } + opts.shards = opts.shardUrls.size(); + LOG.debug("Using SolrCloud shard URLs: {}", opts.shardUrls); + } + } + + private boolean waitForCompletion(Job job, boolean isVerbose) + throws IOException, InterruptedException, ClassNotFoundException { + + LOG.debug("Running job: " + getJobInfo(job)); + boolean success = job.waitForCompletion(isVerbose); + if (!success) { + LOG.error("Job failed! " + getJobInfo(job)); + } + return success; + } + + private void goodbye(Job job, long startTime) { + float secs = (System.currentTimeMillis() - startTime) / 1000.0f; + if (job != null) { + LOG.info("Succeeded with job: " + getJobInfo(job)); + } + LOG.info("Success. Done. Program took {} secs. Goodbye.", secs); + } + + private String getJobInfo(Job job) { + return "jobName: " + job.getJobName() + ", jobId: " + job.getJobID(); + } + + private boolean rename(Path src, Path dst, FileSystem fs) throws IOException { + boolean success = fs.rename(src, dst); + if (!success) { + LOG.error("Cannot rename " + src + " to " + dst); + } + return success; + } + + private boolean delete(Path path, boolean recursive, FileSystem fs) throws IOException { + boolean success = fs.delete(path, recursive); + if (!success) { + LOG.error("Cannot delete " + path); + } + return success; + } + + // same as IntMath.divide(p, q, RoundingMode.CEILING) + private long ceilDivide(long p, long q) { + long result = p / q; + if (p % q != 0) { + result++; + } + return result; + } + + /** + * Returns logbasevalue. + */ + private double log(double base, double value) { + return Math.log(value) / Math.log(base); + } + +} diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/PathArgumentType.java b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/PathArgumentType.java new file mode 100644 index 00000000000..770a2f9f90b --- /dev/null +++ b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/PathArgumentType.java @@ -0,0 +1,233 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop; + +import java.io.IOException; + +import net.sourceforge.argparse4j.inf.Argument; +import net.sourceforge.argparse4j.inf.ArgumentParser; +import net.sourceforge.argparse4j.inf.ArgumentParserException; +import net.sourceforge.argparse4j.inf.ArgumentType; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.FileSystem; +import org.apache.hadoop.fs.Path; +import org.apache.hadoop.fs.permission.FsAction; + +/** + * ArgumentType subclass for HDFS Path type, using fluent style API. + */ +public class PathArgumentType implements ArgumentType { + + private final Configuration conf; + private FileSystem fs; + private boolean acceptSystemIn = false; + private boolean verifyExists = false; + private boolean verifyNotExists = false; + private boolean verifyIsFile = false; + private boolean verifyIsDirectory = false; + private boolean verifyCanRead = false; + private boolean verifyCanWrite = false; + private boolean verifyCanWriteParent = false; + private boolean verifyCanExecute = false; + private boolean verifyIsAbsolute = false; + private boolean verifyHasScheme = false; + private String verifyScheme = null; + + public PathArgumentType(Configuration conf) { + this.conf = conf; + } + + public PathArgumentType acceptSystemIn() { + acceptSystemIn = true; + return this; + } + + public PathArgumentType verifyExists() { + verifyExists = true; + return this; + } + + public PathArgumentType verifyNotExists() { + verifyNotExists = true; + return this; + } + + public PathArgumentType verifyIsFile() { + verifyIsFile = true; + return this; + } + + public PathArgumentType verifyIsDirectory() { + verifyIsDirectory = true; + return this; + } + + public PathArgumentType verifyCanRead() { + verifyCanRead = true; + return this; + } + + public PathArgumentType verifyCanWrite() { + verifyCanWrite = true; + return this; + } + + public PathArgumentType verifyCanWriteParent() { + verifyCanWriteParent = true; + return this; + } + + public PathArgumentType verifyCanExecute() { + verifyCanExecute = true; + return this; + } + + public PathArgumentType verifyIsAbsolute() { + verifyIsAbsolute = true; + return this; + } + + public PathArgumentType verifyHasScheme() { + verifyHasScheme = true; + return this; + } + + public PathArgumentType verifyScheme(String scheme) { + verifyScheme = scheme; + return this; + } + + @Override + public Path convert(ArgumentParser parser, Argument arg, String value) throws ArgumentParserException { + Path file = new Path(value); + try { + fs = file.getFileSystem(conf); + if (verifyHasScheme && !isSystemIn(file)) { + verifyHasScheme(parser, file); + } + if (verifyScheme != null && !isSystemIn(file)) { + verifyScheme(parser, file); + } + if (verifyIsAbsolute && !isSystemIn(file)) { + verifyIsAbsolute(parser, file); + } + if (verifyExists && !isSystemIn(file)) { + verifyExists(parser, file); + } + if (verifyNotExists && !isSystemIn(file)) { + verifyNotExists(parser, file); + } + if (verifyIsFile && !isSystemIn(file)) { + verifyIsFile(parser, file); + } + if (verifyIsDirectory && !isSystemIn(file)) { + verifyIsDirectory(parser, file); + } + if (verifyCanRead && !isSystemIn(file)) { + verifyCanRead(parser, file); + } + if (verifyCanWrite && !isSystemIn(file)) { + verifyCanWrite(parser, file); + } + if (verifyCanWriteParent && !isSystemIn(file)) { + verifyCanWriteParent(parser, file); + } + if (verifyCanExecute && !isSystemIn(file)) { + verifyCanExecute(parser, file); + } + } catch (IOException e) { + throw new ArgumentParserException(e, parser); + } + return file; + } + + private void verifyExists(ArgumentParser parser, Path file) throws ArgumentParserException, IOException { + if (!fs.exists(file)) { + throw new ArgumentParserException("File not found: " + file, parser); + } + } + + private void verifyNotExists(ArgumentParser parser, Path file) throws ArgumentParserException, IOException { + if (fs.exists(file)) { + throw new ArgumentParserException("File found: " + file, parser); + } + } + + private void verifyIsFile(ArgumentParser parser, Path file) throws ArgumentParserException, IOException { + if (!fs.isFile(file)) { + throw new ArgumentParserException("Not a file: " + file, parser); + } + } + + private void verifyIsDirectory(ArgumentParser parser, Path file) throws ArgumentParserException, IOException { + if (!fs.isDirectory(file)) { + throw new ArgumentParserException("Not a directory: " + file, parser); + } + } + + private void verifyCanRead(ArgumentParser parser, Path file) throws ArgumentParserException, IOException { + verifyExists(parser, file); + if (!fs.getFileStatus(file).getPermission().getUserAction().implies(FsAction.READ)) { + throw new ArgumentParserException("Insufficient permissions to read file: " + file, parser); + } + } + + private void verifyCanWrite(ArgumentParser parser, Path file) throws ArgumentParserException, IOException { + verifyExists(parser, file); + if (!fs.getFileStatus(file).getPermission().getUserAction().implies(FsAction.WRITE)) { + throw new ArgumentParserException("Insufficient permissions to write file: " + file, parser); + } + } + + private void verifyCanWriteParent(ArgumentParser parser, Path file) throws ArgumentParserException, IOException { + Path parent = file.getParent(); + if (parent == null || !fs.exists(parent) || !fs.getFileStatus(parent).getPermission().getUserAction().implies(FsAction.WRITE)) { + throw new ArgumentParserException("Cannot write parent of file: " + file, parser); + } + } + + private void verifyCanExecute(ArgumentParser parser, Path file) throws ArgumentParserException, IOException { + verifyExists(parser, file); + if (!fs.getFileStatus(file).getPermission().getUserAction().implies(FsAction.EXECUTE)) { + throw new ArgumentParserException("Insufficient permissions to execute file: " + file, parser); + } + } + + private void verifyIsAbsolute(ArgumentParser parser, Path file) throws ArgumentParserException { + if (!file.isAbsolute()) { + throw new ArgumentParserException("Not an absolute file: " + file, parser); + } + } + + private void verifyHasScheme(ArgumentParser parser, Path file) throws ArgumentParserException { + if (file.toUri().getScheme() == null) { + throw new ArgumentParserException("URI scheme is missing in path: " + file, parser); + } + } + + private void verifyScheme(ArgumentParser parser, Path file) throws ArgumentParserException { + if (!verifyScheme.equals(file.toUri().getScheme())) { + throw new ArgumentParserException("Scheme of path: " + file + " must be: " + verifyScheme, parser); + } + } + + private boolean isSystemIn(Path file) { + return acceptSystemIn && file.toString().equals("-"); + } + +} diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/PathParts.java b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/PathParts.java new file mode 100644 index 00000000000..690901b4c76 --- /dev/null +++ b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/PathParts.java @@ -0,0 +1,130 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop; + +import java.io.IOException; +import java.net.URI; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.FileStatus; +import org.apache.hadoop.fs.FileSystem; +import org.apache.hadoop.fs.Path; +import org.apache.hadoop.hdfs.server.namenode.NameNode; + +/** + * Extracts various components of an HDFS Path + */ +public final class PathParts { + + private final String uploadURL; + private final Configuration conf; + private final FileSystem fs; + private final Path normalizedPath; + private FileStatus stats; + + public PathParts(String uploadURL, Configuration conf) throws IOException { + if (uploadURL == null) { + throw new IllegalArgumentException("Path must not be null: " + uploadURL); + } + this.uploadURL = uploadURL; + if (conf == null) { + throw new IllegalArgumentException("Configuration must not be null: " + uploadURL); + } + this.conf = conf; + URI uri = stringToUri(uploadURL); + this.fs = FileSystem.get(uri, conf); + if (fs == null) { + throw new IllegalArgumentException("File system must not be null: " + uploadURL); + } + this.normalizedPath = fs.makeQualified(new Path(uri)); + if (!normalizedPath.isAbsolute()) { + throw new IllegalArgumentException("Path must be absolute: " + uploadURL); + } + if (getScheme() == null) { + throw new IllegalArgumentException("Scheme must not be null: " + uploadURL); + } + if (getHost() == null) { + throw new IllegalArgumentException("Host must not be null: " + uploadURL); + } + if (getPort() < 0) { + throw new IllegalArgumentException("Port must not be negative: " + uploadURL); + } + } + + public String getUploadURL() { + return uploadURL; + } + + public Path getUploadPath() { + return new Path(getUploadURL()); + } + + public String getURIPath() { + return normalizedPath.toUri().getPath(); + } + + public String getName() { + return normalizedPath.getName(); + } + + public String getScheme() { + return normalizedPath.toUri().getScheme(); + } + + public String getHost() { + return normalizedPath.toUri().getHost(); + } + + public int getPort() { + int port = normalizedPath.toUri().getPort(); + if (port == -1) { + port = fs.getWorkingDirectory().toUri().getPort(); + if (port == -1) { + port = NameNode.DEFAULT_PORT; + } + } + return port; + } + + public String getId() { + return getScheme() + "://" + getHost() + ":" + getPort() + getURIPath(); + } + + public String getDownloadURL() { + return getId(); + } + + public Configuration getConfiguration() { + return conf; + } + + public FileSystem getFileSystem() { + return fs; + } + + public FileStatus getFileStatus() throws IOException { + if (stats == null) { + stats = getFileSystem().getFileStatus(getUploadPath()); + } + return stats; + } + + private URI stringToUri(String pathString) { + //return new Path(pathString).toUri().normalize(); + return URI.create(pathString).normalize(); + } +} diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrCloudPartitioner.java b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrCloudPartitioner.java new file mode 100644 index 00000000000..27f532c174a --- /dev/null +++ b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrCloudPartitioner.java @@ -0,0 +1,142 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.hadoop.conf.Configurable; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.io.Text; +import org.apache.hadoop.mapreduce.Partitioner; +import org.apache.solr.common.SolrInputDocument; +import org.apache.solr.common.cloud.DocCollection; +import org.apache.solr.common.cloud.DocRouter; +import org.apache.solr.common.cloud.Slice; +import org.apache.solr.common.params.MapSolrParams; +import org.apache.solr.common.params.SolrParams; +import org.apache.solr.common.util.Hash; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * MapReduce partitioner that partitions the Mapper output such that each + * SolrInputDocument gets sent to the SolrCloud shard that it would have been + * sent to if the document were ingested via the standard SolrCloud Near Real + * Time (NRT) API. + * + * In other words, this class implements the same partitioning semantics as the + * standard SolrCloud NRT API. This enables to mix batch updates from MapReduce + * ingestion with updates from standard NRT ingestion on the same SolrCloud + * cluster, using identical unique document keys. + */ +public class SolrCloudPartitioner extends Partitioner implements Configurable { + + private Configuration conf; + private DocCollection docCollection; + private Map shardNumbers; + private int shards = 0; + private final SolrParams emptySolrParams = new MapSolrParams(Collections.EMPTY_MAP); + + public static final String SHARDS = SolrCloudPartitioner.class.getName() + ".shards"; + public static final String ZKHOST = SolrCloudPartitioner.class.getName() + ".zkHost"; + public static final String COLLECTION = SolrCloudPartitioner.class.getName() + ".collection"; + + private static final Logger LOG = LoggerFactory.getLogger(SolrCloudPartitioner.class); + + public SolrCloudPartitioner() {} + + @Override + public void setConf(Configuration conf) { + this.conf = conf; + this.shards = conf.getInt(SHARDS, -1); + if (shards <= 0) { + throw new IllegalArgumentException("Illegal shards: " + shards); + } + String zkHost = conf.get(ZKHOST); + if (zkHost == null) { + throw new IllegalArgumentException("zkHost must not be null"); + } + String collection = conf.get(COLLECTION); + if (collection == null) { + throw new IllegalArgumentException("collection must not be null"); + } + LOG.info("Using SolrCloud zkHost: {}, collection: {}", zkHost, collection); + docCollection = new ZooKeeperInspector().extractDocCollection(zkHost, collection); + if (docCollection == null) { + throw new IllegalArgumentException("docCollection must not be null"); + } + if (docCollection.getSlicesMap().size() != shards) { + throw new IllegalArgumentException("Incompatible shards: + " + shards + " for docCollection: " + docCollection); + } + List slices = new ZooKeeperInspector().getSortedSlices(docCollection.getSlices()); + if (slices.size() != shards) { + throw new IllegalStateException("Incompatible sorted shards: + " + shards + " for docCollection: " + docCollection); + } + shardNumbers = new HashMap(10 * slices.size()); // sparse for performance + for (int i = 0; i < slices.size(); i++) { + shardNumbers.put(slices.get(i).getName(), i); + } + LOG.debug("Using SolrCloud docCollection: {}", docCollection); + DocRouter docRouter = docCollection.getRouter(); + if (docRouter == null) { + throw new IllegalArgumentException("docRouter must not be null"); + } + LOG.info("Using SolrCloud docRouterClass: {}", docRouter.getClass()); + } + + @Override + public Configuration getConf() { + return conf; + } + + @Override + public int getPartition(Text key, SolrInputDocumentWritable value, int numPartitions) { + DocRouter docRouter = docCollection.getRouter(); + SolrInputDocument doc = value.getSolrInputDocument(); + String keyStr = key.toString(); + + // TODO: scalability: replace linear search in HashBasedRouter.hashToSlice() with binary search on sorted hash ranges + Slice slice = docRouter.getTargetSlice(keyStr, doc, emptySolrParams, docCollection); + +// LOG.info("slice: {}", slice); + if (slice == null) { + throw new IllegalStateException("No matching slice found! The slice seems unavailable. docRouterClass: " + + docRouter.getClass().getName()); + } + int rootShard = shardNumbers.get(slice.getName()); + if (rootShard < 0 || rootShard >= shards) { + throw new IllegalStateException("Illegal shard number " + rootShard + " for slice: " + slice + ", docCollection: " + + docCollection); + } + + // map doc to micro shard aka leaf shard, akin to HashBasedRouter.sliceHash() + // taking into account mtree merge algorithm + assert numPartitions % shards == 0; // Also note that numPartitions is equal to the number of reducers + int hashCode = Hash.murmurhash3_x86_32(keyStr, 0, keyStr.length(), 0); + int offset = (hashCode & Integer.MAX_VALUE) % (numPartitions / shards); + int microShard = (rootShard * (numPartitions / shards)) + offset; +// LOG.info("Subpartitions rootShard: {}, offset: {}", rootShard, offset); +// LOG.info("Partitioned to p: {} for numPartitions: {}, shards: {}, key: {}, value: {}", microShard, numPartitions, shards, key, value); + + assert microShard >= 0 && microShard < numPartitions; + return microShard; + } + +} diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrCounters.java b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrCounters.java new file mode 100644 index 00000000000..88e9acb57cc --- /dev/null +++ b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrCounters.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop; + +public enum SolrCounters { + + DOCUMENTS_WRITTEN (getClassName(SolrReducer.class) + + ": Number of documents processed"), + + BATCHES_WRITTEN (getClassName(SolrReducer.class) + + ": Number of document batches processed"), + + BATCH_WRITE_TIME (getClassName(SolrReducer.class) + + ": Time spent by reducers writing batches [ms]"), + + PHYSICAL_REDUCER_MERGE_TIME (getClassName(SolrReducer.class) + + ": Time spent by reducers on physical merges [ms]"), + + LOGICAL_TREE_MERGE_TIME (getClassName(TreeMergeMapper.class) + + ": Time spent on logical tree merges [ms]"), + + PHYSICAL_TREE_MERGE_TIME (getClassName(TreeMergeMapper.class) + + ": Time spent on physical tree merges [ms]"); + + private final String label; + + private SolrCounters(String label) { + this.label = label; + } + + public String toString() { + return label; + } + + private static String getClassName(Class clazz) { + return Utils.getShortClassName(clazz); + } + +} diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrInputDocumentWritable.java b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrInputDocumentWritable.java new file mode 100644 index 00000000000..e043f7a0ed2 --- /dev/null +++ b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrInputDocumentWritable.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +import org.apache.hadoop.io.Writable; +import org.apache.solr.common.SolrInputDocument; +import org.apache.solr.common.util.FastOutputStream; +import org.apache.solr.common.util.JavaBinCodec; + +public class SolrInputDocumentWritable implements Writable { + private SolrInputDocument sid; + + public SolrInputDocumentWritable() { + } + + public SolrInputDocumentWritable(SolrInputDocument sid) { + this.sid = sid; + } + + public SolrInputDocument getSolrInputDocument() { + return sid; + } + + @Override + public String toString() { + return sid.toString(); + } + + @Override + public void write(DataOutput out) throws IOException { + JavaBinCodec codec = new JavaBinCodec(); + FastOutputStream daos = FastOutputStream.wrap(DataOutputOutputStream.constructOutputStream(out)); + codec.init(daos); + try { + codec.writeVal(sid); + } finally { + daos.flushBuffer(); + } + } + + @Override + public void readFields(DataInput in) throws IOException { + JavaBinCodec codec = new JavaBinCodec(); + UnbufferedDataInputInputStream dis = new UnbufferedDataInputInputStream(in); + sid = (SolrInputDocument)codec.readVal(dis); + } + +} diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrMapper.java b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrMapper.java new file mode 100644 index 00000000000..2a6d699b541 --- /dev/null +++ b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrMapper.java @@ -0,0 +1,39 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop; + +import java.io.IOException; + +import org.apache.hadoop.fs.Path; +import org.apache.hadoop.io.Text; +import org.apache.hadoop.mapreduce.Mapper; + +public class SolrMapper extends Mapper { + + private Path solrHomeDir; + + @Override + protected void setup(Context context) throws IOException, InterruptedException { + Utils.getLogConfigFile(context.getConfiguration()); + super.setup(context); + solrHomeDir = SolrRecordWriter.findSolrConfig(context.getConfiguration()); + } + + protected Path getSolrHomeDir() { + return solrHomeDir; + } +} diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrOutputFormat.java b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrOutputFormat.java new file mode 100644 index 00000000000..97b2b79404e --- /dev/null +++ b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrOutputFormat.java @@ -0,0 +1,278 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Locale; +import java.util.Set; +import java.util.UUID; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.filecache.DistributedCache; +import org.apache.hadoop.fs.FileSystem; +import org.apache.hadoop.fs.Path; +import org.apache.hadoop.mapreduce.Job; +import org.apache.hadoop.mapreduce.JobContext; +import org.apache.hadoop.mapreduce.RecordWriter; +import org.apache.hadoop.mapreduce.TaskAttemptContext; +import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SolrOutputFormat extends FileOutputFormat { + + private static final Logger LOG = LoggerFactory.getLogger(SolrOutputFormat.class); + + /** + * The parameter used to pass the solr config zip file information. This will + * be the hdfs path to the configuration zip file + */ + public static final String SETUP_OK = "solr.output.format.setup"; + + /** The key used to pass the zip file name through the configuration. */ + public static final String ZIP_NAME = "solr.zip.name"; + + /** + * The base name of the zip file containing the configuration information. + * This file is passed via the distributed cache using a unique name, obtained + * via {@link #getZipName(Configuration jobConf)}. + */ + public static final String ZIP_FILE_BASE_NAME = "solr.zip"; + + /** + * The key used to pass the boolean configuration parameter that instructs for + * regular or zip file output + */ + public static final String OUTPUT_ZIP_FILE = "solr.output.zip.format"; + + static int defaultSolrWriterThreadCount = 0; + + public static final String SOLR_WRITER_THREAD_COUNT = "solr.record.writer.num.threads"; + + static int defaultSolrWriterQueueSize = 1; + + public static final String SOLR_WRITER_QUEUE_SIZE = "solr.record.writer.max.queues.size"; + + static int defaultSolrBatchSize = 20; + + public static final String SOLR_RECORD_WRITER_BATCH_SIZE = "solr.record.writer.batch.size"; + + public static final String SOLR_RECORD_WRITER_MAX_SEGMENTS = "solr.record.writer.maxSegments"; + + public static String getSetupOk() { + return SETUP_OK; + } + + /** Get the number of threads used for index writing */ + public static void setSolrWriterThreadCount(int count, Configuration conf) { + conf.setInt(SOLR_WRITER_THREAD_COUNT, count); + } + + /** Set the number of threads used for index writing */ + public static int getSolrWriterThreadCount(Configuration conf) { + return conf.getInt(SOLR_WRITER_THREAD_COUNT, defaultSolrWriterThreadCount); + } + + /** + * Set the maximum size of the the queue for documents to be written to the + * index. + */ + public static void setSolrWriterQueueSize(int count, Configuration conf) { + conf.setInt(SOLR_WRITER_QUEUE_SIZE, count); + } + + /** Return the maximum size for the number of documents pending index writing. */ + public static int getSolrWriterQueueSize(Configuration conf) { + return conf.getInt(SOLR_WRITER_QUEUE_SIZE, defaultSolrWriterQueueSize); + } + + /** + * Return the file name portion of the configuration zip file, from the + * configuration. + */ + public static String getZipName(Configuration conf) { + return conf.get(ZIP_NAME, ZIP_FILE_BASE_NAME); + } + + /** + * configure the job to output zip files of the output index, or full + * directory trees. Zip files are about 1/5th the size of the raw index, and + * much faster to write, but take more cpu to create. + * + * @param output true if should output zip files + * @param conf to use + */ + public static void setOutputZipFormat(boolean output, Configuration conf) { + conf.setBoolean(OUTPUT_ZIP_FILE, output); + } + + /** + * return true if the output should be a zip file of the index, rather than + * the raw index + * + * @param conf to use + * @return true if output zip files is on + */ + public static boolean isOutputZipFormat(Configuration conf) { + return conf.getBoolean(OUTPUT_ZIP_FILE, false); + } + + public static String getOutputName(JobContext job) { + return FileOutputFormat.getOutputName(job); + } + + @Override + public void checkOutputSpecs(JobContext job) throws IOException { + super.checkOutputSpecs(job); + if (job.getConfiguration().get(SETUP_OK) == null) { + throw new IOException("Solr home cache not set up!"); + } + } + + + @Override + public RecordWriter getRecordWriter(TaskAttemptContext context) throws IOException, InterruptedException { + Utils.getLogConfigFile(context.getConfiguration()); + Path workDir = getDefaultWorkFile(context, ""); + int batchSize = getBatchSize(context.getConfiguration()); + return new SolrRecordWriter(context, workDir, batchSize); + } + + public static void setupSolrHomeCache(File solrHomeDir, Job job) throws IOException{ + File solrHomeZip = createSolrHomeZip(solrHomeDir); + addSolrConfToDistributedCache(job, solrHomeZip); + } + + public static File createSolrHomeZip(File solrHomeDir) throws IOException { + return createSolrHomeZip(solrHomeDir, false); + } + + private static File createSolrHomeZip(File solrHomeDir, boolean safeToModify) throws IOException { + if (solrHomeDir == null || !(solrHomeDir.exists() && solrHomeDir.isDirectory())) { + throw new IOException("Invalid solr home: " + solrHomeDir); + } + File solrHomeZip = File.createTempFile("solr", ".zip"); + createZip(solrHomeDir, solrHomeZip); + return solrHomeZip; + } + + public static void addSolrConfToDistributedCache(Job job, File solrHomeZip) + throws IOException { + // Make a reasonably unique name for the zip file in the distributed cache + // to avoid collisions if multiple jobs are running. + String hdfsZipName = UUID.randomUUID().toString() + '.' + + ZIP_FILE_BASE_NAME; + Configuration jobConf = job.getConfiguration(); + jobConf.set(ZIP_NAME, hdfsZipName); + + Path zipPath = new Path("/tmp", getZipName(jobConf)); + FileSystem fs = FileSystem.get(jobConf); + fs.copyFromLocalFile(new Path(solrHomeZip.toString()), zipPath); + final URI baseZipUrl = fs.getUri().resolve( + zipPath.toString() + '#' + getZipName(jobConf)); + + DistributedCache.addCacheArchive(baseZipUrl, jobConf); + LOG.debug("Set Solr distributed cache: {}", Arrays.asList(job.getCacheArchives())); + LOG.debug("Set zipPath: {}", zipPath); + // Actually send the path for the configuration zip file + jobConf.set(SETUP_OK, zipPath.toString()); + } + + private static void createZip(File dir, File out) throws IOException { + HashSet files = new HashSet(); + // take only conf/ and lib/ + for (String allowedDirectory : SolrRecordWriter + .getAllowedConfigDirectories()) { + File configDir = new File(dir, allowedDirectory); + boolean configDirExists; + /** If the directory does not exist, and is required, bail out */ + if (!(configDirExists = configDir.exists()) + && SolrRecordWriter.isRequiredConfigDirectory(allowedDirectory)) { + throw new IOException(String.format(Locale.ENGLISH, + "required configuration directory %s is not present in %s", + allowedDirectory, dir)); + } + if (!configDirExists) { + continue; + } + listFiles(configDir, files); // Store the files in the existing, allowed + // directory configDir, in the list of files + // to store in the zip file + } + + out.delete(); + int subst = dir.toString().length(); + ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(out)); + byte[] buf = new byte[1024]; + for (File f : files) { + ZipEntry ze = new ZipEntry(f.toString().substring(subst)); + zos.putNextEntry(ze); + InputStream is = new FileInputStream(f); + int cnt; + while ((cnt = is.read(buf)) >= 0) { + zos.write(buf, 0, cnt); + } + is.close(); + zos.flush(); + zos.closeEntry(); + } + + ZipEntry ze = new ZipEntry("solr.xml"); + zos.putNextEntry(ze); + zos.write("".getBytes("UTF-8")); + zos.flush(); + zos.closeEntry(); + zos.close(); + } + + private static void listFiles(File dir, Set files) throws IOException { + File[] list = dir.listFiles(); + + if (list == null && dir.isFile()) { + files.add(dir); + return; + } + + for (File f : list) { + if (f.isFile()) { + files.add(f); + } else { + listFiles(f, files); + } + } + } + + public static int getBatchSize(Configuration jobConf) { + // TODO Auto-generated method stub + return jobConf.getInt(SolrOutputFormat.SOLR_RECORD_WRITER_BATCH_SIZE, + defaultSolrBatchSize); + } + + public static void setBatchSize(int count, Configuration jobConf) { + jobConf.setInt(SOLR_RECORD_WRITER_BATCH_SIZE, count); + } + +} diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrRecordWriter.java b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrRecordWriter.java new file mode 100644 index 00000000000..e589c36313f --- /dev/null +++ b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrRecordWriter.java @@ -0,0 +1,516 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Properties; +import java.util.Set; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.filecache.DistributedCache; +import org.apache.hadoop.fs.FileSystem; +import org.apache.hadoop.fs.Path; +import org.apache.hadoop.mapreduce.RecordWriter; +import org.apache.hadoop.mapreduce.Reducer; +import org.apache.hadoop.mapreduce.TaskAttemptContext; +import org.apache.hadoop.mapreduce.TaskID; +import org.apache.solr.hadoop.SolrOutputFormat; +import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer; +import org.apache.solr.common.SolrInputDocument; +import org.apache.solr.core.CoreContainer; +import org.apache.solr.core.CoreDescriptor; +import org.apache.solr.core.SolrCore; +import org.apache.solr.core.SolrResourceLoader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class SolrRecordWriter extends RecordWriter { + + private static final Logger LOG = LoggerFactory.getLogger(SolrRecordWriter.class); + + public final static List allowedConfigDirectories = new ArrayList( + Arrays.asList(new String[] { "conf", "lib", "solr.xml" })); + + public final static Set requiredConfigDirectories = new HashSet(); + + static { + requiredConfigDirectories.add("conf"); + } + + /** + * Return the list of directories names that may be included in the + * configuration data passed to the tasks. + * + * @return an UnmodifiableList of directory names + */ + public static List getAllowedConfigDirectories() { + return Collections.unmodifiableList(allowedConfigDirectories); + } + + /** + * check if the passed in directory is required to be present in the + * configuration data set. + * + * @param directory The directory to check + * @return true if the directory is required. + */ + public static boolean isRequiredConfigDirectory(final String directory) { + return requiredConfigDirectories.contains(directory); + } + + /** The path that the final index will be written to */ + + /** The location in a local temporary directory that the index is built in. */ + +// /** +// * If true, create a zip file of the completed index in the final storage +// * location A .zip will be appended to the final output name if it is not +// * already present. +// */ +// private boolean outputZipFile = false; + + private final HeartBeater heartBeater; + private final BatchWriter batchWriter; + private final List batch; + private final int batchSize; + private long numDocsWritten = 0; + private long nextLogTime = System.currentTimeMillis(); + + private static HashMap.Context> contextMap = new HashMap.Context>(); + + public SolrRecordWriter(TaskAttemptContext context, Path outputShardDir, int batchSize) { + this.batchSize = batchSize; + this.batch = new ArrayList(batchSize); + Configuration conf = context.getConfiguration(); + + // setLogLevel("org.apache.solr.core", "WARN"); + // setLogLevel("org.apache.solr.update", "WARN"); + + heartBeater = new HeartBeater(context); + try { + heartBeater.needHeartBeat(); + + Path solrHomeDir = SolrRecordWriter.findSolrConfig(conf); + FileSystem fs = outputShardDir.getFileSystem(conf); + EmbeddedSolrServer solr = createEmbeddedSolrServer(solrHomeDir, fs, outputShardDir); + batchWriter = new BatchWriter(solr, batchSize, + context.getTaskAttemptID().getTaskID(), + SolrOutputFormat.getSolrWriterThreadCount(conf), + SolrOutputFormat.getSolrWriterQueueSize(conf)); + + } catch (Exception e) { + throw new IllegalStateException(String.format(Locale.ENGLISH, + "Failed to initialize record writer for %s, %s", context.getJobName(), conf + .get("mapred.task.id")), e); + } finally { + heartBeater.cancelHeartBeat(); + } + } + + public static EmbeddedSolrServer createEmbeddedSolrServer(Path solrHomeDir, FileSystem fs, Path outputShardDir) + throws IOException { + + if (solrHomeDir == null) { + throw new IOException("Unable to find solr home setting"); + } + LOG.info("Creating embedded Solr server with solrHomeDir: " + solrHomeDir + ", fs: " + fs + ", outputShardDir: " + outputShardDir); + + Properties props = new Properties(); + // FIXME note this is odd (no scheme) given Solr doesn't currently + // support uris (just abs/relative path) + Path solrDataDir = new Path(outputShardDir, "data"); + if (!fs.exists(solrDataDir) && !fs.mkdirs(solrDataDir)) { + throw new IOException("Unable to create " + solrDataDir); + } + + String dataDirStr = solrDataDir.toUri().toString(); + props.setProperty("solr.data.dir", dataDirStr); + props.setProperty("solr.home", solrHomeDir.toString()); + + SolrResourceLoader loader = new SolrResourceLoader(solrHomeDir.toString(), + null, props); + + LOG.info(String + .format(Locale.ENGLISH, + "Constructed instance information solr.home %s (%s), instance dir %s, conf dir %s, writing index to solr.data.dir %s, with permdir %s", + solrHomeDir, solrHomeDir.toUri(), loader.getInstanceDir(), + loader.getConfigDir(), dataDirStr, outputShardDir)); + + CoreContainer container = new CoreContainer(loader); + container.load(); + CoreDescriptor descr = new CoreDescriptor(container, "core1", + ".", props); + + SolrCore core = container.create(descr); + container.register(core, false); + + System.setProperty("solr.hdfs.nrtcachingdirectory", "false"); + System.setProperty("solr.hdfs.blockcache.enabled", "false"); + System.setProperty("solr.autoCommit.maxTime", "-1"); + System.setProperty("solr.autoSoftCommit.maxTime", "-1"); + EmbeddedSolrServer solr = new EmbeddedSolrServer(container, "core1"); + return solr; + } + + public static void incrementCounter(TaskID taskId, String groupName, String counterName, long incr) { + Reducer.Context context = contextMap.get(taskId); + if (context != null) { + context.getCounter(groupName, counterName).increment(incr); + } + } + + public static void incrementCounter(TaskID taskId, Enum counterName, long incr) { + Reducer.Context context = contextMap.get(taskId); + if (context != null) { + context.getCounter(counterName).increment(incr); + } + } + + public static void addReducerContext(Reducer.Context context) { + TaskID taskID = context.getTaskAttemptID().getTaskID(); + contextMap.put(taskID, context); + } + + public static Path findSolrConfig(Configuration conf) throws IOException { + Path solrHome = null; + // FIXME when mrunit supports the new cache apis + //URI[] localArchives = context.getCacheArchives(); + Path[] localArchives = DistributedCache.getLocalCacheArchives(conf); + if (localArchives.length == 0) { + throw new IOException(String.format(Locale.ENGLISH, + "No local cache archives, where is %s:%s", SolrOutputFormat + .getSetupOk(), SolrOutputFormat.getZipName(conf))); + } + for (Path unpackedDir : localArchives) { + // Only logged if debugging + if (LOG.isDebugEnabled()) { + LOG.debug(String.format(Locale.ENGLISH, "Examining unpack directory %s for %s", + unpackedDir, SolrOutputFormat.getZipName(conf))); + + ProcessBuilder lsCmd = new ProcessBuilder(new String[] { "/bin/ls", + "-lR", unpackedDir.toString() }); + lsCmd.redirectErrorStream(); + Process ls = lsCmd.start(); + byte[] buf = new byte[16 * 1024]; + InputStream all = ls.getInputStream(); + try { + int count; + while ((count = all.read(buf)) >= 0) { + System.err.write(buf, 0, count); + } + } catch (IOException ignore) { + } finally { + all.close(); + } + String exitValue; + try { + exitValue = String.valueOf(ls.waitFor()); + } catch (InterruptedException e) { + exitValue = "interrupted"; + } + System.err.format("Exit value of 'ls -lR' is %s%n", exitValue); + } + if (unpackedDir.getName().equals(SolrOutputFormat.getZipName(conf))) { + LOG.info("Using this unpacked directory as solr home: {}", unpackedDir); + solrHome = unpackedDir; + break; + } + } + + return solrHome; + } + + /** + * Write a record. This method accumulates records in to a batch, and when + * {@link #batchSize} items are present flushes it to the indexer. The writes + * can take a substantial amount of time, depending on {@link #batchSize}. If + * there is heavy disk contention the writes may take more than the 600 second + * default timeout. + */ + @Override + public void write(K key, V value) throws IOException { + heartBeater.needHeartBeat(); + try { + try { + SolrInputDocumentWritable sidw = (SolrInputDocumentWritable) value; + batch.add(sidw.getSolrInputDocument()); + if (batch.size() >= batchSize) { + batchWriter.queueBatch(batch); + numDocsWritten += batch.size(); + if (System.currentTimeMillis() >= nextLogTime) { + LOG.info("docsWritten: {}", numDocsWritten); + nextLogTime += 10000; + } + batch.clear(); + } + } catch (SolrServerException e) { + throw new IOException(e); + } + } finally { + heartBeater.cancelHeartBeat(); + } + + } + + @Override + public void close(TaskAttemptContext context) throws IOException, InterruptedException { + if (context != null) { + heartBeater.setProgress(context); + } + try { + heartBeater.needHeartBeat(); + if (batch.size() > 0) { + batchWriter.queueBatch(batch); + numDocsWritten += batch.size(); + batch.clear(); + } + LOG.info("docsWritten: {}", numDocsWritten); + batchWriter.close(context); +// if (outputZipFile) { +// context.setStatus("Writing Zip"); +// packZipFile(); // Written to the perm location +// } else { +// context.setStatus("Copying Index"); +// fs.completeLocalOutput(perm, temp); // copy to dfs +// } + } catch (Exception e) { + if (e instanceof IOException) { + throw (IOException) e; + } + throw new IOException(e); + } finally { + heartBeater.cancelHeartBeat(); + heartBeater.close(); +// File tempFile = new File(temp.toString()); +// if (tempFile.exists()) { +// FileUtils.forceDelete(new File(temp.toString())); +// } + } + + context.setStatus("Done"); + } + +// private void packZipFile() throws IOException { +// FSDataOutputStream out = null; +// ZipOutputStream zos = null; +// int zipCount = 0; +// LOG.info("Packing zip file for " + perm); +// try { +// out = fs.create(perm, false); +// zos = new ZipOutputStream(out); +// +// String name = perm.getName().replaceAll(".zip$", ""); +// LOG.info("adding index directory" + temp); +// zipCount = zipDirectory(conf, zos, name, temp.toString(), temp); +// /** +// for (String configDir : allowedConfigDirectories) { +// if (!isRequiredConfigDirectory(configDir)) { +// continue; +// } +// final Path confPath = new Path(solrHome, configDir); +// LOG.info("adding configdirectory" + confPath); +// +// zipCount += zipDirectory(conf, zos, name, solrHome.toString(), confPath); +// } +// **/ +// } catch (Throwable ohFoo) { +// LOG.error("packZipFile exception", ohFoo); +// if (ohFoo instanceof RuntimeException) { +// throw (RuntimeException) ohFoo; +// } +// if (ohFoo instanceof IOException) { +// throw (IOException) ohFoo; +// } +// throw new IOException(ohFoo); +// +// } finally { +// if (zos != null) { +// if (zipCount == 0) { // If no entries were written, only close out, as +// // the zip will throw an error +// LOG.error("No entries written to zip file " + perm); +// fs.delete(perm, false); +// // out.close(); +// } else { +// LOG.info(String.format("Wrote %d items to %s for %s", zipCount, perm, +// temp)); +// zos.close(); +// } +// } +// } +// } +// +// /** +// * Write a file to a zip output stream, removing leading path name components +// * from the actual file name when creating the zip file entry. +// * +// * The entry placed in the zip file is baseName/ +// * relativePath, where relativePath is constructed +// * by removing a leading root from the path for +// * itemToZip. +// * +// * If itemToZip is an empty directory, it is ignored. If +// * itemToZip is a directory, the contents of the directory are +// * added recursively. +// * +// * @param zos The zip output stream +// * @param baseName The base name to use for the file name entry in the zip +// * file +// * @param root The path to remove from itemToZip to make a +// * relative path name +// * @param itemToZip The path to the file to be added to the zip file +// * @return the number of entries added +// * @throws IOException +// */ +// static public int zipDirectory(final Configuration conf, +// final ZipOutputStream zos, final String baseName, final String root, +// final Path itemToZip) throws IOException { +// LOG +// .info(String +// .format("zipDirectory: %s %s %s", baseName, root, itemToZip)); +// LocalFileSystem localFs = FileSystem.getLocal(conf); +// int count = 0; +// +// final FileStatus itemStatus = localFs.getFileStatus(itemToZip); +// if (itemStatus.isDirectory()) { +// final FileStatus[] statai = localFs.listStatus(itemToZip); +// +// // Add a directory entry to the zip file +// final String zipDirName = relativePathForZipEntry(itemToZip.toUri() +// .getPath(), baseName, root); +// final ZipEntry dirZipEntry = new ZipEntry(zipDirName +// + Path.SEPARATOR_CHAR); +// LOG.info(String.format("Adding directory %s to zip", zipDirName)); +// zos.putNextEntry(dirZipEntry); +// zos.closeEntry(); +// count++; +// +// if (statai == null || statai.length == 0) { +// LOG.info(String.format("Skipping empty directory %s", itemToZip)); +// return count; +// } +// for (FileStatus status : statai) { +// count += zipDirectory(conf, zos, baseName, root, status.getPath()); +// } +// LOG.info(String.format("Wrote %d entries for directory %s", count, +// itemToZip)); +// return count; +// } +// +// final String inZipPath = relativePathForZipEntry(itemToZip.toUri() +// .getPath(), baseName, root); +// +// if (inZipPath.length() == 0) { +// LOG.warn(String.format("Skipping empty zip file path for %s (%s %s)", +// itemToZip, root, baseName)); +// return 0; +// } +// +// // Take empty files in case the place holder is needed +// FSDataInputStream in = null; +// try { +// in = localFs.open(itemToZip); +// final ZipEntry ze = new ZipEntry(inZipPath); +// ze.setTime(itemStatus.getModificationTime()); +// // Comments confuse looking at the zip file +// // ze.setComment(itemToZip.toString()); +// zos.putNextEntry(ze); +// +// IOUtils.copyBytes(in, zos, conf, false); +// zos.closeEntry(); +// LOG.info(String.format("Wrote %d entries for file %s", count, itemToZip)); +// return 1; +// } finally { +// in.close(); +// } +// +// } +// +// static String relativePathForZipEntry(final String rawPath, +// final String baseName, final String root) { +// String relativePath = rawPath.replaceFirst(Pattern.quote(root.toString()), +// ""); +// LOG.info(String.format("RawPath %s, baseName %s, root %s, first %s", +// rawPath, baseName, root, relativePath)); +// +// if (relativePath.startsWith(Path.SEPARATOR)) { +// relativePath = relativePath.substring(1); +// } +// LOG.info(String.format( +// "RawPath %s, baseName %s, root %s, post leading slash %s", rawPath, +// baseName, root, relativePath)); +// if (relativePath.isEmpty()) { +// LOG.warn(String.format( +// "No data after root (%s) removal from raw path %s", root, rawPath)); +// return baseName; +// } +// // Construct the path that will be written to the zip file, including +// // removing any leading '/' characters +// String inZipPath = baseName + Path.SEPARATOR_CHAR + relativePath; +// +// LOG.info(String.format("RawPath %s, baseName %s, root %s, inZip 1 %s", +// rawPath, baseName, root, inZipPath)); +// if (inZipPath.startsWith(Path.SEPARATOR)) { +// inZipPath = inZipPath.substring(1); +// } +// LOG.info(String.format("RawPath %s, baseName %s, root %s, inZip 2 %s", +// rawPath, baseName, root, inZipPath)); +// +// return inZipPath; +// +// } +// + /* + static boolean setLogLevel(String packageName, String level) { + Log logger = LogFactory.getLog(packageName); + if (logger == null) { + return false; + } + // look for: org.apache.commons.logging.impl.SLF4JLocationAwareLog + LOG.warn("logger class:"+logger.getClass().getName()); + if (logger instanceof Log4JLogger) { + process(((Log4JLogger) logger).getLogger(), level); + return true; + } + if (logger instanceof Jdk14Logger) { + process(((Jdk14Logger) logger).getLogger(), level); + return true; + } + return false; + } + + public static void process(org.apache.log4j.Logger log, String level) { + if (level != null) { + log.setLevel(org.apache.log4j.Level.toLevel(level)); + } + } + + public static void process(java.util.logging.Logger log, String level) { + if (level != null) { + log.setLevel(java.util.logging.Level.parse(level)); + } + } + */ +} diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrReducer.java b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrReducer.java new file mode 100644 index 00000000000..59f64ee493f --- /dev/null +++ b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrReducer.java @@ -0,0 +1,167 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop; + +import java.io.IOException; +import java.util.Iterator; + +import org.apache.hadoop.io.Text; +import org.apache.hadoop.mapreduce.Reducer; +import org.apache.hadoop.util.ReflectionUtils; +import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.common.SolrInputDocument; +import org.apache.solr.hadoop.dedup.NoChangeUpdateConflictResolver; +import org.apache.solr.hadoop.dedup.RetainMostRecentUpdateConflictResolver; +import org.apache.solr.hadoop.dedup.UpdateConflictResolver; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.cloudera.cdk.morphline.api.ExceptionHandler; +import com.cloudera.cdk.morphline.base.FaultTolerance; + +/** + * This class loads the mapper's SolrInputDocuments into one EmbeddedSolrServer + * per reducer. Each such reducer and Solr server can be seen as a (micro) + * shard. The Solr servers store their data in HDFS. + * + * More specifically, this class consumes a list of <docId, SolrInputDocument> + * pairs, sorted by docId, and sends them to an embedded Solr server to generate + * a Solr index shard from the documents. + */ +public class SolrReducer extends Reducer { + + private UpdateConflictResolver resolver; + private HeartBeater heartBeater; + private ExceptionHandler exceptionHandler; + + public static final String UPDATE_CONFLICT_RESOLVER = SolrReducer.class.getName() + ".updateConflictResolver"; + + private static final Logger LOG = LoggerFactory.getLogger(SolrReducer.class); + + @Override + protected void setup(Context context) throws IOException, InterruptedException { + SolrRecordWriter.addReducerContext(context); + Class resolverClass = context.getConfiguration().getClass( + UPDATE_CONFLICT_RESOLVER, RetainMostRecentUpdateConflictResolver.class, UpdateConflictResolver.class); + + this.resolver = ReflectionUtils.newInstance(resolverClass, context.getConfiguration()); + /* + * Note that ReflectionUtils.newInstance() above also implicitly calls + * resolver.configure(context.getConfiguration()) if the resolver + * implements org.apache.hadoop.conf.Configurable + */ + + this.exceptionHandler = new FaultTolerance( + context.getConfiguration().getBoolean(FaultTolerance.IS_PRODUCTION_MODE, false), + context.getConfiguration().getBoolean(FaultTolerance.IS_IGNORING_RECOVERABLE_EXCEPTIONS, false), + context.getConfiguration().get(FaultTolerance.RECOVERABLE_EXCEPTION_CLASSES, SolrServerException.class.getName())); + + this.heartBeater = new HeartBeater(context); + } + + protected void reduce(Text key, Iterable values, Context context) throws IOException, InterruptedException { + heartBeater.needHeartBeat(); + try { + values = resolve(key, values, context); + super.reduce(key, values, context); + } catch (Exception e) { + LOG.error("Unable to process key " + key, e); + context.getCounter(getClass().getName() + ".errors", e.getClass().getName()).increment(1); + exceptionHandler.handleException(e, null); + } finally { + heartBeater.cancelHeartBeat(); + } + } + + private Iterable resolve( + final Text key, final Iterable values, final Context context) { + + if (resolver instanceof NoChangeUpdateConflictResolver) { + return values; // fast path + } + return new Iterable() { + @Override + public Iterator iterator() { + return new WrapIterator(resolver.orderUpdates(key, new UnwrapIterator(values.iterator()), context)); + } + }; + } + + @Override + protected void cleanup(Context context) throws IOException, InterruptedException { + heartBeater.close(); + super.cleanup(context); + } + + + /////////////////////////////////////////////////////////////////////////////// + // Nested classes: + /////////////////////////////////////////////////////////////////////////////// + private static final class WrapIterator implements Iterator { + + private Iterator parent; + + private WrapIterator(Iterator parent) { + this.parent = parent; + } + + @Override + public boolean hasNext() { + return parent.hasNext(); + } + + @Override + public SolrInputDocumentWritable next() { + return new SolrInputDocumentWritable(parent.next()); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + } + + + /////////////////////////////////////////////////////////////////////////////// + // Nested classes: + /////////////////////////////////////////////////////////////////////////////// + private static final class UnwrapIterator implements Iterator { + + private Iterator parent; + + private UnwrapIterator(Iterator parent) { + this.parent = parent; + } + + @Override + public boolean hasNext() { + return parent.hasNext(); + } + + @Override + public SolrInputDocument next() { + return parent.next().getSolrInputDocument(); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + } + +} diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/ToolRunnerHelpFormatter.java b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/ToolRunnerHelpFormatter.java new file mode 100644 index 00000000000..d2efa96cdcf --- /dev/null +++ b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/ToolRunnerHelpFormatter.java @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop; + +import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.io.StringReader; +import java.io.StringWriter; +import java.io.UnsupportedEncodingException; + +import net.sourceforge.argparse4j.ArgumentParsers; +import net.sourceforge.argparse4j.helper.ASCIITextWidthCounter; +import net.sourceforge.argparse4j.helper.TextHelper; + +import org.apache.hadoop.util.ToolRunner; + +/** + * Nicely formats the output of + * {@link ToolRunner#printGenericCommandUsage(PrintStream)} with the same look and feel that argparse4j uses for help text. + */ +class ToolRunnerHelpFormatter { + + public static String getGenericCommandUsage() { + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + String msg; + try { + ToolRunner.printGenericCommandUsage(new PrintStream(bout, true, "UTF-8")); + msg = new String(bout.toByteArray(), "UTF-8"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); // unreachable + } + + BufferedReader reader = new BufferedReader(new StringReader(msg)); + StringBuilder result = new StringBuilder(); + while (true) { + String line; + try { + line = reader.readLine(); + } catch (IOException e) { + throw new RuntimeException(e); // unreachable + } + + if (line == null) { + return result.toString(); // EOS + } + + if (!line.startsWith("-")) { + result.append(line + "\n"); + } else { + line = line.trim(); + int i = line.indexOf(" "); + if (i < 0) { + i = line.indexOf('\t'); + } + if (i < 0) { + result.append(line + "\n"); + } else { + String title = line.substring(0, i).trim(); + if (title.length() >= 3 && Character.isLetterOrDigit(title.charAt(1)) && Character.isLetterOrDigit(title.charAt(2))) { + title = "-" + title; // prefer "--libjars" long arg style over "-libjars" style but retain "-D foo" short arg style + } + String help = line.substring(i, line.length()).trim(); + StringWriter strWriter = new StringWriter(); + PrintWriter writer = new PrintWriter(strWriter, true); + TextHelper.printHelp(writer, title, help, new ASCIITextWidthCounter(), ArgumentParsers.getFormatWidth()); + result.append(strWriter.toString()); + } + } + } + } +} + diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/TreeMergeMapper.java b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/TreeMergeMapper.java new file mode 100644 index 00000000000..5e2fe86a6fe --- /dev/null +++ b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/TreeMergeMapper.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop; + +import java.io.IOException; + +import org.apache.hadoop.io.LongWritable; +import org.apache.hadoop.io.NullWritable; +import org.apache.hadoop.io.Text; +import org.apache.hadoop.mapreduce.Mapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * For the meat see {@link TreeMergeOutputFormat}. + */ +public class TreeMergeMapper extends Mapper { + + private static final Logger LOGGER = LoggerFactory.getLogger(TreeMergeMapper.class); + + public static final String MAX_SEGMENTS_ON_TREE_MERGE = "maxSegmentsOnTreeMerge"; + + @Override + protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { + LOGGER.trace("map key: {}, value: {}", key, value); + context.write(value, NullWritable.get()); + } + +} \ No newline at end of file diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/TreeMergeOutputFormat.java b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/TreeMergeOutputFormat.java new file mode 100644 index 00000000000..26de0aaa42c --- /dev/null +++ b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/TreeMergeOutputFormat.java @@ -0,0 +1,167 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.apache.hadoop.fs.Path; +import org.apache.hadoop.io.NullWritable; +import org.apache.hadoop.io.Text; +import org.apache.hadoop.mapreduce.RecordWriter; +import org.apache.hadoop.mapreduce.TaskAttemptContext; +import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; +import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.index.IndexWriterConfig; +import org.apache.lucene.index.IndexWriterConfig.OpenMode; +import org.apache.lucene.index.LogMergePolicy; +import org.apache.lucene.index.MergePolicy; +import org.apache.lucene.index.TieredMergePolicy; +import org.apache.lucene.misc.IndexMergeTool; +import org.apache.lucene.store.Directory; +import org.apache.lucene.util.Version; +import org.apache.solr.store.hdfs.HdfsDirectory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * See {@link IndexMergeTool}. + */ +public class TreeMergeOutputFormat extends FileOutputFormat { + + @Override + public RecordWriter getRecordWriter(TaskAttemptContext context) throws IOException { + Utils.getLogConfigFile(context.getConfiguration()); + Path workDir = getDefaultWorkFile(context, ""); + return new TreeMergeRecordWriter(context, workDir); + } + + + /////////////////////////////////////////////////////////////////////////////// + // Nested classes: + /////////////////////////////////////////////////////////////////////////////// + private static final class TreeMergeRecordWriter extends RecordWriter { + + private final Path workDir; + private final List shards = new ArrayList(); + private final HeartBeater heartBeater; + private final TaskAttemptContext context; + + private static final Logger LOG = LoggerFactory.getLogger(TreeMergeRecordWriter.class); + + public TreeMergeRecordWriter(TaskAttemptContext context, Path workDir) { + this.workDir = new Path(workDir, "data/index"); + this.heartBeater = new HeartBeater(context); + this.context = context; + } + + @Override + public void write(Text key, NullWritable value) { + LOG.info("map key: {}", key); + heartBeater.needHeartBeat(); + try { + Path path = new Path(key.toString()); + shards.add(path); + } finally { + heartBeater.cancelHeartBeat(); + } + } + + @Override + public void close(TaskAttemptContext context) throws IOException { + LOG.debug("Merging into dstDir: " + workDir + ", srcDirs: {}", shards); + heartBeater.needHeartBeat(); + try { + Directory mergedIndex = new HdfsDirectory(workDir, context.getConfiguration()); + + IndexWriterConfig writerConfig = new IndexWriterConfig(Version.LUCENE_CURRENT, null) + .setOpenMode(OpenMode.CREATE) + //.setMergePolicy(mergePolicy) // TODO: grab tuned MergePolicy from solrconfig.xml? + //.setMergeScheduler(...) // TODO: grab tuned MergeScheduler from solrconfig.xml? + ; + + if (LOG.isDebugEnabled()) { + writerConfig.setInfoStream(System.out); + } +// writerConfig.setRAMBufferSizeMB(100); // improve performance +// writerConfig.setMaxThreadStates(1); + + // disable compound file to improve performance + // also see http://lucene.472066.n3.nabble.com/Questions-on-compound-file-format-td489105.html + // also see defaults in SolrIndexConfig + MergePolicy mergePolicy = writerConfig.getMergePolicy(); + LOG.debug("mergePolicy was: {}", mergePolicy); + if (mergePolicy instanceof TieredMergePolicy) { + ((TieredMergePolicy) mergePolicy).setNoCFSRatio(0.0); +// ((TieredMergePolicy) mergePolicy).setMaxMergeAtOnceExplicit(10000); +// ((TieredMergePolicy) mergePolicy).setMaxMergeAtOnce(10000); +// ((TieredMergePolicy) mergePolicy).setSegmentsPerTier(10000); + } else if (mergePolicy instanceof LogMergePolicy) { + ((LogMergePolicy) mergePolicy).setNoCFSRatio(0.0); + } + LOG.info("Using mergePolicy: {}", mergePolicy); + + IndexWriter writer = new IndexWriter(mergedIndex, writerConfig); + + Directory[] indexes = new Directory[shards.size()]; + for (int i = 0; i < shards.size(); i++) { + indexes[i] = new HdfsDirectory(shards.get(i), context.getConfiguration()); + } + + context.setStatus("Logically merging " + shards.size() + " shards into one shard"); + LOG.info("Logically merging " + shards.size() + " shards into one shard: " + workDir); + long start = System.currentTimeMillis(); + + writer.addIndexes(indexes); + // TODO: avoid intermediate copying of files into dst directory; rename the files into the dir instead (cp -> rename) + // This can improve performance and turns this phase into a true "logical" merge, completing in constant time. + // See https://issues.apache.org/jira/browse/LUCENE-4746 + + if (LOG.isDebugEnabled()) { + context.getCounter(SolrCounters.class.getName(), SolrCounters.LOGICAL_TREE_MERGE_TIME.toString()).increment(System.currentTimeMillis() - start); + } + float secs = (System.currentTimeMillis() - start) / 1000.0f; + LOG.info("Logical merge took {} secs", secs); + int maxSegments = context.getConfiguration().getInt(TreeMergeMapper.MAX_SEGMENTS_ON_TREE_MERGE, Integer.MAX_VALUE); + context.setStatus("Optimizing Solr: forcing mtree merge down to " + maxSegments + " segments"); + LOG.info("Optimizing Solr: forcing tree merge down to {} segments", maxSegments); + start = System.currentTimeMillis(); + if (maxSegments < Integer.MAX_VALUE) { + writer.forceMerge(maxSegments); + // TODO: consider perf enhancement for no-deletes merges: bulk-copy the postings data + // see http://lucene.472066.n3.nabble.com/Experience-with-large-merge-factors-tp1637832p1647046.html + } + if (LOG.isDebugEnabled()) { + context.getCounter(SolrCounters.class.getName(), SolrCounters.PHYSICAL_TREE_MERGE_TIME.toString()).increment(System.currentTimeMillis() - start); + } + secs = (System.currentTimeMillis() - start) / 1000.0f; + LOG.info("Optimizing Solr: done forcing tree merge down to {} segments in {} secs", maxSegments, secs); + + start = System.currentTimeMillis(); + LOG.info("Optimizing Solr: Closing index writer"); + writer.close(); + secs = (System.currentTimeMillis() - start) / 1000.0f; + LOG.info("Optimizing Solr: Done closing index writer in {} secs", secs); + context.setStatus("Done"); + } finally { + heartBeater.cancelHeartBeat(); + heartBeater.close(); + } + } + } +} diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/UnbufferedDataInputInputStream.java b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/UnbufferedDataInputInputStream.java new file mode 100644 index 00000000000..1ad141a4264 --- /dev/null +++ b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/UnbufferedDataInputInputStream.java @@ -0,0 +1,114 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.hadoop; + +import java.io.BufferedReader; +import java.io.DataInput; +import java.io.DataInputStream; +import java.io.IOException; +import java.io.InputStreamReader; + +public class UnbufferedDataInputInputStream extends org.apache.solr.common.util.DataInputInputStream { + private final DataInputStream in; + + public UnbufferedDataInputInputStream(DataInput in) { + this.in = new DataInputStream(DataInputInputStream.constructInputStream(in)); + } + + @Override + public void readFully(byte[] b) throws IOException { + in.readFully(b); + } + + @Override + public void readFully(byte[] b, int off, int len) throws IOException { + in.readFully(b, off, len); + } + + @Override + public int skipBytes(int n) throws IOException { + return in.skipBytes(n); + } + + @Override + public boolean readBoolean() throws IOException { + return in.readBoolean(); + } + + @Override + public byte readByte() throws IOException { + return in.readByte(); + } + + @Override + public int readUnsignedByte() throws IOException { + return in.readUnsignedByte(); + } + + @Override + public short readShort() throws IOException { + return in.readShort(); + } + + @Override + public int readUnsignedShort() throws IOException { + return in.readUnsignedShort(); + } + + @Override + public char readChar() throws IOException { + return in.readChar(); + } + + @Override + public int readInt() throws IOException { + return in.readInt(); + } + + @Override + public long readLong() throws IOException { + return in.readLong(); + } + + @Override + public float readFloat() throws IOException { + return in.readFloat(); + } + + @Override + public double readDouble() throws IOException { + return in.readDouble(); + } + + @Override + public String readLine() throws IOException { + BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8")); + return reader.readLine(); + } + + @Override + public String readUTF() throws IOException { + return in.readUTF(); + } + + @Override + public int read() throws IOException { + return in.read(); + } + +} diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/Utils.java b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/Utils.java new file mode 100644 index 00000000000..c20d5784c0d --- /dev/null +++ b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/Utils.java @@ -0,0 +1,53 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop; + +import java.io.File; + +import org.apache.hadoop.conf.Configuration; +import org.apache.log4j.PropertyConfigurator; + +import com.google.common.annotations.Beta; + + +@Beta +public final class Utils { + + private static final String LOG_CONFIG_FILE = "hadoop.log4j.configuration"; + + public static void setLogConfigFile(File file, Configuration conf) { + conf.set(LOG_CONFIG_FILE, file.getName()); + } + + public static void getLogConfigFile(Configuration conf) { + String log4jPropertiesFile = conf.get(LOG_CONFIG_FILE); + if (log4jPropertiesFile != null) { + PropertyConfigurator.configure(log4jPropertiesFile); + } + } + + public static String getShortClassName(Class clazz) { + return getShortClassName(clazz.getName()); + } + + public static String getShortClassName(String className) { + int i = className.lastIndexOf('.'); // regular class + int j = className.lastIndexOf('$'); // inner class + return className.substring(1 + Math.max(i, j)); + } + +} diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/ZooKeeperInspector.java b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/ZooKeeperInspector.java new file mode 100644 index 00000000000..ed916a33c93 --- /dev/null +++ b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/ZooKeeperInspector.java @@ -0,0 +1,198 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.hadoop; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import org.apache.commons.io.FileUtils; +import org.apache.solr.cloud.ZkController; +import org.apache.solr.common.SolrException; +import org.apache.solr.common.cloud.Aliases; +import org.apache.solr.common.cloud.ClusterState; +import org.apache.solr.common.cloud.DocCollection; +import org.apache.solr.common.cloud.Replica; +import org.apache.solr.common.cloud.Slice; +import org.apache.solr.common.cloud.SolrZkClient; +import org.apache.solr.common.cloud.ZkCoreNodeProps; +import org.apache.solr.common.cloud.ZkNodeProps; +import org.apache.solr.common.cloud.ZkStateReader; +import org.apache.solr.common.util.StrUtils; +import org.apache.zookeeper.KeeperException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.io.Files; + +/** + * Extracts SolrCloud information from ZooKeeper. + */ +final class ZooKeeperInspector { + + private static final Logger LOG = LoggerFactory.getLogger(ZooKeeperInspector.class); + + public List> extractShardUrls(String zkHost, String collection) { + + DocCollection docCollection = extractDocCollection(zkHost, collection); + List slices = getSortedSlices(docCollection.getSlices()); + List> solrUrls = new ArrayList>(slices.size()); + for (Slice slice : slices) { + if (slice.getLeader() == null) { + throw new IllegalArgumentException("Cannot find SolrCloud slice leader. " + + "It looks like not all of your shards are registered in ZooKeeper yet"); + } + Collection replicas = slice.getReplicas(); + List urls = new ArrayList(replicas.size()); + for (Replica replica : replicas) { + ZkCoreNodeProps props = new ZkCoreNodeProps(replica); + urls.add(props.getCoreUrl()); + } + solrUrls.add(urls); + } + return solrUrls; + } + + public DocCollection extractDocCollection(String zkHost, String collection) { + if (collection == null) { + throw new IllegalArgumentException("collection must not be null"); + } + SolrZkClient zkClient = getZkClient(zkHost); + + try { + ZkStateReader zkStateReader = new ZkStateReader(zkClient); + try { + // first check for alias + collection = checkForAlias(zkClient, collection); + zkStateReader.createClusterStateWatchersAndUpdate(); + } catch (Exception e) { + throw new IllegalArgumentException("Cannot find expected information for SolrCloud in ZooKeeper: " + zkHost, e); + } + + try { + return zkStateReader.getClusterState().getCollection(collection); + } catch (SolrException e) { + throw new IllegalArgumentException("Cannot find collection '" + collection + "' in ZooKeeper: " + zkHost, e); + } + } finally { + zkClient.close(); + } + } + + public SolrZkClient getZkClient(String zkHost) { + if (zkHost == null) { + throw new IllegalArgumentException("zkHost must not be null"); + } + + SolrZkClient zkClient; + try { + zkClient = new SolrZkClient(zkHost, 30000); + } catch (Exception e) { + throw new IllegalArgumentException("Cannot connect to ZooKeeper: " + zkHost, e); + } + return zkClient; + } + + public List getSortedSlices(Collection slices) { + List sorted = new ArrayList(slices); + Collections.sort(sorted, new Comparator() { + @Override + public int compare(Slice slice1, Slice slice2) { + return slice1.getName().compareTo(slice2.getName()); + } + }); + return sorted; + } + + /** + * Returns config value given collection name + * Borrowed heavily from Solr's ZKController. + */ + public String readConfigName(SolrZkClient zkClient, String collection) + throws KeeperException, InterruptedException { + if (collection == null) { + throw new IllegalArgumentException("collection must not be null"); + } + String configName = null; + + // first check for alias + collection = checkForAlias(zkClient, collection); + + String path = ZkStateReader.COLLECTIONS_ZKNODE + "/" + collection; + if (LOG.isInfoEnabled()) { + LOG.info("Load collection config from:" + path); + } + byte[] data = zkClient.getData(path, null, null, true); + + if(data != null) { + ZkNodeProps props = ZkNodeProps.load(data); + configName = props.getStr(ZkController.CONFIGNAME_PROP); + } + + if (configName != null && !zkClient.exists(ZkController.CONFIGS_ZKNODE + "/" + configName, true)) { + LOG.error("Specified config does not exist in ZooKeeper:" + configName); + throw new IllegalArgumentException("Specified config does not exist in ZooKeeper:" + + configName); + } + + return configName; + } + + private String checkForAlias(SolrZkClient zkClient, String collection) + throws KeeperException, InterruptedException { + byte[] aliasData = zkClient.getData(ZkStateReader.ALIASES, null, null, true); + Aliases aliases = ClusterState.load(aliasData); + String alias = aliases.getCollectionAlias(collection); + if (alias != null) { + List aliasList = StrUtils.splitSmart(alias, ",", true); + if (aliasList.size() > 1) { + throw new IllegalArgumentException("collection cannot be an alias that maps to multiple collections"); + } + collection = aliasList.get(0); + } + return collection; + } + + /** + * Download and return the config directory from ZK + */ + public File downloadConfigDir(SolrZkClient zkClient, String configName) + throws IOException, InterruptedException, KeeperException { + File dir = Files.createTempDir(); + dir.deleteOnExit(); + ZkController.downloadConfigDir(zkClient, configName, dir); + File confDir = new File(dir, "conf"); + if (!confDir.isDirectory()) { + // create a temporary directory with "conf" subdir and mv the config in there. This is + // necessary because of CDH-11188; solrctl does not generate nor accept directories with e.g. + // conf/solrconfig.xml which is necessary for proper solr operation. This should work + // even if solrctl changes. + confDir = new File(Files.createTempDir().getAbsolutePath(), "conf"); + confDir.getParentFile().deleteOnExit(); + Files.move(dir, confDir); + dir = confDir.getParentFile(); + } + FileUtils.writeStringToFile(new File(dir, "solr.xml"), "", "UTF-8"); + return dir; + } + +} diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/NoChangeUpdateConflictResolver.java b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/NoChangeUpdateConflictResolver.java new file mode 100644 index 00000000000..0eae9405717 --- /dev/null +++ b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/NoChangeUpdateConflictResolver.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop.dedup; + +import java.util.Iterator; + +import org.apache.hadoop.io.Text; +import org.apache.hadoop.mapreduce.Reducer.Context; +import org.apache.solr.common.SolrInputDocument; + +/** + * UpdateConflictResolver implementation that returns the solr documents in the + * same order as they are received on input, i.e. without change in order. + */ +public final class NoChangeUpdateConflictResolver implements UpdateConflictResolver { + + @Override + public Iterator orderUpdates(Text key, Iterator updates, Context ctx) { + return updates; + } + +} diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/RejectingUpdateConflictResolver.java b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/RejectingUpdateConflictResolver.java new file mode 100644 index 00000000000..60efb4c15bb --- /dev/null +++ b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/RejectingUpdateConflictResolver.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop.dedup; + +import java.util.Collections; +import java.util.Iterator; + +import org.apache.hadoop.io.Text; +import org.apache.hadoop.mapreduce.Reducer.Context; +import org.apache.solr.common.SolrInputDocument; + +/** + * UpdateConflictResolver implementation that rejects multiple documents with + * the same key with an exception. + */ +public final class RejectingUpdateConflictResolver implements UpdateConflictResolver { + + @Override + public Iterator orderUpdates(Text key, Iterator updates, Context ctx) { + SolrInputDocument firstUpdate = null; + while (updates.hasNext()) { + if (firstUpdate == null) { + firstUpdate = updates.next(); + assert firstUpdate != null; + } else { + throw new IllegalArgumentException("Update conflict! Documents with the same unique key are forbidden: " + + key); + } + } + assert firstUpdate != null; + return Collections.singletonList(firstUpdate).iterator(); + } + +} diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/RetainMostRecentUpdateConflictResolver.java b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/RetainMostRecentUpdateConflictResolver.java new file mode 100644 index 00000000000..1994c163dea --- /dev/null +++ b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/RetainMostRecentUpdateConflictResolver.java @@ -0,0 +1,113 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop.dedup; + +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; + +import org.apache.hadoop.conf.Configurable; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.io.Text; +import org.apache.hadoop.mapreduce.Reducer.Context; +import org.apache.solr.common.SolrInputDocument; +import org.apache.solr.hadoop.HdfsFileFieldNames; +import org.apache.solr.hadoop.Utils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * UpdateConflictResolver implementation that ignores all but the most recent + * document version, based on a configurable numeric Solr field, which defaults + * to the file_last_modified timestamp. + */ +public class RetainMostRecentUpdateConflictResolver implements UpdateConflictResolver, Configurable { + + private Configuration conf; + private String orderByFieldName = ORDER_BY_FIELD_NAME_DEFAULT; + + public static final String ORDER_BY_FIELD_NAME_KEY = + RetainMostRecentUpdateConflictResolver.class.getName() + ".orderByFieldName"; + + public static final String ORDER_BY_FIELD_NAME_DEFAULT = HdfsFileFieldNames.FILE_LAST_MODIFIED; + + public static final String COUNTER_GROUP = Utils.getShortClassName(RetainMostRecentUpdateConflictResolver.class); + public static final String DUPLICATES_COUNTER_NAME = "Number of documents ignored as duplicates"; + public static final String OUTDATED_COUNTER_NAME = "Number of documents ignored as outdated"; + + private static final Logger LOG = LoggerFactory.getLogger(RetainMostRecentUpdateConflictResolver.class); + + @Override + public void setConf(Configuration conf) { + this.conf = conf; + this.orderByFieldName = conf.get(ORDER_BY_FIELD_NAME_KEY, orderByFieldName); + } + + @Override + public Configuration getConf() { + return conf; + } + + protected String getOrderByFieldName() { + return orderByFieldName; + } + + @Override + public Iterator orderUpdates(Text key, Iterator updates, Context ctx) { + return getMaximum(updates, getOrderByFieldName(), new SolrInputDocumentComparator.TimeStampComparator(), ctx); + } + + /** Returns the most recent document among the colliding updates */ + protected Iterator getMaximum(Iterator updates, String fieldName, + Comparator child, Context context) { + + SolrInputDocumentComparator comp = new SolrInputDocumentComparator(fieldName, child); + SolrInputDocument max = null; + long numDupes = 0; + long numOutdated = 0; + while (updates.hasNext()) { + SolrInputDocument next = updates.next(); + assert next != null; + if (max == null) { + max = next; + } else { + int c = comp.compare(next, max); + if (c == 0) { + LOG.debug("Ignoring document version because it is a duplicate: {}", next); + numDupes++; + } else if (c > 0) { + LOG.debug("Ignoring document version because it is outdated: {}", max); + max = next; + numOutdated++; + } else { + LOG.debug("Ignoring document version because it is outdated: {}", next); + numOutdated++; + } + } + } + + assert max != null; + if (numDupes > 0) { + context.getCounter(COUNTER_GROUP, DUPLICATES_COUNTER_NAME).increment(numDupes); + } + if (numOutdated > 0) { + context.getCounter(COUNTER_GROUP, OUTDATED_COUNTER_NAME).increment(numOutdated); + } + return Collections.singletonList(max).iterator(); + } + +} diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/SolrInputDocumentComparator.java b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/SolrInputDocumentComparator.java new file mode 100644 index 00000000000..e8cfdbb52e4 --- /dev/null +++ b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/SolrInputDocumentComparator.java @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop.dedup; + +import java.util.Comparator; + +import org.apache.solr.common.SolrInputDocument; +import org.apache.solr.common.SolrInputField; + +/** + * Default mechanism of determining which of two Solr documents with the same + * key is the more recent version. + */ +public final class SolrInputDocumentComparator implements Comparator { + + private Comparator child; + private String fieldName; + + SolrInputDocumentComparator(String fieldName, Comparator child) { + this.child = child; + this.fieldName = fieldName; + } + + @Override + public int compare(SolrInputDocument doc1, SolrInputDocument doc2) { + SolrInputField f1 = doc1.getField(fieldName); + SolrInputField f2 = doc2.getField(fieldName); + if (f1 == f2) { + return 0; + } else if (f1 == null) { + return -1; + } else if (f2 == null) { + return 1; + } + + Object v1 = f1.getFirstValue(); + Object v2 = f2.getFirstValue(); + return child.compare(v1, v2); + } + + /////////////////////////////////////////////////////////////////////////////// + // Nested classes: + /////////////////////////////////////////////////////////////////////////////// + public static final class TimeStampComparator implements Comparator { + + @Override + public int compare(Object v1, Object v2) { + if (v1 == v2) { + return 0; + } else if (v1 == null) { + return -1; + } else if (v2 == null) { + return 1; + } + long t1 = getLong(v1); + long t2 = getLong(v2); + return (t1 < t2 ? -1 : (t1==t2 ? 0 : 1)); + } + + private long getLong(Object v) { + if (v instanceof Long) { + return ((Long) v).longValue(); + } else { + return Long.parseLong(v.toString()); + } + } + + } + +} diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/SortingUpdateConflictResolver.java b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/SortingUpdateConflictResolver.java new file mode 100644 index 00000000000..24ea9363801 --- /dev/null +++ b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/SortingUpdateConflictResolver.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop.dedup; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; + +import org.apache.hadoop.conf.Configurable; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.io.Text; +import org.apache.hadoop.mapreduce.Reducer.Context; +import org.apache.solr.common.SolrInputDocument; +import org.apache.solr.hadoop.HdfsFileFieldNames; + +/** + * UpdateConflictResolver implementation that orders colliding updates ascending + * from least recent to most recent (partial) update, based on a configurable + * numeric Solr field, which defaults to the file_last_modified timestamp. + */ +public class SortingUpdateConflictResolver implements UpdateConflictResolver, Configurable { + + private Configuration conf; + private String orderByFieldName = ORDER_BY_FIELD_NAME_DEFAULT; + + public static final String ORDER_BY_FIELD_NAME_KEY = + SortingUpdateConflictResolver.class.getName() + ".orderByFieldName"; + + public static final String ORDER_BY_FIELD_NAME_DEFAULT = HdfsFileFieldNames.FILE_LAST_MODIFIED; + + @Override + public void setConf(Configuration conf) { + this.conf = conf; + this.orderByFieldName = conf.get(ORDER_BY_FIELD_NAME_KEY, orderByFieldName); + } + + @Override + public Configuration getConf() { + return conf; + } + + protected String getOrderByFieldName() { + return orderByFieldName; + } + + @Override + public Iterator orderUpdates(Text key, Iterator updates, Context ctx) { + return sort(updates, getOrderByFieldName(), new SolrInputDocumentComparator.TimeStampComparator()); + } + + protected Iterator sort(Iterator updates, String fieldName, Comparator child) { + // TODO: use an external merge sort in the pathological case where there are a huge amount of collisions + List sortedUpdates = new ArrayList(1); + while (updates.hasNext()) { + sortedUpdates.add(updates.next()); + } + if (sortedUpdates.size() > 1) { // conflicts are rare + Collections.sort(sortedUpdates, new SolrInputDocumentComparator(fieldName, child)); + } + return sortedUpdates.iterator(); + } + +} diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/UpdateConflictResolver.java b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/UpdateConflictResolver.java new file mode 100644 index 00000000000..94e23e134eb --- /dev/null +++ b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/UpdateConflictResolver.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop.dedup; + +import java.util.Iterator; + +import org.apache.hadoop.conf.Configurable; +import org.apache.hadoop.io.Text; +import org.apache.hadoop.mapreduce.Reducer; +import org.apache.hadoop.mapreduce.Reducer.Context; +import org.apache.solr.common.SolrInputDocument; + +/** + * Interface that enables deduplication and ordering of a series of document + * updates for the same unique document key. + * + * For example, a MapReduce batch job might index multiple files in the same job + * where some of the files contain old and new versions of the very same + * document, using the same unique document key. + * + * Typically, implementations of this interface forbid collisions by throwing an + * exception, or ignore all but the most recent document version, or, in the + * general case, order colliding updates ascending from least recent to most + * recent (partial) update. + * + * The caller of this interface (i.e. the Hadoop Reducer) will then apply the + * updates to Solr in the order returned by the orderUpdates() method. + * + * Configuration: If an UpdateConflictResolver implementation also implements + * {@link Configurable} then the Hadoop Reducer will call + * {@link Configurable#setConf(org.apache.hadoop.conf.Configuration)} on + * instance construction and pass the standard Hadoop configuration information. + */ +public interface UpdateConflictResolver { + + /** + * Given a list of all colliding document updates for the same unique document + * key, this method returns zero or more documents in an application specific + * order. + * + * The caller will then apply the updates for this key to Solr in the order + * returned by the orderUpdate() method. + * + * @param uniqueKey + * the document key common to all collidingUpdates mentioned below + * @param collidingUpdates + * all updates in the MapReduce job that have a key equal to + * {@code uniqueKey} mentioned above. The input order is unspecified. + * @param context + * The Context passed from the {@link Reducer} + * implementations. + * @return the order in which the updates shall be applied to Solr + */ + Iterator orderUpdates( + Text uniqueKey, Iterator collidingUpdates, Context context); + +} diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/package.html b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/package.html new file mode 100644 index 00000000000..5543f0262be --- /dev/null +++ b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/package.html @@ -0,0 +1,22 @@ + + + + +Dedupe related code. + + diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/morphline/MorphlineCounters.java b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/morphline/MorphlineCounters.java new file mode 100644 index 00000000000..5ba98ff3968 --- /dev/null +++ b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/morphline/MorphlineCounters.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop.morphline; + +import org.apache.solr.hadoop.Utils; + +public enum MorphlineCounters { + + FILES_READ (getClassName(MorphlineMapper.class) + ": Number of files read"), + + FILE_BYTES_READ (getClassName(MorphlineMapper.class) + ": Number of file bytes read"), + + DOCS_READ (getClassName(MorphlineMapper.class) + ": Number of documents read"), + + PARSER_OUTPUT_BYTES (getClassName(MorphlineMapper.class) + ": Number of document bytes generated by Tika parser"), + + ERRORS (getClassName(MorphlineMapper.class) + ": Number of errors"); + + private final String label; + + private MorphlineCounters(String label) { + this.label = label; + } + + public String toString() { + return label; + } + + private static String getClassName(Class clazz) { + return Utils.getShortClassName(clazz); + } + +} diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/morphline/MorphlineMapRunner.java b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/morphline/MorphlineMapRunner.java new file mode 100644 index 00000000000..606ac05fd2e --- /dev/null +++ b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/morphline/MorphlineMapRunner.java @@ -0,0 +1,266 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop.morphline; + +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.TreeMap; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.FileStatus; +import org.apache.hadoop.mapreduce.Mapper.Context; +import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.hadoop.HdfsFileFieldNames; +import org.apache.solr.hadoop.PathParts; +import org.apache.solr.hadoop.Utils; +import org.apache.solr.morphlines.solr.DocumentLoader; +import org.apache.solr.morphlines.solr.SolrLocator; +import org.apache.solr.morphlines.solr.SolrMorphlineContext; +import org.apache.solr.schema.IndexSchema; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.cloudera.cdk.morphline.api.Command; +import com.cloudera.cdk.morphline.api.MorphlineCompilationException; +import com.cloudera.cdk.morphline.api.MorphlineContext; +import com.cloudera.cdk.morphline.api.Record; +import com.cloudera.cdk.morphline.base.Compiler; +import com.cloudera.cdk.morphline.base.FaultTolerance; +import com.cloudera.cdk.morphline.base.Fields; +import com.cloudera.cdk.morphline.base.Metrics; +import com.cloudera.cdk.morphline.base.Notifications; +import com.codahale.metrics.MetricRegistry; +import com.codahale.metrics.Timer; +import com.google.common.annotations.Beta; +import com.google.common.base.Joiner; +import com.typesafe.config.Config; +import com.typesafe.config.ConfigFactory; + +/** + * Internal helper for {@link MorphlineMapper} and dryRun mode; This API is for *INTERNAL* use only + * and should not be considered public. + */ +@Beta +public final class MorphlineMapRunner { + + private MorphlineContext morphlineContext; + private Command morphline; + private IndexSchema schema; + private Map commandLineMorphlineHeaders; + private boolean disableFileOpen; + private String morphlineFileAndId; + private final Timer elapsedTime; + + public static final String MORPHLINE_FILE_PARAM = "morphlineFile"; + public static final String MORPHLINE_ID_PARAM = "morphlineId"; + + /** + * Morphline variables can be passed from the CLI to the Morphline, e.g.: + * hadoop ... -D morphlineVariable.zkHost=127.0.0.1:2181/solr + */ + public static final String MORPHLINE_VARIABLE_PARAM = "morphlineVariable"; + + /** + * Headers, including MIME types, can also explicitly be passed by force from the CLI to Morphline, e.g: + * hadoop ... -D morphlineField._attachment_mimetype=text/csv + */ + public static final String MORPHLINE_FIELD_PREFIX = "morphlineField."; + + /** + * Flag to disable reading of file contents if indexing just file metadata is sufficient. + * This improves performance and confidentiality. + */ + public static final String DISABLE_FILE_OPEN = "morphlineDisableFileOpen"; + + private static final Logger LOG = LoggerFactory.getLogger(MorphlineMapRunner.class); + + MorphlineContext getMorphlineContext() { + return morphlineContext; + } + + IndexSchema getSchema() { + return schema; + } + + public MorphlineMapRunner(Configuration configuration, DocumentLoader loader, String solrHomeDir) throws IOException { + if (LOG.isTraceEnabled()) { + LOG.trace("CWD is {}", new File(".").getCanonicalPath()); + TreeMap map = new TreeMap(); + for (Map.Entry entry : configuration) { + map.put(entry.getKey(), entry.getValue()); + } + LOG.trace("Configuration:\n{}", Joiner.on("\n").join(map.entrySet())); + } + + FaultTolerance faultTolerance = new FaultTolerance( + configuration.getBoolean(FaultTolerance.IS_PRODUCTION_MODE, false), + configuration.getBoolean(FaultTolerance.IS_IGNORING_RECOVERABLE_EXCEPTIONS, false), + configuration.get(FaultTolerance.RECOVERABLE_EXCEPTION_CLASSES, SolrServerException.class.getName()) + ); + + morphlineContext = new SolrMorphlineContext.Builder() + .setDocumentLoader(loader) + .setExceptionHandler(faultTolerance) + .setMetricRegistry(new MetricRegistry()) + .build(); + + class MySolrLocator extends SolrLocator { // trick to access protected ctor + public MySolrLocator(MorphlineContext ctx) { + super(ctx); + } + } + + SolrLocator locator = new MySolrLocator(morphlineContext); + locator.setSolrHomeDir(solrHomeDir); + schema = locator.getIndexSchema(); + + // rebuild context, now with schema + morphlineContext = new SolrMorphlineContext.Builder() + .setIndexSchema(schema) + .setDocumentLoader(loader) + .setExceptionHandler(faultTolerance) + .setMetricRegistry(morphlineContext.getMetricRegistry()) + .build(); + + String morphlineFile = configuration.get(MORPHLINE_FILE_PARAM); + String morphlineId = configuration.get(MORPHLINE_ID_PARAM); + if (morphlineFile == null || morphlineFile.trim().length() == 0) { + throw new MorphlineCompilationException("Missing parameter: " + MORPHLINE_FILE_PARAM, null); + } + Map morphlineVariables = new HashMap(); + for (Map.Entry entry : configuration) { + String variablePrefix = MORPHLINE_VARIABLE_PARAM + "."; + if (entry.getKey().startsWith(variablePrefix)) { + morphlineVariables.put(entry.getKey().substring(variablePrefix.length()), entry.getValue()); + } + } + Config override = ConfigFactory.parseMap(morphlineVariables); + morphline = new Compiler().compile(new File(morphlineFile), morphlineId, morphlineContext, null, override); + morphlineFileAndId = morphlineFile + "@" + morphlineId; + + disableFileOpen = configuration.getBoolean(DISABLE_FILE_OPEN, false); + LOG.debug("disableFileOpen: {}", disableFileOpen); + + commandLineMorphlineHeaders = new HashMap(); + for (Map.Entry entry : configuration) { + if (entry.getKey().startsWith(MORPHLINE_FIELD_PREFIX)) { + commandLineMorphlineHeaders.put(entry.getKey().substring(MORPHLINE_FIELD_PREFIX.length()), entry.getValue()); + } + } + LOG.debug("Headers, including MIME types, passed by force from the CLI to morphline: {}", commandLineMorphlineHeaders); + + String metricName = MetricRegistry.name(Utils.getShortClassName(getClass()), Metrics.ELAPSED_TIME); + this.elapsedTime = morphlineContext.getMetricRegistry().timer(metricName); + Notifications.notifyBeginTransaction(morphline); + } + + /** + * Extract content from the path specified in the value. Key is useless. + */ + public void map(String value, Configuration configuration, Context context) throws IOException { + LOG.info("Processing file {}", value); + InputStream in = null; + Record record = null; + Timer.Context timerContext = elapsedTime.time(); + try { + PathParts parts = new PathParts(value.toString(), configuration); + record = getRecord(parts); + if (record == null) { + return; // ignore + } + for (Map.Entry entry : commandLineMorphlineHeaders.entrySet()) { + record.replaceValues(entry.getKey(), entry.getValue()); + } + long fileLength = parts.getFileStatus().getLen(); + if (disableFileOpen) { + in = new ByteArrayInputStream(new byte[0]); + } else { + in = new BufferedInputStream(parts.getFileSystem().open(parts.getUploadPath())); + } + record.put(Fields.ATTACHMENT_BODY, in); + Notifications.notifyStartSession(morphline); + if (!morphline.process(record)) { + LOG.warn("Morphline {} failed to process record: {}", morphlineFileAndId, record); + } + if (context != null) { + context.getCounter(MorphlineCounters.class.getName(), MorphlineCounters.FILES_READ.toString()).increment(1); + context.getCounter(MorphlineCounters.class.getName(), MorphlineCounters.FILE_BYTES_READ.toString()).increment(fileLength); + } + } catch (Exception e) { + LOG.error("Unable to process file " + value, e); + if (context != null) { + context.getCounter(getClass().getName() + ".errors", e.getClass().getName()).increment(1); + } + morphlineContext.getExceptionHandler().handleException(e, record); + } finally { + timerContext.stop(); + if (in != null) { + in.close(); + } + } + } + + protected Record getRecord(PathParts parts) { + FileStatus stats; + try { + stats = parts.getFileStatus(); + } catch (IOException e) { + stats = null; + } + if (stats == null) { + LOG.warn("Ignoring file that somehow has become unavailable since the job was submitted: {}", + parts.getUploadURL()); + return null; + } + + Record headers = new Record(); + //headers.put(getSchema().getUniqueKeyField().getName(), parts.getId()); // use HDFS file path as docId if no docId is specified + headers.put(Fields.BASE_ID, parts.getId()); // with sanitizeUniqueKey command, use HDFS file path as docId if no docId is specified + headers.put(Fields.ATTACHMENT_NAME, parts.getName()); // Tika can use the file name in guessing the right MIME type + + // enable indexing and storing of file meta data in Solr + headers.put(HdfsFileFieldNames.FILE_UPLOAD_URL, parts.getUploadURL()); + headers.put(HdfsFileFieldNames.FILE_DOWNLOAD_URL, parts.getDownloadURL()); + headers.put(HdfsFileFieldNames.FILE_SCHEME, parts.getScheme()); + headers.put(HdfsFileFieldNames.FILE_HOST, parts.getHost()); + headers.put(HdfsFileFieldNames.FILE_PORT, String.valueOf(parts.getPort())); + headers.put(HdfsFileFieldNames.FILE_PATH, parts.getURIPath()); + headers.put(HdfsFileFieldNames.FILE_NAME, parts.getName()); + headers.put(HdfsFileFieldNames.FILE_LAST_MODIFIED, String.valueOf(stats.getModificationTime())); // FIXME also add in SpoolDirectorySource + headers.put(HdfsFileFieldNames.FILE_LENGTH, String.valueOf(stats.getLen())); // FIXME also add in SpoolDirectorySource + headers.put(HdfsFileFieldNames.FILE_OWNER, stats.getOwner()); + headers.put(HdfsFileFieldNames.FILE_GROUP, stats.getGroup()); + headers.put(HdfsFileFieldNames.FILE_PERMISSIONS_USER, stats.getPermission().getUserAction().SYMBOL); + headers.put(HdfsFileFieldNames.FILE_PERMISSIONS_GROUP, stats.getPermission().getGroupAction().SYMBOL); + headers.put(HdfsFileFieldNames.FILE_PERMISSIONS_OTHER, stats.getPermission().getOtherAction().SYMBOL); + headers.put(HdfsFileFieldNames.FILE_PERMISSIONS_STICKYBIT, String.valueOf(stats.getPermission().getStickyBit())); + // TODO: consider to add stats.getAccessTime(), stats.getReplication(), stats.isSymlink(), stats.getBlockSize() + + return headers; + } + + public void cleanup() { + Notifications.notifyCommitTransaction(morphline); + Notifications.notifyShutdown(morphline); + } + +} diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/morphline/MorphlineMapper.java b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/morphline/MorphlineMapper.java new file mode 100644 index 00000000000..8ded6041547 --- /dev/null +++ b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/morphline/MorphlineMapper.java @@ -0,0 +1,192 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop.morphline; + +import java.io.IOException; +import java.util.Collection; +import java.util.Map; + +import org.apache.hadoop.io.LongWritable; +import org.apache.hadoop.io.Text; +import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.client.solrj.response.SolrPingResponse; +import org.apache.solr.client.solrj.response.UpdateResponse; +import org.apache.solr.common.SolrInputDocument; +import org.apache.solr.common.SolrInputField; +import org.apache.solr.hadoop.HeartBeater; +import org.apache.solr.hadoop.SolrInputDocumentWritable; +import org.apache.solr.hadoop.SolrMapper; +import org.apache.solr.morphlines.solr.DocumentLoader; +import org.apache.solr.schema.IndexSchema; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.codahale.metrics.Counter; +import com.codahale.metrics.Counting; +import com.codahale.metrics.Histogram; +import com.codahale.metrics.Meter; +import com.codahale.metrics.MetricRegistry; +import com.codahale.metrics.Timer; + +/** + * This class takes the input files, extracts the relevant content, transforms + * it and hands SolrInputDocuments to a set of reducers. + * + * More specifically, it consumes a list of <offset, hdfsFilePath> input pairs. + * For each such pair extracts a set of zero or more SolrInputDocuments and + * sends them to a downstream Reducer. The key for the reducer is the unique id + * of the SolrInputDocument specified in Solr schema.xml. + */ +public class MorphlineMapper extends SolrMapper { + + private Context context; + private MorphlineMapRunner runner; + private HeartBeater heartBeater; + + private static final Logger LOG = LoggerFactory.getLogger(MorphlineMapper.class); + + protected IndexSchema getSchema() { + return runner.getSchema(); + } + + protected Context getContext() { + return context; + } + + @Override + protected void setup(Context context) throws IOException, InterruptedException { + super.setup(context); + this.context = context; + heartBeater = new HeartBeater(context); + this.runner = new MorphlineMapRunner( + context.getConfiguration(), new MyDocumentLoader(), getSolrHomeDir().toString()); + } + + /** + * Extract content from the path specified in the value. Key is useless. + */ + @Override + public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { + heartBeater.needHeartBeat(); + try { + runner.map(value.toString(), context.getConfiguration(), context); + } finally { + heartBeater.cancelHeartBeat(); + } + } + + @Override + protected void cleanup(Context context) throws IOException, InterruptedException { + heartBeater.close(); + runner.cleanup(); + addMetricsToMRCounters(runner.getMorphlineContext().getMetricRegistry(), context); + super.cleanup(context); + } + + private void addMetricsToMRCounters(MetricRegistry metricRegistry, Context context) { + for (Map.Entry entry : metricRegistry.getCounters().entrySet()) { + addCounting(entry.getKey(), entry.getValue(), 1); + } + for (Map.Entry entry : metricRegistry.getHistograms().entrySet()) { + addCounting(entry.getKey(), entry.getValue(), 1); + } + for (Map.Entry entry : metricRegistry.getMeters().entrySet()) { + addCounting(entry.getKey(), entry.getValue(), 1); + } + for (Map.Entry entry : metricRegistry.getTimers().entrySet()) { + long nanosPerMilliSec = 1000 * 1000; + addCounting(entry.getKey(), entry.getValue(), nanosPerMilliSec); + } + } + + private void addCounting(String metricName, Counting value, long scale) { + context.getCounter("morphline", metricName).increment(value.getCount() / scale); + } + + /////////////////////////////////////////////////////////////////////////////// + // Nested classes: + /////////////////////////////////////////////////////////////////////////////// + private final class MyDocumentLoader implements DocumentLoader { + + @Override + public void beginTransaction() { + } + + @Override + public void load(SolrInputDocument doc) throws IOException, SolrServerException { + String uniqueKeyFieldName = getSchema().getUniqueKeyField().getName(); + Object id = doc.getFieldValue(uniqueKeyFieldName); + if (id == null) { + throw new IllegalArgumentException("Missing value for (required) unique document key: " + uniqueKeyFieldName + + " (see Solr schema.xml)"); + } + try { + context.write(new Text(id.toString()), new SolrInputDocumentWritable(doc)); + } catch (InterruptedException e) { + throw new IOException("Interrupted while writing " + doc, e); + } + + if (LOG.isDebugEnabled()) { + long numParserOutputBytes = 0; + for (SolrInputField field : doc.values()) { + numParserOutputBytes += sizeOf(field.getValue()); + } + context.getCounter(MorphlineCounters.class.getName(), MorphlineCounters.PARSER_OUTPUT_BYTES.toString()).increment(numParserOutputBytes); + } + context.getCounter(MorphlineCounters.class.getName(), MorphlineCounters.DOCS_READ.toString()).increment(1); + } + + // just an approximation + private long sizeOf(Object value) { + if (value instanceof CharSequence) { + return ((CharSequence) value).length(); + } else if (value instanceof Integer) { + return 4; + } else if (value instanceof Long) { + return 8; + } else if (value instanceof Collection) { + long size = 0; + for (Object val : (Collection) value) { + size += sizeOf(val); + } + return size; + } else { + return String.valueOf(value).length(); + } + } + + @Override + public void commitTransaction() { + } + + @Override + public UpdateResponse rollbackTransaction() throws SolrServerException, IOException { + return new UpdateResponse(); + } + + @Override + public void shutdown() { + } + + @Override + public SolrPingResponse ping() throws SolrServerException, IOException { + return new SolrPingResponse(); + } + + } + +} diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/morphline/package.html b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/morphline/package.html new file mode 100644 index 00000000000..9597a15d4f5 --- /dev/null +++ b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/morphline/package.html @@ -0,0 +1,22 @@ + + + + +Morphlines related code. + + diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/package.html b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/package.html new file mode 100644 index 00000000000..c90c7a24775 --- /dev/null +++ b/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/package.html @@ -0,0 +1,22 @@ + + + + +{@link org.apache.solr.hadoop.MapReduceIndexerTool} and related code. + + diff --git a/solr/contrib/solr-mr/src/java/overview.html b/solr/contrib/solr-mr/src/java/overview.html new file mode 100644 index 00000000000..c97f378ca2e --- /dev/null +++ b/solr/contrib/solr-mr/src/java/overview.html @@ -0,0 +1,21 @@ + + + +Apache Solr Search Server: Solr MapReduce index building contrib + + diff --git a/solr/contrib/solr-mr/src/test-files/custom-mimetypes.xml b/solr/contrib/solr-mr/src/test-files/custom-mimetypes.xml new file mode 100644 index 00000000000..6891e42d616 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/custom-mimetypes.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/currency.xml b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/currency.xml new file mode 100644 index 00000000000..3a9c58afee8 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/currency.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/elevate.xml b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/elevate.xml new file mode 100644 index 00000000000..25d5cebe4fb --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/elevate.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/contractions_ca.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/contractions_ca.txt new file mode 100644 index 00000000000..307a85f913d --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/contractions_ca.txt @@ -0,0 +1,8 @@ +# Set of Catalan contractions for ElisionFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +d +l +m +n +s +t diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/contractions_fr.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/contractions_fr.txt new file mode 100644 index 00000000000..722db588333 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/contractions_fr.txt @@ -0,0 +1,9 @@ +# Set of French contractions for ElisionFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +l +m +t +qu +n +s +j diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/contractions_ga.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/contractions_ga.txt new file mode 100644 index 00000000000..9ebe7fa349a --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/contractions_ga.txt @@ -0,0 +1,5 @@ +# Set of Irish contractions for ElisionFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +d +m +b diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/contractions_it.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/contractions_it.txt new file mode 100644 index 00000000000..cac04095372 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/contractions_it.txt @@ -0,0 +1,23 @@ +# Set of Italian contractions for ElisionFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +c +l +all +dall +dell +nell +sull +coll +pell +gl +agl +dagl +degl +negl +sugl +un +m +t +s +v +d diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/hyphenations_ga.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/hyphenations_ga.txt new file mode 100644 index 00000000000..4d2642cc5a3 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/hyphenations_ga.txt @@ -0,0 +1,5 @@ +# Set of Irish hyphenations for StopFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +h +n +t diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stemdict_nl.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stemdict_nl.txt new file mode 100644 index 00000000000..441072971d3 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stemdict_nl.txt @@ -0,0 +1,6 @@ +# Set of overrides for the dutch stemmer +# TODO: load this as a resource from the analyzer and sync it in build.xml +fiets fiets +bromfiets bromfiets +ei eier +kind kinder diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stoptags_ja.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stoptags_ja.txt new file mode 100644 index 00000000000..71b750845e3 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stoptags_ja.txt @@ -0,0 +1,420 @@ +# +# This file defines a Japanese stoptag set for JapanesePartOfSpeechStopFilter. +# +# Any token with a part-of-speech tag that exactly matches those defined in this +# file are removed from the token stream. +# +# Set your own stoptags by uncommenting the lines below. Note that comments are +# not allowed on the same line as a stoptag. See LUCENE-3745 for frequency lists, +# etc. that can be useful for building you own stoptag set. +# +# The entire possible tagset is provided below for convenience. +# +##### +# noun: unclassified nouns +#名詞 +# +# noun-common: Common nouns or nouns where the sub-classification is undefined +#名詞-一般 +# +# noun-proper: Proper nouns where the sub-classification is undefined +#名詞-固有名詞 +# +# noun-proper-misc: miscellaneous proper nouns +#名詞-固有名詞-一般 +# +# noun-proper-person: Personal names where the sub-classification is undefined +#名詞-固有名詞-人名 +# +# noun-proper-person-misc: names that cannot be divided into surname and +# given name; foreign names; names where the surname or given name is unknown. +# e.g. お市の方 +#名詞-固有名詞-人名-一般 +# +# noun-proper-person-surname: Mainly Japanese surnames. +# e.g. 山田 +#名詞-固有名詞-人名-姓 +# +# noun-proper-person-given_name: Mainly Japanese given names. +# e.g. 太郎 +#名詞-固有名詞-人名-名 +# +# noun-proper-organization: Names representing organizations. +# e.g. 通産省, NHK +#名詞-固有名詞-組織 +# +# noun-proper-place: Place names where the sub-classification is undefined +#名詞-固有名詞-地域 +# +# noun-proper-place-misc: Place names excluding countries. +# e.g. アジア, バルセロナ, 京都 +#名詞-固有名詞-地域-一般 +# +# noun-proper-place-country: Country names. +# e.g. 日本, オーストラリア +#名詞-固有名詞-地域-国 +# +# noun-pronoun: Pronouns where the sub-classification is undefined +#名詞-代名詞 +# +# noun-pronoun-misc: miscellaneous pronouns: +# e.g. それ, ここ, あいつ, あなた, あちこち, いくつ, どこか, なに, みなさん, みんな, わたくし, われわれ +#名詞-代名詞-一般 +# +# noun-pronoun-contraction: Spoken language contraction made by combining a +# pronoun and the particle 'wa'. +# e.g. ありゃ, こりゃ, こりゃあ, そりゃ, そりゃあ +#名詞-代名詞-縮約 +# +# noun-adverbial: Temporal nouns such as names of days or months that behave +# like adverbs. Nouns that represent amount or ratios and can be used adverbially, +# e.g. 金曜, 一月, 午後, 少量 +#名詞-副詞可能 +# +# noun-verbal: Nouns that take arguments with case and can appear followed by +# 'suru' and related verbs (する, できる, なさる, くださる) +# e.g. インプット, 愛着, 悪化, 悪戦苦闘, 一安心, 下取り +#名詞-サ変接続 +# +# noun-adjective-base: The base form of adjectives, words that appear before な ("na") +# e.g. 健康, 安易, 駄目, だめ +#名詞-形容動詞語幹 +# +# noun-numeric: Arabic numbers, Chinese numerals, and counters like 何 (回), 数. +# e.g. 0, 1, 2, 何, 数, 幾 +#名詞-数 +# +# noun-affix: noun affixes where the sub-classification is undefined +#名詞-非自立 +# +# noun-affix-misc: Of adnominalizers, the case-marker の ("no"), and words that +# attach to the base form of inflectional words, words that cannot be classified +# into any of the other categories below. This category includes indefinite nouns. +# e.g. あかつき, 暁, かい, 甲斐, 気, きらい, 嫌い, くせ, 癖, こと, 事, ごと, 毎, しだい, 次第, +# 順, せい, 所為, ついで, 序で, つもり, 積もり, 点, どころ, の, はず, 筈, はずみ, 弾み, +# 拍子, ふう, ふり, 振り, ほう, 方, 旨, もの, 物, 者, ゆえ, 故, ゆえん, 所以, わけ, 訳, +# わり, 割り, 割, ん-口語/, もん-口語/ +#名詞-非自立-一般 +# +# noun-affix-adverbial: noun affixes that that can behave as adverbs. +# e.g. あいだ, 間, あげく, 挙げ句, あと, 後, 余り, 以外, 以降, 以後, 以上, 以前, 一方, うえ, +# 上, うち, 内, おり, 折り, かぎり, 限り, きり, っきり, 結果, ころ, 頃, さい, 際, 最中, さなか, +# 最中, じたい, 自体, たび, 度, ため, 為, つど, 都度, とおり, 通り, とき, 時, ところ, 所, +# とたん, 途端, なか, 中, のち, 後, ばあい, 場合, 日, ぶん, 分, ほか, 他, まえ, 前, まま, +# 儘, 侭, みぎり, 矢先 +#名詞-非自立-副詞可能 +# +# noun-affix-aux: noun affixes treated as 助動詞 ("auxiliary verb") in school grammars +# with the stem よう(だ) ("you(da)"). +# e.g. よう, やう, 様 (よう) +#名詞-非自立-助動詞語幹 +# +# noun-affix-adjective-base: noun affixes that can connect to the indeclinable +# connection form な (aux "da"). +# e.g. みたい, ふう +#名詞-非自立-形容動詞語幹 +# +# noun-special: special nouns where the sub-classification is undefined. +#名詞-特殊 +# +# noun-special-aux: The そうだ ("souda") stem form that is used for reporting news, is +# treated as 助動詞 ("auxiliary verb") in school grammars, and attach to the base +# form of inflectional words. +# e.g. そう +#名詞-特殊-助動詞語幹 +# +# noun-suffix: noun suffixes where the sub-classification is undefined. +#名詞-接尾 +# +# noun-suffix-misc: Of the nouns or stem forms of other parts of speech that connect +# to ガル or タイ and can combine into compound nouns, words that cannot be classified into +# any of the other categories below. In general, this category is more inclusive than +# 接尾語 ("suffix") and is usually the last element in a compound noun. +# e.g. おき, かた, 方, 甲斐 (がい), がかり, ぎみ, 気味, ぐるみ, (~した) さ, 次第, 済 (ず) み, +# よう, (でき)っこ, 感, 観, 性, 学, 類, 面, 用 +#名詞-接尾-一般 +# +# noun-suffix-person: Suffixes that form nouns and attach to person names more often +# than other nouns. +# e.g. 君, 様, 著 +#名詞-接尾-人名 +# +# noun-suffix-place: Suffixes that form nouns and attach to place names more often +# than other nouns. +# e.g. 町, 市, 県 +#名詞-接尾-地域 +# +# noun-suffix-verbal: Of the suffixes that attach to nouns and form nouns, those that +# can appear before スル ("suru"). +# e.g. 化, 視, 分け, 入り, 落ち, 買い +#名詞-接尾-サ変接続 +# +# noun-suffix-aux: The stem form of そうだ (様態) that is used to indicate conditions, +# is treated as 助動詞 ("auxiliary verb") in school grammars, and attach to the +# conjunctive form of inflectional words. +# e.g. そう +#名詞-接尾-助動詞語幹 +# +# noun-suffix-adjective-base: Suffixes that attach to other nouns or the conjunctive +# form of inflectional words and appear before the copula だ ("da"). +# e.g. 的, げ, がち +#名詞-接尾-形容動詞語幹 +# +# noun-suffix-adverbial: Suffixes that attach to other nouns and can behave as adverbs. +# e.g. 後 (ご), 以後, 以降, 以前, 前後, 中, 末, 上, 時 (じ) +#名詞-接尾-副詞可能 +# +# noun-suffix-classifier: Suffixes that attach to numbers and form nouns. This category +# is more inclusive than 助数詞 ("classifier") and includes common nouns that attach +# to numbers. +# e.g. 個, つ, 本, 冊, パーセント, cm, kg, カ月, か国, 区画, 時間, 時半 +#名詞-接尾-助数詞 +# +# noun-suffix-special: Special suffixes that mainly attach to inflecting words. +# e.g. (楽し) さ, (考え) 方 +#名詞-接尾-特殊 +# +# noun-suffix-conjunctive: Nouns that behave like conjunctions and join two words +# together. +# e.g. (日本) 対 (アメリカ), 対 (アメリカ), (3) 対 (5), (女優) 兼 (主婦) +#名詞-接続詞的 +# +# noun-verbal_aux: Nouns that attach to the conjunctive particle て ("te") and are +# semantically verb-like. +# e.g. ごらん, ご覧, 御覧, 頂戴 +#名詞-動詞非自立的 +# +# noun-quotation: text that cannot be segmented into words, proverbs, Chinese poetry, +# dialects, English, etc. Currently, the only entry for 名詞 引用文字列 ("noun quotation") +# is いわく ("iwaku"). +#名詞-引用文字列 +# +# noun-nai_adjective: Words that appear before the auxiliary verb ない ("nai") and +# behave like an adjective. +# e.g. 申し訳, 仕方, とんでも, 違い +#名詞-ナイ形容詞語幹 +# +##### +# prefix: unclassified prefixes +#接頭詞 +# +# prefix-nominal: Prefixes that attach to nouns (including adjective stem forms) +# excluding numerical expressions. +# e.g. お (水), 某 (氏), 同 (社), 故 (~氏), 高 (品質), お (見事), ご (立派) +#接頭詞-名詞接続 +# +# prefix-verbal: Prefixes that attach to the imperative form of a verb or a verb +# in conjunctive form followed by なる/なさる/くださる. +# e.g. お (読みなさい), お (座り) +#接頭詞-動詞接続 +# +# prefix-adjectival: Prefixes that attach to adjectives. +# e.g. お (寒いですねえ), バカ (でかい) +#接頭詞-形容詞接続 +# +# prefix-numerical: Prefixes that attach to numerical expressions. +# e.g. 約, およそ, 毎時 +#接頭詞-数接続 +# +##### +# verb: unclassified verbs +#動詞 +# +# verb-main: +#動詞-自立 +# +# verb-auxiliary: +#動詞-非自立 +# +# verb-suffix: +#動詞-接尾 +# +##### +# adjective: unclassified adjectives +#形容詞 +# +# adjective-main: +#形容詞-自立 +# +# adjective-auxiliary: +#形容詞-非自立 +# +# adjective-suffix: +#形容詞-接尾 +# +##### +# adverb: unclassified adverbs +#副詞 +# +# adverb-misc: Words that can be segmented into one unit and where adnominal +# modification is not possible. +# e.g. あいかわらず, 多分 +#副詞-一般 +# +# adverb-particle_conjunction: Adverbs that can be followed by の, は, に, +# な, する, だ, etc. +# e.g. こんなに, そんなに, あんなに, なにか, なんでも +#副詞-助詞類接続 +# +##### +# adnominal: Words that only have noun-modifying forms. +# e.g. この, その, あの, どの, いわゆる, なんらかの, 何らかの, いろんな, こういう, そういう, ああいう, +# どういう, こんな, そんな, あんな, どんな, 大きな, 小さな, おかしな, ほんの, たいした, +# 「(, も) さる (ことながら)」, 微々たる, 堂々たる, 単なる, いかなる, 我が」「同じ, 亡き +#連体詞 +# +##### +# conjunction: Conjunctions that can occur independently. +# e.g. が, けれども, そして, じゃあ, それどころか +接続詞 +# +##### +# particle: unclassified particles. +助詞 +# +# particle-case: case particles where the subclassification is undefined. +助詞-格助詞 +# +# particle-case-misc: Case particles. +# e.g. から, が, で, と, に, へ, より, を, の, にて +助詞-格助詞-一般 +# +# particle-case-quote: the "to" that appears after nouns, a person’s speech, +# quotation marks, expressions of decisions from a meeting, reasons, judgements, +# conjectures, etc. +# e.g. ( だ) と (述べた.), ( である) と (して執行猶予...) +助詞-格助詞-引用 +# +# particle-case-compound: Compounds of particles and verbs that mainly behave +# like case particles. +# e.g. という, といった, とかいう, として, とともに, と共に, でもって, にあたって, に当たって, に当って, +# にあたり, に当たり, に当り, に当たる, にあたる, において, に於いて,に於て, における, に於ける, +# にかけ, にかけて, にかんし, に関し, にかんして, に関して, にかんする, に関する, に際し, +# に際して, にしたがい, に従い, に従う, にしたがって, に従って, にたいし, に対し, にたいして, +# に対して, にたいする, に対する, について, につき, につけ, につけて, につれ, につれて, にとって, +# にとり, にまつわる, によって, に依って, に因って, により, に依り, に因り, による, に依る, に因る, +# にわたって, にわたる, をもって, を以って, を通じ, を通じて, を通して, をめぐって, をめぐり, をめぐる, +# って-口語/, ちゅう-関西弁「という」/, (何) ていう (人)-口語/, っていう-口語/, といふ, とかいふ +助詞-格助詞-連語 +# +# particle-conjunctive: +# e.g. から, からには, が, けれど, けれども, けど, し, つつ, て, で, と, ところが, どころか, とも, ども, +# ながら, なり, ので, のに, ば, ものの, や ( した), やいなや, (ころん) じゃ(いけない)-口語/, +# (行っ) ちゃ(いけない)-口語/, (言っ) たって (しかたがない)-口語/, (それがなく)ったって (平気)-口語/ +助詞-接続助詞 +# +# particle-dependency: +# e.g. こそ, さえ, しか, すら, は, も, ぞ +助詞-係助詞 +# +# particle-adverbial: +# e.g. がてら, かも, くらい, 位, ぐらい, しも, (学校) じゃ(これが流行っている)-口語/, +# (それ)じゃあ (よくない)-口語/, ずつ, (私) なぞ, など, (私) なり (に), (先生) なんか (大嫌い)-口語/, +# (私) なんぞ, (先生) なんて (大嫌い)-口語/, のみ, だけ, (私) だって-口語/, だに, +# (彼)ったら-口語/, (お茶) でも (いかが), 等 (とう), (今後) とも, ばかり, ばっか-口語/, ばっかり-口語/, +# ほど, 程, まで, 迄, (誰) も (が)([助詞-格助詞] および [助詞-係助詞] の前に位置する「も」) +助詞-副助詞 +# +# particle-interjective: particles with interjective grammatical roles. +# e.g. (松島) や +助詞-間投助詞 +# +# particle-coordinate: +# e.g. と, たり, だの, だり, とか, なり, や, やら +助詞-並立助詞 +# +# particle-final: +# e.g. かい, かしら, さ, ぜ, (だ)っけ-口語/, (とまってる) で-方言/, な, ナ, なあ-口語/, ぞ, ね, ネ, +# ねぇ-口語/, ねえ-口語/, ねん-方言/, の, のう-口語/, や, よ, ヨ, よぉ-口語/, わ, わい-口語/ +助詞-終助詞 +# +# particle-adverbial/conjunctive/final: The particle "ka" when unknown whether it is +# adverbial, conjunctive, or sentence final. For example: +# (a) 「A か B か」. Ex:「(国内で運用する) か,(海外で運用する) か (.)」 +# (b) Inside an adverb phrase. Ex:「(幸いという) か (, 死者はいなかった.)」 +# 「(祈りが届いたせい) か (, 試験に合格した.)」 +# (c) 「かのように」. Ex:「(何もなかった) か (のように振る舞った.)」 +# e.g. か +助詞-副助詞/並立助詞/終助詞 +# +# particle-adnominalizer: The "no" that attaches to nouns and modifies +# non-inflectional words. +助詞-連体化 +# +# particle-adnominalizer: The "ni" and "to" that appear following nouns and adverbs +# that are giongo, giseigo, or gitaigo. +# e.g. に, と +助詞-副詞化 +# +# particle-special: A particle that does not fit into one of the above classifications. +# This includes particles that are used in Tanka, Haiku, and other poetry. +# e.g. かな, けむ, ( しただろう) に, (あんた) にゃ(わからん), (俺) ん (家) +助詞-特殊 +# +##### +# auxiliary-verb: +助動詞 +# +##### +# interjection: Greetings and other exclamations. +# e.g. おはよう, おはようございます, こんにちは, こんばんは, ありがとう, どうもありがとう, ありがとうございます, +# いただきます, ごちそうさま, さよなら, さようなら, はい, いいえ, ごめん, ごめんなさい +#感動詞 +# +##### +# symbol: unclassified Symbols. +記号 +# +# symbol-misc: A general symbol not in one of the categories below. +# e.g. [○◎@$〒→+] +記号-一般 +# +# symbol-comma: Commas +# e.g. [,、] +記号-読点 +# +# symbol-period: Periods and full stops. +# e.g. [..。] +記号-句点 +# +# symbol-space: Full-width whitespace. +記号-空白 +# +# symbol-open_bracket: +# e.g. [({‘“『【] +記号-括弧開 +# +# symbol-close_bracket: +# e.g. [)}’”』」】] +記号-括弧閉 +# +# symbol-alphabetic: +#記号-アルファベット +# +##### +# other: unclassified other +#その他 +# +# other-interjection: Words that are hard to classify as noun-suffixes or +# sentence-final particles. +# e.g. (だ)ァ +その他-間投 +# +##### +# filler: Aizuchi that occurs during a conversation or sounds inserted as filler. +# e.g. あの, うんと, えと +フィラー +# +##### +# non-verbal: non-verbal sound. +非言語音 +# +##### +# fragment: +#語断片 +# +##### +# unknown: unknown part of speech. +#未知語 +# +##### End of file diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_ar.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_ar.txt new file mode 100644 index 00000000000..046829db6a2 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_ar.txt @@ -0,0 +1,125 @@ +# This file was created by Jacques Savoy and is distributed under the BSD license. +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# Also see http://www.opensource.org/licenses/bsd-license.html +# Cleaned on October 11, 2009 (not normalized, so use before normalization) +# This means that when modifying this list, you might need to add some +# redundant entries, for example containing forms with both أ and ا +من +ومن +منها +منه +في +وفي +فيها +فيه +و +ف +ثم +او +أو +ب +بها +به +ا +أ +اى +اي +أي +أى +لا +ولا +الا +ألا +إلا +لكن +ما +وما +كما +فما +عن +مع +اذا +إذا +ان +أن +إن +انها +أنها +إنها +انه +أنه +إنه +بان +بأن +فان +فأن +وان +وأن +وإن +التى +التي +الذى +الذي +الذين +الى +الي +إلى +إلي +على +عليها +عليه +اما +أما +إما +ايضا +أيضا +كل +وكل +لم +ولم +لن +ولن +هى +هي +هو +وهى +وهي +وهو +فهى +فهي +فهو +انت +أنت +لك +لها +له +هذه +هذا +تلك +ذلك +هناك +كانت +كان +يكون +تكون +وكانت +وكان +غير +بعض +قد +نحو +بين +بينما +منذ +ضمن +حيث +الان +الآن +خلال +بعد +قبل +حتى +عند +عندما +لدى +جميع diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_bg.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_bg.txt new file mode 100644 index 00000000000..1ae4ba2ae38 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_bg.txt @@ -0,0 +1,193 @@ +# This file was created by Jacques Savoy and is distributed under the BSD license. +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# Also see http://www.opensource.org/licenses/bsd-license.html +а +аз +ако +ала +бе +без +беше +би +бил +била +били +било +близо +бъдат +бъде +бяха +в +вас +ваш +ваша +вероятно +вече +взема +ви +вие +винаги +все +всеки +всички +всичко +всяка +във +въпреки +върху +г +ги +главно +го +д +да +дали +до +докато +докога +дори +досега +доста +е +едва +един +ето +за +зад +заедно +заради +засега +затова +защо +защото +и +из +или +им +има +имат +иска +й +каза +как +каква +какво +както +какъв +като +кога +когато +което +които +кой +който +колко +която +къде +където +към +ли +м +ме +между +мен +ми +мнозина +мога +могат +може +моля +момента +му +н +на +над +назад +най +направи +напред +например +нас +не +него +нея +ни +ние +никой +нито +но +някои +някой +няма +обаче +около +освен +особено +от +отгоре +отново +още +пак +по +повече +повечето +под +поне +поради +после +почти +прави +пред +преди +през +при +пък +първо +с +са +само +се +сега +си +скоро +след +сме +според +сред +срещу +сте +съм +със +също +т +тази +така +такива +такъв +там +твой +те +тези +ти +тн +то +това +тогава +този +той +толкова +точно +трябва +тук +тъй +тя +тях +у +харесва +ч +че +често +чрез +ще +щом +я diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_ca.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_ca.txt new file mode 100644 index 00000000000..3da65deafe1 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_ca.txt @@ -0,0 +1,220 @@ +# Catalan stopwords from http://github.com/vcl/cue.language (Apache 2 Licensed) +a +abans +ací +ah +així +això +al +als +aleshores +algun +alguna +algunes +alguns +alhora +allà +allí +allò +altra +altre +altres +amb +ambdós +ambdues +apa +aquell +aquella +aquelles +aquells +aquest +aquesta +aquestes +aquests +aquí +baix +cada +cadascú +cadascuna +cadascunes +cadascuns +com +contra +d'un +d'una +d'unes +d'uns +dalt +de +del +dels +des +després +dins +dintre +donat +doncs +durant +e +eh +el +els +em +en +encara +ens +entre +érem +eren +éreu +es +és +esta +està +estàvem +estaven +estàveu +esteu +et +etc +ets +fins +fora +gairebé +ha +han +has +havia +he +hem +heu +hi +ho +i +igual +iguals +ja +l'hi +la +les +li +li'n +llavors +m'he +ma +mal +malgrat +mateix +mateixa +mateixes +mateixos +me +mentre +més +meu +meus +meva +meves +molt +molta +moltes +molts +mon +mons +n'he +n'hi +ne +ni +no +nogensmenys +només +nosaltres +nostra +nostre +nostres +o +oh +oi +on +pas +pel +pels +per +però +perquè +poc +poca +pocs +poques +potser +propi +qual +quals +quan +quant +que +què +quelcom +qui +quin +quina +quines +quins +s'ha +s'han +sa +semblant +semblants +ses +seu +seus +seva +seva +seves +si +sobre +sobretot +sóc +solament +sols +son +són +sons +sota +sou +t'ha +t'han +t'he +ta +tal +també +tampoc +tan +tant +tanta +tantes +teu +teus +teva +teves +ton +tons +tot +tota +totes +tots +un +una +unes +uns +us +va +vaig +vam +van +vas +veu +vosaltres +vostra +vostre +vostres diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_cz.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_cz.txt new file mode 100644 index 00000000000..53c6097dac7 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_cz.txt @@ -0,0 +1,172 @@ +a +s +k +o +i +u +v +z +dnes +cz +tímto +budeš +budem +byli +jseš +můj +svým +ta +tomto +tohle +tuto +tyto +jej +zda +proč +máte +tato +kam +tohoto +kdo +kteří +mi +nám +tom +tomuto +mít +nic +proto +kterou +byla +toho +protože +asi +ho +naši +napište +re +což +tím +takže +svých +její +svými +jste +aj +tu +tedy +teto +bylo +kde +ke +pravé +ji +nad +nejsou +či +pod +téma +mezi +přes +ty +pak +vám +ani +když +však +neg +jsem +tento +článku +články +aby +jsme +před +pta +jejich +byl +ještě +až +bez +také +pouze +první +vaše +která +nás +nový +tipy +pokud +může +strana +jeho +své +jiné +zprávy +nové +není +vás +jen +podle +zde +už +být +více +bude +již +než +který +by +které +co +nebo +ten +tak +má +při +od +po +jsou +jak +další +ale +si +se +ve +to +jako +za +zpět +ze +do +pro +je +na +atd +atp +jakmile +přičemž +já +on +ona +ono +oni +ony +my +vy +jí +ji +mě +mne +jemu +tomu +těm +těmu +němu +němuž +jehož +jíž +jelikož +jež +jakož +načež diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_da.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_da.txt new file mode 100644 index 00000000000..a3ff5fe122c --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_da.txt @@ -0,0 +1,108 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/danish/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Danish stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | This is a ranked list (commonest to rarest) of stopwords derived from + | a large text sample. + + +og | and +i | in +jeg | I +det | that (dem. pronoun)/it (pers. pronoun) +at | that (in front of a sentence)/to (with infinitive) +en | a/an +den | it (pers. pronoun)/that (dem. pronoun) +til | to/at/for/until/against/by/of/into, more +er | present tense of "to be" +som | who, as +på | on/upon/in/on/at/to/after/of/with/for, on +de | they +med | with/by/in, along +han | he +af | of/by/from/off/for/in/with/on, off +for | at/for/to/from/by/of/ago, in front/before, because +ikke | not +der | who/which, there/those +var | past tense of "to be" +mig | me/myself +sig | oneself/himself/herself/itself/themselves +men | but +et | a/an/one, one (number), someone/somebody/one +har | present tense of "to have" +om | round/about/for/in/a, about/around/down, if +vi | we +min | my +havde | past tense of "to have" +ham | him +hun | she +nu | now +over | over/above/across/by/beyond/past/on/about, over/past +da | then, when/as/since +fra | from/off/since, off, since +du | you +ud | out +sin | his/her/its/one's +dem | them +os | us/ourselves +op | up +man | you/one +hans | his +hvor | where +eller | or +hvad | what +skal | must/shall etc. +selv | myself/youself/herself/ourselves etc., even +her | here +alle | all/everyone/everybody etc. +vil | will (verb) +blev | past tense of "to stay/to remain/to get/to become" +kunne | could +ind | in +når | when +være | present tense of "to be" +dog | however/yet/after all +noget | something +ville | would +jo | you know/you see (adv), yes +deres | their/theirs +efter | after/behind/according to/for/by/from, later/afterwards +ned | down +skulle | should +denne | this +end | than +dette | this +mit | my/mine +også | also +under | under/beneath/below/during, below/underneath +have | have +dig | you +anden | other +hende | her +mine | my +alt | everything +meget | much/very, plenty of +sit | his, her, its, one's +sine | his, her, its, one's +vor | our +mod | against +disse | these +hvis | if +din | your/yours +nogle | some +hos | by/at +blive | be/become +mange | many +ad | by/through +bliver | present tense of "to be/to become" +hendes | her/hers +været | be +thi | for (conj) +jer | you +sådan | such, like this/like that diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_de.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_de.txt new file mode 100644 index 00000000000..f7703841887 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_de.txt @@ -0,0 +1,292 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/german/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A German stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | The number of forms in this list is reduced significantly by passing it + | through the German stemmer. + + +aber | but + +alle | all +allem +allen +aller +alles + +als | than, as +also | so +am | an + dem +an | at + +ander | other +andere +anderem +anderen +anderer +anderes +anderm +andern +anderr +anders + +auch | also +auf | on +aus | out of +bei | by +bin | am +bis | until +bist | art +da | there +damit | with it +dann | then + +der | the +den +des +dem +die +das + +daß | that + +derselbe | the same +derselben +denselben +desselben +demselben +dieselbe +dieselben +dasselbe + +dazu | to that + +dein | thy +deine +deinem +deinen +deiner +deines + +denn | because + +derer | of those +dessen | of him + +dich | thee +dir | to thee +du | thou + +dies | this +diese +diesem +diesen +dieser +dieses + + +doch | (several meanings) +dort | (over) there + + +durch | through + +ein | a +eine +einem +einen +einer +eines + +einig | some +einige +einigem +einigen +einiger +einiges + +einmal | once + +er | he +ihn | him +ihm | to him + +es | it +etwas | something + +euer | your +eure +eurem +euren +eurer +eures + +für | for +gegen | towards +gewesen | p.p. of sein +hab | have +habe | have +haben | have +hat | has +hatte | had +hatten | had +hier | here +hin | there +hinter | behind + +ich | I +mich | me +mir | to me + + +ihr | you, to her +ihre +ihrem +ihren +ihrer +ihres +euch | to you + +im | in + dem +in | in +indem | while +ins | in + das +ist | is + +jede | each, every +jedem +jeden +jeder +jedes + +jene | that +jenem +jenen +jener +jenes + +jetzt | now +kann | can + +kein | no +keine +keinem +keinen +keiner +keines + +können | can +könnte | could +machen | do +man | one + +manche | some, many a +manchem +manchen +mancher +manches + +mein | my +meine +meinem +meinen +meiner +meines + +mit | with +muss | must +musste | had to +nach | to(wards) +nicht | not +nichts | nothing +noch | still, yet +nun | now +nur | only +ob | whether +oder | or +ohne | without +sehr | very + +sein | his +seine +seinem +seinen +seiner +seines + +selbst | self +sich | herself + +sie | they, she +ihnen | to them + +sind | are +so | so + +solche | such +solchem +solchen +solcher +solches + +soll | shall +sollte | should +sondern | but +sonst | else +über | over +um | about, around +und | and + +uns | us +unse +unsem +unsen +unser +unses + +unter | under +viel | much +vom | von + dem +von | from +vor | before +während | while +war | was +waren | were +warst | wast +was | what +weg | away, off +weil | because +weiter | further + +welche | which +welchem +welchen +welcher +welches + +wenn | when +werde | will +werden | will +wie | how +wieder | again +will | want +wir | we +wird | will +wirst | willst +wo | where +wollen | want +wollte | wanted +würde | would +würden | would +zu | to +zum | zu + dem +zur | zu + der +zwar | indeed +zwischen | between + diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_el.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_el.txt new file mode 100644 index 00000000000..232681f5bd6 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_el.txt @@ -0,0 +1,78 @@ +# Lucene Greek Stopwords list +# Note: by default this file is used after GreekLowerCaseFilter, +# so when modifying this file use 'σ' instead of 'ς' +ο +η +το +οι +τα +του +τησ +των +τον +την +και +κι +κ +ειμαι +εισαι +ειναι +ειμαστε +ειστε +στο +στον +στη +στην +μα +αλλα +απο +για +προσ +με +σε +ωσ +παρα +αντι +κατα +μετα +θα +να +δε +δεν +μη +μην +επι +ενω +εαν +αν +τοτε +που +πωσ +ποιοσ +ποια +ποιο +ποιοι +ποιεσ +ποιων +ποιουσ +αυτοσ +αυτη +αυτο +αυτοι +αυτων +αυτουσ +αυτεσ +αυτα +εκεινοσ +εκεινη +εκεινο +εκεινοι +εκεινεσ +εκεινα +εκεινων +εκεινουσ +οπωσ +ομωσ +ισωσ +οσο +οτι diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_en.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_en.txt new file mode 100644 index 00000000000..2c164c0b2a1 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_en.txt @@ -0,0 +1,54 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# a couple of test stopwords to test that the words are really being +# configured from this file: +stopworda +stopwordb + +# Standard english stop words taken from Lucene's StopAnalyzer +a +an +and +are +as +at +be +but +by +for +if +in +into +is +it +no +not +of +on +or +such +that +the +their +then +there +these +they +this +to +was +will +with diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_es.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_es.txt new file mode 100644 index 00000000000..2db14760075 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_es.txt @@ -0,0 +1,354 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/spanish/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Spanish stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + + | The following is a ranked list (commonest to rarest) of stopwords + | deriving from a large sample of text. + + | Extra words have been added at the end. + +de | from, of +la | the, her +que | who, that +el | the +en | in +y | and +a | to +los | the, them +del | de + el +se | himself, from him etc +las | the, them +por | for, by, etc +un | a +para | for +con | with +no | no +una | a +su | his, her +al | a + el + | es from SER +lo | him +como | how +más | more +pero | pero +sus | su plural +le | to him, her +ya | already +o | or + | fue from SER +este | this + | ha from HABER +sí | himself etc +porque | because +esta | this + | son from SER +entre | between + | está from ESTAR +cuando | when +muy | very +sin | without +sobre | on + | ser from SER + | tiene from TENER +también | also +me | me +hasta | until +hay | there is/are +donde | where + | han from HABER +quien | whom, that + | están from ESTAR + | estado from ESTAR +desde | from +todo | all +nos | us +durante | during + | estados from ESTAR +todos | all +uno | a +les | to them +ni | nor +contra | against +otros | other + | fueron from SER +ese | that +eso | that + | había from HABER +ante | before +ellos | they +e | and (variant of y) +esto | this +mí | me +antes | before +algunos | some +qué | what? +unos | a +yo | I +otro | other +otras | other +otra | other +él | he +tanto | so much, many +esa | that +estos | these +mucho | much, many +quienes | who +nada | nothing +muchos | many +cual | who + | sea from SER +poco | few +ella | she +estar | to be + | haber from HABER +estas | these + | estaba from ESTAR + | estamos from ESTAR +algunas | some +algo | something +nosotros | we + + | other forms + +mi | me +mis | mi plural +tú | thou +te | thee +ti | thee +tu | thy +tus | tu plural +ellas | they +nosotras | we +vosotros | you +vosotras | you +os | you +mío | mine +mía | +míos | +mías | +tuyo | thine +tuya | +tuyos | +tuyas | +suyo | his, hers, theirs +suya | +suyos | +suyas | +nuestro | ours +nuestra | +nuestros | +nuestras | +vuestro | yours +vuestra | +vuestros | +vuestras | +esos | those +esas | those + + | forms of estar, to be (not including the infinitive): +estoy +estás +está +estamos +estáis +están +esté +estés +estemos +estéis +estén +estaré +estarás +estará +estaremos +estaréis +estarán +estaría +estarías +estaríamos +estaríais +estarían +estaba +estabas +estábamos +estabais +estaban +estuve +estuviste +estuvo +estuvimos +estuvisteis +estuvieron +estuviera +estuvieras +estuviéramos +estuvierais +estuvieran +estuviese +estuvieses +estuviésemos +estuvieseis +estuviesen +estando +estado +estada +estados +estadas +estad + + | forms of haber, to have (not including the infinitive): +he +has +ha +hemos +habéis +han +haya +hayas +hayamos +hayáis +hayan +habré +habrás +habrá +habremos +habréis +habrán +habría +habrías +habríamos +habríais +habrían +había +habías +habíamos +habíais +habían +hube +hubiste +hubo +hubimos +hubisteis +hubieron +hubiera +hubieras +hubiéramos +hubierais +hubieran +hubiese +hubieses +hubiésemos +hubieseis +hubiesen +habiendo +habido +habida +habidos +habidas + + | forms of ser, to be (not including the infinitive): +soy +eres +es +somos +sois +son +sea +seas +seamos +seáis +sean +seré +serás +será +seremos +seréis +serán +sería +serías +seríamos +seríais +serían +era +eras +éramos +erais +eran +fui +fuiste +fue +fuimos +fuisteis +fueron +fuera +fueras +fuéramos +fuerais +fueran +fuese +fueses +fuésemos +fueseis +fuesen +siendo +sido + | sed also means 'thirst' + + | forms of tener, to have (not including the infinitive): +tengo +tienes +tiene +tenemos +tenéis +tienen +tenga +tengas +tengamos +tengáis +tengan +tendré +tendrás +tendrá +tendremos +tendréis +tendrán +tendría +tendrías +tendríamos +tendríais +tendrían +tenía +tenías +teníamos +teníais +tenían +tuve +tuviste +tuvo +tuvimos +tuvisteis +tuvieron +tuviera +tuvieras +tuviéramos +tuvierais +tuvieran +tuviese +tuvieses +tuviésemos +tuvieseis +tuviesen +teniendo +tenido +tenida +tenidos +tenidas +tened + diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_eu.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_eu.txt new file mode 100644 index 00000000000..25f1db93460 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_eu.txt @@ -0,0 +1,99 @@ +# example set of basque stopwords +al +anitz +arabera +asko +baina +bat +batean +batek +bati +batzuei +batzuek +batzuetan +batzuk +bera +beraiek +berau +berauek +bere +berori +beroriek +beste +bezala +da +dago +dira +ditu +du +dute +edo +egin +ere +eta +eurak +ez +gainera +gu +gutxi +guzti +haiei +haiek +haietan +hainbeste +hala +han +handik +hango +hara +hari +hark +hartan +hau +hauei +hauek +hauetan +hemen +hemendik +hemengo +hi +hona +honek +honela +honetan +honi +hor +hori +horiei +horiek +horietan +horko +horra +horrek +horrela +horretan +horri +hortik +hura +izan +ni +noiz +nola +non +nondik +nongo +nor +nora +ze +zein +zen +zenbait +zenbat +zer +zergatik +ziren +zituen +zu +zuek +zuen +zuten diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_fa.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_fa.txt new file mode 100644 index 00000000000..723641c6da7 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_fa.txt @@ -0,0 +1,313 @@ +# This file was created by Jacques Savoy and is distributed under the BSD license. +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# Also see http://www.opensource.org/licenses/bsd-license.html +# Note: by default this file is used after normalization, so when adding entries +# to this file, use the arabic 'ي' instead of 'ی' +انان +نداشته +سراسر +خياه +ايشان +وي +تاكنون +بيشتري +دوم +پس +ناشي +وگو +يا +داشتند +سپس +هنگام +هرگز +پنج +نشان +امسال +ديگر +گروهي +شدند +چطور +ده +و +دو +نخستين +ولي +چرا +چه +وسط +ه +كدام +قابل +يك +رفت +هفت +همچنين +در +هزار +بله +بلي +شايد +اما +شناسي +گرفته +دهد +داشته +دانست +داشتن +خواهيم +ميليارد +وقتيكه +امد +خواهد +جز +اورده +شده +بلكه +خدمات +شدن +برخي +نبود +بسياري +جلوگيري +حق +كردند +نوعي +بعري +نكرده +نظير +نبايد +بوده +بودن +داد +اورد +هست +جايي +شود +دنبال +داده +بايد +سابق +هيچ +همان +انجا +كمتر +كجاست +گردد +كسي +تر +مردم +تان +دادن +بودند +سري +جدا +ندارند +مگر +يكديگر +دارد +دهند +بنابراين +هنگامي +سمت +جا +انچه +خود +دادند +زياد +دارند +اثر +بدون +بهترين +بيشتر +البته +به +براساس +بيرون +كرد +بعضي +گرفت +توي +اي +ميليون +او +جريان +تول +بر +مانند +برابر +باشيم +مدتي +گويند +اكنون +تا +تنها +جديد +چند +بي +نشده +كردن +كردم +گويد +كرده +كنيم +نمي +نزد +روي +قصد +فقط +بالاي +ديگران +اين +ديروز +توسط +سوم +ايم +دانند +سوي +استفاده +شما +كنار +داريم +ساخته +طور +امده +رفته +نخست +بيست +نزديك +طي +كنيد +از +انها +تمامي +داشت +يكي +طريق +اش +چيست +روب +نمايد +گفت +چندين +چيزي +تواند +ام +ايا +با +ان +ايد +ترين +اينكه +ديگري +راه +هايي +بروز +همچنان +پاعين +كس +حدود +مختلف +مقابل +چيز +گيرد +ندارد +ضد +همچون +سازي +شان +مورد +باره +مرسي +خويش +برخوردار +چون +خارج +شش +هنوز +تحت +ضمن +هستيم +گفته +فكر +بسيار +پيش +براي +روزهاي +انكه +نخواهد +بالا +كل +وقتي +كي +چنين +كه +گيري +نيست +است +كجا +كند +نيز +يابد +بندي +حتي +توانند +عقب +خواست +كنند +بين +تمام +همه +ما +باشند +مثل +شد +اري +باشد +اره +طبق +بعد +اگر +صورت +غير +جاي +بيش +ريزي +اند +زيرا +چگونه +بار +لطفا +مي +درباره +من +ديده +همين +گذاري +برداري +علت +گذاشته +هم +فوق +نه +ها +شوند +اباد +همواره +هر +اول +خواهند +چهار +نام +امروز +مان +هاي +قبل +كنم +سعي +تازه +را +هستند +زير +جلوي +عنوان +بود diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_fi.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_fi.txt new file mode 100644 index 00000000000..addad798c4b --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_fi.txt @@ -0,0 +1,95 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/finnish/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + +| forms of BE + +olla +olen +olet +on +olemme +olette +ovat +ole | negative form + +oli +olisi +olisit +olisin +olisimme +olisitte +olisivat +olit +olin +olimme +olitte +olivat +ollut +olleet + +en | negation +et +ei +emme +ette +eivät + +|Nom Gen Acc Part Iness Elat Illat Adess Ablat Allat Ess Trans +minä minun minut minua minussa minusta minuun minulla minulta minulle | I +sinä sinun sinut sinua sinussa sinusta sinuun sinulla sinulta sinulle | you +hän hänen hänet häntä hänessä hänestä häneen hänellä häneltä hänelle | he she +me meidän meidät meitä meissä meistä meihin meillä meiltä meille | we +te teidän teidät teitä teissä teistä teihin teillä teiltä teille | you +he heidän heidät heitä heissä heistä heihin heillä heiltä heille | they + +tämä tämän tätä tässä tästä tähän tallä tältä tälle tänä täksi | this +tuo tuon tuotä tuossa tuosta tuohon tuolla tuolta tuolle tuona tuoksi | that +se sen sitä siinä siitä siihen sillä siltä sille sinä siksi | it +nämä näiden näitä näissä näistä näihin näillä näiltä näille näinä näiksi | these +nuo noiden noita noissa noista noihin noilla noilta noille noina noiksi | those +ne niiden niitä niissä niistä niihin niillä niiltä niille niinä niiksi | they + +kuka kenen kenet ketä kenessä kenestä keneen kenellä keneltä kenelle kenenä keneksi| who +ketkä keiden ketkä keitä keissä keistä keihin keillä keiltä keille keinä keiksi | (pl) +mikä minkä minkä mitä missä mistä mihin millä miltä mille minä miksi | which what +mitkä | (pl) + +joka jonka jota jossa josta johon jolla jolta jolle jona joksi | who which +jotka joiden joita joissa joista joihin joilla joilta joille joina joiksi | (pl) + +| conjunctions + +että | that +ja | and +jos | if +koska | because +kuin | than +mutta | but +niin | so +sekä | and +sillä | for +tai | or +vaan | but +vai | or +vaikka | although + + +| prepositions + +kanssa | with +mukaan | according to +noin | about +poikki | across +yli | over, across + +| other + +kun | when +niin | so +nyt | now +itse | self + diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_fr.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_fr.txt new file mode 100644 index 00000000000..c00837ea939 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_fr.txt @@ -0,0 +1,183 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/french/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A French stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + +au | a + le +aux | a + les +avec | with +ce | this +ces | these +dans | with +de | of +des | de + les +du | de + le +elle | she +en | `of them' etc +et | and +eux | them +il | he +je | I +la | the +le | the +leur | their +lui | him +ma | my (fem) +mais | but +me | me +même | same; as in moi-même (myself) etc +mes | me (pl) +moi | me +mon | my (masc) +ne | not +nos | our (pl) +notre | our +nous | we +on | one +ou | where +par | by +pas | not +pour | for +qu | que before vowel +que | that +qui | who +sa | his, her (fem) +se | oneself +ses | his (pl) +son | his, her (masc) +sur | on +ta | thy (fem) +te | thee +tes | thy (pl) +toi | thee +ton | thy (masc) +tu | thou +un | a +une | a +vos | your (pl) +votre | your +vous | you + + | single letter forms + +c | c' +d | d' +j | j' +l | l' +à | to, at +m | m' +n | n' +s | s' +t | t' +y | there + + | forms of être (not including the infinitive): +été +étée +étées +étés +étant +suis +es +est +sommes +êtes +sont +serai +seras +sera +serons +serez +seront +serais +serait +serions +seriez +seraient +étais +était +étions +étiez +étaient +fus +fut +fûmes +fûtes +furent +sois +soit +soyons +soyez +soient +fusse +fusses +fût +fussions +fussiez +fussent + + | forms of avoir (not including the infinitive): +ayant +eu +eue +eues +eus +ai +as +avons +avez +ont +aurai +auras +aura +aurons +aurez +auront +aurais +aurait +aurions +auriez +auraient +avais +avait +avions +aviez +avaient +eut +eûmes +eûtes +eurent +aie +aies +ait +ayons +ayez +aient +eusse +eusses +eût +eussions +eussiez +eussent + + | Later additions (from Jean-Christophe Deschamps) +ceci | this +celà  | that +cet | this +cette | this +ici | here +ils | they +les | the (pl) +leurs | their (pl) +quel | which +quels | which +quelle | which +quelles | which +sans | without +soi | oneself + diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_ga.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_ga.txt new file mode 100644 index 00000000000..9ff88d747e5 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_ga.txt @@ -0,0 +1,110 @@ + +a +ach +ag +agus +an +aon +ar +arna +as +b' +ba +beirt +bhúr +caoga +ceathair +ceathrar +chomh +chtó +chuig +chun +cois +céad +cúig +cúigear +d' +daichead +dar +de +deich +deichniúr +den +dhá +do +don +dtí +dá +dár +dó +faoi +faoin +faoina +faoinár +fara +fiche +gach +gan +go +gur +haon +hocht +i +iad +idir +in +ina +ins +inár +is +le +leis +lena +lenár +m' +mar +mo +mé +na +nach +naoi +naonúr +ná +ní +níor +nó +nócha +ocht +ochtar +os +roimh +sa +seacht +seachtar +seachtó +seasca +seisear +siad +sibh +sinn +sna +sé +sí +tar +thar +thú +triúr +trí +trína +trínár +tríocha +tú +um +ár +é +éis +í +ó +ón +óna +ónár diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_gl.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_gl.txt new file mode 100644 index 00000000000..d8760b12c14 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_gl.txt @@ -0,0 +1,161 @@ +# galican stopwords +a +aínda +alí +aquel +aquela +aquelas +aqueles +aquilo +aquí +ao +aos +as +así +á +ben +cando +che +co +coa +comigo +con +connosco +contigo +convosco +coas +cos +cun +cuns +cunha +cunhas +da +dalgunha +dalgunhas +dalgún +dalgúns +das +de +del +dela +delas +deles +desde +deste +do +dos +dun +duns +dunha +dunhas +e +el +ela +elas +eles +en +era +eran +esa +esas +ese +eses +esta +estar +estaba +está +están +este +estes +estiven +estou +eu +é +facer +foi +foron +fun +había +hai +iso +isto +la +las +lle +lles +lo +los +mais +me +meu +meus +min +miña +miñas +moi +na +nas +neste +nin +no +non +nos +nosa +nosas +noso +nosos +nós +nun +nunha +nuns +nunhas +o +os +ou +ó +ós +para +pero +pode +pois +pola +polas +polo +polos +por +que +se +senón +ser +seu +seus +sexa +sido +sobre +súa +súas +tamén +tan +te +ten +teñen +teño +ter +teu +teus +ti +tido +tiña +tiven +túa +túas +un +unha +unhas +uns +vos +vosa +vosas +voso +vosos +vós diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_hi.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_hi.txt new file mode 100644 index 00000000000..86286bb083b --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_hi.txt @@ -0,0 +1,235 @@ +# Also see http://www.opensource.org/licenses/bsd-license.html +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# This file was created by Jacques Savoy and is distributed under the BSD license. +# Note: by default this file also contains forms normalized by HindiNormalizer +# for spelling variation (see section below), such that it can be used whether or +# not you enable that feature. When adding additional entries to this list, +# please add the normalized form as well. +अंदर +अत +अपना +अपनी +अपने +अभी +आदि +आप +इत्यादि +इन +इनका +इन्हीं +इन्हें +इन्हों +इस +इसका +इसकी +इसके +इसमें +इसी +इसे +उन +उनका +उनकी +उनके +उनको +उन्हीं +उन्हें +उन्हों +उस +उसके +उसी +उसे +एक +एवं +एस +ऐसे +और +कई +कर +करता +करते +करना +करने +करें +कहते +कहा +का +काफ़ी +कि +कितना +किन्हें +किन्हों +किया +किर +किस +किसी +किसे +की +कुछ +कुल +के +को +कोई +कौन +कौनसा +गया +घर +जब +जहाँ +जा +जितना +जिन +जिन्हें +जिन्हों +जिस +जिसे +जीधर +जैसा +जैसे +जो +तक +तब +तरह +तिन +तिन्हें +तिन्हों +तिस +तिसे +तो +था +थी +थे +दबारा +दिया +दुसरा +दूसरे +दो +द्वारा +न +नहीं +ना +निहायत +नीचे +ने +पर +पर +पहले +पूरा +पे +फिर +बनी +बही +बहुत +बाद +बाला +बिलकुल +भी +भीतर +मगर +मानो +मे +में +यदि +यह +यहाँ +यही +या +यिह +ये +रखें +रहा +रहे +ऱ्वासा +लिए +लिये +लेकिन +व +वर्ग +वह +वह +वहाँ +वहीं +वाले +वुह +वे +वग़ैरह +संग +सकता +सकते +सबसे +सभी +साथ +साबुत +साभ +सारा +से +सो +ही +हुआ +हुई +हुए +है +हैं +हो +होता +होती +होते +होना +होने +# additional normalized forms of the above +अपनि +जेसे +होति +सभि +तिंहों +इंहों +दवारा +इसि +किंहें +थि +उंहों +ओर +जिंहें +वहिं +अभि +बनि +हि +उंहिं +उंहें +हें +वगेरह +एसे +रवासा +कोन +निचे +काफि +उसि +पुरा +भितर +हे +बहि +वहां +कोइ +यहां +जिंहों +तिंहें +किसि +कइ +यहि +इंहिं +जिधर +इंहें +अदि +इतयादि +हुइ +कोनसा +इसकि +दुसरे +जहां +अप +किंहों +उनकि +भि +वरग +हुअ +जेसा +नहिं diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_hu.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_hu.txt new file mode 100644 index 00000000000..1a96f1db6f2 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_hu.txt @@ -0,0 +1,209 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/hungarian/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + +| Hungarian stop word list +| prepared by Anna Tordai + +a +ahogy +ahol +aki +akik +akkor +alatt +által +általában +amely +amelyek +amelyekben +amelyeket +amelyet +amelynek +ami +amit +amolyan +amíg +amikor +át +abban +ahhoz +annak +arra +arról +az +azok +azon +azt +azzal +azért +aztán +azután +azonban +bár +be +belül +benne +cikk +cikkek +cikkeket +csak +de +e +eddig +egész +egy +egyes +egyetlen +egyéb +egyik +egyre +ekkor +el +elég +ellen +elő +először +előtt +első +én +éppen +ebben +ehhez +emilyen +ennek +erre +ez +ezt +ezek +ezen +ezzel +ezért +és +fel +felé +hanem +hiszen +hogy +hogyan +igen +így +illetve +ill. +ill +ilyen +ilyenkor +ison +ismét +itt +jó +jól +jobban +kell +kellett +keresztül +keressünk +ki +kívül +között +közül +legalább +lehet +lehetett +legyen +lenne +lenni +lesz +lett +maga +magát +majd +majd +már +más +másik +meg +még +mellett +mert +mely +melyek +mi +mit +míg +miért +milyen +mikor +minden +mindent +mindenki +mindig +mint +mintha +mivel +most +nagy +nagyobb +nagyon +ne +néha +nekem +neki +nem +néhány +nélkül +nincs +olyan +ott +össze +ő +ők +őket +pedig +persze +rá +s +saját +sem +semmi +sok +sokat +sokkal +számára +szemben +szerint +szinte +talán +tehát +teljes +tovább +továbbá +több +úgy +ugyanis +új +újabb +újra +után +utána +utolsó +vagy +vagyis +valaki +valami +valamint +való +vagyok +van +vannak +volt +voltam +voltak +voltunk +vissza +vele +viszont +volna diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_hy.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_hy.txt new file mode 100644 index 00000000000..60c1c50fbc8 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_hy.txt @@ -0,0 +1,46 @@ +# example set of Armenian stopwords. +այդ +այլ +այն +այս +դու +դուք +եմ +են +ենք +ես +եք +է +էի +էին +էինք +էիր +էիք +էր +ըստ +թ +ի +ին +իսկ +իր +կամ +համար +հետ +հետո +մենք +մեջ +մի +ն +նա +նաև +նրա +նրանք +որ +որը +որոնք +որպես +ու +ում +պիտի +վրա +և diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_id.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_id.txt new file mode 100644 index 00000000000..4617f83a5c5 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_id.txt @@ -0,0 +1,359 @@ +# from appendix D of: A Study of Stemming Effects on Information +# Retrieval in Bahasa Indonesia +ada +adanya +adalah +adapun +agak +agaknya +agar +akan +akankah +akhirnya +aku +akulah +amat +amatlah +anda +andalah +antar +diantaranya +antara +antaranya +diantara +apa +apaan +mengapa +apabila +apakah +apalagi +apatah +atau +ataukah +ataupun +bagai +bagaikan +sebagai +sebagainya +bagaimana +bagaimanapun +sebagaimana +bagaimanakah +bagi +bahkan +bahwa +bahwasanya +sebaliknya +banyak +sebanyak +beberapa +seberapa +begini +beginian +beginikah +beginilah +sebegini +begitu +begitukah +begitulah +begitupun +sebegitu +belum +belumlah +sebelum +sebelumnya +sebenarnya +berapa +berapakah +berapalah +berapapun +betulkah +sebetulnya +biasa +biasanya +bila +bilakah +bisa +bisakah +sebisanya +boleh +bolehkah +bolehlah +buat +bukan +bukankah +bukanlah +bukannya +cuma +percuma +dahulu +dalam +dan +dapat +dari +daripada +dekat +demi +demikian +demikianlah +sedemikian +dengan +depan +di +dia +dialah +dini +diri +dirinya +terdiri +dong +dulu +enggak +enggaknya +entah +entahlah +terhadap +terhadapnya +hal +hampir +hanya +hanyalah +harus +haruslah +harusnya +seharusnya +hendak +hendaklah +hendaknya +hingga +sehingga +ia +ialah +ibarat +ingin +inginkah +inginkan +ini +inikah +inilah +itu +itukah +itulah +jangan +jangankan +janganlah +jika +jikalau +juga +justru +kala +kalau +kalaulah +kalaupun +kalian +kami +kamilah +kamu +kamulah +kan +kapan +kapankah +kapanpun +dikarenakan +karena +karenanya +ke +kecil +kemudian +kenapa +kepada +kepadanya +ketika +seketika +khususnya +kini +kinilah +kiranya +sekiranya +kita +kitalah +kok +lagi +lagian +selagi +lah +lain +lainnya +melainkan +selaku +lalu +melalui +terlalu +lama +lamanya +selama +selama +selamanya +lebih +terlebih +bermacam +macam +semacam +maka +makanya +makin +malah +malahan +mampu +mampukah +mana +manakala +manalagi +masih +masihkah +semasih +masing +mau +maupun +semaunya +memang +mereka +merekalah +meski +meskipun +semula +mungkin +mungkinkah +nah +namun +nanti +nantinya +nyaris +oleh +olehnya +seorang +seseorang +pada +padanya +padahal +paling +sepanjang +pantas +sepantasnya +sepantasnyalah +para +pasti +pastilah +per +pernah +pula +pun +merupakan +rupanya +serupa +saat +saatnya +sesaat +saja +sajalah +saling +bersama +sama +sesama +sambil +sampai +sana +sangat +sangatlah +saya +sayalah +se +sebab +sebabnya +sebuah +tersebut +tersebutlah +sedang +sedangkan +sedikit +sedikitnya +segala +segalanya +segera +sesegera +sejak +sejenak +sekali +sekalian +sekalipun +sesekali +sekaligus +sekarang +sekarang +sekitar +sekitarnya +sela +selain +selalu +seluruh +seluruhnya +semakin +sementara +sempat +semua +semuanya +sendiri +sendirinya +seolah +seperti +sepertinya +sering +seringnya +serta +siapa +siapakah +siapapun +disini +disinilah +sini +sinilah +sesuatu +sesuatunya +suatu +sesudah +sesudahnya +sudah +sudahkah +sudahlah +supaya +tadi +tadinya +tak +tanpa +setelah +telah +tentang +tentu +tentulah +tentunya +tertentu +seterusnya +tapi +tetapi +setiap +tiap +setidaknya +tidak +tidakkah +tidaklah +toh +waduh +wah +wahai +sewaktu +walau +walaupun +wong +yaitu +yakni +yang diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_it.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_it.txt new file mode 100644 index 00000000000..4cb5b0891b1 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_it.txt @@ -0,0 +1,301 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/italian/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | An Italian stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + +ad | a (to) before vowel +al | a + il +allo | a + lo +ai | a + i +agli | a + gli +all | a + l' +agl | a + gl' +alla | a + la +alle | a + le +con | with +col | con + il +coi | con + i (forms collo, cogli etc are now very rare) +da | from +dal | da + il +dallo | da + lo +dai | da + i +dagli | da + gli +dall | da + l' +dagl | da + gll' +dalla | da + la +dalle | da + le +di | of +del | di + il +dello | di + lo +dei | di + i +degli | di + gli +dell | di + l' +degl | di + gl' +della | di + la +delle | di + le +in | in +nel | in + el +nello | in + lo +nei | in + i +negli | in + gli +nell | in + l' +negl | in + gl' +nella | in + la +nelle | in + le +su | on +sul | su + il +sullo | su + lo +sui | su + i +sugli | su + gli +sull | su + l' +sugl | su + gl' +sulla | su + la +sulle | su + le +per | through, by +tra | among +contro | against +io | I +tu | thou +lui | he +lei | she +noi | we +voi | you +loro | they +mio | my +mia | +miei | +mie | +tuo | +tua | +tuoi | thy +tue | +suo | +sua | +suoi | his, her +sue | +nostro | our +nostra | +nostri | +nostre | +vostro | your +vostra | +vostri | +vostre | +mi | me +ti | thee +ci | us, there +vi | you, there +lo | him, the +la | her, the +li | them +le | them, the +gli | to him, the +ne | from there etc +il | the +un | a +uno | a +una | a +ma | but +ed | and +se | if +perché | why, because +anche | also +come | how +dov | where (as dov') +dove | where +che | who, that +chi | who +cui | whom +non | not +più | more +quale | who, that +quanto | how much +quanti | +quanta | +quante | +quello | that +quelli | +quella | +quelle | +questo | this +questi | +questa | +queste | +si | yes +tutto | all +tutti | all + + | single letter forms: + +a | at +c | as c' for ce or ci +e | and +i | the +l | as l' +o | or + + | forms of avere, to have (not including the infinitive): + +ho +hai +ha +abbiamo +avete +hanno +abbia +abbiate +abbiano +avrò +avrai +avrà +avremo +avrete +avranno +avrei +avresti +avrebbe +avremmo +avreste +avrebbero +avevo +avevi +aveva +avevamo +avevate +avevano +ebbi +avesti +ebbe +avemmo +aveste +ebbero +avessi +avesse +avessimo +avessero +avendo +avuto +avuta +avuti +avute + + | forms of essere, to be (not including the infinitive): +sono +sei +è +siamo +siete +sia +siate +siano +sarò +sarai +sarà +saremo +sarete +saranno +sarei +saresti +sarebbe +saremmo +sareste +sarebbero +ero +eri +era +eravamo +eravate +erano +fui +fosti +fu +fummo +foste +furono +fossi +fosse +fossimo +fossero +essendo + + | forms of fare, to do (not including the infinitive, fa, fat-): +faccio +fai +facciamo +fanno +faccia +facciate +facciano +farò +farai +farà +faremo +farete +faranno +farei +faresti +farebbe +faremmo +fareste +farebbero +facevo +facevi +faceva +facevamo +facevate +facevano +feci +facesti +fece +facemmo +faceste +fecero +facessi +facesse +facessimo +facessero +facendo + + | forms of stare, to be (not including the infinitive): +sto +stai +sta +stiamo +stanno +stia +stiate +stiano +starò +starai +starà +staremo +starete +staranno +starei +staresti +starebbe +staremmo +stareste +starebbero +stavo +stavi +stava +stavamo +stavate +stavano +stetti +stesti +stette +stemmo +steste +stettero +stessi +stesse +stessimo +stessero +stando diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_ja.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_ja.txt new file mode 100644 index 00000000000..d4321be6b16 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_ja.txt @@ -0,0 +1,127 @@ +# +# This file defines a stopword set for Japanese. +# +# This set is made up of hand-picked frequent terms from segmented Japanese Wikipedia. +# Punctuation characters and frequent kanji have mostly been left out. See LUCENE-3745 +# for frequency lists, etc. that can be useful for making your own set (if desired) +# +# Note that there is an overlap between these stopwords and the terms stopped when used +# in combination with the JapanesePartOfSpeechStopFilter. When editing this file, note +# that comments are not allowed on the same line as stopwords. +# +# Also note that stopping is done in a case-insensitive manner. Change your StopFilter +# configuration if you need case-sensitive stopping. Lastly, note that stopping is done +# using the same character width as the entries in this file. Since this StopFilter is +# normally done after a CJKWidthFilter in your chain, you would usually want your romaji +# entries to be in half-width and your kana entries to be in full-width. +# +の +に +は +を +た +が +で +て +と +し +れ +さ +ある +いる +も +する +から +な +こと +として +い +や +れる +など +なっ +ない +この +ため +その +あっ +よう +また +もの +という +あり +まで +られ +なる +へ +か +だ +これ +によって +により +おり +より +による +ず +なり +られる +において +ば +なかっ +なく +しかし +について +せ +だっ +その後 +できる +それ +う +ので +なお +のみ +でき +き +つ +における +および +いう +さらに +でも +ら +たり +その他 +に関する +たち +ます +ん +なら +に対して +特に +せる +及び +これら +とき +では +にて +ほか +ながら +うち +そして +とともに +ただし +かつて +それぞれ +または +お +ほど +ものの +に対する +ほとんど +と共に +といった +です +とも +ところ +ここ +##### End of file diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_lv.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_lv.txt new file mode 100644 index 00000000000..e21a23c06c3 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_lv.txt @@ -0,0 +1,172 @@ +# Set of Latvian stopwords from A Stemming Algorithm for Latvian, Karlis Kreslins +# the original list of over 800 forms was refined: +# pronouns, adverbs, interjections were removed +# +# prepositions +aiz +ap +ar +apakš +ārpus +augšpus +bez +caur +dēļ +gar +iekš +iz +kopš +labad +lejpus +līdz +no +otrpus +pa +par +pār +pēc +pie +pirms +pret +priekš +starp +šaipus +uz +viņpus +virs +virspus +zem +apakšpus +# Conjunctions +un +bet +jo +ja +ka +lai +tomēr +tikko +turpretī +arī +kaut +gan +tādēļ +tā +ne +tikvien +vien +kā +ir +te +vai +kamēr +# Particles +ar +diezin +droši +diemžēl +nebūt +ik +it +taču +nu +pat +tiklab +iekšpus +nedz +tik +nevis +turpretim +jeb +iekam +iekām +iekāms +kolīdz +līdzko +tiklīdz +jebšu +tālab +tāpēc +nekā +itin +jā +jau +jel +nē +nezin +tad +tikai +vis +tak +iekams +vien +# modal verbs +būt +biju +biji +bija +bijām +bijāt +esmu +esi +esam +esat +būšu +būsi +būs +būsim +būsiet +tikt +tiku +tiki +tika +tikām +tikāt +tieku +tiec +tiek +tiekam +tiekat +tikšu +tiks +tiksim +tiksiet +tapt +tapi +tapāt +topat +tapšu +tapsi +taps +tapsim +tapsiet +kļūt +kļuvu +kļuvi +kļuva +kļuvām +kļuvāt +kļūstu +kļūsti +kļūst +kļūstam +kļūstat +kļūšu +kļūsi +kļūs +kļūsim +kļūsiet +# verbs +varēt +varēju +varējām +varēšu +varēsim +var +varēji +varējāt +varēsi +varēsiet +varat +varēja +varēs diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_nl.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_nl.txt new file mode 100644 index 00000000000..f4d61f5092c --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_nl.txt @@ -0,0 +1,117 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/dutch/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Dutch stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | This is a ranked list (commonest to rarest) of stopwords derived from + | a large sample of Dutch text. + + | Dutch stop words frequently exhibit homonym clashes. These are indicated + | clearly below. + +de | the +en | and +van | of, from +ik | I, the ego +te | (1) chez, at etc, (2) to, (3) too +dat | that, which +die | that, those, who, which +in | in, inside +een | a, an, one +hij | he +het | the, it +niet | not, nothing, naught +zijn | (1) to be, being, (2) his, one's, its +is | is +was | (1) was, past tense of all persons sing. of 'zijn' (to be) (2) wax, (3) the washing, (4) rise of river +op | on, upon, at, in, up, used up +aan | on, upon, to (as dative) +met | with, by +als | like, such as, when +voor | (1) before, in front of, (2) furrow +had | had, past tense all persons sing. of 'hebben' (have) +er | there +maar | but, only +om | round, about, for etc +hem | him +dan | then +zou | should/would, past tense all persons sing. of 'zullen' +of | or, whether, if +wat | what, something, anything +mijn | possessive and noun 'mine' +men | people, 'one' +dit | this +zo | so, thus, in this way +door | through by +over | over, across +ze | she, her, they, them +zich | oneself +bij | (1) a bee, (2) by, near, at +ook | also, too +tot | till, until +je | you +mij | me +uit | out of, from +der | Old Dutch form of 'van der' still found in surnames +daar | (1) there, (2) because +haar | (1) her, their, them, (2) hair +naar | (1) unpleasant, unwell etc, (2) towards, (3) as +heb | present first person sing. of 'to have' +hoe | how, why +heeft | present third person sing. of 'to have' +hebben | 'to have' and various parts thereof +deze | this +u | you +want | (1) for, (2) mitten, (3) rigging +nog | yet, still +zal | 'shall', first and third person sing. of verb 'zullen' (will) +me | me +zij | she, they +nu | now +ge | 'thou', still used in Belgium and south Netherlands +geen | none +omdat | because +iets | something, somewhat +worden | to become, grow, get +toch | yet, still +al | all, every, each +waren | (1) 'were' (2) to wander, (3) wares, (3) +veel | much, many +meer | (1) more, (2) lake +doen | to do, to make +toen | then, when +moet | noun 'spot/mote' and present form of 'to must' +ben | (1) am, (2) 'are' in interrogative second person singular of 'to be' +zonder | without +kan | noun 'can' and present form of 'to be able' +hun | their, them +dus | so, consequently +alles | all, everything, anything +onder | under, beneath +ja | yes, of course +eens | once, one day +hier | here +wie | who +werd | imperfect third person sing. of 'become' +altijd | always +doch | yet, but etc +wordt | present third person sing. of 'become' +wezen | (1) to be, (2) 'been' as in 'been fishing', (3) orphans +kunnen | to be able +ons | us/our +zelf | self +tegen | against, towards, at +na | after, near +reeds | already +wil | (1) present tense of 'want', (2) 'will', noun, (3) fender +kon | could; past tense of 'to be able' +niets | nothing +uw | your +iemand | somebody +geweest | been; past participle of 'be' +andere | other diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_no.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_no.txt new file mode 100644 index 00000000000..e76f36e69ed --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_no.txt @@ -0,0 +1,192 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/norwegian/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Norwegian stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | This stop word list is for the dominant bokmål dialect. Words unique + | to nynorsk are marked *. + + | Revised by Jan Bruusgaard , Jan 2005 + +og | and +i | in +jeg | I +det | it/this/that +at | to (w. inf.) +en | a/an +et | a/an +den | it/this/that +til | to +er | is/am/are +som | who/that +på | on +de | they / you(formal) +med | with +han | he +av | of +ikke | not +ikkje | not * +der | there +så | so +var | was/were +meg | me +seg | you +men | but +ett | one +har | have +om | about +vi | we +min | my +mitt | my +ha | have +hadde | had +hun | she +nå | now +over | over +da | when/as +ved | by/know +fra | from +du | you +ut | out +sin | your +dem | them +oss | us +opp | up +man | you/one +kan | can +hans | his +hvor | where +eller | or +hva | what +skal | shall/must +selv | self (reflective) +sjøl | self (reflective) +her | here +alle | all +vil | will +bli | become +ble | became +blei | became * +blitt | have become +kunne | could +inn | in +når | when +være | be +kom | come +noen | some +noe | some +ville | would +dere | you +som | who/which/that +deres | their/theirs +kun | only/just +ja | yes +etter | after +ned | down +skulle | should +denne | this +for | for/because +deg | you +si | hers/his +sine | hers/his +sitt | hers/his +mot | against +å | to +meget | much +hvorfor | why +dette | this +disse | these/those +uten | without +hvordan | how +ingen | none +din | your +ditt | your +blir | become +samme | same +hvilken | which +hvilke | which (plural) +sånn | such a +inni | inside/within +mellom | between +vår | our +hver | each +hvem | who +vors | us/ours +hvis | whose +både | both +bare | only/just +enn | than +fordi | as/because +før | before +mange | many +også | also +slik | just +vært | been +være | to be +båe | both * +begge | both +siden | since +dykk | your * +dykkar | yours * +dei | they * +deira | them * +deires | theirs * +deim | them * +di | your (fem.) * +då | as/when * +eg | I * +ein | a/an * +eit | a/an * +eitt | a/an * +elles | or * +honom | he * +hjå | at * +ho | she * +hoe | she * +henne | her +hennar | her/hers +hennes | hers +hoss | how * +hossen | how * +ikkje | not * +ingi | noone * +inkje | noone * +korleis | how * +korso | how * +kva | what/which * +kvar | where * +kvarhelst | where * +kven | who/whom * +kvi | why * +kvifor | why * +me | we * +medan | while * +mi | my * +mine | my * +mykje | much * +no | now * +nokon | some (masc./neut.) * +noka | some (fem.) * +nokor | some * +noko | some * +nokre | some * +si | his/hers * +sia | since * +sidan | since * +so | so * +somt | some * +somme | some * +um | about* +upp | up * +vere | be * +vore | was * +verte | become * +vort | become * +varte | became * +vart | became * + diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_pt.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_pt.txt new file mode 100644 index 00000000000..276c1b446f2 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_pt.txt @@ -0,0 +1,251 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/portuguese/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Portuguese stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + + | The following is a ranked list (commonest to rarest) of stopwords + | deriving from a large sample of text. + + | Extra words have been added at the end. + +de | of, from +a | the; to, at; her +o | the; him +que | who, that +e | and +do | de + o +da | de + a +em | in +um | a +para | for + | é from SER +com | with +não | not, no +uma | a +os | the; them +no | em + o +se | himself etc +na | em + a +por | for +mais | more +as | the; them +dos | de + os +como | as, like +mas | but + | foi from SER +ao | a + o +ele | he +das | de + as + | tem from TER +à | a + a +seu | his +sua | her +ou | or + | ser from SER +quando | when +muito | much + | há from HAV +nos | em + os; us +já | already, now + | está from EST +eu | I +também | also +só | only, just +pelo | per + o +pela | per + a +até | up to +isso | that +ela | he +entre | between + | era from SER +depois | after +sem | without +mesmo | same +aos | a + os + | ter from TER +seus | his +quem | whom +nas | em + as +me | me +esse | that +eles | they + | estão from EST +você | you + | tinha from TER + | foram from SER +essa | that +num | em + um +nem | nor +suas | her +meu | my +às | a + as +minha | my + | têm from TER +numa | em + uma +pelos | per + os +elas | they + | havia from HAV + | seja from SER +qual | which + | será from SER +nós | we + | tenho from TER +lhe | to him, her +deles | of them +essas | those +esses | those +pelas | per + as +este | this + | fosse from SER +dele | of him + + | other words. There are many contractions such as naquele = em+aquele, + | mo = me+o, but they are rare. + | Indefinite article plural forms are also rare. + +tu | thou +te | thee +vocês | you (plural) +vos | you +lhes | to them +meus | my +minhas +teu | thy +tua +teus +tuas +nosso | our +nossa +nossos +nossas + +dela | of her +delas | of them + +esta | this +estes | these +estas | these +aquele | that +aquela | that +aqueles | those +aquelas | those +isto | this +aquilo | that + + | forms of estar, to be (not including the infinitive): +estou +está +estamos +estão +estive +esteve +estivemos +estiveram +estava +estávamos +estavam +estivera +estivéramos +esteja +estejamos +estejam +estivesse +estivéssemos +estivessem +estiver +estivermos +estiverem + + | forms of haver, to have (not including the infinitive): +hei +há +havemos +hão +houve +houvemos +houveram +houvera +houvéramos +haja +hajamos +hajam +houvesse +houvéssemos +houvessem +houver +houvermos +houverem +houverei +houverá +houveremos +houverão +houveria +houveríamos +houveriam + + | forms of ser, to be (not including the infinitive): +sou +somos +são +era +éramos +eram +fui +foi +fomos +foram +fora +fôramos +seja +sejamos +sejam +fosse +fôssemos +fossem +for +formos +forem +serei +será +seremos +serão +seria +seríamos +seriam + + | forms of ter, to have (not including the infinitive): +tenho +tem +temos +tém +tinha +tínhamos +tinham +tive +teve +tivemos +tiveram +tivera +tivéramos +tenha +tenhamos +tenham +tivesse +tivéssemos +tivessem +tiver +tivermos +tiverem +terei +terá +teremos +terão +teria +teríamos +teriam diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_ro.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_ro.txt new file mode 100644 index 00000000000..4fdee90a5ba --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_ro.txt @@ -0,0 +1,233 @@ +# This file was created by Jacques Savoy and is distributed under the BSD license. +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# Also see http://www.opensource.org/licenses/bsd-license.html +acea +aceasta +această +aceea +acei +aceia +acel +acela +acele +acelea +acest +acesta +aceste +acestea +aceşti +aceştia +acolo +acum +ai +aia +aibă +aici +al +ăla +ale +alea +ălea +altceva +altcineva +am +ar +are +aş +aşadar +asemenea +asta +ăsta +astăzi +astea +ăstea +ăştia +asupra +aţi +au +avea +avem +aveţi +azi +bine +bucur +bună +ca +că +căci +când +care +cărei +căror +cărui +cât +câte +câţi +către +câtva +ce +cel +ceva +chiar +cînd +cine +cineva +cît +cîte +cîţi +cîtva +contra +cu +cum +cumva +curând +curînd +da +dă +dacă +dar +datorită +de +deci +deja +deoarece +departe +deşi +din +dinaintea +dintr +dintre +drept +după +ea +ei +el +ele +eram +este +eşti +eu +face +fără +fi +fie +fiecare +fii +fim +fiţi +iar +ieri +îi +îl +îmi +împotriva +în +înainte +înaintea +încât +încît +încotro +între +întrucât +întrucît +îţi +la +lângă +le +li +lîngă +lor +lui +mă +mâine +mea +mei +mele +mereu +meu +mi +mine +mult +multă +mulţi +ne +nicăieri +nici +nimeni +nişte +noastră +noastre +noi +noştri +nostru +nu +ori +oricând +oricare +oricât +orice +oricînd +oricine +oricît +oricum +oriunde +până +pe +pentru +peste +pînă +poate +pot +prea +prima +primul +prin +printr +sa +să +săi +sale +sau +său +se +şi +sînt +sîntem +sînteţi +spre +sub +sunt +suntem +sunteţi +ta +tăi +tale +tău +te +ţi +ţie +tine +toată +toate +tot +toţi +totuşi +tu +un +una +unde +undeva +unei +unele +uneori +unor +vă +vi +voastră +voastre +voi +voştri +vostru +vouă +vreo +vreun diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_ru.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_ru.txt new file mode 100644 index 00000000000..64307693457 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_ru.txt @@ -0,0 +1,241 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/russian/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | a russian stop word list. comments begin with vertical bar. each stop + | word is at the start of a line. + + | this is a ranked list (commonest to rarest) of stopwords derived from + | a large text sample. + + | letter `ё' is translated to `е'. + +и | and +в | in/into +во | alternative form +не | not +что | what/that +он | he +на | on/onto +я | i +с | from +со | alternative form +как | how +а | milder form of `no' (but) +то | conjunction and form of `that' +все | all +она | she +так | so, thus +его | him +но | but +да | yes/and +ты | thou +к | towards, by +у | around, chez +же | intensifier particle +вы | you +за | beyond, behind +бы | conditional/subj. particle +по | up to, along +только | only +ее | her +мне | to me +было | it was +вот | here is/are, particle +от | away from +меня | me +еще | still, yet, more +нет | no, there isnt/arent +о | about +из | out of +ему | to him +теперь | now +когда | when +даже | even +ну | so, well +вдруг | suddenly +ли | interrogative particle +если | if +уже | already, but homonym of `narrower' +или | or +ни | neither +быть | to be +был | he was +него | prepositional form of его +до | up to +вас | you accusative +нибудь | indef. suffix preceded by hyphen +опять | again +уж | already, but homonym of `adder' +вам | to you +сказал | he said +ведь | particle `after all' +там | there +потом | then +себя | oneself +ничего | nothing +ей | to her +может | usually with `быть' as `maybe' +они | they +тут | here +где | where +есть | there is/are +надо | got to, must +ней | prepositional form of ей +для | for +мы | we +тебя | thee +их | them, their +чем | than +была | she was +сам | self +чтоб | in order to +без | without +будто | as if +человек | man, person, one +чего | genitive form of `what' +раз | once +тоже | also +себе | to oneself +под | beneath +жизнь | life +будет | will be +ж | short form of intensifer particle `же' +тогда | then +кто | who +этот | this +говорил | was saying +того | genitive form of `that' +потому | for that reason +этого | genitive form of `this' +какой | which +совсем | altogether +ним | prepositional form of `его', `они' +здесь | here +этом | prepositional form of `этот' +один | one +почти | almost +мой | my +тем | instrumental/dative plural of `тот', `то' +чтобы | full form of `in order that' +нее | her (acc.) +кажется | it seems +сейчас | now +были | they were +куда | where to +зачем | why +сказать | to say +всех | all (acc., gen. preposn. plural) +никогда | never +сегодня | today +можно | possible, one can +при | by +наконец | finally +два | two +об | alternative form of `о', about +другой | another +хоть | even +после | after +над | above +больше | more +тот | that one (masc.) +через | across, in +эти | these +нас | us +про | about +всего | in all, only, of all +них | prepositional form of `они' (they) +какая | which, feminine +много | lots +разве | interrogative particle +сказала | she said +три | three +эту | this, acc. fem. sing. +моя | my, feminine +впрочем | moreover, besides +хорошо | good +свою | ones own, acc. fem. sing. +этой | oblique form of `эта', fem. `this' +перед | in front of +иногда | sometimes +лучше | better +чуть | a little +том | preposn. form of `that one' +нельзя | one must not +такой | such a one +им | to them +более | more +всегда | always +конечно | of course +всю | acc. fem. sing of `all' +между | between + + + | b: some paradigms + | + | personal pronouns + | + | я меня мне мной [мною] + | ты тебя тебе тобой [тобою] + | он его ему им [него, нему, ним] + | она ее эи ею [нее, нэи, нею] + | оно его ему им [него, нему, ним] + | + | мы нас нам нами + | вы вас вам вами + | они их им ими [них, ним, ними] + | + | себя себе собой [собою] + | + | demonstrative pronouns: этот (this), тот (that) + | + | этот эта это эти + | этого эты это эти + | этого этой этого этих + | этому этой этому этим + | этим этой этим [этою] этими + | этом этой этом этих + | + | тот та то те + | того ту то те + | того той того тех + | тому той тому тем + | тем той тем [тою] теми + | том той том тех + | + | determinative pronouns + | + | (a) весь (all) + | + | весь вся все все + | всего всю все все + | всего всей всего всех + | всему всей всему всем + | всем всей всем [всею] всеми + | всем всей всем всех + | + | (b) сам (himself etc) + | + | сам сама само сами + | самого саму само самих + | самого самой самого самих + | самому самой самому самим + | самим самой самим [самою] самими + | самом самой самом самих + | + | stems of verbs `to be', `to have', `to do' and modal + | + | быть бы буд быв есть суть + | име + | дел + | мог мож мочь + | уме + | хоч хот + | долж + | можн + | нужн + | нельзя + diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_sv.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_sv.txt new file mode 100644 index 00000000000..22bddfd8cb3 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_sv.txt @@ -0,0 +1,131 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/swedish/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Swedish stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | This is a ranked list (commonest to rarest) of stopwords derived from + | a large text sample. + + | Swedish stop words occasionally exhibit homonym clashes. For example + | så = so, but also seed. These are indicated clearly below. + +och | and +det | it, this/that +att | to (with infinitive) +i | in, at +en | a +jag | I +hon | she +som | who, that +han | he +på | on +den | it, this/that +med | with +var | where, each +sig | him(self) etc +för | for +så | so (also: seed) +till | to +är | is +men | but +ett | a +om | if; around, about +hade | had +de | they, these/those +av | of +icke | not, no +mig | me +du | you +henne | her +då | then, when +sin | his +nu | now +har | have +inte | inte någon = no one +hans | his +honom | him +skulle | 'sake' +hennes | her +där | there +min | my +man | one (pronoun) +ej | nor +vid | at, by, on (also: vast) +kunde | could +något | some etc +från | from, off +ut | out +när | when +efter | after, behind +upp | up +vi | we +dem | them +vara | be +vad | what +över | over +än | than +dig | you +kan | can +sina | his +här | here +ha | have +mot | towards +alla | all +under | under (also: wonder) +någon | some etc +eller | or (else) +allt | all +mycket | much +sedan | since +ju | why +denna | this/that +själv | myself, yourself etc +detta | this/that +åt | to +utan | without +varit | was +hur | how +ingen | no +mitt | my +ni | you +bli | to be, become +blev | from bli +oss | us +din | thy +dessa | these/those +några | some etc +deras | their +blir | from bli +mina | my +samma | (the) same +vilken | who, that +er | you, your +sådan | such a +vår | our +blivit | from bli +dess | its +inom | within +mellan | between +sådant | such a +varför | why +varje | each +vilka | who, that +ditt | thy +vem | who +vilket | who, that +sitta | his +sådana | such a +vart | each +dina | thy +vars | whose +vårt | our +våra | our +ert | your +era | your +vilkas | whose + diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_th.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_th.txt new file mode 100644 index 00000000000..07f0fabe692 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_th.txt @@ -0,0 +1,119 @@ +# Thai stopwords from: +# "Opinion Detection in Thai Political News Columns +# Based on Subjectivity Analysis" +# Khampol Sukhum, Supot Nitsuwat, and Choochart Haruechaiyasak +ไว้ +ไม่ +ไป +ได้ +ให้ +ใน +โดย +แห่ง +แล้ว +และ +แรก +แบบ +แต่ +เอง +เห็น +เลย +เริ่ม +เรา +เมื่อ +เพื่อ +เพราะ +เป็นการ +เป็น +เปิดเผย +เปิด +เนื่องจาก +เดียวกัน +เดียว +เช่น +เฉพาะ +เคย +เข้า +เขา +อีก +อาจ +อะไร +ออก +อย่าง +อยู่ +อยาก +หาก +หลาย +หลังจาก +หลัง +หรือ +หนึ่ง +ส่วน +ส่ง +สุด +สําหรับ +ว่า +วัน +ลง +ร่วม +ราย +รับ +ระหว่าง +รวม +ยัง +มี +มาก +มา +พร้อม +พบ +ผ่าน +ผล +บาง +น่า +นี้ +นํา +นั้น +นัก +นอกจาก +ทุก +ที่สุด +ที่ +ทําให้ +ทํา +ทาง +ทั้งนี้ +ทั้ง +ถ้า +ถูก +ถึง +ต้อง +ต่างๆ +ต่าง +ต่อ +ตาม +ตั้งแต่ +ตั้ง +ด้าน +ด้วย +ดัง +ซึ่ง +ช่วง +จึง +จาก +จัด +จะ +คือ +ความ +ครั้ง +คง +ขึ้น +ของ +ขอ +ขณะ +ก่อน +ก็ +การ +กับ +กัน +กว่า +กล่าว diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_tr.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_tr.txt new file mode 100644 index 00000000000..84d9408d4ea --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_tr.txt @@ -0,0 +1,212 @@ +# Turkish stopwords from LUCENE-559 +# merged with the list from "Information Retrieval on Turkish Texts" +# (http://www.users.muohio.edu/canf/papers/JASIST2008offPrint.pdf) +acaba +altmış +altı +ama +ancak +arada +aslında +ayrıca +bana +bazı +belki +ben +benden +beni +benim +beri +beş +bile +bin +bir +birçok +biri +birkaç +birkez +birşey +birşeyi +biz +bize +bizden +bizi +bizim +böyle +böylece +bu +buna +bunda +bundan +bunlar +bunları +bunların +bunu +bunun +burada +çok +çünkü +da +daha +dahi +de +defa +değil +diğer +diye +doksan +dokuz +dolayı +dolayısıyla +dört +edecek +eden +ederek +edilecek +ediliyor +edilmesi +ediyor +eğer +elli +en +etmesi +etti +ettiği +ettiğini +gibi +göre +halen +hangi +hatta +hem +henüz +hep +hepsi +her +herhangi +herkesin +hiç +hiçbir +için +iki +ile +ilgili +ise +işte +itibaren +itibariyle +kadar +karşın +katrilyon +kendi +kendilerine +kendini +kendisi +kendisine +kendisini +kez +ki +kim +kimden +kime +kimi +kimse +kırk +milyar +milyon +mu +mü +mı +nasıl +ne +neden +nedenle +nerde +nerede +nereye +niye +niçin +o +olan +olarak +oldu +olduğu +olduğunu +olduklarını +olmadı +olmadığı +olmak +olması +olmayan +olmaz +olsa +olsun +olup +olur +olursa +oluyor +on +ona +ondan +onlar +onlardan +onları +onların +onu +onun +otuz +oysa +öyle +pek +rağmen +sadece +sanki +sekiz +seksen +sen +senden +seni +senin +siz +sizden +sizi +sizin +şey +şeyden +şeyi +şeyler +şöyle +şu +şuna +şunda +şundan +şunları +şunu +tarafından +trilyon +tüm +üç +üzere +var +vardı +ve +veya +ya +yani +yapacak +yapılan +yapılması +yapıyor +yapmak +yaptı +yaptığı +yaptığını +yaptıkları +yedi +yerine +yetmiş +yine +yirmi +yoksa +yüz +zaten diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/userdict_ja.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/userdict_ja.txt new file mode 100644 index 00000000000..6f0368e4d81 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/userdict_ja.txt @@ -0,0 +1,29 @@ +# +# This is a sample user dictionary for Kuromoji (JapaneseTokenizer) +# +# Add entries to this file in order to override the statistical model in terms +# of segmentation, readings and part-of-speech tags. Notice that entries do +# not have weights since they are always used when found. This is by-design +# in order to maximize ease-of-use. +# +# Entries are defined using the following CSV format: +# , ... , ... , +# +# Notice that a single half-width space separates tokens and readings, and +# that the number tokens and readings must match exactly. +# +# Also notice that multiple entries with the same is undefined. +# +# Whitespace only lines are ignored. Comments are not allowed on entry lines. +# + +# Custom segmentation for kanji compounds +日本経済新聞,日本 経済 新聞,ニホン ケイザイ シンブン,カスタム名詞 +関西国際空港,関西 国際 空港,カンサイ コクサイ クウコウ,カスタム名詞 + +# Custom segmentation for compound katakana +トートバッグ,トート バッグ,トート バッグ,かずカナ名詞 +ショルダーバッグ,ショルダー バッグ,ショルダー バッグ,かずカナ名詞 + +# Custom reading for former sumo wrestler +朝青龍,朝青龍,アサショウリュウ,カスタム人名 diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/protwords.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/protwords.txt new file mode 100644 index 00000000000..1dfc0abecbf --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/protwords.txt @@ -0,0 +1,21 @@ +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#----------------------------------------------------------------------- +# Use a protected word file to protect against the stemmer reducing two +# unrelated words to the same base word. + +# Some non-words that normally won't be encountered, +# just to test that they won't be stemmed. +dontstems +zwhacky + diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/schema.xml b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/schema.xml new file mode 100644 index 00000000000..ae2c56d18ae --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/schema.xml @@ -0,0 +1,947 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/solrconfig.xml b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/solrconfig.xml new file mode 100644 index 00000000000..9d9178746cf --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/solrconfig.xml @@ -0,0 +1,1764 @@ + + + + + + + + + LUCENE_43 + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${solr.data.dir:} + + + + + + + + + + + + + + + + ${solr.maxIndexingThreads:8} + + + + + + 128 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${solr.ulog.dir:} + + + + + ${solr.autoCommit.maxTime:60000} + false + + + + + + ${solr.autoSoftCommit.maxTime:1000} + + + + + + + + + + + + + + + + + + + + 1024 + + + + + + + + + + + + + + + + + + + + + + true + + + + + + 20 + + + 200 + + + + + + + + + + + + static firstSearcher warming in solrconfig.xml + + + + + + false + + + 4 + + + + + + + + + + + + + + + + + + + + + + + explicit + 10 + text + + + + + + + + + + + + + + explicit + json + true + text + + + + + + + + true + json + true + + + + + + + + explicit + + + velocity + browse + layout + Solritas + + + edismax + + text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 + title^10.0 description^5.0 keywords^5.0 author^2.0 resourcename^1.0 + + text + 100% + *:* + 10 + *,score + + + text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 + title^10.0 description^5.0 keywords^5.0 author^2.0 resourcename^1.0 + + text,features,name,sku,id,manu,cat,title,description,keywords,author,resourcename + 3 + + + on + cat + manu_exact + content_type + author_s + ipod + GB + 1 + cat,inStock + after + price + 0 + 600 + 50 + popularity + 0 + 10 + 3 + manufacturedate_dt + NOW/YEAR-10YEARS + NOW + +1YEAR + before + after + + + on + content features title name + html + <b> + </b> + 0 + title + 0 + name + 3 + 200 + content + 750 + + + on + false + 5 + 2 + 5 + true + true + 5 + 3 + + + + + spellcheck + + + + + + + + + + + + + + application/json + + + + + application/csv + + + + + + + + + + + + + + + + + + + + + solrpingquery + + + all + + + + + + + + + explicit + true + + + + + + + + + + + + + + + + textSpell + + + + + + default + name + solr.DirectSolrSpellChecker + + internal + + 0.5 + + 2 + + 1 + + 5 + + 4 + + 0.01 + + + + + + wordbreak + solr.WordBreakSolrSpellChecker + name + true + true + 10 + + + + + + + + + + + + + + + + text + + default + wordbreak + on + true + 10 + 5 + 5 + true + true + 10 + 5 + + + spellcheck + + + + + + + + + + text + true + + + tvComponent + + + + + + + + + default + + + org.carrot2.clustering.lingo.LingoClusteringAlgorithm + + + 20 + + + clustering/carrot2 + + + ENGLISH + + + stc + org.carrot2.clustering.stc.STCClusteringAlgorithm + + + + + + + true + default + true + + name + id + + features + + true + + + + false + + edismax + + text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 + + *:* + 10 + *,score + + + clustering + + + + + + + + + + true + + + terms + + + + + + + + string + elevate.xml + + + + + + explicit + text + + + elevator + + + + + + + + + + + 100 + + + + + + + + 70 + + 0.5 + + [-\w ,/\n\"']{20,200} + + + + + + + ]]> + ]]> + + + + + + + + + + + + + + + + + + + + + + + + ,, + ,, + ,, + ,, + ,]]> + ]]> + + + + + + 10 + .,!? + + + + + + + WORD + + + en + US + + + + + + + + + + + + + + + + + + + + + + text/plain; charset=UTF-8 + + + + + + + + + 5 + + + + + + + + + + + + + + + + + + *:* + + + diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/stopwords.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/stopwords.txt new file mode 100644 index 00000000000..ae1e83eeb3d --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/stopwords.txt @@ -0,0 +1,14 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/synonyms.txt b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/synonyms.txt new file mode 100644 index 00000000000..7f72128303b --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/synonyms.txt @@ -0,0 +1,29 @@ +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#----------------------------------------------------------------------- +#some test synonym mappings unlikely to appear in real input text +aaafoo => aaabar +bbbfoo => bbbfoo bbbbar +cccfoo => cccbar cccbaz +fooaaa,baraaa,bazaaa + +# Some synonym groups specific to this example +GB,gib,gigabyte,gigabytes +MB,mib,megabyte,megabytes +Television, Televisions, TV, TVs +#notice we use "gib" instead of "GiB" so any WordDelimiterFilter coming +#after us won't split it into two words. + +# Synonym mappings can be used for spelling correction too +pixima => pixma + diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/currency.xml b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/currency.xml new file mode 100644 index 00000000000..3a9c58afee8 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/currency.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/elevate.xml b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/elevate.xml new file mode 100644 index 00000000000..25d5cebe4fb --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/elevate.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/contractions_ca.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/contractions_ca.txt new file mode 100644 index 00000000000..307a85f913d --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/contractions_ca.txt @@ -0,0 +1,8 @@ +# Set of Catalan contractions for ElisionFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +d +l +m +n +s +t diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/contractions_fr.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/contractions_fr.txt new file mode 100644 index 00000000000..722db588333 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/contractions_fr.txt @@ -0,0 +1,9 @@ +# Set of French contractions for ElisionFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +l +m +t +qu +n +s +j diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/contractions_ga.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/contractions_ga.txt new file mode 100644 index 00000000000..9ebe7fa349a --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/contractions_ga.txt @@ -0,0 +1,5 @@ +# Set of Irish contractions for ElisionFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +d +m +b diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/contractions_it.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/contractions_it.txt new file mode 100644 index 00000000000..cac04095372 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/contractions_it.txt @@ -0,0 +1,23 @@ +# Set of Italian contractions for ElisionFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +c +l +all +dall +dell +nell +sull +coll +pell +gl +agl +dagl +degl +negl +sugl +un +m +t +s +v +d diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/hyphenations_ga.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/hyphenations_ga.txt new file mode 100644 index 00000000000..4d2642cc5a3 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/hyphenations_ga.txt @@ -0,0 +1,5 @@ +# Set of Irish hyphenations for StopFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +h +n +t diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stemdict_nl.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stemdict_nl.txt new file mode 100644 index 00000000000..441072971d3 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stemdict_nl.txt @@ -0,0 +1,6 @@ +# Set of overrides for the dutch stemmer +# TODO: load this as a resource from the analyzer and sync it in build.xml +fiets fiets +bromfiets bromfiets +ei eier +kind kinder diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stoptags_ja.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stoptags_ja.txt new file mode 100644 index 00000000000..71b750845e3 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stoptags_ja.txt @@ -0,0 +1,420 @@ +# +# This file defines a Japanese stoptag set for JapanesePartOfSpeechStopFilter. +# +# Any token with a part-of-speech tag that exactly matches those defined in this +# file are removed from the token stream. +# +# Set your own stoptags by uncommenting the lines below. Note that comments are +# not allowed on the same line as a stoptag. See LUCENE-3745 for frequency lists, +# etc. that can be useful for building you own stoptag set. +# +# The entire possible tagset is provided below for convenience. +# +##### +# noun: unclassified nouns +#名詞 +# +# noun-common: Common nouns or nouns where the sub-classification is undefined +#名詞-一般 +# +# noun-proper: Proper nouns where the sub-classification is undefined +#名詞-固有名詞 +# +# noun-proper-misc: miscellaneous proper nouns +#名詞-固有名詞-一般 +# +# noun-proper-person: Personal names where the sub-classification is undefined +#名詞-固有名詞-人名 +# +# noun-proper-person-misc: names that cannot be divided into surname and +# given name; foreign names; names where the surname or given name is unknown. +# e.g. お市の方 +#名詞-固有名詞-人名-一般 +# +# noun-proper-person-surname: Mainly Japanese surnames. +# e.g. 山田 +#名詞-固有名詞-人名-姓 +# +# noun-proper-person-given_name: Mainly Japanese given names. +# e.g. 太郎 +#名詞-固有名詞-人名-名 +# +# noun-proper-organization: Names representing organizations. +# e.g. 通産省, NHK +#名詞-固有名詞-組織 +# +# noun-proper-place: Place names where the sub-classification is undefined +#名詞-固有名詞-地域 +# +# noun-proper-place-misc: Place names excluding countries. +# e.g. アジア, バルセロナ, 京都 +#名詞-固有名詞-地域-一般 +# +# noun-proper-place-country: Country names. +# e.g. 日本, オーストラリア +#名詞-固有名詞-地域-国 +# +# noun-pronoun: Pronouns where the sub-classification is undefined +#名詞-代名詞 +# +# noun-pronoun-misc: miscellaneous pronouns: +# e.g. それ, ここ, あいつ, あなた, あちこち, いくつ, どこか, なに, みなさん, みんな, わたくし, われわれ +#名詞-代名詞-一般 +# +# noun-pronoun-contraction: Spoken language contraction made by combining a +# pronoun and the particle 'wa'. +# e.g. ありゃ, こりゃ, こりゃあ, そりゃ, そりゃあ +#名詞-代名詞-縮約 +# +# noun-adverbial: Temporal nouns such as names of days or months that behave +# like adverbs. Nouns that represent amount or ratios and can be used adverbially, +# e.g. 金曜, 一月, 午後, 少量 +#名詞-副詞可能 +# +# noun-verbal: Nouns that take arguments with case and can appear followed by +# 'suru' and related verbs (する, できる, なさる, くださる) +# e.g. インプット, 愛着, 悪化, 悪戦苦闘, 一安心, 下取り +#名詞-サ変接続 +# +# noun-adjective-base: The base form of adjectives, words that appear before な ("na") +# e.g. 健康, 安易, 駄目, だめ +#名詞-形容動詞語幹 +# +# noun-numeric: Arabic numbers, Chinese numerals, and counters like 何 (回), 数. +# e.g. 0, 1, 2, 何, 数, 幾 +#名詞-数 +# +# noun-affix: noun affixes where the sub-classification is undefined +#名詞-非自立 +# +# noun-affix-misc: Of adnominalizers, the case-marker の ("no"), and words that +# attach to the base form of inflectional words, words that cannot be classified +# into any of the other categories below. This category includes indefinite nouns. +# e.g. あかつき, 暁, かい, 甲斐, 気, きらい, 嫌い, くせ, 癖, こと, 事, ごと, 毎, しだい, 次第, +# 順, せい, 所為, ついで, 序で, つもり, 積もり, 点, どころ, の, はず, 筈, はずみ, 弾み, +# 拍子, ふう, ふり, 振り, ほう, 方, 旨, もの, 物, 者, ゆえ, 故, ゆえん, 所以, わけ, 訳, +# わり, 割り, 割, ん-口語/, もん-口語/ +#名詞-非自立-一般 +# +# noun-affix-adverbial: noun affixes that that can behave as adverbs. +# e.g. あいだ, 間, あげく, 挙げ句, あと, 後, 余り, 以外, 以降, 以後, 以上, 以前, 一方, うえ, +# 上, うち, 内, おり, 折り, かぎり, 限り, きり, っきり, 結果, ころ, 頃, さい, 際, 最中, さなか, +# 最中, じたい, 自体, たび, 度, ため, 為, つど, 都度, とおり, 通り, とき, 時, ところ, 所, +# とたん, 途端, なか, 中, のち, 後, ばあい, 場合, 日, ぶん, 分, ほか, 他, まえ, 前, まま, +# 儘, 侭, みぎり, 矢先 +#名詞-非自立-副詞可能 +# +# noun-affix-aux: noun affixes treated as 助動詞 ("auxiliary verb") in school grammars +# with the stem よう(だ) ("you(da)"). +# e.g. よう, やう, 様 (よう) +#名詞-非自立-助動詞語幹 +# +# noun-affix-adjective-base: noun affixes that can connect to the indeclinable +# connection form な (aux "da"). +# e.g. みたい, ふう +#名詞-非自立-形容動詞語幹 +# +# noun-special: special nouns where the sub-classification is undefined. +#名詞-特殊 +# +# noun-special-aux: The そうだ ("souda") stem form that is used for reporting news, is +# treated as 助動詞 ("auxiliary verb") in school grammars, and attach to the base +# form of inflectional words. +# e.g. そう +#名詞-特殊-助動詞語幹 +# +# noun-suffix: noun suffixes where the sub-classification is undefined. +#名詞-接尾 +# +# noun-suffix-misc: Of the nouns or stem forms of other parts of speech that connect +# to ガル or タイ and can combine into compound nouns, words that cannot be classified into +# any of the other categories below. In general, this category is more inclusive than +# 接尾語 ("suffix") and is usually the last element in a compound noun. +# e.g. おき, かた, 方, 甲斐 (がい), がかり, ぎみ, 気味, ぐるみ, (~した) さ, 次第, 済 (ず) み, +# よう, (でき)っこ, 感, 観, 性, 学, 類, 面, 用 +#名詞-接尾-一般 +# +# noun-suffix-person: Suffixes that form nouns and attach to person names more often +# than other nouns. +# e.g. 君, 様, 著 +#名詞-接尾-人名 +# +# noun-suffix-place: Suffixes that form nouns and attach to place names more often +# than other nouns. +# e.g. 町, 市, 県 +#名詞-接尾-地域 +# +# noun-suffix-verbal: Of the suffixes that attach to nouns and form nouns, those that +# can appear before スル ("suru"). +# e.g. 化, 視, 分け, 入り, 落ち, 買い +#名詞-接尾-サ変接続 +# +# noun-suffix-aux: The stem form of そうだ (様態) that is used to indicate conditions, +# is treated as 助動詞 ("auxiliary verb") in school grammars, and attach to the +# conjunctive form of inflectional words. +# e.g. そう +#名詞-接尾-助動詞語幹 +# +# noun-suffix-adjective-base: Suffixes that attach to other nouns or the conjunctive +# form of inflectional words and appear before the copula だ ("da"). +# e.g. 的, げ, がち +#名詞-接尾-形容動詞語幹 +# +# noun-suffix-adverbial: Suffixes that attach to other nouns and can behave as adverbs. +# e.g. 後 (ご), 以後, 以降, 以前, 前後, 中, 末, 上, 時 (じ) +#名詞-接尾-副詞可能 +# +# noun-suffix-classifier: Suffixes that attach to numbers and form nouns. This category +# is more inclusive than 助数詞 ("classifier") and includes common nouns that attach +# to numbers. +# e.g. 個, つ, 本, 冊, パーセント, cm, kg, カ月, か国, 区画, 時間, 時半 +#名詞-接尾-助数詞 +# +# noun-suffix-special: Special suffixes that mainly attach to inflecting words. +# e.g. (楽し) さ, (考え) 方 +#名詞-接尾-特殊 +# +# noun-suffix-conjunctive: Nouns that behave like conjunctions and join two words +# together. +# e.g. (日本) 対 (アメリカ), 対 (アメリカ), (3) 対 (5), (女優) 兼 (主婦) +#名詞-接続詞的 +# +# noun-verbal_aux: Nouns that attach to the conjunctive particle て ("te") and are +# semantically verb-like. +# e.g. ごらん, ご覧, 御覧, 頂戴 +#名詞-動詞非自立的 +# +# noun-quotation: text that cannot be segmented into words, proverbs, Chinese poetry, +# dialects, English, etc. Currently, the only entry for 名詞 引用文字列 ("noun quotation") +# is いわく ("iwaku"). +#名詞-引用文字列 +# +# noun-nai_adjective: Words that appear before the auxiliary verb ない ("nai") and +# behave like an adjective. +# e.g. 申し訳, 仕方, とんでも, 違い +#名詞-ナイ形容詞語幹 +# +##### +# prefix: unclassified prefixes +#接頭詞 +# +# prefix-nominal: Prefixes that attach to nouns (including adjective stem forms) +# excluding numerical expressions. +# e.g. お (水), 某 (氏), 同 (社), 故 (~氏), 高 (品質), お (見事), ご (立派) +#接頭詞-名詞接続 +# +# prefix-verbal: Prefixes that attach to the imperative form of a verb or a verb +# in conjunctive form followed by なる/なさる/くださる. +# e.g. お (読みなさい), お (座り) +#接頭詞-動詞接続 +# +# prefix-adjectival: Prefixes that attach to adjectives. +# e.g. お (寒いですねえ), バカ (でかい) +#接頭詞-形容詞接続 +# +# prefix-numerical: Prefixes that attach to numerical expressions. +# e.g. 約, およそ, 毎時 +#接頭詞-数接続 +# +##### +# verb: unclassified verbs +#動詞 +# +# verb-main: +#動詞-自立 +# +# verb-auxiliary: +#動詞-非自立 +# +# verb-suffix: +#動詞-接尾 +# +##### +# adjective: unclassified adjectives +#形容詞 +# +# adjective-main: +#形容詞-自立 +# +# adjective-auxiliary: +#形容詞-非自立 +# +# adjective-suffix: +#形容詞-接尾 +# +##### +# adverb: unclassified adverbs +#副詞 +# +# adverb-misc: Words that can be segmented into one unit and where adnominal +# modification is not possible. +# e.g. あいかわらず, 多分 +#副詞-一般 +# +# adverb-particle_conjunction: Adverbs that can be followed by の, は, に, +# な, する, だ, etc. +# e.g. こんなに, そんなに, あんなに, なにか, なんでも +#副詞-助詞類接続 +# +##### +# adnominal: Words that only have noun-modifying forms. +# e.g. この, その, あの, どの, いわゆる, なんらかの, 何らかの, いろんな, こういう, そういう, ああいう, +# どういう, こんな, そんな, あんな, どんな, 大きな, 小さな, おかしな, ほんの, たいした, +# 「(, も) さる (ことながら)」, 微々たる, 堂々たる, 単なる, いかなる, 我が」「同じ, 亡き +#連体詞 +# +##### +# conjunction: Conjunctions that can occur independently. +# e.g. が, けれども, そして, じゃあ, それどころか +接続詞 +# +##### +# particle: unclassified particles. +助詞 +# +# particle-case: case particles where the subclassification is undefined. +助詞-格助詞 +# +# particle-case-misc: Case particles. +# e.g. から, が, で, と, に, へ, より, を, の, にて +助詞-格助詞-一般 +# +# particle-case-quote: the "to" that appears after nouns, a person’s speech, +# quotation marks, expressions of decisions from a meeting, reasons, judgements, +# conjectures, etc. +# e.g. ( だ) と (述べた.), ( である) と (して執行猶予...) +助詞-格助詞-引用 +# +# particle-case-compound: Compounds of particles and verbs that mainly behave +# like case particles. +# e.g. という, といった, とかいう, として, とともに, と共に, でもって, にあたって, に当たって, に当って, +# にあたり, に当たり, に当り, に当たる, にあたる, において, に於いて,に於て, における, に於ける, +# にかけ, にかけて, にかんし, に関し, にかんして, に関して, にかんする, に関する, に際し, +# に際して, にしたがい, に従い, に従う, にしたがって, に従って, にたいし, に対し, にたいして, +# に対して, にたいする, に対する, について, につき, につけ, につけて, につれ, につれて, にとって, +# にとり, にまつわる, によって, に依って, に因って, により, に依り, に因り, による, に依る, に因る, +# にわたって, にわたる, をもって, を以って, を通じ, を通じて, を通して, をめぐって, をめぐり, をめぐる, +# って-口語/, ちゅう-関西弁「という」/, (何) ていう (人)-口語/, っていう-口語/, といふ, とかいふ +助詞-格助詞-連語 +# +# particle-conjunctive: +# e.g. から, からには, が, けれど, けれども, けど, し, つつ, て, で, と, ところが, どころか, とも, ども, +# ながら, なり, ので, のに, ば, ものの, や ( した), やいなや, (ころん) じゃ(いけない)-口語/, +# (行っ) ちゃ(いけない)-口語/, (言っ) たって (しかたがない)-口語/, (それがなく)ったって (平気)-口語/ +助詞-接続助詞 +# +# particle-dependency: +# e.g. こそ, さえ, しか, すら, は, も, ぞ +助詞-係助詞 +# +# particle-adverbial: +# e.g. がてら, かも, くらい, 位, ぐらい, しも, (学校) じゃ(これが流行っている)-口語/, +# (それ)じゃあ (よくない)-口語/, ずつ, (私) なぞ, など, (私) なり (に), (先生) なんか (大嫌い)-口語/, +# (私) なんぞ, (先生) なんて (大嫌い)-口語/, のみ, だけ, (私) だって-口語/, だに, +# (彼)ったら-口語/, (お茶) でも (いかが), 等 (とう), (今後) とも, ばかり, ばっか-口語/, ばっかり-口語/, +# ほど, 程, まで, 迄, (誰) も (が)([助詞-格助詞] および [助詞-係助詞] の前に位置する「も」) +助詞-副助詞 +# +# particle-interjective: particles with interjective grammatical roles. +# e.g. (松島) や +助詞-間投助詞 +# +# particle-coordinate: +# e.g. と, たり, だの, だり, とか, なり, や, やら +助詞-並立助詞 +# +# particle-final: +# e.g. かい, かしら, さ, ぜ, (だ)っけ-口語/, (とまってる) で-方言/, な, ナ, なあ-口語/, ぞ, ね, ネ, +# ねぇ-口語/, ねえ-口語/, ねん-方言/, の, のう-口語/, や, よ, ヨ, よぉ-口語/, わ, わい-口語/ +助詞-終助詞 +# +# particle-adverbial/conjunctive/final: The particle "ka" when unknown whether it is +# adverbial, conjunctive, or sentence final. For example: +# (a) 「A か B か」. Ex:「(国内で運用する) か,(海外で運用する) か (.)」 +# (b) Inside an adverb phrase. Ex:「(幸いという) か (, 死者はいなかった.)」 +# 「(祈りが届いたせい) か (, 試験に合格した.)」 +# (c) 「かのように」. Ex:「(何もなかった) か (のように振る舞った.)」 +# e.g. か +助詞-副助詞/並立助詞/終助詞 +# +# particle-adnominalizer: The "no" that attaches to nouns and modifies +# non-inflectional words. +助詞-連体化 +# +# particle-adnominalizer: The "ni" and "to" that appear following nouns and adverbs +# that are giongo, giseigo, or gitaigo. +# e.g. に, と +助詞-副詞化 +# +# particle-special: A particle that does not fit into one of the above classifications. +# This includes particles that are used in Tanka, Haiku, and other poetry. +# e.g. かな, けむ, ( しただろう) に, (あんた) にゃ(わからん), (俺) ん (家) +助詞-特殊 +# +##### +# auxiliary-verb: +助動詞 +# +##### +# interjection: Greetings and other exclamations. +# e.g. おはよう, おはようございます, こんにちは, こんばんは, ありがとう, どうもありがとう, ありがとうございます, +# いただきます, ごちそうさま, さよなら, さようなら, はい, いいえ, ごめん, ごめんなさい +#感動詞 +# +##### +# symbol: unclassified Symbols. +記号 +# +# symbol-misc: A general symbol not in one of the categories below. +# e.g. [○◎@$〒→+] +記号-一般 +# +# symbol-comma: Commas +# e.g. [,、] +記号-読点 +# +# symbol-period: Periods and full stops. +# e.g. [..。] +記号-句点 +# +# symbol-space: Full-width whitespace. +記号-空白 +# +# symbol-open_bracket: +# e.g. [({‘“『【] +記号-括弧開 +# +# symbol-close_bracket: +# e.g. [)}’”』」】] +記号-括弧閉 +# +# symbol-alphabetic: +#記号-アルファベット +# +##### +# other: unclassified other +#その他 +# +# other-interjection: Words that are hard to classify as noun-suffixes or +# sentence-final particles. +# e.g. (だ)ァ +その他-間投 +# +##### +# filler: Aizuchi that occurs during a conversation or sounds inserted as filler. +# e.g. あの, うんと, えと +フィラー +# +##### +# non-verbal: non-verbal sound. +非言語音 +# +##### +# fragment: +#語断片 +# +##### +# unknown: unknown part of speech. +#未知語 +# +##### End of file diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_ar.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_ar.txt new file mode 100644 index 00000000000..046829db6a2 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_ar.txt @@ -0,0 +1,125 @@ +# This file was created by Jacques Savoy and is distributed under the BSD license. +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# Also see http://www.opensource.org/licenses/bsd-license.html +# Cleaned on October 11, 2009 (not normalized, so use before normalization) +# This means that when modifying this list, you might need to add some +# redundant entries, for example containing forms with both أ and ا +من +ومن +منها +منه +في +وفي +فيها +فيه +و +ف +ثم +او +أو +ب +بها +به +ا +أ +اى +اي +أي +أى +لا +ولا +الا +ألا +إلا +لكن +ما +وما +كما +فما +عن +مع +اذا +إذا +ان +أن +إن +انها +أنها +إنها +انه +أنه +إنه +بان +بأن +فان +فأن +وان +وأن +وإن +التى +التي +الذى +الذي +الذين +الى +الي +إلى +إلي +على +عليها +عليه +اما +أما +إما +ايضا +أيضا +كل +وكل +لم +ولم +لن +ولن +هى +هي +هو +وهى +وهي +وهو +فهى +فهي +فهو +انت +أنت +لك +لها +له +هذه +هذا +تلك +ذلك +هناك +كانت +كان +يكون +تكون +وكانت +وكان +غير +بعض +قد +نحو +بين +بينما +منذ +ضمن +حيث +الان +الآن +خلال +بعد +قبل +حتى +عند +عندما +لدى +جميع diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_bg.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_bg.txt new file mode 100644 index 00000000000..1ae4ba2ae38 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_bg.txt @@ -0,0 +1,193 @@ +# This file was created by Jacques Savoy and is distributed under the BSD license. +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# Also see http://www.opensource.org/licenses/bsd-license.html +а +аз +ако +ала +бе +без +беше +би +бил +била +били +било +близо +бъдат +бъде +бяха +в +вас +ваш +ваша +вероятно +вече +взема +ви +вие +винаги +все +всеки +всички +всичко +всяка +във +въпреки +върху +г +ги +главно +го +д +да +дали +до +докато +докога +дори +досега +доста +е +едва +един +ето +за +зад +заедно +заради +засега +затова +защо +защото +и +из +или +им +има +имат +иска +й +каза +как +каква +какво +както +какъв +като +кога +когато +което +които +кой +който +колко +която +къде +където +към +ли +м +ме +между +мен +ми +мнозина +мога +могат +може +моля +момента +му +н +на +над +назад +най +направи +напред +например +нас +не +него +нея +ни +ние +никой +нито +но +някои +някой +няма +обаче +около +освен +особено +от +отгоре +отново +още +пак +по +повече +повечето +под +поне +поради +после +почти +прави +пред +преди +през +при +пък +първо +с +са +само +се +сега +си +скоро +след +сме +според +сред +срещу +сте +съм +със +също +т +тази +така +такива +такъв +там +твой +те +тези +ти +тн +то +това +тогава +този +той +толкова +точно +трябва +тук +тъй +тя +тях +у +харесва +ч +че +често +чрез +ще +щом +я diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_ca.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_ca.txt new file mode 100644 index 00000000000..3da65deafe1 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_ca.txt @@ -0,0 +1,220 @@ +# Catalan stopwords from http://github.com/vcl/cue.language (Apache 2 Licensed) +a +abans +ací +ah +així +això +al +als +aleshores +algun +alguna +algunes +alguns +alhora +allà +allí +allò +altra +altre +altres +amb +ambdós +ambdues +apa +aquell +aquella +aquelles +aquells +aquest +aquesta +aquestes +aquests +aquí +baix +cada +cadascú +cadascuna +cadascunes +cadascuns +com +contra +d'un +d'una +d'unes +d'uns +dalt +de +del +dels +des +després +dins +dintre +donat +doncs +durant +e +eh +el +els +em +en +encara +ens +entre +érem +eren +éreu +es +és +esta +està +estàvem +estaven +estàveu +esteu +et +etc +ets +fins +fora +gairebé +ha +han +has +havia +he +hem +heu +hi +ho +i +igual +iguals +ja +l'hi +la +les +li +li'n +llavors +m'he +ma +mal +malgrat +mateix +mateixa +mateixes +mateixos +me +mentre +més +meu +meus +meva +meves +molt +molta +moltes +molts +mon +mons +n'he +n'hi +ne +ni +no +nogensmenys +només +nosaltres +nostra +nostre +nostres +o +oh +oi +on +pas +pel +pels +per +però +perquè +poc +poca +pocs +poques +potser +propi +qual +quals +quan +quant +que +què +quelcom +qui +quin +quina +quines +quins +s'ha +s'han +sa +semblant +semblants +ses +seu +seus +seva +seva +seves +si +sobre +sobretot +sóc +solament +sols +son +són +sons +sota +sou +t'ha +t'han +t'he +ta +tal +també +tampoc +tan +tant +tanta +tantes +teu +teus +teva +teves +ton +tons +tot +tota +totes +tots +un +una +unes +uns +us +va +vaig +vam +van +vas +veu +vosaltres +vostra +vostre +vostres diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_cz.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_cz.txt new file mode 100644 index 00000000000..53c6097dac7 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_cz.txt @@ -0,0 +1,172 @@ +a +s +k +o +i +u +v +z +dnes +cz +tímto +budeš +budem +byli +jseš +můj +svým +ta +tomto +tohle +tuto +tyto +jej +zda +proč +máte +tato +kam +tohoto +kdo +kteří +mi +nám +tom +tomuto +mít +nic +proto +kterou +byla +toho +protože +asi +ho +naši +napište +re +což +tím +takže +svých +její +svými +jste +aj +tu +tedy +teto +bylo +kde +ke +pravé +ji +nad +nejsou +či +pod +téma +mezi +přes +ty +pak +vám +ani +když +však +neg +jsem +tento +článku +články +aby +jsme +před +pta +jejich +byl +ještě +až +bez +také +pouze +první +vaše +která +nás +nový +tipy +pokud +může +strana +jeho +své +jiné +zprávy +nové +není +vás +jen +podle +zde +už +být +více +bude +již +než +který +by +které +co +nebo +ten +tak +má +při +od +po +jsou +jak +další +ale +si +se +ve +to +jako +za +zpět +ze +do +pro +je +na +atd +atp +jakmile +přičemž +já +on +ona +ono +oni +ony +my +vy +jí +ji +mě +mne +jemu +tomu +těm +těmu +němu +němuž +jehož +jíž +jelikož +jež +jakož +načež diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_da.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_da.txt new file mode 100644 index 00000000000..a3ff5fe122c --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_da.txt @@ -0,0 +1,108 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/danish/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Danish stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | This is a ranked list (commonest to rarest) of stopwords derived from + | a large text sample. + + +og | and +i | in +jeg | I +det | that (dem. pronoun)/it (pers. pronoun) +at | that (in front of a sentence)/to (with infinitive) +en | a/an +den | it (pers. pronoun)/that (dem. pronoun) +til | to/at/for/until/against/by/of/into, more +er | present tense of "to be" +som | who, as +på | on/upon/in/on/at/to/after/of/with/for, on +de | they +med | with/by/in, along +han | he +af | of/by/from/off/for/in/with/on, off +for | at/for/to/from/by/of/ago, in front/before, because +ikke | not +der | who/which, there/those +var | past tense of "to be" +mig | me/myself +sig | oneself/himself/herself/itself/themselves +men | but +et | a/an/one, one (number), someone/somebody/one +har | present tense of "to have" +om | round/about/for/in/a, about/around/down, if +vi | we +min | my +havde | past tense of "to have" +ham | him +hun | she +nu | now +over | over/above/across/by/beyond/past/on/about, over/past +da | then, when/as/since +fra | from/off/since, off, since +du | you +ud | out +sin | his/her/its/one's +dem | them +os | us/ourselves +op | up +man | you/one +hans | his +hvor | where +eller | or +hvad | what +skal | must/shall etc. +selv | myself/youself/herself/ourselves etc., even +her | here +alle | all/everyone/everybody etc. +vil | will (verb) +blev | past tense of "to stay/to remain/to get/to become" +kunne | could +ind | in +når | when +være | present tense of "to be" +dog | however/yet/after all +noget | something +ville | would +jo | you know/you see (adv), yes +deres | their/theirs +efter | after/behind/according to/for/by/from, later/afterwards +ned | down +skulle | should +denne | this +end | than +dette | this +mit | my/mine +også | also +under | under/beneath/below/during, below/underneath +have | have +dig | you +anden | other +hende | her +mine | my +alt | everything +meget | much/very, plenty of +sit | his, her, its, one's +sine | his, her, its, one's +vor | our +mod | against +disse | these +hvis | if +din | your/yours +nogle | some +hos | by/at +blive | be/become +mange | many +ad | by/through +bliver | present tense of "to be/to become" +hendes | her/hers +været | be +thi | for (conj) +jer | you +sådan | such, like this/like that diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_de.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_de.txt new file mode 100644 index 00000000000..f7703841887 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_de.txt @@ -0,0 +1,292 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/german/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A German stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | The number of forms in this list is reduced significantly by passing it + | through the German stemmer. + + +aber | but + +alle | all +allem +allen +aller +alles + +als | than, as +also | so +am | an + dem +an | at + +ander | other +andere +anderem +anderen +anderer +anderes +anderm +andern +anderr +anders + +auch | also +auf | on +aus | out of +bei | by +bin | am +bis | until +bist | art +da | there +damit | with it +dann | then + +der | the +den +des +dem +die +das + +daß | that + +derselbe | the same +derselben +denselben +desselben +demselben +dieselbe +dieselben +dasselbe + +dazu | to that + +dein | thy +deine +deinem +deinen +deiner +deines + +denn | because + +derer | of those +dessen | of him + +dich | thee +dir | to thee +du | thou + +dies | this +diese +diesem +diesen +dieser +dieses + + +doch | (several meanings) +dort | (over) there + + +durch | through + +ein | a +eine +einem +einen +einer +eines + +einig | some +einige +einigem +einigen +einiger +einiges + +einmal | once + +er | he +ihn | him +ihm | to him + +es | it +etwas | something + +euer | your +eure +eurem +euren +eurer +eures + +für | for +gegen | towards +gewesen | p.p. of sein +hab | have +habe | have +haben | have +hat | has +hatte | had +hatten | had +hier | here +hin | there +hinter | behind + +ich | I +mich | me +mir | to me + + +ihr | you, to her +ihre +ihrem +ihren +ihrer +ihres +euch | to you + +im | in + dem +in | in +indem | while +ins | in + das +ist | is + +jede | each, every +jedem +jeden +jeder +jedes + +jene | that +jenem +jenen +jener +jenes + +jetzt | now +kann | can + +kein | no +keine +keinem +keinen +keiner +keines + +können | can +könnte | could +machen | do +man | one + +manche | some, many a +manchem +manchen +mancher +manches + +mein | my +meine +meinem +meinen +meiner +meines + +mit | with +muss | must +musste | had to +nach | to(wards) +nicht | not +nichts | nothing +noch | still, yet +nun | now +nur | only +ob | whether +oder | or +ohne | without +sehr | very + +sein | his +seine +seinem +seinen +seiner +seines + +selbst | self +sich | herself + +sie | they, she +ihnen | to them + +sind | are +so | so + +solche | such +solchem +solchen +solcher +solches + +soll | shall +sollte | should +sondern | but +sonst | else +über | over +um | about, around +und | and + +uns | us +unse +unsem +unsen +unser +unses + +unter | under +viel | much +vom | von + dem +von | from +vor | before +während | while +war | was +waren | were +warst | wast +was | what +weg | away, off +weil | because +weiter | further + +welche | which +welchem +welchen +welcher +welches + +wenn | when +werde | will +werden | will +wie | how +wieder | again +will | want +wir | we +wird | will +wirst | willst +wo | where +wollen | want +wollte | wanted +würde | would +würden | would +zu | to +zum | zu + dem +zur | zu + der +zwar | indeed +zwischen | between + diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_el.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_el.txt new file mode 100644 index 00000000000..232681f5bd6 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_el.txt @@ -0,0 +1,78 @@ +# Lucene Greek Stopwords list +# Note: by default this file is used after GreekLowerCaseFilter, +# so when modifying this file use 'σ' instead of 'ς' +ο +η +το +οι +τα +του +τησ +των +τον +την +και +κι +κ +ειμαι +εισαι +ειναι +ειμαστε +ειστε +στο +στον +στη +στην +μα +αλλα +απο +για +προσ +με +σε +ωσ +παρα +αντι +κατα +μετα +θα +να +δε +δεν +μη +μην +επι +ενω +εαν +αν +τοτε +που +πωσ +ποιοσ +ποια +ποιο +ποιοι +ποιεσ +ποιων +ποιουσ +αυτοσ +αυτη +αυτο +αυτοι +αυτων +αυτουσ +αυτεσ +αυτα +εκεινοσ +εκεινη +εκεινο +εκεινοι +εκεινεσ +εκεινα +εκεινων +εκεινουσ +οπωσ +ομωσ +ισωσ +οσο +οτι diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_en.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_en.txt new file mode 100644 index 00000000000..2c164c0b2a1 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_en.txt @@ -0,0 +1,54 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# a couple of test stopwords to test that the words are really being +# configured from this file: +stopworda +stopwordb + +# Standard english stop words taken from Lucene's StopAnalyzer +a +an +and +are +as +at +be +but +by +for +if +in +into +is +it +no +not +of +on +or +such +that +the +their +then +there +these +they +this +to +was +will +with diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_es.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_es.txt new file mode 100644 index 00000000000..2db14760075 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_es.txt @@ -0,0 +1,354 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/spanish/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Spanish stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + + | The following is a ranked list (commonest to rarest) of stopwords + | deriving from a large sample of text. + + | Extra words have been added at the end. + +de | from, of +la | the, her +que | who, that +el | the +en | in +y | and +a | to +los | the, them +del | de + el +se | himself, from him etc +las | the, them +por | for, by, etc +un | a +para | for +con | with +no | no +una | a +su | his, her +al | a + el + | es from SER +lo | him +como | how +más | more +pero | pero +sus | su plural +le | to him, her +ya | already +o | or + | fue from SER +este | this + | ha from HABER +sí | himself etc +porque | because +esta | this + | son from SER +entre | between + | está from ESTAR +cuando | when +muy | very +sin | without +sobre | on + | ser from SER + | tiene from TENER +también | also +me | me +hasta | until +hay | there is/are +donde | where + | han from HABER +quien | whom, that + | están from ESTAR + | estado from ESTAR +desde | from +todo | all +nos | us +durante | during + | estados from ESTAR +todos | all +uno | a +les | to them +ni | nor +contra | against +otros | other + | fueron from SER +ese | that +eso | that + | había from HABER +ante | before +ellos | they +e | and (variant of y) +esto | this +mí | me +antes | before +algunos | some +qué | what? +unos | a +yo | I +otro | other +otras | other +otra | other +él | he +tanto | so much, many +esa | that +estos | these +mucho | much, many +quienes | who +nada | nothing +muchos | many +cual | who + | sea from SER +poco | few +ella | she +estar | to be + | haber from HABER +estas | these + | estaba from ESTAR + | estamos from ESTAR +algunas | some +algo | something +nosotros | we + + | other forms + +mi | me +mis | mi plural +tú | thou +te | thee +ti | thee +tu | thy +tus | tu plural +ellas | they +nosotras | we +vosotros | you +vosotras | you +os | you +mío | mine +mía | +míos | +mías | +tuyo | thine +tuya | +tuyos | +tuyas | +suyo | his, hers, theirs +suya | +suyos | +suyas | +nuestro | ours +nuestra | +nuestros | +nuestras | +vuestro | yours +vuestra | +vuestros | +vuestras | +esos | those +esas | those + + | forms of estar, to be (not including the infinitive): +estoy +estás +está +estamos +estáis +están +esté +estés +estemos +estéis +estén +estaré +estarás +estará +estaremos +estaréis +estarán +estaría +estarías +estaríamos +estaríais +estarían +estaba +estabas +estábamos +estabais +estaban +estuve +estuviste +estuvo +estuvimos +estuvisteis +estuvieron +estuviera +estuvieras +estuviéramos +estuvierais +estuvieran +estuviese +estuvieses +estuviésemos +estuvieseis +estuviesen +estando +estado +estada +estados +estadas +estad + + | forms of haber, to have (not including the infinitive): +he +has +ha +hemos +habéis +han +haya +hayas +hayamos +hayáis +hayan +habré +habrás +habrá +habremos +habréis +habrán +habría +habrías +habríamos +habríais +habrían +había +habías +habíamos +habíais +habían +hube +hubiste +hubo +hubimos +hubisteis +hubieron +hubiera +hubieras +hubiéramos +hubierais +hubieran +hubiese +hubieses +hubiésemos +hubieseis +hubiesen +habiendo +habido +habida +habidos +habidas + + | forms of ser, to be (not including the infinitive): +soy +eres +es +somos +sois +son +sea +seas +seamos +seáis +sean +seré +serás +será +seremos +seréis +serán +sería +serías +seríamos +seríais +serían +era +eras +éramos +erais +eran +fui +fuiste +fue +fuimos +fuisteis +fueron +fuera +fueras +fuéramos +fuerais +fueran +fuese +fueses +fuésemos +fueseis +fuesen +siendo +sido + | sed also means 'thirst' + + | forms of tener, to have (not including the infinitive): +tengo +tienes +tiene +tenemos +tenéis +tienen +tenga +tengas +tengamos +tengáis +tengan +tendré +tendrás +tendrá +tendremos +tendréis +tendrán +tendría +tendrías +tendríamos +tendríais +tendrían +tenía +tenías +teníamos +teníais +tenían +tuve +tuviste +tuvo +tuvimos +tuvisteis +tuvieron +tuviera +tuvieras +tuviéramos +tuvierais +tuvieran +tuviese +tuvieses +tuviésemos +tuvieseis +tuviesen +teniendo +tenido +tenida +tenidos +tenidas +tened + diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_eu.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_eu.txt new file mode 100644 index 00000000000..25f1db93460 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_eu.txt @@ -0,0 +1,99 @@ +# example set of basque stopwords +al +anitz +arabera +asko +baina +bat +batean +batek +bati +batzuei +batzuek +batzuetan +batzuk +bera +beraiek +berau +berauek +bere +berori +beroriek +beste +bezala +da +dago +dira +ditu +du +dute +edo +egin +ere +eta +eurak +ez +gainera +gu +gutxi +guzti +haiei +haiek +haietan +hainbeste +hala +han +handik +hango +hara +hari +hark +hartan +hau +hauei +hauek +hauetan +hemen +hemendik +hemengo +hi +hona +honek +honela +honetan +honi +hor +hori +horiei +horiek +horietan +horko +horra +horrek +horrela +horretan +horri +hortik +hura +izan +ni +noiz +nola +non +nondik +nongo +nor +nora +ze +zein +zen +zenbait +zenbat +zer +zergatik +ziren +zituen +zu +zuek +zuen +zuten diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_fa.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_fa.txt new file mode 100644 index 00000000000..723641c6da7 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_fa.txt @@ -0,0 +1,313 @@ +# This file was created by Jacques Savoy and is distributed under the BSD license. +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# Also see http://www.opensource.org/licenses/bsd-license.html +# Note: by default this file is used after normalization, so when adding entries +# to this file, use the arabic 'ي' instead of 'ی' +انان +نداشته +سراسر +خياه +ايشان +وي +تاكنون +بيشتري +دوم +پس +ناشي +وگو +يا +داشتند +سپس +هنگام +هرگز +پنج +نشان +امسال +ديگر +گروهي +شدند +چطور +ده +و +دو +نخستين +ولي +چرا +چه +وسط +ه +كدام +قابل +يك +رفت +هفت +همچنين +در +هزار +بله +بلي +شايد +اما +شناسي +گرفته +دهد +داشته +دانست +داشتن +خواهيم +ميليارد +وقتيكه +امد +خواهد +جز +اورده +شده +بلكه +خدمات +شدن +برخي +نبود +بسياري +جلوگيري +حق +كردند +نوعي +بعري +نكرده +نظير +نبايد +بوده +بودن +داد +اورد +هست +جايي +شود +دنبال +داده +بايد +سابق +هيچ +همان +انجا +كمتر +كجاست +گردد +كسي +تر +مردم +تان +دادن +بودند +سري +جدا +ندارند +مگر +يكديگر +دارد +دهند +بنابراين +هنگامي +سمت +جا +انچه +خود +دادند +زياد +دارند +اثر +بدون +بهترين +بيشتر +البته +به +براساس +بيرون +كرد +بعضي +گرفت +توي +اي +ميليون +او +جريان +تول +بر +مانند +برابر +باشيم +مدتي +گويند +اكنون +تا +تنها +جديد +چند +بي +نشده +كردن +كردم +گويد +كرده +كنيم +نمي +نزد +روي +قصد +فقط +بالاي +ديگران +اين +ديروز +توسط +سوم +ايم +دانند +سوي +استفاده +شما +كنار +داريم +ساخته +طور +امده +رفته +نخست +بيست +نزديك +طي +كنيد +از +انها +تمامي +داشت +يكي +طريق +اش +چيست +روب +نمايد +گفت +چندين +چيزي +تواند +ام +ايا +با +ان +ايد +ترين +اينكه +ديگري +راه +هايي +بروز +همچنان +پاعين +كس +حدود +مختلف +مقابل +چيز +گيرد +ندارد +ضد +همچون +سازي +شان +مورد +باره +مرسي +خويش +برخوردار +چون +خارج +شش +هنوز +تحت +ضمن +هستيم +گفته +فكر +بسيار +پيش +براي +روزهاي +انكه +نخواهد +بالا +كل +وقتي +كي +چنين +كه +گيري +نيست +است +كجا +كند +نيز +يابد +بندي +حتي +توانند +عقب +خواست +كنند +بين +تمام +همه +ما +باشند +مثل +شد +اري +باشد +اره +طبق +بعد +اگر +صورت +غير +جاي +بيش +ريزي +اند +زيرا +چگونه +بار +لطفا +مي +درباره +من +ديده +همين +گذاري +برداري +علت +گذاشته +هم +فوق +نه +ها +شوند +اباد +همواره +هر +اول +خواهند +چهار +نام +امروز +مان +هاي +قبل +كنم +سعي +تازه +را +هستند +زير +جلوي +عنوان +بود diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_fi.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_fi.txt new file mode 100644 index 00000000000..addad798c4b --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_fi.txt @@ -0,0 +1,95 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/finnish/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + +| forms of BE + +olla +olen +olet +on +olemme +olette +ovat +ole | negative form + +oli +olisi +olisit +olisin +olisimme +olisitte +olisivat +olit +olin +olimme +olitte +olivat +ollut +olleet + +en | negation +et +ei +emme +ette +eivät + +|Nom Gen Acc Part Iness Elat Illat Adess Ablat Allat Ess Trans +minä minun minut minua minussa minusta minuun minulla minulta minulle | I +sinä sinun sinut sinua sinussa sinusta sinuun sinulla sinulta sinulle | you +hän hänen hänet häntä hänessä hänestä häneen hänellä häneltä hänelle | he she +me meidän meidät meitä meissä meistä meihin meillä meiltä meille | we +te teidän teidät teitä teissä teistä teihin teillä teiltä teille | you +he heidän heidät heitä heissä heistä heihin heillä heiltä heille | they + +tämä tämän tätä tässä tästä tähän tallä tältä tälle tänä täksi | this +tuo tuon tuotä tuossa tuosta tuohon tuolla tuolta tuolle tuona tuoksi | that +se sen sitä siinä siitä siihen sillä siltä sille sinä siksi | it +nämä näiden näitä näissä näistä näihin näillä näiltä näille näinä näiksi | these +nuo noiden noita noissa noista noihin noilla noilta noille noina noiksi | those +ne niiden niitä niissä niistä niihin niillä niiltä niille niinä niiksi | they + +kuka kenen kenet ketä kenessä kenestä keneen kenellä keneltä kenelle kenenä keneksi| who +ketkä keiden ketkä keitä keissä keistä keihin keillä keiltä keille keinä keiksi | (pl) +mikä minkä minkä mitä missä mistä mihin millä miltä mille minä miksi | which what +mitkä | (pl) + +joka jonka jota jossa josta johon jolla jolta jolle jona joksi | who which +jotka joiden joita joissa joista joihin joilla joilta joille joina joiksi | (pl) + +| conjunctions + +että | that +ja | and +jos | if +koska | because +kuin | than +mutta | but +niin | so +sekä | and +sillä | for +tai | or +vaan | but +vai | or +vaikka | although + + +| prepositions + +kanssa | with +mukaan | according to +noin | about +poikki | across +yli | over, across + +| other + +kun | when +niin | so +nyt | now +itse | self + diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_fr.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_fr.txt new file mode 100644 index 00000000000..c00837ea939 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_fr.txt @@ -0,0 +1,183 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/french/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A French stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + +au | a + le +aux | a + les +avec | with +ce | this +ces | these +dans | with +de | of +des | de + les +du | de + le +elle | she +en | `of them' etc +et | and +eux | them +il | he +je | I +la | the +le | the +leur | their +lui | him +ma | my (fem) +mais | but +me | me +même | same; as in moi-même (myself) etc +mes | me (pl) +moi | me +mon | my (masc) +ne | not +nos | our (pl) +notre | our +nous | we +on | one +ou | where +par | by +pas | not +pour | for +qu | que before vowel +que | that +qui | who +sa | his, her (fem) +se | oneself +ses | his (pl) +son | his, her (masc) +sur | on +ta | thy (fem) +te | thee +tes | thy (pl) +toi | thee +ton | thy (masc) +tu | thou +un | a +une | a +vos | your (pl) +votre | your +vous | you + + | single letter forms + +c | c' +d | d' +j | j' +l | l' +à | to, at +m | m' +n | n' +s | s' +t | t' +y | there + + | forms of être (not including the infinitive): +été +étée +étées +étés +étant +suis +es +est +sommes +êtes +sont +serai +seras +sera +serons +serez +seront +serais +serait +serions +seriez +seraient +étais +était +étions +étiez +étaient +fus +fut +fûmes +fûtes +furent +sois +soit +soyons +soyez +soient +fusse +fusses +fût +fussions +fussiez +fussent + + | forms of avoir (not including the infinitive): +ayant +eu +eue +eues +eus +ai +as +avons +avez +ont +aurai +auras +aura +aurons +aurez +auront +aurais +aurait +aurions +auriez +auraient +avais +avait +avions +aviez +avaient +eut +eûmes +eûtes +eurent +aie +aies +ait +ayons +ayez +aient +eusse +eusses +eût +eussions +eussiez +eussent + + | Later additions (from Jean-Christophe Deschamps) +ceci | this +celà  | that +cet | this +cette | this +ici | here +ils | they +les | the (pl) +leurs | their (pl) +quel | which +quels | which +quelle | which +quelles | which +sans | without +soi | oneself + diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_ga.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_ga.txt new file mode 100644 index 00000000000..9ff88d747e5 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_ga.txt @@ -0,0 +1,110 @@ + +a +ach +ag +agus +an +aon +ar +arna +as +b' +ba +beirt +bhúr +caoga +ceathair +ceathrar +chomh +chtó +chuig +chun +cois +céad +cúig +cúigear +d' +daichead +dar +de +deich +deichniúr +den +dhá +do +don +dtí +dá +dár +dó +faoi +faoin +faoina +faoinár +fara +fiche +gach +gan +go +gur +haon +hocht +i +iad +idir +in +ina +ins +inár +is +le +leis +lena +lenár +m' +mar +mo +mé +na +nach +naoi +naonúr +ná +ní +níor +nó +nócha +ocht +ochtar +os +roimh +sa +seacht +seachtar +seachtó +seasca +seisear +siad +sibh +sinn +sna +sé +sí +tar +thar +thú +triúr +trí +trína +trínár +tríocha +tú +um +ár +é +éis +í +ó +ón +óna +ónár diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_gl.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_gl.txt new file mode 100644 index 00000000000..d8760b12c14 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_gl.txt @@ -0,0 +1,161 @@ +# galican stopwords +a +aínda +alí +aquel +aquela +aquelas +aqueles +aquilo +aquí +ao +aos +as +así +á +ben +cando +che +co +coa +comigo +con +connosco +contigo +convosco +coas +cos +cun +cuns +cunha +cunhas +da +dalgunha +dalgunhas +dalgún +dalgúns +das +de +del +dela +delas +deles +desde +deste +do +dos +dun +duns +dunha +dunhas +e +el +ela +elas +eles +en +era +eran +esa +esas +ese +eses +esta +estar +estaba +está +están +este +estes +estiven +estou +eu +é +facer +foi +foron +fun +había +hai +iso +isto +la +las +lle +lles +lo +los +mais +me +meu +meus +min +miña +miñas +moi +na +nas +neste +nin +no +non +nos +nosa +nosas +noso +nosos +nós +nun +nunha +nuns +nunhas +o +os +ou +ó +ós +para +pero +pode +pois +pola +polas +polo +polos +por +que +se +senón +ser +seu +seus +sexa +sido +sobre +súa +súas +tamén +tan +te +ten +teñen +teño +ter +teu +teus +ti +tido +tiña +tiven +túa +túas +un +unha +unhas +uns +vos +vosa +vosas +voso +vosos +vós diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_hi.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_hi.txt new file mode 100644 index 00000000000..86286bb083b --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_hi.txt @@ -0,0 +1,235 @@ +# Also see http://www.opensource.org/licenses/bsd-license.html +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# This file was created by Jacques Savoy and is distributed under the BSD license. +# Note: by default this file also contains forms normalized by HindiNormalizer +# for spelling variation (see section below), such that it can be used whether or +# not you enable that feature. When adding additional entries to this list, +# please add the normalized form as well. +अंदर +अत +अपना +अपनी +अपने +अभी +आदि +आप +इत्यादि +इन +इनका +इन्हीं +इन्हें +इन्हों +इस +इसका +इसकी +इसके +इसमें +इसी +इसे +उन +उनका +उनकी +उनके +उनको +उन्हीं +उन्हें +उन्हों +उस +उसके +उसी +उसे +एक +एवं +एस +ऐसे +और +कई +कर +करता +करते +करना +करने +करें +कहते +कहा +का +काफ़ी +कि +कितना +किन्हें +किन्हों +किया +किर +किस +किसी +किसे +की +कुछ +कुल +के +को +कोई +कौन +कौनसा +गया +घर +जब +जहाँ +जा +जितना +जिन +जिन्हें +जिन्हों +जिस +जिसे +जीधर +जैसा +जैसे +जो +तक +तब +तरह +तिन +तिन्हें +तिन्हों +तिस +तिसे +तो +था +थी +थे +दबारा +दिया +दुसरा +दूसरे +दो +द्वारा +न +नहीं +ना +निहायत +नीचे +ने +पर +पर +पहले +पूरा +पे +फिर +बनी +बही +बहुत +बाद +बाला +बिलकुल +भी +भीतर +मगर +मानो +मे +में +यदि +यह +यहाँ +यही +या +यिह +ये +रखें +रहा +रहे +ऱ्वासा +लिए +लिये +लेकिन +व +वर्ग +वह +वह +वहाँ +वहीं +वाले +वुह +वे +वग़ैरह +संग +सकता +सकते +सबसे +सभी +साथ +साबुत +साभ +सारा +से +सो +ही +हुआ +हुई +हुए +है +हैं +हो +होता +होती +होते +होना +होने +# additional normalized forms of the above +अपनि +जेसे +होति +सभि +तिंहों +इंहों +दवारा +इसि +किंहें +थि +उंहों +ओर +जिंहें +वहिं +अभि +बनि +हि +उंहिं +उंहें +हें +वगेरह +एसे +रवासा +कोन +निचे +काफि +उसि +पुरा +भितर +हे +बहि +वहां +कोइ +यहां +जिंहों +तिंहें +किसि +कइ +यहि +इंहिं +जिधर +इंहें +अदि +इतयादि +हुइ +कोनसा +इसकि +दुसरे +जहां +अप +किंहों +उनकि +भि +वरग +हुअ +जेसा +नहिं diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_hu.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_hu.txt new file mode 100644 index 00000000000..1a96f1db6f2 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_hu.txt @@ -0,0 +1,209 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/hungarian/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + +| Hungarian stop word list +| prepared by Anna Tordai + +a +ahogy +ahol +aki +akik +akkor +alatt +által +általában +amely +amelyek +amelyekben +amelyeket +amelyet +amelynek +ami +amit +amolyan +amíg +amikor +át +abban +ahhoz +annak +arra +arról +az +azok +azon +azt +azzal +azért +aztán +azután +azonban +bár +be +belül +benne +cikk +cikkek +cikkeket +csak +de +e +eddig +egész +egy +egyes +egyetlen +egyéb +egyik +egyre +ekkor +el +elég +ellen +elő +először +előtt +első +én +éppen +ebben +ehhez +emilyen +ennek +erre +ez +ezt +ezek +ezen +ezzel +ezért +és +fel +felé +hanem +hiszen +hogy +hogyan +igen +így +illetve +ill. +ill +ilyen +ilyenkor +ison +ismét +itt +jó +jól +jobban +kell +kellett +keresztül +keressünk +ki +kívül +között +közül +legalább +lehet +lehetett +legyen +lenne +lenni +lesz +lett +maga +magát +majd +majd +már +más +másik +meg +még +mellett +mert +mely +melyek +mi +mit +míg +miért +milyen +mikor +minden +mindent +mindenki +mindig +mint +mintha +mivel +most +nagy +nagyobb +nagyon +ne +néha +nekem +neki +nem +néhány +nélkül +nincs +olyan +ott +össze +ő +ők +őket +pedig +persze +rá +s +saját +sem +semmi +sok +sokat +sokkal +számára +szemben +szerint +szinte +talán +tehát +teljes +tovább +továbbá +több +úgy +ugyanis +új +újabb +újra +után +utána +utolsó +vagy +vagyis +valaki +valami +valamint +való +vagyok +van +vannak +volt +voltam +voltak +voltunk +vissza +vele +viszont +volna diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_hy.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_hy.txt new file mode 100644 index 00000000000..60c1c50fbc8 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_hy.txt @@ -0,0 +1,46 @@ +# example set of Armenian stopwords. +այդ +այլ +այն +այս +դու +դուք +եմ +են +ենք +ես +եք +է +էի +էին +էինք +էիր +էիք +էր +ըստ +թ +ի +ին +իսկ +իր +կամ +համար +հետ +հետո +մենք +մեջ +մի +ն +նա +նաև +նրա +նրանք +որ +որը +որոնք +որպես +ու +ում +պիտի +վրա +և diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_id.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_id.txt new file mode 100644 index 00000000000..4617f83a5c5 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_id.txt @@ -0,0 +1,359 @@ +# from appendix D of: A Study of Stemming Effects on Information +# Retrieval in Bahasa Indonesia +ada +adanya +adalah +adapun +agak +agaknya +agar +akan +akankah +akhirnya +aku +akulah +amat +amatlah +anda +andalah +antar +diantaranya +antara +antaranya +diantara +apa +apaan +mengapa +apabila +apakah +apalagi +apatah +atau +ataukah +ataupun +bagai +bagaikan +sebagai +sebagainya +bagaimana +bagaimanapun +sebagaimana +bagaimanakah +bagi +bahkan +bahwa +bahwasanya +sebaliknya +banyak +sebanyak +beberapa +seberapa +begini +beginian +beginikah +beginilah +sebegini +begitu +begitukah +begitulah +begitupun +sebegitu +belum +belumlah +sebelum +sebelumnya +sebenarnya +berapa +berapakah +berapalah +berapapun +betulkah +sebetulnya +biasa +biasanya +bila +bilakah +bisa +bisakah +sebisanya +boleh +bolehkah +bolehlah +buat +bukan +bukankah +bukanlah +bukannya +cuma +percuma +dahulu +dalam +dan +dapat +dari +daripada +dekat +demi +demikian +demikianlah +sedemikian +dengan +depan +di +dia +dialah +dini +diri +dirinya +terdiri +dong +dulu +enggak +enggaknya +entah +entahlah +terhadap +terhadapnya +hal +hampir +hanya +hanyalah +harus +haruslah +harusnya +seharusnya +hendak +hendaklah +hendaknya +hingga +sehingga +ia +ialah +ibarat +ingin +inginkah +inginkan +ini +inikah +inilah +itu +itukah +itulah +jangan +jangankan +janganlah +jika +jikalau +juga +justru +kala +kalau +kalaulah +kalaupun +kalian +kami +kamilah +kamu +kamulah +kan +kapan +kapankah +kapanpun +dikarenakan +karena +karenanya +ke +kecil +kemudian +kenapa +kepada +kepadanya +ketika +seketika +khususnya +kini +kinilah +kiranya +sekiranya +kita +kitalah +kok +lagi +lagian +selagi +lah +lain +lainnya +melainkan +selaku +lalu +melalui +terlalu +lama +lamanya +selama +selama +selamanya +lebih +terlebih +bermacam +macam +semacam +maka +makanya +makin +malah +malahan +mampu +mampukah +mana +manakala +manalagi +masih +masihkah +semasih +masing +mau +maupun +semaunya +memang +mereka +merekalah +meski +meskipun +semula +mungkin +mungkinkah +nah +namun +nanti +nantinya +nyaris +oleh +olehnya +seorang +seseorang +pada +padanya +padahal +paling +sepanjang +pantas +sepantasnya +sepantasnyalah +para +pasti +pastilah +per +pernah +pula +pun +merupakan +rupanya +serupa +saat +saatnya +sesaat +saja +sajalah +saling +bersama +sama +sesama +sambil +sampai +sana +sangat +sangatlah +saya +sayalah +se +sebab +sebabnya +sebuah +tersebut +tersebutlah +sedang +sedangkan +sedikit +sedikitnya +segala +segalanya +segera +sesegera +sejak +sejenak +sekali +sekalian +sekalipun +sesekali +sekaligus +sekarang +sekarang +sekitar +sekitarnya +sela +selain +selalu +seluruh +seluruhnya +semakin +sementara +sempat +semua +semuanya +sendiri +sendirinya +seolah +seperti +sepertinya +sering +seringnya +serta +siapa +siapakah +siapapun +disini +disinilah +sini +sinilah +sesuatu +sesuatunya +suatu +sesudah +sesudahnya +sudah +sudahkah +sudahlah +supaya +tadi +tadinya +tak +tanpa +setelah +telah +tentang +tentu +tentulah +tentunya +tertentu +seterusnya +tapi +tetapi +setiap +tiap +setidaknya +tidak +tidakkah +tidaklah +toh +waduh +wah +wahai +sewaktu +walau +walaupun +wong +yaitu +yakni +yang diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_it.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_it.txt new file mode 100644 index 00000000000..4cb5b0891b1 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_it.txt @@ -0,0 +1,301 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/italian/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | An Italian stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + +ad | a (to) before vowel +al | a + il +allo | a + lo +ai | a + i +agli | a + gli +all | a + l' +agl | a + gl' +alla | a + la +alle | a + le +con | with +col | con + il +coi | con + i (forms collo, cogli etc are now very rare) +da | from +dal | da + il +dallo | da + lo +dai | da + i +dagli | da + gli +dall | da + l' +dagl | da + gll' +dalla | da + la +dalle | da + le +di | of +del | di + il +dello | di + lo +dei | di + i +degli | di + gli +dell | di + l' +degl | di + gl' +della | di + la +delle | di + le +in | in +nel | in + el +nello | in + lo +nei | in + i +negli | in + gli +nell | in + l' +negl | in + gl' +nella | in + la +nelle | in + le +su | on +sul | su + il +sullo | su + lo +sui | su + i +sugli | su + gli +sull | su + l' +sugl | su + gl' +sulla | su + la +sulle | su + le +per | through, by +tra | among +contro | against +io | I +tu | thou +lui | he +lei | she +noi | we +voi | you +loro | they +mio | my +mia | +miei | +mie | +tuo | +tua | +tuoi | thy +tue | +suo | +sua | +suoi | his, her +sue | +nostro | our +nostra | +nostri | +nostre | +vostro | your +vostra | +vostri | +vostre | +mi | me +ti | thee +ci | us, there +vi | you, there +lo | him, the +la | her, the +li | them +le | them, the +gli | to him, the +ne | from there etc +il | the +un | a +uno | a +una | a +ma | but +ed | and +se | if +perché | why, because +anche | also +come | how +dov | where (as dov') +dove | where +che | who, that +chi | who +cui | whom +non | not +più | more +quale | who, that +quanto | how much +quanti | +quanta | +quante | +quello | that +quelli | +quella | +quelle | +questo | this +questi | +questa | +queste | +si | yes +tutto | all +tutti | all + + | single letter forms: + +a | at +c | as c' for ce or ci +e | and +i | the +l | as l' +o | or + + | forms of avere, to have (not including the infinitive): + +ho +hai +ha +abbiamo +avete +hanno +abbia +abbiate +abbiano +avrò +avrai +avrà +avremo +avrete +avranno +avrei +avresti +avrebbe +avremmo +avreste +avrebbero +avevo +avevi +aveva +avevamo +avevate +avevano +ebbi +avesti +ebbe +avemmo +aveste +ebbero +avessi +avesse +avessimo +avessero +avendo +avuto +avuta +avuti +avute + + | forms of essere, to be (not including the infinitive): +sono +sei +è +siamo +siete +sia +siate +siano +sarò +sarai +sarà +saremo +sarete +saranno +sarei +saresti +sarebbe +saremmo +sareste +sarebbero +ero +eri +era +eravamo +eravate +erano +fui +fosti +fu +fummo +foste +furono +fossi +fosse +fossimo +fossero +essendo + + | forms of fare, to do (not including the infinitive, fa, fat-): +faccio +fai +facciamo +fanno +faccia +facciate +facciano +farò +farai +farà +faremo +farete +faranno +farei +faresti +farebbe +faremmo +fareste +farebbero +facevo +facevi +faceva +facevamo +facevate +facevano +feci +facesti +fece +facemmo +faceste +fecero +facessi +facesse +facessimo +facessero +facendo + + | forms of stare, to be (not including the infinitive): +sto +stai +sta +stiamo +stanno +stia +stiate +stiano +starò +starai +starà +staremo +starete +staranno +starei +staresti +starebbe +staremmo +stareste +starebbero +stavo +stavi +stava +stavamo +stavate +stavano +stetti +stesti +stette +stemmo +steste +stettero +stessi +stesse +stessimo +stessero +stando diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_ja.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_ja.txt new file mode 100644 index 00000000000..d4321be6b16 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_ja.txt @@ -0,0 +1,127 @@ +# +# This file defines a stopword set for Japanese. +# +# This set is made up of hand-picked frequent terms from segmented Japanese Wikipedia. +# Punctuation characters and frequent kanji have mostly been left out. See LUCENE-3745 +# for frequency lists, etc. that can be useful for making your own set (if desired) +# +# Note that there is an overlap between these stopwords and the terms stopped when used +# in combination with the JapanesePartOfSpeechStopFilter. When editing this file, note +# that comments are not allowed on the same line as stopwords. +# +# Also note that stopping is done in a case-insensitive manner. Change your StopFilter +# configuration if you need case-sensitive stopping. Lastly, note that stopping is done +# using the same character width as the entries in this file. Since this StopFilter is +# normally done after a CJKWidthFilter in your chain, you would usually want your romaji +# entries to be in half-width and your kana entries to be in full-width. +# +の +に +は +を +た +が +で +て +と +し +れ +さ +ある +いる +も +する +から +な +こと +として +い +や +れる +など +なっ +ない +この +ため +その +あっ +よう +また +もの +という +あり +まで +られ +なる +へ +か +だ +これ +によって +により +おり +より +による +ず +なり +られる +において +ば +なかっ +なく +しかし +について +せ +だっ +その後 +できる +それ +う +ので +なお +のみ +でき +き +つ +における +および +いう +さらに +でも +ら +たり +その他 +に関する +たち +ます +ん +なら +に対して +特に +せる +及び +これら +とき +では +にて +ほか +ながら +うち +そして +とともに +ただし +かつて +それぞれ +または +お +ほど +ものの +に対する +ほとんど +と共に +といった +です +とも +ところ +ここ +##### End of file diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_lv.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_lv.txt new file mode 100644 index 00000000000..e21a23c06c3 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_lv.txt @@ -0,0 +1,172 @@ +# Set of Latvian stopwords from A Stemming Algorithm for Latvian, Karlis Kreslins +# the original list of over 800 forms was refined: +# pronouns, adverbs, interjections were removed +# +# prepositions +aiz +ap +ar +apakš +ārpus +augšpus +bez +caur +dēļ +gar +iekš +iz +kopš +labad +lejpus +līdz +no +otrpus +pa +par +pār +pēc +pie +pirms +pret +priekš +starp +šaipus +uz +viņpus +virs +virspus +zem +apakšpus +# Conjunctions +un +bet +jo +ja +ka +lai +tomēr +tikko +turpretī +arī +kaut +gan +tādēļ +tā +ne +tikvien +vien +kā +ir +te +vai +kamēr +# Particles +ar +diezin +droši +diemžēl +nebūt +ik +it +taču +nu +pat +tiklab +iekšpus +nedz +tik +nevis +turpretim +jeb +iekam +iekām +iekāms +kolīdz +līdzko +tiklīdz +jebšu +tālab +tāpēc +nekā +itin +jā +jau +jel +nē +nezin +tad +tikai +vis +tak +iekams +vien +# modal verbs +būt +biju +biji +bija +bijām +bijāt +esmu +esi +esam +esat +būšu +būsi +būs +būsim +būsiet +tikt +tiku +tiki +tika +tikām +tikāt +tieku +tiec +tiek +tiekam +tiekat +tikšu +tiks +tiksim +tiksiet +tapt +tapi +tapāt +topat +tapšu +tapsi +taps +tapsim +tapsiet +kļūt +kļuvu +kļuvi +kļuva +kļuvām +kļuvāt +kļūstu +kļūsti +kļūst +kļūstam +kļūstat +kļūšu +kļūsi +kļūs +kļūsim +kļūsiet +# verbs +varēt +varēju +varējām +varēšu +varēsim +var +varēji +varējāt +varēsi +varēsiet +varat +varēja +varēs diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_nl.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_nl.txt new file mode 100644 index 00000000000..f4d61f5092c --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_nl.txt @@ -0,0 +1,117 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/dutch/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Dutch stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | This is a ranked list (commonest to rarest) of stopwords derived from + | a large sample of Dutch text. + + | Dutch stop words frequently exhibit homonym clashes. These are indicated + | clearly below. + +de | the +en | and +van | of, from +ik | I, the ego +te | (1) chez, at etc, (2) to, (3) too +dat | that, which +die | that, those, who, which +in | in, inside +een | a, an, one +hij | he +het | the, it +niet | not, nothing, naught +zijn | (1) to be, being, (2) his, one's, its +is | is +was | (1) was, past tense of all persons sing. of 'zijn' (to be) (2) wax, (3) the washing, (4) rise of river +op | on, upon, at, in, up, used up +aan | on, upon, to (as dative) +met | with, by +als | like, such as, when +voor | (1) before, in front of, (2) furrow +had | had, past tense all persons sing. of 'hebben' (have) +er | there +maar | but, only +om | round, about, for etc +hem | him +dan | then +zou | should/would, past tense all persons sing. of 'zullen' +of | or, whether, if +wat | what, something, anything +mijn | possessive and noun 'mine' +men | people, 'one' +dit | this +zo | so, thus, in this way +door | through by +over | over, across +ze | she, her, they, them +zich | oneself +bij | (1) a bee, (2) by, near, at +ook | also, too +tot | till, until +je | you +mij | me +uit | out of, from +der | Old Dutch form of 'van der' still found in surnames +daar | (1) there, (2) because +haar | (1) her, their, them, (2) hair +naar | (1) unpleasant, unwell etc, (2) towards, (3) as +heb | present first person sing. of 'to have' +hoe | how, why +heeft | present third person sing. of 'to have' +hebben | 'to have' and various parts thereof +deze | this +u | you +want | (1) for, (2) mitten, (3) rigging +nog | yet, still +zal | 'shall', first and third person sing. of verb 'zullen' (will) +me | me +zij | she, they +nu | now +ge | 'thou', still used in Belgium and south Netherlands +geen | none +omdat | because +iets | something, somewhat +worden | to become, grow, get +toch | yet, still +al | all, every, each +waren | (1) 'were' (2) to wander, (3) wares, (3) +veel | much, many +meer | (1) more, (2) lake +doen | to do, to make +toen | then, when +moet | noun 'spot/mote' and present form of 'to must' +ben | (1) am, (2) 'are' in interrogative second person singular of 'to be' +zonder | without +kan | noun 'can' and present form of 'to be able' +hun | their, them +dus | so, consequently +alles | all, everything, anything +onder | under, beneath +ja | yes, of course +eens | once, one day +hier | here +wie | who +werd | imperfect third person sing. of 'become' +altijd | always +doch | yet, but etc +wordt | present third person sing. of 'become' +wezen | (1) to be, (2) 'been' as in 'been fishing', (3) orphans +kunnen | to be able +ons | us/our +zelf | self +tegen | against, towards, at +na | after, near +reeds | already +wil | (1) present tense of 'want', (2) 'will', noun, (3) fender +kon | could; past tense of 'to be able' +niets | nothing +uw | your +iemand | somebody +geweest | been; past participle of 'be' +andere | other diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_no.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_no.txt new file mode 100644 index 00000000000..e76f36e69ed --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_no.txt @@ -0,0 +1,192 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/norwegian/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Norwegian stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | This stop word list is for the dominant bokmål dialect. Words unique + | to nynorsk are marked *. + + | Revised by Jan Bruusgaard , Jan 2005 + +og | and +i | in +jeg | I +det | it/this/that +at | to (w. inf.) +en | a/an +et | a/an +den | it/this/that +til | to +er | is/am/are +som | who/that +på | on +de | they / you(formal) +med | with +han | he +av | of +ikke | not +ikkje | not * +der | there +så | so +var | was/were +meg | me +seg | you +men | but +ett | one +har | have +om | about +vi | we +min | my +mitt | my +ha | have +hadde | had +hun | she +nå | now +over | over +da | when/as +ved | by/know +fra | from +du | you +ut | out +sin | your +dem | them +oss | us +opp | up +man | you/one +kan | can +hans | his +hvor | where +eller | or +hva | what +skal | shall/must +selv | self (reflective) +sjøl | self (reflective) +her | here +alle | all +vil | will +bli | become +ble | became +blei | became * +blitt | have become +kunne | could +inn | in +når | when +være | be +kom | come +noen | some +noe | some +ville | would +dere | you +som | who/which/that +deres | their/theirs +kun | only/just +ja | yes +etter | after +ned | down +skulle | should +denne | this +for | for/because +deg | you +si | hers/his +sine | hers/his +sitt | hers/his +mot | against +å | to +meget | much +hvorfor | why +dette | this +disse | these/those +uten | without +hvordan | how +ingen | none +din | your +ditt | your +blir | become +samme | same +hvilken | which +hvilke | which (plural) +sånn | such a +inni | inside/within +mellom | between +vår | our +hver | each +hvem | who +vors | us/ours +hvis | whose +både | both +bare | only/just +enn | than +fordi | as/because +før | before +mange | many +også | also +slik | just +vært | been +være | to be +båe | both * +begge | both +siden | since +dykk | your * +dykkar | yours * +dei | they * +deira | them * +deires | theirs * +deim | them * +di | your (fem.) * +då | as/when * +eg | I * +ein | a/an * +eit | a/an * +eitt | a/an * +elles | or * +honom | he * +hjå | at * +ho | she * +hoe | she * +henne | her +hennar | her/hers +hennes | hers +hoss | how * +hossen | how * +ikkje | not * +ingi | noone * +inkje | noone * +korleis | how * +korso | how * +kva | what/which * +kvar | where * +kvarhelst | where * +kven | who/whom * +kvi | why * +kvifor | why * +me | we * +medan | while * +mi | my * +mine | my * +mykje | much * +no | now * +nokon | some (masc./neut.) * +noka | some (fem.) * +nokor | some * +noko | some * +nokre | some * +si | his/hers * +sia | since * +sidan | since * +so | so * +somt | some * +somme | some * +um | about* +upp | up * +vere | be * +vore | was * +verte | become * +vort | become * +varte | became * +vart | became * + diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_pt.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_pt.txt new file mode 100644 index 00000000000..276c1b446f2 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_pt.txt @@ -0,0 +1,251 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/portuguese/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Portuguese stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + + | The following is a ranked list (commonest to rarest) of stopwords + | deriving from a large sample of text. + + | Extra words have been added at the end. + +de | of, from +a | the; to, at; her +o | the; him +que | who, that +e | and +do | de + o +da | de + a +em | in +um | a +para | for + | é from SER +com | with +não | not, no +uma | a +os | the; them +no | em + o +se | himself etc +na | em + a +por | for +mais | more +as | the; them +dos | de + os +como | as, like +mas | but + | foi from SER +ao | a + o +ele | he +das | de + as + | tem from TER +à | a + a +seu | his +sua | her +ou | or + | ser from SER +quando | when +muito | much + | há from HAV +nos | em + os; us +já | already, now + | está from EST +eu | I +também | also +só | only, just +pelo | per + o +pela | per + a +até | up to +isso | that +ela | he +entre | between + | era from SER +depois | after +sem | without +mesmo | same +aos | a + os + | ter from TER +seus | his +quem | whom +nas | em + as +me | me +esse | that +eles | they + | estão from EST +você | you + | tinha from TER + | foram from SER +essa | that +num | em + um +nem | nor +suas | her +meu | my +às | a + as +minha | my + | têm from TER +numa | em + uma +pelos | per + os +elas | they + | havia from HAV + | seja from SER +qual | which + | será from SER +nós | we + | tenho from TER +lhe | to him, her +deles | of them +essas | those +esses | those +pelas | per + as +este | this + | fosse from SER +dele | of him + + | other words. There are many contractions such as naquele = em+aquele, + | mo = me+o, but they are rare. + | Indefinite article plural forms are also rare. + +tu | thou +te | thee +vocês | you (plural) +vos | you +lhes | to them +meus | my +minhas +teu | thy +tua +teus +tuas +nosso | our +nossa +nossos +nossas + +dela | of her +delas | of them + +esta | this +estes | these +estas | these +aquele | that +aquela | that +aqueles | those +aquelas | those +isto | this +aquilo | that + + | forms of estar, to be (not including the infinitive): +estou +está +estamos +estão +estive +esteve +estivemos +estiveram +estava +estávamos +estavam +estivera +estivéramos +esteja +estejamos +estejam +estivesse +estivéssemos +estivessem +estiver +estivermos +estiverem + + | forms of haver, to have (not including the infinitive): +hei +há +havemos +hão +houve +houvemos +houveram +houvera +houvéramos +haja +hajamos +hajam +houvesse +houvéssemos +houvessem +houver +houvermos +houverem +houverei +houverá +houveremos +houverão +houveria +houveríamos +houveriam + + | forms of ser, to be (not including the infinitive): +sou +somos +são +era +éramos +eram +fui +foi +fomos +foram +fora +fôramos +seja +sejamos +sejam +fosse +fôssemos +fossem +for +formos +forem +serei +será +seremos +serão +seria +seríamos +seriam + + | forms of ter, to have (not including the infinitive): +tenho +tem +temos +tém +tinha +tínhamos +tinham +tive +teve +tivemos +tiveram +tivera +tivéramos +tenha +tenhamos +tenham +tivesse +tivéssemos +tivessem +tiver +tivermos +tiverem +terei +terá +teremos +terão +teria +teríamos +teriam diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_ro.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_ro.txt new file mode 100644 index 00000000000..4fdee90a5ba --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_ro.txt @@ -0,0 +1,233 @@ +# This file was created by Jacques Savoy and is distributed under the BSD license. +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# Also see http://www.opensource.org/licenses/bsd-license.html +acea +aceasta +această +aceea +acei +aceia +acel +acela +acele +acelea +acest +acesta +aceste +acestea +aceşti +aceştia +acolo +acum +ai +aia +aibă +aici +al +ăla +ale +alea +ălea +altceva +altcineva +am +ar +are +aş +aşadar +asemenea +asta +ăsta +astăzi +astea +ăstea +ăştia +asupra +aţi +au +avea +avem +aveţi +azi +bine +bucur +bună +ca +că +căci +când +care +cărei +căror +cărui +cât +câte +câţi +către +câtva +ce +cel +ceva +chiar +cînd +cine +cineva +cît +cîte +cîţi +cîtva +contra +cu +cum +cumva +curând +curînd +da +dă +dacă +dar +datorită +de +deci +deja +deoarece +departe +deşi +din +dinaintea +dintr +dintre +drept +după +ea +ei +el +ele +eram +este +eşti +eu +face +fără +fi +fie +fiecare +fii +fim +fiţi +iar +ieri +îi +îl +îmi +împotriva +în +înainte +înaintea +încât +încît +încotro +între +întrucât +întrucît +îţi +la +lângă +le +li +lîngă +lor +lui +mă +mâine +mea +mei +mele +mereu +meu +mi +mine +mult +multă +mulţi +ne +nicăieri +nici +nimeni +nişte +noastră +noastre +noi +noştri +nostru +nu +ori +oricând +oricare +oricât +orice +oricînd +oricine +oricît +oricum +oriunde +până +pe +pentru +peste +pînă +poate +pot +prea +prima +primul +prin +printr +sa +să +săi +sale +sau +său +se +şi +sînt +sîntem +sînteţi +spre +sub +sunt +suntem +sunteţi +ta +tăi +tale +tău +te +ţi +ţie +tine +toată +toate +tot +toţi +totuşi +tu +un +una +unde +undeva +unei +unele +uneori +unor +vă +vi +voastră +voastre +voi +voştri +vostru +vouă +vreo +vreun diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_ru.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_ru.txt new file mode 100644 index 00000000000..64307693457 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_ru.txt @@ -0,0 +1,241 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/russian/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | a russian stop word list. comments begin with vertical bar. each stop + | word is at the start of a line. + + | this is a ranked list (commonest to rarest) of stopwords derived from + | a large text sample. + + | letter `ё' is translated to `е'. + +и | and +в | in/into +во | alternative form +не | not +что | what/that +он | he +на | on/onto +я | i +с | from +со | alternative form +как | how +а | milder form of `no' (but) +то | conjunction and form of `that' +все | all +она | she +так | so, thus +его | him +но | but +да | yes/and +ты | thou +к | towards, by +у | around, chez +же | intensifier particle +вы | you +за | beyond, behind +бы | conditional/subj. particle +по | up to, along +только | only +ее | her +мне | to me +было | it was +вот | here is/are, particle +от | away from +меня | me +еще | still, yet, more +нет | no, there isnt/arent +о | about +из | out of +ему | to him +теперь | now +когда | when +даже | even +ну | so, well +вдруг | suddenly +ли | interrogative particle +если | if +уже | already, but homonym of `narrower' +или | or +ни | neither +быть | to be +был | he was +него | prepositional form of его +до | up to +вас | you accusative +нибудь | indef. suffix preceded by hyphen +опять | again +уж | already, but homonym of `adder' +вам | to you +сказал | he said +ведь | particle `after all' +там | there +потом | then +себя | oneself +ничего | nothing +ей | to her +может | usually with `быть' as `maybe' +они | they +тут | here +где | where +есть | there is/are +надо | got to, must +ней | prepositional form of ей +для | for +мы | we +тебя | thee +их | them, their +чем | than +была | she was +сам | self +чтоб | in order to +без | without +будто | as if +человек | man, person, one +чего | genitive form of `what' +раз | once +тоже | also +себе | to oneself +под | beneath +жизнь | life +будет | will be +ж | short form of intensifer particle `же' +тогда | then +кто | who +этот | this +говорил | was saying +того | genitive form of `that' +потому | for that reason +этого | genitive form of `this' +какой | which +совсем | altogether +ним | prepositional form of `его', `они' +здесь | here +этом | prepositional form of `этот' +один | one +почти | almost +мой | my +тем | instrumental/dative plural of `тот', `то' +чтобы | full form of `in order that' +нее | her (acc.) +кажется | it seems +сейчас | now +были | they were +куда | where to +зачем | why +сказать | to say +всех | all (acc., gen. preposn. plural) +никогда | never +сегодня | today +можно | possible, one can +при | by +наконец | finally +два | two +об | alternative form of `о', about +другой | another +хоть | even +после | after +над | above +больше | more +тот | that one (masc.) +через | across, in +эти | these +нас | us +про | about +всего | in all, only, of all +них | prepositional form of `они' (they) +какая | which, feminine +много | lots +разве | interrogative particle +сказала | she said +три | three +эту | this, acc. fem. sing. +моя | my, feminine +впрочем | moreover, besides +хорошо | good +свою | ones own, acc. fem. sing. +этой | oblique form of `эта', fem. `this' +перед | in front of +иногда | sometimes +лучше | better +чуть | a little +том | preposn. form of `that one' +нельзя | one must not +такой | such a one +им | to them +более | more +всегда | always +конечно | of course +всю | acc. fem. sing of `all' +между | between + + + | b: some paradigms + | + | personal pronouns + | + | я меня мне мной [мною] + | ты тебя тебе тобой [тобою] + | он его ему им [него, нему, ним] + | она ее эи ею [нее, нэи, нею] + | оно его ему им [него, нему, ним] + | + | мы нас нам нами + | вы вас вам вами + | они их им ими [них, ним, ними] + | + | себя себе собой [собою] + | + | demonstrative pronouns: этот (this), тот (that) + | + | этот эта это эти + | этого эты это эти + | этого этой этого этих + | этому этой этому этим + | этим этой этим [этою] этими + | этом этой этом этих + | + | тот та то те + | того ту то те + | того той того тех + | тому той тому тем + | тем той тем [тою] теми + | том той том тех + | + | determinative pronouns + | + | (a) весь (all) + | + | весь вся все все + | всего всю все все + | всего всей всего всех + | всему всей всему всем + | всем всей всем [всею] всеми + | всем всей всем всех + | + | (b) сам (himself etc) + | + | сам сама само сами + | самого саму само самих + | самого самой самого самих + | самому самой самому самим + | самим самой самим [самою] самими + | самом самой самом самих + | + | stems of verbs `to be', `to have', `to do' and modal + | + | быть бы буд быв есть суть + | име + | дел + | мог мож мочь + | уме + | хоч хот + | долж + | можн + | нужн + | нельзя + diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_sv.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_sv.txt new file mode 100644 index 00000000000..22bddfd8cb3 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_sv.txt @@ -0,0 +1,131 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/swedish/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Swedish stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | This is a ranked list (commonest to rarest) of stopwords derived from + | a large text sample. + + | Swedish stop words occasionally exhibit homonym clashes. For example + | så = so, but also seed. These are indicated clearly below. + +och | and +det | it, this/that +att | to (with infinitive) +i | in, at +en | a +jag | I +hon | she +som | who, that +han | he +på | on +den | it, this/that +med | with +var | where, each +sig | him(self) etc +för | for +så | so (also: seed) +till | to +är | is +men | but +ett | a +om | if; around, about +hade | had +de | they, these/those +av | of +icke | not, no +mig | me +du | you +henne | her +då | then, when +sin | his +nu | now +har | have +inte | inte någon = no one +hans | his +honom | him +skulle | 'sake' +hennes | her +där | there +min | my +man | one (pronoun) +ej | nor +vid | at, by, on (also: vast) +kunde | could +något | some etc +från | from, off +ut | out +när | when +efter | after, behind +upp | up +vi | we +dem | them +vara | be +vad | what +över | over +än | than +dig | you +kan | can +sina | his +här | here +ha | have +mot | towards +alla | all +under | under (also: wonder) +någon | some etc +eller | or (else) +allt | all +mycket | much +sedan | since +ju | why +denna | this/that +själv | myself, yourself etc +detta | this/that +åt | to +utan | without +varit | was +hur | how +ingen | no +mitt | my +ni | you +bli | to be, become +blev | from bli +oss | us +din | thy +dessa | these/those +några | some etc +deras | their +blir | from bli +mina | my +samma | (the) same +vilken | who, that +er | you, your +sådan | such a +vår | our +blivit | from bli +dess | its +inom | within +mellan | between +sådant | such a +varför | why +varje | each +vilka | who, that +ditt | thy +vem | who +vilket | who, that +sitta | his +sådana | such a +vart | each +dina | thy +vars | whose +vårt | our +våra | our +ert | your +era | your +vilkas | whose + diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_th.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_th.txt new file mode 100644 index 00000000000..07f0fabe692 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_th.txt @@ -0,0 +1,119 @@ +# Thai stopwords from: +# "Opinion Detection in Thai Political News Columns +# Based on Subjectivity Analysis" +# Khampol Sukhum, Supot Nitsuwat, and Choochart Haruechaiyasak +ไว้ +ไม่ +ไป +ได้ +ให้ +ใน +โดย +แห่ง +แล้ว +และ +แรก +แบบ +แต่ +เอง +เห็น +เลย +เริ่ม +เรา +เมื่อ +เพื่อ +เพราะ +เป็นการ +เป็น +เปิดเผย +เปิด +เนื่องจาก +เดียวกัน +เดียว +เช่น +เฉพาะ +เคย +เข้า +เขา +อีก +อาจ +อะไร +ออก +อย่าง +อยู่ +อยาก +หาก +หลาย +หลังจาก +หลัง +หรือ +หนึ่ง +ส่วน +ส่ง +สุด +สําหรับ +ว่า +วัน +ลง +ร่วม +ราย +รับ +ระหว่าง +รวม +ยัง +มี +มาก +มา +พร้อม +พบ +ผ่าน +ผล +บาง +น่า +นี้ +นํา +นั้น +นัก +นอกจาก +ทุก +ที่สุด +ที่ +ทําให้ +ทํา +ทาง +ทั้งนี้ +ทั้ง +ถ้า +ถูก +ถึง +ต้อง +ต่างๆ +ต่าง +ต่อ +ตาม +ตั้งแต่ +ตั้ง +ด้าน +ด้วย +ดัง +ซึ่ง +ช่วง +จึง +จาก +จัด +จะ +คือ +ความ +ครั้ง +คง +ขึ้น +ของ +ขอ +ขณะ +ก่อน +ก็ +การ +กับ +กัน +กว่า +กล่าว diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_tr.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_tr.txt new file mode 100644 index 00000000000..84d9408d4ea --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_tr.txt @@ -0,0 +1,212 @@ +# Turkish stopwords from LUCENE-559 +# merged with the list from "Information Retrieval on Turkish Texts" +# (http://www.users.muohio.edu/canf/papers/JASIST2008offPrint.pdf) +acaba +altmış +altı +ama +ancak +arada +aslında +ayrıca +bana +bazı +belki +ben +benden +beni +benim +beri +beş +bile +bin +bir +birçok +biri +birkaç +birkez +birşey +birşeyi +biz +bize +bizden +bizi +bizim +böyle +böylece +bu +buna +bunda +bundan +bunlar +bunları +bunların +bunu +bunun +burada +çok +çünkü +da +daha +dahi +de +defa +değil +diğer +diye +doksan +dokuz +dolayı +dolayısıyla +dört +edecek +eden +ederek +edilecek +ediliyor +edilmesi +ediyor +eğer +elli +en +etmesi +etti +ettiği +ettiğini +gibi +göre +halen +hangi +hatta +hem +henüz +hep +hepsi +her +herhangi +herkesin +hiç +hiçbir +için +iki +ile +ilgili +ise +işte +itibaren +itibariyle +kadar +karşın +katrilyon +kendi +kendilerine +kendini +kendisi +kendisine +kendisini +kez +ki +kim +kimden +kime +kimi +kimse +kırk +milyar +milyon +mu +mü +mı +nasıl +ne +neden +nedenle +nerde +nerede +nereye +niye +niçin +o +olan +olarak +oldu +olduğu +olduğunu +olduklarını +olmadı +olmadığı +olmak +olması +olmayan +olmaz +olsa +olsun +olup +olur +olursa +oluyor +on +ona +ondan +onlar +onlardan +onları +onların +onu +onun +otuz +oysa +öyle +pek +rağmen +sadece +sanki +sekiz +seksen +sen +senden +seni +senin +siz +sizden +sizi +sizin +şey +şeyden +şeyi +şeyler +şöyle +şu +şuna +şunda +şundan +şunları +şunu +tarafından +trilyon +tüm +üç +üzere +var +vardı +ve +veya +ya +yani +yapacak +yapılan +yapılması +yapıyor +yapmak +yaptı +yaptığı +yaptığını +yaptıkları +yedi +yerine +yetmiş +yine +yirmi +yoksa +yüz +zaten diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/userdict_ja.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/userdict_ja.txt new file mode 100644 index 00000000000..6f0368e4d81 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/userdict_ja.txt @@ -0,0 +1,29 @@ +# +# This is a sample user dictionary for Kuromoji (JapaneseTokenizer) +# +# Add entries to this file in order to override the statistical model in terms +# of segmentation, readings and part-of-speech tags. Notice that entries do +# not have weights since they are always used when found. This is by-design +# in order to maximize ease-of-use. +# +# Entries are defined using the following CSV format: +# , ... , ... , +# +# Notice that a single half-width space separates tokens and readings, and +# that the number tokens and readings must match exactly. +# +# Also notice that multiple entries with the same is undefined. +# +# Whitespace only lines are ignored. Comments are not allowed on entry lines. +# + +# Custom segmentation for kanji compounds +日本経済新聞,日本 経済 新聞,ニホン ケイザイ シンブン,カスタム名詞 +関西国際空港,関西 国際 空港,カンサイ コクサイ クウコウ,カスタム名詞 + +# Custom segmentation for compound katakana +トートバッグ,トート バッグ,トート バッグ,かずカナ名詞 +ショルダーバッグ,ショルダー バッグ,ショルダー バッグ,かずカナ名詞 + +# Custom reading for former sumo wrestler +朝青龍,朝青龍,アサショウリュウ,カスタム人名 diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/protwords.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/protwords.txt new file mode 100644 index 00000000000..1dfc0abecbf --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/protwords.txt @@ -0,0 +1,21 @@ +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#----------------------------------------------------------------------- +# Use a protected word file to protect against the stemmer reducing two +# unrelated words to the same base word. + +# Some non-words that normally won't be encountered, +# just to test that they won't be stemmed. +dontstems +zwhacky + diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/schema.xml b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/schema.xml new file mode 100644 index 00000000000..65192efe442 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/schema.xml @@ -0,0 +1,961 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/solrconfig.xml b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/solrconfig.xml new file mode 100644 index 00000000000..beff1b2af0a --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/solrconfig.xml @@ -0,0 +1,1784 @@ + + + + + + + + + LUCENE_43 + + + + + + + + + + + + + + + + + + + + + + + + ${solr.data.dir:} + + + + + ${solr.hdfs.home:} + ${solr.hdfs.confdir:} + ${solr.hdfs.blockcache.enabled:true} + ${solr.hdfs.blockcache.slab.count:1} + ${solr.hdfs.blockcache.direct.memory.allocation:true} + ${solr.hdfs.blockcache.blocksperbank:16384} + ${solr.hdfs.blockcache.read.enabled:true} + ${solr.hdfs.blockcache.write.enabled:true} + ${solr.hdfs.nrtcachingdirectory.enable:true} + ${solr.hdfs.nrtcachingdirectory.maxmergesizemb:16} + ${solr.hdfs.nrtcachingdirectory.maxcachedmb:192} + + + + + + + + + + + + + ${solr.maxIndexingThreads:8} + + + + + + 128 + + + + + + + + + + + + + ${solr.lock.type:hdfs} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${solr.ulog.dir:} + + + + + ${solr.autoCommit.maxTime:60000} + false + + + + + ${solr.autoSoftCommit.maxTime:1000} + + + + + + + + + + + + + + + + + + + 1024 + + + + + + + + + + + + + + + + + + + + + + true + + + + + + 20 + + + 200 + + + + + + + + + + + + static firstSearcher warming in solrconfig.xml + + + + + + false + + + 4 + + + + + + + + + + + + + + + + + + + + + + + explicit + 10 + text + + + + + + + + + + + + + + explicit + json + true + text + + + + + + + + true + json + true + + + + + + + + explicit + + + velocity + browse + layout + Solritas + + + edismax + + text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 + title^10.0 description^5.0 keywords^5.0 author^2.0 resourcename^1.0 + + text + 100% + *:* + 10 + *,score + + + text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 + title^10.0 description^5.0 keywords^5.0 author^2.0 resourcename^1.0 + + text,features,name,sku,id,manu,cat,title,description,keywords,author,resourcename + 3 + + + on + cat + manu_exact + content_type + author_s + ipod + GB + 1 + cat,inStock + after + price + 0 + 600 + 50 + popularity + 0 + 10 + 3 + manufacturedate_dt + NOW/YEAR-10YEARS + NOW + +1YEAR + before + after + + + on + content features title name + html + <b> + </b> + 0 + title + 0 + name + 3 + 200 + content + 750 + + + on + false + 5 + 2 + 5 + true + true + 5 + 3 + + + + + spellcheck + + + + + + + + + + + + + + application/json + + + + + application/csv + + + + + + + + + + + + + + + + + + + + + solrpingquery + + + all + + + + + + + + + explicit + true + + + + + + + + + + + + + + + + text_general + + + + + + default + text + solr.DirectSolrSpellChecker + + internal + + 0.5 + + 2 + + 1 + + 5 + + 4 + + 0.01 + + + + + + wordbreak + solr.WordBreakSolrSpellChecker + name + true + true + 10 + + + + + + + + + + + + + + + + text + + default + wordbreak + on + true + 10 + 5 + 5 + true + true + 10 + 5 + + + spellcheck + + + + + + + + + + text + true + + + tvComponent + + + + + + + + + default + + + org.carrot2.clustering.lingo.LingoClusteringAlgorithm + + + 20 + + + clustering/carrot2 + + + ENGLISH + + + stc + org.carrot2.clustering.stc.STCClusteringAlgorithm + + + + + + + true + default + true + + name + id + + features + + true + + + + false + + edismax + + text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 + + *:* + 10 + *,score + + + clustering + + + + + + + + + + true + false + + + terms + + + + + + + + string + elevate.xml + + + + + + explicit + text + + + elevator + + + + + + + + + + + 100 + + + + + + + + 70 + + 0.5 + + [-\w ,/\n\"']{20,200} + + + + + + + ]]> + ]]> + + + + + + + + + + + + + + + + + + + + + + + + ,, + ,, + ,, + ,, + ,]]> + ]]> + + + + + + 10 + .,!? + + + + + + + WORD + + + en + US + + + + + + + + + + + + + + + + + + + + + + text/plain; charset=UTF-8 + + + + + + + + + 5 + + + + + + + + + + + + + + + + + + *:* + + + diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/stopwords.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/stopwords.txt new file mode 100644 index 00000000000..ae1e83eeb3d --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/stopwords.txt @@ -0,0 +1,14 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/synonyms.txt b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/synonyms.txt new file mode 100644 index 00000000000..7f72128303b --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/synonyms.txt @@ -0,0 +1,29 @@ +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#----------------------------------------------------------------------- +#some test synonym mappings unlikely to appear in real input text +aaafoo => aaabar +bbbfoo => bbbfoo bbbbar +cccfoo => cccbar cccbaz +fooaaa,baraaa,bazaaa + +# Some synonym groups specific to this example +GB,gib,gigabyte,gigabytes +MB,mib,megabyte,megabytes +Television, Televisions, TV, TVs +#notice we use "gib" instead of "GiB" so any WordDelimiterFilter coming +#after us won't split it into two words. + +# Synonym mappings can be used for spelling correction too +pixima => pixma + diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/solr.xml b/solr/contrib/solr-mr/src/test-files/solr/minimr/solr.xml new file mode 100644 index 00000000000..6c8b43f75ed --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/minimr/solr.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + ${socketTimeout:120000} + ${connTimeout:15000} + + + + diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/currency.xml b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/currency.xml new file mode 100644 index 00000000000..3a9c58afee8 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/currency.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/elevate.xml b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/elevate.xml new file mode 100644 index 00000000000..25d5cebe4fb --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/elevate.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/contractions_ca.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/contractions_ca.txt new file mode 100644 index 00000000000..307a85f913d --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/contractions_ca.txt @@ -0,0 +1,8 @@ +# Set of Catalan contractions for ElisionFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +d +l +m +n +s +t diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/contractions_fr.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/contractions_fr.txt new file mode 100644 index 00000000000..722db588333 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/contractions_fr.txt @@ -0,0 +1,9 @@ +# Set of French contractions for ElisionFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +l +m +t +qu +n +s +j diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/contractions_ga.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/contractions_ga.txt new file mode 100644 index 00000000000..9ebe7fa349a --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/contractions_ga.txt @@ -0,0 +1,5 @@ +# Set of Irish contractions for ElisionFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +d +m +b diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/contractions_it.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/contractions_it.txt new file mode 100644 index 00000000000..cac04095372 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/contractions_it.txt @@ -0,0 +1,23 @@ +# Set of Italian contractions for ElisionFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +c +l +all +dall +dell +nell +sull +coll +pell +gl +agl +dagl +degl +negl +sugl +un +m +t +s +v +d diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/hyphenations_ga.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/hyphenations_ga.txt new file mode 100644 index 00000000000..4d2642cc5a3 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/hyphenations_ga.txt @@ -0,0 +1,5 @@ +# Set of Irish hyphenations for StopFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +h +n +t diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stemdict_nl.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stemdict_nl.txt new file mode 100644 index 00000000000..441072971d3 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stemdict_nl.txt @@ -0,0 +1,6 @@ +# Set of overrides for the dutch stemmer +# TODO: load this as a resource from the analyzer and sync it in build.xml +fiets fiets +bromfiets bromfiets +ei eier +kind kinder diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stoptags_ja.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stoptags_ja.txt new file mode 100644 index 00000000000..71b750845e3 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stoptags_ja.txt @@ -0,0 +1,420 @@ +# +# This file defines a Japanese stoptag set for JapanesePartOfSpeechStopFilter. +# +# Any token with a part-of-speech tag that exactly matches those defined in this +# file are removed from the token stream. +# +# Set your own stoptags by uncommenting the lines below. Note that comments are +# not allowed on the same line as a stoptag. See LUCENE-3745 for frequency lists, +# etc. that can be useful for building you own stoptag set. +# +# The entire possible tagset is provided below for convenience. +# +##### +# noun: unclassified nouns +#名詞 +# +# noun-common: Common nouns or nouns where the sub-classification is undefined +#名詞-一般 +# +# noun-proper: Proper nouns where the sub-classification is undefined +#名詞-固有名詞 +# +# noun-proper-misc: miscellaneous proper nouns +#名詞-固有名詞-一般 +# +# noun-proper-person: Personal names where the sub-classification is undefined +#名詞-固有名詞-人名 +# +# noun-proper-person-misc: names that cannot be divided into surname and +# given name; foreign names; names where the surname or given name is unknown. +# e.g. お市の方 +#名詞-固有名詞-人名-一般 +# +# noun-proper-person-surname: Mainly Japanese surnames. +# e.g. 山田 +#名詞-固有名詞-人名-姓 +# +# noun-proper-person-given_name: Mainly Japanese given names. +# e.g. 太郎 +#名詞-固有名詞-人名-名 +# +# noun-proper-organization: Names representing organizations. +# e.g. 通産省, NHK +#名詞-固有名詞-組織 +# +# noun-proper-place: Place names where the sub-classification is undefined +#名詞-固有名詞-地域 +# +# noun-proper-place-misc: Place names excluding countries. +# e.g. アジア, バルセロナ, 京都 +#名詞-固有名詞-地域-一般 +# +# noun-proper-place-country: Country names. +# e.g. 日本, オーストラリア +#名詞-固有名詞-地域-国 +# +# noun-pronoun: Pronouns where the sub-classification is undefined +#名詞-代名詞 +# +# noun-pronoun-misc: miscellaneous pronouns: +# e.g. それ, ここ, あいつ, あなた, あちこち, いくつ, どこか, なに, みなさん, みんな, わたくし, われわれ +#名詞-代名詞-一般 +# +# noun-pronoun-contraction: Spoken language contraction made by combining a +# pronoun and the particle 'wa'. +# e.g. ありゃ, こりゃ, こりゃあ, そりゃ, そりゃあ +#名詞-代名詞-縮約 +# +# noun-adverbial: Temporal nouns such as names of days or months that behave +# like adverbs. Nouns that represent amount or ratios and can be used adverbially, +# e.g. 金曜, 一月, 午後, 少量 +#名詞-副詞可能 +# +# noun-verbal: Nouns that take arguments with case and can appear followed by +# 'suru' and related verbs (する, できる, なさる, くださる) +# e.g. インプット, 愛着, 悪化, 悪戦苦闘, 一安心, 下取り +#名詞-サ変接続 +# +# noun-adjective-base: The base form of adjectives, words that appear before な ("na") +# e.g. 健康, 安易, 駄目, だめ +#名詞-形容動詞語幹 +# +# noun-numeric: Arabic numbers, Chinese numerals, and counters like 何 (回), 数. +# e.g. 0, 1, 2, 何, 数, 幾 +#名詞-数 +# +# noun-affix: noun affixes where the sub-classification is undefined +#名詞-非自立 +# +# noun-affix-misc: Of adnominalizers, the case-marker の ("no"), and words that +# attach to the base form of inflectional words, words that cannot be classified +# into any of the other categories below. This category includes indefinite nouns. +# e.g. あかつき, 暁, かい, 甲斐, 気, きらい, 嫌い, くせ, 癖, こと, 事, ごと, 毎, しだい, 次第, +# 順, せい, 所為, ついで, 序で, つもり, 積もり, 点, どころ, の, はず, 筈, はずみ, 弾み, +# 拍子, ふう, ふり, 振り, ほう, 方, 旨, もの, 物, 者, ゆえ, 故, ゆえん, 所以, わけ, 訳, +# わり, 割り, 割, ん-口語/, もん-口語/ +#名詞-非自立-一般 +# +# noun-affix-adverbial: noun affixes that that can behave as adverbs. +# e.g. あいだ, 間, あげく, 挙げ句, あと, 後, 余り, 以外, 以降, 以後, 以上, 以前, 一方, うえ, +# 上, うち, 内, おり, 折り, かぎり, 限り, きり, っきり, 結果, ころ, 頃, さい, 際, 最中, さなか, +# 最中, じたい, 自体, たび, 度, ため, 為, つど, 都度, とおり, 通り, とき, 時, ところ, 所, +# とたん, 途端, なか, 中, のち, 後, ばあい, 場合, 日, ぶん, 分, ほか, 他, まえ, 前, まま, +# 儘, 侭, みぎり, 矢先 +#名詞-非自立-副詞可能 +# +# noun-affix-aux: noun affixes treated as 助動詞 ("auxiliary verb") in school grammars +# with the stem よう(だ) ("you(da)"). +# e.g. よう, やう, 様 (よう) +#名詞-非自立-助動詞語幹 +# +# noun-affix-adjective-base: noun affixes that can connect to the indeclinable +# connection form な (aux "da"). +# e.g. みたい, ふう +#名詞-非自立-形容動詞語幹 +# +# noun-special: special nouns where the sub-classification is undefined. +#名詞-特殊 +# +# noun-special-aux: The そうだ ("souda") stem form that is used for reporting news, is +# treated as 助動詞 ("auxiliary verb") in school grammars, and attach to the base +# form of inflectional words. +# e.g. そう +#名詞-特殊-助動詞語幹 +# +# noun-suffix: noun suffixes where the sub-classification is undefined. +#名詞-接尾 +# +# noun-suffix-misc: Of the nouns or stem forms of other parts of speech that connect +# to ガル or タイ and can combine into compound nouns, words that cannot be classified into +# any of the other categories below. In general, this category is more inclusive than +# 接尾語 ("suffix") and is usually the last element in a compound noun. +# e.g. おき, かた, 方, 甲斐 (がい), がかり, ぎみ, 気味, ぐるみ, (~した) さ, 次第, 済 (ず) み, +# よう, (でき)っこ, 感, 観, 性, 学, 類, 面, 用 +#名詞-接尾-一般 +# +# noun-suffix-person: Suffixes that form nouns and attach to person names more often +# than other nouns. +# e.g. 君, 様, 著 +#名詞-接尾-人名 +# +# noun-suffix-place: Suffixes that form nouns and attach to place names more often +# than other nouns. +# e.g. 町, 市, 県 +#名詞-接尾-地域 +# +# noun-suffix-verbal: Of the suffixes that attach to nouns and form nouns, those that +# can appear before スル ("suru"). +# e.g. 化, 視, 分け, 入り, 落ち, 買い +#名詞-接尾-サ変接続 +# +# noun-suffix-aux: The stem form of そうだ (様態) that is used to indicate conditions, +# is treated as 助動詞 ("auxiliary verb") in school grammars, and attach to the +# conjunctive form of inflectional words. +# e.g. そう +#名詞-接尾-助動詞語幹 +# +# noun-suffix-adjective-base: Suffixes that attach to other nouns or the conjunctive +# form of inflectional words and appear before the copula だ ("da"). +# e.g. 的, げ, がち +#名詞-接尾-形容動詞語幹 +# +# noun-suffix-adverbial: Suffixes that attach to other nouns and can behave as adverbs. +# e.g. 後 (ご), 以後, 以降, 以前, 前後, 中, 末, 上, 時 (じ) +#名詞-接尾-副詞可能 +# +# noun-suffix-classifier: Suffixes that attach to numbers and form nouns. This category +# is more inclusive than 助数詞 ("classifier") and includes common nouns that attach +# to numbers. +# e.g. 個, つ, 本, 冊, パーセント, cm, kg, カ月, か国, 区画, 時間, 時半 +#名詞-接尾-助数詞 +# +# noun-suffix-special: Special suffixes that mainly attach to inflecting words. +# e.g. (楽し) さ, (考え) 方 +#名詞-接尾-特殊 +# +# noun-suffix-conjunctive: Nouns that behave like conjunctions and join two words +# together. +# e.g. (日本) 対 (アメリカ), 対 (アメリカ), (3) 対 (5), (女優) 兼 (主婦) +#名詞-接続詞的 +# +# noun-verbal_aux: Nouns that attach to the conjunctive particle て ("te") and are +# semantically verb-like. +# e.g. ごらん, ご覧, 御覧, 頂戴 +#名詞-動詞非自立的 +# +# noun-quotation: text that cannot be segmented into words, proverbs, Chinese poetry, +# dialects, English, etc. Currently, the only entry for 名詞 引用文字列 ("noun quotation") +# is いわく ("iwaku"). +#名詞-引用文字列 +# +# noun-nai_adjective: Words that appear before the auxiliary verb ない ("nai") and +# behave like an adjective. +# e.g. 申し訳, 仕方, とんでも, 違い +#名詞-ナイ形容詞語幹 +# +##### +# prefix: unclassified prefixes +#接頭詞 +# +# prefix-nominal: Prefixes that attach to nouns (including adjective stem forms) +# excluding numerical expressions. +# e.g. お (水), 某 (氏), 同 (社), 故 (~氏), 高 (品質), お (見事), ご (立派) +#接頭詞-名詞接続 +# +# prefix-verbal: Prefixes that attach to the imperative form of a verb or a verb +# in conjunctive form followed by なる/なさる/くださる. +# e.g. お (読みなさい), お (座り) +#接頭詞-動詞接続 +# +# prefix-adjectival: Prefixes that attach to adjectives. +# e.g. お (寒いですねえ), バカ (でかい) +#接頭詞-形容詞接続 +# +# prefix-numerical: Prefixes that attach to numerical expressions. +# e.g. 約, およそ, 毎時 +#接頭詞-数接続 +# +##### +# verb: unclassified verbs +#動詞 +# +# verb-main: +#動詞-自立 +# +# verb-auxiliary: +#動詞-非自立 +# +# verb-suffix: +#動詞-接尾 +# +##### +# adjective: unclassified adjectives +#形容詞 +# +# adjective-main: +#形容詞-自立 +# +# adjective-auxiliary: +#形容詞-非自立 +# +# adjective-suffix: +#形容詞-接尾 +# +##### +# adverb: unclassified adverbs +#副詞 +# +# adverb-misc: Words that can be segmented into one unit and where adnominal +# modification is not possible. +# e.g. あいかわらず, 多分 +#副詞-一般 +# +# adverb-particle_conjunction: Adverbs that can be followed by の, は, に, +# な, する, だ, etc. +# e.g. こんなに, そんなに, あんなに, なにか, なんでも +#副詞-助詞類接続 +# +##### +# adnominal: Words that only have noun-modifying forms. +# e.g. この, その, あの, どの, いわゆる, なんらかの, 何らかの, いろんな, こういう, そういう, ああいう, +# どういう, こんな, そんな, あんな, どんな, 大きな, 小さな, おかしな, ほんの, たいした, +# 「(, も) さる (ことながら)」, 微々たる, 堂々たる, 単なる, いかなる, 我が」「同じ, 亡き +#連体詞 +# +##### +# conjunction: Conjunctions that can occur independently. +# e.g. が, けれども, そして, じゃあ, それどころか +接続詞 +# +##### +# particle: unclassified particles. +助詞 +# +# particle-case: case particles where the subclassification is undefined. +助詞-格助詞 +# +# particle-case-misc: Case particles. +# e.g. から, が, で, と, に, へ, より, を, の, にて +助詞-格助詞-一般 +# +# particle-case-quote: the "to" that appears after nouns, a person’s speech, +# quotation marks, expressions of decisions from a meeting, reasons, judgements, +# conjectures, etc. +# e.g. ( だ) と (述べた.), ( である) と (して執行猶予...) +助詞-格助詞-引用 +# +# particle-case-compound: Compounds of particles and verbs that mainly behave +# like case particles. +# e.g. という, といった, とかいう, として, とともに, と共に, でもって, にあたって, に当たって, に当って, +# にあたり, に当たり, に当り, に当たる, にあたる, において, に於いて,に於て, における, に於ける, +# にかけ, にかけて, にかんし, に関し, にかんして, に関して, にかんする, に関する, に際し, +# に際して, にしたがい, に従い, に従う, にしたがって, に従って, にたいし, に対し, にたいして, +# に対して, にたいする, に対する, について, につき, につけ, につけて, につれ, につれて, にとって, +# にとり, にまつわる, によって, に依って, に因って, により, に依り, に因り, による, に依る, に因る, +# にわたって, にわたる, をもって, を以って, を通じ, を通じて, を通して, をめぐって, をめぐり, をめぐる, +# って-口語/, ちゅう-関西弁「という」/, (何) ていう (人)-口語/, っていう-口語/, といふ, とかいふ +助詞-格助詞-連語 +# +# particle-conjunctive: +# e.g. から, からには, が, けれど, けれども, けど, し, つつ, て, で, と, ところが, どころか, とも, ども, +# ながら, なり, ので, のに, ば, ものの, や ( した), やいなや, (ころん) じゃ(いけない)-口語/, +# (行っ) ちゃ(いけない)-口語/, (言っ) たって (しかたがない)-口語/, (それがなく)ったって (平気)-口語/ +助詞-接続助詞 +# +# particle-dependency: +# e.g. こそ, さえ, しか, すら, は, も, ぞ +助詞-係助詞 +# +# particle-adverbial: +# e.g. がてら, かも, くらい, 位, ぐらい, しも, (学校) じゃ(これが流行っている)-口語/, +# (それ)じゃあ (よくない)-口語/, ずつ, (私) なぞ, など, (私) なり (に), (先生) なんか (大嫌い)-口語/, +# (私) なんぞ, (先生) なんて (大嫌い)-口語/, のみ, だけ, (私) だって-口語/, だに, +# (彼)ったら-口語/, (お茶) でも (いかが), 等 (とう), (今後) とも, ばかり, ばっか-口語/, ばっかり-口語/, +# ほど, 程, まで, 迄, (誰) も (が)([助詞-格助詞] および [助詞-係助詞] の前に位置する「も」) +助詞-副助詞 +# +# particle-interjective: particles with interjective grammatical roles. +# e.g. (松島) や +助詞-間投助詞 +# +# particle-coordinate: +# e.g. と, たり, だの, だり, とか, なり, や, やら +助詞-並立助詞 +# +# particle-final: +# e.g. かい, かしら, さ, ぜ, (だ)っけ-口語/, (とまってる) で-方言/, な, ナ, なあ-口語/, ぞ, ね, ネ, +# ねぇ-口語/, ねえ-口語/, ねん-方言/, の, のう-口語/, や, よ, ヨ, よぉ-口語/, わ, わい-口語/ +助詞-終助詞 +# +# particle-adverbial/conjunctive/final: The particle "ka" when unknown whether it is +# adverbial, conjunctive, or sentence final. For example: +# (a) 「A か B か」. Ex:「(国内で運用する) か,(海外で運用する) か (.)」 +# (b) Inside an adverb phrase. Ex:「(幸いという) か (, 死者はいなかった.)」 +# 「(祈りが届いたせい) か (, 試験に合格した.)」 +# (c) 「かのように」. Ex:「(何もなかった) か (のように振る舞った.)」 +# e.g. か +助詞-副助詞/並立助詞/終助詞 +# +# particle-adnominalizer: The "no" that attaches to nouns and modifies +# non-inflectional words. +助詞-連体化 +# +# particle-adnominalizer: The "ni" and "to" that appear following nouns and adverbs +# that are giongo, giseigo, or gitaigo. +# e.g. に, と +助詞-副詞化 +# +# particle-special: A particle that does not fit into one of the above classifications. +# This includes particles that are used in Tanka, Haiku, and other poetry. +# e.g. かな, けむ, ( しただろう) に, (あんた) にゃ(わからん), (俺) ん (家) +助詞-特殊 +# +##### +# auxiliary-verb: +助動詞 +# +##### +# interjection: Greetings and other exclamations. +# e.g. おはよう, おはようございます, こんにちは, こんばんは, ありがとう, どうもありがとう, ありがとうございます, +# いただきます, ごちそうさま, さよなら, さようなら, はい, いいえ, ごめん, ごめんなさい +#感動詞 +# +##### +# symbol: unclassified Symbols. +記号 +# +# symbol-misc: A general symbol not in one of the categories below. +# e.g. [○◎@$〒→+] +記号-一般 +# +# symbol-comma: Commas +# e.g. [,、] +記号-読点 +# +# symbol-period: Periods and full stops. +# e.g. [..。] +記号-句点 +# +# symbol-space: Full-width whitespace. +記号-空白 +# +# symbol-open_bracket: +# e.g. [({‘“『【] +記号-括弧開 +# +# symbol-close_bracket: +# e.g. [)}’”』」】] +記号-括弧閉 +# +# symbol-alphabetic: +#記号-アルファベット +# +##### +# other: unclassified other +#その他 +# +# other-interjection: Words that are hard to classify as noun-suffixes or +# sentence-final particles. +# e.g. (だ)ァ +その他-間投 +# +##### +# filler: Aizuchi that occurs during a conversation or sounds inserted as filler. +# e.g. あの, うんと, えと +フィラー +# +##### +# non-verbal: non-verbal sound. +非言語音 +# +##### +# fragment: +#語断片 +# +##### +# unknown: unknown part of speech. +#未知語 +# +##### End of file diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_ar.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_ar.txt new file mode 100644 index 00000000000..046829db6a2 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_ar.txt @@ -0,0 +1,125 @@ +# This file was created by Jacques Savoy and is distributed under the BSD license. +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# Also see http://www.opensource.org/licenses/bsd-license.html +# Cleaned on October 11, 2009 (not normalized, so use before normalization) +# This means that when modifying this list, you might need to add some +# redundant entries, for example containing forms with both أ and ا +من +ومن +منها +منه +في +وفي +فيها +فيه +و +ف +ثم +او +أو +ب +بها +به +ا +أ +اى +اي +أي +أى +لا +ولا +الا +ألا +إلا +لكن +ما +وما +كما +فما +عن +مع +اذا +إذا +ان +أن +إن +انها +أنها +إنها +انه +أنه +إنه +بان +بأن +فان +فأن +وان +وأن +وإن +التى +التي +الذى +الذي +الذين +الى +الي +إلى +إلي +على +عليها +عليه +اما +أما +إما +ايضا +أيضا +كل +وكل +لم +ولم +لن +ولن +هى +هي +هو +وهى +وهي +وهو +فهى +فهي +فهو +انت +أنت +لك +لها +له +هذه +هذا +تلك +ذلك +هناك +كانت +كان +يكون +تكون +وكانت +وكان +غير +بعض +قد +نحو +بين +بينما +منذ +ضمن +حيث +الان +الآن +خلال +بعد +قبل +حتى +عند +عندما +لدى +جميع diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_bg.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_bg.txt new file mode 100644 index 00000000000..1ae4ba2ae38 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_bg.txt @@ -0,0 +1,193 @@ +# This file was created by Jacques Savoy and is distributed under the BSD license. +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# Also see http://www.opensource.org/licenses/bsd-license.html +а +аз +ако +ала +бе +без +беше +би +бил +била +били +било +близо +бъдат +бъде +бяха +в +вас +ваш +ваша +вероятно +вече +взема +ви +вие +винаги +все +всеки +всички +всичко +всяка +във +въпреки +върху +г +ги +главно +го +д +да +дали +до +докато +докога +дори +досега +доста +е +едва +един +ето +за +зад +заедно +заради +засега +затова +защо +защото +и +из +или +им +има +имат +иска +й +каза +как +каква +какво +както +какъв +като +кога +когато +което +които +кой +който +колко +която +къде +където +към +ли +м +ме +между +мен +ми +мнозина +мога +могат +може +моля +момента +му +н +на +над +назад +най +направи +напред +например +нас +не +него +нея +ни +ние +никой +нито +но +някои +някой +няма +обаче +около +освен +особено +от +отгоре +отново +още +пак +по +повече +повечето +под +поне +поради +после +почти +прави +пред +преди +през +при +пък +първо +с +са +само +се +сега +си +скоро +след +сме +според +сред +срещу +сте +съм +със +също +т +тази +така +такива +такъв +там +твой +те +тези +ти +тн +то +това +тогава +този +той +толкова +точно +трябва +тук +тъй +тя +тях +у +харесва +ч +че +често +чрез +ще +щом +я diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_ca.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_ca.txt new file mode 100644 index 00000000000..3da65deafe1 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_ca.txt @@ -0,0 +1,220 @@ +# Catalan stopwords from http://github.com/vcl/cue.language (Apache 2 Licensed) +a +abans +ací +ah +així +això +al +als +aleshores +algun +alguna +algunes +alguns +alhora +allà +allí +allò +altra +altre +altres +amb +ambdós +ambdues +apa +aquell +aquella +aquelles +aquells +aquest +aquesta +aquestes +aquests +aquí +baix +cada +cadascú +cadascuna +cadascunes +cadascuns +com +contra +d'un +d'una +d'unes +d'uns +dalt +de +del +dels +des +després +dins +dintre +donat +doncs +durant +e +eh +el +els +em +en +encara +ens +entre +érem +eren +éreu +es +és +esta +està +estàvem +estaven +estàveu +esteu +et +etc +ets +fins +fora +gairebé +ha +han +has +havia +he +hem +heu +hi +ho +i +igual +iguals +ja +l'hi +la +les +li +li'n +llavors +m'he +ma +mal +malgrat +mateix +mateixa +mateixes +mateixos +me +mentre +més +meu +meus +meva +meves +molt +molta +moltes +molts +mon +mons +n'he +n'hi +ne +ni +no +nogensmenys +només +nosaltres +nostra +nostre +nostres +o +oh +oi +on +pas +pel +pels +per +però +perquè +poc +poca +pocs +poques +potser +propi +qual +quals +quan +quant +que +què +quelcom +qui +quin +quina +quines +quins +s'ha +s'han +sa +semblant +semblants +ses +seu +seus +seva +seva +seves +si +sobre +sobretot +sóc +solament +sols +son +són +sons +sota +sou +t'ha +t'han +t'he +ta +tal +també +tampoc +tan +tant +tanta +tantes +teu +teus +teva +teves +ton +tons +tot +tota +totes +tots +un +una +unes +uns +us +va +vaig +vam +van +vas +veu +vosaltres +vostra +vostre +vostres diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_cz.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_cz.txt new file mode 100644 index 00000000000..53c6097dac7 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_cz.txt @@ -0,0 +1,172 @@ +a +s +k +o +i +u +v +z +dnes +cz +tímto +budeš +budem +byli +jseš +můj +svým +ta +tomto +tohle +tuto +tyto +jej +zda +proč +máte +tato +kam +tohoto +kdo +kteří +mi +nám +tom +tomuto +mít +nic +proto +kterou +byla +toho +protože +asi +ho +naši +napište +re +což +tím +takže +svých +její +svými +jste +aj +tu +tedy +teto +bylo +kde +ke +pravé +ji +nad +nejsou +či +pod +téma +mezi +přes +ty +pak +vám +ani +když +však +neg +jsem +tento +článku +články +aby +jsme +před +pta +jejich +byl +ještě +až +bez +také +pouze +první +vaše +která +nás +nový +tipy +pokud +může +strana +jeho +své +jiné +zprávy +nové +není +vás +jen +podle +zde +už +být +více +bude +již +než +který +by +které +co +nebo +ten +tak +má +při +od +po +jsou +jak +další +ale +si +se +ve +to +jako +za +zpět +ze +do +pro +je +na +atd +atp +jakmile +přičemž +já +on +ona +ono +oni +ony +my +vy +jí +ji +mě +mne +jemu +tomu +těm +těmu +němu +němuž +jehož +jíž +jelikož +jež +jakož +načež diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_da.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_da.txt new file mode 100644 index 00000000000..a3ff5fe122c --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_da.txt @@ -0,0 +1,108 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/danish/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Danish stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | This is a ranked list (commonest to rarest) of stopwords derived from + | a large text sample. + + +og | and +i | in +jeg | I +det | that (dem. pronoun)/it (pers. pronoun) +at | that (in front of a sentence)/to (with infinitive) +en | a/an +den | it (pers. pronoun)/that (dem. pronoun) +til | to/at/for/until/against/by/of/into, more +er | present tense of "to be" +som | who, as +på | on/upon/in/on/at/to/after/of/with/for, on +de | they +med | with/by/in, along +han | he +af | of/by/from/off/for/in/with/on, off +for | at/for/to/from/by/of/ago, in front/before, because +ikke | not +der | who/which, there/those +var | past tense of "to be" +mig | me/myself +sig | oneself/himself/herself/itself/themselves +men | but +et | a/an/one, one (number), someone/somebody/one +har | present tense of "to have" +om | round/about/for/in/a, about/around/down, if +vi | we +min | my +havde | past tense of "to have" +ham | him +hun | she +nu | now +over | over/above/across/by/beyond/past/on/about, over/past +da | then, when/as/since +fra | from/off/since, off, since +du | you +ud | out +sin | his/her/its/one's +dem | them +os | us/ourselves +op | up +man | you/one +hans | his +hvor | where +eller | or +hvad | what +skal | must/shall etc. +selv | myself/youself/herself/ourselves etc., even +her | here +alle | all/everyone/everybody etc. +vil | will (verb) +blev | past tense of "to stay/to remain/to get/to become" +kunne | could +ind | in +når | when +være | present tense of "to be" +dog | however/yet/after all +noget | something +ville | would +jo | you know/you see (adv), yes +deres | their/theirs +efter | after/behind/according to/for/by/from, later/afterwards +ned | down +skulle | should +denne | this +end | than +dette | this +mit | my/mine +også | also +under | under/beneath/below/during, below/underneath +have | have +dig | you +anden | other +hende | her +mine | my +alt | everything +meget | much/very, plenty of +sit | his, her, its, one's +sine | his, her, its, one's +vor | our +mod | against +disse | these +hvis | if +din | your/yours +nogle | some +hos | by/at +blive | be/become +mange | many +ad | by/through +bliver | present tense of "to be/to become" +hendes | her/hers +været | be +thi | for (conj) +jer | you +sådan | such, like this/like that diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_de.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_de.txt new file mode 100644 index 00000000000..f7703841887 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_de.txt @@ -0,0 +1,292 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/german/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A German stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | The number of forms in this list is reduced significantly by passing it + | through the German stemmer. + + +aber | but + +alle | all +allem +allen +aller +alles + +als | than, as +also | so +am | an + dem +an | at + +ander | other +andere +anderem +anderen +anderer +anderes +anderm +andern +anderr +anders + +auch | also +auf | on +aus | out of +bei | by +bin | am +bis | until +bist | art +da | there +damit | with it +dann | then + +der | the +den +des +dem +die +das + +daß | that + +derselbe | the same +derselben +denselben +desselben +demselben +dieselbe +dieselben +dasselbe + +dazu | to that + +dein | thy +deine +deinem +deinen +deiner +deines + +denn | because + +derer | of those +dessen | of him + +dich | thee +dir | to thee +du | thou + +dies | this +diese +diesem +diesen +dieser +dieses + + +doch | (several meanings) +dort | (over) there + + +durch | through + +ein | a +eine +einem +einen +einer +eines + +einig | some +einige +einigem +einigen +einiger +einiges + +einmal | once + +er | he +ihn | him +ihm | to him + +es | it +etwas | something + +euer | your +eure +eurem +euren +eurer +eures + +für | for +gegen | towards +gewesen | p.p. of sein +hab | have +habe | have +haben | have +hat | has +hatte | had +hatten | had +hier | here +hin | there +hinter | behind + +ich | I +mich | me +mir | to me + + +ihr | you, to her +ihre +ihrem +ihren +ihrer +ihres +euch | to you + +im | in + dem +in | in +indem | while +ins | in + das +ist | is + +jede | each, every +jedem +jeden +jeder +jedes + +jene | that +jenem +jenen +jener +jenes + +jetzt | now +kann | can + +kein | no +keine +keinem +keinen +keiner +keines + +können | can +könnte | could +machen | do +man | one + +manche | some, many a +manchem +manchen +mancher +manches + +mein | my +meine +meinem +meinen +meiner +meines + +mit | with +muss | must +musste | had to +nach | to(wards) +nicht | not +nichts | nothing +noch | still, yet +nun | now +nur | only +ob | whether +oder | or +ohne | without +sehr | very + +sein | his +seine +seinem +seinen +seiner +seines + +selbst | self +sich | herself + +sie | they, she +ihnen | to them + +sind | are +so | so + +solche | such +solchem +solchen +solcher +solches + +soll | shall +sollte | should +sondern | but +sonst | else +über | over +um | about, around +und | and + +uns | us +unse +unsem +unsen +unser +unses + +unter | under +viel | much +vom | von + dem +von | from +vor | before +während | while +war | was +waren | were +warst | wast +was | what +weg | away, off +weil | because +weiter | further + +welche | which +welchem +welchen +welcher +welches + +wenn | when +werde | will +werden | will +wie | how +wieder | again +will | want +wir | we +wird | will +wirst | willst +wo | where +wollen | want +wollte | wanted +würde | would +würden | would +zu | to +zum | zu + dem +zur | zu + der +zwar | indeed +zwischen | between + diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_el.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_el.txt new file mode 100644 index 00000000000..232681f5bd6 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_el.txt @@ -0,0 +1,78 @@ +# Lucene Greek Stopwords list +# Note: by default this file is used after GreekLowerCaseFilter, +# so when modifying this file use 'σ' instead of 'ς' +ο +η +το +οι +τα +του +τησ +των +τον +την +και +κι +κ +ειμαι +εισαι +ειναι +ειμαστε +ειστε +στο +στον +στη +στην +μα +αλλα +απο +για +προσ +με +σε +ωσ +παρα +αντι +κατα +μετα +θα +να +δε +δεν +μη +μην +επι +ενω +εαν +αν +τοτε +που +πωσ +ποιοσ +ποια +ποιο +ποιοι +ποιεσ +ποιων +ποιουσ +αυτοσ +αυτη +αυτο +αυτοι +αυτων +αυτουσ +αυτεσ +αυτα +εκεινοσ +εκεινη +εκεινο +εκεινοι +εκεινεσ +εκεινα +εκεινων +εκεινουσ +οπωσ +ομωσ +ισωσ +οσο +οτι diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_en.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_en.txt new file mode 100644 index 00000000000..2c164c0b2a1 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_en.txt @@ -0,0 +1,54 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# a couple of test stopwords to test that the words are really being +# configured from this file: +stopworda +stopwordb + +# Standard english stop words taken from Lucene's StopAnalyzer +a +an +and +are +as +at +be +but +by +for +if +in +into +is +it +no +not +of +on +or +such +that +the +their +then +there +these +they +this +to +was +will +with diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_es.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_es.txt new file mode 100644 index 00000000000..2db14760075 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_es.txt @@ -0,0 +1,354 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/spanish/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Spanish stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + + | The following is a ranked list (commonest to rarest) of stopwords + | deriving from a large sample of text. + + | Extra words have been added at the end. + +de | from, of +la | the, her +que | who, that +el | the +en | in +y | and +a | to +los | the, them +del | de + el +se | himself, from him etc +las | the, them +por | for, by, etc +un | a +para | for +con | with +no | no +una | a +su | his, her +al | a + el + | es from SER +lo | him +como | how +más | more +pero | pero +sus | su plural +le | to him, her +ya | already +o | or + | fue from SER +este | this + | ha from HABER +sí | himself etc +porque | because +esta | this + | son from SER +entre | between + | está from ESTAR +cuando | when +muy | very +sin | without +sobre | on + | ser from SER + | tiene from TENER +también | also +me | me +hasta | until +hay | there is/are +donde | where + | han from HABER +quien | whom, that + | están from ESTAR + | estado from ESTAR +desde | from +todo | all +nos | us +durante | during + | estados from ESTAR +todos | all +uno | a +les | to them +ni | nor +contra | against +otros | other + | fueron from SER +ese | that +eso | that + | había from HABER +ante | before +ellos | they +e | and (variant of y) +esto | this +mí | me +antes | before +algunos | some +qué | what? +unos | a +yo | I +otro | other +otras | other +otra | other +él | he +tanto | so much, many +esa | that +estos | these +mucho | much, many +quienes | who +nada | nothing +muchos | many +cual | who + | sea from SER +poco | few +ella | she +estar | to be + | haber from HABER +estas | these + | estaba from ESTAR + | estamos from ESTAR +algunas | some +algo | something +nosotros | we + + | other forms + +mi | me +mis | mi plural +tú | thou +te | thee +ti | thee +tu | thy +tus | tu plural +ellas | they +nosotras | we +vosotros | you +vosotras | you +os | you +mío | mine +mía | +míos | +mías | +tuyo | thine +tuya | +tuyos | +tuyas | +suyo | his, hers, theirs +suya | +suyos | +suyas | +nuestro | ours +nuestra | +nuestros | +nuestras | +vuestro | yours +vuestra | +vuestros | +vuestras | +esos | those +esas | those + + | forms of estar, to be (not including the infinitive): +estoy +estás +está +estamos +estáis +están +esté +estés +estemos +estéis +estén +estaré +estarás +estará +estaremos +estaréis +estarán +estaría +estarías +estaríamos +estaríais +estarían +estaba +estabas +estábamos +estabais +estaban +estuve +estuviste +estuvo +estuvimos +estuvisteis +estuvieron +estuviera +estuvieras +estuviéramos +estuvierais +estuvieran +estuviese +estuvieses +estuviésemos +estuvieseis +estuviesen +estando +estado +estada +estados +estadas +estad + + | forms of haber, to have (not including the infinitive): +he +has +ha +hemos +habéis +han +haya +hayas +hayamos +hayáis +hayan +habré +habrás +habrá +habremos +habréis +habrán +habría +habrías +habríamos +habríais +habrían +había +habías +habíamos +habíais +habían +hube +hubiste +hubo +hubimos +hubisteis +hubieron +hubiera +hubieras +hubiéramos +hubierais +hubieran +hubiese +hubieses +hubiésemos +hubieseis +hubiesen +habiendo +habido +habida +habidos +habidas + + | forms of ser, to be (not including the infinitive): +soy +eres +es +somos +sois +son +sea +seas +seamos +seáis +sean +seré +serás +será +seremos +seréis +serán +sería +serías +seríamos +seríais +serían +era +eras +éramos +erais +eran +fui +fuiste +fue +fuimos +fuisteis +fueron +fuera +fueras +fuéramos +fuerais +fueran +fuese +fueses +fuésemos +fueseis +fuesen +siendo +sido + | sed also means 'thirst' + + | forms of tener, to have (not including the infinitive): +tengo +tienes +tiene +tenemos +tenéis +tienen +tenga +tengas +tengamos +tengáis +tengan +tendré +tendrás +tendrá +tendremos +tendréis +tendrán +tendría +tendrías +tendríamos +tendríais +tendrían +tenía +tenías +teníamos +teníais +tenían +tuve +tuviste +tuvo +tuvimos +tuvisteis +tuvieron +tuviera +tuvieras +tuviéramos +tuvierais +tuvieran +tuviese +tuvieses +tuviésemos +tuvieseis +tuviesen +teniendo +tenido +tenida +tenidos +tenidas +tened + diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_eu.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_eu.txt new file mode 100644 index 00000000000..25f1db93460 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_eu.txt @@ -0,0 +1,99 @@ +# example set of basque stopwords +al +anitz +arabera +asko +baina +bat +batean +batek +bati +batzuei +batzuek +batzuetan +batzuk +bera +beraiek +berau +berauek +bere +berori +beroriek +beste +bezala +da +dago +dira +ditu +du +dute +edo +egin +ere +eta +eurak +ez +gainera +gu +gutxi +guzti +haiei +haiek +haietan +hainbeste +hala +han +handik +hango +hara +hari +hark +hartan +hau +hauei +hauek +hauetan +hemen +hemendik +hemengo +hi +hona +honek +honela +honetan +honi +hor +hori +horiei +horiek +horietan +horko +horra +horrek +horrela +horretan +horri +hortik +hura +izan +ni +noiz +nola +non +nondik +nongo +nor +nora +ze +zein +zen +zenbait +zenbat +zer +zergatik +ziren +zituen +zu +zuek +zuen +zuten diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_fa.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_fa.txt new file mode 100644 index 00000000000..723641c6da7 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_fa.txt @@ -0,0 +1,313 @@ +# This file was created by Jacques Savoy and is distributed under the BSD license. +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# Also see http://www.opensource.org/licenses/bsd-license.html +# Note: by default this file is used after normalization, so when adding entries +# to this file, use the arabic 'ي' instead of 'ی' +انان +نداشته +سراسر +خياه +ايشان +وي +تاكنون +بيشتري +دوم +پس +ناشي +وگو +يا +داشتند +سپس +هنگام +هرگز +پنج +نشان +امسال +ديگر +گروهي +شدند +چطور +ده +و +دو +نخستين +ولي +چرا +چه +وسط +ه +كدام +قابل +يك +رفت +هفت +همچنين +در +هزار +بله +بلي +شايد +اما +شناسي +گرفته +دهد +داشته +دانست +داشتن +خواهيم +ميليارد +وقتيكه +امد +خواهد +جز +اورده +شده +بلكه +خدمات +شدن +برخي +نبود +بسياري +جلوگيري +حق +كردند +نوعي +بعري +نكرده +نظير +نبايد +بوده +بودن +داد +اورد +هست +جايي +شود +دنبال +داده +بايد +سابق +هيچ +همان +انجا +كمتر +كجاست +گردد +كسي +تر +مردم +تان +دادن +بودند +سري +جدا +ندارند +مگر +يكديگر +دارد +دهند +بنابراين +هنگامي +سمت +جا +انچه +خود +دادند +زياد +دارند +اثر +بدون +بهترين +بيشتر +البته +به +براساس +بيرون +كرد +بعضي +گرفت +توي +اي +ميليون +او +جريان +تول +بر +مانند +برابر +باشيم +مدتي +گويند +اكنون +تا +تنها +جديد +چند +بي +نشده +كردن +كردم +گويد +كرده +كنيم +نمي +نزد +روي +قصد +فقط +بالاي +ديگران +اين +ديروز +توسط +سوم +ايم +دانند +سوي +استفاده +شما +كنار +داريم +ساخته +طور +امده +رفته +نخست +بيست +نزديك +طي +كنيد +از +انها +تمامي +داشت +يكي +طريق +اش +چيست +روب +نمايد +گفت +چندين +چيزي +تواند +ام +ايا +با +ان +ايد +ترين +اينكه +ديگري +راه +هايي +بروز +همچنان +پاعين +كس +حدود +مختلف +مقابل +چيز +گيرد +ندارد +ضد +همچون +سازي +شان +مورد +باره +مرسي +خويش +برخوردار +چون +خارج +شش +هنوز +تحت +ضمن +هستيم +گفته +فكر +بسيار +پيش +براي +روزهاي +انكه +نخواهد +بالا +كل +وقتي +كي +چنين +كه +گيري +نيست +است +كجا +كند +نيز +يابد +بندي +حتي +توانند +عقب +خواست +كنند +بين +تمام +همه +ما +باشند +مثل +شد +اري +باشد +اره +طبق +بعد +اگر +صورت +غير +جاي +بيش +ريزي +اند +زيرا +چگونه +بار +لطفا +مي +درباره +من +ديده +همين +گذاري +برداري +علت +گذاشته +هم +فوق +نه +ها +شوند +اباد +همواره +هر +اول +خواهند +چهار +نام +امروز +مان +هاي +قبل +كنم +سعي +تازه +را +هستند +زير +جلوي +عنوان +بود diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_fi.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_fi.txt new file mode 100644 index 00000000000..addad798c4b --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_fi.txt @@ -0,0 +1,95 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/finnish/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + +| forms of BE + +olla +olen +olet +on +olemme +olette +ovat +ole | negative form + +oli +olisi +olisit +olisin +olisimme +olisitte +olisivat +olit +olin +olimme +olitte +olivat +ollut +olleet + +en | negation +et +ei +emme +ette +eivät + +|Nom Gen Acc Part Iness Elat Illat Adess Ablat Allat Ess Trans +minä minun minut minua minussa minusta minuun minulla minulta minulle | I +sinä sinun sinut sinua sinussa sinusta sinuun sinulla sinulta sinulle | you +hän hänen hänet häntä hänessä hänestä häneen hänellä häneltä hänelle | he she +me meidän meidät meitä meissä meistä meihin meillä meiltä meille | we +te teidän teidät teitä teissä teistä teihin teillä teiltä teille | you +he heidän heidät heitä heissä heistä heihin heillä heiltä heille | they + +tämä tämän tätä tässä tästä tähän tallä tältä tälle tänä täksi | this +tuo tuon tuotä tuossa tuosta tuohon tuolla tuolta tuolle tuona tuoksi | that +se sen sitä siinä siitä siihen sillä siltä sille sinä siksi | it +nämä näiden näitä näissä näistä näihin näillä näiltä näille näinä näiksi | these +nuo noiden noita noissa noista noihin noilla noilta noille noina noiksi | those +ne niiden niitä niissä niistä niihin niillä niiltä niille niinä niiksi | they + +kuka kenen kenet ketä kenessä kenestä keneen kenellä keneltä kenelle kenenä keneksi| who +ketkä keiden ketkä keitä keissä keistä keihin keillä keiltä keille keinä keiksi | (pl) +mikä minkä minkä mitä missä mistä mihin millä miltä mille minä miksi | which what +mitkä | (pl) + +joka jonka jota jossa josta johon jolla jolta jolle jona joksi | who which +jotka joiden joita joissa joista joihin joilla joilta joille joina joiksi | (pl) + +| conjunctions + +että | that +ja | and +jos | if +koska | because +kuin | than +mutta | but +niin | so +sekä | and +sillä | for +tai | or +vaan | but +vai | or +vaikka | although + + +| prepositions + +kanssa | with +mukaan | according to +noin | about +poikki | across +yli | over, across + +| other + +kun | when +niin | so +nyt | now +itse | self + diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_fr.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_fr.txt new file mode 100644 index 00000000000..c00837ea939 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_fr.txt @@ -0,0 +1,183 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/french/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A French stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + +au | a + le +aux | a + les +avec | with +ce | this +ces | these +dans | with +de | of +des | de + les +du | de + le +elle | she +en | `of them' etc +et | and +eux | them +il | he +je | I +la | the +le | the +leur | their +lui | him +ma | my (fem) +mais | but +me | me +même | same; as in moi-même (myself) etc +mes | me (pl) +moi | me +mon | my (masc) +ne | not +nos | our (pl) +notre | our +nous | we +on | one +ou | where +par | by +pas | not +pour | for +qu | que before vowel +que | that +qui | who +sa | his, her (fem) +se | oneself +ses | his (pl) +son | his, her (masc) +sur | on +ta | thy (fem) +te | thee +tes | thy (pl) +toi | thee +ton | thy (masc) +tu | thou +un | a +une | a +vos | your (pl) +votre | your +vous | you + + | single letter forms + +c | c' +d | d' +j | j' +l | l' +à | to, at +m | m' +n | n' +s | s' +t | t' +y | there + + | forms of être (not including the infinitive): +été +étée +étées +étés +étant +suis +es +est +sommes +êtes +sont +serai +seras +sera +serons +serez +seront +serais +serait +serions +seriez +seraient +étais +était +étions +étiez +étaient +fus +fut +fûmes +fûtes +furent +sois +soit +soyons +soyez +soient +fusse +fusses +fût +fussions +fussiez +fussent + + | forms of avoir (not including the infinitive): +ayant +eu +eue +eues +eus +ai +as +avons +avez +ont +aurai +auras +aura +aurons +aurez +auront +aurais +aurait +aurions +auriez +auraient +avais +avait +avions +aviez +avaient +eut +eûmes +eûtes +eurent +aie +aies +ait +ayons +ayez +aient +eusse +eusses +eût +eussions +eussiez +eussent + + | Later additions (from Jean-Christophe Deschamps) +ceci | this +celà  | that +cet | this +cette | this +ici | here +ils | they +les | the (pl) +leurs | their (pl) +quel | which +quels | which +quelle | which +quelles | which +sans | without +soi | oneself + diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_ga.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_ga.txt new file mode 100644 index 00000000000..9ff88d747e5 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_ga.txt @@ -0,0 +1,110 @@ + +a +ach +ag +agus +an +aon +ar +arna +as +b' +ba +beirt +bhúr +caoga +ceathair +ceathrar +chomh +chtó +chuig +chun +cois +céad +cúig +cúigear +d' +daichead +dar +de +deich +deichniúr +den +dhá +do +don +dtí +dá +dár +dó +faoi +faoin +faoina +faoinár +fara +fiche +gach +gan +go +gur +haon +hocht +i +iad +idir +in +ina +ins +inár +is +le +leis +lena +lenár +m' +mar +mo +mé +na +nach +naoi +naonúr +ná +ní +níor +nó +nócha +ocht +ochtar +os +roimh +sa +seacht +seachtar +seachtó +seasca +seisear +siad +sibh +sinn +sna +sé +sí +tar +thar +thú +triúr +trí +trína +trínár +tríocha +tú +um +ár +é +éis +í +ó +ón +óna +ónár diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_gl.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_gl.txt new file mode 100644 index 00000000000..d8760b12c14 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_gl.txt @@ -0,0 +1,161 @@ +# galican stopwords +a +aínda +alí +aquel +aquela +aquelas +aqueles +aquilo +aquí +ao +aos +as +así +á +ben +cando +che +co +coa +comigo +con +connosco +contigo +convosco +coas +cos +cun +cuns +cunha +cunhas +da +dalgunha +dalgunhas +dalgún +dalgúns +das +de +del +dela +delas +deles +desde +deste +do +dos +dun +duns +dunha +dunhas +e +el +ela +elas +eles +en +era +eran +esa +esas +ese +eses +esta +estar +estaba +está +están +este +estes +estiven +estou +eu +é +facer +foi +foron +fun +había +hai +iso +isto +la +las +lle +lles +lo +los +mais +me +meu +meus +min +miña +miñas +moi +na +nas +neste +nin +no +non +nos +nosa +nosas +noso +nosos +nós +nun +nunha +nuns +nunhas +o +os +ou +ó +ós +para +pero +pode +pois +pola +polas +polo +polos +por +que +se +senón +ser +seu +seus +sexa +sido +sobre +súa +súas +tamén +tan +te +ten +teñen +teño +ter +teu +teus +ti +tido +tiña +tiven +túa +túas +un +unha +unhas +uns +vos +vosa +vosas +voso +vosos +vós diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_hi.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_hi.txt new file mode 100644 index 00000000000..86286bb083b --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_hi.txt @@ -0,0 +1,235 @@ +# Also see http://www.opensource.org/licenses/bsd-license.html +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# This file was created by Jacques Savoy and is distributed under the BSD license. +# Note: by default this file also contains forms normalized by HindiNormalizer +# for spelling variation (see section below), such that it can be used whether or +# not you enable that feature. When adding additional entries to this list, +# please add the normalized form as well. +अंदर +अत +अपना +अपनी +अपने +अभी +आदि +आप +इत्यादि +इन +इनका +इन्हीं +इन्हें +इन्हों +इस +इसका +इसकी +इसके +इसमें +इसी +इसे +उन +उनका +उनकी +उनके +उनको +उन्हीं +उन्हें +उन्हों +उस +उसके +उसी +उसे +एक +एवं +एस +ऐसे +और +कई +कर +करता +करते +करना +करने +करें +कहते +कहा +का +काफ़ी +कि +कितना +किन्हें +किन्हों +किया +किर +किस +किसी +किसे +की +कुछ +कुल +के +को +कोई +कौन +कौनसा +गया +घर +जब +जहाँ +जा +जितना +जिन +जिन्हें +जिन्हों +जिस +जिसे +जीधर +जैसा +जैसे +जो +तक +तब +तरह +तिन +तिन्हें +तिन्हों +तिस +तिसे +तो +था +थी +थे +दबारा +दिया +दुसरा +दूसरे +दो +द्वारा +न +नहीं +ना +निहायत +नीचे +ने +पर +पर +पहले +पूरा +पे +फिर +बनी +बही +बहुत +बाद +बाला +बिलकुल +भी +भीतर +मगर +मानो +मे +में +यदि +यह +यहाँ +यही +या +यिह +ये +रखें +रहा +रहे +ऱ्वासा +लिए +लिये +लेकिन +व +वर्ग +वह +वह +वहाँ +वहीं +वाले +वुह +वे +वग़ैरह +संग +सकता +सकते +सबसे +सभी +साथ +साबुत +साभ +सारा +से +सो +ही +हुआ +हुई +हुए +है +हैं +हो +होता +होती +होते +होना +होने +# additional normalized forms of the above +अपनि +जेसे +होति +सभि +तिंहों +इंहों +दवारा +इसि +किंहें +थि +उंहों +ओर +जिंहें +वहिं +अभि +बनि +हि +उंहिं +उंहें +हें +वगेरह +एसे +रवासा +कोन +निचे +काफि +उसि +पुरा +भितर +हे +बहि +वहां +कोइ +यहां +जिंहों +तिंहें +किसि +कइ +यहि +इंहिं +जिधर +इंहें +अदि +इतयादि +हुइ +कोनसा +इसकि +दुसरे +जहां +अप +किंहों +उनकि +भि +वरग +हुअ +जेसा +नहिं diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_hu.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_hu.txt new file mode 100644 index 00000000000..1a96f1db6f2 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_hu.txt @@ -0,0 +1,209 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/hungarian/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + +| Hungarian stop word list +| prepared by Anna Tordai + +a +ahogy +ahol +aki +akik +akkor +alatt +által +általában +amely +amelyek +amelyekben +amelyeket +amelyet +amelynek +ami +amit +amolyan +amíg +amikor +át +abban +ahhoz +annak +arra +arról +az +azok +azon +azt +azzal +azért +aztán +azután +azonban +bár +be +belül +benne +cikk +cikkek +cikkeket +csak +de +e +eddig +egész +egy +egyes +egyetlen +egyéb +egyik +egyre +ekkor +el +elég +ellen +elő +először +előtt +első +én +éppen +ebben +ehhez +emilyen +ennek +erre +ez +ezt +ezek +ezen +ezzel +ezért +és +fel +felé +hanem +hiszen +hogy +hogyan +igen +így +illetve +ill. +ill +ilyen +ilyenkor +ison +ismét +itt +jó +jól +jobban +kell +kellett +keresztül +keressünk +ki +kívül +között +közül +legalább +lehet +lehetett +legyen +lenne +lenni +lesz +lett +maga +magát +majd +majd +már +más +másik +meg +még +mellett +mert +mely +melyek +mi +mit +míg +miért +milyen +mikor +minden +mindent +mindenki +mindig +mint +mintha +mivel +most +nagy +nagyobb +nagyon +ne +néha +nekem +neki +nem +néhány +nélkül +nincs +olyan +ott +össze +ő +ők +őket +pedig +persze +rá +s +saját +sem +semmi +sok +sokat +sokkal +számára +szemben +szerint +szinte +talán +tehát +teljes +tovább +továbbá +több +úgy +ugyanis +új +újabb +újra +után +utána +utolsó +vagy +vagyis +valaki +valami +valamint +való +vagyok +van +vannak +volt +voltam +voltak +voltunk +vissza +vele +viszont +volna diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_hy.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_hy.txt new file mode 100644 index 00000000000..60c1c50fbc8 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_hy.txt @@ -0,0 +1,46 @@ +# example set of Armenian stopwords. +այդ +այլ +այն +այս +դու +դուք +եմ +են +ենք +ես +եք +է +էի +էին +էինք +էիր +էիք +էր +ըստ +թ +ի +ին +իսկ +իր +կամ +համար +հետ +հետո +մենք +մեջ +մի +ն +նա +նաև +նրա +նրանք +որ +որը +որոնք +որպես +ու +ում +պիտի +վրա +և diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_id.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_id.txt new file mode 100644 index 00000000000..4617f83a5c5 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_id.txt @@ -0,0 +1,359 @@ +# from appendix D of: A Study of Stemming Effects on Information +# Retrieval in Bahasa Indonesia +ada +adanya +adalah +adapun +agak +agaknya +agar +akan +akankah +akhirnya +aku +akulah +amat +amatlah +anda +andalah +antar +diantaranya +antara +antaranya +diantara +apa +apaan +mengapa +apabila +apakah +apalagi +apatah +atau +ataukah +ataupun +bagai +bagaikan +sebagai +sebagainya +bagaimana +bagaimanapun +sebagaimana +bagaimanakah +bagi +bahkan +bahwa +bahwasanya +sebaliknya +banyak +sebanyak +beberapa +seberapa +begini +beginian +beginikah +beginilah +sebegini +begitu +begitukah +begitulah +begitupun +sebegitu +belum +belumlah +sebelum +sebelumnya +sebenarnya +berapa +berapakah +berapalah +berapapun +betulkah +sebetulnya +biasa +biasanya +bila +bilakah +bisa +bisakah +sebisanya +boleh +bolehkah +bolehlah +buat +bukan +bukankah +bukanlah +bukannya +cuma +percuma +dahulu +dalam +dan +dapat +dari +daripada +dekat +demi +demikian +demikianlah +sedemikian +dengan +depan +di +dia +dialah +dini +diri +dirinya +terdiri +dong +dulu +enggak +enggaknya +entah +entahlah +terhadap +terhadapnya +hal +hampir +hanya +hanyalah +harus +haruslah +harusnya +seharusnya +hendak +hendaklah +hendaknya +hingga +sehingga +ia +ialah +ibarat +ingin +inginkah +inginkan +ini +inikah +inilah +itu +itukah +itulah +jangan +jangankan +janganlah +jika +jikalau +juga +justru +kala +kalau +kalaulah +kalaupun +kalian +kami +kamilah +kamu +kamulah +kan +kapan +kapankah +kapanpun +dikarenakan +karena +karenanya +ke +kecil +kemudian +kenapa +kepada +kepadanya +ketika +seketika +khususnya +kini +kinilah +kiranya +sekiranya +kita +kitalah +kok +lagi +lagian +selagi +lah +lain +lainnya +melainkan +selaku +lalu +melalui +terlalu +lama +lamanya +selama +selama +selamanya +lebih +terlebih +bermacam +macam +semacam +maka +makanya +makin +malah +malahan +mampu +mampukah +mana +manakala +manalagi +masih +masihkah +semasih +masing +mau +maupun +semaunya +memang +mereka +merekalah +meski +meskipun +semula +mungkin +mungkinkah +nah +namun +nanti +nantinya +nyaris +oleh +olehnya +seorang +seseorang +pada +padanya +padahal +paling +sepanjang +pantas +sepantasnya +sepantasnyalah +para +pasti +pastilah +per +pernah +pula +pun +merupakan +rupanya +serupa +saat +saatnya +sesaat +saja +sajalah +saling +bersama +sama +sesama +sambil +sampai +sana +sangat +sangatlah +saya +sayalah +se +sebab +sebabnya +sebuah +tersebut +tersebutlah +sedang +sedangkan +sedikit +sedikitnya +segala +segalanya +segera +sesegera +sejak +sejenak +sekali +sekalian +sekalipun +sesekali +sekaligus +sekarang +sekarang +sekitar +sekitarnya +sela +selain +selalu +seluruh +seluruhnya +semakin +sementara +sempat +semua +semuanya +sendiri +sendirinya +seolah +seperti +sepertinya +sering +seringnya +serta +siapa +siapakah +siapapun +disini +disinilah +sini +sinilah +sesuatu +sesuatunya +suatu +sesudah +sesudahnya +sudah +sudahkah +sudahlah +supaya +tadi +tadinya +tak +tanpa +setelah +telah +tentang +tentu +tentulah +tentunya +tertentu +seterusnya +tapi +tetapi +setiap +tiap +setidaknya +tidak +tidakkah +tidaklah +toh +waduh +wah +wahai +sewaktu +walau +walaupun +wong +yaitu +yakni +yang diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_it.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_it.txt new file mode 100644 index 00000000000..4cb5b0891b1 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_it.txt @@ -0,0 +1,301 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/italian/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | An Italian stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + +ad | a (to) before vowel +al | a + il +allo | a + lo +ai | a + i +agli | a + gli +all | a + l' +agl | a + gl' +alla | a + la +alle | a + le +con | with +col | con + il +coi | con + i (forms collo, cogli etc are now very rare) +da | from +dal | da + il +dallo | da + lo +dai | da + i +dagli | da + gli +dall | da + l' +dagl | da + gll' +dalla | da + la +dalle | da + le +di | of +del | di + il +dello | di + lo +dei | di + i +degli | di + gli +dell | di + l' +degl | di + gl' +della | di + la +delle | di + le +in | in +nel | in + el +nello | in + lo +nei | in + i +negli | in + gli +nell | in + l' +negl | in + gl' +nella | in + la +nelle | in + le +su | on +sul | su + il +sullo | su + lo +sui | su + i +sugli | su + gli +sull | su + l' +sugl | su + gl' +sulla | su + la +sulle | su + le +per | through, by +tra | among +contro | against +io | I +tu | thou +lui | he +lei | she +noi | we +voi | you +loro | they +mio | my +mia | +miei | +mie | +tuo | +tua | +tuoi | thy +tue | +suo | +sua | +suoi | his, her +sue | +nostro | our +nostra | +nostri | +nostre | +vostro | your +vostra | +vostri | +vostre | +mi | me +ti | thee +ci | us, there +vi | you, there +lo | him, the +la | her, the +li | them +le | them, the +gli | to him, the +ne | from there etc +il | the +un | a +uno | a +una | a +ma | but +ed | and +se | if +perché | why, because +anche | also +come | how +dov | where (as dov') +dove | where +che | who, that +chi | who +cui | whom +non | not +più | more +quale | who, that +quanto | how much +quanti | +quanta | +quante | +quello | that +quelli | +quella | +quelle | +questo | this +questi | +questa | +queste | +si | yes +tutto | all +tutti | all + + | single letter forms: + +a | at +c | as c' for ce or ci +e | and +i | the +l | as l' +o | or + + | forms of avere, to have (not including the infinitive): + +ho +hai +ha +abbiamo +avete +hanno +abbia +abbiate +abbiano +avrò +avrai +avrà +avremo +avrete +avranno +avrei +avresti +avrebbe +avremmo +avreste +avrebbero +avevo +avevi +aveva +avevamo +avevate +avevano +ebbi +avesti +ebbe +avemmo +aveste +ebbero +avessi +avesse +avessimo +avessero +avendo +avuto +avuta +avuti +avute + + | forms of essere, to be (not including the infinitive): +sono +sei +è +siamo +siete +sia +siate +siano +sarò +sarai +sarà +saremo +sarete +saranno +sarei +saresti +sarebbe +saremmo +sareste +sarebbero +ero +eri +era +eravamo +eravate +erano +fui +fosti +fu +fummo +foste +furono +fossi +fosse +fossimo +fossero +essendo + + | forms of fare, to do (not including the infinitive, fa, fat-): +faccio +fai +facciamo +fanno +faccia +facciate +facciano +farò +farai +farà +faremo +farete +faranno +farei +faresti +farebbe +faremmo +fareste +farebbero +facevo +facevi +faceva +facevamo +facevate +facevano +feci +facesti +fece +facemmo +faceste +fecero +facessi +facesse +facessimo +facessero +facendo + + | forms of stare, to be (not including the infinitive): +sto +stai +sta +stiamo +stanno +stia +stiate +stiano +starò +starai +starà +staremo +starete +staranno +starei +staresti +starebbe +staremmo +stareste +starebbero +stavo +stavi +stava +stavamo +stavate +stavano +stetti +stesti +stette +stemmo +steste +stettero +stessi +stesse +stessimo +stessero +stando diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_ja.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_ja.txt new file mode 100644 index 00000000000..d4321be6b16 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_ja.txt @@ -0,0 +1,127 @@ +# +# This file defines a stopword set for Japanese. +# +# This set is made up of hand-picked frequent terms from segmented Japanese Wikipedia. +# Punctuation characters and frequent kanji have mostly been left out. See LUCENE-3745 +# for frequency lists, etc. that can be useful for making your own set (if desired) +# +# Note that there is an overlap between these stopwords and the terms stopped when used +# in combination with the JapanesePartOfSpeechStopFilter. When editing this file, note +# that comments are not allowed on the same line as stopwords. +# +# Also note that stopping is done in a case-insensitive manner. Change your StopFilter +# configuration if you need case-sensitive stopping. Lastly, note that stopping is done +# using the same character width as the entries in this file. Since this StopFilter is +# normally done after a CJKWidthFilter in your chain, you would usually want your romaji +# entries to be in half-width and your kana entries to be in full-width. +# +の +に +は +を +た +が +で +て +と +し +れ +さ +ある +いる +も +する +から +な +こと +として +い +や +れる +など +なっ +ない +この +ため +その +あっ +よう +また +もの +という +あり +まで +られ +なる +へ +か +だ +これ +によって +により +おり +より +による +ず +なり +られる +において +ば +なかっ +なく +しかし +について +せ +だっ +その後 +できる +それ +う +ので +なお +のみ +でき +き +つ +における +および +いう +さらに +でも +ら +たり +その他 +に関する +たち +ます +ん +なら +に対して +特に +せる +及び +これら +とき +では +にて +ほか +ながら +うち +そして +とともに +ただし +かつて +それぞれ +または +お +ほど +ものの +に対する +ほとんど +と共に +といった +です +とも +ところ +ここ +##### End of file diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_lv.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_lv.txt new file mode 100644 index 00000000000..e21a23c06c3 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_lv.txt @@ -0,0 +1,172 @@ +# Set of Latvian stopwords from A Stemming Algorithm for Latvian, Karlis Kreslins +# the original list of over 800 forms was refined: +# pronouns, adverbs, interjections were removed +# +# prepositions +aiz +ap +ar +apakš +ārpus +augšpus +bez +caur +dēļ +gar +iekš +iz +kopš +labad +lejpus +līdz +no +otrpus +pa +par +pār +pēc +pie +pirms +pret +priekš +starp +šaipus +uz +viņpus +virs +virspus +zem +apakšpus +# Conjunctions +un +bet +jo +ja +ka +lai +tomēr +tikko +turpretī +arī +kaut +gan +tādēļ +tā +ne +tikvien +vien +kā +ir +te +vai +kamēr +# Particles +ar +diezin +droši +diemžēl +nebūt +ik +it +taču +nu +pat +tiklab +iekšpus +nedz +tik +nevis +turpretim +jeb +iekam +iekām +iekāms +kolīdz +līdzko +tiklīdz +jebšu +tālab +tāpēc +nekā +itin +jā +jau +jel +nē +nezin +tad +tikai +vis +tak +iekams +vien +# modal verbs +būt +biju +biji +bija +bijām +bijāt +esmu +esi +esam +esat +būšu +būsi +būs +būsim +būsiet +tikt +tiku +tiki +tika +tikām +tikāt +tieku +tiec +tiek +tiekam +tiekat +tikšu +tiks +tiksim +tiksiet +tapt +tapi +tapāt +topat +tapšu +tapsi +taps +tapsim +tapsiet +kļūt +kļuvu +kļuvi +kļuva +kļuvām +kļuvāt +kļūstu +kļūsti +kļūst +kļūstam +kļūstat +kļūšu +kļūsi +kļūs +kļūsim +kļūsiet +# verbs +varēt +varēju +varējām +varēšu +varēsim +var +varēji +varējāt +varēsi +varēsiet +varat +varēja +varēs diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_nl.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_nl.txt new file mode 100644 index 00000000000..f4d61f5092c --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_nl.txt @@ -0,0 +1,117 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/dutch/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Dutch stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | This is a ranked list (commonest to rarest) of stopwords derived from + | a large sample of Dutch text. + + | Dutch stop words frequently exhibit homonym clashes. These are indicated + | clearly below. + +de | the +en | and +van | of, from +ik | I, the ego +te | (1) chez, at etc, (2) to, (3) too +dat | that, which +die | that, those, who, which +in | in, inside +een | a, an, one +hij | he +het | the, it +niet | not, nothing, naught +zijn | (1) to be, being, (2) his, one's, its +is | is +was | (1) was, past tense of all persons sing. of 'zijn' (to be) (2) wax, (3) the washing, (4) rise of river +op | on, upon, at, in, up, used up +aan | on, upon, to (as dative) +met | with, by +als | like, such as, when +voor | (1) before, in front of, (2) furrow +had | had, past tense all persons sing. of 'hebben' (have) +er | there +maar | but, only +om | round, about, for etc +hem | him +dan | then +zou | should/would, past tense all persons sing. of 'zullen' +of | or, whether, if +wat | what, something, anything +mijn | possessive and noun 'mine' +men | people, 'one' +dit | this +zo | so, thus, in this way +door | through by +over | over, across +ze | she, her, they, them +zich | oneself +bij | (1) a bee, (2) by, near, at +ook | also, too +tot | till, until +je | you +mij | me +uit | out of, from +der | Old Dutch form of 'van der' still found in surnames +daar | (1) there, (2) because +haar | (1) her, their, them, (2) hair +naar | (1) unpleasant, unwell etc, (2) towards, (3) as +heb | present first person sing. of 'to have' +hoe | how, why +heeft | present third person sing. of 'to have' +hebben | 'to have' and various parts thereof +deze | this +u | you +want | (1) for, (2) mitten, (3) rigging +nog | yet, still +zal | 'shall', first and third person sing. of verb 'zullen' (will) +me | me +zij | she, they +nu | now +ge | 'thou', still used in Belgium and south Netherlands +geen | none +omdat | because +iets | something, somewhat +worden | to become, grow, get +toch | yet, still +al | all, every, each +waren | (1) 'were' (2) to wander, (3) wares, (3) +veel | much, many +meer | (1) more, (2) lake +doen | to do, to make +toen | then, when +moet | noun 'spot/mote' and present form of 'to must' +ben | (1) am, (2) 'are' in interrogative second person singular of 'to be' +zonder | without +kan | noun 'can' and present form of 'to be able' +hun | their, them +dus | so, consequently +alles | all, everything, anything +onder | under, beneath +ja | yes, of course +eens | once, one day +hier | here +wie | who +werd | imperfect third person sing. of 'become' +altijd | always +doch | yet, but etc +wordt | present third person sing. of 'become' +wezen | (1) to be, (2) 'been' as in 'been fishing', (3) orphans +kunnen | to be able +ons | us/our +zelf | self +tegen | against, towards, at +na | after, near +reeds | already +wil | (1) present tense of 'want', (2) 'will', noun, (3) fender +kon | could; past tense of 'to be able' +niets | nothing +uw | your +iemand | somebody +geweest | been; past participle of 'be' +andere | other diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_no.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_no.txt new file mode 100644 index 00000000000..e76f36e69ed --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_no.txt @@ -0,0 +1,192 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/norwegian/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Norwegian stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | This stop word list is for the dominant bokmål dialect. Words unique + | to nynorsk are marked *. + + | Revised by Jan Bruusgaard , Jan 2005 + +og | and +i | in +jeg | I +det | it/this/that +at | to (w. inf.) +en | a/an +et | a/an +den | it/this/that +til | to +er | is/am/are +som | who/that +på | on +de | they / you(formal) +med | with +han | he +av | of +ikke | not +ikkje | not * +der | there +så | so +var | was/were +meg | me +seg | you +men | but +ett | one +har | have +om | about +vi | we +min | my +mitt | my +ha | have +hadde | had +hun | she +nå | now +over | over +da | when/as +ved | by/know +fra | from +du | you +ut | out +sin | your +dem | them +oss | us +opp | up +man | you/one +kan | can +hans | his +hvor | where +eller | or +hva | what +skal | shall/must +selv | self (reflective) +sjøl | self (reflective) +her | here +alle | all +vil | will +bli | become +ble | became +blei | became * +blitt | have become +kunne | could +inn | in +når | when +være | be +kom | come +noen | some +noe | some +ville | would +dere | you +som | who/which/that +deres | their/theirs +kun | only/just +ja | yes +etter | after +ned | down +skulle | should +denne | this +for | for/because +deg | you +si | hers/his +sine | hers/his +sitt | hers/his +mot | against +å | to +meget | much +hvorfor | why +dette | this +disse | these/those +uten | without +hvordan | how +ingen | none +din | your +ditt | your +blir | become +samme | same +hvilken | which +hvilke | which (plural) +sånn | such a +inni | inside/within +mellom | between +vår | our +hver | each +hvem | who +vors | us/ours +hvis | whose +både | both +bare | only/just +enn | than +fordi | as/because +før | before +mange | many +også | also +slik | just +vært | been +være | to be +båe | both * +begge | both +siden | since +dykk | your * +dykkar | yours * +dei | they * +deira | them * +deires | theirs * +deim | them * +di | your (fem.) * +då | as/when * +eg | I * +ein | a/an * +eit | a/an * +eitt | a/an * +elles | or * +honom | he * +hjå | at * +ho | she * +hoe | she * +henne | her +hennar | her/hers +hennes | hers +hoss | how * +hossen | how * +ikkje | not * +ingi | noone * +inkje | noone * +korleis | how * +korso | how * +kva | what/which * +kvar | where * +kvarhelst | where * +kven | who/whom * +kvi | why * +kvifor | why * +me | we * +medan | while * +mi | my * +mine | my * +mykje | much * +no | now * +nokon | some (masc./neut.) * +noka | some (fem.) * +nokor | some * +noko | some * +nokre | some * +si | his/hers * +sia | since * +sidan | since * +so | so * +somt | some * +somme | some * +um | about* +upp | up * +vere | be * +vore | was * +verte | become * +vort | become * +varte | became * +vart | became * + diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_pt.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_pt.txt new file mode 100644 index 00000000000..276c1b446f2 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_pt.txt @@ -0,0 +1,251 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/portuguese/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Portuguese stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + + | The following is a ranked list (commonest to rarest) of stopwords + | deriving from a large sample of text. + + | Extra words have been added at the end. + +de | of, from +a | the; to, at; her +o | the; him +que | who, that +e | and +do | de + o +da | de + a +em | in +um | a +para | for + | é from SER +com | with +não | not, no +uma | a +os | the; them +no | em + o +se | himself etc +na | em + a +por | for +mais | more +as | the; them +dos | de + os +como | as, like +mas | but + | foi from SER +ao | a + o +ele | he +das | de + as + | tem from TER +à | a + a +seu | his +sua | her +ou | or + | ser from SER +quando | when +muito | much + | há from HAV +nos | em + os; us +já | already, now + | está from EST +eu | I +também | also +só | only, just +pelo | per + o +pela | per + a +até | up to +isso | that +ela | he +entre | between + | era from SER +depois | after +sem | without +mesmo | same +aos | a + os + | ter from TER +seus | his +quem | whom +nas | em + as +me | me +esse | that +eles | they + | estão from EST +você | you + | tinha from TER + | foram from SER +essa | that +num | em + um +nem | nor +suas | her +meu | my +às | a + as +minha | my + | têm from TER +numa | em + uma +pelos | per + os +elas | they + | havia from HAV + | seja from SER +qual | which + | será from SER +nós | we + | tenho from TER +lhe | to him, her +deles | of them +essas | those +esses | those +pelas | per + as +este | this + | fosse from SER +dele | of him + + | other words. There are many contractions such as naquele = em+aquele, + | mo = me+o, but they are rare. + | Indefinite article plural forms are also rare. + +tu | thou +te | thee +vocês | you (plural) +vos | you +lhes | to them +meus | my +minhas +teu | thy +tua +teus +tuas +nosso | our +nossa +nossos +nossas + +dela | of her +delas | of them + +esta | this +estes | these +estas | these +aquele | that +aquela | that +aqueles | those +aquelas | those +isto | this +aquilo | that + + | forms of estar, to be (not including the infinitive): +estou +está +estamos +estão +estive +esteve +estivemos +estiveram +estava +estávamos +estavam +estivera +estivéramos +esteja +estejamos +estejam +estivesse +estivéssemos +estivessem +estiver +estivermos +estiverem + + | forms of haver, to have (not including the infinitive): +hei +há +havemos +hão +houve +houvemos +houveram +houvera +houvéramos +haja +hajamos +hajam +houvesse +houvéssemos +houvessem +houver +houvermos +houverem +houverei +houverá +houveremos +houverão +houveria +houveríamos +houveriam + + | forms of ser, to be (not including the infinitive): +sou +somos +são +era +éramos +eram +fui +foi +fomos +foram +fora +fôramos +seja +sejamos +sejam +fosse +fôssemos +fossem +for +formos +forem +serei +será +seremos +serão +seria +seríamos +seriam + + | forms of ter, to have (not including the infinitive): +tenho +tem +temos +tém +tinha +tínhamos +tinham +tive +teve +tivemos +tiveram +tivera +tivéramos +tenha +tenhamos +tenham +tivesse +tivéssemos +tivessem +tiver +tivermos +tiverem +terei +terá +teremos +terão +teria +teríamos +teriam diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_ro.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_ro.txt new file mode 100644 index 00000000000..4fdee90a5ba --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_ro.txt @@ -0,0 +1,233 @@ +# This file was created by Jacques Savoy and is distributed under the BSD license. +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# Also see http://www.opensource.org/licenses/bsd-license.html +acea +aceasta +această +aceea +acei +aceia +acel +acela +acele +acelea +acest +acesta +aceste +acestea +aceşti +aceştia +acolo +acum +ai +aia +aibă +aici +al +ăla +ale +alea +ălea +altceva +altcineva +am +ar +are +aş +aşadar +asemenea +asta +ăsta +astăzi +astea +ăstea +ăştia +asupra +aţi +au +avea +avem +aveţi +azi +bine +bucur +bună +ca +că +căci +când +care +cărei +căror +cărui +cât +câte +câţi +către +câtva +ce +cel +ceva +chiar +cînd +cine +cineva +cît +cîte +cîţi +cîtva +contra +cu +cum +cumva +curând +curînd +da +dă +dacă +dar +datorită +de +deci +deja +deoarece +departe +deşi +din +dinaintea +dintr +dintre +drept +după +ea +ei +el +ele +eram +este +eşti +eu +face +fără +fi +fie +fiecare +fii +fim +fiţi +iar +ieri +îi +îl +îmi +împotriva +în +înainte +înaintea +încât +încît +încotro +între +întrucât +întrucît +îţi +la +lângă +le +li +lîngă +lor +lui +mă +mâine +mea +mei +mele +mereu +meu +mi +mine +mult +multă +mulţi +ne +nicăieri +nici +nimeni +nişte +noastră +noastre +noi +noştri +nostru +nu +ori +oricând +oricare +oricât +orice +oricînd +oricine +oricît +oricum +oriunde +până +pe +pentru +peste +pînă +poate +pot +prea +prima +primul +prin +printr +sa +să +săi +sale +sau +său +se +şi +sînt +sîntem +sînteţi +spre +sub +sunt +suntem +sunteţi +ta +tăi +tale +tău +te +ţi +ţie +tine +toată +toate +tot +toţi +totuşi +tu +un +una +unde +undeva +unei +unele +uneori +unor +vă +vi +voastră +voastre +voi +voştri +vostru +vouă +vreo +vreun diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_ru.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_ru.txt new file mode 100644 index 00000000000..64307693457 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_ru.txt @@ -0,0 +1,241 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/russian/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | a russian stop word list. comments begin with vertical bar. each stop + | word is at the start of a line. + + | this is a ranked list (commonest to rarest) of stopwords derived from + | a large text sample. + + | letter `ё' is translated to `е'. + +и | and +в | in/into +во | alternative form +не | not +что | what/that +он | he +на | on/onto +я | i +с | from +со | alternative form +как | how +а | milder form of `no' (but) +то | conjunction and form of `that' +все | all +она | she +так | so, thus +его | him +но | but +да | yes/and +ты | thou +к | towards, by +у | around, chez +же | intensifier particle +вы | you +за | beyond, behind +бы | conditional/subj. particle +по | up to, along +только | only +ее | her +мне | to me +было | it was +вот | here is/are, particle +от | away from +меня | me +еще | still, yet, more +нет | no, there isnt/arent +о | about +из | out of +ему | to him +теперь | now +когда | when +даже | even +ну | so, well +вдруг | suddenly +ли | interrogative particle +если | if +уже | already, but homonym of `narrower' +или | or +ни | neither +быть | to be +был | he was +него | prepositional form of его +до | up to +вас | you accusative +нибудь | indef. suffix preceded by hyphen +опять | again +уж | already, but homonym of `adder' +вам | to you +сказал | he said +ведь | particle `after all' +там | there +потом | then +себя | oneself +ничего | nothing +ей | to her +может | usually with `быть' as `maybe' +они | they +тут | here +где | where +есть | there is/are +надо | got to, must +ней | prepositional form of ей +для | for +мы | we +тебя | thee +их | them, their +чем | than +была | she was +сам | self +чтоб | in order to +без | without +будто | as if +человек | man, person, one +чего | genitive form of `what' +раз | once +тоже | also +себе | to oneself +под | beneath +жизнь | life +будет | will be +ж | short form of intensifer particle `же' +тогда | then +кто | who +этот | this +говорил | was saying +того | genitive form of `that' +потому | for that reason +этого | genitive form of `this' +какой | which +совсем | altogether +ним | prepositional form of `его', `они' +здесь | here +этом | prepositional form of `этот' +один | one +почти | almost +мой | my +тем | instrumental/dative plural of `тот', `то' +чтобы | full form of `in order that' +нее | her (acc.) +кажется | it seems +сейчас | now +были | they were +куда | where to +зачем | why +сказать | to say +всех | all (acc., gen. preposn. plural) +никогда | never +сегодня | today +можно | possible, one can +при | by +наконец | finally +два | two +об | alternative form of `о', about +другой | another +хоть | even +после | after +над | above +больше | more +тот | that one (masc.) +через | across, in +эти | these +нас | us +про | about +всего | in all, only, of all +них | prepositional form of `они' (they) +какая | which, feminine +много | lots +разве | interrogative particle +сказала | she said +три | three +эту | this, acc. fem. sing. +моя | my, feminine +впрочем | moreover, besides +хорошо | good +свою | ones own, acc. fem. sing. +этой | oblique form of `эта', fem. `this' +перед | in front of +иногда | sometimes +лучше | better +чуть | a little +том | preposn. form of `that one' +нельзя | one must not +такой | such a one +им | to them +более | more +всегда | always +конечно | of course +всю | acc. fem. sing of `all' +между | between + + + | b: some paradigms + | + | personal pronouns + | + | я меня мне мной [мною] + | ты тебя тебе тобой [тобою] + | он его ему им [него, нему, ним] + | она ее эи ею [нее, нэи, нею] + | оно его ему им [него, нему, ним] + | + | мы нас нам нами + | вы вас вам вами + | они их им ими [них, ним, ними] + | + | себя себе собой [собою] + | + | demonstrative pronouns: этот (this), тот (that) + | + | этот эта это эти + | этого эты это эти + | этого этой этого этих + | этому этой этому этим + | этим этой этим [этою] этими + | этом этой этом этих + | + | тот та то те + | того ту то те + | того той того тех + | тому той тому тем + | тем той тем [тою] теми + | том той том тех + | + | determinative pronouns + | + | (a) весь (all) + | + | весь вся все все + | всего всю все все + | всего всей всего всех + | всему всей всему всем + | всем всей всем [всею] всеми + | всем всей всем всех + | + | (b) сам (himself etc) + | + | сам сама само сами + | самого саму само самих + | самого самой самого самих + | самому самой самому самим + | самим самой самим [самою] самими + | самом самой самом самих + | + | stems of verbs `to be', `to have', `to do' and modal + | + | быть бы буд быв есть суть + | име + | дел + | мог мож мочь + | уме + | хоч хот + | долж + | можн + | нужн + | нельзя + diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_sv.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_sv.txt new file mode 100644 index 00000000000..22bddfd8cb3 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_sv.txt @@ -0,0 +1,131 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/swedish/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Swedish stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | This is a ranked list (commonest to rarest) of stopwords derived from + | a large text sample. + + | Swedish stop words occasionally exhibit homonym clashes. For example + | så = so, but also seed. These are indicated clearly below. + +och | and +det | it, this/that +att | to (with infinitive) +i | in, at +en | a +jag | I +hon | she +som | who, that +han | he +på | on +den | it, this/that +med | with +var | where, each +sig | him(self) etc +för | for +så | so (also: seed) +till | to +är | is +men | but +ett | a +om | if; around, about +hade | had +de | they, these/those +av | of +icke | not, no +mig | me +du | you +henne | her +då | then, when +sin | his +nu | now +har | have +inte | inte någon = no one +hans | his +honom | him +skulle | 'sake' +hennes | her +där | there +min | my +man | one (pronoun) +ej | nor +vid | at, by, on (also: vast) +kunde | could +något | some etc +från | from, off +ut | out +när | when +efter | after, behind +upp | up +vi | we +dem | them +vara | be +vad | what +över | over +än | than +dig | you +kan | can +sina | his +här | here +ha | have +mot | towards +alla | all +under | under (also: wonder) +någon | some etc +eller | or (else) +allt | all +mycket | much +sedan | since +ju | why +denna | this/that +själv | myself, yourself etc +detta | this/that +åt | to +utan | without +varit | was +hur | how +ingen | no +mitt | my +ni | you +bli | to be, become +blev | from bli +oss | us +din | thy +dessa | these/those +några | some etc +deras | their +blir | from bli +mina | my +samma | (the) same +vilken | who, that +er | you, your +sådan | such a +vår | our +blivit | from bli +dess | its +inom | within +mellan | between +sådant | such a +varför | why +varje | each +vilka | who, that +ditt | thy +vem | who +vilket | who, that +sitta | his +sådana | such a +vart | each +dina | thy +vars | whose +vårt | our +våra | our +ert | your +era | your +vilkas | whose + diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_th.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_th.txt new file mode 100644 index 00000000000..07f0fabe692 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_th.txt @@ -0,0 +1,119 @@ +# Thai stopwords from: +# "Opinion Detection in Thai Political News Columns +# Based on Subjectivity Analysis" +# Khampol Sukhum, Supot Nitsuwat, and Choochart Haruechaiyasak +ไว้ +ไม่ +ไป +ได้ +ให้ +ใน +โดย +แห่ง +แล้ว +และ +แรก +แบบ +แต่ +เอง +เห็น +เลย +เริ่ม +เรา +เมื่อ +เพื่อ +เพราะ +เป็นการ +เป็น +เปิดเผย +เปิด +เนื่องจาก +เดียวกัน +เดียว +เช่น +เฉพาะ +เคย +เข้า +เขา +อีก +อาจ +อะไร +ออก +อย่าง +อยู่ +อยาก +หาก +หลาย +หลังจาก +หลัง +หรือ +หนึ่ง +ส่วน +ส่ง +สุด +สําหรับ +ว่า +วัน +ลง +ร่วม +ราย +รับ +ระหว่าง +รวม +ยัง +มี +มาก +มา +พร้อม +พบ +ผ่าน +ผล +บาง +น่า +นี้ +นํา +นั้น +นัก +นอกจาก +ทุก +ที่สุด +ที่ +ทําให้ +ทํา +ทาง +ทั้งนี้ +ทั้ง +ถ้า +ถูก +ถึง +ต้อง +ต่างๆ +ต่าง +ต่อ +ตาม +ตั้งแต่ +ตั้ง +ด้าน +ด้วย +ดัง +ซึ่ง +ช่วง +จึง +จาก +จัด +จะ +คือ +ความ +ครั้ง +คง +ขึ้น +ของ +ขอ +ขณะ +ก่อน +ก็ +การ +กับ +กัน +กว่า +กล่าว diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_tr.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_tr.txt new file mode 100644 index 00000000000..84d9408d4ea --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_tr.txt @@ -0,0 +1,212 @@ +# Turkish stopwords from LUCENE-559 +# merged with the list from "Information Retrieval on Turkish Texts" +# (http://www.users.muohio.edu/canf/papers/JASIST2008offPrint.pdf) +acaba +altmış +altı +ama +ancak +arada +aslında +ayrıca +bana +bazı +belki +ben +benden +beni +benim +beri +beş +bile +bin +bir +birçok +biri +birkaç +birkez +birşey +birşeyi +biz +bize +bizden +bizi +bizim +böyle +böylece +bu +buna +bunda +bundan +bunlar +bunları +bunların +bunu +bunun +burada +çok +çünkü +da +daha +dahi +de +defa +değil +diğer +diye +doksan +dokuz +dolayı +dolayısıyla +dört +edecek +eden +ederek +edilecek +ediliyor +edilmesi +ediyor +eğer +elli +en +etmesi +etti +ettiği +ettiğini +gibi +göre +halen +hangi +hatta +hem +henüz +hep +hepsi +her +herhangi +herkesin +hiç +hiçbir +için +iki +ile +ilgili +ise +işte +itibaren +itibariyle +kadar +karşın +katrilyon +kendi +kendilerine +kendini +kendisi +kendisine +kendisini +kez +ki +kim +kimden +kime +kimi +kimse +kırk +milyar +milyon +mu +mü +mı +nasıl +ne +neden +nedenle +nerde +nerede +nereye +niye +niçin +o +olan +olarak +oldu +olduğu +olduğunu +olduklarını +olmadı +olmadığı +olmak +olması +olmayan +olmaz +olsa +olsun +olup +olur +olursa +oluyor +on +ona +ondan +onlar +onlardan +onları +onların +onu +onun +otuz +oysa +öyle +pek +rağmen +sadece +sanki +sekiz +seksen +sen +senden +seni +senin +siz +sizden +sizi +sizin +şey +şeyden +şeyi +şeyler +şöyle +şu +şuna +şunda +şundan +şunları +şunu +tarafından +trilyon +tüm +üç +üzere +var +vardı +ve +veya +ya +yani +yapacak +yapılan +yapılması +yapıyor +yapmak +yaptı +yaptığı +yaptığını +yaptıkları +yedi +yerine +yetmiş +yine +yirmi +yoksa +yüz +zaten diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/userdict_ja.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/userdict_ja.txt new file mode 100644 index 00000000000..6f0368e4d81 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/userdict_ja.txt @@ -0,0 +1,29 @@ +# +# This is a sample user dictionary for Kuromoji (JapaneseTokenizer) +# +# Add entries to this file in order to override the statistical model in terms +# of segmentation, readings and part-of-speech tags. Notice that entries do +# not have weights since they are always used when found. This is by-design +# in order to maximize ease-of-use. +# +# Entries are defined using the following CSV format: +# , ... , ... , +# +# Notice that a single half-width space separates tokens and readings, and +# that the number tokens and readings must match exactly. +# +# Also notice that multiple entries with the same is undefined. +# +# Whitespace only lines are ignored. Comments are not allowed on entry lines. +# + +# Custom segmentation for kanji compounds +日本経済新聞,日本 経済 新聞,ニホン ケイザイ シンブン,カスタム名詞 +関西国際空港,関西 国際 空港,カンサイ コクサイ クウコウ,カスタム名詞 + +# Custom segmentation for compound katakana +トートバッグ,トート バッグ,トート バッグ,かずカナ名詞 +ショルダーバッグ,ショルダー バッグ,ショルダー バッグ,かずカナ名詞 + +# Custom reading for former sumo wrestler +朝青龍,朝青龍,アサショウリュウ,カスタム人名 diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/protwords.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/protwords.txt new file mode 100644 index 00000000000..1dfc0abecbf --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/protwords.txt @@ -0,0 +1,21 @@ +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#----------------------------------------------------------------------- +# Use a protected word file to protect against the stemmer reducing two +# unrelated words to the same base word. + +# Some non-words that normally won't be encountered, +# just to test that they won't be stemmed. +dontstems +zwhacky + diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/schema.xml b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/schema.xml new file mode 100644 index 00000000000..b133c135f31 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/schema.xml @@ -0,0 +1,961 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/solrconfig.xml b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/solrconfig.xml new file mode 100644 index 00000000000..f9683b27db7 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/solrconfig.xml @@ -0,0 +1,1789 @@ + + + + + + + + + LUCENE_43 + + + + + + + + + + + + + + + + + + + + + + + + ${solr.data.dir:} + + + + + ${solr.hdfs.home:} + ${solr.hdfs.confdir:} + ${solr.hdfs.security.kerberos.enabled:false} + ${solr.hdfs.security.kerberos.keytabfile:} + ${solr.hdfs.security.kerberos.principal:} + ${solr.hdfs.blockcache.enabled:true} + ${solr.hdfs.blockcache.slab.count:1} + ${solr.hdfs.blockcache.direct.memory.allocation:true} + ${solr.hdfs.blockcache.blocksperbank:16384} + ${solr.hdfs.blockcache.read.enabled:true} + ${solr.hdfs.blockcache.write.enabled:true} + ${solr.hdfs.nrtcachingdirectory.enable:true} + ${solr.hdfs.nrtcachingdirectory.maxmergesizemb:16} + ${solr.hdfs.nrtcachingdirectory.maxcachedmb:192} + + + + + + + + + + + + + ${solr.maxIndexingThreads:8} + + + + + + 128 + + + + + + + + + + + + + ${solr.lock.type:hdfs} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${solr.autoCommit.maxTime:60000} + false + + + + + ${solr.autoSoftCommit.maxTime:1000} + + + + + + + + + + + + + + + + + + + 1024 + + + + + + + + + + + + + + + + + + + + + + true + + + + + + 20 + + + 200 + + + + + + + + + + + + static firstSearcher warming in solrconfig.xml + + + + + + false + + + 4 + + + + + + + + + + + + + + + + + + + + + + + explicit + 10 + text + + + + + + + + + + + + + + explicit + json + true + text + + + + + + + + true + json + true + + + + + + + + explicit + + + velocity + browse + layout + Solritas + + + edismax + + text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 + title^10.0 description^5.0 keywords^5.0 author^2.0 resourcename^1.0 + + text + 100% + *:* + 10 + *,score + + + text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 + title^10.0 description^5.0 keywords^5.0 author^2.0 resourcename^1.0 + + text,features,name,sku,id,manu,cat,title,description,keywords,author,resourcename + 3 + + + on + cat + manu_exact + content_type + author_s + ipod + GB + 1 + cat,inStock + after + price + 0 + 600 + 50 + popularity + 0 + 10 + 3 + manufacturedate_dt + NOW/YEAR-10YEARS + NOW + +1YEAR + before + after + + + on + content features title name + html + <b> + </b> + 0 + title + 0 + name + 3 + 200 + content + 750 + + + on + false + 5 + 2 + 5 + true + true + 5 + 3 + + + + + spellcheck + + + + + + + + + + + + + + application/json + + + + + application/csv + + + + + + + + + + + + + + + + + + + + + solrpingquery + + + all + + + + + + + + + explicit + true + + + + + + + + + + + + + + + + text_general + + + + + + default + text + solr.DirectSolrSpellChecker + + internal + + 0.5 + + 2 + + 1 + + 5 + + 4 + + 0.01 + + + + + + wordbreak + solr.WordBreakSolrSpellChecker + name + true + true + 10 + + + + + + + + + + + + + + + + text + + default + wordbreak + on + true + 10 + 5 + 5 + true + true + 10 + 5 + + + spellcheck + + + + + + + + + + text + true + + + tvComponent + + + + + + + + + default + + + org.carrot2.clustering.lingo.LingoClusteringAlgorithm + + + 20 + + + clustering/carrot2 + + + ENGLISH + + + stc + org.carrot2.clustering.stc.STCClusteringAlgorithm + + + + + + + true + default + true + + name + id + + features + + true + + + + false + + edismax + + text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 + + *:* + 10 + *,score + + + clustering + + + + + + + + + + true + false + + + terms + + + + + + + + string + elevate.xml + + + + + + explicit + text + + + elevator + + + + + + + + + + + 100 + + + + + + + + 70 + + 0.5 + + [-\w ,/\n\"']{20,200} + + + + + + + ]]> + ]]> + + + + + + + + + + + + + + + + + + + + + + + + ,, + ,, + ,, + ,, + ,]]> + ]]> + + + + + + 10 + .,!? + + + + + + + WORD + + + en + US + + + + + + + + + + + + + + + + + + + + + + text/plain; charset=UTF-8 + + + + + + + + + 5 + + + + + + + + + + + + + + + + + + *:* + + + diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/stopwords.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/stopwords.txt new file mode 100644 index 00000000000..ae1e83eeb3d --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/stopwords.txt @@ -0,0 +1,14 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/synonyms.txt b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/synonyms.txt new file mode 100644 index 00000000000..7f72128303b --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/synonyms.txt @@ -0,0 +1,29 @@ +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#----------------------------------------------------------------------- +#some test synonym mappings unlikely to appear in real input text +aaafoo => aaabar +bbbfoo => bbbfoo bbbbar +cccfoo => cccbar cccbaz +fooaaa,baraaa,bazaaa + +# Some synonym groups specific to this example +GB,gib,gigabyte,gigabytes +MB,mib,megabyte,megabytes +Television, Televisions, TV, TVs +#notice we use "gib" instead of "GiB" so any WordDelimiterFilter coming +#after us won't split it into two words. + +# Synonym mappings can be used for spelling correction too +pixima => pixma + diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/solr.xml b/solr/contrib/solr-mr/src/test-files/solr/mrunit/solr.xml new file mode 100644 index 00000000000..6c8b43f75ed --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/mrunit/solr.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + ${socketTimeout:120000} + ${connTimeout:15000} + + + + diff --git a/solr/contrib/solr-mr/src/test-files/solr/solr.xml b/solr/contrib/solr-mr/src/test-files/solr/solr.xml new file mode 100644 index 00000000000..4604f60476f --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solr.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + ${socketTimeout:120000} + ${connTimeout:15000} + + + + diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/currency.xml b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/currency.xml new file mode 100644 index 00000000000..3a9c58afee8 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/currency.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/elevate.xml b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/elevate.xml new file mode 100644 index 00000000000..25d5cebe4fb --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/elevate.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_ca.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_ca.txt new file mode 100644 index 00000000000..307a85f913d --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_ca.txt @@ -0,0 +1,8 @@ +# Set of Catalan contractions for ElisionFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +d +l +m +n +s +t diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_fr.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_fr.txt new file mode 100644 index 00000000000..722db588333 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_fr.txt @@ -0,0 +1,9 @@ +# Set of French contractions for ElisionFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +l +m +t +qu +n +s +j diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_ga.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_ga.txt new file mode 100644 index 00000000000..9ebe7fa349a --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_ga.txt @@ -0,0 +1,5 @@ +# Set of Irish contractions for ElisionFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +d +m +b diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_it.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_it.txt new file mode 100644 index 00000000000..cac04095372 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_it.txt @@ -0,0 +1,23 @@ +# Set of Italian contractions for ElisionFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +c +l +all +dall +dell +nell +sull +coll +pell +gl +agl +dagl +degl +negl +sugl +un +m +t +s +v +d diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/hyphenations_ga.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/hyphenations_ga.txt new file mode 100644 index 00000000000..4d2642cc5a3 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/hyphenations_ga.txt @@ -0,0 +1,5 @@ +# Set of Irish hyphenations for StopFilter +# TODO: load this as a resource from the analyzer and sync it in build.xml +h +n +t diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stemdict_nl.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stemdict_nl.txt new file mode 100644 index 00000000000..441072971d3 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stemdict_nl.txt @@ -0,0 +1,6 @@ +# Set of overrides for the dutch stemmer +# TODO: load this as a resource from the analyzer and sync it in build.xml +fiets fiets +bromfiets bromfiets +ei eier +kind kinder diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stoptags_ja.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stoptags_ja.txt new file mode 100644 index 00000000000..71b750845e3 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stoptags_ja.txt @@ -0,0 +1,420 @@ +# +# This file defines a Japanese stoptag set for JapanesePartOfSpeechStopFilter. +# +# Any token with a part-of-speech tag that exactly matches those defined in this +# file are removed from the token stream. +# +# Set your own stoptags by uncommenting the lines below. Note that comments are +# not allowed on the same line as a stoptag. See LUCENE-3745 for frequency lists, +# etc. that can be useful for building you own stoptag set. +# +# The entire possible tagset is provided below for convenience. +# +##### +# noun: unclassified nouns +#名詞 +# +# noun-common: Common nouns or nouns where the sub-classification is undefined +#名詞-一般 +# +# noun-proper: Proper nouns where the sub-classification is undefined +#名詞-固有名詞 +# +# noun-proper-misc: miscellaneous proper nouns +#名詞-固有名詞-一般 +# +# noun-proper-person: Personal names where the sub-classification is undefined +#名詞-固有名詞-人名 +# +# noun-proper-person-misc: names that cannot be divided into surname and +# given name; foreign names; names where the surname or given name is unknown. +# e.g. お市の方 +#名詞-固有名詞-人名-一般 +# +# noun-proper-person-surname: Mainly Japanese surnames. +# e.g. 山田 +#名詞-固有名詞-人名-姓 +# +# noun-proper-person-given_name: Mainly Japanese given names. +# e.g. 太郎 +#名詞-固有名詞-人名-名 +# +# noun-proper-organization: Names representing organizations. +# e.g. 通産省, NHK +#名詞-固有名詞-組織 +# +# noun-proper-place: Place names where the sub-classification is undefined +#名詞-固有名詞-地域 +# +# noun-proper-place-misc: Place names excluding countries. +# e.g. アジア, バルセロナ, 京都 +#名詞-固有名詞-地域-一般 +# +# noun-proper-place-country: Country names. +# e.g. 日本, オーストラリア +#名詞-固有名詞-地域-国 +# +# noun-pronoun: Pronouns where the sub-classification is undefined +#名詞-代名詞 +# +# noun-pronoun-misc: miscellaneous pronouns: +# e.g. それ, ここ, あいつ, あなた, あちこち, いくつ, どこか, なに, みなさん, みんな, わたくし, われわれ +#名詞-代名詞-一般 +# +# noun-pronoun-contraction: Spoken language contraction made by combining a +# pronoun and the particle 'wa'. +# e.g. ありゃ, こりゃ, こりゃあ, そりゃ, そりゃあ +#名詞-代名詞-縮約 +# +# noun-adverbial: Temporal nouns such as names of days or months that behave +# like adverbs. Nouns that represent amount or ratios and can be used adverbially, +# e.g. 金曜, 一月, 午後, 少量 +#名詞-副詞可能 +# +# noun-verbal: Nouns that take arguments with case and can appear followed by +# 'suru' and related verbs (する, できる, なさる, くださる) +# e.g. インプット, 愛着, 悪化, 悪戦苦闘, 一安心, 下取り +#名詞-サ変接続 +# +# noun-adjective-base: The base form of adjectives, words that appear before な ("na") +# e.g. 健康, 安易, 駄目, だめ +#名詞-形容動詞語幹 +# +# noun-numeric: Arabic numbers, Chinese numerals, and counters like 何 (回), 数. +# e.g. 0, 1, 2, 何, 数, 幾 +#名詞-数 +# +# noun-affix: noun affixes where the sub-classification is undefined +#名詞-非自立 +# +# noun-affix-misc: Of adnominalizers, the case-marker の ("no"), and words that +# attach to the base form of inflectional words, words that cannot be classified +# into any of the other categories below. This category includes indefinite nouns. +# e.g. あかつき, 暁, かい, 甲斐, 気, きらい, 嫌い, くせ, 癖, こと, 事, ごと, 毎, しだい, 次第, +# 順, せい, 所為, ついで, 序で, つもり, 積もり, 点, どころ, の, はず, 筈, はずみ, 弾み, +# 拍子, ふう, ふり, 振り, ほう, 方, 旨, もの, 物, 者, ゆえ, 故, ゆえん, 所以, わけ, 訳, +# わり, 割り, 割, ん-口語/, もん-口語/ +#名詞-非自立-一般 +# +# noun-affix-adverbial: noun affixes that that can behave as adverbs. +# e.g. あいだ, 間, あげく, 挙げ句, あと, 後, 余り, 以外, 以降, 以後, 以上, 以前, 一方, うえ, +# 上, うち, 内, おり, 折り, かぎり, 限り, きり, っきり, 結果, ころ, 頃, さい, 際, 最中, さなか, +# 最中, じたい, 自体, たび, 度, ため, 為, つど, 都度, とおり, 通り, とき, 時, ところ, 所, +# とたん, 途端, なか, 中, のち, 後, ばあい, 場合, 日, ぶん, 分, ほか, 他, まえ, 前, まま, +# 儘, 侭, みぎり, 矢先 +#名詞-非自立-副詞可能 +# +# noun-affix-aux: noun affixes treated as 助動詞 ("auxiliary verb") in school grammars +# with the stem よう(だ) ("you(da)"). +# e.g. よう, やう, 様 (よう) +#名詞-非自立-助動詞語幹 +# +# noun-affix-adjective-base: noun affixes that can connect to the indeclinable +# connection form な (aux "da"). +# e.g. みたい, ふう +#名詞-非自立-形容動詞語幹 +# +# noun-special: special nouns where the sub-classification is undefined. +#名詞-特殊 +# +# noun-special-aux: The そうだ ("souda") stem form that is used for reporting news, is +# treated as 助動詞 ("auxiliary verb") in school grammars, and attach to the base +# form of inflectional words. +# e.g. そう +#名詞-特殊-助動詞語幹 +# +# noun-suffix: noun suffixes where the sub-classification is undefined. +#名詞-接尾 +# +# noun-suffix-misc: Of the nouns or stem forms of other parts of speech that connect +# to ガル or タイ and can combine into compound nouns, words that cannot be classified into +# any of the other categories below. In general, this category is more inclusive than +# 接尾語 ("suffix") and is usually the last element in a compound noun. +# e.g. おき, かた, 方, 甲斐 (がい), がかり, ぎみ, 気味, ぐるみ, (~した) さ, 次第, 済 (ず) み, +# よう, (でき)っこ, 感, 観, 性, 学, 類, 面, 用 +#名詞-接尾-一般 +# +# noun-suffix-person: Suffixes that form nouns and attach to person names more often +# than other nouns. +# e.g. 君, 様, 著 +#名詞-接尾-人名 +# +# noun-suffix-place: Suffixes that form nouns and attach to place names more often +# than other nouns. +# e.g. 町, 市, 県 +#名詞-接尾-地域 +# +# noun-suffix-verbal: Of the suffixes that attach to nouns and form nouns, those that +# can appear before スル ("suru"). +# e.g. 化, 視, 分け, 入り, 落ち, 買い +#名詞-接尾-サ変接続 +# +# noun-suffix-aux: The stem form of そうだ (様態) that is used to indicate conditions, +# is treated as 助動詞 ("auxiliary verb") in school grammars, and attach to the +# conjunctive form of inflectional words. +# e.g. そう +#名詞-接尾-助動詞語幹 +# +# noun-suffix-adjective-base: Suffixes that attach to other nouns or the conjunctive +# form of inflectional words and appear before the copula だ ("da"). +# e.g. 的, げ, がち +#名詞-接尾-形容動詞語幹 +# +# noun-suffix-adverbial: Suffixes that attach to other nouns and can behave as adverbs. +# e.g. 後 (ご), 以後, 以降, 以前, 前後, 中, 末, 上, 時 (じ) +#名詞-接尾-副詞可能 +# +# noun-suffix-classifier: Suffixes that attach to numbers and form nouns. This category +# is more inclusive than 助数詞 ("classifier") and includes common nouns that attach +# to numbers. +# e.g. 個, つ, 本, 冊, パーセント, cm, kg, カ月, か国, 区画, 時間, 時半 +#名詞-接尾-助数詞 +# +# noun-suffix-special: Special suffixes that mainly attach to inflecting words. +# e.g. (楽し) さ, (考え) 方 +#名詞-接尾-特殊 +# +# noun-suffix-conjunctive: Nouns that behave like conjunctions and join two words +# together. +# e.g. (日本) 対 (アメリカ), 対 (アメリカ), (3) 対 (5), (女優) 兼 (主婦) +#名詞-接続詞的 +# +# noun-verbal_aux: Nouns that attach to the conjunctive particle て ("te") and are +# semantically verb-like. +# e.g. ごらん, ご覧, 御覧, 頂戴 +#名詞-動詞非自立的 +# +# noun-quotation: text that cannot be segmented into words, proverbs, Chinese poetry, +# dialects, English, etc. Currently, the only entry for 名詞 引用文字列 ("noun quotation") +# is いわく ("iwaku"). +#名詞-引用文字列 +# +# noun-nai_adjective: Words that appear before the auxiliary verb ない ("nai") and +# behave like an adjective. +# e.g. 申し訳, 仕方, とんでも, 違い +#名詞-ナイ形容詞語幹 +# +##### +# prefix: unclassified prefixes +#接頭詞 +# +# prefix-nominal: Prefixes that attach to nouns (including adjective stem forms) +# excluding numerical expressions. +# e.g. お (水), 某 (氏), 同 (社), 故 (~氏), 高 (品質), お (見事), ご (立派) +#接頭詞-名詞接続 +# +# prefix-verbal: Prefixes that attach to the imperative form of a verb or a verb +# in conjunctive form followed by なる/なさる/くださる. +# e.g. お (読みなさい), お (座り) +#接頭詞-動詞接続 +# +# prefix-adjectival: Prefixes that attach to adjectives. +# e.g. お (寒いですねえ), バカ (でかい) +#接頭詞-形容詞接続 +# +# prefix-numerical: Prefixes that attach to numerical expressions. +# e.g. 約, およそ, 毎時 +#接頭詞-数接続 +# +##### +# verb: unclassified verbs +#動詞 +# +# verb-main: +#動詞-自立 +# +# verb-auxiliary: +#動詞-非自立 +# +# verb-suffix: +#動詞-接尾 +# +##### +# adjective: unclassified adjectives +#形容詞 +# +# adjective-main: +#形容詞-自立 +# +# adjective-auxiliary: +#形容詞-非自立 +# +# adjective-suffix: +#形容詞-接尾 +# +##### +# adverb: unclassified adverbs +#副詞 +# +# adverb-misc: Words that can be segmented into one unit and where adnominal +# modification is not possible. +# e.g. あいかわらず, 多分 +#副詞-一般 +# +# adverb-particle_conjunction: Adverbs that can be followed by の, は, に, +# な, する, だ, etc. +# e.g. こんなに, そんなに, あんなに, なにか, なんでも +#副詞-助詞類接続 +# +##### +# adnominal: Words that only have noun-modifying forms. +# e.g. この, その, あの, どの, いわゆる, なんらかの, 何らかの, いろんな, こういう, そういう, ああいう, +# どういう, こんな, そんな, あんな, どんな, 大きな, 小さな, おかしな, ほんの, たいした, +# 「(, も) さる (ことながら)」, 微々たる, 堂々たる, 単なる, いかなる, 我が」「同じ, 亡き +#連体詞 +# +##### +# conjunction: Conjunctions that can occur independently. +# e.g. が, けれども, そして, じゃあ, それどころか +接続詞 +# +##### +# particle: unclassified particles. +助詞 +# +# particle-case: case particles where the subclassification is undefined. +助詞-格助詞 +# +# particle-case-misc: Case particles. +# e.g. から, が, で, と, に, へ, より, を, の, にて +助詞-格助詞-一般 +# +# particle-case-quote: the "to" that appears after nouns, a person’s speech, +# quotation marks, expressions of decisions from a meeting, reasons, judgements, +# conjectures, etc. +# e.g. ( だ) と (述べた.), ( である) と (して執行猶予...) +助詞-格助詞-引用 +# +# particle-case-compound: Compounds of particles and verbs that mainly behave +# like case particles. +# e.g. という, といった, とかいう, として, とともに, と共に, でもって, にあたって, に当たって, に当って, +# にあたり, に当たり, に当り, に当たる, にあたる, において, に於いて,に於て, における, に於ける, +# にかけ, にかけて, にかんし, に関し, にかんして, に関して, にかんする, に関する, に際し, +# に際して, にしたがい, に従い, に従う, にしたがって, に従って, にたいし, に対し, にたいして, +# に対して, にたいする, に対する, について, につき, につけ, につけて, につれ, につれて, にとって, +# にとり, にまつわる, によって, に依って, に因って, により, に依り, に因り, による, に依る, に因る, +# にわたって, にわたる, をもって, を以って, を通じ, を通じて, を通して, をめぐって, をめぐり, をめぐる, +# って-口語/, ちゅう-関西弁「という」/, (何) ていう (人)-口語/, っていう-口語/, といふ, とかいふ +助詞-格助詞-連語 +# +# particle-conjunctive: +# e.g. から, からには, が, けれど, けれども, けど, し, つつ, て, で, と, ところが, どころか, とも, ども, +# ながら, なり, ので, のに, ば, ものの, や ( した), やいなや, (ころん) じゃ(いけない)-口語/, +# (行っ) ちゃ(いけない)-口語/, (言っ) たって (しかたがない)-口語/, (それがなく)ったって (平気)-口語/ +助詞-接続助詞 +# +# particle-dependency: +# e.g. こそ, さえ, しか, すら, は, も, ぞ +助詞-係助詞 +# +# particle-adverbial: +# e.g. がてら, かも, くらい, 位, ぐらい, しも, (学校) じゃ(これが流行っている)-口語/, +# (それ)じゃあ (よくない)-口語/, ずつ, (私) なぞ, など, (私) なり (に), (先生) なんか (大嫌い)-口語/, +# (私) なんぞ, (先生) なんて (大嫌い)-口語/, のみ, だけ, (私) だって-口語/, だに, +# (彼)ったら-口語/, (お茶) でも (いかが), 等 (とう), (今後) とも, ばかり, ばっか-口語/, ばっかり-口語/, +# ほど, 程, まで, 迄, (誰) も (が)([助詞-格助詞] および [助詞-係助詞] の前に位置する「も」) +助詞-副助詞 +# +# particle-interjective: particles with interjective grammatical roles. +# e.g. (松島) や +助詞-間投助詞 +# +# particle-coordinate: +# e.g. と, たり, だの, だり, とか, なり, や, やら +助詞-並立助詞 +# +# particle-final: +# e.g. かい, かしら, さ, ぜ, (だ)っけ-口語/, (とまってる) で-方言/, な, ナ, なあ-口語/, ぞ, ね, ネ, +# ねぇ-口語/, ねえ-口語/, ねん-方言/, の, のう-口語/, や, よ, ヨ, よぉ-口語/, わ, わい-口語/ +助詞-終助詞 +# +# particle-adverbial/conjunctive/final: The particle "ka" when unknown whether it is +# adverbial, conjunctive, or sentence final. For example: +# (a) 「A か B か」. Ex:「(国内で運用する) か,(海外で運用する) か (.)」 +# (b) Inside an adverb phrase. Ex:「(幸いという) か (, 死者はいなかった.)」 +# 「(祈りが届いたせい) か (, 試験に合格した.)」 +# (c) 「かのように」. Ex:「(何もなかった) か (のように振る舞った.)」 +# e.g. か +助詞-副助詞/並立助詞/終助詞 +# +# particle-adnominalizer: The "no" that attaches to nouns and modifies +# non-inflectional words. +助詞-連体化 +# +# particle-adnominalizer: The "ni" and "to" that appear following nouns and adverbs +# that are giongo, giseigo, or gitaigo. +# e.g. に, と +助詞-副詞化 +# +# particle-special: A particle that does not fit into one of the above classifications. +# This includes particles that are used in Tanka, Haiku, and other poetry. +# e.g. かな, けむ, ( しただろう) に, (あんた) にゃ(わからん), (俺) ん (家) +助詞-特殊 +# +##### +# auxiliary-verb: +助動詞 +# +##### +# interjection: Greetings and other exclamations. +# e.g. おはよう, おはようございます, こんにちは, こんばんは, ありがとう, どうもありがとう, ありがとうございます, +# いただきます, ごちそうさま, さよなら, さようなら, はい, いいえ, ごめん, ごめんなさい +#感動詞 +# +##### +# symbol: unclassified Symbols. +記号 +# +# symbol-misc: A general symbol not in one of the categories below. +# e.g. [○◎@$〒→+] +記号-一般 +# +# symbol-comma: Commas +# e.g. [,、] +記号-読点 +# +# symbol-period: Periods and full stops. +# e.g. [..。] +記号-句点 +# +# symbol-space: Full-width whitespace. +記号-空白 +# +# symbol-open_bracket: +# e.g. [({‘“『【] +記号-括弧開 +# +# symbol-close_bracket: +# e.g. [)}’”』」】] +記号-括弧閉 +# +# symbol-alphabetic: +#記号-アルファベット +# +##### +# other: unclassified other +#その他 +# +# other-interjection: Words that are hard to classify as noun-suffixes or +# sentence-final particles. +# e.g. (だ)ァ +その他-間投 +# +##### +# filler: Aizuchi that occurs during a conversation or sounds inserted as filler. +# e.g. あの, うんと, えと +フィラー +# +##### +# non-verbal: non-verbal sound. +非言語音 +# +##### +# fragment: +#語断片 +# +##### +# unknown: unknown part of speech. +#未知語 +# +##### End of file diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ar.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ar.txt new file mode 100644 index 00000000000..046829db6a2 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ar.txt @@ -0,0 +1,125 @@ +# This file was created by Jacques Savoy and is distributed under the BSD license. +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# Also see http://www.opensource.org/licenses/bsd-license.html +# Cleaned on October 11, 2009 (not normalized, so use before normalization) +# This means that when modifying this list, you might need to add some +# redundant entries, for example containing forms with both أ and ا +من +ومن +منها +منه +في +وفي +فيها +فيه +و +ف +ثم +او +أو +ب +بها +به +ا +أ +اى +اي +أي +أى +لا +ولا +الا +ألا +إلا +لكن +ما +وما +كما +فما +عن +مع +اذا +إذا +ان +أن +إن +انها +أنها +إنها +انه +أنه +إنه +بان +بأن +فان +فأن +وان +وأن +وإن +التى +التي +الذى +الذي +الذين +الى +الي +إلى +إلي +على +عليها +عليه +اما +أما +إما +ايضا +أيضا +كل +وكل +لم +ولم +لن +ولن +هى +هي +هو +وهى +وهي +وهو +فهى +فهي +فهو +انت +أنت +لك +لها +له +هذه +هذا +تلك +ذلك +هناك +كانت +كان +يكون +تكون +وكانت +وكان +غير +بعض +قد +نحو +بين +بينما +منذ +ضمن +حيث +الان +الآن +خلال +بعد +قبل +حتى +عند +عندما +لدى +جميع diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_bg.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_bg.txt new file mode 100644 index 00000000000..1ae4ba2ae38 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_bg.txt @@ -0,0 +1,193 @@ +# This file was created by Jacques Savoy and is distributed under the BSD license. +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# Also see http://www.opensource.org/licenses/bsd-license.html +а +аз +ако +ала +бе +без +беше +би +бил +била +били +било +близо +бъдат +бъде +бяха +в +вас +ваш +ваша +вероятно +вече +взема +ви +вие +винаги +все +всеки +всички +всичко +всяка +във +въпреки +върху +г +ги +главно +го +д +да +дали +до +докато +докога +дори +досега +доста +е +едва +един +ето +за +зад +заедно +заради +засега +затова +защо +защото +и +из +или +им +има +имат +иска +й +каза +как +каква +какво +както +какъв +като +кога +когато +което +които +кой +който +колко +която +къде +където +към +ли +м +ме +между +мен +ми +мнозина +мога +могат +може +моля +момента +му +н +на +над +назад +най +направи +напред +например +нас +не +него +нея +ни +ние +никой +нито +но +някои +някой +няма +обаче +около +освен +особено +от +отгоре +отново +още +пак +по +повече +повечето +под +поне +поради +после +почти +прави +пред +преди +през +при +пък +първо +с +са +само +се +сега +си +скоро +след +сме +според +сред +срещу +сте +съм +със +също +т +тази +така +такива +такъв +там +твой +те +тези +ти +тн +то +това +тогава +този +той +толкова +точно +трябва +тук +тъй +тя +тях +у +харесва +ч +че +често +чрез +ще +щом +я diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ca.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ca.txt new file mode 100644 index 00000000000..3da65deafe1 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ca.txt @@ -0,0 +1,220 @@ +# Catalan stopwords from http://github.com/vcl/cue.language (Apache 2 Licensed) +a +abans +ací +ah +així +això +al +als +aleshores +algun +alguna +algunes +alguns +alhora +allà +allí +allò +altra +altre +altres +amb +ambdós +ambdues +apa +aquell +aquella +aquelles +aquells +aquest +aquesta +aquestes +aquests +aquí +baix +cada +cadascú +cadascuna +cadascunes +cadascuns +com +contra +d'un +d'una +d'unes +d'uns +dalt +de +del +dels +des +després +dins +dintre +donat +doncs +durant +e +eh +el +els +em +en +encara +ens +entre +érem +eren +éreu +es +és +esta +està +estàvem +estaven +estàveu +esteu +et +etc +ets +fins +fora +gairebé +ha +han +has +havia +he +hem +heu +hi +ho +i +igual +iguals +ja +l'hi +la +les +li +li'n +llavors +m'he +ma +mal +malgrat +mateix +mateixa +mateixes +mateixos +me +mentre +més +meu +meus +meva +meves +molt +molta +moltes +molts +mon +mons +n'he +n'hi +ne +ni +no +nogensmenys +només +nosaltres +nostra +nostre +nostres +o +oh +oi +on +pas +pel +pels +per +però +perquè +poc +poca +pocs +poques +potser +propi +qual +quals +quan +quant +que +què +quelcom +qui +quin +quina +quines +quins +s'ha +s'han +sa +semblant +semblants +ses +seu +seus +seva +seva +seves +si +sobre +sobretot +sóc +solament +sols +son +són +sons +sota +sou +t'ha +t'han +t'he +ta +tal +també +tampoc +tan +tant +tanta +tantes +teu +teus +teva +teves +ton +tons +tot +tota +totes +tots +un +una +unes +uns +us +va +vaig +vam +van +vas +veu +vosaltres +vostra +vostre +vostres diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_cz.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_cz.txt new file mode 100644 index 00000000000..53c6097dac7 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_cz.txt @@ -0,0 +1,172 @@ +a +s +k +o +i +u +v +z +dnes +cz +tímto +budeš +budem +byli +jseš +můj +svým +ta +tomto +tohle +tuto +tyto +jej +zda +proč +máte +tato +kam +tohoto +kdo +kteří +mi +nám +tom +tomuto +mít +nic +proto +kterou +byla +toho +protože +asi +ho +naši +napište +re +což +tím +takže +svých +její +svými +jste +aj +tu +tedy +teto +bylo +kde +ke +pravé +ji +nad +nejsou +či +pod +téma +mezi +přes +ty +pak +vám +ani +když +však +neg +jsem +tento +článku +články +aby +jsme +před +pta +jejich +byl +ještě +až +bez +také +pouze +první +vaše +která +nás +nový +tipy +pokud +může +strana +jeho +své +jiné +zprávy +nové +není +vás +jen +podle +zde +už +být +více +bude +již +než +který +by +které +co +nebo +ten +tak +má +při +od +po +jsou +jak +další +ale +si +se +ve +to +jako +za +zpět +ze +do +pro +je +na +atd +atp +jakmile +přičemž +já +on +ona +ono +oni +ony +my +vy +jí +ji +mě +mne +jemu +tomu +těm +těmu +němu +němuž +jehož +jíž +jelikož +jež +jakož +načež diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_da.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_da.txt new file mode 100644 index 00000000000..a3ff5fe122c --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_da.txt @@ -0,0 +1,108 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/danish/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Danish stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | This is a ranked list (commonest to rarest) of stopwords derived from + | a large text sample. + + +og | and +i | in +jeg | I +det | that (dem. pronoun)/it (pers. pronoun) +at | that (in front of a sentence)/to (with infinitive) +en | a/an +den | it (pers. pronoun)/that (dem. pronoun) +til | to/at/for/until/against/by/of/into, more +er | present tense of "to be" +som | who, as +på | on/upon/in/on/at/to/after/of/with/for, on +de | they +med | with/by/in, along +han | he +af | of/by/from/off/for/in/with/on, off +for | at/for/to/from/by/of/ago, in front/before, because +ikke | not +der | who/which, there/those +var | past tense of "to be" +mig | me/myself +sig | oneself/himself/herself/itself/themselves +men | but +et | a/an/one, one (number), someone/somebody/one +har | present tense of "to have" +om | round/about/for/in/a, about/around/down, if +vi | we +min | my +havde | past tense of "to have" +ham | him +hun | she +nu | now +over | over/above/across/by/beyond/past/on/about, over/past +da | then, when/as/since +fra | from/off/since, off, since +du | you +ud | out +sin | his/her/its/one's +dem | them +os | us/ourselves +op | up +man | you/one +hans | his +hvor | where +eller | or +hvad | what +skal | must/shall etc. +selv | myself/youself/herself/ourselves etc., even +her | here +alle | all/everyone/everybody etc. +vil | will (verb) +blev | past tense of "to stay/to remain/to get/to become" +kunne | could +ind | in +når | when +være | present tense of "to be" +dog | however/yet/after all +noget | something +ville | would +jo | you know/you see (adv), yes +deres | their/theirs +efter | after/behind/according to/for/by/from, later/afterwards +ned | down +skulle | should +denne | this +end | than +dette | this +mit | my/mine +også | also +under | under/beneath/below/during, below/underneath +have | have +dig | you +anden | other +hende | her +mine | my +alt | everything +meget | much/very, plenty of +sit | his, her, its, one's +sine | his, her, its, one's +vor | our +mod | against +disse | these +hvis | if +din | your/yours +nogle | some +hos | by/at +blive | be/become +mange | many +ad | by/through +bliver | present tense of "to be/to become" +hendes | her/hers +været | be +thi | for (conj) +jer | you +sådan | such, like this/like that diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_de.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_de.txt new file mode 100644 index 00000000000..f7703841887 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_de.txt @@ -0,0 +1,292 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/german/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A German stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | The number of forms in this list is reduced significantly by passing it + | through the German stemmer. + + +aber | but + +alle | all +allem +allen +aller +alles + +als | than, as +also | so +am | an + dem +an | at + +ander | other +andere +anderem +anderen +anderer +anderes +anderm +andern +anderr +anders + +auch | also +auf | on +aus | out of +bei | by +bin | am +bis | until +bist | art +da | there +damit | with it +dann | then + +der | the +den +des +dem +die +das + +daß | that + +derselbe | the same +derselben +denselben +desselben +demselben +dieselbe +dieselben +dasselbe + +dazu | to that + +dein | thy +deine +deinem +deinen +deiner +deines + +denn | because + +derer | of those +dessen | of him + +dich | thee +dir | to thee +du | thou + +dies | this +diese +diesem +diesen +dieser +dieses + + +doch | (several meanings) +dort | (over) there + + +durch | through + +ein | a +eine +einem +einen +einer +eines + +einig | some +einige +einigem +einigen +einiger +einiges + +einmal | once + +er | he +ihn | him +ihm | to him + +es | it +etwas | something + +euer | your +eure +eurem +euren +eurer +eures + +für | for +gegen | towards +gewesen | p.p. of sein +hab | have +habe | have +haben | have +hat | has +hatte | had +hatten | had +hier | here +hin | there +hinter | behind + +ich | I +mich | me +mir | to me + + +ihr | you, to her +ihre +ihrem +ihren +ihrer +ihres +euch | to you + +im | in + dem +in | in +indem | while +ins | in + das +ist | is + +jede | each, every +jedem +jeden +jeder +jedes + +jene | that +jenem +jenen +jener +jenes + +jetzt | now +kann | can + +kein | no +keine +keinem +keinen +keiner +keines + +können | can +könnte | could +machen | do +man | one + +manche | some, many a +manchem +manchen +mancher +manches + +mein | my +meine +meinem +meinen +meiner +meines + +mit | with +muss | must +musste | had to +nach | to(wards) +nicht | not +nichts | nothing +noch | still, yet +nun | now +nur | only +ob | whether +oder | or +ohne | without +sehr | very + +sein | his +seine +seinem +seinen +seiner +seines + +selbst | self +sich | herself + +sie | they, she +ihnen | to them + +sind | are +so | so + +solche | such +solchem +solchen +solcher +solches + +soll | shall +sollte | should +sondern | but +sonst | else +über | over +um | about, around +und | and + +uns | us +unse +unsem +unsen +unser +unses + +unter | under +viel | much +vom | von + dem +von | from +vor | before +während | while +war | was +waren | were +warst | wast +was | what +weg | away, off +weil | because +weiter | further + +welche | which +welchem +welchen +welcher +welches + +wenn | when +werde | will +werden | will +wie | how +wieder | again +will | want +wir | we +wird | will +wirst | willst +wo | where +wollen | want +wollte | wanted +würde | would +würden | would +zu | to +zum | zu + dem +zur | zu + der +zwar | indeed +zwischen | between + diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_el.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_el.txt new file mode 100644 index 00000000000..232681f5bd6 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_el.txt @@ -0,0 +1,78 @@ +# Lucene Greek Stopwords list +# Note: by default this file is used after GreekLowerCaseFilter, +# so when modifying this file use 'σ' instead of 'ς' +ο +η +το +οι +τα +του +τησ +των +τον +την +και +κι +κ +ειμαι +εισαι +ειναι +ειμαστε +ειστε +στο +στον +στη +στην +μα +αλλα +απο +για +προσ +με +σε +ωσ +παρα +αντι +κατα +μετα +θα +να +δε +δεν +μη +μην +επι +ενω +εαν +αν +τοτε +που +πωσ +ποιοσ +ποια +ποιο +ποιοι +ποιεσ +ποιων +ποιουσ +αυτοσ +αυτη +αυτο +αυτοι +αυτων +αυτουσ +αυτεσ +αυτα +εκεινοσ +εκεινη +εκεινο +εκεινοι +εκεινεσ +εκεινα +εκεινων +εκεινουσ +οπωσ +ομωσ +ισωσ +οσο +οτι diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_en.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_en.txt new file mode 100644 index 00000000000..2c164c0b2a1 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_en.txt @@ -0,0 +1,54 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# a couple of test stopwords to test that the words are really being +# configured from this file: +stopworda +stopwordb + +# Standard english stop words taken from Lucene's StopAnalyzer +a +an +and +are +as +at +be +but +by +for +if +in +into +is +it +no +not +of +on +or +such +that +the +their +then +there +these +they +this +to +was +will +with diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_es.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_es.txt new file mode 100644 index 00000000000..2db14760075 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_es.txt @@ -0,0 +1,354 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/spanish/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Spanish stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + + | The following is a ranked list (commonest to rarest) of stopwords + | deriving from a large sample of text. + + | Extra words have been added at the end. + +de | from, of +la | the, her +que | who, that +el | the +en | in +y | and +a | to +los | the, them +del | de + el +se | himself, from him etc +las | the, them +por | for, by, etc +un | a +para | for +con | with +no | no +una | a +su | his, her +al | a + el + | es from SER +lo | him +como | how +más | more +pero | pero +sus | su plural +le | to him, her +ya | already +o | or + | fue from SER +este | this + | ha from HABER +sí | himself etc +porque | because +esta | this + | son from SER +entre | between + | está from ESTAR +cuando | when +muy | very +sin | without +sobre | on + | ser from SER + | tiene from TENER +también | also +me | me +hasta | until +hay | there is/are +donde | where + | han from HABER +quien | whom, that + | están from ESTAR + | estado from ESTAR +desde | from +todo | all +nos | us +durante | during + | estados from ESTAR +todos | all +uno | a +les | to them +ni | nor +contra | against +otros | other + | fueron from SER +ese | that +eso | that + | había from HABER +ante | before +ellos | they +e | and (variant of y) +esto | this +mí | me +antes | before +algunos | some +qué | what? +unos | a +yo | I +otro | other +otras | other +otra | other +él | he +tanto | so much, many +esa | that +estos | these +mucho | much, many +quienes | who +nada | nothing +muchos | many +cual | who + | sea from SER +poco | few +ella | she +estar | to be + | haber from HABER +estas | these + | estaba from ESTAR + | estamos from ESTAR +algunas | some +algo | something +nosotros | we + + | other forms + +mi | me +mis | mi plural +tú | thou +te | thee +ti | thee +tu | thy +tus | tu plural +ellas | they +nosotras | we +vosotros | you +vosotras | you +os | you +mío | mine +mía | +míos | +mías | +tuyo | thine +tuya | +tuyos | +tuyas | +suyo | his, hers, theirs +suya | +suyos | +suyas | +nuestro | ours +nuestra | +nuestros | +nuestras | +vuestro | yours +vuestra | +vuestros | +vuestras | +esos | those +esas | those + + | forms of estar, to be (not including the infinitive): +estoy +estás +está +estamos +estáis +están +esté +estés +estemos +estéis +estén +estaré +estarás +estará +estaremos +estaréis +estarán +estaría +estarías +estaríamos +estaríais +estarían +estaba +estabas +estábamos +estabais +estaban +estuve +estuviste +estuvo +estuvimos +estuvisteis +estuvieron +estuviera +estuvieras +estuviéramos +estuvierais +estuvieran +estuviese +estuvieses +estuviésemos +estuvieseis +estuviesen +estando +estado +estada +estados +estadas +estad + + | forms of haber, to have (not including the infinitive): +he +has +ha +hemos +habéis +han +haya +hayas +hayamos +hayáis +hayan +habré +habrás +habrá +habremos +habréis +habrán +habría +habrías +habríamos +habríais +habrían +había +habías +habíamos +habíais +habían +hube +hubiste +hubo +hubimos +hubisteis +hubieron +hubiera +hubieras +hubiéramos +hubierais +hubieran +hubiese +hubieses +hubiésemos +hubieseis +hubiesen +habiendo +habido +habida +habidos +habidas + + | forms of ser, to be (not including the infinitive): +soy +eres +es +somos +sois +son +sea +seas +seamos +seáis +sean +seré +serás +será +seremos +seréis +serán +sería +serías +seríamos +seríais +serían +era +eras +éramos +erais +eran +fui +fuiste +fue +fuimos +fuisteis +fueron +fuera +fueras +fuéramos +fuerais +fueran +fuese +fueses +fuésemos +fueseis +fuesen +siendo +sido + | sed also means 'thirst' + + | forms of tener, to have (not including the infinitive): +tengo +tienes +tiene +tenemos +tenéis +tienen +tenga +tengas +tengamos +tengáis +tengan +tendré +tendrás +tendrá +tendremos +tendréis +tendrán +tendría +tendrías +tendríamos +tendríais +tendrían +tenía +tenías +teníamos +teníais +tenían +tuve +tuviste +tuvo +tuvimos +tuvisteis +tuvieron +tuviera +tuvieras +tuviéramos +tuvierais +tuvieran +tuviese +tuvieses +tuviésemos +tuvieseis +tuviesen +teniendo +tenido +tenida +tenidos +tenidas +tened + diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_eu.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_eu.txt new file mode 100644 index 00000000000..25f1db93460 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_eu.txt @@ -0,0 +1,99 @@ +# example set of basque stopwords +al +anitz +arabera +asko +baina +bat +batean +batek +bati +batzuei +batzuek +batzuetan +batzuk +bera +beraiek +berau +berauek +bere +berori +beroriek +beste +bezala +da +dago +dira +ditu +du +dute +edo +egin +ere +eta +eurak +ez +gainera +gu +gutxi +guzti +haiei +haiek +haietan +hainbeste +hala +han +handik +hango +hara +hari +hark +hartan +hau +hauei +hauek +hauetan +hemen +hemendik +hemengo +hi +hona +honek +honela +honetan +honi +hor +hori +horiei +horiek +horietan +horko +horra +horrek +horrela +horretan +horri +hortik +hura +izan +ni +noiz +nola +non +nondik +nongo +nor +nora +ze +zein +zen +zenbait +zenbat +zer +zergatik +ziren +zituen +zu +zuek +zuen +zuten diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fa.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fa.txt new file mode 100644 index 00000000000..723641c6da7 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fa.txt @@ -0,0 +1,313 @@ +# This file was created by Jacques Savoy and is distributed under the BSD license. +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# Also see http://www.opensource.org/licenses/bsd-license.html +# Note: by default this file is used after normalization, so when adding entries +# to this file, use the arabic 'ي' instead of 'ی' +انان +نداشته +سراسر +خياه +ايشان +وي +تاكنون +بيشتري +دوم +پس +ناشي +وگو +يا +داشتند +سپس +هنگام +هرگز +پنج +نشان +امسال +ديگر +گروهي +شدند +چطور +ده +و +دو +نخستين +ولي +چرا +چه +وسط +ه +كدام +قابل +يك +رفت +هفت +همچنين +در +هزار +بله +بلي +شايد +اما +شناسي +گرفته +دهد +داشته +دانست +داشتن +خواهيم +ميليارد +وقتيكه +امد +خواهد +جز +اورده +شده +بلكه +خدمات +شدن +برخي +نبود +بسياري +جلوگيري +حق +كردند +نوعي +بعري +نكرده +نظير +نبايد +بوده +بودن +داد +اورد +هست +جايي +شود +دنبال +داده +بايد +سابق +هيچ +همان +انجا +كمتر +كجاست +گردد +كسي +تر +مردم +تان +دادن +بودند +سري +جدا +ندارند +مگر +يكديگر +دارد +دهند +بنابراين +هنگامي +سمت +جا +انچه +خود +دادند +زياد +دارند +اثر +بدون +بهترين +بيشتر +البته +به +براساس +بيرون +كرد +بعضي +گرفت +توي +اي +ميليون +او +جريان +تول +بر +مانند +برابر +باشيم +مدتي +گويند +اكنون +تا +تنها +جديد +چند +بي +نشده +كردن +كردم +گويد +كرده +كنيم +نمي +نزد +روي +قصد +فقط +بالاي +ديگران +اين +ديروز +توسط +سوم +ايم +دانند +سوي +استفاده +شما +كنار +داريم +ساخته +طور +امده +رفته +نخست +بيست +نزديك +طي +كنيد +از +انها +تمامي +داشت +يكي +طريق +اش +چيست +روب +نمايد +گفت +چندين +چيزي +تواند +ام +ايا +با +ان +ايد +ترين +اينكه +ديگري +راه +هايي +بروز +همچنان +پاعين +كس +حدود +مختلف +مقابل +چيز +گيرد +ندارد +ضد +همچون +سازي +شان +مورد +باره +مرسي +خويش +برخوردار +چون +خارج +شش +هنوز +تحت +ضمن +هستيم +گفته +فكر +بسيار +پيش +براي +روزهاي +انكه +نخواهد +بالا +كل +وقتي +كي +چنين +كه +گيري +نيست +است +كجا +كند +نيز +يابد +بندي +حتي +توانند +عقب +خواست +كنند +بين +تمام +همه +ما +باشند +مثل +شد +اري +باشد +اره +طبق +بعد +اگر +صورت +غير +جاي +بيش +ريزي +اند +زيرا +چگونه +بار +لطفا +مي +درباره +من +ديده +همين +گذاري +برداري +علت +گذاشته +هم +فوق +نه +ها +شوند +اباد +همواره +هر +اول +خواهند +چهار +نام +امروز +مان +هاي +قبل +كنم +سعي +تازه +را +هستند +زير +جلوي +عنوان +بود diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fi.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fi.txt new file mode 100644 index 00000000000..addad798c4b --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fi.txt @@ -0,0 +1,95 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/finnish/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + +| forms of BE + +olla +olen +olet +on +olemme +olette +ovat +ole | negative form + +oli +olisi +olisit +olisin +olisimme +olisitte +olisivat +olit +olin +olimme +olitte +olivat +ollut +olleet + +en | negation +et +ei +emme +ette +eivät + +|Nom Gen Acc Part Iness Elat Illat Adess Ablat Allat Ess Trans +minä minun minut minua minussa minusta minuun minulla minulta minulle | I +sinä sinun sinut sinua sinussa sinusta sinuun sinulla sinulta sinulle | you +hän hänen hänet häntä hänessä hänestä häneen hänellä häneltä hänelle | he she +me meidän meidät meitä meissä meistä meihin meillä meiltä meille | we +te teidän teidät teitä teissä teistä teihin teillä teiltä teille | you +he heidän heidät heitä heissä heistä heihin heillä heiltä heille | they + +tämä tämän tätä tässä tästä tähän tallä tältä tälle tänä täksi | this +tuo tuon tuotä tuossa tuosta tuohon tuolla tuolta tuolle tuona tuoksi | that +se sen sitä siinä siitä siihen sillä siltä sille sinä siksi | it +nämä näiden näitä näissä näistä näihin näillä näiltä näille näinä näiksi | these +nuo noiden noita noissa noista noihin noilla noilta noille noina noiksi | those +ne niiden niitä niissä niistä niihin niillä niiltä niille niinä niiksi | they + +kuka kenen kenet ketä kenessä kenestä keneen kenellä keneltä kenelle kenenä keneksi| who +ketkä keiden ketkä keitä keissä keistä keihin keillä keiltä keille keinä keiksi | (pl) +mikä minkä minkä mitä missä mistä mihin millä miltä mille minä miksi | which what +mitkä | (pl) + +joka jonka jota jossa josta johon jolla jolta jolle jona joksi | who which +jotka joiden joita joissa joista joihin joilla joilta joille joina joiksi | (pl) + +| conjunctions + +että | that +ja | and +jos | if +koska | because +kuin | than +mutta | but +niin | so +sekä | and +sillä | for +tai | or +vaan | but +vai | or +vaikka | although + + +| prepositions + +kanssa | with +mukaan | according to +noin | about +poikki | across +yli | over, across + +| other + +kun | when +niin | so +nyt | now +itse | self + diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fr.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fr.txt new file mode 100644 index 00000000000..c00837ea939 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fr.txt @@ -0,0 +1,183 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/french/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A French stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + +au | a + le +aux | a + les +avec | with +ce | this +ces | these +dans | with +de | of +des | de + les +du | de + le +elle | she +en | `of them' etc +et | and +eux | them +il | he +je | I +la | the +le | the +leur | their +lui | him +ma | my (fem) +mais | but +me | me +même | same; as in moi-même (myself) etc +mes | me (pl) +moi | me +mon | my (masc) +ne | not +nos | our (pl) +notre | our +nous | we +on | one +ou | where +par | by +pas | not +pour | for +qu | que before vowel +que | that +qui | who +sa | his, her (fem) +se | oneself +ses | his (pl) +son | his, her (masc) +sur | on +ta | thy (fem) +te | thee +tes | thy (pl) +toi | thee +ton | thy (masc) +tu | thou +un | a +une | a +vos | your (pl) +votre | your +vous | you + + | single letter forms + +c | c' +d | d' +j | j' +l | l' +à | to, at +m | m' +n | n' +s | s' +t | t' +y | there + + | forms of être (not including the infinitive): +été +étée +étées +étés +étant +suis +es +est +sommes +êtes +sont +serai +seras +sera +serons +serez +seront +serais +serait +serions +seriez +seraient +étais +était +étions +étiez +étaient +fus +fut +fûmes +fûtes +furent +sois +soit +soyons +soyez +soient +fusse +fusses +fût +fussions +fussiez +fussent + + | forms of avoir (not including the infinitive): +ayant +eu +eue +eues +eus +ai +as +avons +avez +ont +aurai +auras +aura +aurons +aurez +auront +aurais +aurait +aurions +auriez +auraient +avais +avait +avions +aviez +avaient +eut +eûmes +eûtes +eurent +aie +aies +ait +ayons +ayez +aient +eusse +eusses +eût +eussions +eussiez +eussent + + | Later additions (from Jean-Christophe Deschamps) +ceci | this +celà  | that +cet | this +cette | this +ici | here +ils | they +les | the (pl) +leurs | their (pl) +quel | which +quels | which +quelle | which +quelles | which +sans | without +soi | oneself + diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ga.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ga.txt new file mode 100644 index 00000000000..9ff88d747e5 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ga.txt @@ -0,0 +1,110 @@ + +a +ach +ag +agus +an +aon +ar +arna +as +b' +ba +beirt +bhúr +caoga +ceathair +ceathrar +chomh +chtó +chuig +chun +cois +céad +cúig +cúigear +d' +daichead +dar +de +deich +deichniúr +den +dhá +do +don +dtí +dá +dár +dó +faoi +faoin +faoina +faoinár +fara +fiche +gach +gan +go +gur +haon +hocht +i +iad +idir +in +ina +ins +inár +is +le +leis +lena +lenár +m' +mar +mo +mé +na +nach +naoi +naonúr +ná +ní +níor +nó +nócha +ocht +ochtar +os +roimh +sa +seacht +seachtar +seachtó +seasca +seisear +siad +sibh +sinn +sna +sé +sí +tar +thar +thú +triúr +trí +trína +trínár +tríocha +tú +um +ár +é +éis +í +ó +ón +óna +ónár diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_gl.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_gl.txt new file mode 100644 index 00000000000..d8760b12c14 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_gl.txt @@ -0,0 +1,161 @@ +# galican stopwords +a +aínda +alí +aquel +aquela +aquelas +aqueles +aquilo +aquí +ao +aos +as +así +á +ben +cando +che +co +coa +comigo +con +connosco +contigo +convosco +coas +cos +cun +cuns +cunha +cunhas +da +dalgunha +dalgunhas +dalgún +dalgúns +das +de +del +dela +delas +deles +desde +deste +do +dos +dun +duns +dunha +dunhas +e +el +ela +elas +eles +en +era +eran +esa +esas +ese +eses +esta +estar +estaba +está +están +este +estes +estiven +estou +eu +é +facer +foi +foron +fun +había +hai +iso +isto +la +las +lle +lles +lo +los +mais +me +meu +meus +min +miña +miñas +moi +na +nas +neste +nin +no +non +nos +nosa +nosas +noso +nosos +nós +nun +nunha +nuns +nunhas +o +os +ou +ó +ós +para +pero +pode +pois +pola +polas +polo +polos +por +que +se +senón +ser +seu +seus +sexa +sido +sobre +súa +súas +tamén +tan +te +ten +teñen +teño +ter +teu +teus +ti +tido +tiña +tiven +túa +túas +un +unha +unhas +uns +vos +vosa +vosas +voso +vosos +vós diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hi.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hi.txt new file mode 100644 index 00000000000..86286bb083b --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hi.txt @@ -0,0 +1,235 @@ +# Also see http://www.opensource.org/licenses/bsd-license.html +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# This file was created by Jacques Savoy and is distributed under the BSD license. +# Note: by default this file also contains forms normalized by HindiNormalizer +# for spelling variation (see section below), such that it can be used whether or +# not you enable that feature. When adding additional entries to this list, +# please add the normalized form as well. +अंदर +अत +अपना +अपनी +अपने +अभी +आदि +आप +इत्यादि +इन +इनका +इन्हीं +इन्हें +इन्हों +इस +इसका +इसकी +इसके +इसमें +इसी +इसे +उन +उनका +उनकी +उनके +उनको +उन्हीं +उन्हें +उन्हों +उस +उसके +उसी +उसे +एक +एवं +एस +ऐसे +और +कई +कर +करता +करते +करना +करने +करें +कहते +कहा +का +काफ़ी +कि +कितना +किन्हें +किन्हों +किया +किर +किस +किसी +किसे +की +कुछ +कुल +के +को +कोई +कौन +कौनसा +गया +घर +जब +जहाँ +जा +जितना +जिन +जिन्हें +जिन्हों +जिस +जिसे +जीधर +जैसा +जैसे +जो +तक +तब +तरह +तिन +तिन्हें +तिन्हों +तिस +तिसे +तो +था +थी +थे +दबारा +दिया +दुसरा +दूसरे +दो +द्वारा +न +नहीं +ना +निहायत +नीचे +ने +पर +पर +पहले +पूरा +पे +फिर +बनी +बही +बहुत +बाद +बाला +बिलकुल +भी +भीतर +मगर +मानो +मे +में +यदि +यह +यहाँ +यही +या +यिह +ये +रखें +रहा +रहे +ऱ्वासा +लिए +लिये +लेकिन +व +वर्ग +वह +वह +वहाँ +वहीं +वाले +वुह +वे +वग़ैरह +संग +सकता +सकते +सबसे +सभी +साथ +साबुत +साभ +सारा +से +सो +ही +हुआ +हुई +हुए +है +हैं +हो +होता +होती +होते +होना +होने +# additional normalized forms of the above +अपनि +जेसे +होति +सभि +तिंहों +इंहों +दवारा +इसि +किंहें +थि +उंहों +ओर +जिंहें +वहिं +अभि +बनि +हि +उंहिं +उंहें +हें +वगेरह +एसे +रवासा +कोन +निचे +काफि +उसि +पुरा +भितर +हे +बहि +वहां +कोइ +यहां +जिंहों +तिंहें +किसि +कइ +यहि +इंहिं +जिधर +इंहें +अदि +इतयादि +हुइ +कोनसा +इसकि +दुसरे +जहां +अप +किंहों +उनकि +भि +वरग +हुअ +जेसा +नहिं diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hu.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hu.txt new file mode 100644 index 00000000000..1a96f1db6f2 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hu.txt @@ -0,0 +1,209 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/hungarian/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + +| Hungarian stop word list +| prepared by Anna Tordai + +a +ahogy +ahol +aki +akik +akkor +alatt +által +általában +amely +amelyek +amelyekben +amelyeket +amelyet +amelynek +ami +amit +amolyan +amíg +amikor +át +abban +ahhoz +annak +arra +arról +az +azok +azon +azt +azzal +azért +aztán +azután +azonban +bár +be +belül +benne +cikk +cikkek +cikkeket +csak +de +e +eddig +egész +egy +egyes +egyetlen +egyéb +egyik +egyre +ekkor +el +elég +ellen +elő +először +előtt +első +én +éppen +ebben +ehhez +emilyen +ennek +erre +ez +ezt +ezek +ezen +ezzel +ezért +és +fel +felé +hanem +hiszen +hogy +hogyan +igen +így +illetve +ill. +ill +ilyen +ilyenkor +ison +ismét +itt +jó +jól +jobban +kell +kellett +keresztül +keressünk +ki +kívül +között +közül +legalább +lehet +lehetett +legyen +lenne +lenni +lesz +lett +maga +magát +majd +majd +már +más +másik +meg +még +mellett +mert +mely +melyek +mi +mit +míg +miért +milyen +mikor +minden +mindent +mindenki +mindig +mint +mintha +mivel +most +nagy +nagyobb +nagyon +ne +néha +nekem +neki +nem +néhány +nélkül +nincs +olyan +ott +össze +ő +ők +őket +pedig +persze +rá +s +saját +sem +semmi +sok +sokat +sokkal +számára +szemben +szerint +szinte +talán +tehát +teljes +tovább +továbbá +több +úgy +ugyanis +új +újabb +újra +után +utána +utolsó +vagy +vagyis +valaki +valami +valamint +való +vagyok +van +vannak +volt +voltam +voltak +voltunk +vissza +vele +viszont +volna diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hy.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hy.txt new file mode 100644 index 00000000000..60c1c50fbc8 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hy.txt @@ -0,0 +1,46 @@ +# example set of Armenian stopwords. +այդ +այլ +այն +այս +դու +դուք +եմ +են +ենք +ես +եք +է +էի +էին +էինք +էիր +էիք +էր +ըստ +թ +ի +ին +իսկ +իր +կամ +համար +հետ +հետո +մենք +մեջ +մի +ն +նա +նաև +նրա +նրանք +որ +որը +որոնք +որպես +ու +ում +պիտի +վրա +և diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_id.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_id.txt new file mode 100644 index 00000000000..4617f83a5c5 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_id.txt @@ -0,0 +1,359 @@ +# from appendix D of: A Study of Stemming Effects on Information +# Retrieval in Bahasa Indonesia +ada +adanya +adalah +adapun +agak +agaknya +agar +akan +akankah +akhirnya +aku +akulah +amat +amatlah +anda +andalah +antar +diantaranya +antara +antaranya +diantara +apa +apaan +mengapa +apabila +apakah +apalagi +apatah +atau +ataukah +ataupun +bagai +bagaikan +sebagai +sebagainya +bagaimana +bagaimanapun +sebagaimana +bagaimanakah +bagi +bahkan +bahwa +bahwasanya +sebaliknya +banyak +sebanyak +beberapa +seberapa +begini +beginian +beginikah +beginilah +sebegini +begitu +begitukah +begitulah +begitupun +sebegitu +belum +belumlah +sebelum +sebelumnya +sebenarnya +berapa +berapakah +berapalah +berapapun +betulkah +sebetulnya +biasa +biasanya +bila +bilakah +bisa +bisakah +sebisanya +boleh +bolehkah +bolehlah +buat +bukan +bukankah +bukanlah +bukannya +cuma +percuma +dahulu +dalam +dan +dapat +dari +daripada +dekat +demi +demikian +demikianlah +sedemikian +dengan +depan +di +dia +dialah +dini +diri +dirinya +terdiri +dong +dulu +enggak +enggaknya +entah +entahlah +terhadap +terhadapnya +hal +hampir +hanya +hanyalah +harus +haruslah +harusnya +seharusnya +hendak +hendaklah +hendaknya +hingga +sehingga +ia +ialah +ibarat +ingin +inginkah +inginkan +ini +inikah +inilah +itu +itukah +itulah +jangan +jangankan +janganlah +jika +jikalau +juga +justru +kala +kalau +kalaulah +kalaupun +kalian +kami +kamilah +kamu +kamulah +kan +kapan +kapankah +kapanpun +dikarenakan +karena +karenanya +ke +kecil +kemudian +kenapa +kepada +kepadanya +ketika +seketika +khususnya +kini +kinilah +kiranya +sekiranya +kita +kitalah +kok +lagi +lagian +selagi +lah +lain +lainnya +melainkan +selaku +lalu +melalui +terlalu +lama +lamanya +selama +selama +selamanya +lebih +terlebih +bermacam +macam +semacam +maka +makanya +makin +malah +malahan +mampu +mampukah +mana +manakala +manalagi +masih +masihkah +semasih +masing +mau +maupun +semaunya +memang +mereka +merekalah +meski +meskipun +semula +mungkin +mungkinkah +nah +namun +nanti +nantinya +nyaris +oleh +olehnya +seorang +seseorang +pada +padanya +padahal +paling +sepanjang +pantas +sepantasnya +sepantasnyalah +para +pasti +pastilah +per +pernah +pula +pun +merupakan +rupanya +serupa +saat +saatnya +sesaat +saja +sajalah +saling +bersama +sama +sesama +sambil +sampai +sana +sangat +sangatlah +saya +sayalah +se +sebab +sebabnya +sebuah +tersebut +tersebutlah +sedang +sedangkan +sedikit +sedikitnya +segala +segalanya +segera +sesegera +sejak +sejenak +sekali +sekalian +sekalipun +sesekali +sekaligus +sekarang +sekarang +sekitar +sekitarnya +sela +selain +selalu +seluruh +seluruhnya +semakin +sementara +sempat +semua +semuanya +sendiri +sendirinya +seolah +seperti +sepertinya +sering +seringnya +serta +siapa +siapakah +siapapun +disini +disinilah +sini +sinilah +sesuatu +sesuatunya +suatu +sesudah +sesudahnya +sudah +sudahkah +sudahlah +supaya +tadi +tadinya +tak +tanpa +setelah +telah +tentang +tentu +tentulah +tentunya +tertentu +seterusnya +tapi +tetapi +setiap +tiap +setidaknya +tidak +tidakkah +tidaklah +toh +waduh +wah +wahai +sewaktu +walau +walaupun +wong +yaitu +yakni +yang diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_it.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_it.txt new file mode 100644 index 00000000000..4cb5b0891b1 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_it.txt @@ -0,0 +1,301 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/italian/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | An Italian stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + +ad | a (to) before vowel +al | a + il +allo | a + lo +ai | a + i +agli | a + gli +all | a + l' +agl | a + gl' +alla | a + la +alle | a + le +con | with +col | con + il +coi | con + i (forms collo, cogli etc are now very rare) +da | from +dal | da + il +dallo | da + lo +dai | da + i +dagli | da + gli +dall | da + l' +dagl | da + gll' +dalla | da + la +dalle | da + le +di | of +del | di + il +dello | di + lo +dei | di + i +degli | di + gli +dell | di + l' +degl | di + gl' +della | di + la +delle | di + le +in | in +nel | in + el +nello | in + lo +nei | in + i +negli | in + gli +nell | in + l' +negl | in + gl' +nella | in + la +nelle | in + le +su | on +sul | su + il +sullo | su + lo +sui | su + i +sugli | su + gli +sull | su + l' +sugl | su + gl' +sulla | su + la +sulle | su + le +per | through, by +tra | among +contro | against +io | I +tu | thou +lui | he +lei | she +noi | we +voi | you +loro | they +mio | my +mia | +miei | +mie | +tuo | +tua | +tuoi | thy +tue | +suo | +sua | +suoi | his, her +sue | +nostro | our +nostra | +nostri | +nostre | +vostro | your +vostra | +vostri | +vostre | +mi | me +ti | thee +ci | us, there +vi | you, there +lo | him, the +la | her, the +li | them +le | them, the +gli | to him, the +ne | from there etc +il | the +un | a +uno | a +una | a +ma | but +ed | and +se | if +perché | why, because +anche | also +come | how +dov | where (as dov') +dove | where +che | who, that +chi | who +cui | whom +non | not +più | more +quale | who, that +quanto | how much +quanti | +quanta | +quante | +quello | that +quelli | +quella | +quelle | +questo | this +questi | +questa | +queste | +si | yes +tutto | all +tutti | all + + | single letter forms: + +a | at +c | as c' for ce or ci +e | and +i | the +l | as l' +o | or + + | forms of avere, to have (not including the infinitive): + +ho +hai +ha +abbiamo +avete +hanno +abbia +abbiate +abbiano +avrò +avrai +avrà +avremo +avrete +avranno +avrei +avresti +avrebbe +avremmo +avreste +avrebbero +avevo +avevi +aveva +avevamo +avevate +avevano +ebbi +avesti +ebbe +avemmo +aveste +ebbero +avessi +avesse +avessimo +avessero +avendo +avuto +avuta +avuti +avute + + | forms of essere, to be (not including the infinitive): +sono +sei +è +siamo +siete +sia +siate +siano +sarò +sarai +sarà +saremo +sarete +saranno +sarei +saresti +sarebbe +saremmo +sareste +sarebbero +ero +eri +era +eravamo +eravate +erano +fui +fosti +fu +fummo +foste +furono +fossi +fosse +fossimo +fossero +essendo + + | forms of fare, to do (not including the infinitive, fa, fat-): +faccio +fai +facciamo +fanno +faccia +facciate +facciano +farò +farai +farà +faremo +farete +faranno +farei +faresti +farebbe +faremmo +fareste +farebbero +facevo +facevi +faceva +facevamo +facevate +facevano +feci +facesti +fece +facemmo +faceste +fecero +facessi +facesse +facessimo +facessero +facendo + + | forms of stare, to be (not including the infinitive): +sto +stai +sta +stiamo +stanno +stia +stiate +stiano +starò +starai +starà +staremo +starete +staranno +starei +staresti +starebbe +staremmo +stareste +starebbero +stavo +stavi +stava +stavamo +stavate +stavano +stetti +stesti +stette +stemmo +steste +stettero +stessi +stesse +stessimo +stessero +stando diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ja.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ja.txt new file mode 100644 index 00000000000..d4321be6b16 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ja.txt @@ -0,0 +1,127 @@ +# +# This file defines a stopword set for Japanese. +# +# This set is made up of hand-picked frequent terms from segmented Japanese Wikipedia. +# Punctuation characters and frequent kanji have mostly been left out. See LUCENE-3745 +# for frequency lists, etc. that can be useful for making your own set (if desired) +# +# Note that there is an overlap between these stopwords and the terms stopped when used +# in combination with the JapanesePartOfSpeechStopFilter. When editing this file, note +# that comments are not allowed on the same line as stopwords. +# +# Also note that stopping is done in a case-insensitive manner. Change your StopFilter +# configuration if you need case-sensitive stopping. Lastly, note that stopping is done +# using the same character width as the entries in this file. Since this StopFilter is +# normally done after a CJKWidthFilter in your chain, you would usually want your romaji +# entries to be in half-width and your kana entries to be in full-width. +# +の +に +は +を +た +が +で +て +と +し +れ +さ +ある +いる +も +する +から +な +こと +として +い +や +れる +など +なっ +ない +この +ため +その +あっ +よう +また +もの +という +あり +まで +られ +なる +へ +か +だ +これ +によって +により +おり +より +による +ず +なり +られる +において +ば +なかっ +なく +しかし +について +せ +だっ +その後 +できる +それ +う +ので +なお +のみ +でき +き +つ +における +および +いう +さらに +でも +ら +たり +その他 +に関する +たち +ます +ん +なら +に対して +特に +せる +及び +これら +とき +では +にて +ほか +ながら +うち +そして +とともに +ただし +かつて +それぞれ +または +お +ほど +ものの +に対する +ほとんど +と共に +といった +です +とも +ところ +ここ +##### End of file diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_lv.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_lv.txt new file mode 100644 index 00000000000..e21a23c06c3 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_lv.txt @@ -0,0 +1,172 @@ +# Set of Latvian stopwords from A Stemming Algorithm for Latvian, Karlis Kreslins +# the original list of over 800 forms was refined: +# pronouns, adverbs, interjections were removed +# +# prepositions +aiz +ap +ar +apakš +ārpus +augšpus +bez +caur +dēļ +gar +iekš +iz +kopš +labad +lejpus +līdz +no +otrpus +pa +par +pār +pēc +pie +pirms +pret +priekš +starp +šaipus +uz +viņpus +virs +virspus +zem +apakšpus +# Conjunctions +un +bet +jo +ja +ka +lai +tomēr +tikko +turpretī +arī +kaut +gan +tādēļ +tā +ne +tikvien +vien +kā +ir +te +vai +kamēr +# Particles +ar +diezin +droši +diemžēl +nebūt +ik +it +taču +nu +pat +tiklab +iekšpus +nedz +tik +nevis +turpretim +jeb +iekam +iekām +iekāms +kolīdz +līdzko +tiklīdz +jebšu +tālab +tāpēc +nekā +itin +jā +jau +jel +nē +nezin +tad +tikai +vis +tak +iekams +vien +# modal verbs +būt +biju +biji +bija +bijām +bijāt +esmu +esi +esam +esat +būšu +būsi +būs +būsim +būsiet +tikt +tiku +tiki +tika +tikām +tikāt +tieku +tiec +tiek +tiekam +tiekat +tikšu +tiks +tiksim +tiksiet +tapt +tapi +tapāt +topat +tapšu +tapsi +taps +tapsim +tapsiet +kļūt +kļuvu +kļuvi +kļuva +kļuvām +kļuvāt +kļūstu +kļūsti +kļūst +kļūstam +kļūstat +kļūšu +kļūsi +kļūs +kļūsim +kļūsiet +# verbs +varēt +varēju +varējām +varēšu +varēsim +var +varēji +varējāt +varēsi +varēsiet +varat +varēja +varēs diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_nl.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_nl.txt new file mode 100644 index 00000000000..f4d61f5092c --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_nl.txt @@ -0,0 +1,117 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/dutch/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Dutch stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | This is a ranked list (commonest to rarest) of stopwords derived from + | a large sample of Dutch text. + + | Dutch stop words frequently exhibit homonym clashes. These are indicated + | clearly below. + +de | the +en | and +van | of, from +ik | I, the ego +te | (1) chez, at etc, (2) to, (3) too +dat | that, which +die | that, those, who, which +in | in, inside +een | a, an, one +hij | he +het | the, it +niet | not, nothing, naught +zijn | (1) to be, being, (2) his, one's, its +is | is +was | (1) was, past tense of all persons sing. of 'zijn' (to be) (2) wax, (3) the washing, (4) rise of river +op | on, upon, at, in, up, used up +aan | on, upon, to (as dative) +met | with, by +als | like, such as, when +voor | (1) before, in front of, (2) furrow +had | had, past tense all persons sing. of 'hebben' (have) +er | there +maar | but, only +om | round, about, for etc +hem | him +dan | then +zou | should/would, past tense all persons sing. of 'zullen' +of | or, whether, if +wat | what, something, anything +mijn | possessive and noun 'mine' +men | people, 'one' +dit | this +zo | so, thus, in this way +door | through by +over | over, across +ze | she, her, they, them +zich | oneself +bij | (1) a bee, (2) by, near, at +ook | also, too +tot | till, until +je | you +mij | me +uit | out of, from +der | Old Dutch form of 'van der' still found in surnames +daar | (1) there, (2) because +haar | (1) her, their, them, (2) hair +naar | (1) unpleasant, unwell etc, (2) towards, (3) as +heb | present first person sing. of 'to have' +hoe | how, why +heeft | present third person sing. of 'to have' +hebben | 'to have' and various parts thereof +deze | this +u | you +want | (1) for, (2) mitten, (3) rigging +nog | yet, still +zal | 'shall', first and third person sing. of verb 'zullen' (will) +me | me +zij | she, they +nu | now +ge | 'thou', still used in Belgium and south Netherlands +geen | none +omdat | because +iets | something, somewhat +worden | to become, grow, get +toch | yet, still +al | all, every, each +waren | (1) 'were' (2) to wander, (3) wares, (3) +veel | much, many +meer | (1) more, (2) lake +doen | to do, to make +toen | then, when +moet | noun 'spot/mote' and present form of 'to must' +ben | (1) am, (2) 'are' in interrogative second person singular of 'to be' +zonder | without +kan | noun 'can' and present form of 'to be able' +hun | their, them +dus | so, consequently +alles | all, everything, anything +onder | under, beneath +ja | yes, of course +eens | once, one day +hier | here +wie | who +werd | imperfect third person sing. of 'become' +altijd | always +doch | yet, but etc +wordt | present third person sing. of 'become' +wezen | (1) to be, (2) 'been' as in 'been fishing', (3) orphans +kunnen | to be able +ons | us/our +zelf | self +tegen | against, towards, at +na | after, near +reeds | already +wil | (1) present tense of 'want', (2) 'will', noun, (3) fender +kon | could; past tense of 'to be able' +niets | nothing +uw | your +iemand | somebody +geweest | been; past participle of 'be' +andere | other diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_no.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_no.txt new file mode 100644 index 00000000000..e76f36e69ed --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_no.txt @@ -0,0 +1,192 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/norwegian/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Norwegian stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | This stop word list is for the dominant bokmål dialect. Words unique + | to nynorsk are marked *. + + | Revised by Jan Bruusgaard , Jan 2005 + +og | and +i | in +jeg | I +det | it/this/that +at | to (w. inf.) +en | a/an +et | a/an +den | it/this/that +til | to +er | is/am/are +som | who/that +på | on +de | they / you(formal) +med | with +han | he +av | of +ikke | not +ikkje | not * +der | there +så | so +var | was/were +meg | me +seg | you +men | but +ett | one +har | have +om | about +vi | we +min | my +mitt | my +ha | have +hadde | had +hun | she +nå | now +over | over +da | when/as +ved | by/know +fra | from +du | you +ut | out +sin | your +dem | them +oss | us +opp | up +man | you/one +kan | can +hans | his +hvor | where +eller | or +hva | what +skal | shall/must +selv | self (reflective) +sjøl | self (reflective) +her | here +alle | all +vil | will +bli | become +ble | became +blei | became * +blitt | have become +kunne | could +inn | in +når | when +være | be +kom | come +noen | some +noe | some +ville | would +dere | you +som | who/which/that +deres | their/theirs +kun | only/just +ja | yes +etter | after +ned | down +skulle | should +denne | this +for | for/because +deg | you +si | hers/his +sine | hers/his +sitt | hers/his +mot | against +å | to +meget | much +hvorfor | why +dette | this +disse | these/those +uten | without +hvordan | how +ingen | none +din | your +ditt | your +blir | become +samme | same +hvilken | which +hvilke | which (plural) +sånn | such a +inni | inside/within +mellom | between +vår | our +hver | each +hvem | who +vors | us/ours +hvis | whose +både | both +bare | only/just +enn | than +fordi | as/because +før | before +mange | many +også | also +slik | just +vært | been +være | to be +båe | both * +begge | both +siden | since +dykk | your * +dykkar | yours * +dei | they * +deira | them * +deires | theirs * +deim | them * +di | your (fem.) * +då | as/when * +eg | I * +ein | a/an * +eit | a/an * +eitt | a/an * +elles | or * +honom | he * +hjå | at * +ho | she * +hoe | she * +henne | her +hennar | her/hers +hennes | hers +hoss | how * +hossen | how * +ikkje | not * +ingi | noone * +inkje | noone * +korleis | how * +korso | how * +kva | what/which * +kvar | where * +kvarhelst | where * +kven | who/whom * +kvi | why * +kvifor | why * +me | we * +medan | while * +mi | my * +mine | my * +mykje | much * +no | now * +nokon | some (masc./neut.) * +noka | some (fem.) * +nokor | some * +noko | some * +nokre | some * +si | his/hers * +sia | since * +sidan | since * +so | so * +somt | some * +somme | some * +um | about* +upp | up * +vere | be * +vore | was * +verte | become * +vort | become * +varte | became * +vart | became * + diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_pt.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_pt.txt new file mode 100644 index 00000000000..276c1b446f2 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_pt.txt @@ -0,0 +1,251 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/portuguese/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Portuguese stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + + | The following is a ranked list (commonest to rarest) of stopwords + | deriving from a large sample of text. + + | Extra words have been added at the end. + +de | of, from +a | the; to, at; her +o | the; him +que | who, that +e | and +do | de + o +da | de + a +em | in +um | a +para | for + | é from SER +com | with +não | not, no +uma | a +os | the; them +no | em + o +se | himself etc +na | em + a +por | for +mais | more +as | the; them +dos | de + os +como | as, like +mas | but + | foi from SER +ao | a + o +ele | he +das | de + as + | tem from TER +à | a + a +seu | his +sua | her +ou | or + | ser from SER +quando | when +muito | much + | há from HAV +nos | em + os; us +já | already, now + | está from EST +eu | I +também | also +só | only, just +pelo | per + o +pela | per + a +até | up to +isso | that +ela | he +entre | between + | era from SER +depois | after +sem | without +mesmo | same +aos | a + os + | ter from TER +seus | his +quem | whom +nas | em + as +me | me +esse | that +eles | they + | estão from EST +você | you + | tinha from TER + | foram from SER +essa | that +num | em + um +nem | nor +suas | her +meu | my +às | a + as +minha | my + | têm from TER +numa | em + uma +pelos | per + os +elas | they + | havia from HAV + | seja from SER +qual | which + | será from SER +nós | we + | tenho from TER +lhe | to him, her +deles | of them +essas | those +esses | those +pelas | per + as +este | this + | fosse from SER +dele | of him + + | other words. There are many contractions such as naquele = em+aquele, + | mo = me+o, but they are rare. + | Indefinite article plural forms are also rare. + +tu | thou +te | thee +vocês | you (plural) +vos | you +lhes | to them +meus | my +minhas +teu | thy +tua +teus +tuas +nosso | our +nossa +nossos +nossas + +dela | of her +delas | of them + +esta | this +estes | these +estas | these +aquele | that +aquela | that +aqueles | those +aquelas | those +isto | this +aquilo | that + + | forms of estar, to be (not including the infinitive): +estou +está +estamos +estão +estive +esteve +estivemos +estiveram +estava +estávamos +estavam +estivera +estivéramos +esteja +estejamos +estejam +estivesse +estivéssemos +estivessem +estiver +estivermos +estiverem + + | forms of haver, to have (not including the infinitive): +hei +há +havemos +hão +houve +houvemos +houveram +houvera +houvéramos +haja +hajamos +hajam +houvesse +houvéssemos +houvessem +houver +houvermos +houverem +houverei +houverá +houveremos +houverão +houveria +houveríamos +houveriam + + | forms of ser, to be (not including the infinitive): +sou +somos +são +era +éramos +eram +fui +foi +fomos +foram +fora +fôramos +seja +sejamos +sejam +fosse +fôssemos +fossem +for +formos +forem +serei +será +seremos +serão +seria +seríamos +seriam + + | forms of ter, to have (not including the infinitive): +tenho +tem +temos +tém +tinha +tínhamos +tinham +tive +teve +tivemos +tiveram +tivera +tivéramos +tenha +tenhamos +tenham +tivesse +tivéssemos +tivessem +tiver +tivermos +tiverem +terei +terá +teremos +terão +teria +teríamos +teriam diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ro.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ro.txt new file mode 100644 index 00000000000..4fdee90a5ba --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ro.txt @@ -0,0 +1,233 @@ +# This file was created by Jacques Savoy and is distributed under the BSD license. +# See http://members.unine.ch/jacques.savoy/clef/index.html. +# Also see http://www.opensource.org/licenses/bsd-license.html +acea +aceasta +această +aceea +acei +aceia +acel +acela +acele +acelea +acest +acesta +aceste +acestea +aceşti +aceştia +acolo +acum +ai +aia +aibă +aici +al +ăla +ale +alea +ălea +altceva +altcineva +am +ar +are +aş +aşadar +asemenea +asta +ăsta +astăzi +astea +ăstea +ăştia +asupra +aţi +au +avea +avem +aveţi +azi +bine +bucur +bună +ca +că +căci +când +care +cărei +căror +cărui +cât +câte +câţi +către +câtva +ce +cel +ceva +chiar +cînd +cine +cineva +cît +cîte +cîţi +cîtva +contra +cu +cum +cumva +curând +curînd +da +dă +dacă +dar +datorită +de +deci +deja +deoarece +departe +deşi +din +dinaintea +dintr +dintre +drept +după +ea +ei +el +ele +eram +este +eşti +eu +face +fără +fi +fie +fiecare +fii +fim +fiţi +iar +ieri +îi +îl +îmi +împotriva +în +înainte +înaintea +încât +încît +încotro +între +întrucât +întrucît +îţi +la +lângă +le +li +lîngă +lor +lui +mă +mâine +mea +mei +mele +mereu +meu +mi +mine +mult +multă +mulţi +ne +nicăieri +nici +nimeni +nişte +noastră +noastre +noi +noştri +nostru +nu +ori +oricând +oricare +oricât +orice +oricînd +oricine +oricît +oricum +oriunde +până +pe +pentru +peste +pînă +poate +pot +prea +prima +primul +prin +printr +sa +să +săi +sale +sau +său +se +şi +sînt +sîntem +sînteţi +spre +sub +sunt +suntem +sunteţi +ta +tăi +tale +tău +te +ţi +ţie +tine +toată +toate +tot +toţi +totuşi +tu +un +una +unde +undeva +unei +unele +uneori +unor +vă +vi +voastră +voastre +voi +voştri +vostru +vouă +vreo +vreun diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ru.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ru.txt new file mode 100644 index 00000000000..64307693457 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ru.txt @@ -0,0 +1,241 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/russian/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | a russian stop word list. comments begin with vertical bar. each stop + | word is at the start of a line. + + | this is a ranked list (commonest to rarest) of stopwords derived from + | a large text sample. + + | letter `ё' is translated to `е'. + +и | and +в | in/into +во | alternative form +не | not +что | what/that +он | he +на | on/onto +я | i +с | from +со | alternative form +как | how +а | milder form of `no' (but) +то | conjunction and form of `that' +все | all +она | she +так | so, thus +его | him +но | but +да | yes/and +ты | thou +к | towards, by +у | around, chez +же | intensifier particle +вы | you +за | beyond, behind +бы | conditional/subj. particle +по | up to, along +только | only +ее | her +мне | to me +было | it was +вот | here is/are, particle +от | away from +меня | me +еще | still, yet, more +нет | no, there isnt/arent +о | about +из | out of +ему | to him +теперь | now +когда | when +даже | even +ну | so, well +вдруг | suddenly +ли | interrogative particle +если | if +уже | already, but homonym of `narrower' +или | or +ни | neither +быть | to be +был | he was +него | prepositional form of его +до | up to +вас | you accusative +нибудь | indef. suffix preceded by hyphen +опять | again +уж | already, but homonym of `adder' +вам | to you +сказал | he said +ведь | particle `after all' +там | there +потом | then +себя | oneself +ничего | nothing +ей | to her +может | usually with `быть' as `maybe' +они | they +тут | here +где | where +есть | there is/are +надо | got to, must +ней | prepositional form of ей +для | for +мы | we +тебя | thee +их | them, their +чем | than +была | she was +сам | self +чтоб | in order to +без | without +будто | as if +человек | man, person, one +чего | genitive form of `what' +раз | once +тоже | also +себе | to oneself +под | beneath +жизнь | life +будет | will be +ж | short form of intensifer particle `же' +тогда | then +кто | who +этот | this +говорил | was saying +того | genitive form of `that' +потому | for that reason +этого | genitive form of `this' +какой | which +совсем | altogether +ним | prepositional form of `его', `они' +здесь | here +этом | prepositional form of `этот' +один | one +почти | almost +мой | my +тем | instrumental/dative plural of `тот', `то' +чтобы | full form of `in order that' +нее | her (acc.) +кажется | it seems +сейчас | now +были | they were +куда | where to +зачем | why +сказать | to say +всех | all (acc., gen. preposn. plural) +никогда | never +сегодня | today +можно | possible, one can +при | by +наконец | finally +два | two +об | alternative form of `о', about +другой | another +хоть | even +после | after +над | above +больше | more +тот | that one (masc.) +через | across, in +эти | these +нас | us +про | about +всего | in all, only, of all +них | prepositional form of `они' (they) +какая | which, feminine +много | lots +разве | interrogative particle +сказала | she said +три | three +эту | this, acc. fem. sing. +моя | my, feminine +впрочем | moreover, besides +хорошо | good +свою | ones own, acc. fem. sing. +этой | oblique form of `эта', fem. `this' +перед | in front of +иногда | sometimes +лучше | better +чуть | a little +том | preposn. form of `that one' +нельзя | one must not +такой | such a one +им | to them +более | more +всегда | always +конечно | of course +всю | acc. fem. sing of `all' +между | between + + + | b: some paradigms + | + | personal pronouns + | + | я меня мне мной [мною] + | ты тебя тебе тобой [тобою] + | он его ему им [него, нему, ним] + | она ее эи ею [нее, нэи, нею] + | оно его ему им [него, нему, ним] + | + | мы нас нам нами + | вы вас вам вами + | они их им ими [них, ним, ними] + | + | себя себе собой [собою] + | + | demonstrative pronouns: этот (this), тот (that) + | + | этот эта это эти + | этого эты это эти + | этого этой этого этих + | этому этой этому этим + | этим этой этим [этою] этими + | этом этой этом этих + | + | тот та то те + | того ту то те + | того той того тех + | тому той тому тем + | тем той тем [тою] теми + | том той том тех + | + | determinative pronouns + | + | (a) весь (all) + | + | весь вся все все + | всего всю все все + | всего всей всего всех + | всему всей всему всем + | всем всей всем [всею] всеми + | всем всей всем всех + | + | (b) сам (himself etc) + | + | сам сама само сами + | самого саму само самих + | самого самой самого самих + | самому самой самому самим + | самим самой самим [самою] самими + | самом самой самом самих + | + | stems of verbs `to be', `to have', `to do' and modal + | + | быть бы буд быв есть суть + | име + | дел + | мог мож мочь + | уме + | хоч хот + | долж + | можн + | нужн + | нельзя + diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_sv.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_sv.txt new file mode 100644 index 00000000000..22bddfd8cb3 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_sv.txt @@ -0,0 +1,131 @@ + | From svn.tartarus.org/snowball/trunk/website/algorithms/swedish/stop.txt + | This file is distributed under the BSD License. + | See http://snowball.tartarus.org/license.php + | Also see http://www.opensource.org/licenses/bsd-license.html + | - Encoding was converted to UTF-8. + | - This notice was added. + + | A Swedish stop word list. Comments begin with vertical bar. Each stop + | word is at the start of a line. + + | This is a ranked list (commonest to rarest) of stopwords derived from + | a large text sample. + + | Swedish stop words occasionally exhibit homonym clashes. For example + | så = so, but also seed. These are indicated clearly below. + +och | and +det | it, this/that +att | to (with infinitive) +i | in, at +en | a +jag | I +hon | she +som | who, that +han | he +på | on +den | it, this/that +med | with +var | where, each +sig | him(self) etc +för | for +så | so (also: seed) +till | to +är | is +men | but +ett | a +om | if; around, about +hade | had +de | they, these/those +av | of +icke | not, no +mig | me +du | you +henne | her +då | then, when +sin | his +nu | now +har | have +inte | inte någon = no one +hans | his +honom | him +skulle | 'sake' +hennes | her +där | there +min | my +man | one (pronoun) +ej | nor +vid | at, by, on (also: vast) +kunde | could +något | some etc +från | from, off +ut | out +när | when +efter | after, behind +upp | up +vi | we +dem | them +vara | be +vad | what +över | over +än | than +dig | you +kan | can +sina | his +här | here +ha | have +mot | towards +alla | all +under | under (also: wonder) +någon | some etc +eller | or (else) +allt | all +mycket | much +sedan | since +ju | why +denna | this/that +själv | myself, yourself etc +detta | this/that +åt | to +utan | without +varit | was +hur | how +ingen | no +mitt | my +ni | you +bli | to be, become +blev | from bli +oss | us +din | thy +dessa | these/those +några | some etc +deras | their +blir | from bli +mina | my +samma | (the) same +vilken | who, that +er | you, your +sådan | such a +vår | our +blivit | from bli +dess | its +inom | within +mellan | between +sådant | such a +varför | why +varje | each +vilka | who, that +ditt | thy +vem | who +vilket | who, that +sitta | his +sådana | such a +vart | each +dina | thy +vars | whose +vårt | our +våra | our +ert | your +era | your +vilkas | whose + diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_th.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_th.txt new file mode 100644 index 00000000000..07f0fabe692 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_th.txt @@ -0,0 +1,119 @@ +# Thai stopwords from: +# "Opinion Detection in Thai Political News Columns +# Based on Subjectivity Analysis" +# Khampol Sukhum, Supot Nitsuwat, and Choochart Haruechaiyasak +ไว้ +ไม่ +ไป +ได้ +ให้ +ใน +โดย +แห่ง +แล้ว +และ +แรก +แบบ +แต่ +เอง +เห็น +เลย +เริ่ม +เรา +เมื่อ +เพื่อ +เพราะ +เป็นการ +เป็น +เปิดเผย +เปิด +เนื่องจาก +เดียวกัน +เดียว +เช่น +เฉพาะ +เคย +เข้า +เขา +อีก +อาจ +อะไร +ออก +อย่าง +อยู่ +อยาก +หาก +หลาย +หลังจาก +หลัง +หรือ +หนึ่ง +ส่วน +ส่ง +สุด +สําหรับ +ว่า +วัน +ลง +ร่วม +ราย +รับ +ระหว่าง +รวม +ยัง +มี +มาก +มา +พร้อม +พบ +ผ่าน +ผล +บาง +น่า +นี้ +นํา +นั้น +นัก +นอกจาก +ทุก +ที่สุด +ที่ +ทําให้ +ทํา +ทาง +ทั้งนี้ +ทั้ง +ถ้า +ถูก +ถึง +ต้อง +ต่างๆ +ต่าง +ต่อ +ตาม +ตั้งแต่ +ตั้ง +ด้าน +ด้วย +ดัง +ซึ่ง +ช่วง +จึง +จาก +จัด +จะ +คือ +ความ +ครั้ง +คง +ขึ้น +ของ +ขอ +ขณะ +ก่อน +ก็ +การ +กับ +กัน +กว่า +กล่าว diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_tr.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_tr.txt new file mode 100644 index 00000000000..84d9408d4ea --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_tr.txt @@ -0,0 +1,212 @@ +# Turkish stopwords from LUCENE-559 +# merged with the list from "Information Retrieval on Turkish Texts" +# (http://www.users.muohio.edu/canf/papers/JASIST2008offPrint.pdf) +acaba +altmış +altı +ama +ancak +arada +aslında +ayrıca +bana +bazı +belki +ben +benden +beni +benim +beri +beş +bile +bin +bir +birçok +biri +birkaç +birkez +birşey +birşeyi +biz +bize +bizden +bizi +bizim +böyle +böylece +bu +buna +bunda +bundan +bunlar +bunları +bunların +bunu +bunun +burada +çok +çünkü +da +daha +dahi +de +defa +değil +diğer +diye +doksan +dokuz +dolayı +dolayısıyla +dört +edecek +eden +ederek +edilecek +ediliyor +edilmesi +ediyor +eğer +elli +en +etmesi +etti +ettiği +ettiğini +gibi +göre +halen +hangi +hatta +hem +henüz +hep +hepsi +her +herhangi +herkesin +hiç +hiçbir +için +iki +ile +ilgili +ise +işte +itibaren +itibariyle +kadar +karşın +katrilyon +kendi +kendilerine +kendini +kendisi +kendisine +kendisini +kez +ki +kim +kimden +kime +kimi +kimse +kırk +milyar +milyon +mu +mü +mı +nasıl +ne +neden +nedenle +nerde +nerede +nereye +niye +niçin +o +olan +olarak +oldu +olduğu +olduğunu +olduklarını +olmadı +olmadığı +olmak +olması +olmayan +olmaz +olsa +olsun +olup +olur +olursa +oluyor +on +ona +ondan +onlar +onlardan +onları +onların +onu +onun +otuz +oysa +öyle +pek +rağmen +sadece +sanki +sekiz +seksen +sen +senden +seni +senin +siz +sizden +sizi +sizin +şey +şeyden +şeyi +şeyler +şöyle +şu +şuna +şunda +şundan +şunları +şunu +tarafından +trilyon +tüm +üç +üzere +var +vardı +ve +veya +ya +yani +yapacak +yapılan +yapılması +yapıyor +yapmak +yaptı +yaptığı +yaptığını +yaptıkları +yedi +yerine +yetmiş +yine +yirmi +yoksa +yüz +zaten diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/userdict_ja.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/userdict_ja.txt new file mode 100644 index 00000000000..6f0368e4d81 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/userdict_ja.txt @@ -0,0 +1,29 @@ +# +# This is a sample user dictionary for Kuromoji (JapaneseTokenizer) +# +# Add entries to this file in order to override the statistical model in terms +# of segmentation, readings and part-of-speech tags. Notice that entries do +# not have weights since they are always used when found. This is by-design +# in order to maximize ease-of-use. +# +# Entries are defined using the following CSV format: +# , ... , ... , +# +# Notice that a single half-width space separates tokens and readings, and +# that the number tokens and readings must match exactly. +# +# Also notice that multiple entries with the same is undefined. +# +# Whitespace only lines are ignored. Comments are not allowed on entry lines. +# + +# Custom segmentation for kanji compounds +日本経済新聞,日本 経済 新聞,ニホン ケイザイ シンブン,カスタム名詞 +関西国際空港,関西 国際 空港,カンサイ コクサイ クウコウ,カスタム名詞 + +# Custom segmentation for compound katakana +トートバッグ,トート バッグ,トート バッグ,かずカナ名詞 +ショルダーバッグ,ショルダー バッグ,ショルダー バッグ,かずカナ名詞 + +# Custom reading for former sumo wrestler +朝青龍,朝青龍,アサショウリュウ,カスタム人名 diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/protwords.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/protwords.txt new file mode 100644 index 00000000000..1dfc0abecbf --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/protwords.txt @@ -0,0 +1,21 @@ +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#----------------------------------------------------------------------- +# Use a protected word file to protect against the stemmer reducing two +# unrelated words to the same base word. + +# Some non-words that normally won't be encountered, +# just to test that they won't be stemmed. +dontstems +zwhacky + diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/schema.xml b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/schema.xml new file mode 100644 index 00000000000..83080dfa40c --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/schema.xml @@ -0,0 +1,914 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + id + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/solrconfig.xml b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/solrconfig.xml new file mode 100644 index 00000000000..9d9178746cf --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/solrconfig.xml @@ -0,0 +1,1764 @@ + + + + + + + + + LUCENE_43 + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${solr.data.dir:} + + + + + + + + + + + + + + + + ${solr.maxIndexingThreads:8} + + + + + + 128 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${solr.ulog.dir:} + + + + + ${solr.autoCommit.maxTime:60000} + false + + + + + + ${solr.autoSoftCommit.maxTime:1000} + + + + + + + + + + + + + + + + + + + + 1024 + + + + + + + + + + + + + + + + + + + + + + true + + + + + + 20 + + + 200 + + + + + + + + + + + + static firstSearcher warming in solrconfig.xml + + + + + + false + + + 4 + + + + + + + + + + + + + + + + + + + + + + + explicit + 10 + text + + + + + + + + + + + + + + explicit + json + true + text + + + + + + + + true + json + true + + + + + + + + explicit + + + velocity + browse + layout + Solritas + + + edismax + + text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 + title^10.0 description^5.0 keywords^5.0 author^2.0 resourcename^1.0 + + text + 100% + *:* + 10 + *,score + + + text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 + title^10.0 description^5.0 keywords^5.0 author^2.0 resourcename^1.0 + + text,features,name,sku,id,manu,cat,title,description,keywords,author,resourcename + 3 + + + on + cat + manu_exact + content_type + author_s + ipod + GB + 1 + cat,inStock + after + price + 0 + 600 + 50 + popularity + 0 + 10 + 3 + manufacturedate_dt + NOW/YEAR-10YEARS + NOW + +1YEAR + before + after + + + on + content features title name + html + <b> + </b> + 0 + title + 0 + name + 3 + 200 + content + 750 + + + on + false + 5 + 2 + 5 + true + true + 5 + 3 + + + + + spellcheck + + + + + + + + + + + + + + application/json + + + + + application/csv + + + + + + + + + + + + + + + + + + + + + solrpingquery + + + all + + + + + + + + + explicit + true + + + + + + + + + + + + + + + + textSpell + + + + + + default + name + solr.DirectSolrSpellChecker + + internal + + 0.5 + + 2 + + 1 + + 5 + + 4 + + 0.01 + + + + + + wordbreak + solr.WordBreakSolrSpellChecker + name + true + true + 10 + + + + + + + + + + + + + + + + text + + default + wordbreak + on + true + 10 + 5 + 5 + true + true + 10 + 5 + + + spellcheck + + + + + + + + + + text + true + + + tvComponent + + + + + + + + + default + + + org.carrot2.clustering.lingo.LingoClusteringAlgorithm + + + 20 + + + clustering/carrot2 + + + ENGLISH + + + stc + org.carrot2.clustering.stc.STCClusteringAlgorithm + + + + + + + true + default + true + + name + id + + features + + true + + + + false + + edismax + + text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 + + *:* + 10 + *,score + + + clustering + + + + + + + + + + true + + + terms + + + + + + + + string + elevate.xml + + + + + + explicit + text + + + elevator + + + + + + + + + + + 100 + + + + + + + + 70 + + 0.5 + + [-\w ,/\n\"']{20,200} + + + + + + + ]]> + ]]> + + + + + + + + + + + + + + + + + + + + + + + + ,, + ,, + ,, + ,, + ,]]> + ]]> + + + + + + 10 + .,!? + + + + + + + WORD + + + en + US + + + + + + + + + + + + + + + + + + + + + + text/plain; charset=UTF-8 + + + + + + + + + 5 + + + + + + + + + + + + + + + + + + *:* + + + diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/stopwords.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/stopwords.txt new file mode 100644 index 00000000000..ae1e83eeb3d --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/stopwords.txt @@ -0,0 +1,14 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/synonyms.txt b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/synonyms.txt new file mode 100644 index 00000000000..7f72128303b --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/synonyms.txt @@ -0,0 +1,29 @@ +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#----------------------------------------------------------------------- +#some test synonym mappings unlikely to appear in real input text +aaafoo => aaabar +bbbfoo => bbbfoo bbbbar +cccfoo => cccbar cccbaz +fooaaa,baraaa,bazaaa + +# Some synonym groups specific to this example +GB,gib,gigabyte,gigabytes +MB,mib,megabyte,megabytes +Television, Televisions, TV, TVs +#notice we use "gib" instead of "GiB" so any WordDelimiterFilter coming +#after us won't split it into two words. + +# Synonym mappings can be used for spelling correction too +pixima => pixma + diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcloud/conf/solrconfig.xml b/solr/contrib/solr-mr/src/test-files/solr/solrcloud/conf/solrconfig.xml new file mode 100644 index 00000000000..a37ab12ecfe --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/solr/solrcloud/conf/solrconfig.xml @@ -0,0 +1,1787 @@ + + + + + + + + + LUCENE_43 + + + + + + + + + + + + + + + + + + + + + + + + ${solr.data.dir:} + + + + + ${solr.hdfs.home:} + ${solr.hdfs.confdir:} + ${solr.hdfs.security.kerberos.enabled:false} + ${solr.hdfs.security.kerberos.keytabfile:} + ${solr.hdfs.security.kerberos.principal:} + ${solr.hdfs.blockcache.enabled:true} + ${solr.hdfs.blockcache.slab.count:1} + ${solr.hdfs.blockcache.direct.memory.allocation:true} + ${solr.hdfs.blockcache.blocksperbank:16384} + ${solr.hdfs.blockcache.read.enabled:true} + ${solr.hdfs.blockcache.write.enabled:true} + ${solr.hdfs.nrtcachingdirectory.enable:true} + ${solr.hdfs.nrtcachingdirectory.maxmergesizemb:16} + ${solr.hdfs.nrtcachingdirectory.maxcachedmb:192} + + + + + + + + + + + + + ${solr.maxIndexingThreads:8} + + + + + + 128 + + + + + + + + + + + + + ${solr.lock.type:hdfs} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${solr.ulog.dir:} + + + + + ${solr.autoCommit.maxTime:60000} + false + + + + + ${solr.autoSoftCommit.maxTime:1000} + + + + + + + + + + + + + + + + + + + 1024 + + + + + + + + + + + + + + + + + + + + + + true + + + + + + 20 + + + 200 + + + + + + + + + + + + static firstSearcher warming in solrconfig.xml + + + + + + false + + + 4 + + + + + + + + + + + + + + + + + + + + + + + explicit + 10 + text + + + + + + + + + + + + + + explicit + json + true + text + + + + + + + + true + json + true + + + + + + + + explicit + + + velocity + browse + layout + Solritas + + + edismax + + text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 + title^10.0 description^5.0 keywords^5.0 author^2.0 resourcename^1.0 + + text + 100% + *:* + 10 + *,score + + + text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 + title^10.0 description^5.0 keywords^5.0 author^2.0 resourcename^1.0 + + text,features,name,sku,id,manu,cat,title,description,keywords,author,resourcename + 3 + + + on + cat + manu_exact + content_type + author_s + ipod + GB + 1 + cat,inStock + after + price + 0 + 600 + 50 + popularity + 0 + 10 + 3 + manufacturedate_dt + NOW/YEAR-10YEARS + NOW + +1YEAR + before + after + + + on + content features title name + html + <b> + </b> + 0 + title + 0 + name + 3 + 200 + content + 750 + + + on + false + 5 + 2 + 5 + true + true + 5 + 3 + + + + + spellcheck + + + + + + + + + + + + + + application/json + + + + + application/csv + + + + + + + + + + + + + + + + + + + + + solrpingquery + + + all + + + + + + + + + explicit + true + + + + + + + + + + + + + + + + text_general + + + + + + default + text + solr.DirectSolrSpellChecker + + internal + + 0.5 + + 2 + + 1 + + 5 + + 4 + + 0.01 + + + + + + wordbreak + solr.WordBreakSolrSpellChecker + name + true + true + 10 + + + + + + + + + + + + + + + + text + + default + wordbreak + on + true + 10 + 5 + 5 + true + true + 10 + 5 + + + spellcheck + + + + + + + + + + text + true + + + tvComponent + + + + + + + + + default + + + org.carrot2.clustering.lingo.LingoClusteringAlgorithm + + + 20 + + + clustering/carrot2 + + + ENGLISH + + + stc + org.carrot2.clustering.stc.STCClusteringAlgorithm + + + + + + + true + default + true + + name + id + + features + + true + + + + false + + edismax + + text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 + + *:* + 10 + *,score + + + clustering + + + + + + + + + + true + false + + + terms + + + + + + + + string + elevate.xml + + + + + + explicit + text + + + elevator + + + + + + + + + + + 100 + + + + + + + + 70 + + 0.5 + + [-\w ,/\n\"']{20,200} + + + + + + + ]]> + ]]> + + + + + + + + + + + + + + + + + + + + + + + + ,, + ,, + ,, + ,, + ,]]> + ]]> + + + + + + 10 + .,!? + + + + + + + WORD + + + en + US + + + + + + + + + + + + + + + + + + + + + + text/plain; charset=UTF-8 + + + + + + + + + 5 + + + + + + + + + + + + + + + + + + *:* + + + diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/NullHeader.docx b/solr/contrib/solr-mr/src/test-files/test-documents/NullHeader.docx new file mode 100644 index 0000000000000000000000000000000000000000..cc62b8d6bebaf06dc46dbce5d56089778d6f528f GIT binary patch literal 4355 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 literal 0 HcmV?d00001 diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/boilerplate.html b/solr/contrib/solr-mr/src/test-files/test-documents/boilerplate.html new file mode 100644 index 00000000000..0286578693c --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/test-documents/boilerplate.html @@ -0,0 +1,58 @@ + + + + + + + + Title + + + + + + + +
    + + + + + +
    boilerplatetext
    +
    + +

    This is the real meat of the page, +and represents the text we want. +It has lots of juicy content. + +We assume that it won't get filtered out. +And that all of the lines will be in the +output. +

    + +

    +Here's another paragraph of text. +This is the end of the text. +

    + +

    footer

    + + + diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/complex.mbox b/solr/contrib/solr-mr/src/test-files/test-documents/complex.mbox new file mode 100644 index 00000000000..27f7017d265 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/test-documents/complex.mbox @@ -0,0 +1,291 @@ +From core-user-return-14700-apmail-hadoop-core-user-archive=hadoop.apache.org@hadoop.apache.org Mon Jun 01 04:28:28 2009 +Return-Path: +Delivered-To: apmail-hadoop-core-user-archive@www.apache.org +Received: (qmail 19921 invoked from network); 1 Jun 2009 04:28:28 -0000 +Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) + by minotaur.apache.org with SMTP; 1 Jun 2009 04:28:28 -0000 +Received: (qmail 84995 invoked by uid 500); 1 Jun 2009 04:28:38 -0000 +Delivered-To: apmail-hadoop-core-user-archive@hadoop.apache.org +Received: (qmail 84895 invoked by uid 500); 1 Jun 2009 04:28:38 -0000 +Mailing-List: contact core-user-help@hadoop.apache.org; run by ezmlm +Precedence: bulk +List-Help: +List-Unsubscribe: +List-Post: +List-Id: +Reply-To: core-user@hadoop.apache.org +Delivered-To: mailing list core-user@hadoop.apache.org +Received: (qmail 84885 invoked by uid 99); 1 Jun 2009 04:28:38 -0000 +Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) + by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 01 Jun 2009 04:28:38 +0000 +X-ASF-Spam-Status: No, hits=1.2 required=10.0 + tests=SPF_NEUTRAL +X-Spam-Check-By: apache.org +Received-SPF: neutral (athena.apache.org: local policy) +Received: from [69.147.107.21] (HELO mrout2-b.corp.re1.wahoo.com) (69.147.107.21) + by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 01 Jun 2009 04:28:26 +0000 +Received: from SNV-EXPF01.ds.corp.wahoo.com (snv-expf01.ds.corp.wahoo.com [207.126.227.250]) + by mrout2-b.corp.re1.wahoo.com (8.13.8/8.13.8/y.out) with ESMTP id n514QYA6099963 + for ; Sun, 31 May 2009 21:26:35 -0700 (PDT) +DomainKey-Signature: a=rsa-sha1; s=serpent; d=wahoo-inc.com; c=nofws; q=dns; + h=received:user-agent:date:subject:from:to:message-id: + thread-topic:thread-index:in-reply-to:mime-version:content-type: + content-transfer-encoding:x-originalarrivaltime; + b=YVtSNdgjeeSBS1yY3XDolul49i+HrgNG7QszMo9LzGnrwejjgsl5+iUM6EiQgEpV +Received: from SNV-EXVS08.ds.corp.wahoo.com ([207.126.227.9]) by SNV-EXPF01.ds.corp.wahoo.com with Microsoft SMTPSVC(6.0.3790.3959); + Sun, 31 May 2009 21:26:34 -0700 +Received: from 10.66.92.213 ([10.66.92.213]) by SNV-EXVS08.ds.corp.wahoo.com ([207.126.227.58]) with Microsoft Exchange Server HTTP-DAV ; + Mon, 1 Jun 2009 04:26:33 +0000 +User-Agent: Microsoft-Entourage/12.17.0.090302 +Date: Mon, 01 Jun 2009 09:56:31 +0530 +Subject: Re: question about when shuffle/sort start working +From: Sam Judgement +To: +Message-ID: +Thread-Topic: question about when shuffle/sort start working +Thread-Index: AcnicSNoBw19cMU8UEaXwAdZ1YYhuw== +In-Reply-To: <440622.41041.qm@web111005.mail.gq1.wahoo.com> +Mime-version: 1.0 +Content-type: text/plain; + charset="US-ASCII" +Content-transfer-encoding: 7bit +X-OriginalArrivalTime: 01 Jun 2009 04:26:34.0501 (UTC) FILETIME=[257EAB50:01C9E271] +X-Virus-Checked: Checked by ClamAV on apache.org + +When a Mapper completes, MapCompletionEvents are generated. Reducers try to +fetch map outputs for a given map only on the receipt of such events. + +Sam + + +On 5/30/09 10:00 AM, "Jianmin Foo" wrote: + +> Hi, +> I am being confused by the protocol between mapper and reducer. When mapper +> emitting the (key,value) pair done, is there any signal the mapper send out to +> hadoop framework in protocol to indicate that map is done and the shuffle/sort +> can begin for reducer? If there is no this signal in protocol, when the +> framework begin the shuffle/sort? +> +> Thanks, +> Jianmin +> +> +> +> + + +From core-user-return-14701-apmail-hadoop-core-user-archive=hadoop.apache.org@hadoop.apache.org Mon Jun 01 05:31:14 2009 +Return-Path: +Delivered-To: apmail-hadoop-core-user-archive@www.apache.org +Received: (qmail 38243 invoked from network); 1 Jun 2009 05:31:14 -0000 +Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) + by minotaur.apache.org with SMTP; 1 Jun 2009 05:31:14 -0000 +Received: (qmail 15621 invoked by uid 500); 1 Jun 2009 05:31:24 -0000 +Delivered-To: apmail-hadoop-core-user-archive@hadoop.apache.org +Received: (qmail 15557 invoked by uid 500); 1 Jun 2009 05:31:24 -0000 +Mailing-List: contact core-user-help@hadoop.apache.org; run by ezmlm +Precedence: bulk +List-Help: +List-Unsubscribe: +List-Post: +List-Id: +Reply-To: core-user@hadoop.apache.org +Delivered-To: mailing list core-user@hadoop.apache.org +Received: (qmail 15547 invoked by uid 99); 1 Jun 2009 05:31:24 -0000 +Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) + by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 01 Jun 2009 05:31:24 +0000 +X-ASF-Spam-Status: No, hits=2.2 required=10.0 + tests=HTML_MESSAGE,SPF_PASS +X-Spam-Check-By: apache.org +Received-SPF: pass (nike.apache.org: local policy) +Received: from [68.142.237.94] (HELO n9.bullet.re3.wahoo.com) (68.142.237.94) + by apache.org (qpsmtpd/0.29) with SMTP; Mon, 01 Jun 2009 05:31:11 +0000 +Received: from [68.142.237.88] by n9.bullet.re3.wahoo.com with NNFMP; 01 Jun 2009 05:30:50 -0000 +Received: from [67.195.9.82] by t4.bullet.re3.wahoo.com with NNFMP; 01 Jun 2009 05:30:49 -0000 +Received: from [67.195.9.99] by t2.bullet.mail.gq1.wahoo.com with NNFMP; 01 Jun 2009 05:30:49 -0000 +Received: from [127.0.0.1] by omp103.mail.gq1.wahoo.com with NNFMP; 01 Jun 2009 05:28:01 -0000 +X-wahoo-Newman-Property: ymail-3 +X-wahoo-Newman-Id: 796121.97519.bm@omp103.mail.gq1.wahoo.com +Received: (qmail 35264 invoked by uid 60001); 1 Jun 2009 05:30:49 -0000 +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=wahoo.com; s=s1024; t=1243834249; bh=R8qzdi/IbLyO8UwpnaujDpT9E+6bJ7nkmZN2803EmRk=; h=Message-ID:X-YMail-OSG:Received:X-Mailer:References:Date:From:Subject:To:In-Reply-To:MIME-Version:Content-Type; b=vq4c6RIDbkuLPYd8mirusIXf6DqTb/IeT55In7W00Y5Sxx1ZiXBb78yE9+TDfXJ0elsEZvqv4ocyvolGE0eGtyYeJA0mZikpRNu6pidxPNpCplOcLHBRz7YQ7iERwv3TagRlWy2Xd3oD9ZeV0A05P7WUOiNNX1PUUJD1IVdrEZo= +DomainKey-Signature:a=rsa-sha1; q=dns; c=nofws; + s=s1024; d=wahoo.com; + h=Message-ID:X-YMail-OSG:Received:X-Mailer:References:Date:From:Subject:To:In-Reply-To:MIME-Version:Content-Type; + b=6HXZV98ON5vBwmE/xS8stVD0D2F4dkMY7a0suX5KVTb736JdR8G59mqBq/dWcpbFTLiCLtxi18LMb/dU1RKRGOEdn3l3j/jKXhBrhIgfg3qtNskPedXDKBvn7JGXiSkqpA/tUtPjvc0Uuk8/LaA01SQTz40Engg7nD8/EJdIAhA=; +Message-ID: <592088.35091.qm@web111010.mail.gq1.wahoo.com> +X-YMail-OSG: KzhhrJYVM1m.MCS6vRpRP2ZZO2PrfnbngosELDCIa91ZqvhJph4RdmzfUW0jw9W04RCSch1K730bPohwNpNBIk2QR_zt4_mfbhfq7YEPkSoz9LSXG90P9vIo5Fc8qyZN0U6vA9gtdyGQTpN5ahvillUH9nAF0TMWv2SvZJLjPlQ0Z0p8oK8ltBwGTgLrM8Jtdn9D29yoRyi3_EpVOfdD9OP.EK50Vr1XwSUYMbnpZ0WGHMwd.Yig7A6Elwadm3YVbfOdx2mfrG.jQsUAxQjRBNvbrOM57.FaE11kHTe9aoBWSeihNg-- +Received: from [216.145.54.7] by web111010.mail.gq1.wahoo.com via HTTP; Sun, 31 May 2009 22:30:49 PDT +X-Mailer: wahooMailRC/1277.43 wahooMailWebService/0.7.289.10 +References: +Date: Sun, 31 May 2009 22:30:49 -0700 (PDT) +From: Jianmin Foo +Subject: Re: question about when shuffle/sort start working +To: core-user@hadoop.apache.org +In-Reply-To: +MIME-Version: 1.0 +Content-Type: multipart/alternative; boundary="0-1193839393-1243834249=:35091" +X-Virus-Checked: Checked by ClamAV on apache.org + +--0-1193839393-1243834249=:35091 +Content-Type: text/plain; charset=us-ascii + +Thanks a lot for your explanation, Sam. + +So is this event generated by hadoop framework? Is there any API in mapper to fire this event? Actually, I am thinking to implement a mapper that will emit some pairs, then fire this event to let the reducer works, the same mapper task then emit some other pairs and repeat. Do you think is this logic feasible by current API? + +Thanks, +Jianmin + + + + + +________________________________ +From: Sam Judgement +To: core-user@hadoop.apache.org +Sent: Monday, June 1, 2009 12:26:31 PM +Subject: Re: question about when shuffle/sort start working + +When a Mapper completes, MapCompletionEvents are generated. Reducers try to +fetch map outputs for a given map only on the receipt of such events. + +Sam + + +On 5/30/09 10:00 AM, "Jianmin Foo" wrote: + +> Hi, +> I am being confused by the protocol between mapper and reducer. When mapper +> emitting the (key,value) pair done, is there any signal the mapper send out to +> hadoop framework in protocol to indicate that map is done and the shuffle/sort +> can begin for reducer? If there is no this signal in protocol, when the +> framework begin the shuffle/sort? +> +> Thanks, +> Jianmin +> +> +> +> + + + +--0-1193839393-1243834249=:35091-- + + +From core-user-return-14702-apmail-hadoop-core-user-archive=hadoop.apache.org@hadoop.apache.org Mon Jun 01 06:04:30 2009 +Return-Path: +Delivered-To: apmail-hadoop-core-user-archive@www.apache.org +Received: (qmail 53387 invoked from network); 1 Jun 2009 06:04:29 -0000 +Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) + by minotaur.apache.org with SMTP; 1 Jun 2009 06:04:29 -0000 +Received: (qmail 39066 invoked by uid 500); 1 Jun 2009 06:04:39 -0000 +Delivered-To: apmail-hadoop-core-user-archive@hadoop.apache.org +Received: (qmail 38970 invoked by uid 500); 1 Jun 2009 06:04:39 -0000 +Mailing-List: contact core-user-help@hadoop.apache.org; run by ezmlm +Precedence: bulk +List-Help: +List-Unsubscribe: +List-Post: +List-Id: +Reply-To: core-user@hadoop.apache.org +Delivered-To: mailing list core-user@hadoop.apache.org +Received: (qmail 38955 invoked by uid 99); 1 Jun 2009 06:04:39 -0000 +Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) + by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 01 Jun 2009 06:04:39 +0000 +X-ASF-Spam-Status: No, hits=1.2 required=10.0 + tests=SPF_NEUTRAL +X-Spam-Check-By: apache.org +Received-SPF: neutral (athena.apache.org: local policy) +Received: from [216.145.54.172] (HELO mrout2.wahoo.com) (216.145.54.172) + by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 01 Jun 2009 06:04:28 +0000 +Received: from SNV-EXBH01.ds.corp.wahoo.com (snv-exbh01.ds.corp.wahoo.com [207.126.227.249]) + by mrout2.wahoo.com (8.13.6/8.13.6/y.out) with ESMTP id n5163FGq038852 + for ; Sun, 31 May 2009 23:03:15 -0700 (PDT) +DomainKey-Signature: a=rsa-sha1; s=serpent; d=wahoo-inc.com; c=nofws; q=dns; + h=received:user-agent:date:subject:from:to:message-id: + thread-topic:thread-index:in-reply-to:mime-version:content-type: + content-transfer-encoding:x-originalarrivaltime; + b=rChE4SCnwtWaZpjhovkiXDKfDiVNdRRvsadSGG9S9bgvOexn/9/5JjEQx1pOR7Nb +Received: from SNV-EXVS08.ds.corp.wahoo.com ([207.126.227.9]) by SNV-EXBH01.ds.corp.wahoo.com with Microsoft SMTPSVC(6.0.3790.3959); + Sun, 31 May 2009 23:03:15 -0700 +Received: from 10.66.92.213 ([10.66.92.213]) by SNV-EXVS08.ds.corp.wahoo.com ([207.126.227.58]) with Microsoft Exchange Server HTTP-DAV ; + Mon, 1 Jun 2009 06:03:15 +0000 +User-Agent: Microsoft-Entourage/12.17.0.090302 +Date: Mon, 01 Jun 2009 11:33:13 +0530 +Subject: Re: question about when shuffle/sort start working +From: Sam Judgement +To: +Message-ID: +Thread-Topic: question about when shuffle/sort start working +Thread-Index: AcnifqWrLG6N7GAk7kqy9QalVWfegQ== +In-Reply-To: <592088.35091.qm@web111010.mail.gq1.wahoo.com> +Mime-version: 1.0 +Content-type: text/plain; + charset="US-ASCII" +Content-transfer-encoding: 7bit +X-OriginalArrivalTime: 01 Jun 2009 06:03:15.0462 (UTC) FILETIME=[A7231260:01C9E27E] +X-Virus-Checked: Checked by ClamAV on apache.org + + +No you cannot raise this event yourself, this event is generated internally +by the framework. + +I am guessing that what you probably want is to have a chain of MapReduce +Jobs where the output of one is automatically fed as input to another. You +can look at these classes: JobControl and ChainMapper/ChainReducer. + +Sam + +On 6/1/09 11:00 AM, "Jianmin Foo" wrote: + +> Thanks a lot for your explanation, Sam. +> +> So is this event generated by hadoop framework? Is there any API in mapper to +> fire this event? Actually, I am thinking to implement a mapper that will emit +> some pairs, then fire this event to let the reducer works, the +> same mapper task then emit some other pairs and repeat. Do you +> think is this logic feasible by current API? +> +> Thanks, +> Jianmin +> +> +> +> +> +> ________________________________ +> From: Sam Judgement +> To: core-user@hadoop.apache.org +> Sent: Monday, June 1, 2009 12:26:31 PM +> Subject: Re: question about when shuffle/sort start working +> +> When a Mapper completes, MapCompletionEvents are generated. Reducers try to +> fetch map outputs for a given map only on the receipt of such events. +> +> Sam +> +> +> On 5/30/09 10:00 AM, "Jianmin Foo" wrote: +> +>> Hi, +>> I am being confused by the protocol between mapper and reducer. When mapper +>> emitting the (key,value) pair done, is there any signal the mapper send out +>> to +>> hadoop framework in protocol to indicate that map is done and the +>> shuffle/sort +>> can begin for reducer? If there is no this signal in protocol, when the +>> framework begin the shuffle/sort? +>> +>> Thanks, +>> Jianmin +>> +>> +>> +>> +> +> +> + + diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/rsstest.rss b/solr/contrib/solr-mr/src/test-files/test-documents/rsstest.rss new file mode 100644 index 00000000000..758f6a18363 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/test-documents/rsstest.rss @@ -0,0 +1,36 @@ + + + + + TestChannel + http://test.channel.com/ + Sample RSS File for Junit test + en-us + + + Home Page of Chris Mattmann + http://www-scf.usc.edu/~mattmann/ + Chris Mattmann's home page + + + Awesome Open Source Search Engine + http://www.nutch.org/ + Yup, that's what it is + + + diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/sample-statuses-20120521-100919.avro b/solr/contrib/solr-mr/src/test-files/test-documents/sample-statuses-20120521-100919.avro new file mode 100644 index 0000000000000000000000000000000000000000..36f01a2d48c22f18a91026005bbb741651d43f8e GIT binary patch literal 3192 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 literal 0 HcmV?d00001 diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/sample-statuses-20120906-141433.avro b/solr/contrib/solr-mr/src/test-files/test-documents/sample-statuses-20120906-141433.avro new file mode 100644 index 0000000000000000000000000000000000000000..4dbf180dc1db685eeb37d339e837a04c382b1b8d GIT binary patch literal 1208 zcmb7CL2lGA6!lEIs>G%mv4BnF1!6I6`qF+ z2{ypB$#5SlR)qSg=Dx`MH^D6Y`ZyOLGmDe-^co}rVSa&iMyR*=tiL#|EEt*_0V=bU z>q@x=I>n-{R3#-oT;@p4nG;$y;PczPyc-!ASZ+kQ8p%55yvEhEe28K+HG#UT^Ii@B| znlP9qCYS`kA%ZX?096P=WD`vac#R~`dY+@y^)%XQH1!^)PtuQ5)NlwC^+)wCL4aZ~ zH4^-RfahdI2;1088PWuk2qoeqnIPMRAg6jN5WQr&ff#%!L@WlhG}|G>JQ$qaJF6{_ zha%u#VaL+*j*`P&64R~4mr)D%rzduKB`hlN>EBY z2`Gq^f>JD$B`5E2lh@tI_0>FF5~V1Tl=!FjCL&gTrWbfxi=y5X@?>EtN>auw!b_5s zR*F*i>dE#Yk+%JZS|SpUEhC@jB$8$X6c>C5sp?f@SqTc07%Lzlj+W;rmC7Wdf@5j- z&Z*@_teUdI6|T0Azwn|plqH;{wN!sf;@|MTQk*mXce}3E_Gycz?ws)-$k#QmzjD*7 zY_}fP`nzYhV(oH7LeVi9N;q3`$otXjDF}~icYIq$uj_l?ZWq7CX({+qu^w;9#r!>V zVGk3rkK>}PNV+mUNdK?E{e*tE&);;~-s+n!(GPnJ7E)5pf>M%Fx=TM2p2mfc)wyO0 zG!&QqLsf{mFLNAC#`l>O)QD{RoUD1jOTsvO-m?R6u~8slGkdKuGM)X45I6$9huDL!G>gK z5o5rJ*Q>9lMIm;s0PaR)IG)d{iz75Nb~rsQ(&oxZ8Ijz>?QTaVi25V7>MnlMc3q4ePX6rsWGVKB~zPG?u4(qEWrp=-I18nI&fS_X5op zU57UnCBq0=yy%G7WrUtlxycctJuXM6Ro#*GcxpswUCfByY?53`Qc)^P$d*P6qEaP1 Y4rpfN`6Xw=&0qXo$rRy2L(HQQ9N^IIrvLx| literal 0 HcmV?d00001 diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/sample-statuses-20120906-141433.gz b/solr/contrib/solr-mr/src/test-files/test-documents/sample-statuses-20120906-141433.gz new file mode 100644 index 0000000000000000000000000000000000000000..3e7a44cb5887dc7bd614fc37bfdc967430a73b55 GIT binary patch literal 907 zcmV;619bc!iwFQPiKS5h1JzYsZ`(E$eJ{}eK=5H`F)yZMJFx}yA$8m50_m`ac_3)% zN@hcmDoHi%iv0Io>Z@|>d~HSBF#%{&SL8kCo~siv#-2X;LOp!)G@(wEl>*|g06Z}o z=!9BmRy;Me#t=54QgaKH`pmuIwFAp#MiX5tH3S20l7@J9rpxm%!Az{Ta!lC~#>WYTt-wbHxu})rl{L9kz-1{4 z7!Jv;1f99QkWmyN@Gf#I(#yi)gA5-l6Ih?E**acfw#s1rkYU_=E0iJU%9{Yfac_lo zO85}pU2^0=k87Hs4xoir2W+D>CiEj%nadI0{uC!O*b2*Wp@zgD4}X|JZj>@t$jpZt zoaYY0d3}krw{lx!YL0^zTQxd810-Em9j35~=;57PEHW}Z+}ey$TthBLh4CO@7xWzF zR>_i`_$yf!jhLr4Khml5j)lBBY`5;htuY(@SVn z5#DnGnsc_+B8jPr1o+2VEOp?_D45cV&+dA$8GDpTu{Vk-suOg&CdpUKIWR%qUKx zc`}>-gk}`S@uSV?LTK^^9VnG9{TGJRCvxCOA(h8D(#!bOYQFrYjuhYTNXysj)7h(U z<4AEgx-RF(?WqeouqXB)dy0RwJ>7-zp(fQHam=Oag0OjTso5-vmk)5Mc{7f=RNoEX z(WP#CYoM*4JHAGyMb{{ED-?N$d*s>g7vvYR7FuNDIlaxy;>VcT>YTB~S!ZT(UxEK- hX7}Rl0e5)E-u7D@oicVk&gVXF`v;|Puj6M8003;iz{vmr literal 0 HcmV?d00001 diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/test-outlook.msg b/solr/contrib/solr-mr/src/test-files/test-documents/test-outlook.msg new file mode 100644 index 0000000000000000000000000000000000000000..c975c0c69d4199f1baf05afb5117e66076c993d2 GIT binary patch literal 19968 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 ZpZNbv?(H)zb9>XNkEZbN(*La*_zxA%J0So7 literal 0 HcmV?d00001 diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testAIFF.aif b/solr/contrib/solr-mr/src/test-files/test-documents/testAIFF.aif new file mode 100644 index 0000000000000000000000000000000000000000..97eac1d8e3d94c4ef139d3c8b5e2a3ca16a856fd GIT binary patch literal 3894 zcmZuzYlu}<6#n*^M#sU_EDe*Q98wf8yqwzSP{1%^+V z{$NYX%(hm_7>NR?+lmp*!#tQK)=V-+#vMh>p zRhtvA5`zJf=Ei*QwfKp5Kuw%&T*$J~cBX3aTAEC#7*K+qVf1DrY-M|^shk{?)K@ZGQgKndTdpa@TT;Kt!w}1C;Xj2okpi+r3(3Fv8dBH-{WA)Be{6V5oVrb-#Y(3%BT6uqf_8r`gtEh?Q-{K z!~gckHtIWRAJ4d(nfC)@*YJ5jM1JMkLti6(gDgHUg-mXu{cGyy>3fXwB&nLoBGq2% zPtbmb>viTdb3H)3?`a=RnM-CA^~6-DH^EfCB;I>GIU~46v(`nf z^~!_Kr?{?X_)@Ma{jE}|l52&%RJ)1sJA2%~XEX6Pv(8x7`-l2U=Ksm~`#AV^>i4kL zZWNV6C@#JN(?1oas6$bVfVn_^=Q+XZyX>b8=zo^{rgQBTsq`^_E@K;EE^Z_CbHHVj zU`}+P7}?3^S(w4(C(D4o)AY^a;w<`mn0GgfSqF2jnZ9wX!CFVAz#Q!Y8Xx9bAae9B z;4tUex1F^XGKZ`2C7}Ke6xHP@>PL~sHzKEQ7dh9-Bk&7(ya{vsQ{dPH-~{)q{}aZ~ zLvfZf>ESH#mdKDM&WH6IZiBgM3G-IK^!C6UCiah?iR@b^GG;k&bqCB2o}Vp?VNQ|z zu{}Wd3gU5YgZ2T(yHN~VkK&3mFkSmO_d_B#w2G`^{t}+g4|f7hYsrCi57vu}s)`I> z%|73NY1|?*nEStfyvVWTBE5V=SG^3Z-T`ynUoaD90-JXMAAbRC>J<5HHZb&7U@G@~ z2xo&wMaDI8A9-H(^8GmZh{(0`fqQ4bOzJ`L>WjcqVy>A3OyrC|T8v^TPyT4;OdBed zUe0FzMnHLvSp=NsIbF38hB3OVojxn8p0E1{0povy=~xD%FlwUrxJ z-PQ&dcj|qYH+d0?pI?joOMQ-g2k2T@?%8uHE;RG3x}IZBXP28nFTV}iXW+8_s}jED zrF_0S0Nlym74vVNC6^O&V~=)@>YFw%+5(0?wJ*E6w>u2Qo5Sx;z*9fvJT~NOUXbl` z%)f5N2med<53c0k8<|*- zv*zfT-{oc)F)pI|%AsZ`LcNTvn#Stg{YP+`ucrAPGkFI@WKnL4DLdhorHJdhwR{yP zTNzUogC|P9O4J>%fRH!@%O#&F+t;YcbN&JK!~ZY4lUZh!|1sRzveiO1x%>WWEU9Dq W2XLuntc5(k80&1&ZYu@Nviu({3A^_I literal 0 HcmV?d00001 diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testBMP.bmp b/solr/contrib/solr-mr/src/test-files/test-documents/testBMP.bmp new file mode 100644 index 0000000000000000000000000000000000000000..c0176157039b25d71e93232a93ab16989add80c1 GIT binary patch literal 22554 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 + +1795 +From: "Julien Nioche (JIRA)" +To: dev@tika.apache.org +Subject: [jira] Commented: (TIKA-461) RFC822 messages not parsed +Reply-To: dev@tika.apache.org +Delivered-To: mailing list dev@tika.apache.org +Date: Mon, 6 Sep 2010 05:25:34 -0400 (EDT) +In-Reply-To: <6089099.260231278600349994.JavaMail.jira@thor> +MIME-Version: 1.0 +Content-Type: text/plain; charset=utf-8 +Content-Transfer-Encoding: 7bit +X-JIRA-FingerPrint: 30527f35849b9dde25b450d4833f0394 +X-Virus-Checked: Checked by ClamAV on apache.org + + + [ https://issues.apache.org/jira/browse/TIKA-461?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12906468#action_12906468 ] + +Julien Nioche commented on TIKA-461: +------------------------------------ + +I'll have a look at mime4j and try to use it in Tika + +> RFC822 messages not parsed +> -------------------------- +> +> Key: TIKA-461 +> URL: https://issues.apache.org/jira/browse/TIKA-461 +> Project: Tika +> Issue Type: Bug +> Components: parser +> Affects Versions: 0.7 +> Reporter: Joshua Turner +> Assignee: Julien Nioche +> +> Presented with an RFC822 message exported from Thunderbird, AutodetectParser produces an empty body, and a Metadata containing only one key-value pair: "Content-Type=message/rfc822". Directly calling MboxParser likewise gives an empty body, but with two metadata pairs: "Content-Encoding=us-ascii Content-Type=application/mbox". +> A quick peek at the source of MboxParser shows that the implementation is pretty naive. If the wiring can be sorted out, something like Apache James' mime4j might be a better bet. + +-- +This message is automatically generated by JIRA. +- +You can reply to this email to add a comment to the issue online. + + + + + + flags + 0 + sender + "Julien Nioche (JIRA)" <jira@apache.org> + subject + [jira] Commented: (TIKA-461) RFC822 messages not parsed + to + dev@tika.apache.org + diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testEXCEL.xls b/solr/contrib/solr-mr/src/test-files/test-documents/testEXCEL.xls new file mode 100644 index 0000000000000000000000000000000000000000..86b291606d098e2c636dcc3b72500c5c237c7aa1 GIT binary patch literal 13824 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 V$GXVKswt|uUhpF8>iG1A{|35}>oEWT literal 0 HcmV?d00001 diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testEXCEL.xlsx b/solr/contrib/solr-mr/src/test-files/test-documents/testEXCEL.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..8d5169f84108cc4af5dd66e2c0957eb52e6622e6 GIT binary patch literal 9453 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 literal 0 HcmV?d00001 diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testFLAC.flac b/solr/contrib/solr-mr/src/test-files/test-documents/testFLAC.flac new file mode 100644 index 0000000000000000000000000000000000000000..ccec94717a47661d02153d1287cddbcf0b76db23 GIT binary patch literal 10604 zcmeI2{ZmwB6vv;tcU^FWc108zF;>F?CGbMN;RNi4pn@XGE);^u%OWTsvn-A#a_uWj4$KO_!I z+L(D2wJlw>##V={f)C3_=G86kF~!X8*#BVd#E9zX-99J7!w>otYqTjHn%cs;iEZD7 z{9a+o^irFREk34$PPdHeg_^R97d^as+&db|(x+C>JelAWxAUi5ufj%SpeAh1{_1XP znXcP(wZ^BXY{l`oit>x`rFq5!)&nN5r!k8b=#AISWfwgv_NAC&d`#-%_-1pN?qp%r zUQPY?6I(Tl<8=u}b#aX@VY1PG>MnD9#N?Js9gFWr6)cFoZ>=iVjMl^)hzTz;*Lt-s zR(GVw-uTk}xMr4D+Rm$5%?)dv*IkpT_(-KW;24hFU)c|egbM}IFu-%+2m(lcKOBkSKoT)t6K@34comX`;n2a2 z14+n32!0ie4m3FuBoe{Hi}76GQ}G`FcMgRotMKDII{y1%E?`8)@kfP7+?rrZ2KdiU znBo1fCLkwR@f-}`7C0yq0;I7LcNT@#B(HU(Nfpi;cE_nlt%W?V}4K=9*njYZijEh;J{ zu&G?xAem}Aa(%sxxHa*=f?~7K0d4)E{BB4d`_#ov^oZ%U#_U?>PO_``~s=Xn`!u zo+&(kD7@xY)cZ%O`YTJP#D4y5M(=V-O{eD_RqXaF9WIAfR9vZ>=IZY9)|{~$9d>k| zneMUl4d%eiqp6N{&S|qoZGFW-w zO};-wcOK z1uC(KFEOwNe6C1Rvg1OaVPJ4KR#5h=c;NyeQy z6_9>ycy2LpCmZ1#aUiywW{HH`odO5&!!1M;cPcndFv56<3XJ195*K!WRp#XW3oEhs A`Tzg` literal 0 HcmV?d00001 diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testFLV.flv b/solr/contrib/solr-mr/src/test-files/test-documents/testFLV.flv new file mode 100644 index 0000000000000000000000000000000000000000..d35e9bb6063f1ec353d27e0cea0e2c59de8bd3e0 GIT binary patch literal 90580 zcmZU)3p~^N{|Em0Y_knxYbVDl*@zO(w(d8vx#U)%3>CJDl!P4R685nv2d6{Ay0VmF zuIUtV8;2AXU3AigQ7fsK`&{>bJKx{q|M)*1|2^{PvCrkb&-?v;U7pY9>-E{O(*st6 zAV?kjL1YLfEc_2XC`cnDc$a_pLED4j2l3zl0mA#83Og8nEF>7R8Y#lBS@|srQj0j| z7k(6C`Lh=8fgtQr|6>71!y%UM|Gq<7r;qvhhxmapz^(oe>yNXK zk41x@W&Yn_*x$qb!~8>FFrEMI{{Q_L{>ZT)|Nq@Hv7Gh4yTH=Gx?l-j{NEs^s!^l~ zqF?BI3mw+aKno0*4XuHrYiJHwq+=-z(J&AVhvMy27w|sVtSYs*<8yDV*I&j6i-m_F zJcN+&kaQ)cq3U*Ge&_Hv(^}ueYhNyJGw}Q2jT3`^(KvC!FGAY)t(^nP8KlTn@5|-e z2cC3oTjlqo>Y|XJ5N`N>P zWc|Br#E)#%qYg!GUCq#8mYKB
  • L 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 Yw)D^pdlItgQttW9tIRk5@Bjb>3xH@d?f?J) literal 0 HcmV?d00001 diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testJPEG_EXIF.jpg b/solr/contrib/solr-mr/src/test-files/test-documents/testJPEG_EXIF.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1b93e771832ca9bb9bcaa5d1f8ec8767a55ccc3c GIT binary patch literal 16357 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 ZOOqc^2}(jhU@g%f|JgEmN)Y8g004!~w2%M* literal 0 HcmV?d00001 diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testJPEG_EXIF.jpg.tar.gz b/solr/contrib/solr-mr/src/test-files/test-documents/testJPEG_EXIF.jpg.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..3f35102eaefb0f9cdc648dace30c437b86ffa9de GIT binary patch literal 8722 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 literal 0 HcmV?d00001 diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testMP3i18n.mp3 b/solr/contrib/solr-mr/src/test-files/test-documents/testMP3i18n.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..0f253704ebb559780674b1d999a99e586de1a174 GIT binary patch literal 40832 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 VE7K;Ya97u^%vV=SyO3RG{~N;JA|U_( literal 0 HcmV?d00001 diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testPDF.pdf b/solr/contrib/solr-mr/src/test-files/test-documents/testPDF.pdf new file mode 100644 index 0000000000000000000000000000000000000000..1f1bcff6fe90df04656b43f98640d863a65f8660 GIT binary patch literal 34824 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 literal 0 HcmV?d00001 diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testPNG.png b/solr/contrib/solr-mr/src/test-files/test-documents/testPNG.png new file mode 100644 index 0000000000000000000000000000000000000000..afbcb5f738863e20949365a7ffc801cf89dbd5a6 GIT binary patch literal 17041 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 d%|-5P_X$ch&5EKw;X^>V@5T)zR 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%0Dl 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 z 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 literal 0 HcmV?d00001 diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testPPT_various.pptx b/solr/contrib/solr-mr/src/test-files/test-documents/testPPT_various.pptx new file mode 100644 index 0000000000000000000000000000000000000000..92c2744dc4ec866214d9e00a0a597ee246a21be6 GIT binary patch literal 56659 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 Mz~hQT=f=DL0rCAhZ2$lO literal 0 HcmV?d00001 diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testPSD.psd b/solr/contrib/solr-mr/src/test-files/test-documents/testPSD.psd new file mode 100644 index 0000000000000000000000000000000000000000..7cedbc21a7a8fc3ed3813ade1c6f302545148275 GIT binary patch literal 69410 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

    k+pUF9jIMcN#_3o^mGdlKI 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 literal 0 HcmV?d00001 diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testRTFVarious.rtf b/solr/contrib/solr-mr/src/test-files/test-documents/testRTFVarious.rtf new file mode 100644 index 00000000000..57fadb99988 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/test-documents/testRTFVarious.rtf @@ -0,0 +1,329 @@ +{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff31507\deff0\stshfdbch31506\stshfloch31506\stshfhich31506\stshfbi31507\deflang1033\deflangfe1033\themelang1033\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f1\fbidi \fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Arial;} +{\f2\fbidi \fmodern\fcharset0\fprq1{\*\panose 02070309020205020404}Courier New;}{\f3\fbidi \froman\fcharset2\fprq2{\*\panose 05050102010706020507}Symbol;}{\f10\fbidi \fnil\fcharset2\fprq2{\*\panose 05000000000000000000}Wingdings;} +{\f11\fbidi \fmodern\fcharset128\fprq1{\*\panose 02020609040205080304}MS Mincho{\*\falt \'82\'6c\'82\'72 \'96\'be\'92\'a9};}{\f15\fbidi \fmodern\fcharset128\fprq1{\*\panose 020b0609070205080204}MS Gothic{\*\falt MS Mincho};} +{\f34\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria Math;}{\f37\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\f38\fbidi \fswiss\fcharset0\fprq2{\*\panose 020b0604030504040204}Tahoma;} +{\f175\fbidi \fmodern\fcharset128\fprq1{\*\panose 02020609040205080304}@MS Mincho;}{\f209\fbidi \fmodern\fcharset128\fprq1{\*\panose 00000000000000000000}@MS Gothic;} +{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fdbmajor\f31501\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} +{\fhimajor\f31502\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria;}{\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} +{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fdbminor\f31505\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} +{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f210\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} +{\f211\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\f213\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f214\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f215\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} +{\f216\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f217\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f218\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f220\fbidi \fswiss\fcharset238\fprq2 Arial CE;} +{\f221\fbidi \fswiss\fcharset204\fprq2 Arial Cyr;}{\f223\fbidi \fswiss\fcharset161\fprq2 Arial Greek;}{\f224\fbidi \fswiss\fcharset162\fprq2 Arial Tur;}{\f225\fbidi \fswiss\fcharset177\fprq2 Arial (Hebrew);} +{\f226\fbidi \fswiss\fcharset178\fprq2 Arial (Arabic);}{\f227\fbidi \fswiss\fcharset186\fprq2 Arial Baltic;}{\f228\fbidi \fswiss\fcharset163\fprq2 Arial (Vietnamese);}{\f230\fbidi \fmodern\fcharset238\fprq1 Courier New CE;} +{\f231\fbidi \fmodern\fcharset204\fprq1 Courier New Cyr;}{\f233\fbidi \fmodern\fcharset161\fprq1 Courier New Greek;}{\f234\fbidi \fmodern\fcharset162\fprq1 Courier New Tur;}{\f235\fbidi \fmodern\fcharset177\fprq1 Courier New (Hebrew);} +{\f236\fbidi \fmodern\fcharset178\fprq1 Courier New (Arabic);}{\f237\fbidi \fmodern\fcharset186\fprq1 Courier New Baltic;}{\f238\fbidi \fmodern\fcharset163\fprq1 Courier New (Vietnamese);} +{\f322\fbidi \fmodern\fcharset0\fprq1 MS Mincho Western{\*\falt \'82\'6c\'82\'72 \'96\'be\'92\'a9};}{\f320\fbidi \fmodern\fcharset238\fprq1 MS Mincho CE{\*\falt \'82\'6c\'82\'72 \'96\'be\'92\'a9};} +{\f321\fbidi \fmodern\fcharset204\fprq1 MS Mincho Cyr{\*\falt \'82\'6c\'82\'72 \'96\'be\'92\'a9};}{\f323\fbidi \fmodern\fcharset161\fprq1 MS Mincho Greek{\*\falt \'82\'6c\'82\'72 \'96\'be\'92\'a9};} +{\f324\fbidi \fmodern\fcharset162\fprq1 MS Mincho Tur{\*\falt \'82\'6c\'82\'72 \'96\'be\'92\'a9};}{\f327\fbidi \fmodern\fcharset186\fprq1 MS Mincho Baltic{\*\falt \'82\'6c\'82\'72 \'96\'be\'92\'a9};}{\f550\fbidi \froman\fcharset238\fprq2 Cambria Math CE;} +{\f551\fbidi \froman\fcharset204\fprq2 Cambria Math Cyr;}{\f553\fbidi \froman\fcharset161\fprq2 Cambria Math Greek;}{\f554\fbidi \froman\fcharset162\fprq2 Cambria Math Tur;}{\f557\fbidi \froman\fcharset186\fprq2 Cambria Math Baltic;} +{\f580\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\f581\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\f583\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\f584\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;} +{\f587\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\f590\fbidi \fswiss\fcharset238\fprq2 Tahoma CE;}{\f591\fbidi \fswiss\fcharset204\fprq2 Tahoma Cyr;}{\f593\fbidi \fswiss\fcharset161\fprq2 Tahoma Greek;} +{\f594\fbidi \fswiss\fcharset162\fprq2 Tahoma Tur;}{\f595\fbidi \fswiss\fcharset177\fprq2 Tahoma (Hebrew);}{\f596\fbidi \fswiss\fcharset178\fprq2 Tahoma (Arabic);}{\f597\fbidi \fswiss\fcharset186\fprq2 Tahoma Baltic;} +{\f598\fbidi \fswiss\fcharset163\fprq2 Tahoma (Vietnamese);}{\f599\fbidi \fswiss\fcharset222\fprq2 Tahoma (Thai);}{\f1962\fbidi \fmodern\fcharset0\fprq1 @MS Mincho Western;}{\f1960\fbidi \fmodern\fcharset238\fprq1 @MS Mincho CE;} +{\f1961\fbidi \fmodern\fcharset204\fprq1 @MS Mincho Cyr;}{\f1963\fbidi \fmodern\fcharset161\fprq1 @MS Mincho Greek;}{\f1964\fbidi \fmodern\fcharset162\fprq1 @MS Mincho Tur;}{\f1967\fbidi \fmodern\fcharset186\fprq1 @MS Mincho Baltic;} +{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} +{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} +{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} +{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} +{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} +{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhimajor\f31528\fbidi \froman\fcharset238\fprq2 Cambria CE;}{\fhimajor\f31529\fbidi \froman\fcharset204\fprq2 Cambria Cyr;} +{\fhimajor\f31531\fbidi \froman\fcharset161\fprq2 Cambria Greek;}{\fhimajor\f31532\fbidi \froman\fcharset162\fprq2 Cambria Tur;}{\fhimajor\f31535\fbidi \froman\fcharset186\fprq2 Cambria Baltic;} +{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} +{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} +{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} +{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} +{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} +{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} +{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} +{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} +{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;} +{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} +{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} +{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}} +{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0; +\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;\chyperlink\ctint255\cshade255\red0\green0\blue255;\caccentone\ctint255\cshade255\red79\green129\blue189;}{\*\defchp \f31506\fs22 } +{\*\defpap \ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 +\rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext0 \sqformat \spriority0 \styrsid16456967 Normal;}{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\* +\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\tblind0\tblindtype3\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa200\sl276\slmult1 +\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext11 \ssemihidden \sunhideused \sqformat Normal Table;}{ +\s15\ql \li0\ri0\widctlpar\tqc\tx4680\tqr\tx9360\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 +\sbasedon0 \snext15 \slink16 \sunhideused \styrsid4535536 header;}{\*\cs16 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \sbasedon10 \slink15 \slocked \styrsid4535536 Header Char;}{\s17\ql \li0\ri0\widctlpar +\tqc\tx4680\tqr\tx9360\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 +\sbasedon0 \snext17 \slink18 \sunhideused \styrsid4535536 footer;}{\*\cs18 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \sbasedon10 \slink17 \slocked \styrsid4535536 Footer Char;}{ +\s19\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af38\afs16\alang1025 \ltrch\fcs0 \f38\fs16\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 +\sbasedon0 \snext19 \slink20 \ssemihidden \sunhideused \styrsid4535536 Balloon Text;}{\*\cs20 \additive \rtlch\fcs1 \af38\afs16 \ltrch\fcs0 \f38\fs16 \sbasedon10 \slink19 \slocked \ssemihidden \styrsid4535536 Balloon Text Char;}{\*\cs21 \additive +\rtlch\fcs1 \af0 \ltrch\fcs0 \ul\cf17 \sbasedon10 \sunhideused \styrsid4535536 Hyperlink;}{\*\cs22 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \cf15 \sbasedon10 \ssemihidden \styrsid4535536 Placeholder Text;}{ +\s23\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs20\alang1025 \ltrch\fcs0 \f31506\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 +\sbasedon0 \snext23 \slink24 \ssemihidden \sunhideused \styrsid10829135 footnote text;}{\*\cs24 \additive \rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \fs20 \sbasedon10 \slink23 \slocked \ssemihidden \styrsid10829135 Footnote Text Char;}{\*\cs25 \additive +\rtlch\fcs1 \af0 \ltrch\fcs0 \super \sbasedon10 \ssemihidden \sunhideused \styrsid10829135 footnote reference;}{\*\ts26\tsrowd\trbrdrt\brdrs\brdrw10 \trbrdrl\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trbrdrr\brdrs\brdrw10 \trbrdrh\brdrs\brdrw10 \trbrdrv +\brdrs\brdrw10 \trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\tblind0\tblindtype3\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv +\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon11 \snext26 \spriority59 \styrsid8288896 +Table Grid;}{\s27\ql \li720\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0\contextualspace \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 +\sbasedon0 \snext27 \sqformat \spriority34 \styrsid10055055 List Paragraph;}{\s28\ql \li0\ri0\sa200\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \ab\af31507\afs18\alang1025 \ltrch\fcs0 +\b\f31506\fs18\cf18\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \sunhideused \sqformat \spriority35 \styrsid11105546 caption;}}{\*\listtable{\list\listtemplateid1249008552\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0 +\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\leveltemplateid67698689\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0\hres0\chhres0 \fi-360\li720\lin720 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0 +\levelstartat1\lvltentative\levelspace360\levelindent0{\leveltext\leveltemplateid67698691\'01o;}{\levelnumbers;}\f2\fbias0\hres0\chhres0 \fi-360\li1440\lin1440 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative +\levelspace360\levelindent0{\leveltext\leveltemplateid67698693\'01\u-3929 ?;}{\levelnumbers;}\f10\fbias0\hres0\chhres0 \fi-360\li2160\lin2160 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360 +\levelindent0{\leveltext\leveltemplateid67698689\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0\hres0\chhres0 \fi-360\li2880\lin2880 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360\levelindent0 +{\leveltext\leveltemplateid67698691\'01o;}{\levelnumbers;}\f2\fbias0\hres0\chhres0 \fi-360\li3600\lin3600 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360\levelindent0{\leveltext +\leveltemplateid67698693\'01\u-3929 ?;}{\levelnumbers;}\f10\fbias0\hres0\chhres0 \fi-360\li4320\lin4320 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360\levelindent0{\leveltext +\leveltemplateid67698689\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0\hres0\chhres0 \fi-360\li5040\lin5040 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360\levelindent0{\leveltext +\leveltemplateid67698691\'01o;}{\levelnumbers;}\f2\fbias0\hres0\chhres0 \fi-360\li5760\lin5760 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360\levelindent0{\leveltext\leveltemplateid67698693 +\'01\u-3929 ?;}{\levelnumbers;}\f10\fbias0\hres0\chhres0 \fi-360\li6480\lin6480 }{\listname ;}\listid73432867}{\list\listtemplateid1071396652\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360 +\levelindent0{\leveltext\leveltemplateid67698689\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0\hres0\chhres0 \fi-360\li720\lin720 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360\levelindent0 +{\leveltext\leveltemplateid67698691\'01o;}{\levelnumbers;}\f2\fbias0\hres0\chhres0 \fi-360\li1440\lin1440 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360\levelindent0{\leveltext +\leveltemplateid67698693\'01\u-3929 ?;}{\levelnumbers;}\f10\fbias0\hres0\chhres0 \fi-360\li2160\lin2160 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360\levelindent0{\leveltext +\leveltemplateid67698689\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0\hres0\chhres0 \fi-360\li2880\lin2880 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360\levelindent0{\leveltext +\leveltemplateid67698691\'01o;}{\levelnumbers;}\f2\fbias0\hres0\chhres0 \fi-360\li3600\lin3600 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360\levelindent0{\leveltext\leveltemplateid67698693 +\'01\u-3929 ?;}{\levelnumbers;}\f10\fbias0\hres0\chhres0 \fi-360\li4320\lin4320 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360\levelindent0{\leveltext\leveltemplateid67698689 +\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0\hres0\chhres0 \fi-360\li5040\lin5040 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360\levelindent0{\leveltext\leveltemplateid67698691 +\'01o;}{\levelnumbers;}\f2\fbias0\hres0\chhres0 \fi-360\li5760\lin5760 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360\levelindent0{\leveltext\leveltemplateid67698693 +\'01\u-3929 ?;}{\levelnumbers;}\f10\fbias0\hres0\chhres0 \fi-360\li6480\lin6480 }{\listname ;}\listid169494399}{\list\listtemplateid-487930464\listhybrid{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360 +\levelindent0{\leveltext\leveltemplateid67698705\'02\'00);}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li720\lin720 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360 +\levelindent0{\leveltext\leveltemplateid67698713\'02\'01.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li1440\lin1440 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace360 +\levelindent0{\leveltext\leveltemplateid67698715\'02\'02.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-180\li2160\lin2160 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360 +\levelindent0{\leveltext\leveltemplateid67698703\'02\'03.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li2880\lin2880 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360 +\levelindent0{\leveltext\leveltemplateid67698713\'02\'04.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li3600\lin3600 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace360 +\levelindent0{\leveltext\leveltemplateid67698715\'02\'05.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-180\li4320\lin4320 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360 +\levelindent0{\leveltext\leveltemplateid67698703\'02\'06.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li5040\lin5040 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360 +\levelindent0{\leveltext\leveltemplateid67698713\'02\'07.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li5760\lin5760 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace360 +\levelindent0{\leveltext\leveltemplateid67698715\'02\'08.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-180\li6480\lin6480 }{\listname ;}\listid1132862691}}{\*\listoverridetable{\listoverride\listid169494399\listoverridecount0\ls1} +{\listoverride\listid73432867\listoverridecount0\ls2}{\listoverride\listid1132862691\listoverridecount0\ls3}}{\*\rsidtbl \rsid724479\rsid2255182\rsid2767955\rsid4260063\rsid4535536\rsid5051464\rsid5706211\rsid5843828\rsid7218132\rsid8152053\rsid8288896 +\rsid9897893\rsid9969477\rsid10055055\rsid10249050\rsid10829135\rsid11105546\rsid12662658\rsid12941695\rsid13331334\rsid14163426\rsid14225018\rsid14292078\rsid14556934\rsid16456967\rsid16539678}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0 +\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info{\subject Subject is here}{\author Michael McCandless}{\keywords Keyword1 Keyword2}{\operator Michael McCandless}{\creatim\yr2011\mo8\dy29\hr5\min20} +{\revtim\yr2011\mo8\dy30\hr6\min13}{\version30}{\edmins445}{\nofpages2}{\nofwords95}{\nofchars546}{\nofcharsws640}{\vern32771}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}} +\paperw12240\paperh15840\margl1440\margr1440\margt1440\margb1440\gutter0\ltrsect +\widowctrl\ftnbj\aenddoc\trackmoves1\trackformatting1\donotembedsysfont1\relyonvml0\donotembedlingdata0\grfdocevents0\validatexml1\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors1\noxlattoyen +\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\formshade\horzdoc\dgmargin\dghspace180\dgvspace180\dghorigin1440\dgvorigin1440\dghshow1\dgvshow1 +\jexpand\viewkind1\viewscale150\pgbrdrhead\pgbrdrfoot\splytwnine\ftnlytwnine\htmautsp\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\snaptogridincell\allowfieldendsel\wrppunct +\asianbrkrule\rsidroot4535536\newtblstyruls\nogrowautofit\usenormstyforlist\noindnmbrts\felnbrelev\nocxsptable\indrlsweleven\noafcnsttbl\afelev\utinl\hwelev\spltpgpar\notcvasp\notbrkcnstfrctbl\notvatxbx\krnprsnet\cachedcolbal \nouicompat \fet0 +{\*\wgrffmtfilter 2450}\nofeaturethrottle1\ilfomacatclnup0{\*\ftnsep \ltrpar \pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid4535536 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 +\f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid4535536 \chftnsep +\par }}{\*\ftnsepc \ltrpar \pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid4535536 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 +{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid4535536 \chftnsepc +\par }}{\*\aftnsep \ltrpar \pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid4535536 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 +{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid4535536 \chftnsep +\par }}{\*\aftnsepc \ltrpar \pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid4535536 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 +\f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid4535536 \chftnsepc +\par }}\ltrpar \sectd \ltrsect\linex0\endnhere\sectlinegrid360\sectdefaultcl\sectrsid16456967\sftnbj {\headerr \ltrpar \pard\plain \ltrpar\s15\ql \li0\ri0\widctlpar\tqc\tx4680\tqr\tx9360\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 +\rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid4535536 This is the header text}{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid12662658 .}{\rtlch\fcs1 +\af31507 \ltrch\fcs0 \insrsid4535536 +\par +\par }}{\footerr \ltrpar \pard\plain \ltrpar\s17\ql \li0\ri0\widctlpar\tqc\tx4680\tqr\tx9360\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 +\f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid4535536 This is the footer text. +\par +\par }}{\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}} +{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8 +\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\ql \li0\ri0\sa200\sl276\slmult1 +\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af31507 \ltrch\fcs0 +\lang1024\langfe1024\noproof\langfenp1028\insrsid4535536 {\shp{\*\shpinst\shpleft4866\shptop1990\shpright8593\shpbottom2658\shpfhdr0\shpbxcolumn\shpbxignore\shpbypara\shpbyignore\shpwr3\shpwrk0\shpfblwtxt0\shpz0\shplid1026 +{\sp{\sn shapeType}{\sv 202}}{\sp{\sn fFlipH}{\sv 0}}{\sp{\sn fFlipV}{\sv 0}}{\sp{\sn lTxid}{\sv 65536}}{\sp{\sn hspNext}{\sv 1026}}{\sp{\sn fFitShapeToText}{\sv 1}}{\sp{\sn dhgt}{\sv 251660288}}{\sp{\sn pctHoriz}{\sv 400}}{\sp{\sn pctVert}{\sv 200}} +{\sp{\sn sizerelh}{\sv 0}}{\sp{\sn sizerelv}{\sv 0}}{\sp{\sn fLayoutInCell}{\sv 1}}{\shptxt \ltrpar \pard\plain \ltrpar\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 +\af31507\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid4535536 Here is a text box +\par }}}{\shprslt{\*\do\dobxcolumn\dobypara\dodhgt8192\dptxbx\dptxlrtb{\dptxbxtext\ltrpar \pard\plain \ltrpar\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 +\ltrch\fcs0 \f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid4535536 Here is a text box +\par }}\dpx4866\dpy1990\dpxsize3727\dpysize668\dpfillfgcr255\dpfillfgcg255\dpfillfgcb255\dpfillbgcr255\dpfillbgcg255\dpfillbgcb255\dpfillpat1\dplinew15\dplinecor0\dplinecog0\dplinecob0}}}}{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid4535536 Footnote appears here} +{\rtlch\fcs1 \af31507 \ltrch\fcs0 \cs25\super\insrsid10829135 \chftn {\footnote \ltrpar \pard\plain \ltrpar\s23\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs20\alang1025 \ltrch\fcs0 +\f31506\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \cs25\super\insrsid10829135 \chftn }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid10829135 This is a footnote.}}}{\rtlch\fcs1 \af31507 \ltrch\fcs0 +\insrsid14292078 +\par }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid14556934 +\par }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \b\insrsid14556934\charrsid14556934 Bold}{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid14556934 }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \i\insrsid14556934\charrsid14556934 italic}{\rtlch\fcs1 \af31507 \ltrch\fcs0 +\insrsid14556934 }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \ul\insrsid14556934\charrsid14556934 underline}{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid14556934 }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \super\insrsid14556934\charrsid14556934 superscript}{\rtlch\fcs1 +\af31507 \ltrch\fcs0 \insrsid14556934 }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \sub\insrsid14556934\charrsid14556934 subscript}{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid14556934 +\par }\pard \ltrpar\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10055055 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid14292078 +\par }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid10055055 Here is a list: +\par {\listtext\pard\plain\ltrpar \s27 \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \f3\fs22\insrsid10055055 \loch\af3\dbch\af31506\hich\f3 \'b7\tab}}\pard\plain \ltrpar\s27\ql \fi-360\li720\ri0\sa200\sl276\slmult1 +\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls2\adjustright\rin0\lin720\itap0\pararsid10055055\contextualspace \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af31507 +\ltrch\fcs0 \insrsid10055055 Bullet 1 +\par {\listtext\pard\plain\ltrpar \s27 \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \f3\fs22\insrsid10055055 \loch\af3\dbch\af31506\hich\f3 \'b7\tab}Bullet 2 +\par {\listtext\pard\plain\ltrpar \s27 \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \f3\fs22\insrsid10055055 \loch\af3\dbch\af31506\hich\f3 \'b7\tab}Bullet 3 +\par }\pard\plain \ltrpar\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10055055 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 +{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid10055055 Here is a numbered list: +\par {\listtext\pard\plain\ltrpar \s27 \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \f31506\fs22\insrsid10055055 \hich\af31506\dbch\af31506\loch\f31506 1)\tab}}\pard\plain \ltrpar\s27\ql \fi-360\li720\ri0\sa200\sl276\slmult1 +\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls3\adjustright\rin0\lin720\itap0\pararsid10055055\contextualspace \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af31507 +\ltrch\fcs0 \insrsid10055055 Number bullet 1 +\par {\listtext\pard\plain\ltrpar \s27 \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \f31506\fs22\insrsid10055055 \hich\af31506\dbch\af31506\loch\f31506 2)\tab}Number bullet 2 +\par {\listtext\pard\plain\ltrpar \s27 \rtlch\fcs1 \af31507\afs22 \ltrch\fcs0 \f31506\fs22\insrsid10055055 \hich\af31506\dbch\af31506\loch\f31506 3)\tab}Number bullet 3 +\par }\pard\plain \ltrpar\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 +\af31507 \ltrch\fcs0 \insrsid10829135 +\par }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid4535536\charrsid4535536 }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid4535536 }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid4535536 Keyword1 Keyword2}{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid4535536 }{\rtlch\fcs1 +\af31507 \ltrch\fcs0 \insrsid15481255 +\par }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid4535536 +\par }{\field{\*\fldinst {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid4535536 HYPERLINK "http://tika.apache.org" }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid4535536 {\*\datafield +00d0c9ea79f9bace118c8200aa004ba90b0200000003000000e0c9ea79f9bace118c8200aa004ba90b4800000068007400740070003a002f002f00740069006b0061002e006100700061006300680065002e006f00720067002f000000795881f43b1d7f48af2c825dc485276300000000a5ab0000}}}{\fldrslt { +\rtlch\fcs1 \af31507 \ltrch\fcs0 \cs21\ul\cf17\insrsid4535536\charrsid4535536 This is a hyperlink}}}\sectd \ltrsect\linex0\endnhere\sectlinegrid360\sectdefaultcl\sectrsid16456967\sftnbj {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid14292078 +\par +\par }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid4535536\charrsid4535536 }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid14292078 }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid14292078 Subject is here}{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid14292078 }{\rtlch\fcs1 +\af31507 \ltrch\fcs0 \insrsid4535536 +\par }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid8288896 +\par \ltrrow}\trowd \irow0\irowband0\ltrrow\ts26\trgaph108\trleft-108\trbrdrt\brdrs\brdrw10 \trbrdrl\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trbrdrr\brdrs\brdrw10 \trbrdrh\brdrs\brdrw10 \trbrdrv\brdrs\brdrw10 +\trftsWidth1\trftsWidthB3\trautofit1\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\tblrsid8288896\tbllkhdrrows\tbllkhdrcols\tbllknocolband\tblind0\tblindtype3 \clvertalt\clbrdrt\brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 +\clbrdrr\brdrs\brdrw10 \cltxlrtb\clftsWidth3\clwWidth3192\clshdrawnil \cellx3084\clvertalt\clbrdrt\brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 \clbrdrr\brdrs\brdrw10 \cltxlrtb\clftsWidth3\clwWidth3192\clshdrawnil \cellx6276\clvertalt +\clbrdrt\brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 \clbrdrr\brdrs\brdrw10 \cltxlrtb\clftsWidth3\clwWidth3192\clshdrawnil \cellx9468\pard\plain \ltrpar +\ql \li0\ri0\widctlpar\intbl\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\yts26 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid8288896 +Row 1 Col 1\cell Row 1 Col 2\cell Row 1 Col 3\cell }\pard\plain \ltrpar\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\intbl\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 +\f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid8288896 \trowd \irow0\irowband0\ltrrow\ts26\trgaph108\trleft-108\trbrdrt\brdrs\brdrw10 \trbrdrl\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trbrdrr +\brdrs\brdrw10 \trbrdrh\brdrs\brdrw10 \trbrdrv\brdrs\brdrw10 \trftsWidth1\trftsWidthB3\trautofit1\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\tblrsid8288896\tbllkhdrrows\tbllkhdrcols\tbllknocolband\tblind0\tblindtype3 \clvertalt\clbrdrt +\brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 \clbrdrr\brdrs\brdrw10 \cltxlrtb\clftsWidth3\clwWidth3192\clshdrawnil \cellx3084\clvertalt\clbrdrt\brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 \clbrdrr\brdrs\brdrw10 +\cltxlrtb\clftsWidth3\clwWidth3192\clshdrawnil \cellx6276\clvertalt\clbrdrt\brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 \clbrdrr\brdrs\brdrw10 \cltxlrtb\clftsWidth3\clwWidth3192\clshdrawnil \cellx9468\row \ltrrow}\pard\plain \ltrpar +\ql \li0\ri0\widctlpar\intbl\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\yts26 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid8288896 +Row 2 Col 1\cell Row 2 Col 2\cell Row 2 Col 3\cell }\pard\plain \ltrpar\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\intbl\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 +\f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid8288896 \trowd \irow1\irowband1\lastrow \ltrrow\ts26\trgaph108\trleft-108\trbrdrt\brdrs\brdrw10 \trbrdrl\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trbrdrr +\brdrs\brdrw10 \trbrdrh\brdrs\brdrw10 \trbrdrv\brdrs\brdrw10 \trftsWidth1\trftsWidthB3\trautofit1\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\tblrsid8288896\tbllkhdrrows\tbllkhdrcols\tbllknocolband\tblind0\tblindtype3 \clvertalt\clbrdrt +\brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 \clbrdrr\brdrs\brdrw10 \cltxlrtb\clftsWidth3\clwWidth3192\clshdrawnil \cellx3084\clvertalt\clbrdrt\brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 \clbrdrr\brdrs\brdrw10 +\cltxlrtb\clftsWidth3\clwWidth3192\clshdrawnil \cellx6276\clvertalt\clbrdrt\brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 \clbrdrr\brdrs\brdrw10 \cltxlrtb\clftsWidth3\clwWidth3192\clshdrawnil \cellx9468\row }\pard \ltrpar +\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid8288896 +\par }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid724479 Suddenly some }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid5706211 J}{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid724479 apanese text:}{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid9969477 +\par }{\rtlch\fcs1 \af11 \ltrch\fcs0 \loch\af11\hich\af11\dbch\af11\insrsid724479\charrsid724479 \loch\af11\hich\af11\dbch\f11 \uc2\u12478\'83\'5d\u12523\'83\'8b\u12466\'83\'51\u12392\'82\'c6\u23614\'94\'f6\u23822\'8d\'e8\u12289\'81\'41\u28129\'92\'57\u12293 +\'81\'58\u12392\'82\'c6\u26368\'8d\'c5\u26399\'8a\'fa}{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid9969477 +\par }{\rtlch\fcs1 \af15 \ltrch\fcs0 \lang1033\langfe1041\loch\af15\hich\af15\dbch\af15\langfenp1041\insrsid5843828 \loch\af15\hich\af15\dbch\f15 \uc2\u-248\'81\'69\u-217\'82\'66\u-216\'82\'67\u-207\'82\'70\u-247\'81\'6a}{\rtlch\fcs1 \af31507 \ltrch\fcs0 +\insrsid9969477 +\par }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid5706211 And then some Gothic text: +\par }\pard \ltrpar\ql \li0\ri0\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0\pararsid14163426 {\rtlch\fcs1 \af1\afs20 \ltrch\fcs0 \f1\fs20\insrsid14163426 \u-10240\'3f\u-8398\'3f\u-10240\'3f\u-8385\'3f\u-10240\'3f\u-8380\'3f\u-10240\'3f\u-8391\'3f\u-10240 +\'3f\u-8381\'3f\u-10240\'3f\u-8390\'3f}{\rtlch\fcs1 \af1\afs20 \ltrch\fcs0 \f1\fs20\insrsid14163426 +\par }\pard \ltrpar\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid9969477 +\par }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid7218132 Here is a citation:}{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid9969477 +\par }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid12941695 }{\field{\*\fldinst {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid12941695 CITATION Kra \\l 1033 }}{\fldrslt {\rtlch\fcs1 \af31507 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid12941695 (Kramer)}}} +\sectd \ltrsect\linex0\endnhere\sectlinegrid360\sectdefaultcl\sectrsid16456967\sftnbj {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid12941695 }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid9969477 +\par }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid11105546 +\par }\pard\plain \ltrpar\s28\ql \li0\ri0\sa200\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid11105546 \rtlch\fcs1 \ab\af31507\afs18\alang1025 \ltrch\fcs0 \b\f31506\fs18\cf18\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 +{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid11105546 Figure }{\field{\*\fldinst {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid11105546 SEQ Figure \\* ARABIC }}{\fldrslt {\rtlch\fcs1 \af31507 \ltrch\fcs0 \lang1024\langfe1024\noproof\insrsid11105546 1}}} +\sectd \ltrsect\linex0\endnhere\sectlinegrid360\sectdefaultcl\sectrsid16456967\sftnbj {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid11105546 This is a caption for Figure 1 +\par }\pard\plain \ltrpar\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid8152053 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 { +\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid8152053 +\par +\par }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid5051464 \sect }\sectd \ltrsect\sbknone\linex0\cols2\endnhere\sectlinegrid360\sectdefaultcl\sectrsid5051464\sftnbj \pard\plain \ltrpar\ql \li0\ri0\sa200\sl276\slmult1 +\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid5051464 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid5051464 +Row 1 column 1 +\par Row 2 column 1 +\par }\pard \ltrpar\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid8152053 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid5051464 Row 1 column 2 +\par Row 2 column 2 +\par \sect }\sectd \ltrsect\sbknone\linex0\endnhere\sectlinegrid360\sectdefaultcl\sectrsid5051464\sftnbj \pard\plain \ltrpar\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid8152053 \rtlch\fcs1 +\af31507\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid5051464\charrsid8152053 +\par }{\*\themedata 504b030414000600080000002100828abc13fa0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb6ac3301045f785fe83d0b6d8 +72ba28a5d8cea249777d2cd20f18e4b12d6a8f843409c9df77ecb850ba082d74231062ce997b55ae8fe3a00e1893f354e9555e6885647de3a8abf4fbee29bbd7 +2a3150038327acf409935ed7d757e5ee14302999a654e99e393c18936c8f23a4dc072479697d1c81e51a3b13c07e4087e6b628ee8cf5c4489cf1c4d075f92a0b +44d7a07a83c82f308ac7b0a0f0fbf90c2480980b58abc733615aa2d210c2e02cb04430076a7ee833dfb6ce62e3ed7e14693e8317d8cd0433bf5c60f53fea2fe7 +065bd80facb647e9e25c7fc421fd2ddb526b2e9373fed4bb902e182e97b7b461e6bfad3f010000ffff0300504b030414000600080000002100a5d6a7e7c00000 +00360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4fc7060abb08 +84a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b63095120f88d94fbc +52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462a1a82fe353 +bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f7468656d652f7468 +656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b4b0d592c9c +070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b4757e8d3f7 +29e245eb2b260a0238fd010000ffff0300504b03041400060008000000210096b5ade296060000501b0000160000007468656d652f7468656d652f7468656d65 +312e786d6cec594f6fdb3614bf0fd87720746f6327761a07758ad8b19b2d4d1bc46e871e698996d850a240d2497d1bdae38001c3ba618715d86d87615b8116d8 +a5fb34d93a6c1dd0afb0475292c5585e9236d88aad3e2412f9e3fbff1e1fa9abd7eec70c1d1221294fda5efd72cd4324f1794093b0eddd1ef62fad79482a9c04 +98f184b4bd2991deb58df7dfbb8ad755446282607d22d771db8b944ad79796a40fc3585ee62949606ecc458c15bc8a702910f808e8c66c69b9565b5d8a314d3c +94e018c8de1a8fa94fd05093f43672e23d06af89927ac06762a049136785c10607758d9053d965021d62d6f6804fc08f86e4bef210c352c144dbab999fb7b471 +7509af678b985ab0b6b4ae6f7ed9ba6c4170b06c788a705430adf71bad2b5b057d03606a1ed7ebf5babd7a41cf00b0ef83a6569632cd467faddec9699640f671 +9e76b7d6ac355c7c89feca9cccad4ea7d36c65b258a206641f1b73f8b5da6a6373d9c11b90c537e7f08dce66b7bbeae00dc8e257e7f0fd2badd5868b37a088d1 +e4600ead1ddaef67d40bc898b3ed4af81ac0d76a197c86826828a24bb318f3442d8ab518dfe3a20f000d6458d104a9694ac6d88728eee2782428d60cf03ac1a5 +193be4cbb921cd0b495fd054b5bd0f530c1931a3f7eaf9f7af9e3f45c70f9e1d3ff8e9f8e1c3e3073f5a42ceaa6d9c84e5552fbffdeccfc71fa33f9e7ef3f2d1 +17d57859c6fffac327bffcfc793510d26726ce8b2f9ffcf6ecc98baf3efdfdbb4715f04d814765f890c644a29be408edf3181433567125272371be15c308d3f2 +8acd249438c19a4b05fd9e8a1cf4cd296699771c393ac4b5e01d01e5a30a787d72cf1178108989a2159c77a2d801ee72ce3a5c545a6147f32a99793849c26ae6 +6252c6ed637c58c5bb8b13c7bfbd490a75330f4b47f16e441c31f7184e140e494214d273fc80900aedee52ead87597fa824b3e56e82e451d4c2b4d32a423279a +668bb6690c7e9956e90cfe766cb37b077538abd27a8b1cba48c80acc2a841f12e698f13a9e281c57911ce298950d7e03aba84ac8c154f8655c4f2af074481847 +bd804859b5e696007d4b4edfc150b12addbecba6b18b148a1e54d1bc81392f23b7f84137c2715a851dd0242a633f900710a218ed715505dfe56e86e877f0034e +16bafb0e258ebb4faf06b769e888340b103d3311da9750aa9d0a1cd3e4efca31a3508f6d0c5c5c398602f8e2ebc71591f5b616e24dd893aa3261fb44f95d843b +5974bb5c04f4edafb95b7892ec1108f3f98de75dc97d5772bdff7cc95d94cf672db4b3da0a6557f70db629362d72bcb0431e53c6066acac80d699a6409fb44d0 +8741bdce9c0e4971624a2378cceaba830b05366b90e0ea23aaa241845368b0eb9e2612ca8c742851ca251ceccc70256d8d87265dd96361531f186c3d9058edf2 +c00eafe8e1fc5c509031bb4d680e9f39a3154de0accc56ae644441edd76156d7429d995bdd88664a9dc3ad50197c38af1a0c16d684060441db02565e85f3b966 +0d0713cc48a0ed6ef7dedc2dc60b17e92219e180643ed27acffba86e9c94c78ab90980d8a9f0913ee49d62b512b79626fb06dccee2a432bbc60276b9f7dec44b +7904cfbca4f3f6443ab2a49c9c2c41476dafd55c6e7ac8c769db1bc399161ee314bc2e75cf8759081743be1236ec4f4d6693e5336fb672c5dc24a8c33585b5fb +9cc24e1d4885545b58463634cc5416022cd19cacfccb4d30eb45296023fd35a458598360f8d7a4003bbaae25e331f155d9d9a5116d3bfb9a95523e51440ca2e0 +088dd844ec6370bf0e55d027a012ae264c45d02f708fa6ad6da6dce29c255df9f6cae0ec38666984b372ab5334cf640b37795cc860de4ae2816e95b21be5ceaf +8a49f90b52a51cc6ff3355f47e0237052b81f6800fd7b802239daf6d8f0b1571a8426944fdbe80c6c1d40e8816b88b8569082ab84c36ff0539d4ff6dce591a26 +ade1c0a7f669880485fd484582903d284b26fa4e2156cff62e4b9265844c4495c495a9157b440e091bea1ab8aaf7760f4510eaa69a6465c0e04ec69ffb9e65d0 +28d44d4e39df9c1a52ecbd3607fee9cec7263328e5d661d3d0e4f62f44acd855ed7ab33cdf7bcb8ae889599bd5c8b3029895b6825696f6af29c239b75a5bb1e6 +345e6ee6c28117e73586c1a2214ae1be07e93fb0ff51e133fb65426fa843be0fb515c187064d0cc206a2fa926d3c902e907670048d931db4c1a44959d366ad93 +b65abe595f70a75bf03d616c2dd959fc7d4e6317cd99cbcec9c58b34766661c7d6766ca1a9c1b327531486c6f941c638c67cd22a7f75e2a37be0e82db8df9f30 +254d30c1372581a1f51c983c80e4b71ccdd28dbf000000ffff0300504b0304140006000800000021000dd1909fb60000001b010000270000007468656d652f74 +68656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4350d363f24 +51eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d262452282e3198 +720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f165dfe514173d9850528 +a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100828abc13fa0000001c0200001300000000000000000000000000 +000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7c0000000360100000b000000000000000000000000 +002b0100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a0000001c00000000000000000000000000140200007468 +656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d001400060008000000210096b5ade296060000501b000016000000000000000000 +00000000d10200007468656d652f7468656d652f7468656d65312e786d6c504b01022d00140006000800000021000dd1909fb60000001b010000270000000000 +00000000000000009b0900007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000960a00000000} +{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d +617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169 +6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363 +656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e} +{\*\latentstyles\lsdstimax267\lsdlockeddef0\lsdsemihiddendef1\lsdunhideuseddef1\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal; +\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4; +\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9; +\lsdpriority39 \lsdlocked0 toc 1;\lsdpriority39 \lsdlocked0 toc 2;\lsdpriority39 \lsdlocked0 toc 3;\lsdpriority39 \lsdlocked0 toc 4;\lsdpriority39 \lsdlocked0 toc 5;\lsdpriority39 \lsdlocked0 toc 6;\lsdpriority39 \lsdlocked0 toc 7; +\lsdpriority39 \lsdlocked0 toc 8;\lsdpriority39 \lsdlocked0 toc 9;\lsdqformat1 \lsdpriority35 \lsdlocked0 caption;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdpriority1 \lsdlocked0 Default Paragraph Font; +\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority22 \lsdlocked0 Strong;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority59 \lsdlocked0 Table Grid;\lsdunhideused0 \lsdlocked0 Placeholder Text;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 1; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;\lsdunhideused0 \lsdlocked0 Revision; +\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 1; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 2; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 2; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 2; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 3; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 3; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 3; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 4; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 4; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 4; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 5; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 5; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 5; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 6; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 6; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 6; +\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis; +\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference; +\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdpriority37 \lsdlocked0 Bibliography;\lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;}}{\*\datastore 010500000200000018000000 +4d73786d6c322e534158584d4c5265616465722e352e30000000000000000000000e0000 +d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff0900060000000000000000000000010000000100000000000000001000000200000001000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffdffffff05000000feffffff04000000fefffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffff01000000ec69d9888b8b3d4c859eaf6cd158be0f0000000000000000000000000076 +bb6efd66cc0103000000c0030000000000004d0073006f004400610074006100530074006f0072006500000000000000000000000000000000000000000000000000000000000000000000000000000000001a000101ffffffffffffffff0200000000000000000000000000000000000000000000000076bb6efd66cc01 +0076bb6efd66cc010000000000000000000000003500cb004c0053004a004300ca00d80044005500470056003000cd0045004500d100c3004c00c000cd0051003d003d000000000000000000000000000000000032000101ffffffffffffffff0300000000000000000000000000000000000000000000000076bb6efd66 +cc010076bb6efd66cc010000000000000000000000004900740065006d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000201ffffffff04000000ffffffff000000000000000000000000000000000000000000000000 +0000000000000000000000000000000016020000000000000100000002000000030000000400000005000000060000000700000008000000feffffff0a0000000b0000000c0000000d0000000e000000feffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3c623a536f757263657320786d6c6e733a623d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f6f6666696365446f63756d656e742f323030362f6269626c696f6772617068792220786d6c6e733d +22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f6f6666696365446f63756d656e742f323030362f6269626c696f677261706879222053656c65637465645374796c653d225c4150412e58534c22205374796c654e616d653d22415041223e3c623a536f757263653e3c623a546167 +3e4b72613c2f623a5461673e3c623a536f75726365547970653e426f6f6b3c2f623a536f75726365547970653e3c623a477569643e7b32313839323034362d453338412d344136382d383931312d3837313145343731453345347d3c2f623a477569643e3c623a4c4349443e303c2f623a4c4349443e3c623a417574686f +723e3c623a417574686f723e3c623a4e616d654c6973743e3c623a506572736f6e3e3c623a4c6173743e4b72616d65723c2f623a4c6173743e3c2f623a506572736f6e3e3c2f623a4e616d654c6973743e3c2f623a417574686f723e3c2f623a417574686f723e3c623a5469746c653e486f7720746f207573652054696b +613c2f623a5469746c653e3c623a5265664f726465723e313c2f623a5265664f726465723e3c2f623a536f757263653e3c2f623a536f75726365733e0d0a68aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d262452282e31983c3f786d6c2076657273696f6e3d22312e302220656e +636f64696e673d225554462d3822207374616e64616c6f6e653d226e6f223f3e0d0a3c64733a6461746173746f72654974656d2064733a6974656d49443d227b32344432423237452d423832412d343130442d393536412d4431303443363332453042357d2220786d6c6e733a64733d22687474703a2f2f736368656d61 +732e6f70656e786d6c666f726d6174732e6f72672f6f6666696365446f63756d656e742f323030362f637573746f6d586d6c223e3c64733a736368656d61526566733e3c64733a736368656d615265662064733a7572693d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f6f6666 +696365446f63756d656e742f323030362f6269626c696f677261706879222f3e3c2f64733a736368656d61526566733e3c2f64733a6461746173746f72654974656d3e68656d65312e786d6c504b01022d00140006000800000021000dd1909fb60000001b01000027000000000000000000000000009b0900007468656d +652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d500072006f007000650072007400690065007300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000200ffffffffffffffffffff +ffff0000000000000000000000000000000000000000000000000000000000000000000000000900000055010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffff +ffffffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffff +ffffffffffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffff +ffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000105000000000000}} diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testSVG.svg b/solr/contrib/solr-mr/src/test-files/test-documents/testSVG.svg new file mode 100644 index 00000000000..8a05a4835b6 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/test-documents/testSVG.svg @@ -0,0 +1,23 @@ + + + + + Test SVG image + + \ No newline at end of file diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testTIFF.tif b/solr/contrib/solr-mr/src/test-files/test-documents/testTIFF.tif new file mode 100644 index 0000000000000000000000000000000000000000..8f6c7abba4243d5562e67566675fd12df14cb1d0 GIT binary patch literal 25584 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 literal 0 HcmV?d00001 diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testVISIO.vsd b/solr/contrib/solr-mr/src/test-files/test-documents/testVISIO.vsd new file mode 100644 index 0000000000000000000000000000000000000000..d699e11122bf0ddca65d221828df6f35923ee646 GIT binary patch literal 45568 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 H|Niq|w~)S& literal 0 HcmV?d00001 diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testWAV.wav b/solr/contrib/solr-mr/src/test-files/test-documents/testWAV.wav new file mode 100644 index 0000000000000000000000000000000000000000..59a063ece0114867f9447c30c3c3476a3f185a9b GIT binary patch literal 3884 zcmZ`*eQ1|e6n^eIXHzVf<-(*`ZmF#jvY;SJGq6T6_sL+R>tyZC-gki0aM3&CartbGUJ!fafd*5H{h4XvQJ@+}!dCs}_Wt;uL zj2X2ffk&r4a^F*nTB<7n1Z0^02~fEy!w^*B$>x@35ECGxMo2%(J&_DWny(FsesshJ zVvNCJ`QMZyUq{)LU9+9pR9M`rsbz3q$WO+5S4PXX*`#ywYR+4V^|Mf}sKG0n9>u6C zJ0Y#*YDMDlUc#L?JcoVGq$d%8GxWT$`Ri!zD>+)W_ z3saRwUb8GS z?b%}5k?s4pVLH>>ns(?~J?4tEVr0~n@}%de88$UVD#E9lpJkkrVbTg7ajmv4t?W^I zm(D7`>nlT9cdFW-(tbT2-*Kk-O0GMN#wtF6e7CxVnAWV!%A&&T#J)S_A$2S@Ub+s_3gV(tn&aoB6)F zSd_&@ph!%CR>S=Eg2>zCtK>bZBKHN_23jYzEa1DE9LqF^xlNo*8~us`(8b)J+1p0) zH1NHZ{9~!%558A1?^kk8VeUgA;4WgmEoL}e$nfHYfXRIUWm$&GETHi`=XWmPt)j>* zazEP#Ol96)a`dv!Y~~LqZu{XWPxS)Rhj13OZgSko zy!Et(e}Hkl0hO#V>1e>Azkvri;O5~XchH}EL}W*=$U@dy$irL8z1zw&tf1b}<-q6E zaqCHu4)Xj^7VsMNe{>uee~f3=Bl00@%^|+xEYRL9@;dP~!&sm5xuqhY^-5qR^SVz5 zEIk5zyjx`bK9Ln;fVEfg{_G5B*%mPUB+yCDm0iFT*4@Vo&~-e+hRZUXxjbP1A#i>o zP1iAhH4mp1*!3Q;u12K2Po(^yNO82tnvnsovd?YouZpv&-OpOb_#K=Ud0{oMb4|c+ z*9P1>9@w)L`1AvyV~a@RPr%J1fCZC9num!zrhSYPSBCwppuFB{>%QsD*H%5!T84_R4EGMtQE^M^GQ9k~VJ*+JsGc{+@~-hb z)pt{jay9UK5Z=`^=TL|3b@C1w-n4AmU^v6NpW(ol?EQArG39r!;kg#~IV#_rdXG7W z)wA9*?C3HMty4EsXQgYy_}j3auQPGq-hYm<8UJ-K#;IICm5rq?KC*0^HzSN}ipT4`->%#;d;`i40!DchX+H$G8{sJobN_HkXJ`&)aH52E)2auWA{3i+o@6 myo;igUEI+so*gHgk3=O}H?0x<6r+{AuEjNCkM|Z=rt)8!%e+Sb literal 0 HcmV?d00001 diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testWORD_various.doc b/solr/contrib/solr-mr/src/test-files/test-documents/testWORD_various.doc new file mode 100644 index 0000000000000000000000000000000000000000..a2ad2364565a197d52d678ce221ad941224bbc5c GIT binary patch literal 35328 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 + + + + Tika test document + + Rida Benjelloun + + Java + + XML + + XSLT + + JDOM + + Indexation + + Framework d'indexation des documents XML, HTML, PDF etc.. + + http://www.apache.org + + 2000-12-01T00:00:00.000Z + + test + + application/msword + + Fr + + Archimède et Lius à Châteauneuf testing chars en été + + \ No newline at end of file diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testXML2.xml b/solr/contrib/solr-mr/src/test-files/test-documents/testXML2.xml new file mode 100644 index 00000000000..6611ee14957 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/test-documents/testXML2.xml @@ -0,0 +1,22 @@ + + + + 123 + Hello World + Solr rocks + diff --git a/solr/contrib/solr-mr/src/test-files/test-morphlines/loadSolrBasic.conf b/solr/contrib/solr-mr/src/test-files/test-morphlines/loadSolrBasic.conf new file mode 100644 index 00000000000..b033320b776 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/test-morphlines/loadSolrBasic.conf @@ -0,0 +1,63 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# morphline.conf example file +# this is a comment +// this is yet another comment + +# for details see https://github.com/typesafehub/config#optional-system-or-env-variable-overrides +SOLR_COLLECTION : "collection1" +SOLR_COLLECTION : ${?ENV_SOLR_COLLECTION} + +ZK_HOST : "127.0.0.1:2181/solr" +ZK_HOST : ${?ENV_ZK_HOST} + +SOLR_HOME_DIR : "example/solr/collection1" +SOLR_HOME_DIR : ${?ENV_SOLR_HOME_DIR} + +SOLR_LOCATOR : { + collection : ${SOLR_COLLECTION} + zkHost : ${ZK_HOST} + solrHomeDir : ${SOLR_HOME_DIR} + # batchSize : 1000 +} +SOLR_LOCATOR : ${?ENV_SOLR_LOCATOR} + +morphlines : [ + { + id : morphline1 + importCommands : ["com.cloudera.**", "org.apache.solr.**"] + + commands : [ + { + sanitizeUnknownSolrFields { + solrLocator : ${SOLR_LOCATOR} + } + } + + { + loadSolr { + solrLocator : ${SOLR_LOCATOR} + boosts : { + id : 1.0 + } + } + } + + { logDebug { format : "output record: {}", args : ["@{}"] } } + ] + } +] diff --git a/solr/contrib/solr-mr/src/test-files/test-morphlines/solrCellDocumentTypes.conf b/solr/contrib/solr-mr/src/test-files/test-morphlines/solrCellDocumentTypes.conf new file mode 100644 index 00000000000..bf1e58d5fb4 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/test-morphlines/solrCellDocumentTypes.conf @@ -0,0 +1,255 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Application configuration file in HOCON format (Human-Optimized Config Object Notation). +# HOCON syntax is defined at http://github.com/typesafehub/config/blob/master/HOCON.md +# and also used by Akka (http://www.akka.io) and Play (http://www.playframework.org/). +# For more examples see http://doc.akka.io/docs/akka/2.1.2/general/configuration.html + +# morphline.conf example file +# this is a comment +// this is yet another comment + +morphlines : [ + { + id : morphline1 + importCommands : ["com.cloudera.**", "org.apache.solr.**"] + + commands : [ + { separateAttachments {} } + + # java command that doesn't do anything except for test compilation + { + java { + imports : "import java.util.*;" + code: """ + List tags = record.get("javaWithImports"); + return child.process(record); + """ + } + } + + # java command that doesn't do anything except for test compilation + { + java { + code: """ + List tags = record.get("javaWithoutImports"); + return child.process(record); + """ + } + } + + { + # used for auto-detection if MIME type isn't explicitly supplied + detectMimeType { + includeDefaultMimeTypes : true + mimeTypesFiles : [RESOURCES_DIR/custom-mimetypes.xml] + } + } + + { + tryRules { + throwExceptionIfAllRulesFailed : true + rules : [ + # next top-level rule: + { + commands : [ + { logDebug { format : "hello unpack" } } + { unpack {} } + { generateUUID {} } + { callParentPipe {} } + ] + } + + { + commands : [ + { logDebug { format : "hello decompress" } } + { decompress {} } + { callParentPipe {} } + ] + } + + { + commands : [ + { + readAvroContainer { + supportedMimeTypes : [avro/binary] + # readerSchemaString : "" # optional, avro json schema blurb for getSchema() + # readerSchemaFile : /path/to/syslog.avsc + } + } + + { extractAvroTree {} } + + { + setValues { + id : "@{/id}" + user_screen_name : "@{/user_screen_name}" + text : "@{/text}" + } + } + + { + sanitizeUnknownSolrFields { + solrLocator : ${SOLR_LOCATOR} + } + } + ] + } + + { + commands : [ + { + readJsonTestTweets { + supportedMimeTypes : ["mytwittertest/json+delimited+length"] + } + } + + { + sanitizeUnknownSolrFields { + solrLocator : ${SOLR_LOCATOR} + } + } + ] + } + + # next top-level rule: + { + commands : [ + { logDebug { format : "hello solrcell" } } + { + # wrap SolrCell around an HTML Tika parser + solrCell { + solrLocator : ${SOLR_LOCATOR} + # captureAttr : true # default is false + capture : [ + + # twitter feed schema + user_friends_count + user_location + user_description + user_statuses_count + user_followers_count + user_name + user_screen_name + created_at + text + retweet_count + retweeted + in_reply_to_user_id + source + in_reply_to_status_id + media_url_https + expanded_url + + # file metadata + file_download_url + file_upload_url + file_scheme + file_host + file_port + file_path + file_name + file_length + file_last_modified + file_owner + file_group + file_permissions_user + file_permissions_group + file_permissions_other + file_permissions_stickybit + ] + + fmap : { content : text, content-type : content_type } # rename "content" field to "text" fields + dateFormats : [ "yyyy-MM-dd'T'HH:mm:ss", "yyyy-MM-dd"] # various java.text.SimpleDateFormat + # xpath : "/xhtml:html/xhtml:body/xhtml:div/descendant:node()" + uprefix : "ignored_" + lowernames : true + # solrContentHandlerFactory : org.apache.solr.tika.TrimSolrContentHandlerFactory + + # Tika parsers to be registered. If multiple parsers support the same MIME type, + # the parser is chosen that is closest to the bottom in this list: + parsers : [ + { parser : org.apache.tika.parser.asm.ClassParser } + # { parser : org.gagravarr.tika.OggParser, additionalSupportedMimeTypes : [audio/ogg] } + { parser : org.gagravarr.tika.FlacParser } + { parser : org.apache.tika.parser.audio.AudioParser } + { parser : org.apache.tika.parser.audio.MidiParser } + { parser : org.apache.tika.parser.crypto.Pkcs7Parser } + { parser : org.apache.tika.parser.dwg.DWGParser } + { parser : org.apache.tika.parser.epub.EpubParser } + { parser : org.apache.tika.parser.executable.ExecutableParser } + { parser : org.apache.tika.parser.feed.FeedParser } + { parser : org.apache.tika.parser.font.AdobeFontMetricParser } + { parser : org.apache.tika.parser.font.TrueTypeParser } + { parser : org.apache.tika.parser.xml.XMLParser } + { parser : org.apache.tika.parser.html.HtmlParser } + { parser : org.apache.tika.parser.image.ImageParser } + { parser : org.apache.tika.parser.image.PSDParser } + { parser : org.apache.tika.parser.image.TiffParser } + { parser : org.apache.tika.parser.iptc.IptcAnpaParser } + { parser : org.apache.tika.parser.iwork.IWorkPackageParser } + { parser : org.apache.tika.parser.jpeg.JpegParser } + { parser : org.apache.tika.parser.mail.RFC822Parser } + { parser : org.apache.tika.parser.mbox.MboxParser, additionalSupportedMimeTypes : [message/x-emlx] } + { parser : org.apache.tika.parser.microsoft.OfficeParser } + { parser : org.apache.tika.parser.microsoft.TNEFParser } + { parser : org.apache.tika.parser.microsoft.ooxml.OOXMLParser } + { parser : org.apache.tika.parser.mp3.Mp3Parser } + { parser : org.apache.tika.parser.mp4.MP4Parser } + { parser : org.apache.tika.parser.hdf.HDFParser } + { parser : org.apache.tika.parser.netcdf.NetCDFParser } + { parser : org.apache.tika.parser.odf.OpenDocumentParser } + { parser : org.apache.tika.parser.pdf.PDFParser } + { parser : org.apache.tika.parser.pkg.CompressorParser } + { parser : org.apache.tika.parser.pkg.PackageParser } + { parser : org.apache.tika.parser.rtf.RTFParser } + { parser : org.apache.tika.parser.txt.TXTParser } + { parser : org.apache.tika.parser.video.FLVParser } + { parser : org.apache.tika.parser.xml.DcXMLParser } + { parser : org.apache.tika.parser.xml.FictionBookParser } + { parser : org.apache.tika.parser.chm.ChmParser } + ] + } + } + + { generateUUID { field : ignored_base_id } } + + { + generateSolrSequenceKey { + baseIdField: ignored_base_id + solrLocator : ${SOLR_LOCATOR} + } + } + + ] + } + ] + } + } + + { + loadSolr { + solrLocator : ${SOLR_LOCATOR} + } + } + + { + logDebug { + format : "My output record: {}" + args : ["@{}"] + } + } + + ] + } +] diff --git a/solr/contrib/solr-mr/src/test-files/test-morphlines/solrCellJPGCompressed.conf b/solr/contrib/solr-mr/src/test-files/test-morphlines/solrCellJPGCompressed.conf new file mode 100644 index 00000000000..e1a9679678e --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/test-morphlines/solrCellJPGCompressed.conf @@ -0,0 +1,135 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Application configuration file in HOCON format (Human-Optimized Config Object Notation). +# HOCON syntax is defined at http://github.com/typesafehub/config/blob/master/HOCON.md +# and also used by Akka (http://www.akka.io) and Play (http://www.playframework.org/). +# For more examples see http://doc.akka.io/docs/akka/2.1.2/general/configuration.html + +# morphline.conf example file +# this is a comment +// this is yet another comment + +morphlines : [ + { + id : morphline1 + importCommands : ["com.cloudera.**", "org.apache.solr.**"] + + commands : [ + { separateAttachments {} } + + # java command that doesn't do anything except for test compilation + { + java { + imports : "import java.util.*;" + code: """ + List tags = record.get("javaWithImports"); + return child.process(record); + """ + } + } + + # java command that doesn't do anything except for test compilation + { + java { + code: """ + List tags = record.get("javaWithoutImports"); + return child.process(record); + """ + } + } + + { + # auto-detect MIME type if it isn't explicitly supplied + detectMimeType { + includeDefaultMimeTypes : true + } + } + + { + tryRules { + throwExceptionIfAllRulesFailed : true + rules : [ + # next top-level rule: + { + commands : [ + { logDebug { format : "hello unpack" } } + { unpack {} } + { callParentPipe {} } + ] + } + + { + commands : [ + { logDebug { format : "hello decompress" } } + { decompress {} } + { callParentPipe {} } + ] + } + + # next top-level rule: + { + commands : [ + { logDebug { format : "hello solrcell" } } + { + # wrap SolrCell around a JPG Tika parser + solrCell { + solrLocator : ${SOLR_LOCATOR} + captureAttr : true # default is false + capture : [content, a, h1, h2] # extract some fields + fmap : { exif_image_height : text, a : anchor, h1 : heading1 } # rename some fields + dateFormats : [ "yyyy-MM-dd'T'HH:mm:ss", "yyyy-MM-dd"] # various java.text.SimpleDateFormat + xpath : "/xhtml:html/xhtml:body/xhtml:div/descendant:node()" + uprefix : "ignored_" + lowernames : true + solrContentHandlerFactory : org.apache.solr.morphlines.cell.TrimSolrContentHandlerFactory + parsers : [ # nested Tika parsers + { parser : org.apache.tika.parser.jpeg.JpegParser } + ] + } + } + + { logDebug { format : "solrcell output: {}", args : ["@{}"] } } + ] + } + ] + } + } + + { generateUUID { field : ignored_base_id } } + + { + generateSolrSequenceKey { + baseIdField: ignored_base_id + solrLocator : ${SOLR_LOCATOR} + } + } + + { + loadSolr { + solrLocator : ${SOLR_LOCATOR} + } + } + + { + logDebug { + format : "My output record: {}" + args : ["@{}"] + } + } + + ] + } +] diff --git a/solr/contrib/solr-mr/src/test-files/test-morphlines/solrCellXML.conf b/solr/contrib/solr-mr/src/test-files/test-morphlines/solrCellXML.conf new file mode 100644 index 00000000000..6c19c5ee692 --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/test-morphlines/solrCellXML.conf @@ -0,0 +1,69 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Application configuration file in HOCON format (Human-Optimized Config Object Notation). +# HOCON syntax is defined at http://github.com/typesafehub/config/blob/master/HOCON.md +# and also used by Akka (http://www.akka.io) and Play (http://www.playframework.org/). +# For more examples see http://doc.akka.io/docs/akka/2.1.2/general/configuration.html + +# morphline.conf example file +# this is a comment +// this is yet another comment + +morphlines : [ + { + id : morphline1 + importCommands : ["com.cloudera.**", "org.apache.solr.**"] + + commands : [ + { + addValues { _attachment_mimetype : application/xml } + # alternatively, consider using detectMimeTypes command + } + + { + # wrap SolrCell around a JPG Tika parser + solrCell { + solrLocator : ${SOLR_LOCATOR} + parsers : [ # nested Tika parsers + { parser : org.apache.tika.parser.xml.XMLParser } + ] + } + } + + { + generateSolrSequenceKey { + baseIdField: base_id + solrLocator : ${SOLR_LOCATOR} + } + } + + { + sanitizeUnknownSolrFields { + solrLocator : ${SOLR_LOCATOR} + } + } + + { logDebug { format : "solrcell output: {}", args : ["@{}"] } } + + { + loadSolr { + solrLocator : ${SOLR_LOCATOR} + } + } + + ] + } +] diff --git a/solr/contrib/solr-mr/src/test-files/test-morphlines/tokenizeText.conf b/solr/contrib/solr-mr/src/test-files/test-morphlines/tokenizeText.conf new file mode 100644 index 00000000000..c58d4d2236c --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/test-morphlines/tokenizeText.conf @@ -0,0 +1,34 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +morphlines : [ + { + id : morphline1 + importCommands : ["com.cloudera.**", "org.apache.solr.**"] + + commands : [ + { + tokenizeText { + inputField : message + outputField : tokens + solrFieldType : text_en + solrLocator : ${SOLR_LOCATOR} + } + } + + { logDebug { format : "output record {}", args : ["@{}"] } } + ] + } +] diff --git a/solr/contrib/solr-mr/src/test-files/test-morphlines/tutorialReadAvroContainer.conf b/solr/contrib/solr-mr/src/test-files/test-morphlines/tutorialReadAvroContainer.conf new file mode 100644 index 00000000000..cf34c4fac7e --- /dev/null +++ b/solr/contrib/solr-mr/src/test-files/test-morphlines/tutorialReadAvroContainer.conf @@ -0,0 +1,140 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Application configuration file in HOCON format (Human-Optimized Config Object Notation). +# HOCON syntax is defined at http://github.com/typesafehub/config/blob/master/HOCON.md +# and also used by Akka (http://www.akka.io) and Play (http://www.playframework.org/). +# For more examples see http://doc.akka.io/docs/akka/2.1.2/general/configuration.html + +# morphline.conf example file +# this is a comment + +# Specify server locations in a SOLR_LOCATOR variable; used later in variable substitutions: +SOLR_LOCATOR : { + # Name of solr collection + collection : collection1 + + # ZooKeeper ensemble + zkHost : "127.0.0.1:2181/solr" + + # The maximum number of documents to send to Solr per network batch (throughput knob) + # batchSize : 1000 +} + +# Specify an array of one or more morphlines, each of which defines an ETL +# transformation chain. A morphline consists of one or more (potentially +# nested) commands. A morphline is a way to consume records (e.g. Flume events, +# HDFS files or blocks), turn them into a stream of records, and pipe the stream +# of records through a set of easily configurable transformations on it's way to +# Solr. +morphlines : [ + { + # Name used to identify a morphline. E.g. used if there are multiple morphlines in a + # morphline config file + id : morphline1 + + # Import all morphline commands in these java packages and their subpackages. + # Other commands that may be present on the classpath are not visible to this morphline. + importCommands : ["com.cloudera.**", "org.apache.solr.**"] + + commands : [ + { + # Parse Avro container file and emit a record for each avro object + readAvroContainer { + # Optionally, require the input record to match one of these MIME types: + # supportedMimeTypes : [avro/binary] + + # Optionally, use a custom Avro schema in JSON format inline: + # readerSchemaString : """""" + + # Optionally, use a custom Avro schema file in JSON format: + # readerSchemaFile : /path/to/syslog.avsc + } + } + + { + # Consume the output record of the previous command and pipe another record downstream. + # + # extractAvroPaths is a command that uses zero or more avro path expressions to extract + # values from an Avro object. Each expression consists of a record output field name (on + # the left side of the colon ':') as well as zero or more path steps (on the right hand + # side), each path step separated by a '/' slash. Avro arrays are traversed with the '[]' + # notation. + # + # The result of a path expression is a list of objects, each of which is added to the + # given record output field. + # + # The path language supports all Avro concepts, including nested structures, records, + # arrays, maps, unions, etc, as well as a flatten option that collects the primitives in + # a subtree into a flat list. + extractAvroPaths { + flatten : false + paths : { + id : /id + text : /text + user_friends_count : /user_friends_count + user_location : /user_location + user_description : /user_description + user_statuses_count : /user_statuses_count + user_followers_count : /user_followers_count + user_name : /user_name + user_screen_name : /user_screen_name + created_at : /created_at + retweet_count : /retweet_count + retweeted : /retweeted + in_reply_to_user_id : /in_reply_to_user_id + source : /source + in_reply_to_status_id : /in_reply_to_status_id + media_url_https : /media_url_https + expanded_url : /expanded_url + } + } + } + + # Consume the output record of the previous command and pipe another record downstream. + # + # convert timestamp field to native Solr timestamp format + # e.g. 2012-09-06T07:14:34Z to 2012-09-06T07:14:34.000Z + { + convertTimestamp { + field : created_at + inputFormats : ["yyyy-MM-dd'T'HH:mm:ss'Z'", "yyyy-MM-dd"] + inputTimezone : UTC +# outputFormat : "yyyy-MM-dd'T'HH:mm:ss.SSSZ" + outputTimezone : America/Los_Angeles + } + } + + # Consume the output record of the previous command and pipe another record downstream. + # + # This command sanitizes record fields that are unknown to Solr schema.xml by deleting + # them. Recall that Solr throws an exception on any attempt to load a document that + # contains a field that isn't specified in schema.xml. + { + sanitizeUnknownSolrFields { + # Location from which to fetch Solr schema + solrLocator : ${SOLR_LOCATOR} + } + } + + # log the record at DEBUG level to SLF4J + { logDebug { format : "output record: {}", args : ["@{}"] } } + + # load the record into a Solr server or MapReduce Reducer. + { + loadSolr { + solrLocator : ${SOLR_LOCATOR} + } + } + ] + } +] diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/IdentityMapper.java b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/IdentityMapper.java new file mode 100644 index 00000000000..370dee189c9 --- /dev/null +++ b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/IdentityMapper.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop; + +import java.io.IOException; + +import org.apache.hadoop.io.LongWritable; +import org.apache.hadoop.io.NullWritable; +import org.apache.hadoop.io.Text; +import org.apache.hadoop.mapreduce.Mapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class IdentityMapper extends Mapper { + + private static final Logger LOGGER = LoggerFactory.getLogger(IdentityMapper.class); + + @Override + protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { + LOGGER.info("map key: {}, value: {}", key, value); + context.write(value, NullWritable.get()); + } +} \ No newline at end of file diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/IdentityReducer.java b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/IdentityReducer.java new file mode 100644 index 00000000000..104a88225f7 --- /dev/null +++ b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/IdentityReducer.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop; + +import java.io.IOException; + +import org.apache.hadoop.io.NullWritable; +import org.apache.hadoop.io.Text; +import org.apache.hadoop.mapreduce.Reducer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class IdentityReducer extends Reducer { + + private static final Logger LOGGER = LoggerFactory.getLogger(IdentityReducer.class); + + @Override + protected void reduce(Text key, Iterable values, Context context) throws IOException, InterruptedException { + LOGGER.info("reduce key: {}, value: {}", key, values); + context.write(key, NullWritable.get()); + } +} \ No newline at end of file diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/LineRandomizerMapperReducerTest.java b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/LineRandomizerMapperReducerTest.java new file mode 100644 index 00000000000..379e60a4dc9 --- /dev/null +++ b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/LineRandomizerMapperReducerTest.java @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop; + +import java.io.IOException; +import java.util.Arrays; + +import org.apache.hadoop.io.LongWritable; +import org.apache.hadoop.io.NullWritable; +import org.apache.hadoop.io.Text; +import org.apache.hadoop.mrunit.mapreduce.MapReduceDriver; +import org.apache.hadoop.mrunit.types.Pair; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class LineRandomizerMapperReducerTest extends Assert { + + private MapReduceDriver mapReduceDriver; + + @Before + public void setUp() { + LineRandomizerMapper mapper = new LineRandomizerMapper(); + LineRandomizerReducer reducer = new LineRandomizerReducer(); + mapReduceDriver = MapReduceDriver.newMapReduceDriver(mapper, reducer); + } + + @Test + public void testMapReduce1Item() throws IOException { + mapReduceDriver.withInput(new LongWritable(0), new Text("hello")); + mapReduceDriver.withOutput(new Text("hello"), NullWritable.get()); + mapReduceDriver.runTest(); + } + + @Test + public void testMapReduce2Items() throws IOException { + mapReduceDriver.withAll(Arrays.asList( + new Pair(new LongWritable(0), new Text("hello")), + new Pair(new LongWritable(1), new Text("world")) + )); + mapReduceDriver.withAllOutput(Arrays.asList( + new Pair(new Text("world"), NullWritable.get()), + new Pair(new Text("hello"), NullWritable.get()) + )); + mapReduceDriver.runTest(); + } + + @Test + public void testMapReduce3Items() throws IOException { + mapReduceDriver.withAll(Arrays.asList( + new Pair(new LongWritable(0), new Text("hello")), + new Pair(new LongWritable(1), new Text("world")), + new Pair(new LongWritable(2), new Text("nadja")) + )); + mapReduceDriver.withAllOutput(Arrays.asList( + new Pair(new Text("nadja"), NullWritable.get()), + new Pair(new Text("world"), NullWritable.get()), + new Pair(new Text("hello"), NullWritable.get()) + )); + mapReduceDriver.runTest(); + } + + @Test + public void testMapReduce4Items() throws IOException { + mapReduceDriver.withAll(Arrays.asList( + new Pair(new LongWritable(0), new Text("hello")), + new Pair(new LongWritable(1), new Text("world")), + new Pair(new LongWritable(2), new Text("nadja")), + new Pair(new LongWritable(3), new Text("basti")) + )); + mapReduceDriver.withAllOutput(Arrays.asList( + new Pair(new Text("nadja"), NullWritable.get()), + new Pair(new Text("world"), NullWritable.get()), + new Pair(new Text("basti"), NullWritable.get()), + new Pair(new Text("hello"), NullWritable.get()) + )); + mapReduceDriver.runTest(); + } + +} \ No newline at end of file diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MRUnitBase.java b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MRUnitBase.java new file mode 100644 index 00000000000..6238c225748 --- /dev/null +++ b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MRUnitBase.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop; + +import java.io.File; +import java.io.IOException; + +import org.apache.commons.io.FileUtils; +import org.apache.hadoop.conf.Configuration; +import org.apache.solr.SolrTestCaseJ4; +import org.apache.solr.hadoop.morphline.MorphlineMapRunner; +import org.apache.solr.util.ExternalPaths; +import org.junit.AfterClass; +import org.junit.BeforeClass; + +public abstract class MRUnitBase extends SolrTestCaseJ4 { + + protected static final String RESOURCES_DIR = ExternalPaths.SOURCE_HOME + "/contrib/solr-mr/src/test-files"; + protected static final String DOCUMENTS_DIR = RESOURCES_DIR + "/test-documents"; + protected static File solrHomeZip; + + @BeforeClass + public static void setupClass() throws Exception { + solrHomeZip = SolrOutputFormat.createSolrHomeZip(new File(RESOURCES_DIR + "/solr/mrunit")); + assertNotNull(solrHomeZip); + } + + @AfterClass + public static void teardownClass() throws Exception { + solrHomeZip.delete(); + } + + protected void setupHadoopConfig(Configuration config) throws IOException { + config.set(SolrOutputFormat.ZIP_NAME, solrHomeZip.getName()); + + String tempDir = TEMP_DIR + "/test-morphlines-" + System.currentTimeMillis(); + new File(tempDir).mkdirs(); + FileUtils.copyFile(new File(RESOURCES_DIR + "/custom-mimetypes.xml"), new File(tempDir + "/custom-mimetypes.xml")); + + setupMorphline(tempDir, "test-morphlines/solrCellDocumentTypes"); + + config.set(MorphlineMapRunner.MORPHLINE_FILE_PARAM, tempDir + "/test-morphlines/solrCellDocumentTypes.conf"); + } + + public static void setupMorphline(String tempDir, String file) throws IOException { + String morphlineText = FileUtils.readFileToString(new File(RESOURCES_DIR + "/" + file + ".conf"), "UTF-8"); + morphlineText = morphlineText.replaceAll("RESOURCES_DIR", new File(tempDir).getAbsolutePath()); + morphlineText = morphlineText.replaceAll("\\$\\{SOLR_LOCATOR\\}", "{ collection : collection1 }"); + + FileUtils.writeStringToFile(new File(tempDir + "/" + file + ".conf"), morphlineText, "UTF-8"); + } +} diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MapReduceIndexerToolArgumentParserTest.java b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MapReduceIndexerToolArgumentParserTest.java new file mode 100644 index 00000000000..a292a1b0d39 --- /dev/null +++ b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MapReduceIndexerToolArgumentParserTest.java @@ -0,0 +1,463 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.PrintStream; +import java.io.UnsupportedEncodingException; +import java.util.Arrays; +import java.util.Collections; + +import org.apache.commons.io.FileUtils; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.Path; +import org.apache.lucene.util.LuceneTestCase; +import org.apache.solr.cloud.AbstractZkTestCase; +import org.apache.solr.hadoop.dedup.NoChangeUpdateConflictResolver; +import org.apache.solr.hadoop.dedup.RetainMostRecentUpdateConflictResolver; +import org.apache.solr.util.ExternalPaths; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MapReduceIndexerToolArgumentParserTest extends LuceneTestCase { + + private Configuration conf; + private MapReduceIndexerTool.MyArgumentParser parser; + private MapReduceIndexerTool.Options opts; + private PrintStream oldSystemOut; + private PrintStream oldSystemErr; + private ByteArrayOutputStream bout; + private ByteArrayOutputStream berr; + + private static final String RESOURCES_DIR = ExternalPaths.SOURCE_HOME + "/contrib/solr-mr/src/test-files"; + private static final File MINIMR_INSTANCE_DIR = new File(RESOURCES_DIR + "/solr/minimr"); + + private static final String MORPHLINE_FILE = RESOURCES_DIR + "/test-morphlines/solrCellDocumentTypes.conf"; + + private static final Logger LOG = LoggerFactory.getLogger(MapReduceIndexerToolArgumentParserTest.class); + + + private static final File solrHomeDirectory = new File(TEMP_DIR, MorphlineGoLiveMiniMRTest.class.getName()); + + @Before + public void setUp() throws Exception { + super.setUp(); + AbstractZkTestCase.SOLRHOME = solrHomeDirectory; + FileUtils.copyDirectory(MINIMR_INSTANCE_DIR, solrHomeDirectory); + + conf = new Configuration(); + parser = new MapReduceIndexerTool.MyArgumentParser(); + opts = new MapReduceIndexerTool.Options(); + oldSystemOut = System.out; + bout = new ByteArrayOutputStream(); + System.setOut(new PrintStream(bout, true, "UTF-8")); + oldSystemErr = System.err; + berr = new ByteArrayOutputStream(); + System.setErr(new PrintStream(berr, true, "UTF-8")); + } + + @After + public void tearDown() throws Exception { + super.tearDown(); + System.setOut(oldSystemOut); + System.setErr(oldSystemErr); + } + + @Test + public void testArgsParserTypicalUse() { + String[] args = new String[] { + "--input-list", "file:///tmp", + "--morphline-file", MORPHLINE_FILE, + "--morphline-id", "morphline_xyz", + "--output-dir", "file:/tmp/foo", + "--solr-home-dir", MINIMR_INSTANCE_DIR.getPath(), + "--mappers", "10", + "--reducers", "9", + "--fanout", "8", + "--max-segments", "7", + "--shards", "1", + "--verbose", + "file:///home", + "file:///dev", + }; + Integer res = parser.parseArgs(args, conf, opts); + assertNull(res != null ? res.toString() : "", res); + assertEquals(Collections.singletonList(new Path("file:///tmp")), opts.inputLists); + assertEquals(new Path("file:/tmp/foo"), opts.outputDir); + assertEquals(new File(MINIMR_INSTANCE_DIR.getPath()), opts.solrHomeDir); + assertEquals(10, opts.mappers); + assertEquals(9, opts.reducers); + assertEquals(8, opts.fanout); + assertEquals(7, opts.maxSegments); + assertEquals(new Integer(1), opts.shards); + assertEquals(null, opts.fairSchedulerPool); + assertTrue(opts.isVerbose); + assertEquals(Arrays.asList(new Path("file:///home"), new Path("file:///dev")), opts.inputFiles); + assertEquals(RetainMostRecentUpdateConflictResolver.class.getName(), opts.updateConflictResolver); + assertEquals(MORPHLINE_FILE, opts.morphlineFile.getPath()); + assertEquals("morphline_xyz", opts.morphlineId); + assertEmptySystemErrAndEmptySystemOut(); + } + + @Test + public void testArgsParserMultipleSpecsOfSameKind() { + String[] args = new String[] { + "--input-list", "file:///tmp", + "--input-list", "file:///", + "--morphline-file", MORPHLINE_FILE, + "--output-dir", "file:/tmp/foo", + "--solr-home-dir", MINIMR_INSTANCE_DIR.getPath(), + "--shards", "1", + "file:///home", + "file:///dev", + }; + assertNull(parser.parseArgs(args, conf, opts)); + assertEquals(Arrays.asList(new Path("file:///tmp"), new Path("file:///")), opts.inputLists); + assertEquals(Arrays.asList(new Path("file:///home"), new Path("file:///dev")), opts.inputFiles); + assertEquals(new Path("file:/tmp/foo"), opts.outputDir); + assertEquals(new File(MINIMR_INSTANCE_DIR.getPath()), opts.solrHomeDir); + assertEmptySystemErrAndEmptySystemOut(); + } + + @Test + public void testArgsParserTypicalUseWithEqualsSign() { + String[] args = new String[] { + "--input-list=file:///tmp", + "--morphline-file", MORPHLINE_FILE, + "--output-dir=file:/tmp/foo", + "--solr-home-dir=" + MINIMR_INSTANCE_DIR.getPath(), + "--mappers=10", + "--shards", "1", + "--verbose", + "file:///home", + "file:///dev", + }; + assertNull(parser.parseArgs(args, conf, opts)); + assertEquals(Collections.singletonList(new Path("file:///tmp")), opts.inputLists); + assertEquals(new Path("file:/tmp/foo"), opts.outputDir); + assertEquals(new File(MINIMR_INSTANCE_DIR.getPath()), opts.solrHomeDir); + assertEquals(10, opts.mappers); + assertEquals(new Integer(1), opts.shards); + assertEquals(null, opts.fairSchedulerPool); + assertTrue(opts.isVerbose); + assertEquals(Arrays.asList(new Path("file:///home"), new Path("file:///dev")), opts.inputFiles); + assertEmptySystemErrAndEmptySystemOut(); + } + + @Test + public void testArgsParserMultipleSpecsOfSameKindWithEqualsSign() { + String[] args = new String[] { + "--input-list=file:///tmp", + "--input-list=file:///", + "--morphline-file", MORPHLINE_FILE, + "--output-dir=file:/tmp/foo", + "--solr-home-dir=" + MINIMR_INSTANCE_DIR.getPath(), + "--shards", "1", + "file:///home", + "file:///dev", + }; + assertNull(parser.parseArgs(args, conf, opts)); + assertEquals(Arrays.asList(new Path("file:///tmp"), new Path("file:///")), opts.inputLists); + assertEquals(Arrays.asList(new Path("file:///home"), new Path("file:///dev")), opts.inputFiles); + assertEquals(new Path("file:/tmp/foo"), opts.outputDir); + assertEquals(new File(MINIMR_INSTANCE_DIR.getPath()), opts.solrHomeDir); + assertEmptySystemErrAndEmptySystemOut(); + } + + @Test + public void testArgsParserHelp() throws UnsupportedEncodingException { + String[] args = new String[] { "--help" }; + assertEquals(new Integer(0), parser.parseArgs(args, conf, opts)); + String helpText = new String(bout.toByteArray(), "UTF-8"); + assertTrue(helpText.contains("MapReduce batch job driver that ")); + assertTrue(helpText.contains("bin/hadoop command")); + assertEquals(0, berr.toByteArray().length); + } + + @Test + public void testArgsParserOk() { + String[] args = new String[] { + "--input-list", "file:///tmp", + "--morphline-file", MORPHLINE_FILE, + "--output-dir", "file:/tmp/foo", + "--solr-home-dir", MINIMR_INSTANCE_DIR.getPath(), + "--shards", "1", + }; + assertNull(parser.parseArgs(args, conf, opts)); + assertEquals(new Integer(1), opts.shards); + assertEmptySystemErrAndEmptySystemOut(); + } + + @Test + public void testArgsParserUpdateConflictResolver() { + String[] args = new String[] { + "--input-list", "file:///tmp", + "--morphline-file", MORPHLINE_FILE, + "--output-dir", "file:/tmp/foo", + "--solr-home-dir", MINIMR_INSTANCE_DIR.getPath(), + "--shards", "1", + "--update-conflict-resolver", NoChangeUpdateConflictResolver.class.getName(), + }; + assertNull(parser.parseArgs(args, conf, opts)); + assertEquals(NoChangeUpdateConflictResolver.class.getName(), opts.updateConflictResolver); + assertEmptySystemErrAndEmptySystemOut(); + } + + @Test + public void testArgsParserUnknownArgName() throws Exception { + String[] args = new String[] { + "--xxxxxxxxinputlist", "file:///tmp", + "--morphline-file", MORPHLINE_FILE, + "--output-dir", "file:/tmp/foo", + "--solr-home-dir", MINIMR_INSTANCE_DIR.getPath(), + "--shards", "1", + }; + assertArgumentParserException(args); + } + + @Test + public void testArgsParserFileNotFound1() throws Exception { + String[] args = new String[] { + "--input-list", "file:///tmp", + "--morphline-file", MORPHLINE_FILE, + "--output-dir", "file:/fileNotFound/foo", + "--solr-home-dir", MINIMR_INSTANCE_DIR.getPath(), + "--shards", "1", + }; + assertArgumentParserException(args); + } + + @Test + public void testArgsParserFileNotFound2() throws Exception { + String[] args = new String[] { + "--input-list", "file:///tmp", + "--morphline-file", MORPHLINE_FILE, + "--output-dir", "file:/tmp/foo", + "--solr-home-dir", "/fileNotFound", + "--shards", "1", + }; + assertArgumentParserException(args); + } + + @Test + public void testArgsParserIntOutOfRange() throws Exception { + String[] args = new String[] { + "--input-list", "file:///tmp", + "--morphline-file", MORPHLINE_FILE, + "--output-dir", "file:/tmp/foo", + "--solr-home-dir", MINIMR_INSTANCE_DIR.getPath(), + "--shards", "1", + "--mappers", "-20" + }; + assertArgumentParserException(args); + } + + @Test + public void testArgsParserIllegalFanout() throws Exception { + String[] args = new String[] { + "--input-list", "file:///tmp", + "--morphline-file", MORPHLINE_FILE, + "--output-dir", "file:/tmp/foo", + "--solr-home-dir", MINIMR_INSTANCE_DIR.getPath(), + "--shards", "1", + "--fanout", "1" // must be >= 2 + }; + assertArgumentParserException(args); + } + + @Test + public void testArgsParserSolrHomeMustContainSolrConfigFile() throws Exception { + String[] args = new String[] { + "--input-list", "file:///tmp", + "--morphline-file", MORPHLINE_FILE, + "--output-dir", "file:/tmp/foo", + "--shards", "1", + "--solr-home-dir", "/", + }; + assertArgumentParserException(args); + } + + @Test + public void testArgsShardUrlOk() { + String[] args = new String[] { + "--input-list", "file:///tmp", + "--morphline-file", MORPHLINE_FILE, + "--output-dir", "file:/tmp/foo", + "--solr-home-dir", MINIMR_INSTANCE_DIR.getPath(), + "--shard-url", "http://localhost:8983/solr/collection1", + "--shard-url", "http://localhost:8983/solr/collection2", + }; + assertNull(parser.parseArgs(args, conf, opts)); + assertEquals(Arrays.asList( + Collections.singletonList("http://localhost:8983/solr/collection1"), + Collections.singletonList("http://localhost:8983/solr/collection2")), + opts.shardUrls); + assertEquals(new Integer(2), opts.shards); + assertEmptySystemErrAndEmptySystemOut(); + } + + @Test + public void testArgsShardUrlMustHaveAParam() throws Exception { + String[] args = new String[] { + "--input-list", "file:///tmp", + "--morphline-file", MORPHLINE_FILE, + "--output-dir", "file:/tmp/foo", + "--solr-home-dir", MINIMR_INSTANCE_DIR.getPath(), + "--shard-url", + }; + assertArgumentParserException(args); + } + + @Test + public void testArgsShardUrlAndShardsSucceeds() { + String[] args = new String[] { + "--input-list", "file:///tmp", + "--morphline-file", MORPHLINE_FILE, + "--output-dir", "file:/tmp/foo", + "--solr-home-dir", MINIMR_INSTANCE_DIR.getPath(), + "--shards", "1", + "--shard-url", "http://localhost:8983/solr/collection1", + }; + assertNull(parser.parseArgs(args, conf, opts)); + assertEmptySystemErrAndEmptySystemOut(); + } + + @Test + public void testArgsShardUrlNoGoLive() { + String[] args = new String[] { + "--input-list", "file:///tmp", + "--morphline-file", MORPHLINE_FILE, + "--output-dir", "file:/tmp/foo", + "--solr-home-dir", MINIMR_INSTANCE_DIR.getPath(), + "--shard-url", "http://localhost:8983/solr/collection1" + }; + assertNull(parser.parseArgs(args, conf, opts)); + assertEmptySystemErrAndEmptySystemOut(); + assertEquals(new Integer(1), opts.shards); + } + + @Test + public void testArgsShardUrlsAndZkhostAreMutuallyExclusive() throws Exception { + String[] args = new String[] { + "--input-list", "file:///tmp", + "--morphline-file", MORPHLINE_FILE, + "--output-dir", "file:/tmp/foo", + "--solr-home-dir", MINIMR_INSTANCE_DIR.getPath(), + "--shard-url", "http://localhost:8983/solr/collection1", + "--shard-url", "http://localhost:8983/solr/collection1", + "--zk-host", "http://localhost:2185", + "--go-live" + }; + assertArgumentParserException(args); + } + + @Test + public void testArgsGoLiveAndSolrUrl() { + String[] args = new String[] { + "--input-list", "file:///tmp", + "--morphline-file", MORPHLINE_FILE, + "--output-dir", "file:/tmp/foo", + "--solr-home-dir", MINIMR_INSTANCE_DIR.getPath(), + "--shard-url", "http://localhost:8983/solr/collection1", + "--shard-url", "http://localhost:8983/solr/collection1", + "--go-live" + }; + Integer result = parser.parseArgs(args, conf, opts); + assertNull(result); + assertEmptySystemErrAndEmptySystemOut(); + } + + @Test + public void testArgsZkHostNoGoLive() throws Exception { + String[] args = new String[] { + "--input-list", "file:///tmp", + "--morphline-file", MORPHLINE_FILE, + "--output-dir", "file:/tmp/foo", + "--solr-home-dir", MINIMR_INSTANCE_DIR.getPath(), + "--zk-host", "http://localhost:2185", + }; + assertArgumentParserException(args); + } + + @Test + public void testArgsGoLiveZkHostNoCollection() throws Exception { + String[] args = new String[] { + "--input-list", "file:///tmp", + "--morphline-file", MORPHLINE_FILE, + "--output-dir", "file:/tmp/foo", + "--solr-home-dir", MINIMR_INSTANCE_DIR.getPath(), + "--zk-host", "http://localhost:2185", + "--go-live" + }; + assertArgumentParserException(args); + } + + @Test + public void testArgsGoLiveNoZkHostOrSolrUrl() throws Exception { + String[] args = new String[] { + "--input-list", "file:///tmp", + "--morphline-file", MORPHLINE_FILE, + "--output-dir", "file:/tmp/foo", + "--solr-home-dir", MINIMR_INSTANCE_DIR.getPath(), + "--go-live" + }; + assertArgumentParserException(args); + } + + @Test + public void testNoSolrHomeDirOrZKHost() throws Exception { + String[] args = new String[] { + "--input-list", "file:///tmp", + "--morphline-file", MORPHLINE_FILE, + "--output-dir", "file:/tmp/foo", + "--shards", "1", + }; + assertArgumentParserException(args); + } + + @Test + public void testZKHostNoSolrHomeDirOk() { + String[] args = new String[] { + "--input-list", "file:///tmp", + "--morphline-file", MORPHLINE_FILE, + "--output-dir", "file:/tmp/foo", + "--zk-host", "http://localhost:2185", + "--collection", "collection1", + }; + assertNull(parser.parseArgs(args, conf, opts)); + assertEmptySystemErrAndEmptySystemOut(); + } + + private void assertEmptySystemErrAndEmptySystemOut() { + assertEquals(0, bout.toByteArray().length); + assertEquals(0, berr.toByteArray().length); + } + + private void assertArgumentParserException(String[] args) throws UnsupportedEncodingException { + assertEquals("should have returned fail code", new Integer(1), parser.parseArgs(args, conf, opts)); + assertEquals("no sys out expected:" + new String(bout.toByteArray(), "UTF-8"), 0, bout.toByteArray().length); + String usageText; + usageText = new String(berr.toByteArray(), "UTF-8"); + + assertTrue("should start with usage msg \"usage: hadoop \":" + usageText, usageText.startsWith("usage: hadoop ")); + } + +} diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineBasicMiniMRTest.java b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineBasicMiniMRTest.java new file mode 100644 index 00000000000..49891290b0a --- /dev/null +++ b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineBasicMiniMRTest.java @@ -0,0 +1,401 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.lang.reflect.Array; +import java.util.Arrays; + +import org.apache.commons.io.FileUtils; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.FileSystem; +import org.apache.hadoop.fs.FileUtil; +import org.apache.hadoop.fs.Path; +import org.apache.hadoop.fs.permission.FsPermission; +import org.apache.hadoop.hdfs.MiniDFSCluster; +import org.apache.hadoop.mapred.JobConf; +import org.apache.hadoop.mapreduce.Job; +import org.apache.hadoop.security.authorize.ProxyUsers; +import org.apache.hadoop.util.JarFinder; +import org.apache.hadoop.util.ToolRunner; +import org.apache.hadoop.yarn.conf.YarnConfiguration; +import org.apache.lucene.util.LuceneTestCase; +import org.apache.lucene.util.LuceneTestCase.Slow; +import org.apache.solr.SolrTestCaseJ4; +import org.apache.solr.cloud.AbstractZkTestCase; +import org.apache.solr.hadoop.hack.MiniMRCluster; +import org.apache.solr.util.ExternalPaths; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; + +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakAction; +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakAction.Action; +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakLingering; +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope; +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope.Scope; +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakZombies; +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakZombies.Consequence; + +@ThreadLeakAction({Action.WARN}) +@ThreadLeakLingering(linger = 0) +@ThreadLeakZombies(Consequence.CONTINUE) +@ThreadLeakScope(Scope.NONE) +@Slow +public class MorphlineBasicMiniMRTest extends SolrTestCaseJ4 { + + private static final boolean ENABLE_LOCAL_JOB_RUNNER = false; // for debugging only + private static final String RESOURCES_DIR = ExternalPaths.SOURCE_HOME + "/contrib/solr-mr/src/test-files"; + private static final String DOCUMENTS_DIR = RESOURCES_DIR + "/test-documents"; + private static final File MINIMR_CONF_DIR = new File(RESOURCES_DIR + "/solr/minimr"); + + private static final String SEARCH_ARCHIVES_JAR = JarFinder.getJar(MapReduceIndexerTool.class); + + private static MiniDFSCluster dfsCluster = null; + private static MiniMRCluster mrCluster = null; + private static int numRuns = 0; + + private final String inputAvroFile; + private final int count; + + private static String tempDir; + + private static final File solrHomeDirectory = new File(TEMP_DIR, MorphlineBasicMiniMRTest.class.getName()); + + protected MapReduceIndexerTool createTool() { + return new MapReduceIndexerTool(); + } + + public MorphlineBasicMiniMRTest() { + int data = random().nextInt(3); + switch (data) { + case 0: + this.inputAvroFile = "sample-statuses-20120906-141433.avro"; + this.count = 2; + break; + case 1: + this.inputAvroFile = "sample-statuses-20120521-100919.avro"; + this.count = 20; + break; + case 2: + this.inputAvroFile = "sample-statuses-20120906-141433-medium.avro"; + this.count = 2104; + break; + default: + throw new RuntimeException("Test setup is broken"); + } + + } + + @BeforeClass + public static void setupClass() throws Exception { + LuceneTestCase.assumeTrue( + "Currently this test can only be run without the lucene test security policy in place", + System.getProperty("java.security.manager", "").equals("")); + + LuceneTestCase.assumeFalse("HDFS tests were disabled by -Dtests.disableHdfs", + Boolean.parseBoolean(System.getProperty("tests.disableHdfs", "false"))); + + AbstractZkTestCase.SOLRHOME = solrHomeDirectory; + FileUtils.copyDirectory(MINIMR_CONF_DIR, solrHomeDirectory); + + tempDir = TEMP_DIR + "/test-morphlines-" + System.currentTimeMillis(); + new File(tempDir).mkdirs(); + FileUtils.copyFile(new File(RESOURCES_DIR + "/custom-mimetypes.xml"), new File(tempDir + "/custom-mimetypes.xml")); + + MRUnitBase.setupMorphline(tempDir, "test-morphlines/solrCellDocumentTypes"); + + System.setProperty("hadoop.log.dir", new File(solrHomeDirectory, "logs").getAbsolutePath()); + + int taskTrackers = 1; + int dataNodes = 2; +// String proxyUser = System.getProperty("user.name"); +// String proxyGroup = "g"; +// StringBuilder sb = new StringBuilder(); +// sb.append("127.0.0.1,localhost"); +// for (InetAddress i : InetAddress.getAllByName(InetAddress.getLocalHost().getHostName())) { +// sb.append(",").append(i.getCanonicalHostName()); +// } + + createTempDir(); + new File(dataDir, "nm-local-dirs").mkdirs(); + + System.setProperty("solr.hdfs.blockcache.enabled", "false"); + + System.setProperty("test.build.dir", dataDir + File.separator + "hdfs" + File.separator + "test-build-dir"); + System.setProperty("test.build.data", dataDir + File.separator + "hdfs" + File.separator + "build"); + System.setProperty("test.cache.data", dataDir + File.separator + "hdfs" + File.separator + "cache"); + + JobConf conf = new JobConf(); + conf.set("dfs.block.access.token.enable", "false"); + conf.set("dfs.permissions", "true"); + conf.set("hadoop.security.authentication", "simple"); + conf.set(YarnConfiguration.NM_LOCAL_DIRS, dataDir.getPath() + File.separator + "nm-local-dirs"); + conf.set(YarnConfiguration.DEFAULT_NM_LOG_DIRS, dataDir + File.separator + "nm-logs"); + conf.set("testWorkDir", dataDir.getPath() + File.separator + "testWorkDir"); + + dfsCluster = new MiniDFSCluster(conf, dataNodes, true, null); + FileSystem fileSystem = dfsCluster.getFileSystem(); + fileSystem.mkdirs(new Path("/tmp")); + fileSystem.mkdirs(new Path("/user")); + fileSystem.mkdirs(new Path("/hadoop/mapred/system")); + fileSystem.setPermission(new Path("/tmp"), FsPermission.valueOf("-rwxrwxrwx")); + fileSystem.setPermission(new Path("/user"), FsPermission.valueOf("-rwxrwxrwx")); + fileSystem.setPermission(new Path("/hadoop/mapred/system"), FsPermission.valueOf("-rwx------")); + String nnURI = fileSystem.getUri().toString(); + int numDirs = 1; + String[] racks = null; + String[] hosts = null; + + mrCluster = new MiniMRCluster(0, 0, taskTrackers, nnURI, numDirs, racks, hosts, null, conf); + ProxyUsers.refreshSuperUserGroupsConfiguration(conf); + } + + @AfterClass + public static void teardownClass() throws Exception { + System.clearProperty("solr.hdfs.blockcache.enabled"); + System.clearProperty("test.build.dir"); + System.clearProperty("test.build.data"); + System.clearProperty("test.cache.data"); + if (mrCluster != null) { + mrCluster.shutdown(); + mrCluster = null; + } + if (dfsCluster != null) { + dfsCluster.shutdown(); + dfsCluster = null; + } + } + + @After + public void tearDown() throws Exception { + System.clearProperty("hadoop.log.dir"); + System.clearProperty("solr.hdfs.blockcache.enabled"); + + super.tearDown(); + } + + private JobConf getJobConf() { + return mrCluster.createJobConf(); + } + + @Test + public void testPathParts() throws Exception { // see PathParts + FileSystem fs = dfsCluster.getFileSystem(); + int dfsClusterPort = fs.getWorkingDirectory().toUri().getPort(); + assertTrue(dfsClusterPort > 0); + JobConf jobConf = getJobConf(); + Configuration simpleConf = new Configuration(); + + for (Configuration conf : Arrays.asList(jobConf, simpleConf)) { + for (String queryAndFragment : Arrays.asList("", "?key=value#fragment")) { + for (String up : Arrays.asList("", "../")) { + String down = up.length() == 0 ? "foo/" : ""; + String uploadURL = "hdfs://localhost:12345/user/foo/" + up + "bar.txt" + queryAndFragment; + PathParts parts = new PathParts(uploadURL, conf); + assertEquals(uploadURL, parts.getUploadURL()); + assertEquals("/user/" + down + "bar.txt", parts.getURIPath()); + assertEquals("bar.txt", parts.getName()); + assertEquals("hdfs", parts.getScheme()); + assertEquals("localhost", parts.getHost()); + assertEquals(12345, parts.getPort()); + assertEquals("hdfs://localhost:12345/user/" + down + "bar.txt", parts.getId()); + assertEquals(parts.getId(), parts.getDownloadURL()); + assertFileNotFound(parts); + + uploadURL = "hdfs://localhost/user/foo/" + up + "bar.txt" + queryAndFragment; + parts = new PathParts(uploadURL, conf); + assertEquals(uploadURL, parts.getUploadURL()); + assertEquals("/user/" + down + "bar.txt", parts.getURIPath()); + assertEquals("bar.txt", parts.getName()); + assertEquals("hdfs", parts.getScheme()); + assertEquals("localhost", parts.getHost()); + assertEquals(8020, parts.getPort()); + assertEquals("hdfs://localhost:8020/user/" + down + "bar.txt", parts.getId()); + assertEquals(parts.getId(), parts.getDownloadURL()); + assertFileNotFound(parts); + } + } + } + + for (Configuration conf : Arrays.asList(jobConf)) { + for (String queryAndFragment : Arrays.asList("", "?key=value#fragment")) { + for (String up : Arrays.asList("", "../")) { + // verify using absolute path + String down = up.length() == 0 ? "foo/" : ""; + String uploadURL = "/user/foo/" + up + "bar.txt" + queryAndFragment; + PathParts parts = new PathParts(uploadURL, conf); + assertEquals(uploadURL, parts.getUploadURL()); + assertEquals("/user/" + down + "bar.txt", parts.getURIPath()); + assertEquals("bar.txt", parts.getName()); + assertEquals("hdfs", parts.getScheme()); + assertTrue("localhost".equals(parts.getHost()) || "localhost.localdomain".equals(parts.getHost())); + assertEquals(dfsClusterPort, parts.getPort()); + assertTrue(parts.getId().equals("hdfs://localhost:" + dfsClusterPort + "/user/" + down + "bar.txt") + || parts.getId().equals("hdfs://localhost.localdomain:" + dfsClusterPort + "/user/" + down + "bar.txt") + ); + assertFileNotFound(parts); + + // verify relative path is interpreted to be relative to user's home dir and resolved to an absolute path + uploadURL = "xuser/foo/" + up + "bar.txt" + queryAndFragment; + parts = new PathParts(uploadURL, conf); + assertEquals(uploadURL, parts.getUploadURL()); + String homeDir = "/user/" + System.getProperty("user.name"); + assertEquals(homeDir + "/xuser/" + down + "bar.txt", parts.getURIPath()); + assertEquals("bar.txt", parts.getName()); + assertEquals("hdfs", parts.getScheme()); + assertTrue("localhost".equals(parts.getHost()) || "localhost.localdomain".equals(parts.getHost())); + assertEquals(dfsClusterPort, parts.getPort()); + assertTrue(parts.getId().equals("hdfs://localhost:" + dfsClusterPort + homeDir + "/xuser/" + down + "bar.txt") + || parts.getId().equals("hdfs://localhost.localdomain:" + dfsClusterPort + homeDir + "/xuser/" + down + "bar.txt") + ); + assertFileNotFound(parts); + } + } + } + + try { + new PathParts("/user/foo/bar.txt", simpleConf); + fail("host/port resolution requires minimr conf, not a simple conf"); + } catch (IllegalArgumentException e) { + ; // expected + } + } + + private void assertFileNotFound(PathParts parts) { + try { + parts.getFileSystem().getFileStatus(parts.getUploadPath()); + fail(); + } catch (IOException e) { + ; // expected + } + } + + @Test + public void mrRun() throws Exception { + FileSystem fs = dfsCluster.getFileSystem(); + Path inDir = fs.makeQualified(new Path("/user/testing/testMapperReducer/input")); + fs.delete(inDir, true); + String DATADIR = "/user/testing/testMapperReducer/data"; + Path dataDir = fs.makeQualified(new Path(DATADIR)); + fs.delete(dataDir, true); + Path outDir = fs.makeQualified(new Path("/user/testing/testMapperReducer/output")); + fs.delete(outDir, true); + + assertTrue(fs.mkdirs(inDir)); + Path INPATH = new Path(inDir, "input.txt"); + OutputStream os = fs.create(INPATH); + Writer wr = new OutputStreamWriter(os, "UTF-8"); + wr.write(DATADIR + "/" + inputAvroFile); + wr.close(); + + assertTrue(fs.mkdirs(dataDir)); + fs.copyFromLocalFile(new Path(DOCUMENTS_DIR, inputAvroFile), dataDir); + + JobConf jobConf = getJobConf(); + if (ENABLE_LOCAL_JOB_RUNNER) { // enable Hadoop LocalJobRunner; this enables to run in debugger and set breakpoints + jobConf.set("mapred.job.tracker", "local"); + } + jobConf.setMaxMapAttempts(1); + jobConf.setMaxReduceAttempts(1); + jobConf.setJar(SEARCH_ARCHIVES_JAR); + jobConf.setBoolean("ignoreTikaException", false); + + int shards = 2; + int maxReducers = Integer.MAX_VALUE; + if (ENABLE_LOCAL_JOB_RUNNER) { + // local job runner has a couple of limitations: only one reducer is supported and the DistributedCache doesn't work. + // see http://blog.cloudera.com/blog/2009/07/advice-on-qa-testing-your-mapreduce-jobs/ + maxReducers = 1; + shards = 1; + } + + String[] args = new String[] { + "--morphline-file=" + tempDir + "/test-morphlines/solrCellDocumentTypes.conf", + "--morphline-id=morphline1", + "--solr-home-dir=" + MINIMR_CONF_DIR.getAbsolutePath(), + "--output-dir=" + outDir.toString(), + "--shards=" + shards, + "--verbose", + numRuns % 2 == 0 ? "--input-list=" + INPATH.toString() : dataDir.toString(), + numRuns % 3 == 0 ? "--reducers=" + shards : (numRuns % 3 == 1 ? "--reducers=-1" : "--reducers=" + Math.min(8, maxReducers)) + }; + if (numRuns % 3 == 2) { + args = concat(args, new String[] {"--fanout=2"}); + } + if (numRuns == 0) { + // force (slow) MapReduce based randomization to get coverage for that as well + args = concat(new String[] {"-D", MapReduceIndexerTool.MAIN_MEMORY_RANDOMIZATION_THRESHOLD + "=-1"}, args); + } + MapReduceIndexerTool tool = createTool(); + int res = ToolRunner.run(jobConf, tool, args); + assertEquals(0, res); + Job job = tool.job; + assertTrue(job.isComplete()); + assertTrue(job.isSuccessful()); + + if (numRuns % 3 != 2) { + // Only run this check if mtree merge is disabled. + // With mtree merge enabled the BatchWriter counters aren't available anymore because + // variable "job" now refers to the merge job rather than the indexing job + assertEquals("Invalid counter " + SolrRecordWriter.class.getName() + "." + SolrCounters.DOCUMENTS_WRITTEN, + count, job.getCounters().findCounter(SolrCounters.class.getName(), SolrCounters.DOCUMENTS_WRITTEN.toString()).getValue()); + } + + // Check the output is as expected + outDir = new Path(outDir, MapReduceIndexerTool.RESULTS_DIR); + Path[] outputFiles = FileUtil.stat2Paths(fs.listStatus(outDir)); + + System.out.println("outputfiles:" + Arrays.toString(outputFiles)); + + UtilsForTests.validateSolrServerDocumentCount(MINIMR_CONF_DIR, fs, outDir, count, shards); + + // run again with --dryrun mode: + tool = createTool(); + args = concat(args, new String[] {"--dry-run"}); + res = ToolRunner.run(jobConf, tool, args); + assertEquals(0, res); + + numRuns++; + } + + protected static T[] concat(T[]... arrays) { + if (arrays.length <= 0) { + throw new IllegalArgumentException(); + } + Class clazz = null; + int length = 0; + for (T[] array : arrays) { + clazz = array.getClass(); + length += array.length; + } + T[] result = (T[]) Array.newInstance(clazz.getComponentType(), length); + int pos = 0; + for (T[] array : arrays) { + System.arraycopy(array, 0, result, pos, array.length); + pos += array.length; + } + return result; + } + +} diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineGoLiveMiniMRTest.java b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineGoLiveMiniMRTest.java new file mode 100644 index 00000000000..32f24980fa0 --- /dev/null +++ b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineGoLiveMiniMRTest.java @@ -0,0 +1,730 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.UnsupportedEncodingException; +import java.io.Writer; +import java.lang.reflect.Array; +import java.net.URI; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.commons.io.FileUtils; +import org.apache.hadoop.fs.FileSystem; +import org.apache.hadoop.fs.Path; +import org.apache.hadoop.fs.permission.FsPermission; +import org.apache.hadoop.hdfs.MiniDFSCluster; +import org.apache.hadoop.mapred.JobConf; +import org.apache.hadoop.mapreduce.Job; +import org.apache.hadoop.security.authorize.ProxyUsers; +import org.apache.hadoop.util.JarFinder; +import org.apache.hadoop.util.ToolRunner; +import org.apache.hadoop.yarn.conf.YarnConfiguration; +import org.apache.lucene.util.LuceneTestCase; +import org.apache.lucene.util.LuceneTestCase.Slow; +import org.apache.lucene.util.LuceneTestCase.SuppressCodecs; +import org.apache.solr.client.solrj.SolrQuery; +import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.client.solrj.embedded.JettySolrRunner; +import org.apache.solr.client.solrj.impl.HttpSolrServer; +import org.apache.solr.client.solrj.request.QueryRequest; +import org.apache.solr.client.solrj.response.QueryResponse; +import org.apache.solr.cloud.AbstractFullDistribZkTestBase; +import org.apache.solr.cloud.AbstractZkTestCase; +import org.apache.solr.common.cloud.Replica; +import org.apache.solr.common.cloud.Slice; +import org.apache.solr.common.cloud.SolrZkClient; +import org.apache.solr.common.cloud.ZkCoreNodeProps; +import org.apache.solr.common.params.CollectionParams.CollectionAction; +import org.apache.solr.common.params.ModifiableSolrParams; +import org.apache.solr.common.util.NamedList; +import org.apache.solr.hadoop.hack.MiniMRClientCluster; +import org.apache.solr.hadoop.hack.MiniMRClientClusterFactory; +import org.apache.solr.util.ExternalPaths; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; + +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakAction; +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakAction.Action; +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakLingering; +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope; +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope.Scope; +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakZombies; +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakZombies.Consequence; + +@ThreadLeakAction({Action.WARN}) +@ThreadLeakLingering(linger = 0) +@ThreadLeakZombies(Consequence.CONTINUE) +@ThreadLeakScope(Scope.NONE) +@SuppressCodecs({"Lucene3x", "Lucene40"}) +@Slow +public class MorphlineGoLiveMiniMRTest extends AbstractFullDistribZkTestBase { + + private static final String RESOURCES_DIR = ExternalPaths.SOURCE_HOME + "/contrib/solr-mr/src/test-files"; + private static final String DOCUMENTS_DIR = RESOURCES_DIR + "/test-documents"; + private static final File MINIMR_INSTANCE_DIR = new File(RESOURCES_DIR + "/solr/minimr"); + private static final File MINIMR_CONF_DIR = new File(RESOURCES_DIR + "/solr/minimr"); + + private static final String SEARCH_ARCHIVES_JAR = JarFinder.getJar(MapReduceIndexerTool.class); + + private static MiniDFSCluster dfsCluster = null; + private static MiniMRClientCluster mrCluster = null; + private static int numRuns = 0; + private static String tempDir; + + private final String inputAvroFile1; + private final String inputAvroFile2; + private final String inputAvroFile3; + + private static final File solrHomeDirectory = new File(TEMP_DIR, MorphlineGoLiveMiniMRTest.class.getName()); + + @Override + public String getSolrHome() { + return solrHomeDirectory.getPath(); + } + + public MorphlineGoLiveMiniMRTest() { + this.inputAvroFile1 = "sample-statuses-20120521-100919.avro"; + this.inputAvroFile2 = "sample-statuses-20120906-141433.avro"; + this.inputAvroFile3 = "sample-statuses-20120906-141433-medium.avro"; + + fixShardCount = true; + sliceCount = TEST_NIGHTLY ? 3 : 3; + shardCount = TEST_NIGHTLY ? 3 : 3; + } + + private static boolean isYarn() { + try { + Job.class.getMethod("getCluster"); + return true; + } catch (NoSuchMethodException e) { + return false; + } + } + + @BeforeClass + public static void setupClass() throws Exception { + LuceneTestCase.assumeTrue( + "Currently this test can only be run without the lucene test security policy in place", + System.getProperty("java.security.manager", "").equals("")); + + LuceneTestCase.assumeFalse("HDFS tests were disabled by -Dtests.disableHdfs", + Boolean.parseBoolean(System.getProperty("tests.disableHdfs", "false"))); + + AbstractZkTestCase.SOLRHOME = solrHomeDirectory; + FileUtils.copyDirectory(MINIMR_INSTANCE_DIR, solrHomeDirectory); + + tempDir = TEMP_DIR + "/test-morphlines-" + System.currentTimeMillis(); + new File(tempDir).mkdirs(); + FileUtils.copyFile(new File(RESOURCES_DIR + "/custom-mimetypes.xml"), new File(tempDir + "/custom-mimetypes.xml")); + + MRUnitBase.setupMorphline(tempDir, "test-morphlines/solrCellDocumentTypes"); + + + System.setProperty("hadoop.log.dir", new File(dataDir, "logs").getAbsolutePath()); + + int taskTrackers = 2; + int dataNodes = 2; + + System.setProperty("solr.hdfs.blockcache.enabled", "false"); + + JobConf conf = new JobConf(); + conf.set("dfs.block.access.token.enable", "false"); + conf.set("dfs.permissions", "true"); + conf.set("hadoop.security.authentication", "simple"); + + conf.set(YarnConfiguration.NM_LOCAL_DIRS, dataDir + File.separator + "nm-local-dirs"); + conf.set(YarnConfiguration.DEFAULT_NM_LOG_DIRS, dataDir + File.separator + "nm-logs"); + + + createTempDir(); + new File(dataDir + File.separator + "nm-local-dirs").mkdirs(); + + System.setProperty("test.build.dir", dataDir + File.separator + "hdfs" + File.separator + "test-build-dir"); + System.setProperty("test.build.data", dataDir + File.separator + "hdfs" + File.separator + "build"); + System.setProperty("test.cache.data", dataDir + File.separator + "hdfs" + File.separator + "cache"); + + dfsCluster = new MiniDFSCluster(conf, dataNodes, true, null); + FileSystem fileSystem = dfsCluster.getFileSystem(); + fileSystem.mkdirs(new Path("/tmp")); + fileSystem.mkdirs(new Path("/user")); + fileSystem.mkdirs(new Path("/hadoop/mapred/system")); + fileSystem.setPermission(new Path("/tmp"), + FsPermission.valueOf("-rwxrwxrwx")); + fileSystem.setPermission(new Path("/user"), + FsPermission.valueOf("-rwxrwxrwx")); + fileSystem.setPermission(new Path("/hadoop/mapred/system"), + FsPermission.valueOf("-rwx------")); + + mrCluster = MiniMRClientClusterFactory.create(MorphlineGoLiveMiniMRTest.class, 1, conf, new File(dataDir, "mrCluster")); + + //new MiniMRCluster(0, 0, taskTrackers, nnURI, numDirs, racks, + //hosts, null, conf); + + ProxyUsers.refreshSuperUserGroupsConfiguration(conf); + } + + @Override + @Before + public void setUp() throws Exception { + super.setUp(); + System.setProperty("host", "127.0.0.1"); + System.setProperty("numShards", Integer.toString(sliceCount)); + URI uri = dfsCluster.getFileSystem().getUri(); + System.setProperty("solr.hdfs.home", uri.toString() + "/" + this.getClass().getName()); + uploadConfFiles(); + } + + @Override + @After + public void tearDown() throws Exception { + super.tearDown(); + System.clearProperty("host"); + System.clearProperty("numShards"); + System.clearProperty("solr.hdfs.home"); + } + + @AfterClass + public static void teardownClass() throws Exception { + System.clearProperty("solr.hdfs.blockcache.enabled"); + System.clearProperty("hadoop.log.dir"); + System.clearProperty("test.build.dir"); + System.clearProperty("test.build.data"); + System.clearProperty("test.cache.data"); + + if (mrCluster != null) { + //mrCluster.shutdown(); + mrCluster = null; + } + if (dfsCluster != null) { + dfsCluster.shutdown(); + dfsCluster = null; + } + FileSystem.closeAll(); + } + + private JobConf getJobConf() throws IOException { + JobConf jobConf = new JobConf(mrCluster.getConfig()); + return jobConf; + } + + @Test + @Override + public void testDistribSearch() throws Exception { + super.testDistribSearch(); + } + + @Test + public void testBuildShardUrls() throws Exception { + // 2x3 + Integer numShards = 2; + List urls = new ArrayList(); + urls.add("shard1"); + urls.add("shard2"); + urls.add("shard3"); + urls.add("shard4"); + urls.add("shard5"); + urls.add("shard6"); + List> shardUrls = MapReduceIndexerTool.buildShardUrls(urls , numShards); + + assertEquals(shardUrls.toString(), 2, shardUrls.size()); + + for (List u : shardUrls) { + assertEquals(3, u.size()); + } + + // 1x6 + numShards = 1; + shardUrls = MapReduceIndexerTool.buildShardUrls(urls , numShards); + + assertEquals(shardUrls.toString(), 1, shardUrls.size()); + + for (List u : shardUrls) { + assertEquals(6, u.size()); + } + + // 6x1 + numShards = 6; + shardUrls = MapReduceIndexerTool.buildShardUrls(urls , numShards); + + assertEquals(shardUrls.toString(), 6, shardUrls.size()); + + for (List u : shardUrls) { + assertEquals(1, u.size()); + } + + // 3x2 + numShards = 3; + shardUrls = MapReduceIndexerTool.buildShardUrls(urls , numShards); + + assertEquals(shardUrls.toString(), 3, shardUrls.size()); + + for (List u : shardUrls) { + assertEquals(2, u.size()); + } + + // null shards, 6x1 + numShards = null; + shardUrls = MapReduceIndexerTool.buildShardUrls(urls , numShards); + + assertEquals(shardUrls.toString(), 6, shardUrls.size()); + + for (List u : shardUrls) { + assertEquals(1, u.size()); + } + + // null shards 3x1 + numShards = null; + + urls = new ArrayList(); + urls.add("shard1"); + urls.add("shard2"); + urls.add("shard3"); + + shardUrls = MapReduceIndexerTool.buildShardUrls(urls , numShards); + + assertEquals(shardUrls.toString(), 3, shardUrls.size()); + + for (List u : shardUrls) { + assertEquals(1, u.size()); + } + + // 2x(2,3) off balance + numShards = 2; + urls = new ArrayList(); + urls.add("shard1"); + urls.add("shard2"); + urls.add("shard3"); + urls.add("shard4"); + urls.add("shard5"); + shardUrls = MapReduceIndexerTool.buildShardUrls(urls , numShards); + + assertEquals(shardUrls.toString(), 2, shardUrls.size()); + + Set counts = new HashSet(); + counts.add(shardUrls.get(0).size()); + counts.add(shardUrls.get(1).size()); + + assertTrue(counts.contains(2)); + assertTrue(counts.contains(3)); + } + + private String[] prependInitialArgs(String[] args) { + String[] head = new String[] { + "--morphline-file=" + tempDir + "/test-morphlines/solrCellDocumentTypes.conf", + "--morphline-id=morphline1", + }; + return concat(head, args); + } + + @Override + public void doTest() throws Exception { + + waitForRecoveriesToFinish(false); + + FileSystem fs = dfsCluster.getFileSystem(); + Path inDir = fs.makeQualified(new Path( + "/user/testing/testMapperReducer/input")); + fs.delete(inDir, true); + String DATADIR = "/user/testing/testMapperReducer/data"; + Path dataDir = fs.makeQualified(new Path(DATADIR)); + fs.delete(dataDir, true); + Path outDir = fs.makeQualified(new Path( + "/user/testing/testMapperReducer/output")); + fs.delete(outDir, true); + + assertTrue(fs.mkdirs(inDir)); + Path INPATH = upAvroFile(fs, inDir, DATADIR, dataDir, inputAvroFile1); + + JobConf jobConf = getJobConf(); + // enable mapred.job.tracker = local to run in debugger and set breakpoints + // jobConf.set("mapred.job.tracker", "local"); + jobConf.setMaxMapAttempts(1); + jobConf.setMaxReduceAttempts(1); + jobConf.setJar(SEARCH_ARCHIVES_JAR); + jobConf.setBoolean("ignoreTikaException", false); + + MapReduceIndexerTool tool; + int res; + QueryResponse results; + HttpSolrServer server = new HttpSolrServer(cloudJettys.get(0).url); + String[] args = new String[]{}; + + args = new String[] { + "--solr-home-dir=" + MINIMR_CONF_DIR.getAbsolutePath(), + "--output-dir=" + outDir.toString(), + "--log4j=" + ExternalPaths.SOURCE_HOME + "/core/src/test-files/log4j.properties", + "--mappers=3", + ++numRuns % 2 == 0 ? "--input-list=" + INPATH.toString() : dataDir.toString(), + "--go-live-threads", Integer.toString(random().nextInt(15) + 1), + "--verbose", + "--go-live" + }; + args = prependInitialArgs(args); + List argList = new ArrayList(); + getShardUrlArgs(argList); + args = concat(args, argList.toArray(new String[0])); + + if (true) { + tool = new MapReduceIndexerTool(); + + res = ToolRunner.run(jobConf, tool, args); + + assertEquals(0, res); + assertTrue(tool.job.isComplete()); + assertTrue(tool.job.isSuccessful()); + results = server.query(new SolrQuery("*:*")); + assertEquals(20, results.getResults().getNumFound()); + } + + fs.delete(inDir, true); + fs.delete(outDir, true); + fs.delete(dataDir, true); + assertTrue(fs.mkdirs(inDir)); + INPATH = upAvroFile(fs, inDir, DATADIR, dataDir, inputAvroFile2); + + args = new String[] { + "--solr-home-dir=" + MINIMR_CONF_DIR.getAbsolutePath(), + "--output-dir=" + outDir.toString(), + "--mappers=3", + "--verbose", + "--go-live", + ++numRuns % 2 == 0 ? "--input-list=" + INPATH.toString() : dataDir.toString(), + "--go-live-threads", Integer.toString(random().nextInt(15) + 1) + }; + args = prependInitialArgs(args); + argList = new ArrayList(); + getShardUrlArgs(argList); + args = concat(args, argList.toArray(new String[0])); + + if (true) { + tool = new MapReduceIndexerTool(); + res = ToolRunner.run(jobConf, tool, args); + assertEquals(0, res); + assertTrue(tool.job.isComplete()); + assertTrue(tool.job.isSuccessful()); + results = server.query(new SolrQuery("*:*")); + + assertEquals(22, results.getResults().getNumFound()); + } + + // try using zookeeper + String collection = "collection1"; + if (random().nextBoolean()) { + // sometimes, use an alias + createAlias("updatealias", "collection1"); + collection = "updatealias"; + } + + fs.delete(inDir, true); + fs.delete(outDir, true); + fs.delete(dataDir, true); + INPATH = upAvroFile(fs, inDir, DATADIR, dataDir, inputAvroFile3); + + args = new String[] { + "--output-dir=" + outDir.toString(), + "--mappers=3", + "--reducers=6", + "--verbose", + "--go-live", + ++numRuns % 2 == 0 ? "--input-list=" + INPATH.toString() : dataDir.toString(), + "--zk-host", zkServer.getZkAddress(), + "--collection", collection + }; + args = prependInitialArgs(args); + + if (true) { + tool = new MapReduceIndexerTool(); + res = ToolRunner.run(jobConf, tool, args); + assertEquals(0, res); + assertTrue(tool.job.isComplete()); + assertTrue(tool.job.isSuccessful()); + + results = server.query(new SolrQuery("*:*")); + assertEquals(2126, results.getResults().getNumFound()); + } + + server.shutdown(); + + // try using zookeeper with replication + String replicatedCollection = "replicated_collection"; + createCollection(replicatedCollection, 2, 3, 2); + waitForRecoveriesToFinish(false); + cloudClient.setDefaultCollection(replicatedCollection); + fs.delete(inDir, true); + fs.delete(outDir, true); + fs.delete(dataDir, true); + assertTrue(fs.mkdirs(dataDir)); + INPATH = upAvroFile(fs, inDir, DATADIR, dataDir, inputAvroFile3); + + args = new String[] { + "--solr-home-dir=" + MINIMR_CONF_DIR.getAbsolutePath(), + "--output-dir=" + outDir.toString(), + "--mappers=3", + "--reducers=6", + "--verbose", + "--go-live", + "--zk-host", zkServer.getZkAddress(), + "--collection", replicatedCollection, dataDir.toString() + }; + args = prependInitialArgs(args); + + if (true) { + tool = new MapReduceIndexerTool(); + res = ToolRunner.run(jobConf, tool, args); + assertEquals(0, res); + assertTrue(tool.job.isComplete()); + assertTrue(tool.job.isSuccessful()); + + results = cloudClient.query(new SolrQuery("*:*")); + assertEquals(2104, results.getResults().getNumFound()); + + checkConsistency(replicatedCollection); + } + + // try using solr_url with replication + cloudClient.deleteByQuery("*:*"); + cloudClient.commit(); + fs.delete(inDir, true); + fs.delete(dataDir, true); + assertTrue(fs.mkdirs(dataDir)); + INPATH = upAvroFile(fs, inDir, DATADIR, dataDir, inputAvroFile3); + + args = new String[] { + "--solr-home-dir=" + MINIMR_CONF_DIR.getAbsolutePath(), + "--output-dir=" + outDir.toString(), + "--shards", "2", + "--mappers=3", + "--verbose", + "--go-live", + "--go-live-threads", Integer.toString(random().nextInt(15) + 1), dataDir.toString() + }; + args = prependInitialArgs(args); + + argList = new ArrayList(); + getShardUrlArgs(argList, replicatedCollection); + args = concat(args, argList.toArray(new String[0])); + + if (true) { + tool = new MapReduceIndexerTool(); + res = ToolRunner.run(jobConf, tool, args); + assertEquals(0, res); + assertTrue(tool.job.isComplete()); + assertTrue(tool.job.isSuccessful()); + + checkConsistency(replicatedCollection); + + results = cloudClient.query(new SolrQuery("*:*")); + assertEquals(2104, results.getResults().getNumFound()); + } + + } + + private void getShardUrlArgs(List args) { + for (int i = 0; i < shardCount; i++) { + args.add("--shard-url"); + args.add(cloudJettys.get(i).url); + } + } + + private void checkConsistency(String replicatedCollection) + throws SolrServerException { + Collection slices = cloudClient.getZkStateReader().getClusterState() + .getSlices(replicatedCollection); + for (Slice slice : slices) { + Collection replicas = slice.getReplicas(); + long found = -1; + for (Replica replica : replicas) { + HttpSolrServer client = new HttpSolrServer( + new ZkCoreNodeProps(replica).getCoreUrl()); + SolrQuery query = new SolrQuery("*:*"); + query.set("distrib", false); + QueryResponse replicaResults = client.query(query); + long count = replicaResults.getResults().getNumFound(); + if (found != -1) { + assertEquals(slice.getName() + " is inconsistent " + + new ZkCoreNodeProps(replica).getCoreUrl(), found, count); + } + found = count; + } + } + } + + private void getShardUrlArgs(List args, String replicatedCollection) { + Collection slices = cloudClient.getZkStateReader().getClusterState().getSlices(replicatedCollection); + for (Slice slice : slices) { + Collection replicas = slice.getReplicas(); + for (Replica replica : replicas) { + args.add("--shard-url"); + args.add(new ZkCoreNodeProps(replica).getCoreUrl()); + } + } + } + + private Path upAvroFile(FileSystem fs, Path inDir, String DATADIR, + Path dataDir, String localFile) throws IOException, UnsupportedEncodingException { + Path INPATH = new Path(inDir, "input.txt"); + OutputStream os = fs.create(INPATH); + Writer wr = new OutputStreamWriter(os, "UTF-8"); + wr.write(DATADIR + File.separator + localFile); + wr.close(); + + assertTrue(fs.mkdirs(dataDir)); + fs.copyFromLocalFile(new Path(DOCUMENTS_DIR, localFile), dataDir); + return INPATH; + } + + @Override + public JettySolrRunner createJetty(File solrHome, String dataDir, + String shardList, String solrConfigOverride, String schemaOverride) + throws Exception { + + JettySolrRunner jetty = new JettySolrRunner(solrHome.getAbsolutePath(), + context, 0, solrConfigOverride, schemaOverride); + + jetty.setShards(shardList); + + if (System.getProperty("collection") == null) { + System.setProperty("collection", "collection1"); + } + + jetty.start(); + + System.clearProperty("collection"); + + return jetty; + } + + private static void putConfig(SolrZkClient zkClient, File solrhome, String name) throws Exception { + putConfig(zkClient, solrhome, name, name); + } + + private static void putConfig(SolrZkClient zkClient, File solrhome, String srcName, String destName) + throws Exception { + + File file = new File(solrhome, "conf" + File.separator + srcName); + if (!file.exists()) { + // LOG.info("skipping " + file.getAbsolutePath() + + // " because it doesn't exist"); + return; + } + + String destPath = "/configs/conf1/" + destName; + // LOG.info("put " + file.getAbsolutePath() + " to " + destPath); + zkClient.makePath(destPath, file, false, true); + } + + private void uploadConfFiles() throws Exception { + // upload our own config files + SolrZkClient zkClient = new SolrZkClient(zkServer.getZkAddress(), 10000); + putConfig(zkClient, new File(RESOURCES_DIR + "/solr/solrcloud"), + "solrconfig.xml"); + putConfig(zkClient, MINIMR_CONF_DIR, "schema.xml"); + putConfig(zkClient, MINIMR_CONF_DIR, "elevate.xml"); + putConfig(zkClient, MINIMR_CONF_DIR, "lang/stopwords_en.txt"); + putConfig(zkClient, MINIMR_CONF_DIR, "lang/stopwords_ar.txt"); + + putConfig(zkClient, MINIMR_CONF_DIR, "lang/stopwords_bg.txt"); + putConfig(zkClient, MINIMR_CONF_DIR, "lang/stopwords_ca.txt"); + putConfig(zkClient, MINIMR_CONF_DIR, "lang/stopwords_cz.txt"); + putConfig(zkClient, MINIMR_CONF_DIR, "lang/stopwords_da.txt"); + putConfig(zkClient, MINIMR_CONF_DIR, "lang/stopwords_el.txt"); + putConfig(zkClient, MINIMR_CONF_DIR, "lang/stopwords_es.txt"); + putConfig(zkClient, MINIMR_CONF_DIR, "lang/stopwords_eu.txt"); + putConfig(zkClient, MINIMR_CONF_DIR, "lang/stopwords_de.txt"); + putConfig(zkClient, MINIMR_CONF_DIR, "lang/stopwords_fa.txt"); + putConfig(zkClient, MINIMR_CONF_DIR, "lang/stopwords_fi.txt"); + putConfig(zkClient, MINIMR_CONF_DIR, "lang/stopwords_fr.txt"); + putConfig(zkClient, MINIMR_CONF_DIR, "lang/stopwords_ga.txt"); + putConfig(zkClient, MINIMR_CONF_DIR, "lang/stopwords_gl.txt"); + putConfig(zkClient, MINIMR_CONF_DIR, "lang/stopwords_hi.txt"); + putConfig(zkClient, MINIMR_CONF_DIR, "lang/stopwords_hu.txt"); + putConfig(zkClient, MINIMR_CONF_DIR, "lang/stopwords_hy.txt"); + putConfig(zkClient, MINIMR_CONF_DIR, "lang/stopwords_id.txt"); + putConfig(zkClient, MINIMR_CONF_DIR, "lang/stopwords_it.txt"); + putConfig(zkClient, MINIMR_CONF_DIR, "lang/stopwords_ja.txt"); + putConfig(zkClient, MINIMR_CONF_DIR, "lang/stopwords_lv.txt"); + putConfig(zkClient, MINIMR_CONF_DIR, "lang/stopwords_nl.txt"); + putConfig(zkClient, MINIMR_CONF_DIR, "lang/stopwords_no.txt"); + putConfig(zkClient, MINIMR_CONF_DIR, "lang/stopwords_pt.txt"); + putConfig(zkClient, MINIMR_CONF_DIR, "lang/stopwords_ro.txt"); + putConfig(zkClient, MINIMR_CONF_DIR, "lang/stopwords_ru.txt"); + putConfig(zkClient, MINIMR_CONF_DIR, "lang/stopwords_sv.txt"); + putConfig(zkClient, MINIMR_CONF_DIR, "lang/stopwords_th.txt"); + putConfig(zkClient, MINIMR_CONF_DIR, "lang/stopwords_tr.txt"); + + putConfig(zkClient, MINIMR_CONF_DIR, "lang/contractions_ca.txt"); + putConfig(zkClient, MINIMR_CONF_DIR, "lang/contractions_fr.txt"); + putConfig(zkClient, MINIMR_CONF_DIR, "lang/contractions_ga.txt"); + putConfig(zkClient, MINIMR_CONF_DIR, "lang/contractions_it.txt"); + + putConfig(zkClient, MINIMR_CONF_DIR, "lang/stemdict_nl.txt"); + + putConfig(zkClient, MINIMR_CONF_DIR, "lang/hyphenations_ga.txt"); + + putConfig(zkClient, MINIMR_CONF_DIR, "stopwords.txt"); + putConfig(zkClient, MINIMR_CONF_DIR, "protwords.txt"); + putConfig(zkClient, MINIMR_CONF_DIR, "currency.xml"); + putConfig(zkClient, MINIMR_CONF_DIR, "open-exchange-rates.json"); + putConfig(zkClient, MINIMR_CONF_DIR, "mapping-ISOLatin1Accent.txt"); + putConfig(zkClient, MINIMR_CONF_DIR, "old_synonyms.txt"); + putConfig(zkClient, MINIMR_CONF_DIR, "synonyms.txt"); + zkClient.close(); + } + + protected static T[] concat(T[]... arrays) { + if (arrays.length <= 0) { + throw new IllegalArgumentException(); + } + Class clazz = null; + int length = 0; + for (T[] array : arrays) { + clazz = array.getClass(); + length += array.length; + } + T[] result = (T[]) Array.newInstance(clazz.getComponentType(), length); + int pos = 0; + for (T[] array : arrays) { + System.arraycopy(array, 0, result, pos, array.length); + pos += array.length; + } + return result; + } + + private NamedList createAlias(String alias, String collections) throws SolrServerException, IOException { + ModifiableSolrParams params = new ModifiableSolrParams(); + params.set("collections", collections); + params.set("name", alias); + params.set("action", CollectionAction.CREATEALIAS.toString()); + QueryRequest request = new QueryRequest(params); + request.setPath("/admin/collections"); + return cloudClient.request(request); + } + + +} diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineMapperTest.java b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineMapperTest.java new file mode 100644 index 00000000000..3316caa0824 --- /dev/null +++ b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineMapperTest.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop; + +import java.util.List; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.io.LongWritable; +import org.apache.hadoop.io.Text; +import org.apache.hadoop.mrunit.mapreduce.MapDriver; +import org.apache.hadoop.mrunit.types.Pair; +import org.apache.solr.common.SolrInputDocument; +import org.apache.solr.hadoop.morphline.MorphlineMapper; +import org.junit.Test; + +public class MorphlineMapperTest extends MRUnitBase { + + @Test + public void testMapper() throws Exception { + MorphlineMapper mapper = new MorphlineMapper(); + MapDriver mapDriver = MapDriver.newMapDriver(mapper);; + + Configuration config = mapDriver.getConfiguration(); + setupHadoopConfig(config); + + mapDriver.withInput(new LongWritable(0L), new Text("hdfs://localhost/" + DOCUMENTS_DIR + "/sample-statuses-20120906-141433.avro")); + + SolrInputDocument sid = new SolrInputDocument(); + sid.addField("id", "uniqueid1"); + sid.addField("user_name", "user1"); + sid.addField("text", "content of record one"); + SolrInputDocumentWritable sidw = new SolrInputDocumentWritable(sid); + + mapDriver + .withCacheArchive(solrHomeZip.getAbsolutePath()) + .withOutput(new Text("0"), sidw); + //mapDriver.runTest(); + List> result = mapDriver.run(); + for (Pair p: result) { + System.out.println(p.getFirst()); + System.out.println(p.getSecond()); + } + } +} diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineReducerTest.java b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineReducerTest.java new file mode 100644 index 00000000000..dee44119243 --- /dev/null +++ b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineReducerTest.java @@ -0,0 +1,112 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop; + +import static org.mockito.Mockito.when; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.io.FileUtils; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.io.Text; +import org.apache.hadoop.mapred.TaskID; +import org.apache.hadoop.mapreduce.InputFormat; +import org.apache.hadoop.mapreduce.InputSplit; +import org.apache.hadoop.mapreduce.JobContext; +import org.apache.hadoop.mapreduce.RecordReader; +import org.apache.hadoop.mapreduce.TaskAttemptContext; +import org.apache.hadoop.mapreduce.TaskAttemptID; +import org.apache.hadoop.mrunit.mapreduce.ReduceDriver; +import org.apache.lucene.util.LuceneTestCase; +import org.apache.solr.cloud.AbstractZkTestCase; +import org.apache.solr.common.SolrInputDocument; +import org.junit.BeforeClass; +import org.junit.Test; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +import com.google.common.collect.Lists; + +public class MorphlineReducerTest extends MRUnitBase { + + public static class MySolrReducer extends SolrReducer { + Context context; + + @Override + protected void setup(Context context) throws IOException, InterruptedException { + this.context = context; + + // handle a bug in MRUnit - should be fixed in MRUnit 1.0.0 + when(context.getTaskAttemptID()).thenAnswer(new Answer() { + @Override + public TaskAttemptID answer(final InvocationOnMock invocation) { + // FIXME MRUNIT seems to pass taskid to the reduce task as mapred.TaskID rather than mapreduce.TaskID + return new TaskAttemptID(new TaskID("000000000000", 0, true, 0), 0); + } + }); + + super.setup(context); + } + + } + + public static class NullInputFormat extends InputFormat { + @Override + public List getSplits(JobContext context) throws IOException, + InterruptedException { + return Lists.newArrayList(); + } + + @Override + public RecordReader createRecordReader(InputSplit split, + TaskAttemptContext context) throws IOException, InterruptedException { + return null; + } + + } + + @Test + public void testReducer() throws Exception { + MySolrReducer myReducer = new MySolrReducer(); + ReduceDriver reduceDriver = ReduceDriver.newReduceDriver(myReducer); + + Configuration config = reduceDriver.getConfiguration(); + setupHadoopConfig(config); + + List values = new ArrayList(); + SolrInputDocument sid = new SolrInputDocument(); + String id = "myid1"; + sid.addField("id", id); + sid.addField("text", "some unique text"); + SolrInputDocumentWritable sidw = new SolrInputDocumentWritable(sid); + values.add(sidw); + reduceDriver.withInput(new Text(id), values); + + reduceDriver.withCacheArchive(solrHomeZip.getAbsolutePath()); + + reduceDriver.withOutputFormat(SolrOutputFormat.class, NullInputFormat.class); + + reduceDriver.run(); + + assertEquals("Expected 1 counter increment", 1, reduceDriver.getCounters() + .findCounter(SolrCounters.class.getName(), SolrCounters.DOCUMENTS_WRITTEN.toString()).getValue()); + } + +} diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/PathValidation.java b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/PathValidation.java new file mode 100644 index 00000000000..c76649edb71 --- /dev/null +++ b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/PathValidation.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop; + +import java.util.regex.Pattern; + +import org.apache.hadoop.fs.Path; +import org.junit.Test; + +public class PathValidation extends MRUnitBase { + + @Test + public void testPath() { + Path path = new Path("hdfs://c2202.mycompany.com:8020/user/foo/bar.txt"); + assertEquals("/user/foo/bar.txt", path.toUri().getPath()); + assertEquals("bar.txt", path.getName()); + assertEquals("hdfs", path.toUri().getScheme()); + assertEquals("c2202.mycompany.com:8020", path.toUri().getAuthority()); + + path = new Path("/user/foo/bar.txt"); + assertEquals("/user/foo/bar.txt", path.toUri().getPath()); + assertEquals("bar.txt", path.getName()); + assertEquals(null, path.toUri().getScheme()); + assertEquals(null, path.toUri().getAuthority()); + + assertEquals("-", new Path("-").toString()); + } + + @Test + public void testRegex() { + Pattern regex = Pattern.compile("text/plain|text/html"); + assertTrue(regex.matcher("text/plain").matches()); + assertTrue(regex.matcher("text/html").matches()); + assertFalse(regex.matcher("xxtext/html").matches()); + } + +} diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/UtilsForTests.java b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/UtilsForTests.java new file mode 100644 index 00000000000..b21d8d204e7 --- /dev/null +++ b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/UtilsForTests.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop; + +import static org.junit.Assert.assertEquals; + +import java.io.File; +import java.io.IOException; + +import org.apache.commons.io.FileUtils; +import org.apache.hadoop.fs.FileStatus; +import org.apache.hadoop.fs.FileSystem; +import org.apache.hadoop.fs.Path; +import org.apache.solr.client.solrj.SolrQuery; +import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer; +import org.apache.solr.client.solrj.response.QueryResponse; +import org.apache.solr.util.ExternalPaths; + + +public class UtilsForTests { + protected static final String RESOURCES_DIR = ExternalPaths.SOURCE_HOME + "/contrib/solr-mr/src/test-files"; + + public static void validateSolrServerDocumentCount(File solrHomeDir, FileSystem fs, Path outDir, int expectedDocs, int expectedShards) + throws IOException, SolrServerException { + + long actualDocs = 0; + int actualShards = 0; + for (FileStatus dir : fs.listStatus(outDir)) { // for each shard + if (dir.getPath().getName().startsWith("part") && dir.isDirectory()) { + actualShards++; + EmbeddedSolrServer solr = SolrRecordWriter.createEmbeddedSolrServer( + new Path(solrHomeDir.getAbsolutePath()), fs, dir.getPath()); + + try { + SolrQuery query = new SolrQuery(); + query.setQuery("*:*"); + QueryResponse resp = solr.query(query); + long numDocs = resp.getResults().getNumFound(); + actualDocs += numDocs; + } finally { + solr.shutdown(); + } + } + } + assertEquals(expectedShards, actualShards); + assertEquals(expectedDocs, actualDocs); + } + +} diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/hack/MiniMRClientCluster.java b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/hack/MiniMRClientCluster.java new file mode 100644 index 00000000000..be5ea01cd29 --- /dev/null +++ b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/hack/MiniMRClientCluster.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop.hack; + +import java.io.IOException; + +import org.apache.hadoop.conf.Configuration; + +/* + * A simple interface for a client MR cluster used for testing. This interface + * provides basic methods which are independent of the underlying Mini Cluster ( + * either through MR1 or MR2). + */ +public interface MiniMRClientCluster { + + public void start() throws IOException; + + /** + * Stop and start back the cluster using the same configuration. + */ + public void restart() throws IOException; + + public void stop() throws IOException; + + public Configuration getConfig() throws IOException; + +} diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/hack/MiniMRClientClusterFactory.java b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/hack/MiniMRClientClusterFactory.java new file mode 100644 index 00000000000..2bf721b7a6c --- /dev/null +++ b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/hack/MiniMRClientClusterFactory.java @@ -0,0 +1,88 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop.hack; + +import java.io.File; +import java.io.IOException; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.FileSystem; +import org.apache.hadoop.fs.Path; +import org.apache.hadoop.fs.permission.FsPermission; +import org.apache.hadoop.mapreduce.Job; +import org.apache.hadoop.util.JarFinder; + +/** + * A MiniMRCluster factory. In MR2, it provides a wrapper MiniMRClientCluster + * interface around the MiniMRYarnCluster. While in MR1, it provides such + * wrapper around MiniMRCluster. This factory should be used in tests to provide + * an easy migration of tests across MR1 and MR2. + */ +public class MiniMRClientClusterFactory { + + public static MiniMRClientCluster create(Class caller, int noOfNMs, + Configuration conf, File testWorkDir) throws IOException { + return create(caller, caller.getSimpleName(), noOfNMs, conf, testWorkDir); + } + + public static MiniMRClientCluster create(Class caller, String identifier, + int noOfNMs, Configuration conf, File testWorkDir) throws IOException { + + if (conf == null) { + conf = new Configuration(); + } + + FileSystem fs = FileSystem.get(conf); + + Path testRootDir = new Path(testWorkDir.getPath(), identifier + "-tmpDir") + .makeQualified(fs); + Path appJar = new Path(testRootDir, "MRAppJar.jar"); + + // Copy MRAppJar and make it private. + Path appMasterJar = new Path(MiniMRYarnCluster.APPJAR); + + fs.copyFromLocalFile(appMasterJar, appJar); + fs.setPermission(appJar, new FsPermission("744")); + + Job job = Job.getInstance(conf); + + job.addFileToClassPath(appJar); + + Path callerJar = new Path(JarFinder.getJar(caller)); + Path remoteCallerJar = new Path(testRootDir, callerJar.getName()); + fs.copyFromLocalFile(callerJar, remoteCallerJar); + fs.setPermission(remoteCallerJar, new FsPermission("744")); + job.addFileToClassPath(remoteCallerJar); + + MiniMRYarnCluster miniMRYarnCluster; + try { + miniMRYarnCluster = new MiniMRYarnCluster(identifier, + noOfNMs, testWorkDir); + } catch (Exception e) { + throw new RuntimeException(e); + } + job.getConfiguration().set("minimrclientcluster.caller.name", + identifier); + job.getConfiguration().setInt("minimrclientcluster.nodemanagers.number", + noOfNMs); + miniMRYarnCluster.init(job.getConfiguration()); + miniMRYarnCluster.start(); + + return new MiniMRYarnClusterAdapter(miniMRYarnCluster, testWorkDir); + } + +} diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/hack/MiniMRCluster.java b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/hack/MiniMRCluster.java new file mode 100644 index 00000000000..b399b7a9552 --- /dev/null +++ b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/hack/MiniMRCluster.java @@ -0,0 +1,283 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop.hack; + +import java.io.File; +import java.io.IOException; +import java.util.Random; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.fs.FileSystem; +import org.apache.hadoop.mapred.JobConf; +import org.apache.hadoop.mapred.JobID; +import org.apache.hadoop.mapred.JobPriority; +import org.apache.hadoop.mapred.MapTaskCompletionEventsUpdate; +import org.apache.hadoop.mapred.TaskCompletionEvent; +import org.apache.hadoop.security.AccessControlException; +import org.apache.hadoop.security.UserGroupInformation; +import org.apache.hadoop.yarn.conf.YarnConfiguration; +import org.apache.lucene.util.LuceneTestCase; + + +/** + * This class is an MR2 replacement for older MR1 MiniMRCluster, that was used + * by tests prior to MR2. This replacement class uses the new MiniMRYarnCluster + * in MR2 but provides the same old MR1 interface, so tests can be migrated from + * MR1 to MR2 with minimal changes. + * + * Due to major differences between MR1 and MR2, a number of methods are either + * unimplemented/unsupported or were re-implemented to provide wrappers around + * MR2 functionality. + * + * @deprecated Use {@link org.apache.hadoop.mapred.MiniMRClientClusterFactory} + * instead + */ +@Deprecated +public class MiniMRCluster { + private static final Log LOG = LogFactory.getLog(MiniMRCluster.class); + + private MiniMRClientCluster mrClientCluster; + + public String getTaskTrackerLocalDir(int taskTracker) { + throw new UnsupportedOperationException(); + } + + public String[] getTaskTrackerLocalDirs(int taskTracker) { + throw new UnsupportedOperationException(); + } + + class JobTrackerRunner { + // Mock class + } + + class TaskTrackerRunner { + // Mock class + } + + public JobTrackerRunner getJobTrackerRunner() { + throw new UnsupportedOperationException(); + } + + TaskTrackerRunner getTaskTrackerRunner(int id) { + throw new UnsupportedOperationException(); + } + + public int getNumTaskTrackers() { + throw new UnsupportedOperationException(); + } + + public void setInlineCleanupThreads() { + throw new UnsupportedOperationException(); + } + + public void waitUntilIdle() { + throw new UnsupportedOperationException(); + } + + private void waitTaskTrackers() { + throw new UnsupportedOperationException(); + } + + public int getJobTrackerPort() { + throw new UnsupportedOperationException(); + } + + public JobConf createJobConf() { + JobConf jobConf = null; + try { + jobConf = new JobConf(mrClientCluster.getConfig()); + } catch (IOException e) { + LOG.error(e); + } + return jobConf; + } + + public JobConf createJobConf(JobConf conf) { + JobConf jobConf = null; + try { + jobConf = new JobConf(mrClientCluster.getConfig()); + } catch (IOException e) { + LOG.error(e); + } + return jobConf; + } + + static JobConf configureJobConf(JobConf conf, String namenode, + int jobTrackerPort, int jobTrackerInfoPort, UserGroupInformation ugi) { + throw new UnsupportedOperationException(); + } + + public MiniMRCluster(int numTaskTrackers, String namenode, int numDir, + String[] racks, String[] hosts) throws Exception { + this(0, 0, numTaskTrackers, namenode, numDir, racks, hosts); + } + + public MiniMRCluster(int numTaskTrackers, String namenode, int numDir, + String[] racks, String[] hosts, JobConf conf) throws Exception { + this(0, 0, numTaskTrackers, namenode, numDir, racks, hosts, null, conf); + } + + public MiniMRCluster(int numTaskTrackers, String namenode, int numDir) + throws Exception { + this(0, 0, numTaskTrackers, namenode, numDir); + } + + public MiniMRCluster(int jobTrackerPort, int taskTrackerPort, + int numTaskTrackers, String namenode, int numDir) throws Exception { + this(jobTrackerPort, taskTrackerPort, numTaskTrackers, namenode, numDir, + null); + } + + public MiniMRCluster(int jobTrackerPort, int taskTrackerPort, + int numTaskTrackers, String namenode, int numDir, String[] racks) + throws Exception { + this(jobTrackerPort, taskTrackerPort, numTaskTrackers, namenode, numDir, + racks, null); + } + + public MiniMRCluster(int jobTrackerPort, int taskTrackerPort, + int numTaskTrackers, String namenode, int numDir, String[] racks, + String[] hosts) throws Exception { + this(jobTrackerPort, taskTrackerPort, numTaskTrackers, namenode, numDir, + racks, hosts, null); + } + + public MiniMRCluster(int jobTrackerPort, int taskTrackerPort, + int numTaskTrackers, String namenode, int numDir, String[] racks, + String[] hosts, UserGroupInformation ugi) throws Exception { + this(jobTrackerPort, taskTrackerPort, numTaskTrackers, namenode, numDir, + racks, hosts, ugi, null); + } + + public MiniMRCluster(int jobTrackerPort, int taskTrackerPort, + int numTaskTrackers, String namenode, int numDir, String[] racks, + String[] hosts, UserGroupInformation ugi, JobConf conf) + throws Exception { + this(jobTrackerPort, taskTrackerPort, numTaskTrackers, namenode, numDir, + racks, hosts, ugi, conf, 0); + } + + public MiniMRCluster(int jobTrackerPort, int taskTrackerPort, + int numTaskTrackers, String namenode, int numDir, String[] racks, + String[] hosts, UserGroupInformation ugi, JobConf conf, + int numTrackerToExclude) throws Exception { + this(jobTrackerPort, taskTrackerPort, numTaskTrackers, namenode, numDir, + racks, hosts, ugi, conf, numTrackerToExclude, new Clock()); + } + + public MiniMRCluster(int jobTrackerPort, int taskTrackerPort, + int numTaskTrackers, String namenode, int numDir, String[] racks, + String[] hosts, UserGroupInformation ugi, JobConf conf, + int numTrackerToExclude, Clock clock) throws Exception { + if (conf == null) conf = new JobConf(); + FileSystem.setDefaultUri(conf, namenode); + String identifier = this.getClass().getSimpleName() + "_" + + Integer.toString(LuceneTestCase.random().nextInt(Integer.MAX_VALUE)); + mrClientCluster = MiniMRClientClusterFactory.create(this.getClass(), + identifier, numTaskTrackers, conf, new File(conf.get("testWorkDir"))); + } + + public UserGroupInformation getUgi() { + throw new UnsupportedOperationException(); + } + + public TaskCompletionEvent[] getTaskCompletionEvents(JobID id, int from, + int max) throws IOException { + throw new UnsupportedOperationException(); + } + + public void setJobPriority(JobID jobId, JobPriority priority) + throws AccessControlException, IOException { + throw new UnsupportedOperationException(); + } + + public JobPriority getJobPriority(JobID jobId) { + throw new UnsupportedOperationException(); + } + + public long getJobFinishTime(JobID jobId) { + throw new UnsupportedOperationException(); + } + + public void initializeJob(JobID jobId) throws IOException { + throw new UnsupportedOperationException(); + } + + public MapTaskCompletionEventsUpdate getMapTaskCompletionEventsUpdates( + int index, JobID jobId, int max) throws IOException { + throw new UnsupportedOperationException(); + } + + public JobConf getJobTrackerConf() { + JobConf jobConf = null; + try { + jobConf = new JobConf(mrClientCluster.getConfig()); + } catch (IOException e) { + LOG.error(e); + } + return jobConf; + } + + public int getFaultCount(String hostName) { + throw new UnsupportedOperationException(); + } + + public void startJobTracker() { + // Do nothing + } + + public void startJobTracker(boolean wait) { + // Do nothing + } + + public void stopJobTracker() { + // Do nothing + } + + public void stopTaskTracker(int id) { + // Do nothing + } + + public void startTaskTracker(String host, String rack, int idx, int numDir) + throws IOException { + // Do nothing + } + + void addTaskTracker(TaskTrackerRunner taskTracker) { + throw new UnsupportedOperationException(); + } + + int getTaskTrackerID(String trackerName) { + throw new UnsupportedOperationException(); + } + + public void shutdown() { + try { + mrClientCluster.stop(); + } catch (IOException e) { + LOG.error(e); + } + } + + static class Clock { + long getTime() { + return System.currentTimeMillis(); + } + } + +} diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/hack/MiniMRYarnCluster.java b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/hack/MiniMRYarnCluster.java new file mode 100644 index 00000000000..8fa1b3132bc --- /dev/null +++ b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/hack/MiniMRYarnCluster.java @@ -0,0 +1,205 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop.hack; + +import java.io.File; +import java.io.IOException; +import java.util.Locale; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.CommonConfigurationKeys; +import org.apache.hadoop.fs.FileContext; +import org.apache.hadoop.fs.LocalFileSystem; +import org.apache.hadoop.fs.Path; +import org.apache.hadoop.mapred.LocalContainerLauncher; +import org.apache.hadoop.mapred.ShuffleHandler; +import org.apache.hadoop.mapreduce.MRConfig; +import org.apache.hadoop.mapreduce.MRJobConfig; +import org.apache.hadoop.mapreduce.v2.hs.JobHistoryServer; +import org.apache.hadoop.mapreduce.v2.jobhistory.JHAdminConfig; +import org.apache.hadoop.mapreduce.v2.jobhistory.JobHistoryUtils; +import org.apache.hadoop.service.AbstractService; +import org.apache.hadoop.service.Service; +import org.apache.hadoop.util.JarFinder; +import org.apache.hadoop.yarn.conf.YarnConfiguration; +import org.apache.hadoop.yarn.exceptions.YarnRuntimeException; +import org.apache.hadoop.yarn.server.nodemanager.ContainerExecutor; +import org.apache.hadoop.yarn.server.nodemanager.DefaultContainerExecutor; + +/** + * Configures and starts the MR-specific components in the YARN cluster. + * + */ +public class MiniMRYarnCluster extends MiniYARNCluster { + + public static final String APPJAR = JarFinder.getJar(LocalContainerLauncher.class); + + private static final Log LOG = LogFactory.getLog(MiniMRYarnCluster.class); + private JobHistoryServer historyServer; + private JobHistoryServerWrapper historyServerWrapper; + + public MiniMRYarnCluster(String testName, File testWorkDir) { + this(testName, 1, testWorkDir); + } + + public MiniMRYarnCluster(String testName, int noOfNMs, File testWorkDir) { + super(testName, noOfNMs, 4, 4, testWorkDir); + //TODO: add the history server + historyServerWrapper = new JobHistoryServerWrapper(); + addService(historyServerWrapper); + } + + @Override + public void serviceInit(Configuration conf) throws Exception { + conf.set(MRConfig.FRAMEWORK_NAME, MRConfig.YARN_FRAMEWORK_NAME); + if (conf.get(MRJobConfig.MR_AM_STAGING_DIR) == null) { + conf.set(MRJobConfig.MR_AM_STAGING_DIR, new File(getTestWorkDir(), + "apps_staging_dir/").getAbsolutePath()); + } + + // By default, VMEM monitoring disabled, PMEM monitoring enabled. + if (!conf.getBoolean( + MRConfig.MAPREDUCE_MINICLUSTER_CONTROL_RESOURCE_MONITORING, + MRConfig.DEFAULT_MAPREDUCE_MINICLUSTER_CONTROL_RESOURCE_MONITORING)) { + conf.setBoolean(YarnConfiguration.NM_PMEM_CHECK_ENABLED, false); + conf.setBoolean(YarnConfiguration.NM_VMEM_CHECK_ENABLED, false); + } + + conf.set(CommonConfigurationKeys.FS_PERMISSIONS_UMASK_KEY, "000"); + + try { + Path stagingPath = FileContext.getFileContext(conf).makeQualified( + new Path(conf.get(MRJobConfig.MR_AM_STAGING_DIR))); + /* + * Re-configure the staging path on Windows if the file system is localFs. + * We need to use a absolute path that contains the drive letter. The unit + * test could run on a different drive than the AM. We can run into the + * issue that job files are localized to the drive where the test runs on, + * while the AM starts on a different drive and fails to find the job + * metafiles. Using absolute path can avoid this ambiguity. + */ + if (Path.WINDOWS) { + if (LocalFileSystem.class.isInstance(stagingPath.getFileSystem(conf))) { + conf.set(MRJobConfig.MR_AM_STAGING_DIR, + new File(conf.get(MRJobConfig.MR_AM_STAGING_DIR)) + .getAbsolutePath()); + } + } + FileContext fc=FileContext.getFileContext(stagingPath.toUri(), conf); + if (fc.util().exists(stagingPath)) { + LOG.info(stagingPath + " exists! deleting..."); + fc.delete(stagingPath, true); + } + LOG.info("mkdir: " + stagingPath); + //mkdir the staging directory so that right permissions are set while running as proxy user + fc.mkdir(stagingPath, null, true); + //mkdir done directory as well + String doneDir = JobHistoryUtils.getConfiguredHistoryServerDoneDirPrefix(conf); + Path doneDirPath = fc.makeQualified(new Path(doneDir)); + fc.mkdir(doneDirPath, null, true); + } catch (IOException e) { + throw new YarnRuntimeException("Could not create staging directory. ", e); + } + conf.set(MRConfig.MASTER_ADDRESS, "test"); // The default is local because of + // which shuffle doesn't happen + //configure the shuffle service in NM + conf.setStrings(YarnConfiguration.NM_AUX_SERVICES, + new String[] { ShuffleHandler.MAPREDUCE_SHUFFLE_SERVICEID }); + conf.setClass(String.format(Locale.ENGLISH, YarnConfiguration.NM_AUX_SERVICE_FMT, + ShuffleHandler.MAPREDUCE_SHUFFLE_SERVICEID), ShuffleHandler.class, + Service.class); + + // Non-standard shuffle port + conf.setInt(ShuffleHandler.SHUFFLE_PORT_CONFIG_KEY, 0); + + conf.setClass(YarnConfiguration.NM_CONTAINER_EXECUTOR, + DefaultContainerExecutor.class, ContainerExecutor.class); + + // TestMRJobs is for testing non-uberized operation only; see TestUberAM + // for corresponding uberized tests. + conf.setBoolean(MRJobConfig.JOB_UBERTASK_ENABLE, false); + + super.serviceInit(conf); + } + + private class JobHistoryServerWrapper extends AbstractService { + public JobHistoryServerWrapper() { + super(JobHistoryServerWrapper.class.getName()); + } + + @Override + public synchronized void serviceStart() throws Exception { + try { + if (!getConfig().getBoolean( + JHAdminConfig.MR_HISTORY_MINICLUSTER_FIXED_PORTS, + JHAdminConfig.DEFAULT_MR_HISTORY_MINICLUSTER_FIXED_PORTS)) { + // pick free random ports. + getConfig().set(JHAdminConfig.MR_HISTORY_ADDRESS, + MiniYARNCluster.getHostname() + ":0"); + getConfig().set(JHAdminConfig.MR_HISTORY_WEBAPP_ADDRESS, + MiniYARNCluster.getHostname() + ":0"); + } + historyServer = new JobHistoryServer(); + historyServer.init(getConfig()); + new Thread() { + public void run() { + historyServer.start(); + }; + }.start(); + while (historyServer.getServiceState() == STATE.INITED) { + LOG.info("Waiting for HistoryServer to start..."); + Thread.sleep(1500); + } + //TODO Add a timeout. State.STOPPED check ? + if (historyServer.getServiceState() != STATE.STARTED) { + throw new IOException("HistoryServer failed to start"); + } + super.serviceStart(); + } catch (Throwable t) { + throw new YarnRuntimeException(t); + } + //need to do this because historyServer.init creates a new Configuration + getConfig().set(JHAdminConfig.MR_HISTORY_ADDRESS, + historyServer.getConfig().get(JHAdminConfig.MR_HISTORY_ADDRESS)); + getConfig().set(JHAdminConfig.MR_HISTORY_WEBAPP_ADDRESS, + historyServer.getConfig().get(JHAdminConfig.MR_HISTORY_WEBAPP_ADDRESS)); + + LOG.info("MiniMRYARN ResourceManager address: " + + getConfig().get(YarnConfiguration.RM_ADDRESS)); + LOG.info("MiniMRYARN ResourceManager web address: " + + getConfig().get(YarnConfiguration.RM_WEBAPP_ADDRESS)); + LOG.info("MiniMRYARN HistoryServer address: " + + getConfig().get(JHAdminConfig.MR_HISTORY_ADDRESS)); + LOG.info("MiniMRYARN HistoryServer web address: " + + getConfig().get(JHAdminConfig.MR_HISTORY_WEBAPP_ADDRESS)); + } + + @Override + public synchronized void serviceStop() throws Exception { + if (historyServer != null) { + historyServer.stop(); + } + super.serviceStop(); + } + } + + public JobHistoryServer getHistoryServer() { + return this.historyServer; + } +} diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/hack/MiniMRYarnClusterAdapter.java b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/hack/MiniMRYarnClusterAdapter.java new file mode 100644 index 00000000000..08ab881005b --- /dev/null +++ b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/hack/MiniMRYarnClusterAdapter.java @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop.hack; + +import java.io.File; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.mapreduce.v2.jobhistory.JHAdminConfig; +import org.apache.hadoop.service.Service.STATE; +import org.apache.hadoop.yarn.conf.YarnConfiguration; + +/** + * An adapter for MiniMRYarnCluster providing a MiniMRClientCluster interface. + * This interface could be used by tests across both MR1 and MR2. + */ +public class MiniMRYarnClusterAdapter implements MiniMRClientCluster { + + private MiniMRYarnCluster miniMRYarnCluster; + + private File testWorkDir; + + private static final Log LOG = LogFactory.getLog(MiniMRYarnClusterAdapter.class); + + public MiniMRYarnClusterAdapter(MiniMRYarnCluster miniMRYarnCluster, File testWorkDir) { + this.miniMRYarnCluster = miniMRYarnCluster; + this.testWorkDir = testWorkDir; + } + + @Override + public Configuration getConfig() { + return miniMRYarnCluster.getConfig(); + } + + @Override + public void start() { + miniMRYarnCluster.start(); + } + + @Override + public void stop() { + miniMRYarnCluster.stop(); + } + + @Override + public void restart() { + if (!miniMRYarnCluster.getServiceState().equals(STATE.STARTED)){ + LOG.warn("Cannot restart the mini cluster, start it first"); + return; + } + Configuration oldConf = new Configuration(getConfig()); + String callerName = oldConf.get("minimrclientcluster.caller.name", + this.getClass().getName()); + int noOfNMs = oldConf.getInt("minimrclientcluster.nodemanagers.number", 1); + oldConf.setBoolean(YarnConfiguration.YARN_MINICLUSTER_FIXED_PORTS, true); + oldConf.setBoolean(JHAdminConfig.MR_HISTORY_MINICLUSTER_FIXED_PORTS, true); + stop(); + miniMRYarnCluster = new MiniMRYarnCluster(callerName, noOfNMs, testWorkDir); + miniMRYarnCluster.init(oldConf); + miniMRYarnCluster.start(); + } + +} diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/hack/MiniYARNCluster.java b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/hack/MiniYARNCluster.java new file mode 100644 index 00000000000..d02726657e4 --- /dev/null +++ b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/hack/MiniYARNCluster.java @@ -0,0 +1,410 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop.hack; + +import java.io.File; +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Locale; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.FileContext; +import org.apache.hadoop.fs.Path; +import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem; +import org.apache.hadoop.service.AbstractService; +import org.apache.hadoop.service.CompositeService; +import org.apache.hadoop.util.Shell; +import org.apache.hadoop.util.Shell.ShellCommandExecutor; +import org.apache.hadoop.yarn.conf.YarnConfiguration; +import org.apache.hadoop.yarn.event.Dispatcher; +import org.apache.hadoop.yarn.exceptions.YarnException; +import org.apache.hadoop.yarn.exceptions.YarnRuntimeException; +import org.apache.hadoop.yarn.factories.RecordFactory; +import org.apache.hadoop.yarn.factory.providers.RecordFactoryProvider; +import org.apache.hadoop.yarn.ipc.RPCUtil; +import org.apache.hadoop.yarn.server.api.ResourceTracker; +import org.apache.hadoop.yarn.server.api.protocolrecords.NodeHeartbeatRequest; +import org.apache.hadoop.yarn.server.api.protocolrecords.NodeHeartbeatResponse; +import org.apache.hadoop.yarn.server.api.protocolrecords.RegisterNodeManagerRequest; +import org.apache.hadoop.yarn.server.api.protocolrecords.RegisterNodeManagerResponse; +import org.apache.hadoop.yarn.server.nodemanager.Context; +import org.apache.hadoop.yarn.server.nodemanager.NodeHealthCheckerService; +import org.apache.hadoop.yarn.server.nodemanager.NodeManager; +import org.apache.hadoop.yarn.server.nodemanager.NodeStatusUpdater; +import org.apache.hadoop.yarn.server.nodemanager.NodeStatusUpdaterImpl; +import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager; +import org.apache.hadoop.yarn.server.resourcemanager.ResourceTrackerService; + +public class MiniYARNCluster extends CompositeService { + + private static final Log LOG = LogFactory.getLog(MiniYARNCluster.class); + + // temp fix until metrics system can auto-detect itself running in unit test: + static { + DefaultMetricsSystem.setMiniClusterMode(true); + } + + private NodeManager[] nodeManagers; + private ResourceManager resourceManager; + + private ResourceManagerWrapper resourceManagerWrapper; + + private File testWorkDir; + + // Number of nm-local-dirs per nodemanager + private int numLocalDirs; + // Number of nm-log-dirs per nodemanager + private int numLogDirs; + + /** + * @param testName name of the test + * @param noOfNodeManagers the number of node managers in the cluster + * @param numLocalDirs the number of nm-local-dirs per nodemanager + * @param numLogDirs the number of nm-log-dirs per nodemanager + */ + public MiniYARNCluster(String testName, int noOfNodeManagers, + int numLocalDirs, int numLogDirs, File testWorkDir) { + super(testName.replace("$", "")); + this.numLocalDirs = numLocalDirs; + this.numLogDirs = numLogDirs; + String testSubDir = testName.replace("$", ""); + File targetWorkDir = new File(testWorkDir, testSubDir); + try { + FileContext.getLocalFSFileContext().delete( + new Path(targetWorkDir.getAbsolutePath()), true); + } catch (Exception e) { + LOG.warn("COULD NOT CLEANUP", e); + throw new YarnRuntimeException("could not cleanup test dir: "+ e, e); + } + + if (Shell.WINDOWS) { + // The test working directory can exceed the maximum path length supported + // by some Windows APIs and cmd.exe (260 characters). To work around this, + // create a symlink in temporary storage with a much shorter path, + // targeting the full path to the test working directory. Then, use the + // symlink as the test working directory. + String targetPath = targetWorkDir.getAbsolutePath(); + File link = new File(System.getProperty("java.io.tmpdir"), + String.valueOf(System.currentTimeMillis())); + String linkPath = link.getAbsolutePath(); + + try { + FileContext.getLocalFSFileContext().delete(new Path(linkPath), true); + } catch (IOException e) { + throw new YarnRuntimeException("could not cleanup symlink: " + linkPath, e); + } + + // Guarantee target exists before creating symlink. + targetWorkDir.mkdirs(); + + ShellCommandExecutor shexec = new ShellCommandExecutor( + Shell.getSymlinkCommand(targetPath, linkPath)); + try { + shexec.execute(); + } catch (IOException e) { + throw new YarnRuntimeException(String.format(Locale.ENGLISH, + "failed to create symlink from %s to %s, shell output: %s", linkPath, + targetPath, shexec.getOutput()), e); + } + + this.testWorkDir = link; + } else { + this.testWorkDir = targetWorkDir; + } + + resourceManagerWrapper = new ResourceManagerWrapper(); + addService(resourceManagerWrapper); + nodeManagers = new CustomNodeManager[noOfNodeManagers]; + for(int index = 0; index < noOfNodeManagers; index++) { + addService(new NodeManagerWrapper(index)); + nodeManagers[index] = new CustomNodeManager(); + } + } + + @Override + public void serviceInit(Configuration conf) throws Exception { + super.serviceInit(conf instanceof YarnConfiguration ? conf + : new YarnConfiguration( + conf)); + } + + public File getTestWorkDir() { + return testWorkDir; + } + + public ResourceManager getResourceManager() { + return this.resourceManager; + } + + public NodeManager getNodeManager(int i) { + return this.nodeManagers[i]; + } + + public static String getHostname() { + try { + return InetAddress.getLocalHost().getHostName(); + } + catch (UnknownHostException ex) { + throw new RuntimeException(ex); + } + } + + private class ResourceManagerWrapper extends AbstractService { + public ResourceManagerWrapper() { + super(ResourceManagerWrapper.class.getName()); + } + + @Override + public synchronized void serviceStart() throws Exception { + try { + getConfig().setBoolean(YarnConfiguration.IS_MINI_YARN_CLUSTER, true); + if (!getConfig().getBoolean( + YarnConfiguration.YARN_MINICLUSTER_FIXED_PORTS, + YarnConfiguration.DEFAULT_YARN_MINICLUSTER_FIXED_PORTS)) { + // pick free random ports. + String hostname = MiniYARNCluster.getHostname(); + getConfig().set(YarnConfiguration.RM_ADDRESS, + hostname + ":0"); + getConfig().set(YarnConfiguration.RM_ADMIN_ADDRESS, + hostname + ":0"); + getConfig().set(YarnConfiguration.RM_SCHEDULER_ADDRESS, + hostname + ":0"); + getConfig().set(YarnConfiguration.RM_RESOURCE_TRACKER_ADDRESS, + hostname + ":0"); + getConfig().set(YarnConfiguration.RM_WEBAPP_ADDRESS, + hostname + ":0"); + } + resourceManager = new ResourceManager() { + @Override + protected void doSecureLogin() throws IOException { + // Don't try to login using keytab in the testcase. + }; + }; + resourceManager.init(getConfig()); + new Thread() { + public void run() { + resourceManager.start(); + }; + }.start(); + int waitCount = 0; + while (resourceManager.getServiceState() == STATE.INITED + && waitCount++ < 60) { + LOG.info("Waiting for RM to start..."); + Thread.sleep(1500); + } + if (resourceManager.getServiceState() != STATE.STARTED) { + // RM could have failed. + throw new IOException( + "ResourceManager failed to start. Final state is " + + resourceManager.getServiceState()); + } + super.serviceStart(); + } catch (Throwable t) { + throw new YarnRuntimeException(t); + } + LOG.info("MiniYARN ResourceManager address: " + + getConfig().get(YarnConfiguration.RM_ADDRESS)); + LOG.info("MiniYARN ResourceManager web address: " + + getConfig().get(YarnConfiguration.RM_WEBAPP_ADDRESS)); + } + + @Override + public synchronized void serviceStop() throws Exception { + if (resourceManager != null) { + resourceManager.stop(); + } + super.serviceStop(); + + if (Shell.WINDOWS) { + // On Windows, clean up the short temporary symlink that was created to + // work around path length limitation. + String testWorkDirPath = testWorkDir.getAbsolutePath(); + try { + FileContext.getLocalFSFileContext().delete(new Path(testWorkDirPath), + true); + } catch (IOException e) { + LOG.warn("could not cleanup symlink: " + + testWorkDir.getAbsolutePath()); + } + } + } + } + + private class NodeManagerWrapper extends AbstractService { + int index = 0; + + public NodeManagerWrapper(int i) { + super(NodeManagerWrapper.class.getName() + "_" + i); + index = i; + } + + public synchronized void serviceInit(Configuration conf) throws Exception { + Configuration config = new YarnConfiguration(conf); + super.serviceInit(config); + } + + /** + * Create local/log directories + * @param dirType type of directories i.e. local dirs or log dirs + * @param numDirs number of directories + * @return the created directories as a comma delimited String + */ + private String prepareDirs(String dirType, int numDirs) { + File []dirs = new File[numDirs]; + String dirsString = ""; + for (int i = 0; i < numDirs; i++) { + dirs[i]= new File(testWorkDir, MiniYARNCluster.this.getName() + + "-" + dirType + "Dir-nm-" + index + "_" + i); + dirs[i].mkdirs(); + LOG.info("Created " + dirType + "Dir in " + dirs[i].getAbsolutePath()); + String delimiter = (i > 0) ? "," : ""; + dirsString = dirsString.concat(delimiter + dirs[i].getAbsolutePath()); + } + return dirsString; + } + + public synchronized void serviceStart() throws Exception { + try { + // create nm-local-dirs and configure them for the nodemanager + String localDirsString = prepareDirs("local", numLocalDirs); + getConfig().set(YarnConfiguration.NM_LOCAL_DIRS, localDirsString); + // create nm-log-dirs and configure them for the nodemanager + String logDirsString = prepareDirs("log", numLogDirs); + getConfig().set(YarnConfiguration.NM_LOG_DIRS, logDirsString); + + File remoteLogDir = + new File(testWorkDir, MiniYARNCluster.this.getName() + + "-remoteLogDir-nm-" + index); + remoteLogDir.mkdir(); + getConfig().set(YarnConfiguration.NM_REMOTE_APP_LOG_DIR, + remoteLogDir.getAbsolutePath()); + // By default AM + 2 containers + getConfig().setInt(YarnConfiguration.NM_PMEM_MB, 4*1024); + getConfig().set(YarnConfiguration.NM_ADDRESS, + MiniYARNCluster.getHostname() + ":0"); + getConfig().set(YarnConfiguration.NM_LOCALIZER_ADDRESS, + MiniYARNCluster.getHostname() + ":0"); + getConfig().set(YarnConfiguration.NM_WEBAPP_ADDRESS, + MiniYARNCluster.getHostname() + ":0"); + + // Disable resource checks by default + if (!getConfig().getBoolean( + YarnConfiguration.YARN_MINICLUSTER_CONTROL_RESOURCE_MONITORING, + YarnConfiguration. + DEFAULT_YARN_MINICLUSTER_CONTROL_RESOURCE_MONITORING)) { + getConfig().setBoolean(YarnConfiguration.NM_PMEM_CHECK_ENABLED, false); + getConfig().setBoolean(YarnConfiguration.NM_VMEM_CHECK_ENABLED, false); + } + + LOG.info("Starting NM: " + index); + nodeManagers[index].init(getConfig()); + new Thread() { + public void run() { + nodeManagers[index].start(); + }; + }.start(); + int waitCount = 0; + while (nodeManagers[index].getServiceState() == STATE.INITED + && waitCount++ < 60) { + LOG.info("Waiting for NM " + index + " to start..."); + Thread.sleep(1000); + } + if (nodeManagers[index].getServiceState() != STATE.STARTED) { + // RM could have failed. + throw new IOException("NodeManager " + index + " failed to start"); + } + super.serviceStart(); + } catch (Throwable t) { + throw new YarnRuntimeException(t); + } + } + + @Override + public synchronized void serviceStop() throws Exception { + if (nodeManagers[index] != null) { + nodeManagers[index].stop(); + } + super.serviceStop(); + } + } + + private class CustomNodeManager extends NodeManager { + @Override + protected void doSecureLogin() throws IOException { + // Don't try to login using keytab in the testcase. + }; + + @Override + protected NodeStatusUpdater createNodeStatusUpdater(Context context, + Dispatcher dispatcher, NodeHealthCheckerService healthChecker) { + return new NodeStatusUpdaterImpl(context, dispatcher, + healthChecker, metrics) { + @Override + protected ResourceTracker getRMClient() { + final ResourceTrackerService rt = resourceManager + .getResourceTrackerService(); + final RecordFactory recordFactory = + RecordFactoryProvider.getRecordFactory(null); + + // For in-process communication without RPC + return new ResourceTracker() { + + @Override + public NodeHeartbeatResponse nodeHeartbeat( + NodeHeartbeatRequest request) throws YarnException, + IOException { + NodeHeartbeatResponse response = recordFactory.newRecordInstance( + NodeHeartbeatResponse.class); + try { + response = rt.nodeHeartbeat(request); + } catch (YarnException e) { + LOG.info("Exception in heartbeat from node " + + request.getNodeStatus().getNodeId(), e); + throw e; + } + return response; + } + + @Override + public RegisterNodeManagerResponse registerNodeManager( + RegisterNodeManagerRequest request) + throws YarnException, IOException { + RegisterNodeManagerResponse response = recordFactory. + newRecordInstance(RegisterNodeManagerResponse.class); + try { + response = rt.registerNodeManager(request); + } catch (YarnException e) { + LOG.info("Exception in node registration from " + + request.getNodeId().toString(), e); + throw e; + } + return response; + } + }; + }; + + @Override + protected void stopRMProxy() { + return; + } + }; + }; + } +} diff --git a/solr/core/src/java/org/apache/solr/store/hdfs/HdfsDirectory.java b/solr/core/src/java/org/apache/solr/store/hdfs/HdfsDirectory.java index 8e9fcb0f2e9..af8c0973a4b 100644 --- a/solr/core/src/java/org/apache/solr/store/hdfs/HdfsDirectory.java +++ b/solr/core/src/java/org/apache/solr/store/hdfs/HdfsDirectory.java @@ -54,7 +54,6 @@ public class HdfsDirectory extends BaseDirectory { public HdfsDirectory(Path hdfsDirPath, Configuration configuration) throws IOException { - assert hdfsDirPath.toString().startsWith("hdfs:/") : hdfsDirPath.toString(); setLockFactory(NoLockFactory.getNoLockFactory()); this.hdfsDirPath = hdfsDirPath; this.configuration = configuration; diff --git a/solr/core/src/test-files/log4j.properties b/solr/core/src/test-files/log4j.properties index 4562e3fd80a..08a32f3f38f 100644 --- a/solr/core/src/test-files/log4j.properties +++ b/solr/core/src/test-files/log4j.properties @@ -8,6 +8,7 @@ log4j.appender.CONSOLE.layout.ConversionPattern=%-5p - %d{yyyy-MM-dd HH:mm:ss.SS log4j.logger.org.apache.zookeeper=WARN log4j.logger.org.apache.hadoop=WARN +log4j.logger.org.apache.solr.hadoop=INFO #log4j.logger.org.apache.solr.update.processor.LogUpdateProcessor=DEBUG #log4j.logger.org.apache.solr.update.processor.DistributedUpdateProcessor=DEBUG diff --git a/solr/example/cloud-scripts/log4j.properties b/solr/example/scripts/cloud-scripts/log4j.properties similarity index 100% rename from solr/example/cloud-scripts/log4j.properties rename to solr/example/scripts/cloud-scripts/log4j.properties diff --git a/solr/example/cloud-scripts/zkcli.bat b/solr/example/scripts/cloud-scripts/zkcli.bat similarity index 67% rename from solr/example/cloud-scripts/zkcli.bat rename to solr/example/scripts/cloud-scripts/zkcli.bat index 8232a726cac..ac092e01874 100644 --- a/solr/example/cloud-scripts/zkcli.bat +++ b/solr/example/scripts/cloud-scripts/zkcli.bat @@ -8,4 +8,4 @@ REM Find location of this script set SDIR=%~dp0 if "%SDIR:~-1%"=="\" set SDIR=%SDIR:~0,-1% -"%JVM%" -Dlog4j.configuration=file:%SDIR%\log4j.properties -classpath "%SDIR%\..\solr-webapp\webapp\WEB-INF\lib\*;%SDIR%\..\lib\ext\*" org.apache.solr.cloud.ZkCLI %* +"%JVM%" -Dlog4j.configuration=file:%SDIR%\log4j.properties -classpath "%SDIR%\..\..\solr-webapp\webapp\WEB-INF\lib\*;%SDIR%\..\..\lib\ext\*" org.apache.solr.cloud.ZkCLI %* diff --git a/solr/example/cloud-scripts/zkcli.sh b/solr/example/scripts/cloud-scripts/zkcli.sh similarity index 62% rename from solr/example/cloud-scripts/zkcli.sh rename to solr/example/scripts/cloud-scripts/zkcli.sh index ab5da966fa5..15b5392d2e5 100644 --- a/solr/example/cloud-scripts/zkcli.sh +++ b/solr/example/scripts/cloud-scripts/zkcli.sh @@ -9,5 +9,5 @@ JVM="java" sdir="`dirname \"$0\"`" -PATH=$JAVA_HOME/bin:$PATH $JVM -Dlog4j.configuration=file:$sdir/log4j.properties -classpath "$sdir/../solr-webapp/webapp/WEB-INF/lib/*:$sdir/../lib/ext/*" org.apache.solr.cloud.ZkCLI ${1+"$@"} +PATH=$JAVA_HOME/bin:$PATH $JVM -Dlog4j.configuration=file:$sdir/log4j.properties -classpath "$sdir/../../solr-webapp/webapp/WEB-INF/lib/*:$sdir/../../lib/ext/*" org.apache.solr.cloud.ZkCLI ${1+"$@"} diff --git a/solr/example/scripts/solr-mr/solr-mr.bat b/solr/example/scripts/solr-mr/solr-mr.bat new file mode 100644 index 00000000000..89f934628bd --- /dev/null +++ b/solr/example/scripts/solr-mr/solr-mr.bat @@ -0,0 +1,9 @@ + +set JVM=java + +REM Find location of this script + +set SDIR=%~dp0 +if "%SDIR:~-1%"=="\" set SDIR=%SDIR:~0,-1% + +"%JVM%" -classpath "%SDIR%\..\..\..\dist\*:%SDIR%\..\..\..\contrib\solr-mr\lib\*:%SDIR%\..\..\..\contrib\solr-morphlines-core\lib\*:%SDIR%\..\..\..\contrib\solr-morphlines-cell\lib\*:%SDIR%\..\..\..\contrib\extraction\lib\*:%SDIR%\..\..\solr-webapp\solr\WEB-INF\lib\*:%SDIR%\..\..\lib\ext\*" org.apache.solr.hadoop.MapReduceIndexerTool %* diff --git a/solr/example/scripts/solr-mr/solr-mr.sh b/solr/example/scripts/solr-mr/solr-mr.sh new file mode 100644 index 00000000000..f48eaae336b --- /dev/null +++ b/solr/example/scripts/solr-mr/solr-mr.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +JVM="java" + +# Find location of this script + +sdir="`dirname \"$0\"`" + +PATH=$JAVA_HOME/bin:$PATH $JVM -cp "$sdir/../../../dist/*:$sdir/../../../contrib/solr-mr/lib/*:$sdir/../../../contrib/solr-morphlines-core/lib/*:$sdir/../../../contrib/solr-morphlines-cell/lib/*:$sdir/../../../contrib/extraction/lib/*:$sdir/../../solr-webapp/solr/WEB-INF/lib/*:$sdir/../../lib/ext/*" org.apache.solr.hadoop.MapReduceIndexerTool ${1+"$@"} + diff --git a/solr/licenses/Saxon-HE-9.5.1-2.jar.sha1 b/solr/licenses/Saxon-HE-9.5.1-2.jar.sha1 new file mode 100644 index 00000000000..2d919372410 --- /dev/null +++ b/solr/licenses/Saxon-HE-9.5.1-2.jar.sha1 @@ -0,0 +1 @@ +02a76558799673a46d88914e11b247dcf80ba92c diff --git a/solr/licenses/Saxon-HE-LICENSE-MPL.txt b/solr/licenses/Saxon-HE-LICENSE-MPL.txt new file mode 100644 index 00000000000..608cd2ef524 --- /dev/null +++ b/solr/licenses/Saxon-HE-LICENSE-MPL.txt @@ -0,0 +1,108 @@ +MOZILLA PUBLIC LICENSE +Version 1.0 + +1. Definitions. + +1.1. ``Contributor'' means each entity that creates or contributes to the creation of Modifications. +1.2. ``Contributor Version'' means the combination of the Original Code, prior Modifications used by a Contributor, and the Modifications made by that particular Contributor. + +1.3. ``Covered Code'' means the Original Code or Modifications or the combination of the Original Code and Modifications, in each case including portions thereof. + +1.4. ``Electronic Distribution Mechanism'' means a mechanism generally accepted in the software development community for the electronic transfer of data. + +1.5. ``Executable'' means Covered Code in any form other than Source Code. + +1.6. ``Initial Developer'' means the individual or entity identified as the Initial Developer in the Source Code notice required by Exhibit A. + +1.7. ``Larger Work'' means a work which combines Covered Code or portions thereof with code not governed by the terms of this License. + +1.8. ``License'' means this document. + +1.9. ``Modifications'' means any addition to or deletion from the substance or structure of either the Original Code or any previous Modifications. When Covered Code is released as a series of files, a Modification is: + +A. Any addition to or deletion from the contents of a file containing Original Code or previous Modifications. + +B. Any new file that contains any part of the Original Code or previous Modifications. + +1.10. ``Original Code'' means Source Code of computer software code which is described in the Source Code notice required by Exhibit A as Original Code, and which, at the time of its release under this License is not already Covered Code governed by this License. + +1.11. ``Source Code'' means the preferred form of the Covered Code for making modifications to it, including all modules it contains, plus any associated interface definition files, scripts used to control compilation and installation of an Executable, or a list of source code differential comparisons against either the Original Code or another well known, available Covered Code of the Contributor's choice. The Source Code can be in a compressed or archival form, provided the appropriate decompression or de-archiving software is widely available for no charge. + +1.12. ``You'' means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License or a future version of this License issued under Section 6.1. For legal entities, ``You'' includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, ``control'' means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of fifty percent (50%) or more of the outstanding shares or beneficial ownership of such entity. + +2. Source Code License. +2.1. The Initial Developer Grant. +The Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license, subject to third party intellectual property claims: +(a) to use, reproduce, modify, display, perform, sublicense and distribute the Original Code (or portions thereof) with or without Modifications, or as part of a Larger Work; and + +(b) under patents now or hereafter owned or controlled by Initial Developer, to make, have made, use and sell (``Utilize'') the Original Code (or portions thereof), but solely to the extent that any such patent is reasonably necessary to enable You to Utilize the Original Code (or portions thereof) and not to any greater extent that may be necessary to Utilize further Modifications or combinations. + +2.2. Contributor Grant. +Each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license, subject to third party intellectual property claims: + +(a) to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof) either on an unmodified basis, with other Modifications, as Covered Code or as part of a Larger Work; and + +(b) under patents now or hereafter owned or controlled by Contributor, to Utilize the Contributor Version (or portions thereof), but solely to the extent that any such patent is reasonably necessary to enable You to Utilize the Contributor Version (or portions thereof), and not to any greater extent that may be necessary to Utilize further Modifications or combinations. + +3. Distribution Obligations. +3.1. Application of License. +The Modifications which You create or to which You contribute are governed by the terms of this License, including without limitation Section 2.2. The Source Code version of Covered Code may be distributed only under the terms of this License or a future version of this License released under Section 6.1, and You must include a copy of this License with every copy of the Source Code You distribute. You may not offer or impose any terms on any Source Code version that alters or restricts the applicable version of this License or the recipients' rights hereunder. However, You may include an additional document offering the additional rights described in Section 3.5. +3.2. Availability of Source Code. +Any Modification which You create or to which You contribute must be made available in Source Code form under the terms of this License either on the same media as an Executable version or via an accepted Electronic Distribution Mechanism to anyone to whom you made an Executable version available; and if made available via Electronic Distribution Mechanism, must remain available for at least twelve (12) months after the date it initially became available, or at least six (6) months after a subsequent version of that particular Modification has been made available to such recipients. You are responsible for ensuring that the Source Code version remains available even if the Electronic Distribution Mechanism is maintained by a third party. + +3.3. Description of Modifications. +You must cause all Covered Code to which you contribute to contain a file documenting the changes You made to create that Covered Code and the date of any change. You must include a prominent statement that the Modification is derived, directly or indirectly, from Original Code provided by the Initial Developer and including the name of the Initial Developer in (a) the Source Code, and (b) in any notice in an Executable version or related documentation in which You describe the origin or ownership of the Covered Code. + +3.4. Intellectual Property Matters + +(a) Third Party Claims. +If You have knowledge that a party claims an intellectual property right in particular functionality or code (or its utilization under this License), you must include a text file with the source code distribution titled ``LEGAL'' which describes the claim and the party making the claim in sufficient detail that a recipient will know whom to contact. If you obtain such knowledge after You make Your Modification available as described in Section 3.2, You shall promptly modify the LEGAL file in all copies You make available thereafter and shall take other steps (such as notifying appropriate mailing lists or newsgroups) reasonably calculated to inform those who received the Covered Code that new knowledge has been obtained. + +(b) Contributor APIs. +If Your Modification is an application programming interface and You own or control patents which are reasonably necessary to implement that API, you must also include this information in the LEGAL file. + +3.5. Required Notices. +You must duplicate the notice in Exhibit A in each file of the Source Code, and this License in any documentation for the Source Code, where You describe recipients' rights relating to Covered Code. If You created one or more Modification(s), You may add your name as a Contributor to the notice described in Exhibit A. If it is not possible to put such notice in a particular Source Code file due to its structure, then you must include such notice in a location (such as a relevant directory file) where a user would be likely to look for such a notice. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Code. However, You may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear than any such warranty, support, indemnity or liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of warranty, support, indemnity or liability terms You offer. + +3.6. Distribution of Executable Versions. +You may distribute Covered Code in Executable form only if the requirements of Section 3.1-3.5 have been met for that Covered Code, and if You include a notice stating that the Source Code version of the Covered Code is available under the terms of this License, including a description of how and where You have fulfilled the obligations of Section 3.2. The notice must be conspicuously included in any notice in an Executable version, related documentation or collateral in which You describe recipients' rights relating to the Covered Code. You may distribute the Executable version of Covered Code under a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable version does not attempt to limit or alter the recipient's rights in the Source Code version from the rights set forth in this License. If You distribute the Executable version under a different license You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or any Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer. + +3.7. Larger Works. +You may create a Larger Work by combining Covered Code with other code not governed by the terms of this License and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this License are fulfilled for the Covered Code. + +4. Inability to Comply Due to Statute or Regulation. +If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Code due to statute or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) describe the limitations and the code they affect. Such description must be included in the LEGAL file described in Section 3.4 and must be included with all distributions of the Source Code. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill to be able to understand it. + +5. Application of this License. +This License applies to code to which the Initial Developer has attached the notice in Exhibit A, and to related Covered Code. +6. Versions of the License. +6.1. New Versions. +Netscape Communications Corporation (``Netscape'') may publish revised and/or new versions of the License from time to time. Each version will be given a distinguishing version number. +6.2. Effect of New Versions. +Once Covered Code has been published under a particular version of the License, You may always continue to use it under the terms of that version. You may also choose to use such Covered Code under the terms of any subsequent version of the License published by Netscape. No one other than Netscape has the right to modify the terms applicable to Covered Code created under this License. + +6.3. Derivative Works. +If you create or use a modified version of this License (which you may only do in order to apply it to code which is not already Covered Code governed by this License), you must (a) rename Your license so that the phrases ``Mozilla'', ``MOZILLAPL'', ``MOZPL'', ``Netscape'', ``NPL'' or any confusingly similar phrase do not appear anywhere in your license and (b) otherwise make it clear that your version of the license contains terms which differ from the Mozilla Public License and Netscape Public License. (Filling in the name of the Initial Developer, Original Code or Contributor in the notice described in Exhibit A shall not of themselves be deemed to be modifications of this License.) + +7. DISCLAIMER OF WARRANTY. +COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN ``AS IS'' BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. +8. TERMINATION. +This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach within 30 days of becoming aware of the breach. All sublicenses to the Covered Code which are properly granted shall survive any termination of this License. Provisions which, by their nature, must remain in effect beyond the termination of this License shall survive. +9. LIMITATION OF LIABILITY. +UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL THE INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THAT EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. +10. U.S. GOVERNMENT END USERS. +The Covered Code is a ``commercial item,'' as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of ``commercial computer software'' and ``commercial computer software documentation,'' as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Code with only those rights set forth herein. +11. MISCELLANEOUS. +This License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by California law provisions (except to the extent applicable law, if any, provides otherwise), excluding its conflict-of-law provisions. With respect to disputes in which at least one party is a citizen of, or an entity chartered or registered to do business in, the United States of America: (a) unless otherwise agreed in writing, all disputes relating to this License (excepting any dispute relating to intellectual property rights) shall be subject to final and binding arbitration, with the losing party paying all costs of arbitration; (b) any arbitration relating to this Agreement shall be held in Santa Clara County, California, under the auspices of JAMS/EndDispute; and (c) any litigation relating to this Agreement shall be subject to the jurisdiction of the Federal Courts of the Northern District of California, with venue lying in Santa Clara County, California, with the losing party responsible for costs, including without limitation, court costs and reasonable attorneys fees and expenses. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License. +12. RESPONSIBILITY FOR CLAIMS. +Except in cases where another Contributor has failed to comply with Section 3.4, You are responsible for damages arising, directly or indirectly, out of Your utilization of rights under this License, based on the number of copies of Covered Code you made available, the revenues you received from utilizing such rights, and other relevant factors. You agree to work with affected parties to distribute responsibility on an equitable basis. +EXHIBIT A. +``The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ +Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. + +The Original Code is ______________________________________. + +The Initial Developer of the Original Code is ________________________. Portions created by ______________________ are Copyright (C) ______ _______________________. All Rights Reserved. + +Contributor(s): ______________________________________.'' + diff --git a/solr/licenses/aopalliance-1.0.jar.sha1 b/solr/licenses/aopalliance-1.0.jar.sha1 new file mode 100644 index 00000000000..5da3c21c7f4 --- /dev/null +++ b/solr/licenses/aopalliance-1.0.jar.sha1 @@ -0,0 +1 @@ +0235ba8b489512805ac13a8f9ea77a1ca5ebe3e8 diff --git a/solr/licenses/aopalliance-LICENSE-PD.txt b/solr/licenses/aopalliance-LICENSE-PD.txt new file mode 100644 index 00000000000..c75d4e6d9aa --- /dev/null +++ b/solr/licenses/aopalliance-LICENSE-PD.txt @@ -0,0 +1 @@ +Released to Public Domain \ No newline at end of file diff --git a/solr/licenses/argparse4j-0.4.0.jar.sha1 b/solr/licenses/argparse4j-0.4.0.jar.sha1 new file mode 100644 index 00000000000..142c614e02f --- /dev/null +++ b/solr/licenses/argparse4j-0.4.0.jar.sha1 @@ -0,0 +1 @@ +d6ec4128ff0a3ef64f992f1d489b2b4179c8ba81 diff --git a/solr/licenses/argparse4j-LICENSE-MIT.txt b/solr/licenses/argparse4j-LICENSE-MIT.txt new file mode 100644 index 00000000000..42612cfa84a --- /dev/null +++ b/solr/licenses/argparse4j-LICENSE-MIT.txt @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2011, 2013 Tatsuhiro Tsujikawa + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ \ No newline at end of file diff --git a/solr/licenses/asm-3.1.jar.sha1 b/solr/licenses/asm-3.1.jar.sha1 new file mode 100644 index 00000000000..f746051b226 --- /dev/null +++ b/solr/licenses/asm-3.1.jar.sha1 @@ -0,0 +1 @@ +c157def142714c544bdea2e6144645702adf7097 diff --git a/solr/licenses/asm-LICENSE-BSD.txt b/solr/licenses/asm-LICENSE-BSD.txt new file mode 100644 index 00000000000..dda31be0099 --- /dev/null +++ b/solr/licenses/asm-LICENSE-BSD.txt @@ -0,0 +1,29 @@ +/*** + * ASM: a very small and fast Java bytecode manipulation framework + * Copyright (c) 2000-2007 INRIA, France Telecom + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ \ No newline at end of file diff --git a/solr/licenses/aspectjrt-1.6.11.jar.sha1 b/solr/licenses/aspectjrt-1.6.11.jar.sha1 new file mode 100644 index 00000000000..8ee4319d892 --- /dev/null +++ b/solr/licenses/aspectjrt-1.6.11.jar.sha1 @@ -0,0 +1 @@ +70afce58891e5f0566a968288c93120b977e3bd0 diff --git a/solr/licenses/aspectjrt-LICENSE-EPL.txt b/solr/licenses/aspectjrt-LICENSE-EPL.txt new file mode 100644 index 00000000000..c93934f3940 --- /dev/null +++ b/solr/licenses/aspectjrt-LICENSE-EPL.txt @@ -0,0 +1,71 @@ +Eclipse Public License - v 1.0 + +THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +1. DEFINITIONS + +"Contribution" means: + +a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and +b) in the case of each subsequent Contributor: +i) changes to the Program, and +ii) additions to the Program; +where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. +"Contributor" means any person or entity that distributes the Program. + +"Licensed Patents" mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. + +"Program" means the Contributions distributed in accordance with this Agreement. + +"Recipient" means anyone who receives the Program under this Agreement, including all Contributors. + +2. GRANT OF RIGHTS + +a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. +b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. +c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. +d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. +3. REQUIREMENTS + +A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: + +a) it complies with the terms and conditions of this Agreement; and +b) its license agreement: +i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; +ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; +iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and +iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. +When the Program is made available in source code form: + +a) it must be made available under this Agreement; and +b) a copy of this Agreement must be included with each copy of the Program. +Contributors may not remove or alter any copyright notices contained within the Program. + +Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. + +For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +7. GENERAL + +If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. + +If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. + +All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. + +Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. + +This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. + diff --git a/solr/licenses/avro-1.7.4.jar.sha1 b/solr/licenses/avro-1.7.4.jar.sha1 new file mode 100644 index 00000000000..d2d38cd1d91 --- /dev/null +++ b/solr/licenses/avro-1.7.4.jar.sha1 @@ -0,0 +1 @@ +416e7030879814f52845b97f04bb50ecd1cef372 diff --git a/solr/licenses/avro-LICENSE-ASL.txt b/solr/licenses/avro-LICENSE-ASL.txt new file mode 100644 index 00000000000..2f23f979d2d --- /dev/null +++ b/solr/licenses/avro-LICENSE-ASL.txt @@ -0,0 +1,308 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +---------------------------------------------------------------------- +License for the Jansson C JSON parser used in the C implementation: + +Copyright (c) 2009 Petri Lehtinen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------- +License for the Json.NET used in the C# implementation: + +Copyright (c) 2007 James Newton-King + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +---------------------------------------------------------------------- +License for msinttypes used in the C implementation: +Source from: +http://code.google.com/p/msinttypes/downloads/detail?name=msinttypes-r26.zip + +Copyright (c) 2006-2008 Alexander Chemeris + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +License for Dirent API for Microsoft Visual Studio used in the C implementation: +Source from: +http://www.softagalleria.net/download/dirent/dirent-1.11.zip + +Copyright (C) 2006 Toni Ronkko + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +``Software''), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL TONI RONKKO BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +---------------------------------------------------------------------- \ No newline at end of file diff --git a/solr/licenses/avro-NOTICE.txt b/solr/licenses/avro-NOTICE.txt new file mode 100644 index 00000000000..da479fec1be --- /dev/null +++ b/solr/licenses/avro-NOTICE.txt @@ -0,0 +1,9 @@ +Apache Avro +Copyright 2010 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +C JSON parsing provided by Jansson and +written by Petri Lehtinen. The original software is +available from http://www.digip.org/jansson/. \ No newline at end of file diff --git a/solr/licenses/cdk-morphlines-avro-0.8.1.jar.sha1 b/solr/licenses/cdk-morphlines-avro-0.8.1.jar.sha1 new file mode 100644 index 00000000000..d18d6607c4f --- /dev/null +++ b/solr/licenses/cdk-morphlines-avro-0.8.1.jar.sha1 @@ -0,0 +1 @@ +571c226f5ac71ce5fd23ae9aafb363eb4c58481f diff --git a/solr/licenses/cdk-morphlines-avro-LICENSE-ASL.txt b/solr/licenses/cdk-morphlines-avro-LICENSE-ASL.txt new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/solr/licenses/cdk-morphlines-avro-LICENSE-ASL.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/solr/licenses/cdk-morphlines-avro-NOTICE.txt b/solr/licenses/cdk-morphlines-avro-NOTICE.txt new file mode 100644 index 00000000000..e66f59741cd --- /dev/null +++ b/solr/licenses/cdk-morphlines-avro-NOTICE.txt @@ -0,0 +1,8 @@ +This product includes software developed by Cloudera, Inc. +(http://www.cloudera.com/). + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +This product includes software developed by +Saxonica (http://www.saxonica.com/). \ No newline at end of file diff --git a/solr/licenses/cdk-morphlines-core-0.8.1-tests.jar.sha1 b/solr/licenses/cdk-morphlines-core-0.8.1-tests.jar.sha1 new file mode 100644 index 00000000000..9018483ca64 --- /dev/null +++ b/solr/licenses/cdk-morphlines-core-0.8.1-tests.jar.sha1 @@ -0,0 +1 @@ +93b395579f13f4387c90d370f5f6fdb054070a3e diff --git a/solr/licenses/cdk-morphlines-core-0.8.1.jar.sha1 b/solr/licenses/cdk-morphlines-core-0.8.1.jar.sha1 new file mode 100644 index 00000000000..ea6f85d696c --- /dev/null +++ b/solr/licenses/cdk-morphlines-core-0.8.1.jar.sha1 @@ -0,0 +1 @@ +c0b87a3c7377db58e328dfecb850323d99655775 diff --git a/solr/licenses/cdk-morphlines-core-LICENSE-ASL.txt b/solr/licenses/cdk-morphlines-core-LICENSE-ASL.txt new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/solr/licenses/cdk-morphlines-core-LICENSE-ASL.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/solr/licenses/cdk-morphlines-core-NOTICE.txt b/solr/licenses/cdk-morphlines-core-NOTICE.txt new file mode 100644 index 00000000000..e66f59741cd --- /dev/null +++ b/solr/licenses/cdk-morphlines-core-NOTICE.txt @@ -0,0 +1,8 @@ +This product includes software developed by Cloudera, Inc. +(http://www.cloudera.com/). + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +This product includes software developed by +Saxonica (http://www.saxonica.com/). \ No newline at end of file diff --git a/solr/licenses/cdk-morphlines-hadoop-sequencefile-0.8.1.jar.sha1 b/solr/licenses/cdk-morphlines-hadoop-sequencefile-0.8.1.jar.sha1 new file mode 100644 index 00000000000..5efdde56d53 --- /dev/null +++ b/solr/licenses/cdk-morphlines-hadoop-sequencefile-0.8.1.jar.sha1 @@ -0,0 +1 @@ +c50c9ff93fcf4007dba04edb3f07872849b5aebb diff --git a/solr/licenses/cdk-morphlines-hadoop-sequencefile-LICENSE-ASL.txt b/solr/licenses/cdk-morphlines-hadoop-sequencefile-LICENSE-ASL.txt new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/solr/licenses/cdk-morphlines-hadoop-sequencefile-LICENSE-ASL.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/solr/licenses/cdk-morphlines-hadoop-sequencefile-NOTICE.txt b/solr/licenses/cdk-morphlines-hadoop-sequencefile-NOTICE.txt new file mode 100644 index 00000000000..e66f59741cd --- /dev/null +++ b/solr/licenses/cdk-morphlines-hadoop-sequencefile-NOTICE.txt @@ -0,0 +1,8 @@ +This product includes software developed by Cloudera, Inc. +(http://www.cloudera.com/). + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +This product includes software developed by +Saxonica (http://www.saxonica.com/). \ No newline at end of file diff --git a/solr/licenses/cdk-morphlines-json-0.8.1.jar.sha1 b/solr/licenses/cdk-morphlines-json-0.8.1.jar.sha1 new file mode 100644 index 00000000000..6c50b027662 --- /dev/null +++ b/solr/licenses/cdk-morphlines-json-0.8.1.jar.sha1 @@ -0,0 +1 @@ +494a6d3bcbba7abc8fddf25ac511e51c7c5a2ff9 diff --git a/solr/licenses/cdk-morphlines-json-LICENSE-ASL.txt b/solr/licenses/cdk-morphlines-json-LICENSE-ASL.txt new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/solr/licenses/cdk-morphlines-json-LICENSE-ASL.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/solr/licenses/cdk-morphlines-json-NOTICE.txt b/solr/licenses/cdk-morphlines-json-NOTICE.txt new file mode 100644 index 00000000000..e66f59741cd --- /dev/null +++ b/solr/licenses/cdk-morphlines-json-NOTICE.txt @@ -0,0 +1,8 @@ +This product includes software developed by Cloudera, Inc. +(http://www.cloudera.com/). + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +This product includes software developed by +Saxonica (http://www.saxonica.com/). \ No newline at end of file diff --git a/solr/licenses/cdk-morphlines-saxon-0.8.1.jar.sha1 b/solr/licenses/cdk-morphlines-saxon-0.8.1.jar.sha1 new file mode 100644 index 00000000000..486d6a6c692 --- /dev/null +++ b/solr/licenses/cdk-morphlines-saxon-0.8.1.jar.sha1 @@ -0,0 +1 @@ +9805d7f1cf0240869c02832651fc4518bac77cf9 diff --git a/solr/licenses/cdk-morphlines-saxon-LICENSE-ASL.txt b/solr/licenses/cdk-morphlines-saxon-LICENSE-ASL.txt new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/solr/licenses/cdk-morphlines-saxon-LICENSE-ASL.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/solr/licenses/cdk-morphlines-saxon-NOTICE.txt b/solr/licenses/cdk-morphlines-saxon-NOTICE.txt new file mode 100644 index 00000000000..e66f59741cd --- /dev/null +++ b/solr/licenses/cdk-morphlines-saxon-NOTICE.txt @@ -0,0 +1,8 @@ +This product includes software developed by Cloudera, Inc. +(http://www.cloudera.com/). + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +This product includes software developed by +Saxonica (http://www.saxonica.com/). \ No newline at end of file diff --git a/solr/licenses/cdk-morphlines-tika-core-0.8.1.jar.sha1 b/solr/licenses/cdk-morphlines-tika-core-0.8.1.jar.sha1 new file mode 100644 index 00000000000..312593060bd --- /dev/null +++ b/solr/licenses/cdk-morphlines-tika-core-0.8.1.jar.sha1 @@ -0,0 +1 @@ +96c3497423c8fb2c2fd75f836960e40b7e69454d diff --git a/solr/licenses/cdk-morphlines-tika-core-LICENSE-ASL.txt b/solr/licenses/cdk-morphlines-tika-core-LICENSE-ASL.txt new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/solr/licenses/cdk-morphlines-tika-core-LICENSE-ASL.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/solr/licenses/cdk-morphlines-tika-core-NOTICE.txt b/solr/licenses/cdk-morphlines-tika-core-NOTICE.txt new file mode 100644 index 00000000000..e66f59741cd --- /dev/null +++ b/solr/licenses/cdk-morphlines-tika-core-NOTICE.txt @@ -0,0 +1,8 @@ +This product includes software developed by Cloudera, Inc. +(http://www.cloudera.com/). + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +This product includes software developed by +Saxonica (http://www.saxonica.com/). \ No newline at end of file diff --git a/solr/licenses/cdk-morphlines-tika-decompress-0.8.1.jar.sha1 b/solr/licenses/cdk-morphlines-tika-decompress-0.8.1.jar.sha1 new file mode 100644 index 00000000000..36e3c3f6628 --- /dev/null +++ b/solr/licenses/cdk-morphlines-tika-decompress-0.8.1.jar.sha1 @@ -0,0 +1 @@ +060ccc1dda318af6826feca736c6c25ef9c8f207 diff --git a/solr/licenses/cdk-morphlines-tika-decompress-LICENSE-ASL.txt b/solr/licenses/cdk-morphlines-tika-decompress-LICENSE-ASL.txt new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/solr/licenses/cdk-morphlines-tika-decompress-LICENSE-ASL.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/solr/licenses/cdk-morphlines-tika-decompress-NOTICE.txt b/solr/licenses/cdk-morphlines-tika-decompress-NOTICE.txt new file mode 100644 index 00000000000..e66f59741cd --- /dev/null +++ b/solr/licenses/cdk-morphlines-tika-decompress-NOTICE.txt @@ -0,0 +1,8 @@ +This product includes software developed by Cloudera, Inc. +(http://www.cloudera.com/). + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +This product includes software developed by +Saxonica (http://www.saxonica.com/). \ No newline at end of file diff --git a/solr/licenses/cdk-morphlines-twitter-0.8.1.jar.sha1 b/solr/licenses/cdk-morphlines-twitter-0.8.1.jar.sha1 new file mode 100644 index 00000000000..8368d3d6ab5 --- /dev/null +++ b/solr/licenses/cdk-morphlines-twitter-0.8.1.jar.sha1 @@ -0,0 +1 @@ +d950d1f83ff52f4c8d948962c57bd60252c5e773 diff --git a/solr/licenses/cdk-morphlines-twitter-LICENSE-ASL.txt b/solr/licenses/cdk-morphlines-twitter-LICENSE-ASL.txt new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/solr/licenses/cdk-morphlines-twitter-LICENSE-ASL.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/solr/licenses/cdk-morphlines-twitter-NOTICE.txt b/solr/licenses/cdk-morphlines-twitter-NOTICE.txt new file mode 100644 index 00000000000..e66f59741cd --- /dev/null +++ b/solr/licenses/cdk-morphlines-twitter-NOTICE.txt @@ -0,0 +1,8 @@ +This product includes software developed by Cloudera, Inc. +(http://www.cloudera.com/). + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +This product includes software developed by +Saxonica (http://www.saxonica.com/). \ No newline at end of file diff --git a/solr/licenses/config-1.0.2.jar.sha1 b/solr/licenses/config-1.0.2.jar.sha1 new file mode 100644 index 00000000000..6dbf80d7f94 --- /dev/null +++ b/solr/licenses/config-1.0.2.jar.sha1 @@ -0,0 +1 @@ +a0bca82c39f23f75e3afccd6e12840eeabaea123 diff --git a/solr/licenses/config-LICENSE-ASL.txt b/solr/licenses/config-LICENSE-ASL.txt new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/solr/licenses/config-LICENSE-ASL.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/solr/licenses/config-NOTICE.txt b/solr/licenses/config-NOTICE.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/solr/licenses/guice-3.0.jar.sha1 b/solr/licenses/guice-3.0.jar.sha1 new file mode 100644 index 00000000000..7ce1a30309c --- /dev/null +++ b/solr/licenses/guice-3.0.jar.sha1 @@ -0,0 +1 @@ +9d84f15fe35e2c716a02979fb62f50a29f38aefa diff --git a/solr/licenses/guice-LICENSE-ASL.txt b/solr/licenses/guice-LICENSE-ASL.txt new file mode 100644 index 00000000000..7a4a3ea2424 --- /dev/null +++ b/solr/licenses/guice-LICENSE-ASL.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/solr/licenses/guice-NOTICE.txt b/solr/licenses/guice-NOTICE.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/solr/licenses/guice-servlet-3.0.jar.sha1 b/solr/licenses/guice-servlet-3.0.jar.sha1 new file mode 100644 index 00000000000..a496feb6904 --- /dev/null +++ b/solr/licenses/guice-servlet-3.0.jar.sha1 @@ -0,0 +1 @@ +610cde0e8da5a8b7d8efb8f0b8987466ffebaaf9 diff --git a/solr/licenses/guice-servlet-LICENSE-ASL.txt b/solr/licenses/guice-servlet-LICENSE-ASL.txt new file mode 100644 index 00000000000..7a4a3ea2424 --- /dev/null +++ b/solr/licenses/guice-servlet-LICENSE-ASL.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/solr/licenses/guice-servlet-NOTICE.txt b/solr/licenses/guice-servlet-NOTICE.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/solr/licenses/hadoop-mapreduce-client-app-2.2.0.jar.sha1 b/solr/licenses/hadoop-mapreduce-client-app-2.2.0.jar.sha1 new file mode 100644 index 00000000000..32c3a59dcc7 --- /dev/null +++ b/solr/licenses/hadoop-mapreduce-client-app-2.2.0.jar.sha1 @@ -0,0 +1 @@ +9e5bdd970000b330382128350a957609cbcfe348 diff --git a/solr/licenses/hadoop-mapreduce-client-app-LICENSE-ASL.txt b/solr/licenses/hadoop-mapreduce-client-app-LICENSE-ASL.txt new file mode 100644 index 00000000000..9a8e847ee84 --- /dev/null +++ b/solr/licenses/hadoop-mapreduce-client-app-LICENSE-ASL.txt @@ -0,0 +1,244 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +APACHE HADOOP SUBCOMPONENTS: + +The Apache Hadoop project contains subcomponents with separate copyright +notices and license terms. Your use of the source code for the these +subcomponents is subject to the terms and conditions of the following +licenses. + +For the org.apache.hadoop.util.bloom.* classes: + +/** + * + * Copyright (c) 2005, European Commission project OneLab under contract + * 034819 (http://www.one-lab.org) + * All rights reserved. + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * - Neither the name of the University Catholique de Louvain - UCL + * nor the names of its contributors may be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ \ No newline at end of file diff --git a/solr/licenses/hadoop-mapreduce-client-app-NOTICE.txt b/solr/licenses/hadoop-mapreduce-client-app-NOTICE.txt new file mode 100644 index 00000000000..c56a5e4eac1 --- /dev/null +++ b/solr/licenses/hadoop-mapreduce-client-app-NOTICE.txt @@ -0,0 +1,2 @@ +This product includes software developed by The Apache Software +Foundation (http://www.apache.org/). \ No newline at end of file diff --git a/solr/licenses/hadoop-mapreduce-client-common-2.2.0.jar.sha1 b/solr/licenses/hadoop-mapreduce-client-common-2.2.0.jar.sha1 new file mode 100644 index 00000000000..87cb25e47b1 --- /dev/null +++ b/solr/licenses/hadoop-mapreduce-client-common-2.2.0.jar.sha1 @@ -0,0 +1 @@ +5600fdda58499e3901bf179f1614a8ca38090871 diff --git a/solr/licenses/hadoop-mapreduce-client-common-LICENSE-ASL.txt b/solr/licenses/hadoop-mapreduce-client-common-LICENSE-ASL.txt new file mode 100644 index 00000000000..9a8e847ee84 --- /dev/null +++ b/solr/licenses/hadoop-mapreduce-client-common-LICENSE-ASL.txt @@ -0,0 +1,244 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +APACHE HADOOP SUBCOMPONENTS: + +The Apache Hadoop project contains subcomponents with separate copyright +notices and license terms. Your use of the source code for the these +subcomponents is subject to the terms and conditions of the following +licenses. + +For the org.apache.hadoop.util.bloom.* classes: + +/** + * + * Copyright (c) 2005, European Commission project OneLab under contract + * 034819 (http://www.one-lab.org) + * All rights reserved. + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * - Neither the name of the University Catholique de Louvain - UCL + * nor the names of its contributors may be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ \ No newline at end of file diff --git a/solr/licenses/hadoop-mapreduce-client-common-NOTICE.txt b/solr/licenses/hadoop-mapreduce-client-common-NOTICE.txt new file mode 100644 index 00000000000..c56a5e4eac1 --- /dev/null +++ b/solr/licenses/hadoop-mapreduce-client-common-NOTICE.txt @@ -0,0 +1,2 @@ +This product includes software developed by The Apache Software +Foundation (http://www.apache.org/). \ No newline at end of file diff --git a/solr/licenses/hadoop-mapreduce-client-core-2.2.0.jar.sha1 b/solr/licenses/hadoop-mapreduce-client-core-2.2.0.jar.sha1 new file mode 100644 index 00000000000..ead6387a193 --- /dev/null +++ b/solr/licenses/hadoop-mapreduce-client-core-2.2.0.jar.sha1 @@ -0,0 +1 @@ +4be274d45f35543d3c4dd8e2bfed2cebc56696c7 diff --git a/solr/licenses/hadoop-mapreduce-client-core-LICENSE-ASL.txt b/solr/licenses/hadoop-mapreduce-client-core-LICENSE-ASL.txt new file mode 100644 index 00000000000..9a8e847ee84 --- /dev/null +++ b/solr/licenses/hadoop-mapreduce-client-core-LICENSE-ASL.txt @@ -0,0 +1,244 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +APACHE HADOOP SUBCOMPONENTS: + +The Apache Hadoop project contains subcomponents with separate copyright +notices and license terms. Your use of the source code for the these +subcomponents is subject to the terms and conditions of the following +licenses. + +For the org.apache.hadoop.util.bloom.* classes: + +/** + * + * Copyright (c) 2005, European Commission project OneLab under contract + * 034819 (http://www.one-lab.org) + * All rights reserved. + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * - Neither the name of the University Catholique de Louvain - UCL + * nor the names of its contributors may be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ \ No newline at end of file diff --git a/solr/licenses/hadoop-mapreduce-client-core-NOTICE.txt b/solr/licenses/hadoop-mapreduce-client-core-NOTICE.txt new file mode 100644 index 00000000000..c56a5e4eac1 --- /dev/null +++ b/solr/licenses/hadoop-mapreduce-client-core-NOTICE.txt @@ -0,0 +1,2 @@ +This product includes software developed by The Apache Software +Foundation (http://www.apache.org/). \ No newline at end of file diff --git a/solr/licenses/hadoop-mapreduce-client-hs-2.2.0.jar.sha1 b/solr/licenses/hadoop-mapreduce-client-hs-2.2.0.jar.sha1 new file mode 100644 index 00000000000..455d9cdee85 --- /dev/null +++ b/solr/licenses/hadoop-mapreduce-client-hs-2.2.0.jar.sha1 @@ -0,0 +1 @@ +7c3b62138f881f1a98f02347b1002b9bde052b81 diff --git a/solr/licenses/hadoop-mapreduce-client-hs-LICENSE-ASL.txt b/solr/licenses/hadoop-mapreduce-client-hs-LICENSE-ASL.txt new file mode 100644 index 00000000000..9a8e847ee84 --- /dev/null +++ b/solr/licenses/hadoop-mapreduce-client-hs-LICENSE-ASL.txt @@ -0,0 +1,244 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +APACHE HADOOP SUBCOMPONENTS: + +The Apache Hadoop project contains subcomponents with separate copyright +notices and license terms. Your use of the source code for the these +subcomponents is subject to the terms and conditions of the following +licenses. + +For the org.apache.hadoop.util.bloom.* classes: + +/** + * + * Copyright (c) 2005, European Commission project OneLab under contract + * 034819 (http://www.one-lab.org) + * All rights reserved. + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * - Neither the name of the University Catholique de Louvain - UCL + * nor the names of its contributors may be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ \ No newline at end of file diff --git a/solr/licenses/hadoop-mapreduce-client-hs-NOTICE.txt b/solr/licenses/hadoop-mapreduce-client-hs-NOTICE.txt new file mode 100644 index 00000000000..c56a5e4eac1 --- /dev/null +++ b/solr/licenses/hadoop-mapreduce-client-hs-NOTICE.txt @@ -0,0 +1,2 @@ +This product includes software developed by The Apache Software +Foundation (http://www.apache.org/). \ No newline at end of file diff --git a/solr/licenses/hadoop-mapreduce-client-jobclient-2.2.0-tests.jar.sha1 b/solr/licenses/hadoop-mapreduce-client-jobclient-2.2.0-tests.jar.sha1 new file mode 100644 index 00000000000..67376200fee --- /dev/null +++ b/solr/licenses/hadoop-mapreduce-client-jobclient-2.2.0-tests.jar.sha1 @@ -0,0 +1 @@ +4c75b683a7d96a48172535c115b2067faf211cfc diff --git a/solr/licenses/hadoop-mapreduce-client-jobclient-2.2.0.jar.sha1 b/solr/licenses/hadoop-mapreduce-client-jobclient-2.2.0.jar.sha1 new file mode 100644 index 00000000000..8f63967662f --- /dev/null +++ b/solr/licenses/hadoop-mapreduce-client-jobclient-2.2.0.jar.sha1 @@ -0,0 +1 @@ +842d0c9d8793fd21bfbb1c6b1fa9fbc05698f76c diff --git a/solr/licenses/hadoop-mapreduce-client-jobclient-LICENSE-ASL.txt b/solr/licenses/hadoop-mapreduce-client-jobclient-LICENSE-ASL.txt new file mode 100644 index 00000000000..9a8e847ee84 --- /dev/null +++ b/solr/licenses/hadoop-mapreduce-client-jobclient-LICENSE-ASL.txt @@ -0,0 +1,244 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +APACHE HADOOP SUBCOMPONENTS: + +The Apache Hadoop project contains subcomponents with separate copyright +notices and license terms. Your use of the source code for the these +subcomponents is subject to the terms and conditions of the following +licenses. + +For the org.apache.hadoop.util.bloom.* classes: + +/** + * + * Copyright (c) 2005, European Commission project OneLab under contract + * 034819 (http://www.one-lab.org) + * All rights reserved. + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * - Neither the name of the University Catholique de Louvain - UCL + * nor the names of its contributors may be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ \ No newline at end of file diff --git a/solr/licenses/hadoop-mapreduce-client-jobclient-NOTICE.txt b/solr/licenses/hadoop-mapreduce-client-jobclient-NOTICE.txt new file mode 100644 index 00000000000..c56a5e4eac1 --- /dev/null +++ b/solr/licenses/hadoop-mapreduce-client-jobclient-NOTICE.txt @@ -0,0 +1,2 @@ +This product includes software developed by The Apache Software +Foundation (http://www.apache.org/). \ No newline at end of file diff --git a/solr/licenses/hadoop-mapreduce-client-shuffle-2.2.0.jar.sha1 b/solr/licenses/hadoop-mapreduce-client-shuffle-2.2.0.jar.sha1 new file mode 100644 index 00000000000..1845c5437bf --- /dev/null +++ b/solr/licenses/hadoop-mapreduce-client-shuffle-2.2.0.jar.sha1 @@ -0,0 +1 @@ +c4c9da8f8f6ab1e3ba68798f30360eff4ba52187 diff --git a/solr/licenses/hadoop-mapreduce-client-shuffle-LICENSE-ASL.txt b/solr/licenses/hadoop-mapreduce-client-shuffle-LICENSE-ASL.txt new file mode 100644 index 00000000000..9a8e847ee84 --- /dev/null +++ b/solr/licenses/hadoop-mapreduce-client-shuffle-LICENSE-ASL.txt @@ -0,0 +1,244 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +APACHE HADOOP SUBCOMPONENTS: + +The Apache Hadoop project contains subcomponents with separate copyright +notices and license terms. Your use of the source code for the these +subcomponents is subject to the terms and conditions of the following +licenses. + +For the org.apache.hadoop.util.bloom.* classes: + +/** + * + * Copyright (c) 2005, European Commission project OneLab under contract + * 034819 (http://www.one-lab.org) + * All rights reserved. + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * - Neither the name of the University Catholique de Louvain - UCL + * nor the names of its contributors may be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ \ No newline at end of file diff --git a/solr/licenses/hadoop-mapreduce-client-shuffle-NOTICE.txt b/solr/licenses/hadoop-mapreduce-client-shuffle-NOTICE.txt new file mode 100644 index 00000000000..c56a5e4eac1 --- /dev/null +++ b/solr/licenses/hadoop-mapreduce-client-shuffle-NOTICE.txt @@ -0,0 +1,2 @@ +This product includes software developed by The Apache Software +Foundation (http://www.apache.org/). \ No newline at end of file diff --git a/solr/licenses/hadoop-yarn-api-2.2.0.jar.sha1 b/solr/licenses/hadoop-yarn-api-2.2.0.jar.sha1 new file mode 100644 index 00000000000..c81f37c98eb --- /dev/null +++ b/solr/licenses/hadoop-yarn-api-2.2.0.jar.sha1 @@ -0,0 +1 @@ +655910becbe9c5c60033e9e64e95aab0ec4ce94a diff --git a/solr/licenses/hadoop-yarn-api-LICENSE-ASL.txt b/solr/licenses/hadoop-yarn-api-LICENSE-ASL.txt new file mode 100644 index 00000000000..9a8e847ee84 --- /dev/null +++ b/solr/licenses/hadoop-yarn-api-LICENSE-ASL.txt @@ -0,0 +1,244 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +APACHE HADOOP SUBCOMPONENTS: + +The Apache Hadoop project contains subcomponents with separate copyright +notices and license terms. Your use of the source code for the these +subcomponents is subject to the terms and conditions of the following +licenses. + +For the org.apache.hadoop.util.bloom.* classes: + +/** + * + * Copyright (c) 2005, European Commission project OneLab under contract + * 034819 (http://www.one-lab.org) + * All rights reserved. + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * - Neither the name of the University Catholique de Louvain - UCL + * nor the names of its contributors may be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ \ No newline at end of file diff --git a/solr/licenses/hadoop-yarn-api-NOTICE.txt b/solr/licenses/hadoop-yarn-api-NOTICE.txt new file mode 100644 index 00000000000..c56a5e4eac1 --- /dev/null +++ b/solr/licenses/hadoop-yarn-api-NOTICE.txt @@ -0,0 +1,2 @@ +This product includes software developed by The Apache Software +Foundation (http://www.apache.org/). \ No newline at end of file diff --git a/solr/licenses/hadoop-yarn-client-2.2.0.jar.sha1 b/solr/licenses/hadoop-yarn-client-2.2.0.jar.sha1 new file mode 100644 index 00000000000..ed769373d3f --- /dev/null +++ b/solr/licenses/hadoop-yarn-client-2.2.0.jar.sha1 @@ -0,0 +1 @@ +f299044dd9e546ca30a30014ef30699306e9ef3e diff --git a/solr/licenses/hadoop-yarn-client-LICENSE-ASL.txt b/solr/licenses/hadoop-yarn-client-LICENSE-ASL.txt new file mode 100644 index 00000000000..9a8e847ee84 --- /dev/null +++ b/solr/licenses/hadoop-yarn-client-LICENSE-ASL.txt @@ -0,0 +1,244 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +APACHE HADOOP SUBCOMPONENTS: + +The Apache Hadoop project contains subcomponents with separate copyright +notices and license terms. Your use of the source code for the these +subcomponents is subject to the terms and conditions of the following +licenses. + +For the org.apache.hadoop.util.bloom.* classes: + +/** + * + * Copyright (c) 2005, European Commission project OneLab under contract + * 034819 (http://www.one-lab.org) + * All rights reserved. + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * - Neither the name of the University Catholique de Louvain - UCL + * nor the names of its contributors may be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ \ No newline at end of file diff --git a/solr/licenses/hadoop-yarn-client-NOTICE.txt b/solr/licenses/hadoop-yarn-client-NOTICE.txt new file mode 100644 index 00000000000..c56a5e4eac1 --- /dev/null +++ b/solr/licenses/hadoop-yarn-client-NOTICE.txt @@ -0,0 +1,2 @@ +This product includes software developed by The Apache Software +Foundation (http://www.apache.org/). \ No newline at end of file diff --git a/solr/licenses/hadoop-yarn-common-2.2.0.jar.sha1 b/solr/licenses/hadoop-yarn-common-2.2.0.jar.sha1 new file mode 100644 index 00000000000..05d1a40d409 --- /dev/null +++ b/solr/licenses/hadoop-yarn-common-2.2.0.jar.sha1 @@ -0,0 +1 @@ +77f18c3d40dcb45b0be2602cfa5115a5edb40db1 diff --git a/solr/licenses/hadoop-yarn-common-LICENSE-ASL.txt b/solr/licenses/hadoop-yarn-common-LICENSE-ASL.txt new file mode 100644 index 00000000000..9a8e847ee84 --- /dev/null +++ b/solr/licenses/hadoop-yarn-common-LICENSE-ASL.txt @@ -0,0 +1,244 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +APACHE HADOOP SUBCOMPONENTS: + +The Apache Hadoop project contains subcomponents with separate copyright +notices and license terms. Your use of the source code for the these +subcomponents is subject to the terms and conditions of the following +licenses. + +For the org.apache.hadoop.util.bloom.* classes: + +/** + * + * Copyright (c) 2005, European Commission project OneLab under contract + * 034819 (http://www.one-lab.org) + * All rights reserved. + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * - Neither the name of the University Catholique de Louvain - UCL + * nor the names of its contributors may be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ \ No newline at end of file diff --git a/solr/licenses/hadoop-yarn-common-NOTICE.txt b/solr/licenses/hadoop-yarn-common-NOTICE.txt new file mode 100644 index 00000000000..c56a5e4eac1 --- /dev/null +++ b/solr/licenses/hadoop-yarn-common-NOTICE.txt @@ -0,0 +1,2 @@ +This product includes software developed by The Apache Software +Foundation (http://www.apache.org/). \ No newline at end of file diff --git a/solr/licenses/hadoop-yarn-server-common-2.2.0.jar.sha1 b/solr/licenses/hadoop-yarn-server-common-2.2.0.jar.sha1 new file mode 100644 index 00000000000..ad9a65e2451 --- /dev/null +++ b/solr/licenses/hadoop-yarn-server-common-2.2.0.jar.sha1 @@ -0,0 +1 @@ +ce13e5699bbe644da95bfd7e01549c6a389fec7f diff --git a/solr/licenses/hadoop-yarn-server-common-LICENSE-ASL.txt b/solr/licenses/hadoop-yarn-server-common-LICENSE-ASL.txt new file mode 100644 index 00000000000..9a8e847ee84 --- /dev/null +++ b/solr/licenses/hadoop-yarn-server-common-LICENSE-ASL.txt @@ -0,0 +1,244 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +APACHE HADOOP SUBCOMPONENTS: + +The Apache Hadoop project contains subcomponents with separate copyright +notices and license terms. Your use of the source code for the these +subcomponents is subject to the terms and conditions of the following +licenses. + +For the org.apache.hadoop.util.bloom.* classes: + +/** + * + * Copyright (c) 2005, European Commission project OneLab under contract + * 034819 (http://www.one-lab.org) + * All rights reserved. + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * - Neither the name of the University Catholique de Louvain - UCL + * nor the names of its contributors may be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ \ No newline at end of file diff --git a/solr/licenses/hadoop-yarn-server-common-NOTICE.txt b/solr/licenses/hadoop-yarn-server-common-NOTICE.txt new file mode 100644 index 00000000000..c56a5e4eac1 --- /dev/null +++ b/solr/licenses/hadoop-yarn-server-common-NOTICE.txt @@ -0,0 +1,2 @@ +This product includes software developed by The Apache Software +Foundation (http://www.apache.org/). \ No newline at end of file diff --git a/solr/licenses/hadoop-yarn-server-nodemanager-2.2.0.jar.sha1 b/solr/licenses/hadoop-yarn-server-nodemanager-2.2.0.jar.sha1 new file mode 100644 index 00000000000..52551013e9c --- /dev/null +++ b/solr/licenses/hadoop-yarn-server-nodemanager-2.2.0.jar.sha1 @@ -0,0 +1 @@ +5e7f0f16676afffff62919578bcb5606e3548f36 diff --git a/solr/licenses/hadoop-yarn-server-nodemanager-LICENSE-ASL.txt b/solr/licenses/hadoop-yarn-server-nodemanager-LICENSE-ASL.txt new file mode 100644 index 00000000000..9a8e847ee84 --- /dev/null +++ b/solr/licenses/hadoop-yarn-server-nodemanager-LICENSE-ASL.txt @@ -0,0 +1,244 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +APACHE HADOOP SUBCOMPONENTS: + +The Apache Hadoop project contains subcomponents with separate copyright +notices and license terms. Your use of the source code for the these +subcomponents is subject to the terms and conditions of the following +licenses. + +For the org.apache.hadoop.util.bloom.* classes: + +/** + * + * Copyright (c) 2005, European Commission project OneLab under contract + * 034819 (http://www.one-lab.org) + * All rights reserved. + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * - Neither the name of the University Catholique de Louvain - UCL + * nor the names of its contributors may be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ \ No newline at end of file diff --git a/solr/licenses/hadoop-yarn-server-nodemanager-NOTICE.txt b/solr/licenses/hadoop-yarn-server-nodemanager-NOTICE.txt new file mode 100644 index 00000000000..c56a5e4eac1 --- /dev/null +++ b/solr/licenses/hadoop-yarn-server-nodemanager-NOTICE.txt @@ -0,0 +1,2 @@ +This product includes software developed by The Apache Software +Foundation (http://www.apache.org/). \ No newline at end of file diff --git a/solr/licenses/hadoop-yarn-server-resourcemanager-2.2.0.jar.sha1 b/solr/licenses/hadoop-yarn-server-resourcemanager-2.2.0.jar.sha1 new file mode 100644 index 00000000000..57843e0d07b --- /dev/null +++ b/solr/licenses/hadoop-yarn-server-resourcemanager-2.2.0.jar.sha1 @@ -0,0 +1 @@ +867da9c1c98a2c8c9b6cf7f3f9354818cd8831cf diff --git a/solr/licenses/hadoop-yarn-server-resourcemanager-LICENSE-ASL.txt b/solr/licenses/hadoop-yarn-server-resourcemanager-LICENSE-ASL.txt new file mode 100644 index 00000000000..9a8e847ee84 --- /dev/null +++ b/solr/licenses/hadoop-yarn-server-resourcemanager-LICENSE-ASL.txt @@ -0,0 +1,244 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +APACHE HADOOP SUBCOMPONENTS: + +The Apache Hadoop project contains subcomponents with separate copyright +notices and license terms. Your use of the source code for the these +subcomponents is subject to the terms and conditions of the following +licenses. + +For the org.apache.hadoop.util.bloom.* classes: + +/** + * + * Copyright (c) 2005, European Commission project OneLab under contract + * 034819 (http://www.one-lab.org) + * All rights reserved. + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * - Neither the name of the University Catholique de Louvain - UCL + * nor the names of its contributors may be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ \ No newline at end of file diff --git a/solr/licenses/hadoop-yarn-server-resourcemanager-NOTICE.txt b/solr/licenses/hadoop-yarn-server-resourcemanager-NOTICE.txt new file mode 100644 index 00000000000..c56a5e4eac1 --- /dev/null +++ b/solr/licenses/hadoop-yarn-server-resourcemanager-NOTICE.txt @@ -0,0 +1,2 @@ +This product includes software developed by The Apache Software +Foundation (http://www.apache.org/). \ No newline at end of file diff --git a/solr/licenses/hadoop-yarn-server-tests-2.2.0-tests.jar.sha1 b/solr/licenses/hadoop-yarn-server-tests-2.2.0-tests.jar.sha1 new file mode 100644 index 00000000000..dafd029f029 --- /dev/null +++ b/solr/licenses/hadoop-yarn-server-tests-2.2.0-tests.jar.sha1 @@ -0,0 +1 @@ +d6bf9776d45f3812a9011d768d571bc554706f05 diff --git a/solr/licenses/hadoop-yarn-server-tests-LICENSE-ASL.txt b/solr/licenses/hadoop-yarn-server-tests-LICENSE-ASL.txt new file mode 100644 index 00000000000..9a8e847ee84 --- /dev/null +++ b/solr/licenses/hadoop-yarn-server-tests-LICENSE-ASL.txt @@ -0,0 +1,244 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +APACHE HADOOP SUBCOMPONENTS: + +The Apache Hadoop project contains subcomponents with separate copyright +notices and license terms. Your use of the source code for the these +subcomponents is subject to the terms and conditions of the following +licenses. + +For the org.apache.hadoop.util.bloom.* classes: + +/** + * + * Copyright (c) 2005, European Commission project OneLab under contract + * 034819 (http://www.one-lab.org) + * All rights reserved. + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * - Neither the name of the University Catholique de Louvain - UCL + * nor the names of its contributors may be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ \ No newline at end of file diff --git a/solr/licenses/hadoop-yarn-server-tests-NOTICE.txt b/solr/licenses/hadoop-yarn-server-tests-NOTICE.txt new file mode 100644 index 00000000000..c56a5e4eac1 --- /dev/null +++ b/solr/licenses/hadoop-yarn-server-tests-NOTICE.txt @@ -0,0 +1,2 @@ +This product includes software developed by The Apache Software +Foundation (http://www.apache.org/). \ No newline at end of file diff --git a/solr/licenses/hadoop-yarn-server-web-proxy-2.2.0.jar.sha1 b/solr/licenses/hadoop-yarn-server-web-proxy-2.2.0.jar.sha1 new file mode 100644 index 00000000000..23494168c8c --- /dev/null +++ b/solr/licenses/hadoop-yarn-server-web-proxy-2.2.0.jar.sha1 @@ -0,0 +1 @@ +ab2404e576910f14cbcd185f81776ff806571b37 diff --git a/solr/licenses/hadoop-yarn-server-web-proxy-LICENSE-ASL.txt b/solr/licenses/hadoop-yarn-server-web-proxy-LICENSE-ASL.txt new file mode 100644 index 00000000000..9a8e847ee84 --- /dev/null +++ b/solr/licenses/hadoop-yarn-server-web-proxy-LICENSE-ASL.txt @@ -0,0 +1,244 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +APACHE HADOOP SUBCOMPONENTS: + +The Apache Hadoop project contains subcomponents with separate copyright +notices and license terms. Your use of the source code for the these +subcomponents is subject to the terms and conditions of the following +licenses. + +For the org.apache.hadoop.util.bloom.* classes: + +/** + * + * Copyright (c) 2005, European Commission project OneLab under contract + * 034819 (http://www.one-lab.org) + * All rights reserved. + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * - Neither the name of the University Catholique de Louvain - UCL + * nor the names of its contributors may be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ \ No newline at end of file diff --git a/solr/licenses/hadoop-yarn-server-web-proxy-NOTICE.txt b/solr/licenses/hadoop-yarn-server-web-proxy-NOTICE.txt new file mode 100644 index 00000000000..c56a5e4eac1 --- /dev/null +++ b/solr/licenses/hadoop-yarn-server-web-proxy-NOTICE.txt @@ -0,0 +1,2 @@ +This product includes software developed by The Apache Software +Foundation (http://www.apache.org/). \ No newline at end of file diff --git a/solr/licenses/jackson-annotations-2.2.3.jar.sha1 b/solr/licenses/jackson-annotations-2.2.3.jar.sha1 new file mode 100644 index 00000000000..bd1ab32a61c --- /dev/null +++ b/solr/licenses/jackson-annotations-2.2.3.jar.sha1 @@ -0,0 +1 @@ +0527fece4f23a457070a36c371a26d6c0208e1c3 diff --git a/solr/licenses/jackson-annotations-LICENSE-ASL.txt b/solr/licenses/jackson-annotations-LICENSE-ASL.txt new file mode 100644 index 00000000000..cebe8c83b06 --- /dev/null +++ b/solr/licenses/jackson-annotations-LICENSE-ASL.txt @@ -0,0 +1,8 @@ +This copy of Jackson JSON processor annotations is licensed under the +Apache (Software) License, version 2.0 ("the License"). +See the License for details about distribution rights, and the +specific rights regarding derivate works. + +You may obtain a copy of the License at: + +http://www.apache.org/licenses/LICENSE-2.0 \ No newline at end of file diff --git a/solr/licenses/jackson-annotations-NOTICE.txt b/solr/licenses/jackson-annotations-NOTICE.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/solr/licenses/jackson-core-2.2.3.jar.sha1 b/solr/licenses/jackson-core-2.2.3.jar.sha1 new file mode 100644 index 00000000000..a3463fa5a65 --- /dev/null +++ b/solr/licenses/jackson-core-2.2.3.jar.sha1 @@ -0,0 +1 @@ +1a0113da2cab5f4c216b4e5e7c1dbfaa67087e14 diff --git a/solr/licenses/jackson-core-LICENSE-ASL.txt b/solr/licenses/jackson-core-LICENSE-ASL.txt new file mode 100644 index 00000000000..aa15a313ac3 --- /dev/null +++ b/solr/licenses/jackson-core-LICENSE-ASL.txt @@ -0,0 +1,8 @@ +This copy of Jackson JSON processor streaming parser/generator is licensed under the +Apache (Software) License, version 2.0 ("the License"). +See the License for details about distribution rights, and the +specific rights regarding derivate works. + +You may obtain a copy of the License at: + +http://www.apache.org/licenses/LICENSE-2.0 \ No newline at end of file diff --git a/solr/licenses/jackson-core-NOTICE.txt b/solr/licenses/jackson-core-NOTICE.txt new file mode 100644 index 00000000000..deee84d3747 --- /dev/null +++ b/solr/licenses/jackson-core-NOTICE.txt @@ -0,0 +1,20 @@ +# Jackson JSON processor + +Jackson is a high-performance, Free/Open Source JSON processing library. +It was originally written by Tatu Saloranta (tatu.saloranta@iki.fi), and has +been in development since 2007. +It is currently developed by a community of developers, as well as supported +commercially by FasterXML.com. + +## Licensing + +Jackson core and extension components may licensed under different licenses. +To find the details that apply to this artifact see the accompanying LICENSE file. +For more information, including possible other licensing options, contact +FasterXML.com (http://fasterxml.com). + +## Credits + +A list of contributors may be found from CREDITS file, which is included +in some artifacts (usually source distributions); but is always available +from the source code management (SCM) system project uses. \ No newline at end of file diff --git a/solr/licenses/jackson-core-asl-1.9.13.jar.sha1 b/solr/licenses/jackson-core-asl-1.9.13.jar.sha1 new file mode 100644 index 00000000000..80a8b891a3c --- /dev/null +++ b/solr/licenses/jackson-core-asl-1.9.13.jar.sha1 @@ -0,0 +1 @@ +3c304d70f42f832e0a86d45bd437f692129299a4 diff --git a/solr/licenses/jackson-databind-2.2.3.jar.sha1 b/solr/licenses/jackson-databind-2.2.3.jar.sha1 new file mode 100644 index 00000000000..c554c3215da --- /dev/null +++ b/solr/licenses/jackson-databind-2.2.3.jar.sha1 @@ -0,0 +1 @@ +03ae380888029daefb91d3ecdca3a37d8cb92bc9 diff --git a/solr/licenses/jackson-databind-LICENSE-ASL.txt b/solr/licenses/jackson-databind-LICENSE-ASL.txt new file mode 100644 index 00000000000..97c8034a608 --- /dev/null +++ b/solr/licenses/jackson-databind-LICENSE-ASL.txt @@ -0,0 +1,8 @@ +This copy of Jackson JSON processor databind module is licensed under the +Apache (Software) License, version 2.0 ("the License"). +See the License for details about distribution rights, and the +specific rights regarding derivate works. + +You may obtain a copy of the License at: + +http://www.apache.org/licenses/LICENSE-2.0 \ No newline at end of file diff --git a/solr/licenses/jackson-databind-NOTICE.txt b/solr/licenses/jackson-databind-NOTICE.txt new file mode 100644 index 00000000000..8c716829153 --- /dev/null +++ b/solr/licenses/jackson-databind-NOTICE.txt @@ -0,0 +1,20 @@ +# Jackson JSON processor + +Jackson is a high-performance, Free/Open Source JSON processing library. +It was originally written by Tatu Saloranta (tatu.saloranta@iki.fi), and has +been in development since 2007. +It is currently developed by a community of developers, as well as supported +commercially by FasterXML.com. + +## Licensing + +Jackson core and extension components may be licensed under different licenses. +To find the details that apply to this artifact see the accompanying LICENSE file. +For more information, including possible other licensing options, contact +FasterXML.com (http://fasterxml.com). + +## Credits + +A list of contributors may be found from CREDITS file, which is included +in some artifacts (usually source distributions); but is always available +from the source code management (SCM) system project uses. \ No newline at end of file diff --git a/solr/licenses/jackson-jaxrs-1.9.13.jar.sha1 b/solr/licenses/jackson-jaxrs-1.9.13.jar.sha1 new file mode 100644 index 00000000000..3bffb8f68d0 --- /dev/null +++ b/solr/licenses/jackson-jaxrs-1.9.13.jar.sha1 @@ -0,0 +1 @@ +534d72d2b9d6199dd531dfb27083dd4844082bba diff --git a/solr/licenses/jackson-jaxrs-LICENSE-ASL.txt b/solr/licenses/jackson-jaxrs-LICENSE-ASL.txt new file mode 100644 index 00000000000..49ac3a7d45f --- /dev/null +++ b/solr/licenses/jackson-jaxrs-LICENSE-ASL.txt @@ -0,0 +1,13 @@ +This copy of Jackson JSON processor is licensed under the +Apache (Software) License, version 2.0 ("the License"). +See the License for details about distribution rights, and the +specific rights regarding derivate works. + +You may obtain a copy of the License at: + +http://www.apache.org/licenses/ + +A copy is also included with both the the downloadable source code package +and jar that contains class bytecodes, as file "ASL 2.0". In both cases, +that file should be located next to this file: in source distribution +the location should be "release-notes/asl"; and in jar "META-INF/" \ No newline at end of file diff --git a/solr/licenses/jackson-jaxrs-NOTICE.txt b/solr/licenses/jackson-jaxrs-NOTICE.txt new file mode 100644 index 00000000000..e9ebcc69fde --- /dev/null +++ b/solr/licenses/jackson-jaxrs-NOTICE.txt @@ -0,0 +1,7 @@ +This product currently only contains code developed by authors +of specific components, as identified by the source code files; +if such notes are missing files have been created by +Tatu Saloranta. + +For additional credits (generally to people who reported problems) +see CREDITS file. \ No newline at end of file diff --git a/solr/licenses/jackson-mapper-asl-1.9.13.jar.sha1 b/solr/licenses/jackson-mapper-asl-1.9.13.jar.sha1 new file mode 100644 index 00000000000..972b214d969 --- /dev/null +++ b/solr/licenses/jackson-mapper-asl-1.9.13.jar.sha1 @@ -0,0 +1 @@ +1ee2f2bed0e5dd29d1cb155a166e6f8d50bbddb7 diff --git a/solr/licenses/javax.inject-1.jar.sha1 b/solr/licenses/javax.inject-1.jar.sha1 new file mode 100644 index 00000000000..7ef3c707b3c --- /dev/null +++ b/solr/licenses/javax.inject-1.jar.sha1 @@ -0,0 +1 @@ +6975da39a7040257bd51d21a231b76c915872d38 diff --git a/solr/licenses/javax.inject-LICENSE-ASL.txt b/solr/licenses/javax.inject-LICENSE-ASL.txt new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/solr/licenses/javax.inject-LICENSE-ASL.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/solr/licenses/javax.inject-NOTICE.txt b/solr/licenses/javax.inject-NOTICE.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/solr/licenses/jaxb-impl-2.2.2.jar.sha1 b/solr/licenses/jaxb-impl-2.2.2.jar.sha1 new file mode 100644 index 00000000000..1b31975a311 --- /dev/null +++ b/solr/licenses/jaxb-impl-2.2.2.jar.sha1 @@ -0,0 +1 @@ +5b206d63c546fd4a8fa53c3b4a96345ad80fc45a diff --git a/solr/licenses/jaxb-impl-LICENSE-CDDL.txt b/solr/licenses/jaxb-impl-LICENSE-CDDL.txt new file mode 100644 index 00000000000..a0ccc93564c --- /dev/null +++ b/solr/licenses/jaxb-impl-LICENSE-CDDL.txt @@ -0,0 +1,263 @@ +COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + +1. Definitions. + + 1.1. Contributor. means each individual or entity that creates or contributes to the creation of Modifications. + + 1.2. Contributor Version. means the combination of the Original Software, prior Modifications used by a Contributor (if any), and the Modifications made by that particular Contributor. + + 1.3. Covered Software. means (a) the Original Software, or (b) Modifications, or (c) the combination of files containing Original Software with files containing Modifications, in each case including portions thereof. + + 1.4. Executable. means the Covered Software in any form other than Source Code. + + 1.5. Initial Developer. means the individual or entity that first makes Original Software available under this License. + + 1.6. Larger Work. means a work which combines Covered Software or portions thereof with code not governed by the terms of this License. + + 1.7. License. means this document. + + 1.8. Licensable. means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently acquired, any and all of the rights conveyed herein. + + 1.9. Modifications. means the Source Code and Executable form of any of the following: + + A. Any file that results from an addition to, deletion from or modification of the contents of a file containing Original Software or previous Modifications; + + B. Any new file that contains any part of the Original Software or previous Modification; or + + C. Any new file that is contributed or otherwise made available under the terms of this License. + + 1.10. Original Software. means the Source Code and Executable form of computer software code that is originally released under this License. + + 1.11. Patent Claims. means any patent claim(s), now owned or hereafter acquired, including without limitation, method, process, and apparatus claims, in any patent Licensable by grantor. + + 1.12. Source Code. means (a) the common form of computer software code in which modifications are made and (b) associated documentation included in or with such code. + + 1.13. You. (or .Your.) means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, .You. includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, .control. means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. + +2. License Grants. + + 2.1. The Initial Developer Grant. + + Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, the Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license: + + (a) under intellectual property rights (other than patent or trademark) Licensable by Initial Developer, to use, reproduce, modify, display, perform, sublicense and distribute the Original Software (or portions thereof), with or without Modifications, and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using or selling of Original Software, to make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of the Original Software (or portions thereof). + + (c) The licenses granted in Sections 2.1(a) and (b) are effective on the date Initial Developer first distributes or otherwise makes the Original Software available to a third party under the terms of this License. + + (d) Notwithstanding Section 2.1(b) above, no patent license is granted: (1) for code that You delete from the Original Software, or (2) for infringements caused by: (i) the modification of the Original Software, or (ii) the combination of the Original Software with other software or devices. + + 2.2. Contributor Grant. + + Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license: + + (a) under intellectual property rights (other than patent or trademark) Licensable by Contributor to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof), either on an unmodified basis, with other Modifications, as Covered Software and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using, or selling of Modifications made by that Contributor either alone and/or in combination with its Contributor Version (or portions of such combination), to make, use, sell, offer for sale, have made, and/or otherwise dispose of: (1) Modifications made by that Contributor (or portions thereof); and (2) the combination of Modifications made by that Contributor with its Contributor Version (or portions of such combination). + + (c) The licenses granted in Sections 2.2(a) and 2.2(b) are effective on the date Contributor first distributes or otherwise makes the Modifications available to a third party. + + (d) Notwithstanding Section 2.2(b) above, no patent license is granted: (1) for any code that Contributor has deleted from the Contributor Version; (2) for infringements caused by: (i) third party modifications of Contributor Version, or (ii) the combination of Modifications made by that Contributor with other software (except as part of the Contributor Version) or other devices; or (3) under Patent Claims infringed by Covered Software in the absence of Modifications made by that Contributor. + +3. Distribution Obligations. + + 3.1. Availability of Source Code. + Any Covered Software that You distribute or otherwise make available in Executable form must also be made available in Source Code form and that Source Code form must be distributed only under the terms of this License. You must include a copy of this License with every copy of the Source Code form of the Covered Software You distribute or otherwise make available. You must inform recipients of any such Covered Software in Executable form as to how they can obtain such Covered Software in Source Code form in a reasonable manner on or through a medium customarily used for software exchange. + + 3.2. Modifications. + The Modifications that You create or to which You contribute are governed by the terms of this License. You represent that You believe Your Modifications are Your original creation(s) and/or You have sufficient rights to grant the rights conveyed by this License. + + 3.3. Required Notices. + You must include a notice in each of Your Modifications that identifies You as the Contributor of the Modification. You may not remove or alter any copyright, patent or trademark notices contained within the Covered Software, or any notices of licensing or any descriptive text giving attribution to any Contributor or the Initial Developer. + + 3.4. Application of Additional Terms. + You may not offer or impose any terms on any Covered Software in Source Code form that alters or restricts the applicable version of this License or the recipients. rights hereunder. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Software. However, you may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear that any such warranty, support, indemnity or liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of warranty, support, indemnity or liability terms You offer. + + 3.5. Distribution of Executable Versions. + You may distribute the Executable form of the Covered Software under the terms of this License or under the terms of a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable form does not attempt to limit or alter the recipient.s rights in the Source Code form from the rights set forth in this License. If You distribute the Covered Software in Executable form under a different license, You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer. + + 3.6. Larger Works. + You may create a Larger Work by combining Covered Software with other code not governed by the terms of this License and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this License are fulfilled for the Covered Software. + +4. Versions of the License. + + 4.1. New Versions. + Sun Microsystems, Inc. is the initial license steward and may publish revised and/or new versions of this License from time to time. Each version will be given a distinguishing version number. Except as provided in Section 4.3, no one other than the license steward has the right to modify this License. + + 4.2. Effect of New Versions. + You may always continue to use, distribute or otherwise make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. If the Initial Developer includes a notice in the Original Software prohibiting it from being distributed or otherwise made available under any subsequent version of the License, You must distribute and make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. Otherwise, You may also choose to use, distribute or otherwise make the Covered Software available under the terms of any subsequent version of the License published by the license steward. + + 4.3. Modified Versions. + When You are an Initial Developer and You want to create a new license for Your Original Software, You may create and use a modified version of this License if You: (a) rename the license and remove any references to the name of the license steward (except to note that the license differs from this License); and (b) otherwise make it clear that the license contains terms which differ from this License. + +5. DISCLAIMER OF WARRANTY. + + COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN .AS IS. BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + +6. TERMINATION. + + 6.1. This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach within 30 days of becoming aware of the breach. Provisions which, by their nature, must remain in effect beyond the termination of this License shall survive. + + 6.2. If You assert a patent infringement claim (excluding declaratory judgment actions) against Initial Developer or a Contributor (the Initial Developer or Contributor against whom You assert such claim is referred to as .Participant.) alleging that the Participant Software (meaning the Contributor Version where the Participant is a Contributor or the Original Software where the Participant is the Initial Developer) directly or indirectly infringes any patent, then any and all rights granted directly or indirectly to You by such Participant, the Initial Developer (if the Initial Developer is not the Participant) and all Contributors under Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice from Participant terminate prospectively and automatically at the expiration of such 60 day notice period, unless if within such 60 day period You withdraw Your claim with respect to the Participant Software against such Participant either unilaterally or pursuant to a written agreement with Participant. + + 6.3. In the event of termination under Sections 6.1 or 6.2 above, all end user licenses that have been validly granted by You or any distributor hereunder prior to termination (excluding licenses granted to You by any distributor) shall survive termination. + +7. LIMITATION OF LIABILITY. + + UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOST PROFITS, LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY.S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. + +8. U.S. GOVERNMENT END USERS. + + The Covered Software is a .commercial item,. as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of .commercial computer software. (as that term is defined at 48 C.F.R. ? 252.227-7014(a)(1)) and .commercial computer software documentation. as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Software with only those rights set forth herein. This U.S. Government Rights clause is in lieu of, and supersedes, any other FAR, DFAR, or other clause or provision that addresses Government rights in computer software under this License. + +9. MISCELLANEOUS. + + This License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by the law of the jurisdiction specified in a notice contained within the Original Software (except to the extent applicable law, if any, provides otherwise), excluding such jurisdiction.s conflict-of-law provisions. Any litigation relating to this License shall be subject to the jurisdiction of the courts located in the jurisdiction and venue specified in a notice contained within the Original Software, with the losing party responsible for costs, including, without limitation, court costs and reasonable attorneys. fees and expenses. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License. You agree that You alone are responsible for compliance with the United States export administration regulations (and the export control laws and regulation of any other countries) when You use, distribute or otherwise make available any Covered Software. + +10. RESPONSIBILITY FOR CLAIMS. + + As between Initial Developer and the Contributors, each party is responsible for claims and damages arising, directly or indirectly, out of its utilization of rights under this License and You agree to work with Initial Developer and Contributors to distribute such responsibility on an equitable basis. Nothing herein is intended or shall be deemed to constitute any admission of liability. + + NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) + + The code released under the CDDL shall be governed by the laws of the State of California (excluding conflict-of-law provisions). Any litigation relating to this License shall be subject to the jurisdiction of the Federal Courts of the Northern District of California and the state courts of the State of California, with venue lying in Santa Clara County, California. + + +The GNU General Public License (GPL) Version 2, June 1991 + + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. + +Preamble + +The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. + +To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. + +For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. + +We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. + +Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. + +Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. + +The precise terms and conditions for copying, distribution and modification follow. + + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. + +1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. + +You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. + + c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. + +3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. + +If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. + +4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. + +5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. + +6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. + +7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. + +This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. + +9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. + +10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. + +NO WARRANTY + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +END OF TERMS AND CONDITIONS + + +How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. + + One line to give the program's name and a brief idea of what it does. + + Copyright (C) + + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. + + signature of Ty Coon, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. + + +"CLASSPATH" EXCEPTION TO THE GPL VERSION 2 + +Certain source files distributed by Sun Microsystems, Inc. are subject to the following clarification and special exception to the GPL Version 2, but only where Sun has expressly included in the particular source file's header the words + +"Sun designates this particular file as subject to the "Classpath" exception as provided by Sun in the License file that accompanied this code." + +Linking this library statically or dynamically with other modules is making a combined work based on this library. Thus, the terms and conditions of the GNU General Public License Version 2 cover the whole combination. + +As a special exception, the copyright holders of this library give you permission to link this library with independent modules to produce an executable, regardless of the license terms of these independent modules, and to copy and distribute the resulting executable under terms of your choice, provided that you also meet, for each linked independent module, the terms and conditions of the license of that module.? An independent module is a module which is not derived from or based on this library.? If you modify this library, you may extend this exception to your version of the library, but you are not obligated to do so.? If you do not wish to do so, delete this exception statement from your version. diff --git a/solr/licenses/jersey-bundle-1.8.jar.sha1 b/solr/licenses/jersey-bundle-1.8.jar.sha1 new file mode 100644 index 00000000000..4ff2c766383 --- /dev/null +++ b/solr/licenses/jersey-bundle-1.8.jar.sha1 @@ -0,0 +1 @@ +b59d9d4dd6d6301515697b29260f1f4dcaabd771 diff --git a/solr/licenses/jersey-bundle-LICENSE-CDDL.txt b/solr/licenses/jersey-bundle-LICENSE-CDDL.txt new file mode 100644 index 00000000000..64df8d56300 --- /dev/null +++ b/solr/licenses/jersey-bundle-LICENSE-CDDL.txt @@ -0,0 +1,85 @@ +COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL)Version 1.1 + +1. Definitions. + +1.1. “Contributor” means each individual or entity that creates or contributes to the creation of Modifications. +1.2. “Contributor Version” means the combination of the Original Software, prior Modifications used by a Contributor (if any), and the Modifications made by that particular Contributor. +1.3. “Covered Software” means (a) the Original Software, or (b) Modifications, or (c) the combination of files containing Original Software with files containing Modifications, in each case including portions thereof. +1.4. “Executable” means the Covered Software in any form other than Source Code. +1.5. “Initial Developer” means the individual or entity that first makes Original Software available under this License. +1.6. “Larger Work” means a work which combines Covered Software or portions thereof with code not governed by the terms of this License. +1.7. “License” means this document. +1.8. “Licensable” means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently acquired, any and all of the rights conveyed herein. +1.9. “Modifications” means the Source Code and Executable form of any of the following: +A. Any file that results from an addition to, deletion from or modification of the contents of a file containing Original Software or previous Modifications; +B. Any new file that contains any part of the Original Software or previous Modification; or +C. Any new file that is contributed or otherwise made available under the terms of this License. +1.10. “Original Software” means the Source Code and Executable form of computer software code that is originally released under this License. +1.11. “Patent Claims” means any patent claim(s), now owned or hereafter acquired, including without limitation, method, process, and apparatus claims, in any patent Licensable by grantor. +1.12. “Source Code” means (a) the common form of computer software code in which modifications are made and (b) associated documentation included in or with such code. +1.13. “You” (or “Your”) means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, “You” includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, “control” means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. +2. License Grants. + +2.1. The Initial Developer Grant. +Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, the Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license: +(a) under intellectual property rights (other than patent or trademark) Licensable by Initial Developer, to use, reproduce, modify, display, perform, sublicense and distribute the Original Software (or portions thereof), with or without Modifications, and/or as part of a Larger Work; and +(b) under Patent Claims infringed by the making, using or selling of Original Software, to make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of the Original Software (or portions thereof). +(c) The licenses granted in Sections 2.1(a) and (b) are effective on the date Initial Developer first distributes or otherwise makes the Original Software available to a third party under the terms of this License. +(d) Notwithstanding Section 2.1(b) above, no patent license is granted: (1) for code that You delete from the Original Software, or (2) for infringements caused by: (i) the modification of the Original Software, or (ii) the combination of the Original Software with other software or devices. +2.2. Contributor Grant. +Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license: +(a) under intellectual property rights (other than patent or trademark) Licensable by Contributor to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof), either on an unmodified basis, with other Modifications, as Covered Software and/or as part of a Larger Work; and +(b) under Patent Claims infringed by the making, using, or selling of Modifications made by that Contributor either alone and/or in combination with its Contributor Version (or portions of such combination), to make, use, sell, offer for sale, have made, and/or otherwise dispose of: (1) Modifications made by that Contributor (or portions thereof); and (2) the combination of Modifications made by that Contributor with its Contributor Version (or portions of such combination). +(c) The licenses granted in Sections 2.2(a) and 2.2(b) are effective on the date Contributor first distributes or otherwise makes the Modifications available to a third party. +(d) Notwithstanding Section 2.2(b) above, no patent license is granted: (1) for any code that Contributor has deleted from the Contributor Version; (2) for infringements caused by: (i) third party modifications of Contributor Version, or (ii) the combination of Modifications made by that Contributor with other software (except as part of the Contributor Version) or other devices; or (3) under Patent Claims infringed by Covered Software in the absence of Modifications made by that Contributor. +3. Distribution Obligations. + +3.1. Availability of Source Code. +Any Covered Software that You distribute or otherwise make available in Executable form must also be made available in Source Code form and that Source Code form must be distributed only under the terms of this License. You must include a copy of this License with every copy of the Source Code form of the Covered Software You distribute or otherwise make available. You must inform recipients of any such Covered Software in Executable form as to how they can obtain such Covered Software in Source Code form in a reasonable manner on or through a medium customarily used for software exchange. +3.2. Modifications. +The Modifications that You create or to which You contribute are governed by the terms of this License. You represent that You believe Your Modifications are Your original creation(s) and/or You have sufficient rights to grant the rights conveyed by this License. +3.3. Required Notices. +You must include a notice in each of Your Modifications that identifies You as the Contributor of the Modification. You may not remove or alter any copyright, patent or trademark notices contained within the Covered Software, or any notices of licensing or any descriptive text giving attribution to any Contributor or the Initial Developer. +3.4. Application of Additional Terms. +You may not offer or impose any terms on any Covered Software in Source Code form that alters or restricts the applicable version of this License or the recipients' rights hereunder. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Software. However, you may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear that any such warranty, support, indemnity or liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of warranty, support, indemnity or liability terms You offer. +3.5. Distribution of Executable Versions. +You may distribute the Executable form of the Covered Software under the terms of this License or under the terms of a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable form does not attempt to limit or alter the recipient's rights in the Source Code form from the rights set forth in this License. If You distribute the Covered Software in Executable form under a different license, You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer. +3.6. Larger Works. +You may create a Larger Work by combining Covered Software with other code not governed by the terms of this License and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this License are fulfilled for the Covered Software. +4. Versions of the License. + +4.1. New Versions. +Oracle is the initial license steward and may publish revised and/or new versions of this License from time to time. Each version will be given a distinguishing version number. Except as provided in Section 4.3, no one other than the license steward has the right to modify this License. +4.2. Effect of New Versions. +You may always continue to use, distribute or otherwise make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. If the Initial Developer includes a notice in the Original Software prohibiting it from being distributed or otherwise made available under any subsequent version of the License, You must distribute and make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. Otherwise, You may also choose to use, distribute or otherwise make the Covered Software available under the terms of any subsequent version of the License published by the license steward. +4.3. Modified Versions. +When You are an Initial Developer and You want to create a new license for Your Original Software, You may create and use a modified version of this License if You: (a) rename the license and remove any references to the name of the license steward (except to note that the license differs from this License); and (b) otherwise make it clear that the license contains terms which differ from this License. +5. DISCLAIMER OF WARRANTY. + +COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN “AS IS” BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + +6. TERMINATION. + +6.1. This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach within 30 days of becoming aware of the breach. Provisions which, by their nature, must remain in effect beyond the termination of this License shall survive. +6.2. If You assert a patent infringement claim (excluding declaratory judgment actions) against Initial Developer or a Contributor (the Initial Developer or Contributor against whom You assert such claim is referred to as “Participant”) alleging that the Participant Software (meaning the Contributor Version where the Participant is a Contributor or the Original Software where the Participant is the Initial Developer) directly or indirectly infringes any patent, then any and all rights granted directly or indirectly to You by such Participant, the Initial Developer (if the Initial Developer is not the Participant) and all Contributors under Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice from Participant terminate prospectively and automatically at the expiration of such 60 day notice period, unless if within such 60 day period You withdraw Your claim with respect to the Participant Software against such Participant either unilaterally or pursuant to a written agreement with Participant. +6.3. If You assert a patent infringement claim against Participant alleging that the Participant Software directly or indirectly infringes any patent where such claim is resolved (such as by license or settlement) prior to the initiation of patent infringement litigation, then the reasonable value of the licenses granted by such Participant under Sections 2.1 or 2.2 shall be taken into account in determining the amount or value of any payment or license. +6.4. In the event of termination under Sections 6.1 or 6.2 above, all end user licenses that have been validly granted by You or any distributor hereunder prior to termination (excluding licenses granted to You by any distributor) shall survive termination. +7. LIMITATION OF LIABILITY. + +UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. + +8. U.S. GOVERNMENT END USERS. + +The Covered Software is a “commercial item,” as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of “commercial computer software” (as that term is defined at 48 C.F.R. § 252.227-7014(a)(1)) and “commercial computer software documentation” as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Software with only those rights set forth herein. This U.S. Government Rights clause is in lieu of, and supersedes, any other FAR, DFAR, or other clause or provision that addresses Government rights in computer software under this License. + +9. MISCELLANEOUS. + +This License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by the law of the jurisdiction specified in a notice contained within the Original Software (except to the extent applicable law, if any, provides otherwise), excluding such jurisdiction's conflict-of-law provisions. Any litigation relating to this License shall be subject to the jurisdiction of the courts located in the jurisdiction and venue specified in a notice contained within the Original Software, with the losing party responsible for costs, including, without limitation, court costs and reasonable attorneys' fees and expenses. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License. You agree that You alone are responsible for compliance with the United States export administration regulations (and the export control laws and regulation of any other countries) when You use, distribute or otherwise make available any Covered Software. + +10. RESPONSIBILITY FOR CLAIMS. + +As between Initial Developer and the Contributors, each party is responsible for claims and damages arising, directly or indirectly, out of its utilization of rights under this License and You agree to work with Initial Developer and Contributors to distribute such responsibility on an equitable basis. Nothing herein is intended or shall be deemed to constitute any admission of liability. + +NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) + +The code released under the CDDL shall be governed by the laws of the State of California (excluding conflict-of-law provisions). Any litigation relating to this License shall be subject to the jurisdiction of the Federal Courts of the Northern District of California and the state courts of the State of California, with venue lying in Santa Clara County, California. \ No newline at end of file diff --git a/solr/licenses/jersey-core-1.8.jar.sha1 b/solr/licenses/jersey-core-1.8.jar.sha1 new file mode 100644 index 00000000000..1a24e1368da --- /dev/null +++ b/solr/licenses/jersey-core-1.8.jar.sha1 @@ -0,0 +1 @@ +b6a0553c0eb3da45a9b8947a0a7283b3b9266d0d diff --git a/solr/licenses/jersey-guice-1.8.jar.sha1 b/solr/licenses/jersey-guice-1.8.jar.sha1 new file mode 100644 index 00000000000..c37b9bf62d9 --- /dev/null +++ b/solr/licenses/jersey-guice-1.8.jar.sha1 @@ -0,0 +1 @@ +f4e7772030608e281bb39ffcc7028c2e430356e7 diff --git a/solr/licenses/jersey-guice-LICENSE-CDDL.txt b/solr/licenses/jersey-guice-LICENSE-CDDL.txt new file mode 100644 index 00000000000..64df8d56300 --- /dev/null +++ b/solr/licenses/jersey-guice-LICENSE-CDDL.txt @@ -0,0 +1,85 @@ +COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL)Version 1.1 + +1. Definitions. + +1.1. “Contributor” means each individual or entity that creates or contributes to the creation of Modifications. +1.2. “Contributor Version” means the combination of the Original Software, prior Modifications used by a Contributor (if any), and the Modifications made by that particular Contributor. +1.3. “Covered Software” means (a) the Original Software, or (b) Modifications, or (c) the combination of files containing Original Software with files containing Modifications, in each case including portions thereof. +1.4. “Executable” means the Covered Software in any form other than Source Code. +1.5. “Initial Developer” means the individual or entity that first makes Original Software available under this License. +1.6. “Larger Work” means a work which combines Covered Software or portions thereof with code not governed by the terms of this License. +1.7. “License” means this document. +1.8. “Licensable” means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently acquired, any and all of the rights conveyed herein. +1.9. “Modifications” means the Source Code and Executable form of any of the following: +A. Any file that results from an addition to, deletion from or modification of the contents of a file containing Original Software or previous Modifications; +B. Any new file that contains any part of the Original Software or previous Modification; or +C. Any new file that is contributed or otherwise made available under the terms of this License. +1.10. “Original Software” means the Source Code and Executable form of computer software code that is originally released under this License. +1.11. “Patent Claims” means any patent claim(s), now owned or hereafter acquired, including without limitation, method, process, and apparatus claims, in any patent Licensable by grantor. +1.12. “Source Code” means (a) the common form of computer software code in which modifications are made and (b) associated documentation included in or with such code. +1.13. “You” (or “Your”) means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, “You” includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, “control” means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. +2. License Grants. + +2.1. The Initial Developer Grant. +Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, the Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license: +(a) under intellectual property rights (other than patent or trademark) Licensable by Initial Developer, to use, reproduce, modify, display, perform, sublicense and distribute the Original Software (or portions thereof), with or without Modifications, and/or as part of a Larger Work; and +(b) under Patent Claims infringed by the making, using or selling of Original Software, to make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of the Original Software (or portions thereof). +(c) The licenses granted in Sections 2.1(a) and (b) are effective on the date Initial Developer first distributes or otherwise makes the Original Software available to a third party under the terms of this License. +(d) Notwithstanding Section 2.1(b) above, no patent license is granted: (1) for code that You delete from the Original Software, or (2) for infringements caused by: (i) the modification of the Original Software, or (ii) the combination of the Original Software with other software or devices. +2.2. Contributor Grant. +Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license: +(a) under intellectual property rights (other than patent or trademark) Licensable by Contributor to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof), either on an unmodified basis, with other Modifications, as Covered Software and/or as part of a Larger Work; and +(b) under Patent Claims infringed by the making, using, or selling of Modifications made by that Contributor either alone and/or in combination with its Contributor Version (or portions of such combination), to make, use, sell, offer for sale, have made, and/or otherwise dispose of: (1) Modifications made by that Contributor (or portions thereof); and (2) the combination of Modifications made by that Contributor with its Contributor Version (or portions of such combination). +(c) The licenses granted in Sections 2.2(a) and 2.2(b) are effective on the date Contributor first distributes or otherwise makes the Modifications available to a third party. +(d) Notwithstanding Section 2.2(b) above, no patent license is granted: (1) for any code that Contributor has deleted from the Contributor Version; (2) for infringements caused by: (i) third party modifications of Contributor Version, or (ii) the combination of Modifications made by that Contributor with other software (except as part of the Contributor Version) or other devices; or (3) under Patent Claims infringed by Covered Software in the absence of Modifications made by that Contributor. +3. Distribution Obligations. + +3.1. Availability of Source Code. +Any Covered Software that You distribute or otherwise make available in Executable form must also be made available in Source Code form and that Source Code form must be distributed only under the terms of this License. You must include a copy of this License with every copy of the Source Code form of the Covered Software You distribute or otherwise make available. You must inform recipients of any such Covered Software in Executable form as to how they can obtain such Covered Software in Source Code form in a reasonable manner on or through a medium customarily used for software exchange. +3.2. Modifications. +The Modifications that You create or to which You contribute are governed by the terms of this License. You represent that You believe Your Modifications are Your original creation(s) and/or You have sufficient rights to grant the rights conveyed by this License. +3.3. Required Notices. +You must include a notice in each of Your Modifications that identifies You as the Contributor of the Modification. You may not remove or alter any copyright, patent or trademark notices contained within the Covered Software, or any notices of licensing or any descriptive text giving attribution to any Contributor or the Initial Developer. +3.4. Application of Additional Terms. +You may not offer or impose any terms on any Covered Software in Source Code form that alters or restricts the applicable version of this License or the recipients' rights hereunder. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Software. However, you may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear that any such warranty, support, indemnity or liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of warranty, support, indemnity or liability terms You offer. +3.5. Distribution of Executable Versions. +You may distribute the Executable form of the Covered Software under the terms of this License or under the terms of a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable form does not attempt to limit or alter the recipient's rights in the Source Code form from the rights set forth in this License. If You distribute the Covered Software in Executable form under a different license, You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer. +3.6. Larger Works. +You may create a Larger Work by combining Covered Software with other code not governed by the terms of this License and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this License are fulfilled for the Covered Software. +4. Versions of the License. + +4.1. New Versions. +Oracle is the initial license steward and may publish revised and/or new versions of this License from time to time. Each version will be given a distinguishing version number. Except as provided in Section 4.3, no one other than the license steward has the right to modify this License. +4.2. Effect of New Versions. +You may always continue to use, distribute or otherwise make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. If the Initial Developer includes a notice in the Original Software prohibiting it from being distributed or otherwise made available under any subsequent version of the License, You must distribute and make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. Otherwise, You may also choose to use, distribute or otherwise make the Covered Software available under the terms of any subsequent version of the License published by the license steward. +4.3. Modified Versions. +When You are an Initial Developer and You want to create a new license for Your Original Software, You may create and use a modified version of this License if You: (a) rename the license and remove any references to the name of the license steward (except to note that the license differs from this License); and (b) otherwise make it clear that the license contains terms which differ from this License. +5. DISCLAIMER OF WARRANTY. + +COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN “AS IS” BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + +6. TERMINATION. + +6.1. This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach within 30 days of becoming aware of the breach. Provisions which, by their nature, must remain in effect beyond the termination of this License shall survive. +6.2. If You assert a patent infringement claim (excluding declaratory judgment actions) against Initial Developer or a Contributor (the Initial Developer or Contributor against whom You assert such claim is referred to as “Participant”) alleging that the Participant Software (meaning the Contributor Version where the Participant is a Contributor or the Original Software where the Participant is the Initial Developer) directly or indirectly infringes any patent, then any and all rights granted directly or indirectly to You by such Participant, the Initial Developer (if the Initial Developer is not the Participant) and all Contributors under Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice from Participant terminate prospectively and automatically at the expiration of such 60 day notice period, unless if within such 60 day period You withdraw Your claim with respect to the Participant Software against such Participant either unilaterally or pursuant to a written agreement with Participant. +6.3. If You assert a patent infringement claim against Participant alleging that the Participant Software directly or indirectly infringes any patent where such claim is resolved (such as by license or settlement) prior to the initiation of patent infringement litigation, then the reasonable value of the licenses granted by such Participant under Sections 2.1 or 2.2 shall be taken into account in determining the amount or value of any payment or license. +6.4. In the event of termination under Sections 6.1 or 6.2 above, all end user licenses that have been validly granted by You or any distributor hereunder prior to termination (excluding licenses granted to You by any distributor) shall survive termination. +7. LIMITATION OF LIABILITY. + +UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. + +8. U.S. GOVERNMENT END USERS. + +The Covered Software is a “commercial item,” as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of “commercial computer software” (as that term is defined at 48 C.F.R. § 252.227-7014(a)(1)) and “commercial computer software documentation” as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Software with only those rights set forth herein. This U.S. Government Rights clause is in lieu of, and supersedes, any other FAR, DFAR, or other clause or provision that addresses Government rights in computer software under this License. + +9. MISCELLANEOUS. + +This License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by the law of the jurisdiction specified in a notice contained within the Original Software (except to the extent applicable law, if any, provides otherwise), excluding such jurisdiction's conflict-of-law provisions. Any litigation relating to this License shall be subject to the jurisdiction of the courts located in the jurisdiction and venue specified in a notice contained within the Original Software, with the losing party responsible for costs, including, without limitation, court costs and reasonable attorneys' fees and expenses. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License. You agree that You alone are responsible for compliance with the United States export administration regulations (and the export control laws and regulation of any other countries) when You use, distribute or otherwise make available any Covered Software. + +10. RESPONSIBILITY FOR CLAIMS. + +As between Initial Developer and the Contributors, each party is responsible for claims and damages arising, directly or indirectly, out of its utilization of rights under this License and You agree to work with Initial Developer and Contributors to distribute such responsibility on an equitable basis. Nothing herein is intended or shall be deemed to constitute any admission of liability. + +NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) + +The code released under the CDDL shall be governed by the laws of the State of California (excluding conflict-of-law provisions). Any litigation relating to this License shall be subject to the jurisdiction of the Federal Courts of the Northern District of California and the state courts of the State of California, with venue lying in Santa Clara County, California. \ No newline at end of file diff --git a/solr/licenses/jersey-json-1.8.jar.sha1 b/solr/licenses/jersey-json-1.8.jar.sha1 new file mode 100644 index 00000000000..dcd29565da0 --- /dev/null +++ b/solr/licenses/jersey-json-1.8.jar.sha1 @@ -0,0 +1 @@ +825621478fec59983106efaa032c679f925b4eff diff --git a/solr/licenses/jersey-json-LICENSE-CDDL.txt b/solr/licenses/jersey-json-LICENSE-CDDL.txt new file mode 100644 index 00000000000..64df8d56300 --- /dev/null +++ b/solr/licenses/jersey-json-LICENSE-CDDL.txt @@ -0,0 +1,85 @@ +COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL)Version 1.1 + +1. Definitions. + +1.1. “Contributor” means each individual or entity that creates or contributes to the creation of Modifications. +1.2. “Contributor Version” means the combination of the Original Software, prior Modifications used by a Contributor (if any), and the Modifications made by that particular Contributor. +1.3. “Covered Software” means (a) the Original Software, or (b) Modifications, or (c) the combination of files containing Original Software with files containing Modifications, in each case including portions thereof. +1.4. “Executable” means the Covered Software in any form other than Source Code. +1.5. “Initial Developer” means the individual or entity that first makes Original Software available under this License. +1.6. “Larger Work” means a work which combines Covered Software or portions thereof with code not governed by the terms of this License. +1.7. “License” means this document. +1.8. “Licensable” means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently acquired, any and all of the rights conveyed herein. +1.9. “Modifications” means the Source Code and Executable form of any of the following: +A. Any file that results from an addition to, deletion from or modification of the contents of a file containing Original Software or previous Modifications; +B. Any new file that contains any part of the Original Software or previous Modification; or +C. Any new file that is contributed or otherwise made available under the terms of this License. +1.10. “Original Software” means the Source Code and Executable form of computer software code that is originally released under this License. +1.11. “Patent Claims” means any patent claim(s), now owned or hereafter acquired, including without limitation, method, process, and apparatus claims, in any patent Licensable by grantor. +1.12. “Source Code” means (a) the common form of computer software code in which modifications are made and (b) associated documentation included in or with such code. +1.13. “You” (or “Your”) means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, “You” includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, “control” means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. +2. License Grants. + +2.1. The Initial Developer Grant. +Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, the Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license: +(a) under intellectual property rights (other than patent or trademark) Licensable by Initial Developer, to use, reproduce, modify, display, perform, sublicense and distribute the Original Software (or portions thereof), with or without Modifications, and/or as part of a Larger Work; and +(b) under Patent Claims infringed by the making, using or selling of Original Software, to make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of the Original Software (or portions thereof). +(c) The licenses granted in Sections 2.1(a) and (b) are effective on the date Initial Developer first distributes or otherwise makes the Original Software available to a third party under the terms of this License. +(d) Notwithstanding Section 2.1(b) above, no patent license is granted: (1) for code that You delete from the Original Software, or (2) for infringements caused by: (i) the modification of the Original Software, or (ii) the combination of the Original Software with other software or devices. +2.2. Contributor Grant. +Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license: +(a) under intellectual property rights (other than patent or trademark) Licensable by Contributor to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof), either on an unmodified basis, with other Modifications, as Covered Software and/or as part of a Larger Work; and +(b) under Patent Claims infringed by the making, using, or selling of Modifications made by that Contributor either alone and/or in combination with its Contributor Version (or portions of such combination), to make, use, sell, offer for sale, have made, and/or otherwise dispose of: (1) Modifications made by that Contributor (or portions thereof); and (2) the combination of Modifications made by that Contributor with its Contributor Version (or portions of such combination). +(c) The licenses granted in Sections 2.2(a) and 2.2(b) are effective on the date Contributor first distributes or otherwise makes the Modifications available to a third party. +(d) Notwithstanding Section 2.2(b) above, no patent license is granted: (1) for any code that Contributor has deleted from the Contributor Version; (2) for infringements caused by: (i) third party modifications of Contributor Version, or (ii) the combination of Modifications made by that Contributor with other software (except as part of the Contributor Version) or other devices; or (3) under Patent Claims infringed by Covered Software in the absence of Modifications made by that Contributor. +3. Distribution Obligations. + +3.1. Availability of Source Code. +Any Covered Software that You distribute or otherwise make available in Executable form must also be made available in Source Code form and that Source Code form must be distributed only under the terms of this License. You must include a copy of this License with every copy of the Source Code form of the Covered Software You distribute or otherwise make available. You must inform recipients of any such Covered Software in Executable form as to how they can obtain such Covered Software in Source Code form in a reasonable manner on or through a medium customarily used for software exchange. +3.2. Modifications. +The Modifications that You create or to which You contribute are governed by the terms of this License. You represent that You believe Your Modifications are Your original creation(s) and/or You have sufficient rights to grant the rights conveyed by this License. +3.3. Required Notices. +You must include a notice in each of Your Modifications that identifies You as the Contributor of the Modification. You may not remove or alter any copyright, patent or trademark notices contained within the Covered Software, or any notices of licensing or any descriptive text giving attribution to any Contributor or the Initial Developer. +3.4. Application of Additional Terms. +You may not offer or impose any terms on any Covered Software in Source Code form that alters or restricts the applicable version of this License or the recipients' rights hereunder. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Software. However, you may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear that any such warranty, support, indemnity or liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of warranty, support, indemnity or liability terms You offer. +3.5. Distribution of Executable Versions. +You may distribute the Executable form of the Covered Software under the terms of this License or under the terms of a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable form does not attempt to limit or alter the recipient's rights in the Source Code form from the rights set forth in this License. If You distribute the Covered Software in Executable form under a different license, You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer. +3.6. Larger Works. +You may create a Larger Work by combining Covered Software with other code not governed by the terms of this License and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this License are fulfilled for the Covered Software. +4. Versions of the License. + +4.1. New Versions. +Oracle is the initial license steward and may publish revised and/or new versions of this License from time to time. Each version will be given a distinguishing version number. Except as provided in Section 4.3, no one other than the license steward has the right to modify this License. +4.2. Effect of New Versions. +You may always continue to use, distribute or otherwise make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. If the Initial Developer includes a notice in the Original Software prohibiting it from being distributed or otherwise made available under any subsequent version of the License, You must distribute and make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. Otherwise, You may also choose to use, distribute or otherwise make the Covered Software available under the terms of any subsequent version of the License published by the license steward. +4.3. Modified Versions. +When You are an Initial Developer and You want to create a new license for Your Original Software, You may create and use a modified version of this License if You: (a) rename the license and remove any references to the name of the license steward (except to note that the license differs from this License); and (b) otherwise make it clear that the license contains terms which differ from this License. +5. DISCLAIMER OF WARRANTY. + +COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN “AS IS” BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + +6. TERMINATION. + +6.1. This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach within 30 days of becoming aware of the breach. Provisions which, by their nature, must remain in effect beyond the termination of this License shall survive. +6.2. If You assert a patent infringement claim (excluding declaratory judgment actions) against Initial Developer or a Contributor (the Initial Developer or Contributor against whom You assert such claim is referred to as “Participant”) alleging that the Participant Software (meaning the Contributor Version where the Participant is a Contributor or the Original Software where the Participant is the Initial Developer) directly or indirectly infringes any patent, then any and all rights granted directly or indirectly to You by such Participant, the Initial Developer (if the Initial Developer is not the Participant) and all Contributors under Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice from Participant terminate prospectively and automatically at the expiration of such 60 day notice period, unless if within such 60 day period You withdraw Your claim with respect to the Participant Software against such Participant either unilaterally or pursuant to a written agreement with Participant. +6.3. If You assert a patent infringement claim against Participant alleging that the Participant Software directly or indirectly infringes any patent where such claim is resolved (such as by license or settlement) prior to the initiation of patent infringement litigation, then the reasonable value of the licenses granted by such Participant under Sections 2.1 or 2.2 shall be taken into account in determining the amount or value of any payment or license. +6.4. In the event of termination under Sections 6.1 or 6.2 above, all end user licenses that have been validly granted by You or any distributor hereunder prior to termination (excluding licenses granted to You by any distributor) shall survive termination. +7. LIMITATION OF LIABILITY. + +UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. + +8. U.S. GOVERNMENT END USERS. + +The Covered Software is a “commercial item,” as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of “commercial computer software” (as that term is defined at 48 C.F.R. § 252.227-7014(a)(1)) and “commercial computer software documentation” as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Software with only those rights set forth herein. This U.S. Government Rights clause is in lieu of, and supersedes, any other FAR, DFAR, or other clause or provision that addresses Government rights in computer software under this License. + +9. MISCELLANEOUS. + +This License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by the law of the jurisdiction specified in a notice contained within the Original Software (except to the extent applicable law, if any, provides otherwise), excluding such jurisdiction's conflict-of-law provisions. Any litigation relating to this License shall be subject to the jurisdiction of the courts located in the jurisdiction and venue specified in a notice contained within the Original Software, with the losing party responsible for costs, including, without limitation, court costs and reasonable attorneys' fees and expenses. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License. You agree that You alone are responsible for compliance with the United States export administration regulations (and the export control laws and regulation of any other countries) when You use, distribute or otherwise make available any Covered Software. + +10. RESPONSIBILITY FOR CLAIMS. + +As between Initial Developer and the Contributors, each party is responsible for claims and damages arising, directly or indirectly, out of its utilization of rights under this License and You agree to work with Initial Developer and Contributors to distribute such responsibility on an equitable basis. Nothing herein is intended or shall be deemed to constitute any admission of liability. + +NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) + +The code released under the CDDL shall be governed by the laws of the State of California (excluding conflict-of-law provisions). Any litigation relating to this License shall be subject to the jurisdiction of the Federal Courts of the Northern District of California and the state courts of the State of California, with venue lying in Santa Clara County, California. \ No newline at end of file diff --git a/solr/licenses/jersey-server-1.8.jar.sha1 b/solr/licenses/jersey-server-1.8.jar.sha1 new file mode 100644 index 00000000000..9e885f6d7e9 --- /dev/null +++ b/solr/licenses/jersey-server-1.8.jar.sha1 @@ -0,0 +1 @@ +6da1231f5e2d7a9f7d194e292fc3695ba7710b2f diff --git a/solr/licenses/jersey-server-LICENSE-CDDL.txt b/solr/licenses/jersey-server-LICENSE-CDDL.txt new file mode 100644 index 00000000000..64df8d56300 --- /dev/null +++ b/solr/licenses/jersey-server-LICENSE-CDDL.txt @@ -0,0 +1,85 @@ +COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL)Version 1.1 + +1. Definitions. + +1.1. “Contributor” means each individual or entity that creates or contributes to the creation of Modifications. +1.2. “Contributor Version” means the combination of the Original Software, prior Modifications used by a Contributor (if any), and the Modifications made by that particular Contributor. +1.3. “Covered Software” means (a) the Original Software, or (b) Modifications, or (c) the combination of files containing Original Software with files containing Modifications, in each case including portions thereof. +1.4. “Executable” means the Covered Software in any form other than Source Code. +1.5. “Initial Developer” means the individual or entity that first makes Original Software available under this License. +1.6. “Larger Work” means a work which combines Covered Software or portions thereof with code not governed by the terms of this License. +1.7. “License” means this document. +1.8. “Licensable” means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently acquired, any and all of the rights conveyed herein. +1.9. “Modifications” means the Source Code and Executable form of any of the following: +A. Any file that results from an addition to, deletion from or modification of the contents of a file containing Original Software or previous Modifications; +B. Any new file that contains any part of the Original Software or previous Modification; or +C. Any new file that is contributed or otherwise made available under the terms of this License. +1.10. “Original Software” means the Source Code and Executable form of computer software code that is originally released under this License. +1.11. “Patent Claims” means any patent claim(s), now owned or hereafter acquired, including without limitation, method, process, and apparatus claims, in any patent Licensable by grantor. +1.12. “Source Code” means (a) the common form of computer software code in which modifications are made and (b) associated documentation included in or with such code. +1.13. “You” (or “Your”) means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, “You” includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, “control” means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. +2. License Grants. + +2.1. The Initial Developer Grant. +Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, the Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license: +(a) under intellectual property rights (other than patent or trademark) Licensable by Initial Developer, to use, reproduce, modify, display, perform, sublicense and distribute the Original Software (or portions thereof), with or without Modifications, and/or as part of a Larger Work; and +(b) under Patent Claims infringed by the making, using or selling of Original Software, to make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of the Original Software (or portions thereof). +(c) The licenses granted in Sections 2.1(a) and (b) are effective on the date Initial Developer first distributes or otherwise makes the Original Software available to a third party under the terms of this License. +(d) Notwithstanding Section 2.1(b) above, no patent license is granted: (1) for code that You delete from the Original Software, or (2) for infringements caused by: (i) the modification of the Original Software, or (ii) the combination of the Original Software with other software or devices. +2.2. Contributor Grant. +Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license: +(a) under intellectual property rights (other than patent or trademark) Licensable by Contributor to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof), either on an unmodified basis, with other Modifications, as Covered Software and/or as part of a Larger Work; and +(b) under Patent Claims infringed by the making, using, or selling of Modifications made by that Contributor either alone and/or in combination with its Contributor Version (or portions of such combination), to make, use, sell, offer for sale, have made, and/or otherwise dispose of: (1) Modifications made by that Contributor (or portions thereof); and (2) the combination of Modifications made by that Contributor with its Contributor Version (or portions of such combination). +(c) The licenses granted in Sections 2.2(a) and 2.2(b) are effective on the date Contributor first distributes or otherwise makes the Modifications available to a third party. +(d) Notwithstanding Section 2.2(b) above, no patent license is granted: (1) for any code that Contributor has deleted from the Contributor Version; (2) for infringements caused by: (i) third party modifications of Contributor Version, or (ii) the combination of Modifications made by that Contributor with other software (except as part of the Contributor Version) or other devices; or (3) under Patent Claims infringed by Covered Software in the absence of Modifications made by that Contributor. +3. Distribution Obligations. + +3.1. Availability of Source Code. +Any Covered Software that You distribute or otherwise make available in Executable form must also be made available in Source Code form and that Source Code form must be distributed only under the terms of this License. You must include a copy of this License with every copy of the Source Code form of the Covered Software You distribute or otherwise make available. You must inform recipients of any such Covered Software in Executable form as to how they can obtain such Covered Software in Source Code form in a reasonable manner on or through a medium customarily used for software exchange. +3.2. Modifications. +The Modifications that You create or to which You contribute are governed by the terms of this License. You represent that You believe Your Modifications are Your original creation(s) and/or You have sufficient rights to grant the rights conveyed by this License. +3.3. Required Notices. +You must include a notice in each of Your Modifications that identifies You as the Contributor of the Modification. You may not remove or alter any copyright, patent or trademark notices contained within the Covered Software, or any notices of licensing or any descriptive text giving attribution to any Contributor or the Initial Developer. +3.4. Application of Additional Terms. +You may not offer or impose any terms on any Covered Software in Source Code form that alters or restricts the applicable version of this License or the recipients' rights hereunder. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Software. However, you may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear that any such warranty, support, indemnity or liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of warranty, support, indemnity or liability terms You offer. +3.5. Distribution of Executable Versions. +You may distribute the Executable form of the Covered Software under the terms of this License or under the terms of a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable form does not attempt to limit or alter the recipient's rights in the Source Code form from the rights set forth in this License. If You distribute the Covered Software in Executable form under a different license, You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer. +3.6. Larger Works. +You may create a Larger Work by combining Covered Software with other code not governed by the terms of this License and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this License are fulfilled for the Covered Software. +4. Versions of the License. + +4.1. New Versions. +Oracle is the initial license steward and may publish revised and/or new versions of this License from time to time. Each version will be given a distinguishing version number. Except as provided in Section 4.3, no one other than the license steward has the right to modify this License. +4.2. Effect of New Versions. +You may always continue to use, distribute or otherwise make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. If the Initial Developer includes a notice in the Original Software prohibiting it from being distributed or otherwise made available under any subsequent version of the License, You must distribute and make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. Otherwise, You may also choose to use, distribute or otherwise make the Covered Software available under the terms of any subsequent version of the License published by the license steward. +4.3. Modified Versions. +When You are an Initial Developer and You want to create a new license for Your Original Software, You may create and use a modified version of this License if You: (a) rename the license and remove any references to the name of the license steward (except to note that the license differs from this License); and (b) otherwise make it clear that the license contains terms which differ from this License. +5. DISCLAIMER OF WARRANTY. + +COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN “AS IS” BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + +6. TERMINATION. + +6.1. This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach within 30 days of becoming aware of the breach. Provisions which, by their nature, must remain in effect beyond the termination of this License shall survive. +6.2. If You assert a patent infringement claim (excluding declaratory judgment actions) against Initial Developer or a Contributor (the Initial Developer or Contributor against whom You assert such claim is referred to as “Participant”) alleging that the Participant Software (meaning the Contributor Version where the Participant is a Contributor or the Original Software where the Participant is the Initial Developer) directly or indirectly infringes any patent, then any and all rights granted directly or indirectly to You by such Participant, the Initial Developer (if the Initial Developer is not the Participant) and all Contributors under Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice from Participant terminate prospectively and automatically at the expiration of such 60 day notice period, unless if within such 60 day period You withdraw Your claim with respect to the Participant Software against such Participant either unilaterally or pursuant to a written agreement with Participant. +6.3. If You assert a patent infringement claim against Participant alleging that the Participant Software directly or indirectly infringes any patent where such claim is resolved (such as by license or settlement) prior to the initiation of patent infringement litigation, then the reasonable value of the licenses granted by such Participant under Sections 2.1 or 2.2 shall be taken into account in determining the amount or value of any payment or license. +6.4. In the event of termination under Sections 6.1 or 6.2 above, all end user licenses that have been validly granted by You or any distributor hereunder prior to termination (excluding licenses granted to You by any distributor) shall survive termination. +7. LIMITATION OF LIABILITY. + +UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. + +8. U.S. GOVERNMENT END USERS. + +The Covered Software is a “commercial item,” as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of “commercial computer software” (as that term is defined at 48 C.F.R. § 252.227-7014(a)(1)) and “commercial computer software documentation” as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Software with only those rights set forth herein. This U.S. Government Rights clause is in lieu of, and supersedes, any other FAR, DFAR, or other clause or provision that addresses Government rights in computer software under this License. + +9. MISCELLANEOUS. + +This License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by the law of the jurisdiction specified in a notice contained within the Original Software (except to the extent applicable law, if any, provides otherwise), excluding such jurisdiction's conflict-of-law provisions. Any litigation relating to this License shall be subject to the jurisdiction of the courts located in the jurisdiction and venue specified in a notice contained within the Original Software, with the losing party responsible for costs, including, without limitation, court costs and reasonable attorneys' fees and expenses. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License. You agree that You alone are responsible for compliance with the United States export administration regulations (and the export control laws and regulation of any other countries) when You use, distribute or otherwise make available any Covered Software. + +10. RESPONSIBILITY FOR CLAIMS. + +As between Initial Developer and the Contributors, each party is responsible for claims and damages arising, directly or indirectly, out of its utilization of rights under this License and You agree to work with Initial Developer and Contributors to distribute such responsibility on an equitable basis. Nothing herein is intended or shall be deemed to constitute any admission of liability. + +NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) + +The code released under the CDDL shall be governed by the laws of the State of California (excluding conflict-of-law provisions). Any litigation relating to this License shall be subject to the jurisdiction of the Federal Courts of the Northern District of California and the state courts of the State of California, with venue lying in Santa Clara County, California. \ No newline at end of file diff --git a/solr/licenses/metrics-core-3.0.1.jar.sha1 b/solr/licenses/metrics-core-3.0.1.jar.sha1 new file mode 100644 index 00000000000..1d42f50b422 --- /dev/null +++ b/solr/licenses/metrics-core-3.0.1.jar.sha1 @@ -0,0 +1 @@ +1e98427c7f6e53363b598e2943e50903ce4f3657 diff --git a/solr/licenses/metrics-core-LICENSE-ASL.txt b/solr/licenses/metrics-core-LICENSE-ASL.txt new file mode 100644 index 00000000000..e4ba40426da --- /dev/null +++ b/solr/licenses/metrics-core-LICENSE-ASL.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2010-2012 Coda Hale and Yammer, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/solr/licenses/metrics-core-NOTICE.txt b/solr/licenses/metrics-core-NOTICE.txt new file mode 100644 index 00000000000..4fe83de38a5 --- /dev/null +++ b/solr/licenses/metrics-core-NOTICE.txt @@ -0,0 +1,11 @@ +Metrics +Copyright 2010-2013 Coda Hale and Yammer, Inc. + +This product includes software developed by Coda Hale and Yammer, Inc. + +This product includes code derived from the JSR-166 project (ThreadLocalRandom, Striped64, +LongAdder), which was released with the following comments: + + Written by Doug Lea with assistance from members of JCP JSR-166 + Expert Group and released to the public domain, as explained at + http://creativecommons.org/publicdomain/zero/1.0/ diff --git a/solr/licenses/metrics-healthchecks-3.0.1.jar.sha1 b/solr/licenses/metrics-healthchecks-3.0.1.jar.sha1 new file mode 100644 index 00000000000..4c1055ff1fe --- /dev/null +++ b/solr/licenses/metrics-healthchecks-3.0.1.jar.sha1 @@ -0,0 +1 @@ +bec37e61ebe40bf0f52f3fc8b7df57b5c1773682 diff --git a/solr/licenses/metrics-healthchecks-LICENSE-ASL.txt b/solr/licenses/metrics-healthchecks-LICENSE-ASL.txt new file mode 100644 index 00000000000..e4ba40426da --- /dev/null +++ b/solr/licenses/metrics-healthchecks-LICENSE-ASL.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2010-2012 Coda Hale and Yammer, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/solr/licenses/metrics-healthchecks-NOTICE.txt b/solr/licenses/metrics-healthchecks-NOTICE.txt new file mode 100644 index 00000000000..4fe83de38a5 --- /dev/null +++ b/solr/licenses/metrics-healthchecks-NOTICE.txt @@ -0,0 +1,11 @@ +Metrics +Copyright 2010-2013 Coda Hale and Yammer, Inc. + +This product includes software developed by Coda Hale and Yammer, Inc. + +This product includes code derived from the JSR-166 project (ThreadLocalRandom, Striped64, +LongAdder), which was released with the following comments: + + Written by Doug Lea with assistance from members of JCP JSR-166 + Expert Group and released to the public domain, as explained at + http://creativecommons.org/publicdomain/zero/1.0/ diff --git a/solr/licenses/mockito-core-1.9.5.jar.sha1 b/solr/licenses/mockito-core-1.9.5.jar.sha1 new file mode 100644 index 00000000000..5de9041c834 --- /dev/null +++ b/solr/licenses/mockito-core-1.9.5.jar.sha1 @@ -0,0 +1 @@ +c3264abeea62c4d2f367e21484fbb40c7e256393 diff --git a/solr/licenses/mockito-core-LICENSE-MIT.txt b/solr/licenses/mockito-core-LICENSE-MIT.txt new file mode 100644 index 00000000000..e0840a446ca --- /dev/null +++ b/solr/licenses/mockito-core-LICENSE-MIT.txt @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2007 Mockito contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/solr/licenses/mrunit-1.0.0-hadoop2.jar.sha1 b/solr/licenses/mrunit-1.0.0-hadoop2.jar.sha1 new file mode 100644 index 00000000000..6146ee05008 --- /dev/null +++ b/solr/licenses/mrunit-1.0.0-hadoop2.jar.sha1 @@ -0,0 +1 @@ +d6e4cce578b705508bfd7fd3fafbccc3adb33e83 diff --git a/solr/licenses/mrunit-LICENSE-ASL.txt b/solr/licenses/mrunit-LICENSE-ASL.txt new file mode 100644 index 00000000000..75f307ab0ad --- /dev/null +++ b/solr/licenses/mrunit-LICENSE-ASL.txt @@ -0,0 +1,479 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +========================================================================== +The Apache License, Version 2.0 applies to the following libraries: +commons-logging + +========================================================================== +The following license applies to the junit library +-------------------------------------------------------------------------- + +Common Public License Version 1.0 + +THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC +LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM +CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +1. DEFINITIONS + +"Contribution" means: + +a) in the case of the initial Contributor, the initial code and +documentation distributed under this Agreement, and + +b) in the case of each subsequent Contributor: + +i) changes to the Program, and + +ii) additions to the Program; + +where such changes and/or additions to the Program originate from and are +distributed by that particular Contributor. A Contribution 'originates' from a +Contributor if it was added to the Program by such Contributor itself or anyone +acting on such Contributor's behalf. Contributions do not include additions to +the Program which: (i) are separate modules of software distributed in +conjunction with the Program under their own license agreement, and (ii) are not +derivative works of the Program. + +"Contributor" means any person or entity that distributes the Program. + +"Licensed Patents " mean patent claims licensable by a Contributor which are +necessarily infringed by the use or sale of its Contribution alone or when +combined with the Program. + +"Program" means the Contributions distributed in accordance with this Agreement. + +"Recipient" means anyone who receives the Program under this Agreement, +including all Contributors. + +2. GRANT OF RIGHTS + +a) Subject to the terms of this Agreement, each Contributor hereby grants +Recipient a non-exclusive, worldwide, royalty-free copyright license to +reproduce, prepare derivative works of, publicly display, publicly perform, +distribute and sublicense the Contribution of such Contributor, if any, and such +derivative works, in source code and object code form. + +b) Subject to the terms of this Agreement, each Contributor hereby grants +Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed +Patents to make, use, sell, offer to sell, import and otherwise transfer the +Contribution of such Contributor, if any, in source code and object code form. +This patent license shall apply to the combination of the Contribution and the +Program if, at the time the Contribution is added by the Contributor, such +addition of the Contribution causes such combination to be covered by the +Licensed Patents. The patent license shall not apply to any other combinations +which include the Contribution. No hardware per se is licensed hereunder. + +c) Recipient understands that although each Contributor grants the licenses +to its Contributions set forth herein, no assurances are provided by any +Contributor that the Program does not infringe the patent or other intellectual +property rights of any other entity. Each Contributor disclaims any liability to +Recipient for claims brought by any other entity based on infringement of +intellectual property rights or otherwise. As a condition to exercising the +rights and licenses granted hereunder, each Recipient hereby assumes sole +responsibility to secure any other intellectual property rights needed, if any. +For example, if a third party patent license is required to allow Recipient to +distribute the Program, it is Recipient's responsibility to acquire that license +before distributing the Program. + +d) Each Contributor represents that to its knowledge it has sufficient +copyright rights in its Contribution, if any, to grant the copyright license set +forth in this Agreement. + +3. REQUIREMENTS + +A Contributor may choose to distribute the Program in object code form under its +own license agreement, provided that: + +a) it complies with the terms and conditions of this Agreement; and + +b) its license agreement: + +i) effectively disclaims on behalf of all Contributors all warranties and +conditions, express and implied, including warranties or conditions of title and +non-infringement, and implied warranties or conditions of merchantability and +fitness for a particular purpose; + +ii) effectively excludes on behalf of all Contributors all liability for +damages, including direct, indirect, special, incidental and consequential +damages, such as lost profits; + +iii) states that any provisions which differ from this Agreement are offered +by that Contributor alone and not by any other party; and + +iv) states that source code for the Program is available from such +Contributor, and informs licensees how to obtain it in a reasonable manner on or +through a medium customarily used for software exchange. + +When the Program is made available in source code form: + +a) it must be made available under this Agreement; and + +b) a copy of this Agreement must be included with each copy of the Program. + +Contributors may not remove or alter any copyright notices contained within the +Program. + +Each Contributor must identify itself as the originator of its Contribution, if +any, in a manner that reasonably allows subsequent Recipients to identify the +originator of the Contribution. + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain responsibilities with +respect to end users, business partners and the like. While this license is +intended to facilitate the commercial use of the Program, the Contributor who +includes the Program in a commercial product offering should do so in a manner +which does not create potential liability for other Contributors. Therefore, if +a Contributor includes the Program in a commercial product offering, such +Contributor ("Commercial Contributor") hereby agrees to defend and indemnify +every other Contributor ("Indemnified Contributor") against any losses, damages +and costs (collectively "Losses") arising from claims, lawsuits and other legal +actions brought by a third party against the Indemnified Contributor to the +extent caused by the acts or omissions of such Commercial Contributor in +connection with its distribution of the Program in a commercial product +offering. The obligations in this section do not apply to any claims or Losses +relating to any actual or alleged intellectual property infringement. In order +to qualify, an Indemnified Contributor must: a) promptly notify the Commercial +Contributor in writing of such claim, and b) allow the Commercial Contributor to +control, and cooperate with the Commercial Contributor in, the defense and any +related settlement negotiations. The Indemnified Contributor may participate in +any such claim at its own expense. + +For example, a Contributor might include the Program in a commercial product +offering, Product X. That Contributor is then a Commercial Contributor. If that +Commercial Contributor then makes performance claims, or offers warranties +related to Product X, those performance claims and warranties are such +Commercial Contributor's responsibility alone. Under this section, the +Commercial Contributor would have to defend claims against the other +Contributors related to those performance claims and warranties, and if a court +requires any other Contributor to pay any damages as a result, the Commercial +Contributor must pay those damages. + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR +IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, +NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each +Recipient is solely responsible for determining the appropriateness of using and +distributing the Program and assumes all risks associated with its exercise of +rights under this Agreement, including but not limited to the risks and costs of +program errors, compliance with applicable laws, damage to or loss of data, +programs or equipment, and unavailability or interruption of operations. + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY +CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST +PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS +GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +7. GENERAL + +If any provision of this Agreement is invalid or unenforceable under applicable +law, it shall not affect the validity or enforceability of the remainder of the +terms of this Agreement, and without further action by the parties hereto, such +provision shall be reformed to the minimum extent necessary to make such +provision valid and enforceable. + +If Recipient institutes patent litigation against a Contributor with respect to +a patent applicable to software (including a cross-claim or counterclaim in a +lawsuit), then any patent licenses granted by that Contributor to such Recipient +under this Agreement shall terminate as of the date such litigation is filed. In +addition, if Recipient institutes patent litigation against any entity +(including a cross-claim or counterclaim in a lawsuit) alleging that the Program +itself (excluding combinations of the Program with other software or hardware) +infringes such Recipient's patent(s), then such Recipient's rights granted under +Section 2(b) shall terminate as of the date such litigation is filed. + +All Recipient's rights under this Agreement shall terminate if it fails to +comply with any of the material terms or conditions of this Agreement and does +not cure such failure in a reasonable period of time after becoming aware of +such noncompliance. If all Recipient's rights under this Agreement terminate, +Recipient agrees to cease use and distribution of the Program as soon as +reasonably practicable. However, Recipient's obligations under this Agreement +and any licenses granted by Recipient relating to the Program shall continue and +survive. + +Everyone is permitted to copy and distribute copies of this Agreement, but in +order to avoid inconsistency the Agreement is copyrighted and may only be +modified in the following manner. The Agreement Steward reserves the right to +publish new versions (including revisions) of this Agreement from time to time. +No one other than the Agreement Steward has the right to modify this Agreement. +IBM is the initial Agreement Steward. IBM may assign the responsibility to serve +as the Agreement Steward to a suitable separate entity. Each new version of the +Agreement will be given a distinguishing version number. The Program (including +Contributions) may always be distributed subject to the version of the Agreement +under which it was received. In addition, after a new version of the Agreement +is published, Contributor may elect to distribute the Program (including its +Contributions) under the new version. Except as expressly stated in Sections +2(a) and 2(b) above, Recipient receives no rights or licenses to the +intellectual property of any Contributor under this Agreement, whether +expressly, by implication, estoppel or otherwise. All rights in the Program not +expressly granted under this Agreement are reserved. + +This Agreement is governed by the laws of the State of New York and the +intellectual property laws of the United States of America. No party to this +Agreement will bring a legal action under this Agreement more than one year +after the cause of action arose. Each party waives its rights to a jury trial in +any resulting litigation. + +========================================================================== +The following license applies to the mockito library +-------------------------------------------------------------------------- + +The MIT License + +Copyright (c) 2007 Mockito contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +========================================================================== +The following license applies to the hamcrest library +-------------------------------------------------------------------------- + +The BSD 2-Clause License + +Copyright (c) 2000-2006, www.hamcrest.org +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +- Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/solr/licenses/mrunit-NOTICE.txt b/solr/licenses/mrunit-NOTICE.txt new file mode 100644 index 00000000000..2dfba62fbfc --- /dev/null +++ b/solr/licenses/mrunit-NOTICE.txt @@ -0,0 +1,5 @@ +Apache MRUnit +Copyright 2011-2012 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). \ No newline at end of file diff --git a/solr/licenses/netty-3.6.2.Final.jar.sha1 b/solr/licenses/netty-3.6.2.Final.jar.sha1 new file mode 100644 index 00000000000..10c334de1a8 --- /dev/null +++ b/solr/licenses/netty-3.6.2.Final.jar.sha1 @@ -0,0 +1 @@ +69be11c61427f0604a30539755add84ad9e37e5e diff --git a/solr/licenses/netty-LICENSE-ASL.txt b/solr/licenses/netty-LICENSE-ASL.txt new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/solr/licenses/netty-LICENSE-ASL.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/solr/licenses/netty-NOTICE.txt b/solr/licenses/netty-NOTICE.txt new file mode 100644 index 00000000000..ef811d15d03 --- /dev/null +++ b/solr/licenses/netty-NOTICE.txt @@ -0,0 +1,121 @@ + + The Netty Project + ================= + +Please visit the Netty web site for more information: + + * http://netty.io/ + +Copyright 2011 The Netty Project + +The Netty Project licenses this file to you under the Apache License, +version 2.0 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at: + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +License for the specific language governing permissions and limitations +under the License. + +Also, please refer to each LICENSE..txt file, which is located in +the 'license' directory of the distribution file, for the license terms of the +components that this product depends on. + +------------------------------------------------------------------------------- +This product contains the extensions to Java Collections Framework which has +been derived from the works by JSR-166 EG, Doug Lea, and Jason T. Greene: + + * LICENSE: + * license/LICENSE.jsr166y.txt (Public Domain) + * HOMEPAGE: + * http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/ + * http://viewvc.jboss.org/cgi-bin/viewvc.cgi/jbosscache/experimental/jsr166/ + +This product contains a modified version of Robert Harder's Public Domain +Base64 Encoder and Decoder, which can be obtained at: + + * LICENSE: + * license/LICENSE.base64.txt (Public Domain) + * HOMEPAGE: + * http://iharder.sourceforge.net/current/java/base64/ + +This product contains a modified portion of 'Webbit', an event based +WebSocket and HTTP server, which can be obtained at: + + * LICENSE: + * license/LICENSE.webbit.txt (BSD License) + * HOMEPAGE: + * https://github.com/joewalnes/webbit + +This product contains a modified portion of 'Caliper', Google's micro- +benchmarking framework, which can be obtained at: + + * LICENSE: + * license/LICENSE.caliper.txt (Apache License 2.0) + * HOMEPAGE: + * http://code.google.com/p/caliper/ + +This product contains a modified portion of 'SLF4J', a simple logging +facade for Java, which can be obtained at: + + * LICENSE: + * license/LICENSE.slf4j.txt (MIT License) + * HOMEPAGE: + * http://www.slf4j.org/ + +This product contains a modified portion of 'ArrayDeque', written by Josh +Bloch of Google, Inc: + + * LICENSE: + * license/LICENSE.deque.txt (Public Domain) + +This product optionally depends on 'JZlib', a re-implementation of zlib in +pure Java, which can be obtained at: + + * LICENSE: + * license/LICENSE.jzlib.txt (BSD style License) + * HOMEPAGE: + * http://www.jcraft.com/jzlib/ + +This product optionally depends on 'Protocol Buffers', Google's data +interchange format, which can be obtained at: + + * LICENSE: + * license/LICENSE.protobuf.txt (New BSD License) + * HOMEPAGE: + * http://code.google.com/p/protobuf/ + +This product optionally depends on 'JBoss Marshalling', an alternative Java +serialization API, which can be obtained at: + + * LICENSE: + * license/LICENSE.jboss-marshalling.txt (GNU LGPL 2.1) + * HOMEPAGE: + * http://www.jboss.org/jbossmarshalling + +This product optionally depends on 'Apache Commons Logging', a logging +framework, which can be obtained at: + + * LICENSE: + * license/LICENSE.commons-logging.txt (Apache License 2.0) + * HOMEPAGE: + * http://commons.apache.org/logging/ + +This product optionally depends on 'Apache Log4J', a logging framework, which +can be obtained at: + + * LICENSE: + * license/LICENSE.log4j.txt (Apache License 2.0) + * HOMEPAGE: + * http://logging.apache.org/log4j/ + +This product optionally depends on 'Snappy', a compression library produced +by Google Inc, which can be obtained at: + + * LICENSE: + * license/LICENSE.snappy.txt (New BSD License) + * HOMEPAGE: + * http://code.google.com/p/snappy/ diff --git a/solr/licenses/paranamer-2.3.jar.sha1 b/solr/licenses/paranamer-2.3.jar.sha1 new file mode 100644 index 00000000000..21c0b2636d3 --- /dev/null +++ b/solr/licenses/paranamer-2.3.jar.sha1 @@ -0,0 +1 @@ +4a85963a752c0a2f715c3924bfc686865e7e1bc6 diff --git a/solr/licenses/paranamer-LICENSE-BSD.txt b/solr/licenses/paranamer-LICENSE-BSD.txt new file mode 100644 index 00000000000..fca18473ba0 --- /dev/null +++ b/solr/licenses/paranamer-LICENSE-BSD.txt @@ -0,0 +1,28 @@ +[ ParaNamer used to be 'Pubic Domain', but since it includes a small piece of ASM it is now the same license as that: BSD ] + + Copyright (c) 2006 Paul Hammant & ThoughtWorks Inc + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/solr/licenses/paranamer-NOTICE.txt b/solr/licenses/paranamer-NOTICE.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/solr/licenses/snappy-java-1.0.4.1.jar.sha1 b/solr/licenses/snappy-java-1.0.4.1.jar.sha1 new file mode 100644 index 00000000000..b74def86e17 --- /dev/null +++ b/solr/licenses/snappy-java-1.0.4.1.jar.sha1 @@ -0,0 +1 @@ +f88b89a5a21a466aeb0ecf0c063605bd584b4947 diff --git a/solr/licenses/snappy-java-LICENSE-ASL.txt b/solr/licenses/snappy-java-LICENSE-ASL.txt new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/solr/licenses/snappy-java-LICENSE-ASL.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/solr/licenses/snappy-java-NOTICE.txt b/solr/licenses/snappy-java-NOTICE.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/solr/licenses/tika-xmp-1.4.jar.sha1 b/solr/licenses/tika-xmp-1.4.jar.sha1 new file mode 100644 index 00000000000..e0d756cdb09 --- /dev/null +++ b/solr/licenses/tika-xmp-1.4.jar.sha1 @@ -0,0 +1 @@ +412c97017eb6318e30c47e9a69e51879b20b4dde diff --git a/solr/licenses/tika-xmp-LICENSE-ASL.txt b/solr/licenses/tika-xmp-LICENSE-ASL.txt new file mode 100644 index 00000000000..ca855f4c37c --- /dev/null +++ b/solr/licenses/tika-xmp-LICENSE-ASL.txt @@ -0,0 +1,238 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +APACHE TIKA SUBCOMPONENTS + +Apache Tika includes a number of subcomponents with separate copyright notices +and license terms. Your use of these subcomponents is subject to the terms and +conditions of the following licenses. + +MIME type information from file-4.26.tar.gz (http://www.darwinsys.com/file/) + + Copyright (c) Ian F. Darwin 1986, 1987, 1989, 1990, 1991, 1992, 1994, 1995. + Software written by Ian F. Darwin and others; + maintained 1994- Christos Zoulas. + + This software is not subject to any export provision of the United States + Department of Commerce, and may be exported to any country or planet. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice immediately at the beginning of the file, without modification, + this list of conditions, and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. diff --git a/solr/licenses/tika-xmp-NOTICE.txt b/solr/licenses/tika-xmp-NOTICE.txt new file mode 100644 index 00000000000..156a582d5b3 --- /dev/null +++ b/solr/licenses/tika-xmp-NOTICE.txt @@ -0,0 +1,15 @@ +Apache Tika xmp +Copyright 2011 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +Copyright 1993-2010 University Corporation for Atmospheric Research/Unidata +This software contains code derived from UCAR/Unidata's NetCDF library. + +Tika-server compoment uses CDDL-licensed dependencies: jersey (http://jersey.java.net/) and +Grizzly (http://grizzly.java.net/) + +OpenCSV: Copyright 2005 Bytecode Pty Ltd. Licensed under the Apache License, Version 2.0 + +IPTC Photo Metadata descriptions Copyright 2010 International Press Telecommunications Council. diff --git a/solr/licenses/xmpcore-5.1.2.jar.sha1 b/solr/licenses/xmpcore-5.1.2.jar.sha1 new file mode 100644 index 00000000000..19af7ca17ff --- /dev/null +++ b/solr/licenses/xmpcore-5.1.2.jar.sha1 @@ -0,0 +1 @@ +55615fa2582424e38705487d1d3969af8554f637 diff --git a/solr/licenses/xmpcore-LICENSE-BSD.txt b/solr/licenses/xmpcore-LICENSE-BSD.txt new file mode 100644 index 00000000000..f0296f1c4c6 --- /dev/null +++ b/solr/licenses/xmpcore-LICENSE-BSD.txt @@ -0,0 +1,11 @@ +Copyright (c) 2009, Adobe Systems Incorporated All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +* Neither the name of Adobe Systems Incorporated, nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANT ABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/solr/licenses/xmpcore-NOTICE.txt b/solr/licenses/xmpcore-NOTICE.txt new file mode 100644 index 00000000000..e69de29bb2d From b49acb38940e6a5a04039b3c944903860da80e98 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Mon, 2 Dec 2013 20:51:19 +0000 Subject: [PATCH 157/223] SOLR-1301: Ivy likes to act funny if you don't declare compile and test resources in the same dependency. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1547187 13f79535-47bb-0310-9956-ffa450edef68 --- solr/contrib/solr-morphlines-core/ivy.xml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/solr/contrib/solr-morphlines-core/ivy.xml b/solr/contrib/solr-morphlines-core/ivy.xml index 290460d27cb..c9948e0cc59 100644 --- a/solr/contrib/solr-morphlines-core/ivy.xml +++ b/solr/contrib/solr-morphlines-core/ivy.xml @@ -27,7 +27,10 @@ - + + + + @@ -37,10 +40,6 @@ - - - - From b7911212bfc783f78993e0ead853d20becb7db46 Mon Sep 17 00:00:00 2001 From: Uwe Schindler Date: Mon, 2 Dec 2013 22:45:34 +0000 Subject: [PATCH 158/223] SOLR-1301: Fix compilation for Java 8 (the Java 8 compiler is more picky, but it's not a Java 8 regression: the code was just wrong) git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1547232 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/solr/morphlines/cell/SolrCellBuilder.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/solr/contrib/solr-morphlines-cell/src/java/org/apache/solr/morphlines/cell/SolrCellBuilder.java b/solr/contrib/solr-morphlines-cell/src/java/org/apache/solr/morphlines/cell/SolrCellBuilder.java index 8d5873fe4e3..af50c7cfd12 100644 --- a/solr/contrib/solr-morphlines-cell/src/java/org/apache/solr/morphlines/cell/SolrCellBuilder.java +++ b/solr/contrib/solr-morphlines-cell/src/java/org/apache/solr/morphlines/cell/SolrCellBuilder.java @@ -124,7 +124,7 @@ public final class SolrCellBuilder implements CommandBuilder { if (uprefix != null) { cellParams.put(ExtractingParams.UNKNOWN_FIELD_PREFIX, uprefix); } - for (String capture : getConfigs().getStringList(config, ExtractingParams.CAPTURE_ELEMENTS, Collections.EMPTY_LIST)) { + for (String capture : getConfigs().getStringList(config, ExtractingParams.CAPTURE_ELEMENTS, Collections.emptyList())) { cellParams.put(ExtractingParams.CAPTURE_ELEMENTS, capture); } Config fmapConfig = getConfigs().getConfig(config, "fmap", null); @@ -182,7 +182,7 @@ public final class SolrCellBuilder implements CommandBuilder { Parser parser = (Parser) obj; this.parsers.add(parser); - List mediaTypes = getConfigs().getStringList(parserConfig, SUPPORTED_MIME_TYPES, Collections.EMPTY_LIST); + List mediaTypes = getConfigs().getStringList(parserConfig, SUPPORTED_MIME_TYPES, Collections.emptyList()); for (String mediaTypeStr : mediaTypes) { MediaType mediaType = parseMediaType(mediaTypeStr); addSupportedMimeType(mediaTypeStr); @@ -195,7 +195,7 @@ public final class SolrCellBuilder implements CommandBuilder { addSupportedMimeType(mediaType.toString()); this.mediaTypeToParserMap.put(mediaType, parser); } - List extras = getConfigs().getStringList(parserConfig, ADDITIONAL_SUPPORTED_MIME_TYPES, Collections.EMPTY_LIST); + List extras = getConfigs().getStringList(parserConfig, ADDITIONAL_SUPPORTED_MIME_TYPES, Collections.emptyList()); for (String mediaTypeStr : extras) { MediaType mediaType = parseMediaType(mediaTypeStr); addSupportedMimeType(mediaTypeStr); From ae33505da58589591f729f1e4745a2922f6a3a94 Mon Sep 17 00:00:00 2001 From: Uwe Schindler Date: Mon, 2 Dec 2013 23:30:54 +0000 Subject: [PATCH 159/223] SOLR-1301: Fix windows problem with escaping of folder name (see crazy https://github.com/typesafehub/config/blob/master/HOCON.md for correct format: string must be quoted and escaped like javascript) git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1547239 13f79535-47bb-0310-9956-ffa450edef68 --- .../solr/morphlines/solr/AbstractSolrMorphlineTestBase.java | 3 ++- .../src/test-files/test-morphlines/solrCellDocumentTypes.conf | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/AbstractSolrMorphlineTestBase.java b/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/AbstractSolrMorphlineTestBase.java index e5e1d3cce67..ac562e66ac7 100644 --- a/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/AbstractSolrMorphlineTestBase.java +++ b/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/AbstractSolrMorphlineTestBase.java @@ -28,6 +28,7 @@ import java.util.Map.Entry; import java.util.concurrent.atomic.AtomicInteger; import org.apache.commons.io.FileUtils; +import org.apache.commons.lang.StringEscapeUtils; import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.SolrServer; @@ -182,7 +183,7 @@ public class AbstractSolrMorphlineTestBase extends SolrTestCaseJ4 { public static void setupMorphline(String tempDir, String file) throws IOException { String morphlineText = FileUtils.readFileToString(new File(RESOURCES_DIR + "/" + file + ".conf"), "UTF-8"); - morphlineText = morphlineText.replaceAll("RESOURCES_DIR", new File(tempDir).getAbsolutePath()); + morphlineText = morphlineText.replace("RESOURCES_DIR", StringEscapeUtils.escapeJavaScript(new File(tempDir).getAbsolutePath())); FileUtils.writeStringToFile(new File(tempDir + "/" + file + ".conf"), morphlineText, "UTF-8"); } diff --git a/solr/contrib/solr-mr/src/test-files/test-morphlines/solrCellDocumentTypes.conf b/solr/contrib/solr-mr/src/test-files/test-morphlines/solrCellDocumentTypes.conf index bf1e58d5fb4..dd769a71ba1 100644 --- a/solr/contrib/solr-mr/src/test-files/test-morphlines/solrCellDocumentTypes.conf +++ b/solr/contrib/solr-mr/src/test-files/test-morphlines/solrCellDocumentTypes.conf @@ -52,7 +52,7 @@ morphlines : [ # used for auto-detection if MIME type isn't explicitly supplied detectMimeType { includeDefaultMimeTypes : true - mimeTypesFiles : [RESOURCES_DIR/custom-mimetypes.xml] + mimeTypesFiles : ["RESOURCES_DIR/custom-mimetypes.xml"] } } From 4a1301c75084a913963f9949fe1f350c5c80f51a Mon Sep 17 00:00:00 2001 From: Uwe Schindler Date: Mon, 2 Dec 2013 23:49:30 +0000 Subject: [PATCH 160/223] SOLR-1301: Ignore windows tests that cannot work because they use UNIX semantics. Also remove a never-executed test which tests nothing git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1547242 13f79535-47bb-0310-9956-ffa450edef68 --- ...apReduceIndexerToolArgumentParserTest.java | 8 ++- .../solr/hadoop/MorphlineMapperTest.java | 7 +++ .../solr/hadoop/MorphlineReducerTest.java | 6 +++ .../apache/solr/hadoop/PathValidation.java | 51 ------------------- 4 files changed, 20 insertions(+), 52 deletions(-) delete mode 100644 solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/PathValidation.java diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MapReduceIndexerToolArgumentParserTest.java b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MapReduceIndexerToolArgumentParserTest.java index a292a1b0d39..e95ebb851d7 100644 --- a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MapReduceIndexerToolArgumentParserTest.java +++ b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MapReduceIndexerToolArgumentParserTest.java @@ -26,6 +26,7 @@ import java.util.Collections; import org.apache.commons.io.FileUtils; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; +import org.apache.lucene.util.Constants; import org.apache.lucene.util.LuceneTestCase; import org.apache.solr.cloud.AbstractZkTestCase; import org.apache.solr.hadoop.dedup.NoChangeUpdateConflictResolver; @@ -33,6 +34,7 @@ import org.apache.solr.hadoop.dedup.RetainMostRecentUpdateConflictResolver; import org.apache.solr.util.ExternalPaths; import org.junit.After; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -53,10 +55,14 @@ public class MapReduceIndexerToolArgumentParserTest extends LuceneTestCase { private static final String MORPHLINE_FILE = RESOURCES_DIR + "/test-morphlines/solrCellDocumentTypes.conf"; private static final Logger LOG = LoggerFactory.getLogger(MapReduceIndexerToolArgumentParserTest.class); - private static final File solrHomeDirectory = new File(TEMP_DIR, MorphlineGoLiveMiniMRTest.class.getName()); + @BeforeClass + public static void beforeClass() { + assumeFalse("Does not work on Windows, because it uses UNIX shell commands or POSIX paths", Constants.WINDOWS); + } + @Before public void setUp() throws Exception { super.setUp(); diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineMapperTest.java b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineMapperTest.java index 3316caa0824..bbd3897df69 100644 --- a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineMapperTest.java +++ b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineMapperTest.java @@ -23,12 +23,19 @@ import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mrunit.mapreduce.MapDriver; import org.apache.hadoop.mrunit.types.Pair; +import org.apache.lucene.util.Constants; import org.apache.solr.common.SolrInputDocument; import org.apache.solr.hadoop.morphline.MorphlineMapper; +import org.junit.BeforeClass; import org.junit.Test; public class MorphlineMapperTest extends MRUnitBase { + @BeforeClass + public static void beforeClass() { + assumeFalse("Does not work on Windows, because it uses UNIX shell commands or POSIX paths", Constants.WINDOWS); + } + @Test public void testMapper() throws Exception { MorphlineMapper mapper = new MorphlineMapper(); diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineReducerTest.java b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineReducerTest.java index dee44119243..faa92ea2d09 100644 --- a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineReducerTest.java +++ b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineReducerTest.java @@ -34,6 +34,7 @@ import org.apache.hadoop.mapreduce.RecordReader; import org.apache.hadoop.mapreduce.TaskAttemptContext; import org.apache.hadoop.mapreduce.TaskAttemptID; import org.apache.hadoop.mrunit.mapreduce.ReduceDriver; +import org.apache.lucene.util.Constants; import org.apache.lucene.util.LuceneTestCase; import org.apache.solr.cloud.AbstractZkTestCase; import org.apache.solr.common.SolrInputDocument; @@ -46,6 +47,11 @@ import com.google.common.collect.Lists; public class MorphlineReducerTest extends MRUnitBase { + @BeforeClass + public static void beforeClass() { + assumeFalse("Does not work on Windows, because it uses UNIX shell commands or POSIX paths", Constants.WINDOWS); + } + public static class MySolrReducer extends SolrReducer { Context context; diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/PathValidation.java b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/PathValidation.java deleted file mode 100644 index c76649edb71..00000000000 --- a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/PathValidation.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.solr.hadoop; - -import java.util.regex.Pattern; - -import org.apache.hadoop.fs.Path; -import org.junit.Test; - -public class PathValidation extends MRUnitBase { - - @Test - public void testPath() { - Path path = new Path("hdfs://c2202.mycompany.com:8020/user/foo/bar.txt"); - assertEquals("/user/foo/bar.txt", path.toUri().getPath()); - assertEquals("bar.txt", path.getName()); - assertEquals("hdfs", path.toUri().getScheme()); - assertEquals("c2202.mycompany.com:8020", path.toUri().getAuthority()); - - path = new Path("/user/foo/bar.txt"); - assertEquals("/user/foo/bar.txt", path.toUri().getPath()); - assertEquals("bar.txt", path.getName()); - assertEquals(null, path.toUri().getScheme()); - assertEquals(null, path.toUri().getAuthority()); - - assertEquals("-", new Path("-").toString()); - } - - @Test - public void testRegex() { - Pattern regex = Pattern.compile("text/plain|text/html"); - assertTrue(regex.matcher("text/plain").matches()); - assertTrue(regex.matcher("text/html").matches()); - assertFalse(regex.matcher("xxtext/html").matches()); - } - -} From 8e6f865deed2db3c7014350f8b41e24bc1cf520b Mon Sep 17 00:00:00 2001 From: Erick Erickson Date: Tue, 3 Dec 2013 00:55:25 +0000 Subject: [PATCH 161/223] SOLR-5518: Move editing files to a separte request handler git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1547251 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 3 + .../handler/admin/EditFileRequestHandler.java | 357 ++++++++++++ .../handler/admin/ShowFileRequestHandler.java | 509 +++++------------- .../solr/collection1/conf/solrconfig-tlog.xml | 5 + .../solr/collection1/conf/solrconfig.xml | 6 + .../solr/cloud/TestModifyConfFiles.java | 29 +- .../solr/schema/ModifyConfFileTest.java | 33 +- .../solr/collection1/conf/solrconfig.xml | 13 + 8 files changed, 578 insertions(+), 377 deletions(-) create mode 100644 solr/core/src/java/org/apache/solr/handler/admin/EditFileRequestHandler.java diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 1e5f40d38a9..5a5c1bca2ca 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -117,6 +117,9 @@ New Features * SOLR-5506: Support docValues in CollationField and ICUCollationField. (Robert Muir) + + * SOLR-5518: Added EditFileRequestHandler to deal with security issues around modifying + solr configuration files. * SOLR-5023: Add support for deleteInstanceDir to be passed from SolrJ for Core Unload action. (Lyubov Romanchuk, shalin) diff --git a/solr/core/src/java/org/apache/solr/handler/admin/EditFileRequestHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/EditFileRequestHandler.java new file mode 100644 index 00000000000..fbc4c1b3873 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/handler/admin/EditFileRequestHandler.java @@ -0,0 +1,357 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.handler.admin; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.apache.solr.cloud.ZkController; +import org.apache.solr.cloud.ZkSolrResourceLoader; +import org.apache.solr.common.SolrException; +import org.apache.solr.common.SolrException.ErrorCode; +import org.apache.solr.common.cloud.SolrZkClient; +import org.apache.solr.common.util.ContentStream; +import org.apache.solr.common.util.NamedList; +import org.apache.solr.core.Config; +import org.apache.solr.core.CoreContainer; +import org.apache.solr.core.CoreDescriptor; +import org.apache.solr.core.SolrConfig; +import org.apache.solr.core.SolrCore; +import org.apache.solr.handler.RequestHandlerBase; +import org.apache.solr.request.SolrQueryRequest; +import org.apache.solr.response.RawResponseWriter; +import org.apache.solr.response.SolrQueryResponse; +import org.apache.zookeeper.KeeperException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.xml.sax.InputSource; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Locale; +import java.util.Set; + +/** + * This handler uses the RawResponseWriter to give client access to + * files inside ${solr.home}/conf + *

    + * If you want to selectively restrict access some configuration files, you can list + * these files in the hidden invariants. For example to hide + * synonyms.txt and anotherfile.txt, you would register: + *

    + *

    + * <requestHandler name="/admin/fileupdate" class="org.apache.solr.handler.admin.EditFileRequestHandler" >
    + *   <lst name="defaults">
    + *    <str name="echoParams">explicit</str>
    + *   </lst>
    + *   <lst name="invariants">
    + *    <str name="hidden">synonyms.txt</str>
    + *    <str name="hidden">anotherfile.txt</str>
    + *    <str name="hidden">*</str>
    + *   </lst>
    + * </requestHandler>
    + * 
    + *

    + * At present, there is only explicit file names (including path) or the glob '*' are supported. Variants like '*.xml' + * are NOT supported.ere + *

    + *

    + * The EditFileRequestHandler uses the {@link RawResponseWriter} (wt=raw) to return + * file contents. If you need to use a different writer, you will need to change + * the registered invariant param for wt. + *

    + * If you want to override the contentType header returned for a given file, you can + * set it directly using: CONTENT_TYPE. For example, to get a plain text + * version of schema.xml, try: + *

    + *   http://localhost:8983/solr/admin/fileedit?file=schema.xml&contentType=text/plain
    + * 
    + * + * @since solr 4.7 + *

    + *

    + * You can use this handler to modify any files in the conf directory, e.g. solrconfig.xml + * or schema.xml, or even in sub-directories (e.g. velocity/error.vm) by POSTing a file. Here's an example cURL command + *

    + *                                            curl -X POST --form "fileupload=@schema.new" 'http://localhost:8983/solr/collection1/admin/fileedit?op=write&file=schema.xml'
    + *                                           
    + * + * or + *
    + *                                            curl -X POST --form "fileupload=@error.new" 'http://localhost:8983/solr/collection1/admin/file?op=write&file=velocity/error.vm'
    + *                                           
    + * + * For the first iteration, this is probably going to be used from the Solr admin screen. + * + * NOTE: Specifying a directory or simply leaving the any "file=XXX" parameters will list the contents of a directory. + * + * NOTE: You must reload the core/collection for any changes made via this handler to take effect! + * + * NOTE: If the core does not load (say schema.xml is not well formed for instance) you may be unable to replace + * the files with this interface. + * + * NOTE: Leaving this handler enabled is a security risk! This handler should be disabled in all but trusted + * (probably development only) environments! + * + * Configuration files in ZooKeeper are supported. + */ +public class EditFileRequestHandler extends RequestHandlerBase { + + protected static final Logger log = LoggerFactory.getLogger(EditFileRequestHandler.class); + + private final static String OP_PARAM = "op"; + private final static String OP_WRITE = "write"; + private final static String OP_TEST = "test"; + + ContentStream stream; + private byte[] data = null; + Set hiddenFiles; + + public EditFileRequestHandler() { + super(); + } + + @Override + public void init(NamedList args) { + super.init(args); + hiddenFiles = ShowFileRequestHandler.initHidden(invariants); + } + + @Override + public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) + throws InterruptedException, KeeperException, IOException { + + CoreContainer coreContainer = req.getCore().getCoreDescriptor().getCoreContainer(); + String op = req.getParams().get(OP_PARAM); + if (OP_WRITE.equalsIgnoreCase(op) || OP_TEST.equalsIgnoreCase(op)) { + String fname = req.getParams().get("file", null); + if (fname == null) { + rsp.setException(new SolrException(ErrorCode.BAD_REQUEST, "No file name specified for write operation.")); + } else { + fname = fname.replace('\\', '/'); + stream = getOneInputStream(req, rsp); + if (stream == null) { + return; // Error already in rsp. + } + + data = IOUtils.toByteArray(new InputStreamReader(stream.getStream(), "UTF-8"), "UTF-8"); + + // If it's "solrconfig.xml", try parsing it as that object. Otherwise, if it ends in '.xml', + // see if it at least parses. + if ("solrconfig.xml".equals(fname)) { + try { + new SolrConfig("unused", new InputSource(new ByteArrayInputStream(data))); + } catch (Exception e) { + rsp.setException(new SolrException(ErrorCode.BAD_REQUEST, "Invalid solr config file: " + e.getMessage())); + return; + } + } else if (fname.endsWith(".xml")) { // At least do a rudimentary test, see if the thing parses. + try { + new Config(null, null, new InputSource(new ByteArrayInputStream(data)), null, false); + } catch (Exception e) { + rsp.setException(new SolrException(ErrorCode.BAD_REQUEST, "Invalid XML file: " + e.getMessage())); + return; + } + } + if (ShowFileRequestHandler.isHiddenFile(req, rsp, fname, true, hiddenFiles) == false) { + if (coreContainer.isZooKeeperAware()) { + writeToZooKeeper(req, rsp); + } else { + writeToFileSystem(req, rsp); + } + } + } + } + } + + // write the file contained in the parameter "file=XXX" to ZooKeeper. The file may be a path, e.g. + // file=velocity/error.vm or file=schema.xml + // + // Important: Assumes that the file already exists in ZK, so far we aren't creating files there. + private void writeToZooKeeper(SolrQueryRequest req, SolrQueryResponse rsp) + throws KeeperException, InterruptedException, IOException { + + CoreContainer coreContainer = req.getCore().getCoreDescriptor().getCoreContainer(); + SolrZkClient zkClient = coreContainer.getZkController().getZkClient(); + + String adminFile = ShowFileRequestHandler.getAdminFileFromZooKeeper(req, rsp, zkClient, hiddenFiles); + String fname = req.getParams().get("file", null); + if (OP_TEST.equals(req.getParams().get(OP_PARAM))) { + testReloadSuccess(req, rsp); + return; + } + // Persist the managed schema + try { + // Assumption: the path exists + zkClient.setData(adminFile, data, true); + log.info("Saved " + fname + " to ZooKeeper successfully."); + } catch (KeeperException.BadVersionException e) { + log.error("Cannot save file: " + fname + " to Zookeeper, " + + "ZooKeeper error: " + e.getMessage()); + rsp.setException(new SolrException(ErrorCode.SERVER_ERROR, "Cannot save file: " + fname + " to Zookeeper, " + + "ZooKeeper error: " + e.getMessage())); + } + } + + // Used when POSTing the configuration files to Solr (either ZooKeeper or locally). + // + // It takes some effort to insure that there is one (and only one) stream provided, there's no provision for + // more than one stream at present. + private ContentStream getOneInputStream(SolrQueryRequest req, SolrQueryResponse rsp) { + String file = req.getParams().get("file"); + if (file == null) { + log.error("You must specify a file for the write operation."); + rsp.setException(new SolrException(ErrorCode.BAD_REQUEST, "You must specify a file for the write operation.")); + return null; + } + + // Now, this is truly clumsy + Iterable streams = req.getContentStreams(); + if (streams == null) { + log.error("Input stream list was null for admin file write operation."); + rsp.setException(new SolrException(ErrorCode.BAD_REQUEST, "Input stream list was null for admin file write operation.")); + return null; + } + Iterator iter = streams.iterator(); + if (!iter.hasNext()) { + log.error("No input streams were in the list for admin file write operation."); + rsp.setException(new SolrException(ErrorCode.BAD_REQUEST, "No input streams were in the list for admin file write operation.")); + return null; + } + ContentStream stream = iter.next(); + if (iter.hasNext()) { + log.error("More than one input stream was found for admin file write operation."); + rsp.setException(new SolrException(ErrorCode.BAD_REQUEST, "More than one input stream was found for admin file write operation.")); + return null; + } + return stream; + } + + // Write the data passed in from the stream to the file indicated by the file=XXX parameter on the local file system + private void writeToFileSystem(SolrQueryRequest req, SolrQueryResponse rsp) throws IOException { + + File adminFile = ShowFileRequestHandler.getAdminFileFromFileSystem(req, rsp, hiddenFiles); + if (adminFile == null || adminFile.isDirectory()) { + String fname = req.getParams().get("file", null); + + if (adminFile == null) { + log.error("File " + fname + " was not found."); + rsp.setException(new SolrException(ErrorCode.BAD_REQUEST, "File " + fname + " was not found.")); + return; + } + log.error("File " + fname + " is a directory."); + rsp.setException(new SolrException(ErrorCode.BAD_REQUEST, "File " + fname + " is a directory.")); + return; + } + if (OP_TEST.equals(req.getParams().get(OP_PARAM))) { + testReloadSuccess(req, rsp); + return; + } + + FileUtils.copyInputStreamToFile(stream.getStream(), adminFile); + log.info("Successfully saved file " + adminFile.getAbsolutePath() + " locally"); + } + + private boolean testReloadSuccess(SolrQueryRequest req, SolrQueryResponse rsp) { + // Try writing the config to a temporary core and reloading to see that we don't allow people to shoot themselves + // in the foot. + File home = null; + try { + home = new File(FileUtils.getTempDirectory(), "SOLR_5459"); // Unlikely to name a core or collection this! + FileUtils.writeStringToFile(new File(home, "solr.xml"), "", "UTF-8"); // Use auto-discovery + File coll = new File(home, "SOLR_5459"); + + SolrCore core = req.getCore(); + CoreDescriptor desc = core.getCoreDescriptor(); + CoreContainer coreContainer = desc.getCoreContainer(); + + if (coreContainer.isZooKeeperAware()) { + try { + String confPath = ((ZkSolrResourceLoader) core.getResourceLoader()).getCollectionZkPath(); + + ZkController.downloadConfigDir(coreContainer.getZkController().getZkClient(), confPath, + new File(coll, "conf")); + } catch (Exception ex) { + log.error("Error when attempting to download conf from ZooKeeper: " + ex.getMessage()); + rsp.setException(new SolrException(ErrorCode.BAD_REQUEST, + "Error when attempting to download conf from ZooKeeper" + ex.getMessage())); + return false; + } + } else { + FileUtils.copyDirectory(new File(desc.getInstanceDir(), "conf"), + new File(coll, "conf")); + } + + FileUtils.writeStringToFile(new File(coll, "core.properties"), "name=SOLR_5459", "UTF-8"); + + FileUtils.writeByteArrayToFile(new File(new File(coll, "conf"), req.getParams().get("file", null)), data); + + return tryReloading(rsp, home); + + } catch (IOException ex) { + log.warn("Caught IO exception when trying to verify configs. " + ex.getMessage()); + rsp.setException(new SolrException(ErrorCode.SERVER_ERROR, + "Caught IO exception when trying to verify configs. " + ex.getMessage())); + return false; + } finally { + if (home != null) { + try { + FileUtils.deleteDirectory(home); + } catch (IOException e) { + log.warn("Caught IO exception trying to delete temporary directory " + home + e.getMessage()); + return true; // Don't fail for this reason! + } + } + } + } + + private boolean tryReloading(SolrQueryResponse rsp, File home) { + CoreContainer cc = null; + try { + cc = CoreContainer.createAndLoad(home.getAbsolutePath(), new File(home, "solr.xml")); + if (cc.getCoreInitFailures().size() > 0) { + for (Exception ex : cc.getCoreInitFailures().values()) { + log.error("Error when attempting to reload core: " + ex.getMessage()); + rsp.setException(new SolrException(ErrorCode.BAD_REQUEST, + "Error when attempting to reload core after writing config" + ex.getMessage())); + } + return false; + } + return true; + } finally { + if (cc != null) { + cc.shutdown(); + } + } + } + + //////////////////////// SolrInfoMBeans methods ////////////////////// + + @Override + public String getDescription() { + return "Admin Config File -- update config files directly"; + } + + @Override + public String getSource() { + return "$URL: https://svn.apache.org/repos/asf/lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/admin/ShowFileRequestHandler.java $"; + } +} diff --git a/solr/core/src/java/org/apache/solr/handler/admin/ShowFileRequestHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/ShowFileRequestHandler.java index 743deb5b917..d8314258be2 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/ShowFileRequestHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/ShowFileRequestHandler.java @@ -17,21 +17,17 @@ package org.apache.solr.handler.admin; -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; -import org.apache.solr.cloud.ZkController; import org.apache.solr.cloud.ZkSolrResourceLoader; import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrException.ErrorCode; import org.apache.solr.common.cloud.SolrZkClient; import org.apache.solr.common.params.CommonParams; import org.apache.solr.common.params.ModifiableSolrParams; -import org.apache.solr.common.util.ContentStream; +import org.apache.solr.common.params.SolrParams; import org.apache.solr.common.util.ContentStreamBase; import org.apache.solr.common.util.NamedList; import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.core.CoreContainer; -import org.apache.solr.core.CoreDescriptor; import org.apache.solr.core.SolrCore; import org.apache.solr.core.SolrResourceLoader; import org.apache.solr.handler.RequestHandlerBase; @@ -46,12 +42,10 @@ import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; -import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.URISyntaxException; import java.util.Date; import java.util.HashSet; -import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Set; @@ -94,47 +88,17 @@ import java.util.Set; * * * @since solr 1.3 - * - * - * As of Solr 4.7, you can use this handler to modify any files in the conf directory, e.g. solrconfig.xml - * or schema.xml, or even in sub-directories (e.g. velocity/error.vm) by POSTing a file. Here's an example cURL command - *
    - *   curl -X POST --form "fileupload=@schema.new" 'http://localhost:8983/solr/collection1/admin/file?op=write&file=schema.xml'
    - * 
    - * - * or - *
    - * curl -X POST --form "fileupload=@error.new" 'http://localhost:8983/solr/collection1/admin/file?op=write&file=velocity/error.vm'
    - * 
    - * - * For the first iteration, this is probably going to be used from the Solr admin screen. - * - * NOTE: Specifying a directory or simply leaving the any "file=XXX" parameters will list the contents of a directory. - * - * NOTE: You must reload the core/collection for any changes made via this handler to take effect! - * - * NOTE: If the core does not load (say schema.xml is not well formed for instance) you may be unable to replace - * the files with this interface. - * - * Configuration files in ZooKeeper are supported. - * - * Writing files out, @since solr 4.7 */ public class ShowFileRequestHandler extends RequestHandlerBase { + public static final String HIDDEN = "hidden"; + public static final String USE_CONTENT_TYPE = "contentType"; + + protected Set hiddenFiles; protected static final Logger log = LoggerFactory .getLogger(ShowFileRequestHandler.class); - public static final String HIDDEN = "hidden"; - public static final String USE_CONTENT_TYPE = "contentType"; - - protected Set hiddenFiles; - - private final static String OP_PARAM = "op"; - private final static String OP_WRITE = "write"; - private final static String OP_TEST = "test"; - public ShowFileRequestHandler() { @@ -144,161 +108,33 @@ public class ShowFileRequestHandler extends RequestHandlerBase @Override public void init(NamedList args) { super.init( args ); + hiddenFiles = initHidden(invariants); + } + public static Set initHidden(SolrParams invariants) { + + Set hiddenRet = new HashSet(); // Build a list of hidden files - hiddenFiles = new HashSet(); - if( invariants != null ) { - String[] hidden = invariants.getParams( HIDDEN ); - if( hidden != null ) { - for( String s : hidden ) { - hiddenFiles.add( s.toUpperCase(Locale.ROOT) ); + if (invariants != null) { + String[] hidden = invariants.getParams(HIDDEN); + if (hidden != null) { + for (String s : hidden) { + hiddenRet.add(s.toUpperCase(Locale.ROOT)); } } } + return hiddenRet; } - - public Set getHiddenFiles() - { - return hiddenFiles; - } - + @Override public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws InterruptedException, KeeperException, IOException { CoreContainer coreContainer = req.getCore().getCoreDescriptor().getCoreContainer(); - String op = req.getParams().get(OP_PARAM); - if (op == null) { - if (coreContainer.isZooKeeperAware()) { - showFromZooKeeper(req, rsp, coreContainer); - } else { - showFromFileSystem(req, rsp); - } - } else if (OP_WRITE.equalsIgnoreCase(op) || OP_TEST.equalsIgnoreCase(op)) { - String fname = req.getParams().get("file", null); - if (fname == null) { - rsp.setException(new SolrException(ErrorCode.BAD_REQUEST, "No file name specified for write operation.")); - } else { - fname = fname.replace('\\', '/'); - if (isHiddenFile(req, rsp, fname, true) == false) { - if (coreContainer.isZooKeeperAware()) { - writeToZooKeeper(req, rsp); - } else { - writeToFileSystem(req, rsp); - } - } - } - } - } - - // See if we should deal with this file - - private boolean isHiddenFile(SolrQueryRequest req, SolrQueryResponse rsp, String fnameIn, boolean reportError) { - String fname = fnameIn.toUpperCase(Locale.ROOT); - if (hiddenFiles.contains(fname) || hiddenFiles.contains("*")) { - if (reportError) { - log.error("Cannot access " + fname); - rsp.setException(new SolrException(ErrorCode.FORBIDDEN, "Can not access: " + fnameIn)); - } - return true; - } - - // This is slightly off, a valid path is something like ./schema.xml. I don't think it's worth the effort though - // to fix it to handle all possibilities though. - if (fname.indexOf("..") >= 0 || fname.startsWith(".")) { - if (reportError) { - log.error("Invalid path: " + fname); - rsp.setException(new SolrException(ErrorCode.FORBIDDEN, "Invalid path: " + fnameIn)); - } - return true; - } - - // Make sure that if the schema is managed, we don't allow editing. Don't really want to put - // this in the init since we're not entirely sure when the managed schema will get initialized relative to this - // handler. - SolrCore core = req.getCore(); - IndexSchema schema = core.getLatestSchema(); - if (schema instanceof ManagedIndexSchema) { - String managed = schema.getResourceName(); - - if (fname.equalsIgnoreCase(managed)) { - return true; - } - } - return false; - } - - // Refactored to be usable from multiple methods. Gets the path of the requested file from ZK. - // Returns null if the file is not found. - // - // Assumes that the file is in a parameter called "file". - - private String getAdminFileFromZooKeeper(SolrQueryRequest req, SolrQueryResponse rsp, SolrZkClient zkClient) - throws KeeperException, InterruptedException { - String adminFile = null; - SolrCore core = req.getCore(); - - final ZkSolrResourceLoader loader = (ZkSolrResourceLoader) core - .getResourceLoader(); - String confPath = loader.getCollectionZkPath(); - - String fname = req.getParams().get("file", null); - if (fname == null) { - adminFile = confPath; + if (coreContainer.isZooKeeperAware()) { + showFromZooKeeper(req, rsp, coreContainer); } else { - fname = fname.replace('\\', '/'); // normalize slashes - if (isHiddenFile(req, rsp, fname, true)) { - return null; - } - if (fname.startsWith("/")) { // Only files relative to conf are valid - fname = fname.substring(1); - } - adminFile = confPath + "/" + fname; - } - - // Make sure the file exists, is readable and is not a hidden file - if (!zkClient.exists(adminFile, true)) { - log.error("Can not find: " + adminFile); - rsp.setException(new SolrException(ErrorCode.NOT_FOUND, "Can not find: " - + adminFile)); - return null; - } - - return adminFile; - } - - // write the file contained in the parameter "file=XXX" to ZooKeeper. The file may be a path, e.g. - // file=velocity/error.vm or file=schema.xml - // - // Important: Assumes that the file already exists in ZK, so far we aren't creating files there. - private void writeToZooKeeper(SolrQueryRequest req, SolrQueryResponse rsp) - throws KeeperException, InterruptedException, IOException { - - CoreContainer coreContainer = req.getCore().getCoreDescriptor().getCoreContainer(); - SolrZkClient zkClient = coreContainer.getZkController().getZkClient(); - - String adminFile = getAdminFileFromZooKeeper(req, rsp, zkClient); - ContentStream stream = getOneInputStream(req, rsp); - if (stream == null) { - return; // Error already in rsp. - } - - byte[] data = IOUtils.toByteArray(new InputStreamReader(stream.getStream(), "UTF-8"), "UTF-8"); - String fname = req.getParams().get("file", null); - if (OP_TEST.equals(req.getParams().get(OP_PARAM))) { - testReloadSuccess(req, rsp, stream); - return; - } - // Persist the managed schema - try { - // Assumption: the path exists - zkClient.setData(adminFile, data, true); - log.info("Saved " + fname + " to ZooKeeper successfully."); - } catch (KeeperException.BadVersionException e) { - log.error("Cannot save file: " + fname + " to Zookeeper, " + - "ZooKeeper error: " + e.getMessage()); - rsp.setException(new SolrException(ErrorCode.SERVER_ERROR, "Cannot save file: " + fname + " to Zookeeper, " + - "ZooKeeper error: " + e.getMessage())); + showFromFileSystem(req, rsp); } } @@ -309,7 +145,7 @@ public class ShowFileRequestHandler extends RequestHandlerBase SolrZkClient zkClient = coreContainer.getZkController().getZkClient(); - String adminFile = getAdminFileFromZooKeeper(req, rsp, zkClient); + String adminFile = getAdminFileFromZooKeeper(req, rsp, zkClient, hiddenFiles); if (adminFile == null) { return; @@ -321,7 +157,7 @@ public class ShowFileRequestHandler extends RequestHandlerBase NamedList> files = new SimpleOrderedMap>(); for (String f : children) { - if (isHiddenFile(req, rsp, f, false)) { + if (isHiddenFile(req, rsp, f, false, hiddenFiles)) { continue; } @@ -352,185 +188,9 @@ public class ShowFileRequestHandler extends RequestHandlerBase rsp.setHttpCaching(false); } - - // Used when POSTing the configuration files to Solr (either ZooKeeper or locally). - // - // It takes some effort to insure that there is one (and only one) stream provided, there's no provision for - // more than one stream at present. - private ContentStream getOneInputStream(SolrQueryRequest req, SolrQueryResponse rsp) { - String file = req.getParams().get("file"); - if (file == null) { - log.error("You must specify a file for the write operation."); - rsp.setException(new SolrException(ErrorCode.BAD_REQUEST, "You must specify a file for the write operation.")); - return null; - } - - // Now, this is truly clumsy - Iterable streams = req.getContentStreams(); - if (streams == null) { - log.error("Input stream list was null for admin file write operation."); - rsp.setException(new SolrException(ErrorCode.BAD_REQUEST, "Input stream list was null for admin file write operation.")); - return null; - } - Iterator iter = streams.iterator(); - if (!iter.hasNext()) { - log.error("No input streams were in the list for admin file write operation."); - rsp.setException(new SolrException(ErrorCode.BAD_REQUEST, "No input streams were in the list for admin file write operation.")); - return null; - } - ContentStream stream = iter.next(); - if (iter.hasNext()) { - log.error("More than one input stream was found for admin file write operation."); - rsp.setException(new SolrException(ErrorCode.BAD_REQUEST, "More than one input stream was found for admin file write operation.")); - return null; - } - return stream; - } - - - // Write the data passed in from the stream to the file indicated by the file=XXX parameter on the local file system - private void writeToFileSystem(SolrQueryRequest req, SolrQueryResponse rsp) throws IOException { - ContentStream stream = getOneInputStream(req, rsp); - if (stream == null) { - return; // Error should already have been logged. - } - - File adminFile = getAdminFileFromFileSystem(req, rsp); - if (adminFile == null || adminFile.isDirectory()) { - String fname = req.getParams().get("file", null); - - if (adminFile == null) { - log.error("File " + fname + " was not found."); - rsp.setException(new SolrException( ErrorCode.BAD_REQUEST, "File " + fname + " was not found.")); - return; - } - log.error("File " + fname + " is a directory."); - rsp.setException(new SolrException( ErrorCode.BAD_REQUEST, "File " + fname + " is a directory.")); - return; - } - if (OP_TEST.equals(req.getParams().get(OP_PARAM))) { - testReloadSuccess(req, rsp, stream); - return; - } - - FileUtils.copyInputStreamToFile(stream.getStream(), adminFile); - log.info("Successfully saved file " + adminFile.getAbsolutePath() + " locally"); - } - - private boolean testReloadSuccess(SolrQueryRequest req, SolrQueryResponse rsp, ContentStream stream) { - // Try writing the config to a temporary core and reloading to see that we don't allow people to shoot themselves - // in the foot. - File home = null; - try { - home = new File(FileUtils.getTempDirectory(), "SOLR_5459"); // Unlikely to name a core or collection this! - FileUtils.writeStringToFile(new File(home, "solr.xml"), "", "UTF-8"); // Use auto-discovery - File coll = new File(home, "SOLR_5459"); - - SolrCore core = req.getCore(); - CoreDescriptor desc = core.getCoreDescriptor(); - CoreContainer coreContainer = desc.getCoreContainer(); - - if (coreContainer.isZooKeeperAware()) { - try { - String confPath = ((ZkSolrResourceLoader) core.getResourceLoader()).getCollectionZkPath(); - - ZkController.downloadConfigDir(coreContainer.getZkController().getZkClient(), confPath, - new File(coll, "conf")); - } catch (Exception ex) { - log.error("Error when attempting to download conf from ZooKeeper: " + ex.getMessage()); - rsp.setException(new SolrException(ErrorCode.BAD_REQUEST, - "Error when attempting to download conf from ZooKeeper" + ex.getMessage())); - return false; - } - } else { - FileUtils.copyDirectory(new File(desc.getInstanceDir(), "conf"), - new File(coll, "conf")); - } - - FileUtils.writeStringToFile(new File(coll, "core.properties"), "name=SOLR_5459", "UTF-8"); - - FileUtils.copyInputStreamToFile(stream.getStream(), - new File(new File(coll, "conf"), req.getParams().get("file", null))); - - return tryReloading(rsp, home); - - } catch (IOException ex) { - log.warn("Caught IO exception when trying to verify configs. " + ex.getMessage()); - rsp.setException(new SolrException(ErrorCode.SERVER_ERROR, - "Caught IO exception when trying to verify configs. " + ex.getMessage())); - return false; - } finally { - if (home != null) { - try { - FileUtils.deleteDirectory(home); - } catch (IOException e) { - log.warn("Caught IO exception trying to delete temporary directory " + home + e.getMessage()); - return true; // Don't fail for this reason! - } - } - } - } - - private boolean tryReloading(SolrQueryResponse rsp, File home) { - CoreContainer cc = null; - try { - cc = CoreContainer.createAndLoad(home.getAbsolutePath(), new File(home, "solr.xml")); - if (cc.getCoreInitFailures().size() > 0) { - for (Exception ex : cc.getCoreInitFailures().values()) { - log.error("Error when attempting to reload core: " + ex.getMessage()); - rsp.setException(new SolrException( ErrorCode.BAD_REQUEST, - "Error when attempting to reload core after writing config" + ex.getMessage())); - } - return false; - } - return true; - } finally { - if (cc != null) { - cc.shutdown(); - } - } - } - - // Find the file indicated by the "file=XXX" parameter or the root of the conf directory on the local - // file system. Respects all the "interesting" stuff around what the resource loader does to find files. - private File getAdminFileFromFileSystem(SolrQueryRequest req, SolrQueryResponse rsp) { - File adminFile = null; - final SolrResourceLoader loader = req.getCore().getResourceLoader(); - File configdir = new File( loader.getConfigDir() ); - if (!configdir.exists()) { - // TODO: maybe we should just open it this way to start with? - try { - configdir = new File( loader.getClassLoader().getResource(loader.getConfigDir()).toURI() ); - } catch (URISyntaxException e) { - log.error("Can not access configuration directory!"); - rsp.setException(new SolrException( ErrorCode.FORBIDDEN, "Can not access configuration directory!", e)); - return null; - } - } - String fname = req.getParams().get("file", null); - if( fname == null ) { - adminFile = configdir; - } - else { - fname = fname.replace( '\\', '/' ); // normalize slashes - if( hiddenFiles.contains( fname.toUpperCase(Locale.ROOT) ) ) { - log.error("Can not access: "+ fname); - rsp.setException(new SolrException( ErrorCode.FORBIDDEN, "Can not access: "+fname )); - return null; - } - if( fname.indexOf( ".." ) >= 0 ) { - log.error("Invalid path: "+ fname); - rsp.setException(new SolrException( ErrorCode.FORBIDDEN, "Invalid path: "+fname )); - return null; - } - adminFile = new File( configdir, fname ); - } - return adminFile; - } - // Return the file indicated (or the directory listing) from the local file system. private void showFromFileSystem(SolrQueryRequest req, SolrQueryResponse rsp) { - File adminFile = getAdminFileFromFileSystem(req, rsp); + File adminFile = getAdminFileFromFileSystem(req, rsp, hiddenFiles); if (adminFile == null) { // exception already recorded return; @@ -561,7 +221,7 @@ public class ShowFileRequestHandler extends RequestHandlerBase String path = f.getAbsolutePath().substring( basePath ); path = path.replace( '\\', '/' ); // normalize slashes - if (isHiddenFile(req, rsp, f.getName().replace('\\', '/'), false)) { + if (isHiddenFile(req, rsp, f.getName().replace('\\', '/'), false, hiddenFiles)) { continue; } @@ -593,6 +253,127 @@ public class ShowFileRequestHandler extends RequestHandlerBase rsp.setHttpCaching(false); } + //////////////////////// Static methods ////////////////////////////// + + public static boolean isHiddenFile(SolrQueryRequest req, SolrQueryResponse rsp, String fnameIn, boolean reportError, + Set hiddenFiles) { + String fname = fnameIn.toUpperCase(Locale.ROOT); + if (hiddenFiles.contains(fname) || hiddenFiles.contains("*")) { + if (reportError) { + log.error("Cannot access " + fname); + rsp.setException(new SolrException(SolrException.ErrorCode.FORBIDDEN, "Can not access: " + fnameIn)); + } + return true; + } + + // This is slightly off, a valid path is something like ./schema.xml. I don't think it's worth the effort though + // to fix it to handle all possibilities though. + if (fname.indexOf("..") >= 0 || fname.startsWith(".")) { + if (reportError) { + log.error("Invalid path: " + fname); + rsp.setException(new SolrException(SolrException.ErrorCode.FORBIDDEN, "Invalid path: " + fnameIn)); + } + return true; + } + + // Make sure that if the schema is managed, we don't allow editing. Don't really want to put + // this in the init since we're not entirely sure when the managed schema will get initialized relative to this + // handler. + SolrCore core = req.getCore(); + IndexSchema schema = core.getLatestSchema(); + if (schema instanceof ManagedIndexSchema) { + String managed = schema.getResourceName(); + + if (fname.equalsIgnoreCase(managed)) { + return true; + } + } + return false; + } + + // Refactored to be usable from multiple methods. Gets the path of the requested file from ZK. + // Returns null if the file is not found. + // + // Assumes that the file is in a parameter called "file". + + public static String getAdminFileFromZooKeeper(SolrQueryRequest req, SolrQueryResponse rsp, SolrZkClient zkClient, + Set hiddenFiles) + throws KeeperException, InterruptedException { + String adminFile = null; + SolrCore core = req.getCore(); + + final ZkSolrResourceLoader loader = (ZkSolrResourceLoader) core + .getResourceLoader(); + String confPath = loader.getCollectionZkPath(); + + String fname = req.getParams().get("file", null); + if (fname == null) { + adminFile = confPath; + } else { + fname = fname.replace('\\', '/'); // normalize slashes + if (isHiddenFile(req, rsp, fname, true, hiddenFiles)) { + return null; + } + if (fname.startsWith("/")) { // Only files relative to conf are valid + fname = fname.substring(1); + } + adminFile = confPath + "/" + fname; + } + + // Make sure the file exists, is readable and is not a hidden file + if (!zkClient.exists(adminFile, true)) { + log.error("Can not find: " + adminFile); + rsp.setException(new SolrException(SolrException.ErrorCode.NOT_FOUND, "Can not find: " + + adminFile)); + return null; + } + + return adminFile; + } + + + // Find the file indicated by the "file=XXX" parameter or the root of the conf directory on the local + // file system. Respects all the "interesting" stuff around what the resource loader does to find files. + public static File getAdminFileFromFileSystem(SolrQueryRequest req, SolrQueryResponse rsp, + Set hiddenFiles) { + File adminFile = null; + final SolrResourceLoader loader = req.getCore().getResourceLoader(); + File configdir = new File( loader.getConfigDir() ); + if (!configdir.exists()) { + // TODO: maybe we should just open it this way to start with? + try { + configdir = new File( loader.getClassLoader().getResource(loader.getConfigDir()).toURI() ); + } catch (URISyntaxException e) { + log.error("Can not access configuration directory!"); + rsp.setException(new SolrException( SolrException.ErrorCode.FORBIDDEN, "Can not access configuration directory!", e)); + return null; + } + } + String fname = req.getParams().get("file", null); + if( fname == null ) { + adminFile = configdir; + } + else { + fname = fname.replace( '\\', '/' ); // normalize slashes + if( hiddenFiles.contains( fname.toUpperCase(Locale.ROOT) ) ) { + log.error("Can not access: "+ fname); + rsp.setException(new SolrException( SolrException.ErrorCode.FORBIDDEN, "Can not access: "+fname )); + return null; + } + if( fname.indexOf( ".." ) >= 0 ) { + log.error("Invalid path: "+ fname); + rsp.setException(new SolrException( SolrException.ErrorCode.FORBIDDEN, "Invalid path: "+fname )); + return null; + } + adminFile = new File( configdir, fname ); + } + return adminFile; + } + + public final Set getHiddenFiles() { + return hiddenFiles; + } + //////////////////////// SolrInfoMBeans methods ////////////////////// @Override diff --git a/solr/core/src/test-files/solr/collection1/conf/solrconfig-tlog.xml b/solr/core/src/test-files/solr/collection1/conf/solrconfig-tlog.xml index d4a36cd3923..22c5b3ff57b 100644 --- a/solr/core/src/test-files/solr/collection1/conf/solrconfig-tlog.xml +++ b/solr/core/src/test-files/solr/collection1/conf/solrconfig-tlog.xml @@ -92,6 +92,11 @@ + + + bogus.txt + + diff --git a/solr/core/src/test-files/solr/collection1/conf/solrconfig.xml b/solr/core/src/test-files/solr/collection1/conf/solrconfig.xml index e38e1d6a01f..d2413b09654 100644 --- a/solr/core/src/test-files/solr/collection1/conf/solrconfig.xml +++ b/solr/core/src/test-files/solr/collection1/conf/solrconfig.xml @@ -240,6 +240,12 @@ + + + bogus.txt + + + diff --git a/solr/core/src/test/org/apache/solr/cloud/TestModifyConfFiles.java b/solr/core/src/test/org/apache/solr/cloud/TestModifyConfFiles.java index aa36cde2fd7..d92e3e87c04 100644 --- a/solr/core/src/test/org/apache/solr/cloud/TestModifyConfFiles.java +++ b/solr/core/src/test/org/apache/solr/cloud/TestModifyConfFiles.java @@ -16,6 +16,8 @@ package org.apache.solr.cloud; * limitations under the License. */ +import org.apache.commons.io.FileUtils; +import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.client.solrj.impl.HttpSolrServer; import org.apache.solr.client.solrj.request.QueryRequest; import org.apache.solr.common.cloud.SolrZkClient; @@ -23,6 +25,8 @@ import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.util.NamedList; import org.apache.solr.common.util.SimpleOrderedMap; +import java.io.File; + public class TestModifyConfFiles extends AbstractFullDistribZkTestBase { public TestModifyConfFiles() { @@ -38,7 +42,7 @@ public class TestModifyConfFiles extends AbstractFullDistribZkTestBase { params.set("op", "write"); params.set("file", "schema.xml"); QueryRequest request = new QueryRequest(params); - request.setPath("/admin/file"); + request.setPath("/admin/fileedit"); try { client.request(request); fail("Should have caught exception"); @@ -50,7 +54,7 @@ public class TestModifyConfFiles extends AbstractFullDistribZkTestBase { params.set("stream.body", "Testing rewrite of schema.xml file."); params.set("op", "test"); request = new QueryRequest(params); - request.setPath("/admin/file"); + request.setPath("/admin/fileedit"); try { client.request(request); fail("Should have caught exception"); @@ -61,7 +65,7 @@ public class TestModifyConfFiles extends AbstractFullDistribZkTestBase { params.set("op", "write"); params.set("file", "bogus.txt"); request = new QueryRequest(params); - request.setPath("/admin/file"); + request.setPath("/admin/fileedit"); try { client.request(request); fail("Should have caught exception"); @@ -69,16 +73,29 @@ public class TestModifyConfFiles extends AbstractFullDistribZkTestBase { assertEquals(e.getMessage(), "Can not access: bogus.txt"); } + try { + params.set("file", "schema.xml"); + request = new QueryRequest(params); + request.setPath("/admin/fileedit"); + client.request(request); + fail("Should have caught exception since it's mal-formed XML"); + } catch (Exception e) { + assertTrue("Should have a sax parser exception here!", + e.getMessage().contains("Invalid XML file: org.xml.sax.SAXParseException")); + } + + String top = SolrTestCaseJ4.TEST_HOME() + "/collection1/conf"; + params.set("stream.body", FileUtils.readFileToString(new File(top, "schema-tiny.xml"), "UTF-8")); params.set("file", "schema.xml"); request = new QueryRequest(params); - request.setPath("/admin/file"); + request.setPath("/admin/fileedit"); client.request(request); SolrZkClient zkClient = cloudClient.getZkStateReader().getZkClient(); String contents = new String(zkClient.getData("/configs/conf1/schema.xml", null, null, true), "UTF-8"); - assertTrue("Schema contents should have changed!", "Testing rewrite of schema.xml file.".equals(contents)); + assertTrue("Schema contents should have changed!", contents.contains("")); // Create a velocity/whatever node. Put a bit of data in it. See if you can change it. zkClient.makePath("/configs/conf1/velocity/test.vm", false, true); @@ -86,7 +103,7 @@ public class TestModifyConfFiles extends AbstractFullDistribZkTestBase { params.set("stream.body", "Some bogus stuff for a test."); params.set("file", "velocity/test.vm"); request = new QueryRequest(params); - request.setPath("/admin/file"); + request.setPath("/admin/fileedit"); client.request(request); diff --git a/solr/core/src/test/org/apache/solr/schema/ModifyConfFileTest.java b/solr/core/src/test/org/apache/solr/schema/ModifyConfFileTest.java index c763190be19..7d04a4d12a7 100644 --- a/solr/core/src/test/org/apache/solr/schema/ModifyConfFileTest.java +++ b/solr/core/src/test/org/apache/solr/schema/ModifyConfFileTest.java @@ -21,6 +21,7 @@ import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule; import org.apache.commons.codec.Charsets; import org.apache.commons.io.FileUtils; import org.apache.solr.SolrTestCaseJ4; +import org.apache.solr.client.solrj.request.QueryRequest; import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.util.ContentStream; import org.apache.solr.common.util.ContentStreamBase; @@ -41,6 +42,7 @@ import java.util.ArrayList; public class ModifyConfFileTest extends SolrTestCaseJ4 { private File solrHomeDirectory = new File(TEMP_DIR, this.getClass().getName()); + @Rule public TestRule solrTestRules = RuleChain.outerRule(new SystemPropertiesRestoreRule()); @@ -69,26 +71,42 @@ public class ModifyConfFileTest extends SolrTestCaseJ4 { SolrCore core = cc.getCore("core1"); SolrQueryResponse rsp = new SolrQueryResponse(); - SolrRequestHandler handler = core.getRequestHandler("/admin/file"); + SolrRequestHandler handler = core.getRequestHandler("/admin/fileedit"); ModifiableSolrParams params = params("file","schema.xml", "op","write"); core.execute(handler, new LocalSolrQueryRequest(core, params), rsp); assertEquals(rsp.getException().getMessage(), "Input stream list was null for admin file write operation."); - params = params("op", "write", "stream.body", "Testing rewrite of schema.xml file."); + params = params("op", "write"); core.execute(handler, new LocalSolrQueryRequest(core, params), rsp); assertEquals(rsp.getException().getMessage(), "No file name specified for write operation."); + ArrayList streams = new ArrayList( 2 ); + streams.add(new ContentStreamBase.StringStream("Testing rewrite of schema.xml file." ) ); params = params("op", "write", "file", "bogus.txt"); - core.execute(handler, new LocalSolrQueryRequest(core, params), rsp); + LocalSolrQueryRequest locReq = new LocalSolrQueryRequest(core, params); + locReq.setContentStreams(streams); + core.execute(handler, locReq, rsp); assertEquals(rsp.getException().getMessage(), "Can not access: bogus.txt"); - ArrayList streams = new ArrayList( 2 ); - streams.add( new ContentStreamBase.StringStream( "Testing rewrite of schema.xml file." ) ); + String top = SolrTestCaseJ4.TEST_HOME() + "/collection1/conf"; + String badConf = FileUtils.readFileToString(new File(top, "solrconfig-minimal.xml"), "UTF-8").replace("", ""); + + params = params("op", "write", "file", "solrconfig.xml"); + locReq = new LocalSolrQueryRequest(core, params); + streams.clear(); + streams.add(new ContentStreamBase.StringStream(badConf)); + locReq.setContentStreams(streams); + core.execute(handler, locReq, rsp); + assertTrue("should have detected an error early!", + rsp.getException().getMessage().contains("\"dataDir\"")); + + assertTrue("should have detected an error early!", + rsp.getException().getMessage().contains("\"\"")); params = params("op", "test", "file", "schema.xml", "stream.body", "Testing rewrite of schema.xml file."); - LocalSolrQueryRequest locReq = new LocalSolrQueryRequest(core, params); + locReq = new LocalSolrQueryRequest(core, params); locReq.setContentStreams(streams); core.execute(handler, locReq, rsp); @@ -116,7 +134,8 @@ public class ModifyConfFileTest extends SolrTestCaseJ4 { streams.clear(); params = params(); locReq = new LocalSolrQueryRequest(core, params); - core.execute(handler, locReq, rsp); + + core.execute(core.getRequestHandler("/admin/file"), locReq, rsp); NamedList res = rsp.getValues(); diff --git a/solr/example/solr/collection1/conf/solrconfig.xml b/solr/example/solr/collection1/conf/solrconfig.xml index fa467336a97..c770599b7e2 100755 --- a/solr/example/solr/collection1/conf/solrconfig.xml +++ b/solr/example/solr/collection1/conf/solrconfig.xml @@ -1139,6 +1139,19 @@ --> + + From d1085391c1964924d47c54d89a6116896fe6f000 Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Tue, 3 Dec 2013 06:28:24 +0000 Subject: [PATCH 162/223] remove unused sha1s git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1547298 13f79535-47bb-0310-9956-ffa450edef68 --- solr/licenses/jackson-core-asl-1.7.4.jar.sha1 | 1 - solr/licenses/jackson-mapper-asl-1.7.4.jar.sha1 | 1 - solr/licenses/jersey-core-1.16.jar.sha1 | 1 - 3 files changed, 3 deletions(-) delete mode 100644 solr/licenses/jackson-core-asl-1.7.4.jar.sha1 delete mode 100644 solr/licenses/jackson-mapper-asl-1.7.4.jar.sha1 delete mode 100644 solr/licenses/jersey-core-1.16.jar.sha1 diff --git a/solr/licenses/jackson-core-asl-1.7.4.jar.sha1 b/solr/licenses/jackson-core-asl-1.7.4.jar.sha1 deleted file mode 100644 index 2d326ba7db9..00000000000 --- a/solr/licenses/jackson-core-asl-1.7.4.jar.sha1 +++ /dev/null @@ -1 +0,0 @@ -11bc06af8fb695664f042bede95143a1859160c5 diff --git a/solr/licenses/jackson-mapper-asl-1.7.4.jar.sha1 b/solr/licenses/jackson-mapper-asl-1.7.4.jar.sha1 deleted file mode 100644 index 44d635affc8..00000000000 --- a/solr/licenses/jackson-mapper-asl-1.7.4.jar.sha1 +++ /dev/null @@ -1 +0,0 @@ -4e0a4619f999f28cd599d8524a1bb0095ddaa2fb diff --git a/solr/licenses/jersey-core-1.16.jar.sha1 b/solr/licenses/jersey-core-1.16.jar.sha1 deleted file mode 100644 index 28e748dc38e..00000000000 --- a/solr/licenses/jersey-core-1.16.jar.sha1 +++ /dev/null @@ -1 +0,0 @@ -34e9e164039913283da97af8d806ed92a931d32b From ce46fecc2896cd91ed7bbc241bb759425cf7664f Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Tue, 3 Dec 2013 09:19:30 +0000 Subject: [PATCH 163/223] SOLR-5517: Return HTTP error on POST requests with no Content-Type git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1547322 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 3 +++ .../solr/handler/UpdateRequestHandler.java | 4 ++-- .../solr/handler/component/SearchHandler.java | 6 ++++++ .../apache/solr/servlet/SolrRequestParsers.java | 9 ++++++--- .../solr/request/TestRemoteStreaming.java | 11 ++++++++--- .../solr/servlet/SolrRequestParserTest.java | 17 +++++++++++++++++ .../org/apache/solr/common/SolrException.java | 1 + 7 files changed, 43 insertions(+), 8 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 5a5c1bca2ca..cf95edc9454 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -218,6 +218,9 @@ Other Changes * SOLR-5499: Log a warning if /get is not registered when using SolrCloud. (Daniel Collins via shalin) +* SOLR-5517: Return HTTP error on POST requests with no Content-Type. + (Ryan Ernst, Uwe Schindler) + ================== 4.6.0 ================== Versions of Major Components diff --git a/solr/core/src/java/org/apache/solr/handler/UpdateRequestHandler.java b/solr/core/src/java/org/apache/solr/handler/UpdateRequestHandler.java index 3d136ebb28d..aa46b2ef0b8 100644 --- a/solr/core/src/java/org/apache/solr/handler/UpdateRequestHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/UpdateRequestHandler.java @@ -75,7 +75,7 @@ public class UpdateRequestHandler extends ContentStreamHandlerBase { type = stream.getContentType(); } if( type == null ) { // Normal requests will not get here. - throw new SolrException(ErrorCode.BAD_REQUEST, "Missing ContentType"); + throw new SolrException(ErrorCode.UNSUPPORTED_MEDIA_TYPE, "Missing ContentType"); } int idx = type.indexOf(';'); if(idx>0) { @@ -83,7 +83,7 @@ public class UpdateRequestHandler extends ContentStreamHandlerBase { } ContentStreamLoader loader = loaders.get(type); if(loader==null) { - throw new SolrException(ErrorCode.BAD_REQUEST, "Unsupported ContentType: " + throw new SolrException(ErrorCode.UNSUPPORTED_MEDIA_TYPE, "Unsupported ContentType: " +type+ " Not in: "+loaders.keySet()); } if(loader.getDefaultWT()!=null) { diff --git a/solr/core/src/java/org/apache/solr/handler/component/SearchHandler.java b/solr/core/src/java/org/apache/solr/handler/component/SearchHandler.java index 2f49229ed10..05c766441ad 100644 --- a/solr/core/src/java/org/apache/solr/handler/component/SearchHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/component/SearchHandler.java @@ -22,9 +22,11 @@ import java.util.LinkedList; import java.util.List; import org.apache.solr.common.SolrException; +import org.apache.solr.common.SolrException.ErrorCode; import org.apache.solr.common.params.CommonParams; import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.params.ShardParams; +import org.apache.solr.common.util.ContentStream; import org.apache.solr.core.CloseHook; import org.apache.solr.core.PluginInfo; import org.apache.solr.core.SolrCore; @@ -165,6 +167,10 @@ public class SearchHandler extends RequestHandlerBase implements SolrCoreAware , { // int sleep = req.getParams().getInt("sleep",0); // if (sleep > 0) {log.error("SLEEPING for " + sleep); Thread.sleep(sleep);} + if (req.getContentStreams() != null && req.getContentStreams().iterator().hasNext()) { + throw new SolrException(ErrorCode.BAD_REQUEST, "Search requests cannot accept content streams"); + } + ResponseBuilder rb = new ResponseBuilder(req, rsp, components); if (rb.requestInfo != null) { rb.requestInfo.setResponseBuilder(rb); diff --git a/solr/core/src/java/org/apache/solr/servlet/SolrRequestParsers.java b/solr/core/src/java/org/apache/solr/servlet/SolrRequestParsers.java index 4e76eac2611..ccba0d65ed1 100644 --- a/solr/core/src/java/org/apache/solr/servlet/SolrRequestParsers.java +++ b/solr/core/src/java/org/apache/solr/servlet/SolrRequestParsers.java @@ -584,7 +584,7 @@ public class SolrRequestParsers if (!isFormData(req)) { throw new SolrException( ErrorCode.BAD_REQUEST, "Not application/x-www-form-urlencoded content: "+req.getContentType() ); } - + final Map map = new HashMap(); // also add possible URL parameters and include into the map (parsed using UTF-8): @@ -600,7 +600,7 @@ public class SolrRequestParsers throw new SolrException(ErrorCode.BAD_REQUEST, "application/x-www-form-urlencoded content length (" + totalLength + " bytes) exceeds upload limit of " + uploadLimitKB + " KB"); } - + // get query String from request body, using the charset given in content-type: final String cs = ContentStreamBase.getCharsetFromContentType(req.getContentType()); final Charset charset = (cs == null) ? IOUtils.CHARSET_UTF_8 : Charset.forName(cs); @@ -680,7 +680,10 @@ public class SolrRequestParsers if (ServletFileUpload.isMultipartContent(req)) { return multipart.parseParamsAndFillStreams(req, streams); } - return raw.parseParamsAndFillStreams(req, streams); + if (req.getContentType() != null) { + return raw.parseParamsAndFillStreams(req, streams); + } + throw new SolrException(ErrorCode.UNSUPPORTED_MEDIA_TYPE, "Must specify a Content-Type header with POST requests"); } throw new SolrException(ErrorCode.BAD_REQUEST, "Unsupported method: " + method + " for request " + req); } diff --git a/solr/core/src/test/org/apache/solr/request/TestRemoteStreaming.java b/solr/core/src/test/org/apache/solr/request/TestRemoteStreaming.java index c1f74ac13c7..1217ecefeeb 100644 --- a/solr/core/src/test/org/apache/solr/request/TestRemoteStreaming.java +++ b/solr/core/src/test/org/apache/solr/request/TestRemoteStreaming.java @@ -27,6 +27,7 @@ import org.apache.solr.client.solrj.request.QueryRequest; import org.apache.solr.client.solrj.response.QueryResponse; import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrInputDocument; +import org.apache.solr.common.SolrException.ErrorCode; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; @@ -103,14 +104,18 @@ public class TestRemoteStreaming extends SolrJettyTestBase { return null; } - /** Do a select query with the stream.url. Solr should NOT access that URL, and so the data should be there. */ + /** Do a select query with the stream.url. Solr should fail */ @Test public void testNoUrlAccess() throws Exception { SolrQuery query = new SolrQuery(); query.setQuery( "*:*" );//for anything query.add("stream.url",makeDeleteAllUrl()); - getSolrServer().query(query); - assertTrue(searchFindsIt());//still there + try { + getSolrServer().query(query); + fail(); + } catch (SolrException se) { + assertSame(ErrorCode.BAD_REQUEST, ErrorCode.getErrorCode(se.code())); + } } /** SOLR-3161 diff --git a/solr/core/src/test/org/apache/solr/servlet/SolrRequestParserTest.java b/solr/core/src/test/org/apache/solr/servlet/SolrRequestParserTest.java index 6017ab9368e..e569b510e1c 100644 --- a/solr/core/src/test/org/apache/solr/servlet/SolrRequestParserTest.java +++ b/solr/core/src/test/org/apache/solr/servlet/SolrRequestParserTest.java @@ -379,4 +379,21 @@ public class SolrRequestParserTest extends SolrTestCaseJ4 { assertEquals("10.0.0.1", ((HttpServletRequest)solrReq.getContext().get("httpRequest")).getHeaders("X-Forwarded-For").nextElement()); } + + public void testPostMissingContentType() throws Exception { + HttpServletRequest request = createMock(HttpServletRequest.class); + expect(request.getMethod()).andReturn("POST").anyTimes(); + expect(request.getContentType()).andReturn(null).anyTimes(); + expect(request.getQueryString()).andReturn(null).anyTimes(); + replay(request); + + SolrRequestParsers parsers = new SolrRequestParsers(h.getCore().getSolrConfig()); + try { + parsers.parse(h.getCore(), "/select", request); + fail("should throw SolrException"); + } catch (SolrException e) { + assertTrue(e.getMessage().startsWith("Must specify a Content-Type header with POST requests")); + assertEquals(415, e.code()); + } + } } diff --git a/solr/solrj/src/java/org/apache/solr/common/SolrException.java b/solr/solrj/src/java/org/apache/solr/common/SolrException.java index a89783ad405..3cd03e5d71d 100644 --- a/solr/solrj/src/java/org/apache/solr/common/SolrException.java +++ b/solr/solrj/src/java/org/apache/solr/common/SolrException.java @@ -42,6 +42,7 @@ public class SolrException extends RuntimeException { FORBIDDEN( 403 ), NOT_FOUND( 404 ), CONFLICT( 409 ), + UNSUPPORTED_MEDIA_TYPE( 415 ), SERVER_ERROR( 500 ), SERVICE_UNAVAILABLE( 503 ), UNKNOWN(0); From df14f55a40fbb0078646c35f6139d84fec8dc21d Mon Sep 17 00:00:00 2001 From: Noble Paul Date: Tue, 3 Dec 2013 09:29:24 +0000 Subject: [PATCH 164/223] SOLR-5519 git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1547324 13f79535-47bb-0310-9956-ffa450edef68 --- .../cloud/OverseerCollectionProcessor.java | 38 +++++++++++++++++-- .../OverseerCollectionProcessorTest.java | 10 +++++ 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java b/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java index b0ff86de6ef..1a74bf4772a 100644 --- a/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java +++ b/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java @@ -47,7 +47,6 @@ import org.apache.solr.common.params.CoreAdminParams; import org.apache.solr.common.params.CoreAdminParams.CoreAdminAction; import org.apache.solr.common.params.MapSolrParams; import org.apache.solr.common.params.ModifiableSolrParams; -import org.apache.solr.common.params.UpdateParams; import org.apache.solr.common.util.NamedList; import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.common.util.StrUtils; @@ -116,7 +115,8 @@ public class OverseerCollectionProcessor implements Runnable, ClosableThread { public static final Map COLL_PROPS = ZkNodeProps.makeMap( ROUTER, DocRouter.DEFAULT_NAME, REPLICATION_FACTOR, "1", - MAX_SHARDS_PER_NODE, "1"); + MAX_SHARDS_PER_NODE, "1", + "external",null ); // TODO: use from Overseer? @@ -1392,6 +1392,7 @@ public class OverseerCollectionProcessor implements Runnable, ClosableThread { + ". This requires " + requestedShardsToCreate + " shards to be created (higher than the allowed number)"); } + String configName = createConfNode(collectionName, message); Overseer.getInQueue(zkStateReader.getZkClient()).offer(ZkStateReader.toJSON(message)); @@ -1406,8 +1407,6 @@ public class OverseerCollectionProcessor implements Runnable, ClosableThread { if (!created) throw new SolrException(ErrorCode.SERVER_ERROR, "Could not fully createcollection: " + message.getStr("name")); - - String configName = message.getStr(COLL_CONF); log.info("going to create cores replicas shardNames {} , repFactor : {}", shardNames, repFactor); for (int i = 1; i <= shardNames.size(); i++) { String sliceName = shardNames.get(i-1); @@ -1462,6 +1461,37 @@ public class OverseerCollectionProcessor implements Runnable, ClosableThread { } } + private String createConfNode(String coll, ZkNodeProps message) throws KeeperException, InterruptedException { + String configName = message.getStr(OverseerCollectionProcessor.COLL_CONF); + if(configName == null){ + // if there is only one conf, use that + List configNames=null; + try { + configNames = zkStateReader.getZkClient().getChildren(ZkController.CONFIGS_ZKNODE, null, true); + if (configNames != null && configNames.size() == 1) { + configName = configNames.get(0); + // no config set named, but there is only 1 - use it + log.info("Only one config set found in zk - using it:" + configName); + } + } catch (KeeperException.NoNodeException e) { + + } + + } + + if(configName!= null){ + log.info("creating collections conf node {} ",ZkStateReader.COLLECTIONS_ZKNODE + "/" + coll); + zkStateReader.getZkClient().makePath(ZkStateReader.COLLECTIONS_ZKNODE + "/" + coll, + ZkStateReader.toJSON(ZkNodeProps.makeMap(ZkController.CONFIGNAME_PROP,configName)),true ); + + } else { + String msg = "Could not obtain config name"; + log.warn(msg); + } + return configName; + + } + private void collectionCmd(ClusterState clusterState, ZkNodeProps message, ModifiableSolrParams params, NamedList results, String stateMatcher) { log.info("Executing Collection Cmd : " + params); String collectionName = message.getStr("name"); diff --git a/solr/core/src/test/org/apache/solr/cloud/OverseerCollectionProcessorTest.java b/solr/core/src/test/org/apache/solr/cloud/OverseerCollectionProcessorTest.java index 6d1b30a7b3d..c23a2a1903c 100644 --- a/solr/core/src/test/org/apache/solr/cloud/OverseerCollectionProcessorTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/OverseerCollectionProcessorTest.java @@ -218,6 +218,16 @@ public class OverseerCollectionProcessorTest extends SolrTestCaseJ4 { }).anyTimes(); } + clusterStateMock.hasCollection(anyObject(String.class)); + expectLastCall().andAnswer(new IAnswer() { + @Override + public Boolean answer() throws Throwable { + String key = (String) getCurrentArguments()[0]; + return collectionsSet.contains(key); + } + } ).anyTimes(); + + clusterStateMock.getLiveNodes(); expectLastCall().andAnswer(new IAnswer() { @Override From 8dcabf03651e905793ac9576a6b4160bed631f7a Mon Sep 17 00:00:00 2001 From: Uwe Schindler Date: Tue, 3 Dec 2013 11:40:52 +0000 Subject: [PATCH 165/223] LUCENE-5355: Add support for -Dbootjdk to point to a separate JAVA_HOME that is used to generate javadocs; validate the -Dbootclasspath to point to a valid rt.jar git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1547346 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/common-build.xml | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/lucene/common-build.xml b/lucene/common-build.xml index 938813c536b..a5ad7e03a92 100644 --- a/lucene/common-build.xml +++ b/lucene/common-build.xml @@ -159,7 +159,6 @@ - @@ -169,6 +168,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 8c04dea24c6e470dc3193273d2b982592eea5ea8 Mon Sep 17 00:00:00 2001 From: Uwe Schindler Date: Tue, 3 Dec 2013 12:17:58 +0000 Subject: [PATCH 166/223] For now don't run javadocs-lint on Java 8, because https://bugs.openjdk.java.net/browse/JDK-8027977 is still not fixed git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1547364 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/common-build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lucene/common-build.xml b/lucene/common-build.xml index a5ad7e03a92..63df8074a47 100644 --- a/lucene/common-build.xml +++ b/lucene/common-build.xml @@ -336,7 +336,7 @@ - + From fcf3a107049944b92b5b28d809fd718a3efddd30 Mon Sep 17 00:00:00 2001 From: Shalin Shekhar Mangar Date: Tue, 3 Dec 2013 14:13:13 +0000 Subject: [PATCH 167/223] SOLR-5527: DIH logs spurious warning for special commands git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1547394 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 2 ++ .../solr/handler/dataimport/DocBuilder.java | 15 ++++++++++----- .../handler/dataimport/EntityProcessorBase.java | 3 --- .../handler/dataimport/XPathEntityProcessor.java | 2 +- .../dataimport/config/DIHConfiguration.java | 12 +++++++++++- .../solr/handler/dataimport/TestDocBuilder2.java | 12 ++++++------ 6 files changed, 30 insertions(+), 16 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index cf95edc9454..3250c726e60 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -187,6 +187,8 @@ Bug Fixes * SOLR-5204: StatsComponent and SpellCheckComponent do not support the shards.tolerant=true parameter. (Anca Kopetz, shalin) +* SOLR-5527: DIH logs spurious warning for special commands. (shalin) + Optimizations ---------------------- diff --git a/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/DocBuilder.java b/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/DocBuilder.java index d3e5230e866..dc33a31ea89 100644 --- a/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/DocBuilder.java +++ b/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/DocBuilder.java @@ -51,6 +51,11 @@ public class DocBuilder { private static final Logger LOG = LoggerFactory.getLogger(DocBuilder.class); private static final Date EPOCH = new Date(0); + public static final String DELETE_DOC_BY_ID = "$deleteDocById"; + public static final String DELETE_DOC_BY_QUERY = "$deleteDocByQuery"; + public static final String DOC_BOOST = "$docBoost"; + public static final String SKIP_DOC = "$skipDoc"; + public static final String SKIP_ROW = "$skipRow"; DataImporter dataImporter; @@ -568,7 +573,7 @@ public class DocBuilder { } private void handleSpecialCommands(Map arow, DocWrapper doc) { - Object value = arow.get("$deleteDocById"); + Object value = arow.get(DELETE_DOC_BY_ID); if (value != null) { if (value instanceof Collection) { Collection collection = (Collection) value; @@ -581,7 +586,7 @@ public class DocBuilder { importStatistics.deletedDocCount.incrementAndGet(); } } - value = arow.get("$deleteDocByQuery"); + value = arow.get(DELETE_DOC_BY_QUERY); if (value != null) { if (value instanceof Collection) { Collection collection = (Collection) value; @@ -594,7 +599,7 @@ public class DocBuilder { importStatistics.deletedDocCount.incrementAndGet(); } } - value = arow.get("$docBoost"); + value = arow.get(DOC_BOOST); if (value != null) { float value1 = 1.0f; if (value instanceof Number) { @@ -605,7 +610,7 @@ public class DocBuilder { doc.setDocumentBoost(value1); } - value = arow.get("$skipDoc"); + value = arow.get(SKIP_DOC); if (value != null) { if (Boolean.parseBoolean(value.toString())) { throw new DataImportHandlerException(DataImportHandlerException.SKIP, @@ -613,7 +618,7 @@ public class DocBuilder { } } - value = arow.get("$skipRow"); + value = arow.get(SKIP_ROW); if (value != null) { if (Boolean.parseBoolean(value.toString())) { throw new DataImportHandlerException(DataImportHandlerException.SKIP_ROW); diff --git a/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/EntityProcessorBase.java b/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/EntityProcessorBase.java index 1aa882e7281..7c9d03169e5 100644 --- a/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/EntityProcessorBase.java +++ b/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/EntityProcessorBase.java @@ -153,7 +153,4 @@ public class EntityProcessorBase extends EntityProcessor { public static final String CONTINUE = "continue"; public static final String SKIP = "skip"; - - public static final String SKIP_DOC = "$skipDoc"; - } diff --git a/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/XPathEntityProcessor.java b/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/XPathEntityProcessor.java index c18ae65375b..4819e75089c 100644 --- a/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/XPathEntityProcessor.java +++ b/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/XPathEntityProcessor.java @@ -330,7 +330,7 @@ public class XPathEntityProcessor extends EntityProcessorBase { } else if (SKIP.equals(onError)) { LOG.warn(msg, e); Map map = new HashMap(); - map.put(SKIP_DOC, Boolean.TRUE); + map.put(DocBuilder.SKIP_DOC, Boolean.TRUE); rows.add(map); } else if (CONTINUE.equals(onError)) { LOG.warn(msg, e); diff --git a/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/config/DIHConfiguration.java b/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/config/DIHConfiguration.java index 4b5b7510481..bf07e40f16b 100644 --- a/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/config/DIHConfiguration.java +++ b/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/config/DIHConfiguration.java @@ -8,6 +8,7 @@ import java.util.Locale; import java.util.Map; import org.apache.solr.handler.dataimport.DataImporter; +import org.apache.solr.handler.dataimport.DocBuilder; import org.apache.solr.schema.IndexSchema; import org.apache.solr.schema.SchemaField; import org.slf4j.Logger; @@ -111,7 +112,7 @@ public class DIHConfiguration { for (Map.Entry entry : fields.entrySet()) { EntityField fld = entry.getValue(); SchemaField field = getSchemaField(fld.getName()); - if (field == null) { + if (field == null && !isSpecialCommand(fld.getName())) { LOG.info("The field :" + fld.getName() + " present in DataConfig does not have a counterpart in Solr Schema"); } } @@ -178,4 +179,13 @@ public class DIHConfiguration { public IndexSchema getSchema() { return schema; } + + public static boolean isSpecialCommand(String fld) { + return DocBuilder.DELETE_DOC_BY_ID.equals(fld) || + DocBuilder.DELETE_DOC_BY_QUERY.equals(fld) || + DocBuilder.DOC_BOOST.equals(fld) || + DocBuilder.SKIP_DOC.equals(fld) || + DocBuilder.SKIP_ROW.equals(fld); + + } } \ No newline at end of file diff --git a/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestDocBuilder2.java b/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestDocBuilder2.java index 2ead5f2b90c..dbd38be1899 100644 --- a/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestDocBuilder2.java +++ b/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestDocBuilder2.java @@ -132,7 +132,7 @@ public class TestDocBuilder2 extends AbstractDataImportHandlerTestCase { public void testSkipDoc() throws Exception { List rows = new ArrayList(); rows.add(createMap("id", "1", "desc", "one")); - rows.add(createMap("id", "2", "desc", "two", "$skipDoc", "true")); + rows.add(createMap("id", "2", "desc", "two", DocBuilder.SKIP_DOC, "true")); MockDataSource.setIterator("select * from x", rows.iterator()); runFullImport(dataConfigWithDynamicTransformer); @@ -146,7 +146,7 @@ public class TestDocBuilder2 extends AbstractDataImportHandlerTestCase { public void testSkipRow() throws Exception { List rows = new ArrayList(); rows.add(createMap("id", "1", "desc", "one")); - rows.add(createMap("id", "2", "desc", "two", "$skipRow", "true")); + rows.add(createMap("id", "2", "desc", "two", DocBuilder.SKIP_ROW, "true")); MockDataSource.setIterator("select * from x", rows.iterator()); runFullImport(dataConfigWithDynamicTransformer); @@ -166,7 +166,7 @@ public class TestDocBuilder2 extends AbstractDataImportHandlerTestCase { MockDataSource.setIterator("3", rows.iterator()); rows = new ArrayList(); - rows.add(createMap("name_s", "xyz", "$skipRow", "true")); + rows.add(createMap("name_s", "xyz", DocBuilder.SKIP_ROW, "true")); MockDataSource.setIterator("4", rows.iterator()); runFullImport(dataConfigWithTwoEntities); @@ -197,7 +197,7 @@ public class TestDocBuilder2 extends AbstractDataImportHandlerTestCase { List rows = new ArrayList(); rows.add(createMap("id", "1", "desc", "one")); rows.add(createMap("id", "2", "desc", "two")); - rows.add(createMap("id", "3", "desc", "two", "$deleteDocById", "2")); + rows.add(createMap("id", "3", "desc", "two", DocBuilder.DELETE_DOC_BY_ID, "2")); MockDataSource.setIterator("select * from x", rows.iterator()); runFullImport(dataConfigForSkipTransform); @@ -213,7 +213,7 @@ public class TestDocBuilder2 extends AbstractDataImportHandlerTestCase { rows = new ArrayList(); rows.add(createMap("id", "1", "desc", "one")); rows.add(createMap("id", "2", "desc", "one")); - rows.add(createMap("id", "3", "desc", "two", "$deleteDocByQuery", "desc:one")); + rows.add(createMap("id", "3", "desc", "two", DocBuilder.DELETE_DOC_BY_QUERY, "desc:one")); MockDataSource.setIterator("select * from x", rows.iterator()); runFullImport(dataConfigForSkipTransform); @@ -227,7 +227,7 @@ public class TestDocBuilder2 extends AbstractDataImportHandlerTestCase { MockDataSource.clearCache(); rows = new ArrayList(); - rows.add(createMap("$deleteDocById", "3")); + rows.add(createMap(DocBuilder.DELETE_DOC_BY_ID, "3")); MockDataSource.setIterator("select * from x", rows.iterator()); runFullImport(dataConfigForSkipTransform, createMap("clean","false")); assertQ(req("id:3"), "//*[@numFound='0']"); From e8237d6a7a44814e05702d8c7af92746518a433f Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Tue, 3 Dec 2013 14:55:42 +0000 Subject: [PATCH 168/223] SOLR-5449: Add more stress testing around creating and removing collections. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1547415 13f79535-47bb-0310-9956-ffa450edef68 --- .../CollectionsAPIDistributedZkTest.java | 80 ++++++++++++++++++- 1 file changed, 77 insertions(+), 3 deletions(-) diff --git a/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIDistributedZkTest.java b/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIDistributedZkTest.java index a88bf0a90ff..5c8c498bc64 100644 --- a/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIDistributedZkTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIDistributedZkTest.java @@ -43,7 +43,6 @@ import javax.management.MBeanServer; import javax.management.MBeanServerFactory; import javax.management.ObjectName; -import org.apache.lucene.util.Constants; import org.apache.lucene.util.LuceneTestCase.Slow; import org.apache.lucene.util._TestUtil; import org.apache.solr.SolrTestCaseJ4; @@ -195,6 +194,7 @@ public class CollectionsAPIDistributedZkTest extends AbstractFullDistribZkTestBa testSolrJAPICalls(); testNodesUsedByCreate(); testCollectionsAPI(); + testCollectionsAPIAddRemoveStress(); testErrorHandling(); deletePartiallyCreatedCollection(); deleteCollectionRemovesStaleZkCollectionsNode(); @@ -612,11 +612,11 @@ public class CollectionsAPIDistributedZkTest extends AbstractFullDistribZkTestBa // create new collections rapid fire Map> collectionInfos = new HashMap>(); - int cnt = random().nextInt(6) + 1; + int cnt = random().nextInt(TEST_NIGHTLY ? 6 : 3) + 1; for (int i = 0; i < cnt; i++) { int numShards = _TestUtil.nextInt(random(), 0, shardCount) + 1; - int replicationFactor = _TestUtil.nextInt(random(), 0, 3) + 2; + int replicationFactor = _TestUtil.nextInt(random(), 0, 3) + 1; int maxShardsPerNode = (((numShards * replicationFactor) / getCommonCloudSolrServer() .getZkStateReader().getClusterState().getLiveNodes().size())) + 1; @@ -882,6 +882,80 @@ public class CollectionsAPIDistributedZkTest extends AbstractFullDistribZkTestBa checkNoTwoShardsUseTheSameIndexDir(); } + + private void testCollectionsAPIAddRemoveStress() throws Exception { + + class CollectionThread extends Thread { + + private String name; + + public CollectionThread(String name) { + this.name = name; + } + + public void run() { + // create new collections rapid fire + Map> collectionInfos = new HashMap>(); + int cnt = random().nextInt(TEST_NIGHTLY ? 13 : 3) + 1; + + for (int i = 0; i < cnt; i++) { + String collectionName = "awholynewstresscollection_" + name + "_" + i; + int numShards = _TestUtil.nextInt(random(), 0, shardCount * 2) + 1; + int replicationFactor = _TestUtil.nextInt(random(), 0, 3) + 1; + int maxShardsPerNode = (((numShards * 2 * replicationFactor) / getCommonCloudSolrServer() + .getZkStateReader().getClusterState().getLiveNodes().size())) + 1; + + CloudSolrServer client = null; + try { + if (i == 0) { + client = createCloudClient(null); + } else if (i == 1) { + client = createCloudClient(collectionName); + } + + createCollection(collectionInfos, collectionName, + numShards, replicationFactor, maxShardsPerNode, client, null, + "conf1"); + + // remove collection + ModifiableSolrParams params = new ModifiableSolrParams(); + params.set("action", CollectionAction.DELETE.toString()); + params.set("name", collectionName); + QueryRequest request = new QueryRequest(params); + request.setPath("/admin/collections"); + + if (client == null) { + client = createCloudClient(null); + } + + client.request(request); + + } catch (SolrServerException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } finally { + if (client != null) client.shutdown(); + } + } + } + } + List threads = new ArrayList(); + int numThreads = TEST_NIGHTLY ? 6 : 2; + for (int i = 0; i < numThreads; i++) { + CollectionThread thread = new CollectionThread("collection" + i); + threads.add(thread); + } + + for (Thread thread : threads) { + thread.start(); + } + for (Thread thread : threads) { + thread.join(); + } + } private void checkInstanceDirs(JettySolrRunner jetty) { CoreContainer cores = ((SolrDispatchFilter) jetty.getDispatchFilter() From dff3579da3e9b27c4478343286aeaa6a6a0da83b Mon Sep 17 00:00:00 2001 From: Steven Rowe Date: Tue, 3 Dec 2013 15:22:59 +0000 Subject: [PATCH 169/223] SOLR-5354: applying hoss's patch to fix function edge case in distributed sort git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1547430 13f79535-47bb-0310-9956-ffa450edef68 --- .../handler/component/QueryComponent.java | 63 +++++++++++++------ .../component/QueryElevationComponent.java | 47 ++++++++++---- .../solr/search/LuceneQParserPlugin.java | 6 +- .../java/org/apache/solr/search/QParser.java | 10 +-- .../org/apache/solr/search/QueryParsing.java | 52 ++++++++++----- .../java/org/apache/solr/search/SortSpec.java | 53 ++++++++++++++-- .../org/apache/solr/util/SolrPluginUtils.java | 4 +- .../collection1/conf/schema-custom-field.xml | 3 + ...stributedQueryComponentCustomSortTest.java | 8 ++- .../apache/solr/search/QueryParsingTest.java | 49 ++++++++++++++- .../test/org/apache/solr/search/TestSort.java | 11 +++- 11 files changed, 239 insertions(+), 67 deletions(-) diff --git a/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java b/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java index ca072e18dec..55ff8ad913f 100644 --- a/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java +++ b/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java @@ -190,7 +190,7 @@ public class QueryComponent extends SearchComponent // groupSort defaults to sort String groupSortStr = params.get(GroupParams.GROUP_SORT); //TODO: move weighting of sort - Sort sortWithinGroup = groupSortStr == null ? groupSort : searcher.weightSort(QueryParsing.parseSort(groupSortStr, req)); + Sort sortWithinGroup = groupSortStr == null ? groupSort : searcher.weightSort(QueryParsing.parseSortSpec(groupSortStr, req).getSort()); if (sortWithinGroup == null) { sortWithinGroup = Sort.RELEVANCE; } @@ -454,8 +454,6 @@ public class QueryComponent extends SearchComponent // take the documents given and re-derive the sort values. boolean fsv = req.getParams().getBool(ResponseBuilder.FIELD_SORT_VALUES,false); if(fsv){ - Sort sort = searcher.weightSort(rb.getSortSpec().getSort()); - SortField[] sortFields = sort==null ? new SortField[]{SortField.FIELD_SCORE} : sort.getSort(); NamedList sortVals = new NamedList(); // order is important for the sort fields IndexReaderContext topReaderContext = searcher.getTopReaderContext(); List leaves = topReaderContext.leaves(); @@ -477,18 +475,22 @@ public class QueryComponent extends SearchComponent } Arrays.sort(sortedIds); + SortSpec sortSpec = rb.getSortSpec(); + Sort sort = searcher.weightSort(sortSpec.getSort()); + SortField[] sortFields = sort==null ? new SortField[]{SortField.FIELD_SCORE} : sort.getSort(); + List schemaFields = sortSpec.getSchemaFields(); + + for (int fld = 0; fld < schemaFields.size(); fld++) { + SchemaField schemaField = schemaFields.get(fld); + FieldType ft = null == schemaField? null : schemaField.getType(); + SortField sortField = sortFields[fld]; - for (SortField sortField: sortFields) { SortField.Type type = sortField.getType(); + // :TODO: would be simpler to always serialize every position of SortField[] if (type==SortField.Type.SCORE || type==SortField.Type.DOC) continue; FieldComparator comparator = null; - - String fieldname = sortField.getField(); - FieldType ft = fieldname==null ? null : searcher.getSchema().getFieldTypeNoEx(fieldname); - Object[] vals = new Object[nDocs]; - int lastIdx = -1; int idx = 0; @@ -518,7 +520,7 @@ public class QueryComponent extends SearchComponent vals[position] = val; } - sortVals.add(fieldname, vals); + sortVals.add(sortField.getField(), vals); } rsp.add("sort_values", sortVals); @@ -865,7 +867,7 @@ public class QueryComponent extends SearchComponent } } - shardDoc.sortFieldValues = unmarshalSortValues(sortFieldValues, schema); + shardDoc.sortFieldValues = unmarshalSortValues(ss, sortFieldValues, schema); queue.insertWithOverflow(shardDoc); } // end for-each-doc-in-response @@ -907,22 +909,43 @@ public class QueryComponent extends SearchComponent } } - private NamedList unmarshalSortValues(NamedList sortFieldValues, IndexSchema schema) { + private NamedList unmarshalSortValues(SortSpec sortSpec, + NamedList sortFieldValues, + IndexSchema schema) { NamedList unmarshalledSortValsPerField = new NamedList(); - for (int fieldNum = 0 ; fieldNum < sortFieldValues.size() ; ++fieldNum) { - String fieldName = sortFieldValues.getName(fieldNum); - SchemaField field = schema.getFieldOrNull(fieldName); - List sortVals = (List)sortFieldValues.getVal(fieldNum); - if (null == field) { - unmarshalledSortValsPerField.add(fieldName, sortVals); + + if (0 == sortFieldValues.size()) return unmarshalledSortValsPerField; + + List schemaFields = sortSpec.getSchemaFields(); + SortField[] sortFields = sortSpec.getSort().getSort(); + + int marshalledFieldNum = 0; + for (int sortFieldNum = 0; sortFieldNum < sortFields.length; sortFieldNum++) { + final SortField sortField = sortFields[sortFieldNum]; + final SortField.Type type = sortField.getType(); + + // :TODO: would be simpler to always serialize every position of SortField[] + if (type==SortField.Type.SCORE || type==SortField.Type.DOC) continue; + + final String sortFieldName = sortField.getField(); + final String valueFieldName = sortFieldValues.getName(marshalledFieldNum); + assert sortFieldName.equals(valueFieldName) + : "sortFieldValues name key does not match expected SortField.getField"; + + List sortVals = (List)sortFieldValues.getVal(marshalledFieldNum); + + final SchemaField schemaField = schemaFields.get(sortFieldNum); + if (null == schemaField) { + unmarshalledSortValsPerField.add(sortField.getField(), sortVals); } else { - FieldType fieldType = field.getType(); + FieldType fieldType = schemaField.getType(); List unmarshalledSortVals = new ArrayList(); for (Object sortVal : sortVals) { unmarshalledSortVals.add(fieldType.unmarshalSortValue(sortVal)); } - unmarshalledSortValsPerField.add(fieldName, unmarshalledSortVals); + unmarshalledSortValsPerField.add(sortField.getField(), unmarshalledSortVals); } + marshalledFieldNum++; } return unmarshalledSortValsPerField; } diff --git a/solr/core/src/java/org/apache/solr/handler/component/QueryElevationComponent.java b/solr/core/src/java/org/apache/solr/handler/component/QueryElevationComponent.java index b0caa898c28..15ca4e695fa 100644 --- a/solr/core/src/java/org/apache/solr/handler/component/QueryElevationComponent.java +++ b/solr/core/src/java/org/apache/solr/handler/component/QueryElevationComponent.java @@ -419,16 +419,16 @@ public class QueryElevationComponent extends SearchComponent implements SolrCore // insert documents in their proper place SortSpec sortSpec = rb.getSortSpec(); if (sortSpec.getSort() == null) { - sortSpec.setSort(new Sort(new SortField[]{ - new SortField("_elevate_", comparator, true), - new SortField(null, SortField.Type.SCORE, false) - })); + sortSpec.setSortAndFields(new Sort(new SortField[]{ + new SortField("_elevate_", comparator, true), + new SortField(null, SortField.Type.SCORE, false) + }), + Arrays.asList(new SchemaField[2])); } else { // Check if the sort is based on score - SortField[] current = sortSpec.getSort().getSort(); - Sort modified = this.modifySort(current, force, comparator); - if(modified != null) { - sortSpec.setSort(modified); + SortSpec modSortSpec = this.modifySortSpec(sortSpec, force, comparator); + if (null != modSortSpec) { + rb.setSortSpec(modSortSpec); } } @@ -470,22 +470,43 @@ public class QueryElevationComponent extends SearchComponent implements SolrCore } private Sort modifySort(SortField[] current, boolean force, ElevationComparatorSource comparator) { + SortSpec tmp = new SortSpec(new Sort(current), Arrays.asList(new SchemaField[current.length])); + tmp = modifySortSpec(tmp, force, comparator); + return null == tmp ? null : tmp.getSort(); + } + + private SortSpec modifySortSpec(SortSpec current, boolean force, ElevationComparatorSource comparator) { boolean modify = false; - ArrayList sorts = new ArrayList(current.length + 1); + SortField[] currentSorts = current.getSort().getSort(); + List currentFields = current.getSchemaFields(); + + ArrayList sorts = new ArrayList(currentSorts.length + 1); + List fields = new ArrayList(currentFields.size() + 1); + // Perhaps force it to always sort by score - if (force && current[0].getType() != SortField.Type.SCORE) { + if (force && currentSorts[0].getType() != SortField.Type.SCORE) { sorts.add(new SortField("_elevate_", comparator, true)); + fields.add(null); modify = true; } - for (SortField sf : current) { + for (int i = 0; i < currentSorts.length; i++) { + SortField sf = currentSorts[i]; if (sf.getType() == SortField.Type.SCORE) { sorts.add(new SortField("_elevate_", comparator, !sf.getReverse())); + fields.add(null); modify = true; } sorts.add(sf); + fields.add(currentFields.get(i)); } - - return modify ? new Sort(sorts.toArray(new SortField[sorts.size()])) : null; + if (modify) { + SortSpec newSpec = new SortSpec(new Sort(sorts.toArray(new SortField[sorts.size()])), + fields); + newSpec.setOffset(current.getOffset()); + newSpec.setCount(current.getCount()); + return newSpec; + } + return null; } @Override diff --git a/solr/core/src/java/org/apache/solr/search/LuceneQParserPlugin.java b/solr/core/src/java/org/apache/solr/search/LuceneQParserPlugin.java index 00c4424b2f1..8ea19187328 100644 --- a/solr/core/src/java/org/apache/solr/search/LuceneQParserPlugin.java +++ b/solr/core/src/java/org/apache/solr/search/LuceneQParserPlugin.java @@ -86,9 +86,9 @@ class OldLuceneQParser extends LuceneQParser { public SortSpec getSort(boolean useGlobal) throws SyntaxError { SortSpec sort = super.getSort(useGlobal); if (sortStr != null && sortStr.length()>0 && sort.getSort()==null) { - Sort oldSort = QueryParsing.parseSort(sortStr, getReq()); - if( oldSort != null ) { - sort.sort = oldSort; + SortSpec oldSort = QueryParsing.parseSortSpec(sortStr, getReq()); + if( oldSort.getSort() != null ) { + sort.setSortAndFields(oldSort.getSort(), oldSort.getSchemaFields()); } } return sort; diff --git a/solr/core/src/java/org/apache/solr/search/QParser.java b/solr/core/src/java/org/apache/solr/search/QParser.java index 16db2d36b5f..e39d424bd9b 100644 --- a/solr/core/src/java/org/apache/solr/search/QParser.java +++ b/solr/core/src/java/org/apache/solr/search/QParser.java @@ -276,11 +276,11 @@ public abstract class QParser { int start = startS != null ? Integer.parseInt(startS) : 0; int rows = rowsS != null ? Integer.parseInt(rowsS) : 10; - Sort sort = null; - if( sortStr != null ) { - sort = QueryParsing.parseSort(sortStr, req); - } - return new SortSpec( sort, start, rows ); + SortSpec sort = QueryParsing.parseSortSpec(sortStr, req); + + sort.setOffset(start); + sort.setCount(rows); + return sort; } public String[] getDefaultHighlightFields() { diff --git a/solr/core/src/java/org/apache/solr/search/QueryParsing.java b/solr/core/src/java/org/apache/solr/search/QueryParsing.java index 1cdb4c4e3f7..75d5b527d06 100644 --- a/solr/core/src/java/org/apache/solr/search/QueryParsing.java +++ b/solr/core/src/java/org/apache/solr/search/QueryParsing.java @@ -43,6 +43,7 @@ import org.apache.solr.schema.FieldType; import org.apache.solr.schema.IndexSchema; import org.apache.solr.schema.SchemaField; import java.io.IOException; +import java.util.Collections; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -219,16 +220,24 @@ public class QueryParsing { return new MapSolrParams(localParams); } + /** + * Returns the Sort object represented by the string, or null if default sort + * by score descending should be used. + * @see #parseSortSpec + * @deprecated use {@link #parseSortSpec} + */ + @Deprecated + public static Sort parseSort(String sortSpec, SolrQueryRequest req) { + return parseSortSpec(sortSpec, req).getSort(); + } /** - * Returns null if the sortSpec is the standard sort desc. - *

    *

    * The form of the sort specification string currently parsed is: *

    *
        * SortSpec ::= SingleSort [, SingleSort]*
    -   * SingleSort ::= <fieldname> SortDirection
    +   * SingleSort ::= <fieldname|function> SortDirection
        * SortDirection ::= top | desc | bottom | asc
        * 
    * Examples: @@ -239,10 +248,15 @@ public class QueryParsing { * height desc,weight desc #sort by height descending, and use weight descending to break any ties * height desc,weight asc #sort by height descending, using weight ascending as a tiebreaker * + * @return a SortSpec object populated with the appropriate Sort (which may be null if + * default score sort is used) and SchemaFields (where applicable) using + * hardcoded default count & offset values. */ - public static Sort parseSort(String sortSpec, SolrQueryRequest req) { - if (sortSpec == null || sortSpec.length() == 0) return null; - List lst = new ArrayList(4); + public static SortSpec parseSortSpec(String sortSpec, SolrQueryRequest req) { + if (sortSpec == null || sortSpec.length() == 0) return newEmptySortSpec(); + + List sorts = new ArrayList(4); + List fields = new ArrayList(4); try { @@ -299,10 +313,11 @@ public class QueryParsing { if (null != top) { // we have a Query and a valid direction if (q instanceof FunctionQuery) { - lst.add(((FunctionQuery)q).getValueSource().getSortField(top)); + sorts.add(((FunctionQuery)q).getValueSource().getSortField(top)); } else { - lst.add((new QueryValueSource(q, 0.0f)).getSortField(top)); + sorts.add((new QueryValueSource(q, 0.0f)).getSortField(top)); } + fields.add(null); continue; } } catch (Exception e) { @@ -327,12 +342,14 @@ public class QueryParsing { if (SCORE.equals(field)) { if (top) { - lst.add(SortField.FIELD_SCORE); + sorts.add(SortField.FIELD_SCORE); } else { - lst.add(new SortField(null, SortField.Type.SCORE, true)); + sorts.add(new SortField(null, SortField.Type.SCORE, true)); } + fields.add(null); } else if (DOCID.equals(field)) { - lst.add(new SortField(null, SortField.Type.DOC, top)); + sorts.add(new SortField(null, SortField.Type.DOC, top)); + fields.add(null); } else { // try to find the field SchemaField sf = req.getSchema().getFieldOrNull(field); @@ -348,7 +365,8 @@ public class QueryParsing { (SolrException.ErrorCode.BAD_REQUEST, "sort param field can't be found: " + field); } - lst.add(sf.getSortField(top)); + sorts.add(sf.getSortField(top)); + fields.add(sf); } } @@ -358,13 +376,17 @@ public class QueryParsing { // normalize a sort on score desc to null - if (lst.size()==1 && lst.get(0) == SortField.FIELD_SCORE) { - return null; + if (sorts.size()==1 && sorts.get(0) == SortField.FIELD_SCORE) { + return newEmptySortSpec(); } - return new Sort(lst.toArray(new SortField[lst.size()])); + Sort s = new Sort(sorts.toArray(new SortField[sorts.size()])); + return new SortSpec(s, fields); } + private static SortSpec newEmptySortSpec() { + return new SortSpec(null, Collections.emptyList()); + } /////////////////////////// diff --git a/solr/core/src/java/org/apache/solr/search/SortSpec.java b/solr/core/src/java/org/apache/solr/search/SortSpec.java index 4573bf691bd..6655aa67a79 100644 --- a/solr/core/src/java/org/apache/solr/search/SortSpec.java +++ b/solr/core/src/java/org/apache/solr/search/SortSpec.java @@ -20,29 +20,63 @@ package org.apache.solr.search; import org.apache.lucene.search.Sort; import org.apache.lucene.search.SortField; +import org.apache.solr.schema.SchemaField; + +import java.util.Arrays; +import java.util.List; +import java.util.ArrayList; +import java.util.Collections; /*** * SortSpec encapsulates a Lucene Sort and a count of the number of documents * to return. */ public class SortSpec { - Sort sort; - int num; - int offset; + private Sort sort; + private List fields; + private int num = 10; + private int offset = 0; + public SortSpec(Sort sort, List fields) { + setSortAndFields(sort, fields); + } + public SortSpec(Sort sort, SchemaField[] fields) { + setSortAndFields(sort, Arrays.asList(fields)); + } + + /** @deprecated Specify both Sort and SchemaField[] when constructing */ + @Deprecated public SortSpec(Sort sort, int num) { this(sort,0,num); } + /** @deprecated Specify both Sort and SchemaField[] when constructing */ + @Deprecated public SortSpec(Sort sort, int offset, int num) { - this.sort=sort; + setSort(sort); this.offset=offset; this.num=num; } + /** @deprecated use {@link #setSortAndFields} */ + @Deprecated public void setSort( Sort s ) { sort = s; + fields = Collections.unmodifiableList(Arrays.asList(new SchemaField[s.getSort().length])); + } + + /** + * the specified SchemaFields must correspond one to one with the Sort's SortFields, + * using null where appropriate. + */ + public void setSortAndFields( Sort s, List fields ) + { + + assert null == s || s.getSort().length == fields.size() + : "SortFields and SchemaFields do not have equal lengths"; + this.sort = s; + this.fields = Collections.unmodifiableList(fields); } public static boolean includesScore(Sort sort) { @@ -63,10 +97,20 @@ public class SortSpec */ public Sort getSort() { return sort; } + /** + * Gets the Solr SchemaFields that correspond to each of the SortFields used + * in this sort. The array may contain null if a SortField doesn't correspond directly + * to a SchemaField (ie: score, lucene docid, custom function sorting, etc...) + * + * @return an immutable list, may be empty if getSort is null + */ + public List getSchemaFields() { return fields; } + /** * Offset into the list of results. */ public int getOffset() { return offset; } + public void setOffset(int offset) { this.offset = offset; } /** * Gets the number of documents to return after sorting. @@ -74,6 +118,7 @@ public class SortSpec * @return number of docs to return, or -1 for no cut off (just sort) */ public int getCount() { return num; } + public void setCount(int count) { this.num = count; } @Override public String toString() { diff --git a/solr/core/src/java/org/apache/solr/util/SolrPluginUtils.java b/solr/core/src/java/org/apache/solr/util/SolrPluginUtils.java index 8e9e405f404..af7a9633a76 100644 --- a/solr/core/src/java/org/apache/solr/util/SolrPluginUtils.java +++ b/solr/core/src/java/org/apache/solr/util/SolrPluginUtils.java @@ -430,7 +430,7 @@ public class SolrPluginUtils { // we can use the Lucene sort ability. Sort sort = null; if (commands.size() >= 2) { - sort = QueryParsing.parseSort(commands.get(1), req); + sort = QueryParsing.parseSortSpec(commands.get(1), req).getSort(); } DocList results = req.getSearcher().getDocList(query,(DocSet)null, sort, start, limit); @@ -825,7 +825,7 @@ public class SolrPluginUtils { SolrException sortE = null; Sort ss = null; try { - ss = QueryParsing.parseSort(sort, req); + ss = QueryParsing.parseSortSpec(sort, req).getSort(); } catch (SolrException e) { sortE = e; } diff --git a/solr/core/src/test-files/solr/collection1/conf/schema-custom-field.xml b/solr/core/src/test-files/solr/collection1/conf/schema-custom-field.xml index de206bce0bb..602527541c9 100644 --- a/solr/core/src/test-files/solr/collection1/conf/schema-custom-field.xml +++ b/solr/core/src/test-files/solr/collection1/conf/schema-custom-field.xml @@ -36,6 +36,9 @@ + + + text id diff --git a/solr/core/src/test/org/apache/solr/handler/component/DistributedQueryComponentCustomSortTest.java b/solr/core/src/test/org/apache/solr/handler/component/DistributedQueryComponentCustomSortTest.java index 8a4b9735e0b..b19b486ea7a 100644 --- a/solr/core/src/test/org/apache/solr/handler/component/DistributedQueryComponentCustomSortTest.java +++ b/solr/core/src/test/org/apache/solr/handler/component/DistributedQueryComponentCustomSortTest.java @@ -47,7 +47,9 @@ public class DistributedQueryComponentCustomSortTest extends BaseDistributedSear public void doTest() throws Exception { del("*:*"); - index(id, "1", "text", "a", "payload", ByteBuffer.wrap(new byte[] { 0x12, 0x62, 0x15 })); // 2 + index(id, "1", "text", "a", "payload", ByteBuffer.wrap(new byte[] { 0x12, 0x62, 0x15 }), // 2 + // quick check to prove "*" dynamicField hasn't been broken by somebody mucking with schema + "asdfasdf_field_should_match_catchall_dynamic_field_adsfasdf", "value"); index(id, "2", "text", "b", "payload", ByteBuffer.wrap(new byte[] { 0x25, 0x21, 0x16 })); // 5 index(id, "3", "text", "a", "payload", ByteBuffer.wrap(new byte[] { 0x35, 0x32, 0x58 })); // 8 index(id, "4", "text", "b", "payload", ByteBuffer.wrap(new byte[] { 0x25, 0x21, 0x15 })); // 4 @@ -90,6 +92,10 @@ public class DistributedQueryComponentCustomSortTest extends BaseDistributedSear rsp = query("q", "text:d", "fl", "id", "sort", "payload desc", "rows", "20"); assertFieldValues(rsp.getResults(), id, 11, 13, 12); + // sanity check function sorting + rsp = query("q", "id:[1 TO 10]", "fl", "id", "rows", "20", + "sort", "abs(sub(5,id)) asc, id desc"); + assertFieldValues(rsp.getResults(), id, 5 , 6,4 , 7,3 , 8,2 , 9,1 , 10 ); // Add two more docs with same payload as in doc #4 index(id, "14", "text", "b", "payload", ByteBuffer.wrap(new byte[] { 0x25, 0x21, 0x15 })); diff --git a/solr/core/src/test/org/apache/solr/search/QueryParsingTest.java b/solr/core/src/test/org/apache/solr/search/QueryParsingTest.java index ae9fe340092..482c02e79ea 100644 --- a/solr/core/src/test/org/apache/solr/search/QueryParsingTest.java +++ b/solr/core/src/test/org/apache/solr/search/QueryParsingTest.java @@ -20,11 +20,15 @@ import org.apache.lucene.search.Query; import org.apache.lucene.search.Sort; import org.apache.lucene.search.SortField; import org.apache.solr.SolrTestCaseJ4; +import org.apache.solr.schema.SchemaField; +import org.apache.solr.search.SortSpec; import org.apache.solr.common.SolrException; import org.apache.solr.request.SolrQueryRequest; import org.junit.BeforeClass; import org.junit.Test; +import java.util.List; + /** * * @@ -72,22 +76,48 @@ public class QueryParsingTest extends SolrTestCaseJ4 { @Test public void testSort() throws Exception { Sort sort; + SortSpec spec; SolrQueryRequest req = req(); sort = QueryParsing.parseSort("score desc", req); assertNull("sort", sort);//only 1 thing in the list, no Sort specified + spec = QueryParsing.parseSortSpec("score desc", req); + assertNotNull("spec", spec); + assertNull(spec.getSort()); + assertNotNull(spec.getSchemaFields()); + assertEquals(0, spec.getSchemaFields().size()); + // SOLR-4458 - using different case variations of asc and desc sort = QueryParsing.parseSort("score aSc", req); SortField[] flds = sort.getSort(); assertEquals(flds[0].getType(), SortField.Type.SCORE); assertTrue(flds[0].getReverse()); + spec = QueryParsing.parseSortSpec("score aSc", req); + flds = spec.getSort().getSort(); + assertEquals(1, flds.length); + assertEquals(flds[0].getType(), SortField.Type.SCORE); + assertTrue(flds[0].getReverse()); + assertEquals(1, spec.getSchemaFields().size()); + assertNull(spec.getSchemaFields().get(0)); + sort = QueryParsing.parseSort("weight dEsC", req); flds = sort.getSort(); assertEquals(flds[0].getType(), SortField.Type.FLOAT); assertEquals(flds[0].getField(), "weight"); assertEquals(flds[0].getReverse(), true); + + spec = QueryParsing.parseSortSpec("weight dEsC", req); + flds = spec.getSort().getSort(); + assertEquals(1, flds.length); + assertEquals(flds[0].getType(), SortField.Type.FLOAT); + assertEquals(flds[0].getField(), "weight"); + assertEquals(flds[0].getReverse(), true); + assertEquals(1, spec.getSchemaFields().size()); + assertNotNull(spec.getSchemaFields().get(0)); + assertEquals("weight", spec.getSchemaFields().get(0).getName()); + sort = QueryParsing.parseSort("weight desc,bday ASC", req); flds = sort.getSort(); assertEquals(flds[0].getType(), SortField.Type.FLOAT); @@ -147,20 +177,29 @@ public class QueryParsingTest extends SolrTestCaseJ4 { //Not thrilled about the fragility of string matching here, but... //the value sources get wrapped, so the out field is different than the input assertEquals(flds[0].getField(), "pow(float(weight),const(2.0))"); + + spec = QueryParsing.parseSortSpec("pow(weight, 2.0) desc, weight desc, bday asc", req); + flds = spec.getSort().getSort(); + List schemaFlds = spec.getSchemaFields(); + assertEquals(3, flds.length); + assertEquals(3, schemaFlds.size()); - sort = QueryParsing.parseSort("pow(weight, 2.0) desc, weight desc, bday asc", req); - flds = sort.getSort(); assertEquals(flds[0].getType(), SortField.Type.REWRITEABLE); - //Not thrilled about the fragility of string matching here, but... //the value sources get wrapped, so the out field is different than the input assertEquals(flds[0].getField(), "pow(float(weight),const(2.0))"); + assertNull(schemaFlds.get(0)); assertEquals(flds[1].getType(), SortField.Type.FLOAT); assertEquals(flds[1].getField(), "weight"); + assertNotNull(schemaFlds.get(1)); + assertEquals("weight", schemaFlds.get(1).getName()); + assertEquals(flds[2].getField(), "bday"); assertEquals(flds[2].getType(), SortField.Type.LONG); + assertNotNull(schemaFlds.get(2)); + assertEquals("bday", schemaFlds.get(2).getName()); //handles trailing commas sort = QueryParsing.parseSort("weight desc,", req); @@ -178,6 +217,10 @@ public class QueryParsingTest extends SolrTestCaseJ4 { sort = QueryParsing.parseSort("", req); assertNull(sort); + spec = QueryParsing.parseSortSpec("", req); + assertNotNull(spec); + assertNull(spec.getSort()); + req.close(); } diff --git a/solr/core/src/test/org/apache/solr/search/TestSort.java b/solr/core/src/test/org/apache/solr/search/TestSort.java index 1f391c5e762..5be8848807e 100644 --- a/solr/core/src/test/org/apache/solr/search/TestSort.java +++ b/solr/core/src/test/org/apache/solr/search/TestSort.java @@ -36,6 +36,7 @@ import org.apache.lucene.util.Bits; import org.apache.lucene.util.OpenBitSet; import org.apache.lucene.util._TestUtil; import org.apache.solr.SolrTestCaseJ4; +import org.apache.solr.schema.SchemaField; import org.apache.solr.request.SolrQueryRequest; import org.junit.BeforeClass; @@ -114,13 +115,18 @@ public class TestSort extends SolrTestCaseJ4 { } input.deleteCharAt(input.length()-1); SortField[] sorts = null; + List fields = null; try { - sorts = QueryParsing.parseSort(input.toString(), req).getSort(); + SortSpec spec = QueryParsing.parseSortSpec(input.toString(), req); + sorts = spec.getSort().getSort(); + fields = spec.getSchemaFields(); } catch (RuntimeException e) { throw new RuntimeException("Failed to parse sort: " + input, e); } assertEquals("parsed sorts had unexpected size", names.length, sorts.length); + assertEquals("parsed sort schema fields had unexpected size", + names.length, fields.size()); for (int j = 0; j < names.length; j++) { assertEquals("sorts["+j+"] had unexpected reverse: " + input, reverse[j], sorts[j].getReverse()); @@ -144,6 +150,9 @@ public class TestSort extends SolrTestCaseJ4 { assertEquals("sorts["+j+"] ("+type.toString()+ ") had unexpected field in: " + input, names[j], sorts[j].getField()); + assertEquals("fields["+j+"] ("+type.toString()+ + ") had unexpected name in: " + input, + names[j], fields.get(j).getName()); } } } From 09aa2dce76f6f384700d708b148028cbd20d2fdd Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Tue, 3 Dec 2013 15:42:16 +0000 Subject: [PATCH 170/223] SOLR-1301: Ignore these tests on java 8 and j9 for now. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1547442 13f79535-47bb-0310-9956-ffa450edef68 --- .../solr/morphlines/cell/SolrCellMorphlineTest.java | 7 +++++++ .../apache/solr/morphlines/solr/SolrMorphlineTest.java | 8 ++++++++ .../solr/morphlines/solr/SolrMorphlineZkAliasTest.java | 10 +++++++++- .../solr/morphlines/solr/SolrMorphlineZkAvroTest.java | 8 ++++++++ .../solr/morphlines/solr/SolrMorphlineZkTest.java | 10 +++++++++- .../apache/solr/hadoop/MorphlineBasicMiniMRTest.java | 8 ++++++-- .../apache/solr/hadoop/MorphlineGoLiveMiniMRTest.java | 8 ++++++-- .../org/apache/solr/hadoop/MorphlineMapperTest.java | 2 ++ .../org/apache/solr/hadoop/MorphlineReducerTest.java | 6 ++---- 9 files changed, 57 insertions(+), 10 deletions(-) diff --git a/solr/contrib/solr-morphlines-cell/src/test/org/apache/solr/morphlines/cell/SolrCellMorphlineTest.java b/solr/contrib/solr-morphlines-cell/src/test/org/apache/solr/morphlines/cell/SolrCellMorphlineTest.java index 80d2d43499c..912febceef6 100644 --- a/solr/contrib/solr-morphlines-cell/src/test/org/apache/solr/morphlines/cell/SolrCellMorphlineTest.java +++ b/solr/contrib/solr-morphlines-cell/src/test/org/apache/solr/morphlines/cell/SolrCellMorphlineTest.java @@ -21,6 +21,7 @@ import java.util.HashMap; import java.util.Map; import org.apache.commons.io.FileUtils; +import org.apache.lucene.util.Constants; import org.apache.solr.common.SolrInputDocument; import org.apache.solr.common.params.MapSolrParams; import org.apache.solr.common.util.DateUtil; @@ -29,6 +30,7 @@ import org.apache.solr.morphlines.solr.AbstractSolrMorphlineTestBase; import org.apache.solr.schema.IndexSchema; import org.apache.tika.metadata.Metadata; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; @@ -36,6 +38,11 @@ public class SolrCellMorphlineTest extends AbstractSolrMorphlineTestBase { private Map expectedRecords = new HashMap(); + @BeforeClass + public static void beforeClass2() { + assumeFalse("FIXME: This test fails under Java 8 due to the Saxon dependency - see SOLR-1301", Constants.JRE_IS_MINIMUM_JAVA8); + assumeFalse("FIXME: This test fails under J9 due to the Saxon dependency - see SOLR-1301", System.getProperty("java.vm.info", "").contains("IBM J9")); + } @Before public void setUp() throws Exception { diff --git a/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineTest.java b/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineTest.java index 126eef34979..658020ca3c0 100644 --- a/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineTest.java +++ b/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineTest.java @@ -18,6 +18,8 @@ package org.apache.solr.morphlines.solr; import java.util.Arrays; +import org.apache.lucene.util.Constants; +import org.junit.BeforeClass; import org.junit.Test; import com.cloudera.cdk.morphline.api.Record; @@ -26,6 +28,12 @@ import com.cloudera.cdk.morphline.base.Notifications; public class SolrMorphlineTest extends AbstractSolrMorphlineTestBase { + @BeforeClass + public static void beforeClass2() { + assumeFalse("FIXME: This test fails under Java 8 due to the Saxon dependency - see SOLR-1301", Constants.JRE_IS_MINIMUM_JAVA8); + assumeFalse("FIXME: This test fails under J9 due to the Saxon dependency - see SOLR-1301", System.getProperty("java.vm.info", "").contains("IBM J9")); + } + @Test public void testLoadSolrBasic() throws Exception { //System.setProperty("ENV_SOLR_HOME", testSolrHome + "/collection1"); diff --git a/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkAliasTest.java b/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkAliasTest.java index 2fce297b34d..939ef199c89 100644 --- a/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkAliasTest.java +++ b/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkAliasTest.java @@ -19,6 +19,7 @@ package org.apache.solr.morphlines.solr; import java.io.IOException; import java.util.Iterator; +import org.apache.lucene.util.Constants; import org.apache.lucene.util.LuceneTestCase.Slow; import org.apache.lucene.util.LuceneTestCase.SuppressCodecs; import org.apache.solr.client.solrj.SolrQuery; @@ -29,6 +30,7 @@ import org.apache.solr.common.SolrDocument; import org.apache.solr.common.params.CollectionParams.CollectionAction; import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.util.NamedList; +import org.junit.BeforeClass; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakAction; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakAction.Action; @@ -48,7 +50,13 @@ import com.cloudera.cdk.morphline.base.Notifications; @SuppressCodecs({"Lucene3x", "Lucene40"}) @Slow public class SolrMorphlineZkAliasTest extends AbstractSolrMorphlineZkTestBase { - + + @BeforeClass + public static void beforeClass2() { + assumeFalse("FIXME: This test fails under Java 8 due to the Saxon dependency - see SOLR-1301", Constants.JRE_IS_MINIMUM_JAVA8); + assumeFalse("FIXME: This test fails under J9 due to the Saxon dependency - see SOLR-1301", System.getProperty("java.vm.info", "").contains("IBM J9")); + } + @Override public void doTest() throws Exception { diff --git a/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkAvroTest.java b/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkAvroTest.java index 4e082cc260f..41abfe54ff7 100644 --- a/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkAvroTest.java +++ b/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkAvroTest.java @@ -28,11 +28,13 @@ import org.apache.avro.file.DataFileReader; import org.apache.avro.file.FileReader; import org.apache.avro.generic.GenericData; import org.apache.avro.generic.GenericDatumReader; +import org.apache.lucene.util.Constants; import org.apache.lucene.util.LuceneTestCase.Slow; import org.apache.lucene.util.LuceneTestCase.SuppressCodecs; import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.response.QueryResponse; import org.apache.solr.common.SolrDocument; +import org.junit.BeforeClass; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakAction; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakAction.Action; @@ -55,6 +57,12 @@ import com.google.common.io.Files; @Slow public class SolrMorphlineZkAvroTest extends AbstractSolrMorphlineZkTestBase { + @BeforeClass + public static void beforeClass2() { + assumeFalse("FIXME: This test fails under Java 8 due to the Saxon dependency - see SOLR-1301", Constants.JRE_IS_MINIMUM_JAVA8); + assumeFalse("FIXME: This test fails under J9 due to the Saxon dependency - see SOLR-1301", System.getProperty("java.vm.info", "").contains("IBM J9")); + } + @Override public void doTest() throws Exception { File file = new File(RESOURCES_DIR + "/test-documents/sample-statuses-20120906-141433-medium.avro"); diff --git a/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkTest.java b/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkTest.java index 0537c2e23ab..d104e7b84ee 100644 --- a/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkTest.java +++ b/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkTest.java @@ -18,11 +18,13 @@ package org.apache.solr.morphlines.solr; import java.util.Iterator; +import org.apache.lucene.util.Constants; import org.apache.lucene.util.LuceneTestCase.Slow; import org.apache.lucene.util.LuceneTestCase.SuppressCodecs; import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.response.QueryResponse; import org.apache.solr.common.SolrDocument; +import org.junit.BeforeClass; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakAction; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakAction.Action; @@ -42,7 +44,13 @@ import com.cloudera.cdk.morphline.base.Notifications; @SuppressCodecs({"Lucene3x", "Lucene40"}) @Slow public class SolrMorphlineZkTest extends AbstractSolrMorphlineZkTestBase { - + + @BeforeClass + public static void beforeClass2() { + assumeFalse("FIXME: This test fails under Java 8 due to the Saxon dependency - see SOLR-1301", Constants.JRE_IS_MINIMUM_JAVA8); + assumeFalse("FIXME: This test fails under J9 due to the Saxon dependency - see SOLR-1301", System.getProperty("java.vm.info", "").contains("IBM J9")); + } + @Override public void doTest() throws Exception { diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineBasicMiniMRTest.java b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineBasicMiniMRTest.java index 49891290b0a..1a0101e171f 100644 --- a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineBasicMiniMRTest.java +++ b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineBasicMiniMRTest.java @@ -37,6 +37,7 @@ import org.apache.hadoop.security.authorize.ProxyUsers; import org.apache.hadoop.util.JarFinder; import org.apache.hadoop.util.ToolRunner; import org.apache.hadoop.yarn.conf.YarnConfiguration; +import org.apache.lucene.util.Constants; import org.apache.lucene.util.LuceneTestCase; import org.apache.lucene.util.LuceneTestCase.Slow; import org.apache.solr.SolrTestCaseJ4; @@ -109,13 +110,16 @@ public class MorphlineBasicMiniMRTest extends SolrTestCaseJ4 { @BeforeClass public static void setupClass() throws Exception { - LuceneTestCase.assumeTrue( + assumeTrue( "Currently this test can only be run without the lucene test security policy in place", System.getProperty("java.security.manager", "").equals("")); - LuceneTestCase.assumeFalse("HDFS tests were disabled by -Dtests.disableHdfs", + assumeFalse("HDFS tests were disabled by -Dtests.disableHdfs", Boolean.parseBoolean(System.getProperty("tests.disableHdfs", "false"))); + assumeFalse("FIXME: This test fails under Java 8 due to the Saxon dependency - see SOLR-1301", Constants.JRE_IS_MINIMUM_JAVA8); + assumeFalse("FIXME: This test fails under J9 due to the Saxon dependency - see SOLR-1301", System.getProperty("java.vm.info", "").contains("IBM J9")); + AbstractZkTestCase.SOLRHOME = solrHomeDirectory; FileUtils.copyDirectory(MINIMR_CONF_DIR, solrHomeDirectory); diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineGoLiveMiniMRTest.java b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineGoLiveMiniMRTest.java index 32f24980fa0..5b654bcc6d7 100644 --- a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineGoLiveMiniMRTest.java +++ b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineGoLiveMiniMRTest.java @@ -41,6 +41,7 @@ import org.apache.hadoop.security.authorize.ProxyUsers; import org.apache.hadoop.util.JarFinder; import org.apache.hadoop.util.ToolRunner; import org.apache.hadoop.yarn.conf.YarnConfiguration; +import org.apache.lucene.util.Constants; import org.apache.lucene.util.LuceneTestCase; import org.apache.lucene.util.LuceneTestCase.Slow; import org.apache.lucene.util.LuceneTestCase.SuppressCodecs; @@ -129,13 +130,16 @@ public class MorphlineGoLiveMiniMRTest extends AbstractFullDistribZkTestBase { @BeforeClass public static void setupClass() throws Exception { - LuceneTestCase.assumeTrue( + assumeTrue( "Currently this test can only be run without the lucene test security policy in place", System.getProperty("java.security.manager", "").equals("")); - LuceneTestCase.assumeFalse("HDFS tests were disabled by -Dtests.disableHdfs", + assumeFalse("HDFS tests were disabled by -Dtests.disableHdfs", Boolean.parseBoolean(System.getProperty("tests.disableHdfs", "false"))); + assumeFalse("FIXME: This test fails under Java 8 due to the Saxon dependency - see SOLR-1301", Constants.JRE_IS_MINIMUM_JAVA8); + assumeFalse("FIXME: This test fails under J9 due to the Saxon dependency - see SOLR-1301", System.getProperty("java.vm.info", "").contains("IBM J9")); + AbstractZkTestCase.SOLRHOME = solrHomeDirectory; FileUtils.copyDirectory(MINIMR_INSTANCE_DIR, solrHomeDirectory); diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineMapperTest.java b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineMapperTest.java index bbd3897df69..fed109f12df 100644 --- a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineMapperTest.java +++ b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineMapperTest.java @@ -34,6 +34,8 @@ public class MorphlineMapperTest extends MRUnitBase { @BeforeClass public static void beforeClass() { assumeFalse("Does not work on Windows, because it uses UNIX shell commands or POSIX paths", Constants.WINDOWS); + assumeFalse("FIXME: This test fails under Java 8 due to the Saxon dependency - see SOLR-1301", Constants.JRE_IS_MINIMUM_JAVA8); + assumeFalse("FIXME: This test fails under J9 due to the Saxon dependency - see SOLR-1301", System.getProperty("java.vm.info", "").contains("IBM J9")); } @Test diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineReducerTest.java b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineReducerTest.java index faa92ea2d09..844aff09ace 100644 --- a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineReducerTest.java +++ b/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineReducerTest.java @@ -18,12 +18,10 @@ package org.apache.solr.hadoop; import static org.mockito.Mockito.when; -import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; -import org.apache.commons.io.FileUtils; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapred.TaskID; @@ -35,8 +33,6 @@ import org.apache.hadoop.mapreduce.TaskAttemptContext; import org.apache.hadoop.mapreduce.TaskAttemptID; import org.apache.hadoop.mrunit.mapreduce.ReduceDriver; import org.apache.lucene.util.Constants; -import org.apache.lucene.util.LuceneTestCase; -import org.apache.solr.cloud.AbstractZkTestCase; import org.apache.solr.common.SolrInputDocument; import org.junit.BeforeClass; import org.junit.Test; @@ -50,6 +46,8 @@ public class MorphlineReducerTest extends MRUnitBase { @BeforeClass public static void beforeClass() { assumeFalse("Does not work on Windows, because it uses UNIX shell commands or POSIX paths", Constants.WINDOWS); + assumeFalse("FIXME: This test fails under Java 8 due to the Saxon dependency - see SOLR-1301", Constants.JRE_IS_MINIMUM_JAVA8); + assumeFalse("FIXME: This test fails under J9 due to the Saxon dependency - see SOLR-1301", System.getProperty("java.vm.info", "").contains("IBM J9")); } public static class MySolrReducer extends SolrReducer { From 1f57856b9039ab418a1c49373dc88c72be936518 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Tue, 3 Dec 2013 16:10:58 +0000 Subject: [PATCH 171/223] SOLR-5502: A "/" in a document id will cause an exception to be thrown when using the composite id router. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1547452 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 6 +++--- .../apache/solr/cloud/ShardRoutingTest.java | 21 +++++++++++-------- .../cloud/TriLevelCompositeIdRoutingTest.java | 1 - .../solr/common/cloud/CompositeIdRouter.java | 11 +++++----- 4 files changed, 21 insertions(+), 18 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 3250c726e60..961a2e1e9be 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -189,6 +189,9 @@ Bug Fixes * SOLR-5527: DIH logs spurious warning for special commands. (shalin) +* SOLR-5502: A "/" in a document id will cause an exception to be thrown + when using the composite id router. (Anshum Gupta via Mark Miller) + Optimizations ---------------------- @@ -220,9 +223,6 @@ Other Changes * SOLR-5499: Log a warning if /get is not registered when using SolrCloud. (Daniel Collins via shalin) -* SOLR-5517: Return HTTP error on POST requests with no Content-Type. - (Ryan Ernst, Uwe Schindler) - ================== 4.6.0 ================== Versions of Major Components diff --git a/solr/core/src/test/org/apache/solr/cloud/ShardRoutingTest.java b/solr/core/src/test/org/apache/solr/cloud/ShardRoutingTest.java index 679b1dd9c78..4275aad7f00 100644 --- a/solr/core/src/test/org/apache/solr/cloud/ShardRoutingTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/ShardRoutingTest.java @@ -148,30 +148,33 @@ public class ShardRoutingTest extends AbstractFullDistribZkTestBase { doAddDoc("d!doc3"); doAddDoc("e!doc4"); doAddDoc("f1!f2!doc5"); + // Check successful addition of a document with a '/' in the id part. + doAddDoc("f1!f2!doc5/5"); doRTG("b!doc1"); doRTG("c!doc2"); doRTG("d!doc3"); doRTG("e!doc4"); doRTG("f1!f2!doc5"); + doRTG("f1!f2!doc5/5"); doRTG("b!doc1,c!doc2"); doRTG("d!doc3,e!doc4"); commit(); - doQuery("b!doc1,c!doc2,d!doc3,e!doc4,f1!f2!doc5", "q","*:*"); - doQuery("b!doc1,c!doc2,d!doc3,e!doc4,f1!f2!doc5", "q","*:*", "shards","shard1,shard2,shard3,shard4"); - doQuery("b!doc1,c!doc2,d!doc3,e!doc4,f1!f2!doc5", "q","*:*", shardKeys,"b!,c!,d!,e!,f1!f2!"); + doQuery("b!doc1,c!doc2,d!doc3,e!doc4,f1!f2!doc5,f1!f2!doc5/5", "q","*:*"); + doQuery("b!doc1,c!doc2,d!doc3,e!doc4,f1!f2!doc5,f1!f2!doc5/5", "q","*:*", "shards","shard1,shard2,shard3,shard4"); + doQuery("b!doc1,c!doc2,d!doc3,e!doc4,f1!f2!doc5,f1!f2!doc5/5", "q","*:*", shardKeys,"b!,c!,d!,e!,f1!f2!"); doQuery("b!doc1", "q","*:*", shardKeys,"b!"); doQuery("c!doc2", "q","*:*", shardKeys,"c!"); - doQuery("d!doc3,f1!f2!doc5", "q","*:*", shardKeys,"d!"); + doQuery("d!doc3,f1!f2!doc5,f1!f2!doc5/5", "q","*:*", shardKeys,"d!"); doQuery("e!doc4", "q","*:*", shardKeys,"e!"); - doQuery("f1!f2!doc5,d!doc3", "q","*:*", shardKeys,"f1/8!"); + doQuery("f1!f2!doc5,d!doc3,f1!f2!doc5/5", "q","*:*", shardKeys,"f1/8!"); // try using shards parameter doQuery("b!doc1", "q","*:*", "shards",bucket1); doQuery("c!doc2", "q","*:*", "shards",bucket2); - doQuery("d!doc3,f1!f2!doc5", "q","*:*", "shards",bucket3); + doQuery("d!doc3,f1!f2!doc5,f1!f2!doc5/5", "q","*:*", "shards",bucket3); doQuery("e!doc4", "q","*:*", "shards",bucket4); @@ -181,16 +184,16 @@ public class ShardRoutingTest extends AbstractFullDistribZkTestBase { doQuery("b!doc1,c!doc2", "q","*:*", shardKeys,"b,c"); // query shards that would contain *documents* "b" and "c" (i.e. not prefixes). The upper bits are the same, so the shards should be the same. doQuery("b!doc1,c!doc2", "q","*:*", shardKeys,"b/1!"); // top bit of hash(b)==1, so shard1 and shard2 - doQuery("d!doc3,e!doc4,f1!f2!doc5", "q","*:*", shardKeys,"d/1!"); // top bit of hash(b)==0, so shard3 and shard4 + doQuery("d!doc3,e!doc4,f1!f2!doc5,f1!f2!doc5/5", "q","*:*", shardKeys,"d/1!"); // top bit of hash(b)==0, so shard3 and shard4 doQuery("b!doc1,c!doc2", "q","*:*", shardKeys,"b!,c!"); - doQuery("b!doc1,f1!f2!doc5,c!doc2,d!doc3,e!doc4", "q","*:*", shardKeys,"foo/0!"); + doQuery("b!doc1,f1!f2!doc5,c!doc2,d!doc3,e!doc4,f1!f2!doc5/5", "q","*:*", shardKeys,"foo/0!"); // test targeting deleteByQuery at only certain shards doDBQ("*:*", shardKeys,"b!"); commit(); - doQuery("c!doc2,d!doc3,e!doc4,f1!f2!doc5", "q","*:*"); + doQuery("c!doc2,d!doc3,e!doc4,f1!f2!doc5,f1!f2!doc5/5", "q","*:*"); doAddDoc("b!doc1"); doDBQ("*:*", shardKeys,"f1!"); diff --git a/solr/core/src/test/org/apache/solr/cloud/TriLevelCompositeIdRoutingTest.java b/solr/core/src/test/org/apache/solr/cloud/TriLevelCompositeIdRoutingTest.java index 024cc016e0f..26aa92c414c 100644 --- a/solr/core/src/test/org/apache/solr/cloud/TriLevelCompositeIdRoutingTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/TriLevelCompositeIdRoutingTest.java @@ -143,7 +143,6 @@ public class TriLevelCompositeIdRoutingTest extends ShardRoutingTest { Set doQueryGetUniqueIdKeys(String... queryParams) throws Exception { QueryResponse rsp = cloudClient.query(params(queryParams)); Set obtainedIdKeys = new HashSet(); - Set obtainedIdKeys2 = new HashSet(); for (SolrDocument doc : rsp.getResults()) { obtainedIdKeys.add(getKey((String) doc.get("id"))); } diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/CompositeIdRouter.java b/solr/solrj/src/java/org/apache/solr/common/cloud/CompositeIdRouter.java index 862e41759a4..766b115d605 100644 --- a/solr/solrj/src/java/org/apache/solr/common/cloud/CompositeIdRouter.java +++ b/solr/solrj/src/java/org/apache/solr/common/cloud/CompositeIdRouter.java @@ -202,15 +202,16 @@ public class CompositeIdRouter extends HashBasedRouter { } else { numBits[0] = 16; triLevel = false; - } for (int i = 0; i < parts.length; i++) { - int commaIdx = parts[i].indexOf(bitsSeparator); + if (i < pieces - 1) { + int commaIdx = parts[i].indexOf(bitsSeparator); - if (commaIdx > 0) { - numBits[i] = getNumBits(parts[i], commaIdx); - parts[i] = parts[i].substring(0, commaIdx); + if (commaIdx > 0) { + numBits[i] = getNumBits(parts[i], commaIdx); + parts[i] = parts[i].substring(0, commaIdx); + } } hashes[i] = Hash.murmurhash3_x86_32(parts[i], 0, parts[i].length(), 0); } From 0f768189e5acabfea373c362efebd97a4e6b1584 Mon Sep 17 00:00:00 2001 From: Steven Rowe Date: Tue, 3 Dec 2013 17:08:11 +0000 Subject: [PATCH 172/223] When dependency/@conf contains BOTH 'test' and 'compile', and dependency/artifact/@type != 'test', the artifact is NOT a test dependency, to handle solr-morphlines-core's compile-scope cdk-morphlines-core and test-scope cdk-morphlines-core-tests dependencies git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1547479 13f79535-47bb-0310-9956-ffa450edef68 --- .../lucene/dependencies/GetMavenDependenciesTask.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lucene/tools/src/java/org/apache/lucene/dependencies/GetMavenDependenciesTask.java b/lucene/tools/src/java/org/apache/lucene/dependencies/GetMavenDependenciesTask.java index b01f81f9cf7..e1ac4ce84b6 100644 --- a/lucene/tools/src/java/org/apache/lucene/dependencies/GetMavenDependenciesTask.java +++ b/lucene/tools/src/java/org/apache/lucene/dependencies/GetMavenDependenciesTask.java @@ -667,7 +667,7 @@ public class GetMavenDependenciesTask extends Task { dependencyClassifiers.put(dependencyCoordinate, classifiers); } String conf = dependency.getAttribute("conf"); - boolean isTestDependency = conf.contains("test"); + boolean confContainsTest = conf.contains("test"); boolean isOptional = optionalExternalDependencies.contains(dependencyCoordinate); SortedSet deps = allExternalDependencies.get(module); if (null == deps) { @@ -683,6 +683,8 @@ public class GetMavenDependenciesTask extends Task { Element artifact = (Element)artifacts.item(artifactNum); String type = artifact.getAttribute("type"); String ext = artifact.getAttribute("ext"); + // When conf contains BOTH "test" and "compile", and type != "test", this is NOT a test dependency + boolean isTestDependency = confContainsTest && (type.equals("test") || ! conf.contains("compile")); if ((type.isEmpty() && ext.isEmpty()) || type.equals("jar") || ext.equals("jar")) { String classifier = artifact.getAttribute("maven:classifier"); if (classifier.isEmpty()) { @@ -696,7 +698,7 @@ public class GetMavenDependenciesTask extends Task { } } else { classifiers.add(null); - deps.add(new ExternalDependency(groupId, artifactId, null, isTestDependency, isOptional)); + deps.add(new ExternalDependency(groupId, artifactId, null, confContainsTest, isOptional)); } } } From 5f5098299a43d25f121d1b4067e5708798d5ff5a Mon Sep 17 00:00:00 2001 From: Steven Rowe Date: Tue, 3 Dec 2013 17:54:57 +0000 Subject: [PATCH 173/223] SOLR-1301: remove unnecessary (POM-only) dependency org.apache.hadoop:hadoop-yarn-server git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1547498 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/ivy-versions.properties | 1 - solr/contrib/solr-morphlines-core/ivy.xml | 1 - 2 files changed, 2 deletions(-) diff --git a/lucene/ivy-versions.properties b/lucene/ivy-versions.properties index a340d2bbdae..cf088e44b38 100644 --- a/lucene/ivy-versions.properties +++ b/lucene/ivy-versions.properties @@ -111,7 +111,6 @@ org.apache.hadoop.version = 2.2.0 /org.apache.hadoop/hadoop-yarn-api = ${org.apache.hadoop.version} /org.apache.hadoop/hadoop-yarn-client = ${org.apache.hadoop.version} /org.apache.hadoop/hadoop-yarn-common = ${org.apache.hadoop.version} -/org.apache.hadoop/hadoop-yarn-server = ${org.apache.hadoop.version} /org.apache.hadoop/hadoop-yarn-server-common = ${org.apache.hadoop.version} /org.apache.hadoop/hadoop-yarn-server-nodemanager = ${org.apache.hadoop.version} /org.apache.hadoop/hadoop-yarn-server-resourcemanager = ${org.apache.hadoop.version} diff --git a/solr/contrib/solr-morphlines-core/ivy.xml b/solr/contrib/solr-morphlines-core/ivy.xml index c9948e0cc59..abefff79135 100644 --- a/solr/contrib/solr-morphlines-core/ivy.xml +++ b/solr/contrib/solr-morphlines-core/ivy.xml @@ -45,7 +45,6 @@ - From b5dbac5e3582a1cfd59af34c1a41f88aed203da1 Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Tue, 3 Dec 2013 18:05:23 +0000 Subject: [PATCH 174/223] LUCENE-4381: upgrade ICU to icu4j 52.1 git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1547502 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/CHANGES.txt | 2 + ...LStripCharFilter.SUPPLEMENTARY.jflex-macro | 2 +- .../standard/SUPPLEMENTARY.jflex-macro | 2 +- .../analysis/icu/src/data/uax29/Default.rbbi | 129 +++++++--- .../analysis/icu/src/data/uax29/Hebrew.rbbi | 61 ----- lucene/analysis/icu/src/data/uax29/Lao.rbbi | 192 --------------- .../icu/src/data/utr30/BasicFoldings.txt | 1 - lucene/analysis/icu/src/data/utr30/nfc.txt | 4 +- lucene/analysis/icu/src/data/utr30/nfkc.txt | 4 +- .../analysis/icu/src/data/utr30/nfkc_cf.txt | 7 +- .../segmentation/BreakIteratorWrapper.java | 8 +- .../segmentation/CompositeBreakIterator.java | 3 +- .../DefaultICUTokenizerConfig.java | 41 ++-- .../icu/segmentation/ICUTokenizer.java | 2 +- .../icu/segmentation/ICUTokenizerConfig.java | 2 + .../icu/segmentation/ICUTokenizerFactory.java | 8 +- .../icu/segmentation/LaoBreakIterator.java | 230 ------------------ .../icu/segmentation/ScriptIterator.java | 31 ++- .../tokenattributes/ScriptAttributeImpl.java | 6 +- lucene/analysis/icu/src/java/overview.html | 2 +- .../analysis/icu/segmentation/Default.brk | Bin 28152 -> 32736 bytes .../analysis/icu/segmentation/Hebrew.brk | Bin 26200 -> 0 bytes .../analysis/icu/segmentation/Khmer.brk | Bin 16320 -> 16328 bytes .../lucene/analysis/icu/segmentation/Lao.brk | Bin 47344 -> 0 bytes .../analysis/icu/segmentation/Myanmar.brk | Bin 18384 -> 18392 bytes .../org/apache/lucene/analysis/icu/utr30.nrm | Bin 52288 -> 52288 bytes .../icu/segmentation/TestICUTokenizer.java | 14 +- .../icu/segmentation/TestICUTokenizerCJK.java | 91 +++++++ .../segmentation/TestLaoBreakIterator.java | 90 ------- .../segmentation/TestWithCJKBigramFilter.java | 4 +- .../analysis/icu/GenerateUTR30DataFiles.java | 2 +- lucene/ivy-versions.properties | 2 +- lucene/licenses/icu4j-49.1.jar.sha1 | 1 - lucene/licenses/icu4j-52.1.jar.sha1 | 1 + .../analysis/BaseTokenStreamTestCase.java | 4 +- solr/licenses/icu4j-49.1.jar.sha1 | 1 - solr/licenses/icu4j-52.1.jar.sha1 | 1 + 37 files changed, 281 insertions(+), 667 deletions(-) delete mode 100644 lucene/analysis/icu/src/data/uax29/Hebrew.rbbi delete mode 100644 lucene/analysis/icu/src/data/uax29/Lao.rbbi delete mode 100644 lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/segmentation/LaoBreakIterator.java delete mode 100644 lucene/analysis/icu/src/resources/org/apache/lucene/analysis/icu/segmentation/Hebrew.brk delete mode 100644 lucene/analysis/icu/src/resources/org/apache/lucene/analysis/icu/segmentation/Lao.brk create mode 100644 lucene/analysis/icu/src/test/org/apache/lucene/analysis/icu/segmentation/TestICUTokenizerCJK.java delete mode 100644 lucene/analysis/icu/src/test/org/apache/lucene/analysis/icu/segmentation/TestLaoBreakIterator.java delete mode 100644 lucene/licenses/icu4j-49.1.jar.sha1 create mode 100644 lucene/licenses/icu4j-52.1.jar.sha1 delete mode 100644 solr/licenses/icu4j-49.1.jar.sha1 create mode 100644 solr/licenses/icu4j-52.1.jar.sha1 diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index f16bce3e712..4b3dae1b5bb 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -89,6 +89,8 @@ Build * LUCENE-5347: Upgrade forbidden-apis checker to version 1.4. (Uwe Schindler) +* LUCENE-4381: Upgrade analysis/icu to 52.1. (Robert Muir) + Bug fixes * LUCENE-5285: Improved highlighting of multi-valued fields with diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/charfilter/HTMLStripCharFilter.SUPPLEMENTARY.jflex-macro b/lucene/analysis/common/src/java/org/apache/lucene/analysis/charfilter/HTMLStripCharFilter.SUPPLEMENTARY.jflex-macro index f0a1e5ddaf2..f80ebd2de77 100755 --- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/charfilter/HTMLStripCharFilter.SUPPLEMENTARY.jflex-macro +++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/charfilter/HTMLStripCharFilter.SUPPLEMENTARY.jflex-macro @@ -14,7 +14,7 @@ * limitations under the License. */ -// Generated using ICU4J 49.1.0.0 +// Generated using ICU4J 52.1.0.0 // by org.apache.lucene.analysis.icu.GenerateHTMLStripCharFilterSupplementaryMacros diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/SUPPLEMENTARY.jflex-macro b/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/SUPPLEMENTARY.jflex-macro index efc0fe1dcd3..4ad87b7cb00 100644 --- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/SUPPLEMENTARY.jflex-macro +++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/SUPPLEMENTARY.jflex-macro @@ -14,7 +14,7 @@ * limitations under the License. */ -// Generated using ICU4J 49.1.0.0 +// Generated using ICU4J 52.1.0.0 // by org.apache.lucene.analysis.icu.GenerateJFlexSupplementaryMacros diff --git a/lucene/analysis/icu/src/data/uax29/Default.rbbi b/lucene/analysis/icu/src/data/uax29/Default.rbbi index 9dbab966632..6c6d1f9ef23 100644 --- a/lucene/analysis/icu/src/data/uax29/Default.rbbi +++ b/lucene/analysis/icu/src/data/uax29/Default.rbbi @@ -14,27 +14,52 @@ # See the License for the specific language governing permissions and # limitations under the License. # -# Default RBBI rules, based on UAX#29. +# This file is from ICU (with some small modifications, to avoid CJK dictionary break) # +# Copyright (C) 2002-2013, International Business Machines Corporation +# and others. All Rights Reserved. +# +# file: word.txt +# +# ICU Word Break Rules +# See Unicode Standard Annex #29. +# These rules are based on UAX #29 Revision 22 for Unicode Version 6.3 +# +# Note: Updates to word.txt will usually need to be merged into +# word_POSIX.txt also. + +############################################################################## +# +# Character class definitions from TR 29 +# +############################################################################## !!chain; + # # Character Class Definitions. # -$CR = [\p{Word_Break = CR}]; -$LF = [\p{Word_Break = LF}]; -$Newline = [\p{Word_Break = Newline}]; -$Extend = [\p{Word_Break = Extend}]; -$Format = [\p{Word_Break = Format}]; -$Katakana = [\p{Word_Break = Katakana}]; -$ALetter = [\p{Word_Break = ALetter}]; -$MidNumLet = [\p{Word_Break = MidNumLet}]; -$MidLetter = [\p{Word_Break = MidLetter}]; -$MidNum = [\p{Word_Break = MidNum}]; -$Numeric = [\p{Word_Break = Numeric}[[:Decomposition_Type=Wide:]&[:General_Category=Decimal_Number:]]]; -$ExtendNumLet = [\p{Word_Break = ExtendNumLet}]; +$CR = [\p{Word_Break = CR}]; +$LF = [\p{Word_Break = LF}]; +$Newline = [\p{Word_Break = Newline}]; +$Extend = [\p{Word_Break = Extend}]; +$Regional_Indicator = [\p{Word_Break = Regional_Indicator}]; +$Format = [\p{Word_Break = Format}]; +$Katakana = [\p{Word_Break = Katakana}]; +$Hebrew_Letter = [\p{Word_Break = Hebrew_Letter}]; +$ALetter = [\p{Word_Break = ALetter}]; +$Single_Quote = [\p{Word_Break = Single_Quote}]; +$Double_Quote = [\p{Word_Break = Double_Quote}]; +$MidNumLet = [\p{Word_Break = MidNumLet}]; +$MidLetter = [\p{Word_Break = MidLetter}]; +$MidNum = [\p{Word_Break = MidNum}]; +$Numeric = [\p{Word_Break = Numeric}[[:Decomposition_Type=Wide:]&[:General_Category=Decimal_Number:]]]; +$ExtendNumLet = [\p{Word_Break = ExtendNumLet}]; + +$Han = [:Han:]; +$Hiragana = [:Hiragana:]; # Dictionary character set, for triggering language-based break engines. Currently @@ -42,24 +67,34 @@ $ExtendNumLet = [\p{Word_Break = ExtendNumLet}]; # 5.0 or later as the definition of Complex_Context was corrected to include all # characters requiring dictionary break. -$dictionary = [:LineBreak = Complex_Context:]; $Control = [\p{Grapheme_Cluster_Break = Control}]; -$ALetterPlus = [$ALetter [$dictionary-$Extend-$Control]]; # Note: default ALetter does not - # include the dictionary characters. +$HangulSyllable = [\uac00-\ud7a3]; +$ComplexContext = [:LineBreak = Complex_Context:]; +$KanaKanji = [$Han $Hiragana $Katakana]; +$dictionaryCJK = [$Han $Hiragana $HangulSyllable]; +$dictionary = [$ComplexContext]; + +# leave CJK scripts out of ALetterPlus +$ALetterPlus = [$ALetter-$dictionaryCJK [$ComplexContext-$Extend-$Control]]; + # # Rules 4 Ignore Format and Extend characters, # except when they appear at the beginning of a region of text. # -$KatakanaEx = $Katakana ($Extend | $Format)*; -$ALetterEx = $ALetterPlus ($Extend | $Format)*; -$MidNumLetEx = $MidNumLet ($Extend | $Format)*; -$MidLetterEx = $MidLetter ($Extend | $Format)*; -$MidNumEx = $MidNum ($Extend | $Format)*; -$NumericEx = $Numeric ($Extend | $Format)*; -$ExtendNumLetEx = $ExtendNumLet ($Extend | $Format)*; +# TODO: check if handling of katakana in dictionary makes rules incorrect/void +$KatakanaEx = $Katakana ($Extend | $Format)*; +$Hebrew_LetterEx = $Hebrew_Letter ($Extend | $Format)*; +$ALetterEx = $ALetterPlus ($Extend | $Format)*; +$Single_QuoteEx = $Single_Quote ($Extend | $Format)*; +$Double_QuoteEx = $Double_Quote ($Extend | $Format)*; +$MidNumLetEx = $MidNumLet ($Extend | $Format)*; +$MidLetterEx = $MidLetter ($Extend | $Format)*; +$MidNumEx = $MidNum ($Extend | $Format)*; +$NumericEx = $Numeric ($Extend | $Format)*; +$ExtendNumLetEx = $ExtendNumLet ($Extend | $Format)*; +$Regional_IndicatorEx = $Regional_Indicator ($Extend | $Format)*; -$Hiragana = [\p{script=Hiragana}]; $Ideographic = [\p{Ideographic}]; $HiraganaEx = $Hiragana ($Extend | $Format)*; $IdeographicEx = $Ideographic ($Extend | $Format)*; @@ -77,23 +112,31 @@ $CR $LF; # of a region of Text. The rule here comes into play when the start of text # begins with a group of Format chars, or with a "word" consisting of a single # char that is not in any of the listed word break categories followed by -# format char(s). +# format char(s), or is not a CJK dictionary character. [^$CR $LF $Newline]? ($Extend | $Format)+; $NumericEx {100}; $ALetterEx {200}; +$HangulSyllable {200}; +$Hebrew_LetterEx{200}; $KatakanaEx {300}; # note: these status values override those from rule 5 -$HiraganaEx {300}; # by virtual of being numerically larger. +$HiraganaEx {300}; # by virtue of being numerically larger. $IdeographicEx {400}; # # # rule 5 # Do not break between most letters. # -$ALetterEx $ALetterEx {200}; +($ALetterEx | $Hebrew_LetterEx) ($ALetterEx | $Hebrew_LetterEx) {200}; # rule 6 and 7 -$ALetterEx ($MidLetterEx | $MidNumLetEx) $ALetterEx {200}; +($ALetterEx | $Hebrew_LetterEx) ($MidLetterEx | $MidNumLetEx | $Single_QuoteEx) ($ALetterEx | $Hebrew_LetterEx) {200}; + +# rule 7a +$Hebrew_LetterEx $Single_QuoteEx {200}; + +# rule 7b and 7c +$Hebrew_LetterEx $Double_QuoteEx $Hebrew_LetterEx {200}; # rule 8 @@ -101,27 +144,35 @@ $NumericEx $NumericEx {100}; # rule 9 -$ALetterEx $NumericEx {200}; +($ALetterEx | $Hebrew_LetterEx) $NumericEx {200}; # rule 10 -$NumericEx $ALetterEx {200}; +$NumericEx ($ALetterEx | $Hebrew_LetterEx) {200}; # rule 11 and 12 -$NumericEx ($MidNumEx | $MidNumLetEx) $NumericEx {100}; +$NumericEx ($MidNumEx | $MidNumLetEx | $Single_QuoteEx) $NumericEx {100}; # rule 13 - $KatakanaEx $KatakanaEx {300}; # rule 13a/b -$ALetterEx $ExtendNumLetEx {200}; # (13a) -$NumericEx $ExtendNumLetEx {100}; # (13a) -$KatakanaEx $ExtendNumLetEx {300}; # (13a) -$ExtendNumLetEx $ExtendNumLetEx {200}; # (13a) +$ALetterEx $ExtendNumLetEx {200}; # (13a) +$Hebrew_LetterEx $ExtendNumLetEx {200}; # (13a) +$NumericEx $ExtendNumLetEx {100}; # (13a) +$KatakanaEx $ExtendNumLetEx {300}; # (13a) +$ExtendNumLetEx $ExtendNumLetEx {200}; # (13a) -$ExtendNumLetEx $ALetterEx {200}; # (13b) -$ExtendNumLetEx $NumericEx {100}; # (13b) -$ExtendNumLetEx $KatakanaEx {300}; # (13b) +$ExtendNumLetEx $ALetterEx {200}; # (13b) +$ExtendNumLetEx $Hebrew_Letter {200}; # (13b) +$ExtendNumLetEx $NumericEx {100}; # (13b) +$ExtendNumLetEx $KatakanaEx {300}; # (13b) + +# rule 13c + +$Regional_IndicatorEx $Regional_IndicatorEx; + +# special handling for CJK characters: chain for later dictionary segmentation +$HangulSyllable $HangulSyllable {200}; diff --git a/lucene/analysis/icu/src/data/uax29/Hebrew.rbbi b/lucene/analysis/icu/src/data/uax29/Hebrew.rbbi deleted file mode 100644 index c238cbb4216..00000000000 --- a/lucene/analysis/icu/src/data/uax29/Hebrew.rbbi +++ /dev/null @@ -1,61 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# -# This is an example of rule tailoring for Hebrew. -# In this example the single-quote is added to the Extend category -# The double-quote is added to the MidLetter category. -# -!!chain; -$CR = [\p{Word_Break = CR}]; -$LF = [\p{Word_Break = LF}]; -$Newline = [\p{Word_Break = Newline}]; -$Extend = [\p{Word_Break = Extend}\u0027]; -$Format = [\p{Word_Break = Format}]; -$ALetter = [\p{Word_Break = ALetter}]; -$MidNumLet = [\p{Word_Break = MidNumLet}]; -$MidLetter = [\p{Word_Break = MidLetter}\u0022]; -$MidNum = [\p{Word_Break = MidNum}]; -$Numeric = [\p{Word_Break = Numeric}]; -$ExtendNumLet = [\p{Word_Break = ExtendNumLet}]; -$dictionary = [:LineBreak = Complex_Context:]; -$Control = [\p{Grapheme_Cluster_Break = Control}]; -$ALetterPlus = [$ALetter [$dictionary-$Extend-$Control]]; - -$ALetterEx = $ALetterPlus ($Extend | $Format)*; -$MidNumLetEx = $MidNumLet ($Extend | $Format)*; -$MidLetterEx = $MidLetter ($Extend | $Format)*; -$MidNumEx = $MidNum ($Extend | $Format)*; -$NumericEx = $Numeric ($Extend | $Format)*; -$ExtendNumLetEx = $ExtendNumLet ($Extend | $Format)*; - -!!forward; - -$CR $LF; -[^$CR $LF $Newline]? ($Extend | $Format)+; -$NumericEx {100}; -$ALetterEx {200}; -$ALetterEx $ALetterEx {200}; -$ALetterEx ($MidLetterEx | $MidNumLetEx) $ALetterEx {200}; -$NumericEx $NumericEx {100}; -$ALetterEx $NumericEx {200}; -$NumericEx $ALetterEx {200}; -$NumericEx ($MidNumEx | $MidNumLetEx) $NumericEx {100}; -$ALetterEx $ExtendNumLetEx {200}; -$NumericEx $ExtendNumLetEx {100}; -$ExtendNumLetEx $ExtendNumLetEx {200}; -$ExtendNumLetEx $ALetterEx {200}; -$ExtendNumLetEx $NumericEx {100}; diff --git a/lucene/analysis/icu/src/data/uax29/Lao.rbbi b/lucene/analysis/icu/src/data/uax29/Lao.rbbi deleted file mode 100644 index 8ce4f152efe..00000000000 --- a/lucene/analysis/icu/src/data/uax29/Lao.rbbi +++ /dev/null @@ -1,192 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Parses Lao text, with syllable as token. -# -# The definition of Lao syllable is based from: -# -# Syllabification of Lao Script for Line Breaking -# Phonpasit Phissamay, Valaxay Dalolay, Chitaphone Chanhsililath, Oulaiphone Silimasak, -# Sarmad Hussain, Nadir Durrani, Science Technology and Environment Agency, CRULP -# http://www.panl10n.net/english/final%20reports/pdf%20files/Laos/LAO06.pdf -# http://www.panl10n.net/Presentations/Cambodia/Phonpassit/LineBreakingAlgo.pdf -# -# NOTE: -# There are some ambiguities in Lao syllabification without additional processing, as mentioned in the paper. -# For this reason, this RBBI grammar really only works with LaoBreakIterator, as it does this additional work. -# -# Syllable structure, where X is the nuclear consonant: -# -# +----+ -# | X5 | -# +----+ -# | X4 | -# +----+----+----+----+----+----+----+-----+ -# | X0 | X1 | X | X6 | X7 | X8 | X9 | X10 | -# +----+----+----+----+----+----+----+-----+ -# | X2 | -# +----+ -# | X3 | -# +----+ -# -# X0 represents a vowel which occurs before the nuclear consonant. -# It can always define the beginning of syllable. -$X0 = [\u0EC0-\u0EC4]; -# X1 is a combination consonant which comes before the nuclear consonant, -# but only if nuclear consonant is one of {ງ ຍ ລ ວ ຼ ມ ນ ຣ} -$X1 = [\u0EAB]; -# X represents the nuclear consonant. -$X = [\u0E81-\u0EAE\u0EDC\u0EDD]; -# X2 is a combination consonant which comes after the nuclear consonant, -# which is placed under or next to the nuclear consonant. -$X2 = [\u0EBC\u0EA3\u0EA7\u0EA5]; -# X3 represents a vowel which occurs under the nuclear consonant. -$X3 = [\u0EB8\u0EB9]; -# X4 represents a vowel which occurs above the nuclear consonant. -$X4 = [\u0EB4-\u0EB7\u0ECD\u0EBB\u0EB1]; -# X5 represents a tone mark which occurs above the nuclear consonant or upper vowel. -$X5 = [\u0EC8-\u0ECB]; -# X6 represents a consonant vowel, which occurs after the nuclear consonant. -# It functions when the syllable doesn’t have any vowels. And it always exists with X8. -$X6 = [\u0EA7\u0EAD\u0EBD]; -# X7 represents a final vowel. -# However X7_1 always represents the end of syllable and it never exists with tone mark. -$X7 = [\u0EB0\u0EB2\u0EB3]; -# X8 represents an alternate consonant. -$X8 = [\u0E81\u0E87\u0E8D\u0E94\u0E99\u0EA1\u0E9A\u0EA7]; -# X9 represents alternate consonants to pronounce foreign terms, it always exist with X10_3. -$X9 = [\u0E88\u0EAA\u0E8A\u0E9E\u0E9F\u0EA5]; -# X10 represents a sign mark. -# It always occurs at the end of a syllable, but mostly people keep it separate from syllable. -$X10 = [\u0EAF\u0EC6\u0ECC]; - -# Section 1 -$X0_1 = [\u0EC0]; -$X4_1_2 = [\u0EB4\u0EB5]; -$X4_3_4 = [\u0EB6\u0EB7]; -$X4_6 = [\u0EBB]; -$X4_7 = [\u0EB1]; -$X6_2 = [\u0EAD]; -$X6_3 = [\u0EBD]; -$X7_1 = [\u0EB0]; -$X7_2 = [\u0EB2]; -$X10_1 = [\u0EAF]; -$X10_2 = [\u0EC6]; -$X10_3 = [\u0ECC]; - -$Rule1_1 = $X0_1 ($X1)? $X ($X2)? ($X5)? ($X8)? ($X9 $X10_3)? ($X10_2)? ($X10_1)?; -$Rule1_2 = $X0_1 ($X1)? $X ($X2)? $X4_1_2 ($X5)? ($X8)? ($X9 $X10_3)? ($X10_2)? ($X10_1)?; -$Rule1_3 = $X0_1 ($X1)? $X ($X2)? $X4_3_4 ($X5)? $X6_2 ($X8)? ($X9 $X10_3)? ($X10_2)? ($X10_1)?; -$Rule1_4 = $X0_1 ($X1)? $X ($X2)? ($X7_2)? $X7_1; -$Rule1_5 = $X0_1 ($X1)? $X ($X2)? $X4_6 ($X5)? $X7_2 ($X9 $X10_3)? ($X10_2)? ($X10_1)?; -$Rule1_6 = $X0_1 ($X1)? $X ($X2)? $X4_7 ($X5)? $X8 ($X9 $X10_3)? ($X10_2)? ($X10_1)?; -$Rule1_7 = $X0_1 ($X1)? $X ($X2)? ($X4_7)? ($X5)? $X6_3 ($X9 $X10_3)? ($X10_2)? ($X10_1)?; - -$Rule1 = ($Rule1_1 | $Rule1_2 | $Rule1_3 | $Rule1_4 | $Rule1_5 | $Rule1_6 | $Rule1_7); - -# Section 2 -$X0_2 = [\u0EC1]; - -$Rule2_1 = $X0_2 ($X1)? $X ($X2)? ($X5)? ($X6)? ($X8)? ($X9 $X10_3)? ($X10_2)? ($X10_1)?; -$Rule2_2 = $X0_2 ($X1)? $X ($X2)? $X7_1; -$Rule2_3 = $X0_2 ($X1)? $X ($X2)? $X4_7 ($X5)? $X8 ($X9 $X10_3)? ($X10_2)? ($X10_1)?; - -$Rule2 = ($Rule2_1 | $Rule2_2 | $Rule2_3); - -# Section 3 -$X0_3 = [\u0EC2]; -$X8_3 = [\u0E8D]; -$X8_8 = [\u0EA7]; - -$Rule3_1 = $X0_3 ($X1)? $X ($X2)? ($X5)? ($X8)? ($X9 $X10_3)? ($X10_2)? ($X10_1)?; -$Rule3_2 = $X0_3 ($X1)? $X ($X2)? $X7_1; -$Rule3_3 = $X0_3 ($X1)? $X ($X2)? $X4_7 ($X5)? ($X8_3 | $X8_8); - -$Rule3 = ($Rule3_1 | $Rule3_2 | $Rule3_3); - -# Section 4 -$X0_4 = [\u0EC4]; -$X6_1 = [\u0EA7]; - -$Rule4 = $X0_4 ($X1)? $X ($X2)? ($X5)? ($X6_1)? ($X9 $X10_3)? ($X10_2)? ($X10_1)?; - -# Section 5 -$X0_5 = [\u0EC3]; - -$Rule5 = $X0_5 ($X1)? $X ($X2)? ($X5)? ($X6_1)? ($X9 $X10_3)? ($X10_2)? ($X10_1)?; - -# Section 6 -$Rule6 = ($X1)? $X ($X2)? $X3 ($X5)? ($X8)? ($X9 $X10_3)? ($X10_2)? ($X10_1)?; - -# Section 7 -$X4_1_4 = [\u0EB4-\u0EB7]; - -$Rule7 = ($X1)? $X ($X2)? $X4_1_4 ($X5)? ($X8)? ($X9 $X10_3)? ($X10_2)? ($X10_1)?; - -# Section 8 -$X4_5 = [\u0ECD]; - -$Rule8 = ($X1)? $X ($X2)? $X4_5 ($X5)? ($X7_2)? ($X9 $X10_3)? ($X10_2)? ($X10_1)?; - -# Section 9 - -$Rule9_1 = ($X1)? $X ($X2)? $X4_6 ($X5)? $X8 ($X9 $X10_3)? ($X10_2)? ($X10_1)?; -$Rule9_2 = ($X1)? $X ($X2)? $X4_6 ($X5)? $X6_1 $X7_1; - -$Rule9 = ($Rule9_1 | $Rule9_2); - -# Section 10 -$Rule10 = ($X1)? $X ($X2)? $X4_7 ($X5)? ($X6_1)? $X8 ($X9 $X10_3)? ($X10_2)? ($X10_1)?; - -# Section 11 -$Rule11 = ($X1)? $X ($X2)? ($X5)? $X6 $X8 ($X9 $X10_3)? ($X10_2)? ($X10_1)?; - -# Section 12 -$Rule12 = ($X1)? $X ($X2)? ($X5)? $X7_1; - -# Section 13 -$Rule13 = ($X1)? $X ($X2)? ($X5)? $X7_2 ($X8)? ($X9 $X10_3)? ($X10_2)? ($X10_1)?; - -# Section 14 -$X7_3 = [\u0EB3]; - -$Rule14 = ($X1)? $X ($X2)? ($X5)? $X7_3 ($X9 $X10_3)? ($X10_2)? ($X10_1)?; - -$LaoSyllableEx = ($Rule1 | $Rule2 | $Rule3 | $Rule4 | $Rule5 | $Rule6 | $Rule7 | $Rule8 | $Rule9 | $Rule10 | $Rule11 | $Rule12 | $Rule13 | $Rule14); - -$WordJoin = [:Line_Break=Word_Joiner:]; - -$LaoJoinedSyllableEx = $LaoSyllableEx ($WordJoin $LaoSyllableEx)*; - -# -# default numerical definitions -# -$Extend = [\p{Word_Break = Extend}]; -$Format = [\p{Word_Break = Format}]; -$MidNumLet = [\p{Word_Break = MidNumLet}]; -$MidNum = [\p{Word_Break = MidNum}]; -$Numeric = [\p{Word_Break = Numeric}]; -$ExtendNumLet = [\p{Word_Break = ExtendNumLet}]; -$MidNumLetEx = $MidNumLet ($Extend | $Format)*; -$MidNumEx = $MidNum ($Extend | $Format)*; -$NumericEx = $Numeric ($Extend | $Format)*; -$ExtendNumLetEx = $ExtendNumLet ($Extend | $Format)*; - -!!forward; - -$LaoJoinedSyllableEx {200}; -# default numeric rules -$NumericEx $ExtendNumLetEx? (($MidNumEx | $MidNumLetEx)? $NumericEx $ExtendNumLetEx?)* {100}; diff --git a/lucene/analysis/icu/src/data/utr30/BasicFoldings.txt b/lucene/analysis/icu/src/data/utr30/BasicFoldings.txt index 44a1d5793d9..ed8b3a70040 100644 --- a/lucene/analysis/icu/src/data/utr30/BasicFoldings.txt +++ b/lucene/analysis/icu/src/data/utr30/BasicFoldings.txt @@ -78,7 +78,6 @@ FF0D>002D ## Space Folding # Rule: [[:Zs:] - [:Changes_When_NFKC_Casefolded=Yes:] - [\u0020]] > 0020 1680>0020 -180E>0020 ## Spacing Accents folding (done by kd) diff --git a/lucene/analysis/icu/src/data/utr30/nfc.txt b/lucene/analysis/icu/src/data/utr30/nfc.txt index d251d531b1c..6ecdfd3482c 100644 --- a/lucene/analysis/icu/src/data/utr30/nfc.txt +++ b/lucene/analysis/icu/src/data/utr30/nfc.txt @@ -1,4 +1,4 @@ -# Copyright (C) 1999-2012, International Business Machines +# Copyright (C) 1999-2013, International Business Machines # Corporation and others. All Rights Reserved. # # file name: nfc.txt @@ -7,7 +7,7 @@ # # Complete data for Unicode NFC normalization. -* Unicode 6.1.0 +* Unicode 6.3.0 # Canonical_Combining_Class (ccc) values 0300..0314:230 diff --git a/lucene/analysis/icu/src/data/utr30/nfkc.txt b/lucene/analysis/icu/src/data/utr30/nfkc.txt index fccbbacca16..2cafb0d8853 100644 --- a/lucene/analysis/icu/src/data/utr30/nfkc.txt +++ b/lucene/analysis/icu/src/data/utr30/nfkc.txt @@ -1,4 +1,4 @@ -# Copyright (C) 1999-2012, International Business Machines +# Copyright (C) 1999-2013, International Business Machines # Corporation and others. All Rights Reserved. # # file name: nfkc.txt @@ -11,7 +11,7 @@ # to NFKC one-way mappings. # Use this file as the second gennorm2 input file after nfc.txt. -* Unicode 6.1.0 +* Unicode 6.3.0 00A0>0020 00A8>0020 0308 diff --git a/lucene/analysis/icu/src/data/utr30/nfkc_cf.txt b/lucene/analysis/icu/src/data/utr30/nfkc_cf.txt index 1b043d17a6a..0ac6134f20c 100644 --- a/lucene/analysis/icu/src/data/utr30/nfkc_cf.txt +++ b/lucene/analysis/icu/src/data/utr30/nfkc_cf.txt @@ -1,5 +1,5 @@ # Unicode Character Database -# Copyright (c) 1991-2012 Unicode, Inc. +# Copyright (c) 1991-2013 Unicode, Inc. # For terms of use, see http://www.unicode.org/terms_of_use.html # For documentation, see http://www.unicode.org/reports/tr44/ # @@ -12,7 +12,7 @@ # and reformatted into syntax for the gennorm2 Normalizer2 data generator tool. # Use this file as the third gennorm2 input file after nfc.txt and nfkc.txt. -* Unicode 6.1.0 +* Unicode 6.3.0 0041>0061 0042>0062 @@ -537,6 +537,7 @@ 0555>0585 0556>0586 0587>0565 0582 +061C> 0675>0627 0674 0676>0648 0674 0677>06C7 0674 @@ -627,7 +628,7 @@ 10FC>10DC 115F..1160> 17B4..17B5> -180B..180D> +180B..180E> 1D2C>0061 1D2D>00E6 1D2E>0062 diff --git a/lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/segmentation/BreakIteratorWrapper.java b/lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/segmentation/BreakIteratorWrapper.java index 654d1adc7c2..9a8a8070b84 100644 --- a/lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/segmentation/BreakIteratorWrapper.java +++ b/lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/segmentation/BreakIteratorWrapper.java @@ -21,7 +21,6 @@ import java.text.CharacterIterator; import com.ibm.icu.lang.UCharacter; import com.ibm.icu.text.BreakIterator; -import com.ibm.icu.text.DictionaryBasedBreakIterator; import com.ibm.icu.text.RuleBasedBreakIterator; import com.ibm.icu.text.UTF16; @@ -60,15 +59,12 @@ abstract class BreakIteratorWrapper { } /** - * If its a DictionaryBasedBreakIterator, it doesn't return rulestatus, so - * treat it like a generic BreakIterator If its any other - * RuleBasedBreakIterator, the rule status can be used for token type. If its + * If its a RuleBasedBreakIterator, the rule status can be used for token type. If its * any other BreakIterator, the rulestatus method is not available, so treat * it like a generic BreakIterator. */ static BreakIteratorWrapper wrap(BreakIterator breakIterator) { - if (breakIterator instanceof RuleBasedBreakIterator - && !(breakIterator instanceof DictionaryBasedBreakIterator)) + if (breakIterator instanceof RuleBasedBreakIterator) return new RBBIWrapper((RuleBasedBreakIterator) breakIterator); else return new BIWrapper(breakIterator); diff --git a/lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/segmentation/CompositeBreakIterator.java b/lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/segmentation/CompositeBreakIterator.java index 5f15880c184..51ff1647f53 100644 --- a/lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/segmentation/CompositeBreakIterator.java +++ b/lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/segmentation/CompositeBreakIterator.java @@ -41,12 +41,13 @@ final class CompositeBreakIterator { private final BreakIteratorWrapper wordBreakers[] = new BreakIteratorWrapper[UScript.CODE_LIMIT]; private BreakIteratorWrapper rbbi; - private final ScriptIterator scriptIterator = new ScriptIterator(); + private final ScriptIterator scriptIterator; private char text[]; CompositeBreakIterator(ICUTokenizerConfig config) { this.config = config; + this.scriptIterator = new ScriptIterator(config.combineCJ()); } /** diff --git a/lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/segmentation/DefaultICUTokenizerConfig.java b/lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/segmentation/DefaultICUTokenizerConfig.java index f7ac9949692..bb41f46a295 100644 --- a/lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/segmentation/DefaultICUTokenizerConfig.java +++ b/lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/segmentation/DefaultICUTokenizerConfig.java @@ -35,12 +35,9 @@ import com.ibm.icu.util.ULocale; * ({@link BreakIterator#getWordInstance(ULocale) BreakIterator.getWordInstance(ULocale.ROOT)}), * but with the following tailorings: *
      - *
    • Thai text is broken into words with a - * {@link com.ibm.icu.text.DictionaryBasedBreakIterator} - *
    • Lao, Myanmar, and Khmer text is broken into syllables + *
    • Thai, Lao, and CJK text is broken into words with a dictionary. + *
    • Myanmar, and Khmer text is broken into syllables * based on custom BreakIterator rules. - *
    • Hebrew text has custom tailorings to handle special cases - * involving punctuation. *
    * @lucene.experimental */ @@ -62,34 +59,44 @@ public class DefaultICUTokenizerConfig extends ICUTokenizerConfig { * the default breakiterators in use. these can be expensive to * instantiate, cheap to clone. */ - private static final BreakIterator rootBreakIterator = + // we keep the cjk breaking separate, thats because it cannot be customized (because dictionary + // is only triggered when kind = WORD, but kind = LINE by default and we have no non-evil way to change it) + private static final BreakIterator cjkBreakIterator = BreakIterator.getWordInstance(ULocale.ROOT); + // the same as ROOT, except no dictionary segmentation for cjk + private static final BreakIterator defaultBreakIterator = readBreakIterator("Default.brk"); - private static final BreakIterator thaiBreakIterator = - BreakIterator.getWordInstance(new ULocale("th_TH")); - private static final BreakIterator hebrewBreakIterator = - readBreakIterator("Hebrew.brk"); private static final BreakIterator khmerBreakIterator = readBreakIterator("Khmer.brk"); - private static final BreakIterator laoBreakIterator = - new LaoBreakIterator(readBreakIterator("Lao.brk")); private static final BreakIterator myanmarBreakIterator = readBreakIterator("Myanmar.brk"); + // TODO: deprecate this boolean? you only care if you are doing super-expert stuff... + private final boolean cjkAsWords; + /** * Creates a new config. This object is lightweight, but the first * time the class is referenced, breakiterators will be initialized. + * @param cjkAsWords true if cjk text should undergo dictionary-based segmentation, + * otherwise text will be segmented according to UAX#29 defaults. + * If this is true, all Han+Hiragana+Katakana words will be tagged as + * IDEOGRAPHIC. */ - public DefaultICUTokenizerConfig() {} + public DefaultICUTokenizerConfig(boolean cjkAsWords) { + this.cjkAsWords = cjkAsWords; + } + + @Override + public boolean combineCJ() { + return cjkAsWords; + } @Override public BreakIterator getBreakIterator(int script) { switch(script) { - case UScript.THAI: return (BreakIterator)thaiBreakIterator.clone(); - case UScript.HEBREW: return (BreakIterator)hebrewBreakIterator.clone(); case UScript.KHMER: return (BreakIterator)khmerBreakIterator.clone(); - case UScript.LAO: return (BreakIterator)laoBreakIterator.clone(); case UScript.MYANMAR: return (BreakIterator)myanmarBreakIterator.clone(); - default: return (BreakIterator)rootBreakIterator.clone(); + case UScript.JAPANESE: return (BreakIterator)cjkBreakIterator.clone(); + default: return (BreakIterator)defaultBreakIterator.clone(); } } diff --git a/lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/segmentation/ICUTokenizer.java b/lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/segmentation/ICUTokenizer.java index 24a6fdea108..68b16a6bcee 100644 --- a/lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/segmentation/ICUTokenizer.java +++ b/lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/segmentation/ICUTokenizer.java @@ -68,7 +68,7 @@ public final class ICUTokenizer extends Tokenizer { * @see DefaultICUTokenizerConfig */ public ICUTokenizer(Reader input) { - this(input, new DefaultICUTokenizerConfig()); + this(input, new DefaultICUTokenizerConfig(true)); } /** diff --git a/lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/segmentation/ICUTokenizerConfig.java b/lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/segmentation/ICUTokenizerConfig.java index 550db3c8de8..c972d0c1205 100644 --- a/lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/segmentation/ICUTokenizerConfig.java +++ b/lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/segmentation/ICUTokenizerConfig.java @@ -36,4 +36,6 @@ public abstract class ICUTokenizerConfig { /** Return a token type value for a given script and BreakIterator * rule status. */ public abstract String getType(int script, int ruleStatus); + /** true if Han, Hiragana, and Katakana scripts should all be returned as Japanese */ + public abstract boolean combineCJ(); } diff --git a/lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/segmentation/ICUTokenizerFactory.java b/lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/segmentation/ICUTokenizerFactory.java index fecbb2253e0..81507b31309 100644 --- a/lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/segmentation/ICUTokenizerFactory.java +++ b/lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/segmentation/ICUTokenizerFactory.java @@ -70,7 +70,7 @@ import com.ibm.icu.text.RuleBasedBreakIterator; *
      * <fieldType name="text_icu_custom" class="solr.TextField" positionIncrementGap="100">
      *   <analyzer>
    - *     <tokenizer class="solr.ICUTokenizerFactory"
    + *     <tokenizer class="solr.ICUTokenizerFactory" cjkAsWords="true"
      *                rulefiles="Latn:my.Latin.rules.rbbi,Cyrl:my.Cyrillic.rules.rbbi"/>
      *   </analyzer>
      * </fieldType>
    @@ -79,6 +79,7 @@ public class ICUTokenizerFactory extends TokenizerFactory implements ResourceLoa static final String RULEFILES = "rulefiles"; private final Map tailored; private ICUTokenizerConfig config; + private final boolean cjkAsWords; /** Creates a new ICUTokenizerFactory */ public ICUTokenizerFactory(Map args) { @@ -94,6 +95,7 @@ public class ICUTokenizerFactory extends TokenizerFactory implements ResourceLoa tailored.put(UCharacter.getPropertyValueEnum(UProperty.SCRIPT, scriptCode), resourcePath); } } + cjkAsWords = getBoolean(args, "cjkAsWords", true); if (!args.isEmpty()) { throw new IllegalArgumentException("Unknown parameters: " + args); } @@ -103,7 +105,7 @@ public class ICUTokenizerFactory extends TokenizerFactory implements ResourceLoa public void inform(ResourceLoader loader) throws IOException { assert tailored != null : "init must be called first!"; if (tailored.isEmpty()) { - config = new DefaultICUTokenizerConfig(); + config = new DefaultICUTokenizerConfig(cjkAsWords); } else { final BreakIterator breakers[] = new BreakIterator[UScript.CODE_LIMIT]; for (Map.Entry entry : tailored.entrySet()) { @@ -111,7 +113,7 @@ public class ICUTokenizerFactory extends TokenizerFactory implements ResourceLoa String resourcePath = entry.getValue(); breakers[code] = parseRules(resourcePath, loader); } - config = new DefaultICUTokenizerConfig() { + config = new DefaultICUTokenizerConfig(cjkAsWords) { @Override public BreakIterator getBreakIterator(int script) { diff --git a/lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/segmentation/LaoBreakIterator.java b/lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/segmentation/LaoBreakIterator.java deleted file mode 100644 index 16e56a4f8b3..00000000000 --- a/lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/segmentation/LaoBreakIterator.java +++ /dev/null @@ -1,230 +0,0 @@ -package org.apache.lucene.analysis.icu.segmentation; - -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import java.text.CharacterIterator; - -import com.ibm.icu.lang.UCharacter; -import com.ibm.icu.text.BreakIterator; -import com.ibm.icu.text.RuleBasedBreakIterator; -import com.ibm.icu.text.UnicodeSet; - -/** - * Syllable iterator for Lao text. - *

    - * This breaks Lao text into syllables according to: - * Syllabification of Lao Script for Line Breaking - * Phonpasit Phissamay, Valaxay Dalolay, Chitaphone Chanhsililath, Oulaiphone Silimasak, - * Sarmad Hussain, Nadir Durrani, Science Technology and Environment Agency, CRULP. - *

      - *
    • http://www.panl10n.net/english/final%20reports/pdf%20files/Laos/LAO06.pdf - *
    • http://www.panl10n.net/Presentations/Cambodia/Phonpassit/LineBreakingAlgo.pdf - *
    - *

    - * Most work is accomplished with RBBI rules, however some additional special logic is needed - * that cannot be coded in a grammar, and this is implemented here. - *

    - * For example, what appears to be a final consonant might instead be part of the next syllable. - * Rules match in a greedy fashion, leaving an illegal sequence that matches no rules. - *

    - * Take for instance the text ກວ່າດອກ - * The first rule greedily matches ກວ່າດ, but then ອກ is encountered, which is illegal. - * What LaoBreakIterator does, according to the paper: - *

      - *
    1. backtrack and remove the ດ from the last syllable, placing it on the current syllable. - *
    2. verify the modified previous syllable (ກວ່າ ) is still legal. - *
    3. verify the modified current syllable (ດອກ) is now legal. - *
    4. If 2 or 3 fails, then restore the ດ to the last syllable and skip the current character. - *
    - *

    - * Finally, LaoBreakIterator also takes care of the second concern mentioned in the paper. - * This is the issue of combining marks being in the wrong order (typos). - * @lucene.experimental - */ -public class LaoBreakIterator extends BreakIterator { - RuleBasedBreakIterator rules; - CharArrayIterator text; - - CharArrayIterator working = new CharArrayIterator(); - int workingOffset = 0; - - CharArrayIterator verifyText = new CharArrayIterator(); - RuleBasedBreakIterator verify; - - private static final UnicodeSet laoSet; - static { - laoSet = new UnicodeSet("[:Lao:]"); - laoSet.compact(); - laoSet.freeze(); - } - - /** - * Creates a new iterator, performing the backtracking verification - * across the provided rules. - */ - public LaoBreakIterator(RuleBasedBreakIterator rules) { - this.rules = (RuleBasedBreakIterator) rules.clone(); - this.verify = (RuleBasedBreakIterator) rules.clone(); - } - - @Override - public int current() { - int current = rules.current(); - return current == BreakIterator.DONE ? BreakIterator.DONE : workingOffset + current; - } - - @Override - public int first() { - working.setText(this.text.getText(), this.text.getStart(), this.text.getLength()); - rules.setText(working); - workingOffset = 0; - int first = rules.first(); - return first == BreakIterator.DONE ? BreakIterator.DONE : workingOffset + first; - } - - @Override - public int following(int offset) { - throw new UnsupportedOperationException(); - } - - @Override - public CharacterIterator getText() { - return text; - } - - @Override - public int last() { - throw new UnsupportedOperationException(); - } - - @Override - public int next() { - int current = current(); - int next = rules.next(); - if (next == BreakIterator.DONE) - return next; - else - next += workingOffset; - - char c = working.current(); - int following = rules.next(); // lookahead - if (following != BreakIterator.DONE) { - following += workingOffset; - if (rules.getRuleStatus() == 0 && laoSet.contains(c) && verifyPushBack(current, next)) { - workingOffset = next - 1; - working.setText(text.getText(), text.getStart() + workingOffset, text.getLength() - workingOffset); - return next - 1; - } - rules.previous(); // undo the lookahead - } - - return next; - } - - @Override - public int next(int n) { - if (n < 0) - throw new UnsupportedOperationException("Backwards traversal is unsupported"); - - int result = current(); - while (n > 0) { - result = next(); - --n; - } - return result; - } - - @Override - public int previous() { - throw new UnsupportedOperationException("Backwards traversal is unsupported"); - } - - @Override - public void setText(CharacterIterator text) { - if (!(text instanceof CharArrayIterator)) - throw new UnsupportedOperationException("unsupported CharacterIterator"); - this.text = (CharArrayIterator) text; - ccReorder(this.text.getText(), this.text.getStart(), this.text.getLength()); - working.setText(this.text.getText(), this.text.getStart(), this.text.getLength()); - rules.setText(working); - workingOffset = 0; - } - - @Override - public void setText(String newText) { - CharArrayIterator ci = new CharArrayIterator(); - ci.setText(newText.toCharArray(), 0, newText.length()); - setText(ci); - } - - private boolean verifyPushBack(int current, int next) { - int shortenedSyllable = next - current - 1; - - verifyText.setText(text.getText(), text.getStart() + current, shortenedSyllable); - verify.setText(verifyText); - if (verify.next() != shortenedSyllable || verify.getRuleStatus() == 0) - return false; - - - verifyText.setText(text.getText(), text.getStart() + next - 1, text.getLength() - next + 1); - verify.setText(verifyText); - - return (verify.next() != BreakIterator.DONE && verify.getRuleStatus() != 0); - } - - // TODO: only bubblesort around runs of combining marks, instead of the entire text. - private void ccReorder(char[] text, int start, int length) { - boolean reordered; - do { - int prevCC = 0; - reordered = false; - for (int i = start; i < start + length; i++) { - final char c = text[i]; - final int cc = UCharacter.getCombiningClass(c); - if (cc > 0 && cc < prevCC) { - // swap - text[i] = text[i - 1]; - text[i - 1] = c; - reordered = true; - } else { - prevCC = cc; - } - } - - } while (reordered == true); - } - - /** - * Clone method. Creates another LaoBreakIterator with the same behavior - * and current state as this one. - * @return The clone. - */ - @Override - public LaoBreakIterator clone() { - LaoBreakIterator other = (LaoBreakIterator) super.clone(); - other.rules = (RuleBasedBreakIterator) rules.clone(); - other.verify = (RuleBasedBreakIterator) verify.clone(); - if (text != null) - other.text = text.clone(); - if (working != null) - other.working = working.clone(); - if (verifyText != null) - other.verifyText = verifyText.clone(); - return other; - } -} diff --git a/lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/segmentation/ScriptIterator.java b/lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/segmentation/ScriptIterator.java index 779dc9ba404..f573b192bce 100644 --- a/lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/segmentation/ScriptIterator.java +++ b/lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/segmentation/ScriptIterator.java @@ -59,6 +59,15 @@ final class ScriptIterator { private int scriptStart; private int scriptLimit; private int scriptCode; + + private final boolean combineCJ; + + /** + * @param combineCJ if true: Han,Hiragana,Katakana will all return as {@link UScript#JAPANESE} + */ + ScriptIterator(boolean combineCJ) { + this.combineCJ = combineCJ; + } /** * Get the start of this script run @@ -162,10 +171,24 @@ final class ScriptIterator { } /** fast version of UScript.getScript(). Basic Latin is an array lookup */ - private static int getScript(int codepoint) { - if (0 <= codepoint && codepoint < basicLatin.length) + private int getScript(int codepoint) { + if (0 <= codepoint && codepoint < basicLatin.length) { return basicLatin[codepoint]; - else - return UScript.getScript(codepoint); + } else { + int script = UScript.getScript(codepoint); + if (combineCJ) { + if (script == UScript.HAN || script == UScript.HIRAGANA || script == UScript.KATAKANA) { + return UScript.JAPANESE; + } else if (codepoint >= 0xFF10 && codepoint <= 0xFF19) { + // when using CJK dictionary breaking, don't let full width numbers go to it, otherwise + // they are treated as punctuation. we currently have no cleaner way to fix this! + return UScript.LATIN; + } else { + return script; + } + } else { + return script; + } + } } } diff --git a/lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/tokenattributes/ScriptAttributeImpl.java b/lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/tokenattributes/ScriptAttributeImpl.java index 9e5ac475979..e9d911964da 100644 --- a/lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/tokenattributes/ScriptAttributeImpl.java +++ b/lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/tokenattributes/ScriptAttributeImpl.java @@ -84,6 +84,10 @@ public class ScriptAttributeImpl extends AttributeImpl implements ScriptAttribut @Override public void reflectWith(AttributeReflector reflector) { - reflector.reflect(ScriptAttribute.class, "script", getName()); + // when wordbreaking CJK, we use the 15924 code Japanese (Han+Hiragana+Katakana) to + // mark runs of Chinese/Japanese. our use is correct (as for chinese Han is a subset), + // but this is just to help prevent confusion. + String name = code == UScript.JAPANESE ? "Chinese/Japanese" : getName(); + reflector.reflect(ScriptAttribute.class, "script", name); } } diff --git a/lucene/analysis/icu/src/java/overview.html b/lucene/analysis/icu/src/java/overview.html index a379f55963e..0c123bfa5d9 100644 --- a/lucene/analysis/icu/src/java/overview.html +++ b/lucene/analysis/icu/src/java/overview.html @@ -353,7 +353,7 @@ and

    Backwards Compatibility

    This module exists to provide up-to-date Unicode functionality that supports -the most recent version of Unicode (currently 6.1). However, some users who wish +the most recent version of Unicode (currently 6.3). However, some users who wish for stronger backwards compatibility can restrict {@link org.apache.lucene.analysis.icu.ICUNormalizer2Filter} to operate on only a specific Unicode Version by using a {@link com.ibm.icu.text.FilteredNormalizer2}. diff --git a/lucene/analysis/icu/src/resources/org/apache/lucene/analysis/icu/segmentation/Default.brk b/lucene/analysis/icu/src/resources/org/apache/lucene/analysis/icu/segmentation/Default.brk index 3972d1cd7d433c2b0d0a13f79191e08790ee1a06..e4b35d24e803a362f589793ffb76f05eb3d4f7ee 100644 GIT binary patch literal 32736 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 P>ZWHzxK5hnMqd99aNyr_ literal 28152 zcmeHPdyG}Z86P9gCL5Dsk>-w zwS@E!V=%EMt+vtD8fz*gHqpi=HnFi*6DzSKHrB*e6CbtJe&2leyWh;5nS0LJ#b6We z5VF@Hz_khX-WM*<-ayq{iwN!+WAql|f73%2lCSwLsBA>C2}+&c`%)AAJNP zip69rHC|0nJ;3T!eJY053zvRri+0~KnFymv>M%7Ks-Hlc3|IB5A5^BQX;9h2fnt4+ zP)hr#vb8eT7HNe^4s})f0-`N&9DYrQStvk^*O9d>6wDgVTYK(m%=?jRCs%p-AVD@|U3Sf(>IqwDi$#Cgc&<9F+&ii0(O@&L(xi;(eHWP#s zq0NL#zqAkEE-}~cBv_NZaMgREkHetNgiF7)kE+ZkL*CfBTcDIPp8|Visy?N7wO7qY zKiKwadw{7G)l~2>87}<_TA-Apng;t2_hR)PWQ+2yt=dsX;QrQE)sA8x)75l{YPu0s zm5(EFxALVkud410H3O>K-YvmenJ3&#SR<3+k{9|I#r;8h6|^y`x`FmZ8`loP0e-Yn z;}$A))MI1+GIrnCzmNUr*!Ln8#KM4Fs;>Y7B<7a?A z7rzw08owU@D}Fy2lN8B>WJ2d!cujIua&2;B^1Y}( zxg+ZBWMR}H*$J|{le?1pfbNFtr(pLB)Jz_SObyLYKY22FM(aP9yp+6}yq>%Te*c|( zlxFD!&f~7;n-|uc1$)e z`$E*8eF+hpwCpsnI;)Ar0nzP`T2T*YnSBlBV`6+MiF!XXHo2 zXl{OTx;(-yc6WO75 zr~?0w704gVf0;kpy0i78*6!B*t)Dk&kBV--XLPNzmv~Pdq6f7C{^!;FDb3#lC+4&H zpYy-sde2|YU-Pc}sc;VW=WoFER{l=@VUZT&i%FzeOv6w6$uq@3@u{e%IJP)(bgL)d zlRRC_FHVP5q|age%!GaTT&$~DoJ$lwx6Xyy+7ki4Q2&;JZ0ALDwyH`A4yj=W^k&AzD&qFbux8ZufHKtWW z{jI*%xYjgZC0a+dJ`?p8Z-aI#Y8CGk@3iK&PVgXF(X@)zsjbsm=d_lzzE!2`lebp- zxWet<|xA83ESOW*R&YYj91(kaqnTZ@ zMGV4`cRS`#h20p%iY2szh0i_w{hk_gh~mF!z@9%V(Pey_`mKCi_l(6cp1$ZEF?-u9 z*~Sl#(8~6M=b6bNRIW5ikmHMkykM?XJG@7G4M!ysGm>zhe2P`~o*$=s%;9{y`?95F z&nU;}Y5uC#iH*i1Mm1-W`%F=NdGlveN74Th=6>W~IYX zxLRd2(!i{JYtB8<%472F@@bW!H$?V%Wu7a=G0lN!VBOqIPzQZ8MGdl(cUglJ2_dqT zFJICVgmTZ9FKe+i`SHK|^2Nx>mJ!VJPqN_1IR^AAQi_7TN*y^mU%rS$7A_83u`k9I z%9$_~iP>|dG&Z@Eg*(4e0p2yJSDs^zlPG%TD*5uYwaX*QmJv)^t`AEQ1^seP%=i1R z%7E57V^Jj~H}S$a?3rVbXt-x;5}y4|=v-xvp2tinf5sx4a!ru$&zrr3DEdV_J2uI; zEU`8Ha+6D*-F3$KF?Dm2sNBd!Vn)IqnVK@Q@0Xig^yfSGxKc#@@tU!64JqEx{9tUR zmEAWZuirUx*`x;ar*y2o$FOP(cC9Fx89!ac$Y%Wa7{XDmUU8w2Ml+3^fgWXLx; z#HCoey?51H*f+{HQQJ>kXf&Ofj>y3_bWk7kD$fE$P#IqMZuZ3sNmy$7WC}gf%IhMp`GxtM~KWT%UOps{BpKtDn6?9MVGDXQADPd zTBVPg-CC8s$o(iHcYCPs^2*~nIzB6orYu7aNlC_YoDhZ*5?o;fmN{)J-8rE44I1{3$=Y_p?sL1UeYj@80@M@B^hdt0^TTQ*OlLmTh zSYN4DI|DoFt|Lzd?I$^pq&jb%L$7acs`5AG-6A&if_H#oq1N`n+O1^BIhd z?|mjRLMdi0zpA;vyL#`{e8sDdU7FMdF(Y zj*-#ivj9o_=xoKfA-^u4?bur#iWsJzJEjQb>Co0TEq#4g8^;tiX_w`uf3r_ixJQ|Ht_?OrG%U{{bw7@?8T`=+7-Xm&VpS474qOb;0(s5^+Ez!>G6Ap9Ok9aiw zxP7tWo~uzkW=oe=TZ)F*3Qw}6*+CssYWBsRdZw(p5^{#QIR3GXjw4&I`M8W|a>99w z)_8?~t1jcZJ+!i$xfe2pf6q=05lIuXWqkhY^#ef>6TPE9!eif~qmqR^Pxgp1vU&ay z=N_hhyDDxNk0nj(z;;aSnI74Qu}m69GPT0}aAm?arliU~EGJ3mdCBzAt=}D=ca;Bm z$~`T*W0BO3rTYBB2yB}=qjDr@RpvI~mh za?iA+KG~P&4sB7RqV5arZ%yisI^V5S+T*WQ^u0#=TN%Rw`6$)DVCiVf`FS~l5tvu0 z9NKe@{Bvc_fM^rfH?|`(t#LKFV_UmCB7KRMdUUR%cE$X4{FRZ3W5*L3v2{pZ&1VGp z)HSkR_`XliqTS>uvm@oGTq;^337yvNoQkbI->65r=DVp~w=XeO^{NpOp_^8f2Ui}# zVm)^yyJPxXZ~uh@+ak5~O^Ml;?+Hw<-AA1X`rn7*cM(PVZwqXl@<{UQUN_MT^$^?s z#-r)8wyTe|K~&RY{c$;0AE&%)>Dv?5HGT7Xw|Tx%y&d7^;v#VjBctWox%f2hj?Ol$ z#bc)C?68hWSq~}l>(@{$xteTm`V_71y>d*n^W@G$8oVDFjeRj?eidbZ?8QcBFRWFc zR{3RQn<75#&9c4iyYBs$aBMI3$bT=FCpX(KkLvkn?dG(ce-+2?gMYQQb8b5FV+)t@ z!ZG6aJfc669{b>@MH%D&KWR5phJEyB^O{7!mUV4Nzpl2e7p|ZyX}Z(>_UN5YJfWx? z#wQCKFRX3r`9@+((bzg7CBAP=HSBI@OL64$R@QPku76kV8<%a+x9<#T$|Gcar)@hSe=zV^AC=HuJc zZ3EbvTapF*mA(F7&)alWoBp2Ym>;z1=YZn>Pm6MtDK!h)Nu)h+dsDbv|)H02Ao;uTuM4HuDXwO*ZgO}^n zIvwYrg<3Bz+n!Mu!T$-r8IZ4nT&5BXGwx~XJji~tuE9nFweAer_Kdn1W@(i=UtOctxAD2Q^`b4?+sM9{n;@I^HZsM` z(GqQfO!kaPqe0jqYhjm}sP!;y`)#oME>ZK$XbQi?dn@-nX=?M|GPIs|wGnLC@(!by)|p>vfJ;7t9j(Io5*C zIO1-E%-31-f^%ff%~`rySHlT82vr%>i0fcoZ_=0>VO&1{Ol-<%0M1o=r+gj!B8vEP zHSnyR4Z8?ej$Mhlz&9(1<1_U9Z-!_wBbq03y&a7HY~`Lh7_~%#buR0O{IgD;1L_8C zJsa){c=w?bc8)q$Hs+Y`;HTVZn!n)xc9Po_W0tE|JBjl`FEVugH}I-~JLJKFR@ zXyv@v3(;nI*=L*UjeOZUrnhFk5S{Px=6OY4$yZ2cKsEDqHtbkDVOPUt->ETv^u^CT zn_y?-o#ASTZGm#__$)jJ&VWH!@2fQ`oPW?#)xaMKdn8|e z9rW157e2pUp-+SBpx*dID$lU9;Vy9|j4x5&(I+H6*Afq@{XDo#eYt_>^E%TuQc0zzU0Y0CrQ)KwX^Y^!8n_A z7MkZ1Vd8ntQg>g@(J~*R?bA04IJ@}l$xmLKYt`I@?93VSA=jym&rWJX(z;dgVc9Fs zzpk*_eu=r_{MpDlw4XjG7MfeGv($^N{FP-X#)Y=wGuq6KtwOnoyb80tXR6|;lACL@ bZXBU{j||JVHU{7myR7~CaaFICHrD?DyzhDA diff --git a/lucene/analysis/icu/src/resources/org/apache/lucene/analysis/icu/segmentation/Hebrew.brk b/lucene/analysis/icu/src/resources/org/apache/lucene/analysis/icu/segmentation/Hebrew.brk deleted file mode 100644 index 5a6666466a7514a67d8a37212d85c742a5d224f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26200 zcmeHQdyHO16`y|hz3q0pEq&ANmbSD=pcNt{5TJ+@j69V96}q&sZQ9rZmJ+~HgQ&@F zNl-8$h!I=FNJtZqm>~KGAVJ^{MMx;{M_Y&iZ3raQ*aRQoIdi_Vb7t<$eeC)O$?oL) z&dfQ#^E+qG%-s9k{mP=$|NH0Xd!k90!^St@Z3ev7DV5EE*R9aM5#*mi!jF`f4=c6i zex;_Y0tpzk91($^WuTuOu(eZnG(1urXt91zRH`!Q#~|YhGHFA!@}TnyfA#UlL92&b zqbXb0tx!E`vYMiL)l`*0>s5(HOBVL&Q`4Z^ucpJg90M~JlCvDKB6wSv%-p*l)UuE=D*sNfV`$te{T zJQmovg1wOS4Aon~JymBy6`TqyG#g&wpT4eX0mwdR3shf4CcKsdu$I%H4d~SkvG)t^ zewe`m)vvkz>%UOcWIF7ZUNyZUlR@C-n#_QTKntQ3WQ#vklVe~sTOFg(T3vbz?Lq%( zSS0eE1u=TntY9X6>NtqTdC!JCW~kXgw1P8$Ka}?z7{RH~Xn!V)MJ96>+RmQNBb~=PzwA8Id9m|{&KsSB746;52c4t3{XObLJ)MJ5FQcQG zqrLgjV6;3sIXX2uGdef=JfJR*)}S>SiZ(^pM>j>c>Cqk0aCCQcU-YBsr_nxWzkt`T zqvxXMqu)iZMF*lkM(;&`js6i&ii@~Eo*OTWm&Gfh10YY2&xtRHFO9E?hvH4~)_6y} zBECJoGu|EF3-W>Zq4?4GiTJ7b+4!aSmH4&zK(sG@Cw@Qv8_0hpNz$84Pv$0r$?|Al zvNAa>IXhXMT+%t1T-kY@XCY;BE!Z|BUrx4y+zhYn;P-VzBzH#3B{I}cb|?30`~%5D z$)m{=$*&;pZ;}_1my_4D{s3^j1Fyr$k>o?T!6(Vev^Sj@?MoLxZ)ti``kC}BtWtV@ zdSQBLdSyD4Zt5INx54Y?bXVt)wtXkP%gW$r`h9B*8K*yl*N;1g;QeRmW9gIW)9G*1 z->3W2gVDauU($Ee57MLQN1cONii~YqR)AMu8;}147UuVAXFty}n+-L*67pD>Ez4G9 zD>_G`ec9<%ak8_s&!IiLsEb;bU4d-bnrwZQ--Koetdp%ej3-ib1*;Kjy5rxsK6(s0{QCv;{39n{+>BK z3tP5j2A^L&zQ$*1LVhwTkgv-(=QrXW&v)edIl8pp55aZ#VEzqweLEk{zn9;iKbSvE zsQl6ViO%E6z0tn>sm}iV+5DyP?VkMVe}i&H_KiPm%|d#^ap;Ktj7EZ-kng{mXdy0v}J)-Wr1 z7GL0TTiG^p8EV%CdE5i&g;cp#a-|llUIwop*>%`RA#g_#opqT;?3gi;&3r~ zh9si+uxAoBzK(Q%KS;kNJla#R{=X&7FF(iFi&VMA`Wv~_V<}@Z_}(#x7qw!v*8{!D z@WOAV+?K<)2JDf+@0r^-_MQqn?Y(U$87gW#>g5V4#%#}=a1hQj;G1^*r(W}mAjJkd3Sele#X11H{L3T{4;0f zRXMn}axGm%lQC7r=4#>>#$?vD0GY?Ly5x%-#ADv=oI@3M^E6&;G1od{!ybO`P0iNh zxBjT{&&pt#-K7#%sMb$7DOA0DBX9S5&xQbVjijm9fZ7!hMQqysCSCp6Z;#^R13$Tg#Erj@i@t)$J3TjYrHXSCacI5o6fHJ?3mK zDSDW(nFXuhkJ-$hYtT-bo$im_OiM9krNddcC|?Bh###IJoLi;xm}0wn+GQ9GnSD`N z=UQ=0YhVyqH+Lq8;mj!q_9JhybDuIHM)vZ}mvHRmlfL;fj=d?4|J^rV%$$6gL0!@P^F=1|aCz8^V==FhJQJ42B73ft#!^eOaM#yVfKLtL%4^Jd zlElbdCEt8)ba_OxWd;3WTW~D?sm|Zdmm-@? zaZLV37w!>P*lt_onz03SZVo(8Gdo^E$_({VLt4tE>b(-Ts(+kqy7r&GN;Ew)osq*W zFo*|S?X>_IRE95nmwgk3ENqoA*+L99OBYwlAF!C`Xhgzw8N>{9{6PMkL*<$At(m)4 z0e(66Zl87s?hxihF5Yh}eS48@eks|IG1O>p8V*0Myo3F?u$J>N(#+WCYI?jrptMfN@KZ~)uJ;b}Z^0*1c=f&BS zZKxqD*%;}Uet+U%8&$fkKYR1%jPd#Vy{oFnHrgoxf9w30Pp;9JQ(M`i%F{gz`*_XJ zy5{$jK&G0-tVA83seZGb8@23(_cVhl+rt{;WqM(BorO3;_bHB0XGff;hE4VZR>9yz zO*pn?H%RO;dh{9}-c4rjVGnTZtED%0Lg+YkRkZD-Y! zw>EY2m-ecRB`(-E6|pPTbY%S9p3T5}#~1H@QD3b`tl+hG5hQs6D9M6BxT}T3C@w(%(DPl{Os(-yrH;(w1Tbu`Kq z{U&|$rghpWaCf3x7jg>}5H^2CL6kd`o~ZIM2*kCAO;yHQ={ zzVqP5Hyr++%!qu=RZZGlZ^TM_xbJ$JvCLKWt5?eZ{2~3zxtN&cp7f+X`IpxYeGySp z_p0a63ft(jeg%epKY-t&&~tY8w*-EfFo&v_!vm-I9D-Ft6 zLRVXNO^mO-UWg;Ce3$5^eUnpNubvSZs!(+iTziO%aqdoZ$Ml?N|BHF{MQP)uMfS~e zr_|bg#7x!y-VmQ{d&Ix$w{iB!%&)p`1{dlfulodTp1H9OW@P6Ou8xfhjj)DjlbJOi zhgfZW`E=4#JELT5J{PvmH)?ir+_|_+oWs~;xppo;jjP$&hfzFcDOZOvQZf!D>YLZl zcycw_U&b`3>Rve~I-%wcLkK>%%*L@;vc67oJdVQbb$(=L@3Q3lY~C_1q^XN<^YaMV z=o(P=w<9&ZPZJOG`=tM#Z$9DKae34%KBL>q^8D*G{uumit8eDbb$)K6Wu|bBWh{R> zWM7o>H<{R%HtZvdtuws!J@%|e5`yqe(Kaqz3D?s0#QXg*I$!yWL~NL!JZ!!&+Q#`t z#+S0OF~&-I-M?NY1lu4t3~-UR&$Mes*!aleQo59kv%@WPdD<+h~U_*e3&-6 z-GjSVVQb?fvG89j>%X?#l^eS9MUeRSAaRU+1%DB9k@||-tk$b7>Uwo1{9VfP)ED*N z)x^K8X}7are2uym{#x@+b(Ok7Z3mv~)Mr6%1plvs6%pvaORd#h7pc__2QxO~LVxDE z1ftxcw(2}LTCB~uY=34wU)`#90Q2=Q7tW1jGgj%p3u<$-S_$nGb$Yh~t96~WL49_N ziC_A2&gZI&Ambf6@9h?Avz%>zX1y3HyFpz7GuYPU=Xx|_E&JQdzMR`IOMhAEQ@WLw z@j3H0D=GasbE?Kh*x_5?lt|WQncM!%D))?C?`Etaf9Btyv)uvjH^9DL582<=&7Jtq zfc3@GzR`1bZ-CXm5l-1gI2YH!Sw;ptA9za6=vJDw+rhfkstQ&}&fx-xy&m{B1H(3W zA>&rqVK;U6uJ7tW5s8~-GzeEEd(U3hWijzw1YW6@z<$Pcvnz2D=w$_QY|m(|o~K;x z|9#(`4`wX0z$&{KS(W9^ECq9&#FD2u z6iZ^p6N}E6j6!VXd2tky?dD~lbvGKtvN1ARyI9E1cP)7Zp{Nuqgc*eYi-LUus`dtc zKG>vp%q{v#vO#=CSOV9P)iAzB4e2w4pBqSr(!SrWRp)@UY2*`i6uVk9x1H+K`VPBG zBkZdJBTgAbaE0BILP)=MC)~a99v+T>v!K%;cPMe#N~sv*+kzZc-bcpQ#O5n^wigRX;mkU#vMs3ZDr%WA^gbhOJFF&0aKK^?qZ^wR(R3 W^%{gv>Si}{j&<=vb&>1Q<@z_q1>%?h diff --git a/lucene/analysis/icu/src/resources/org/apache/lucene/analysis/icu/segmentation/Khmer.brk b/lucene/analysis/icu/src/resources/org/apache/lucene/analysis/icu/segmentation/Khmer.brk index f5b50e14e76e96f2d18148a6a451568c23a7a4ef..dd368d05ec260317ccf534ec214e7fce1a50cf4c 100644 GIT binary patch delta 1077 zcmZ8fU1(HS5We@!% zRD!Mq$%BfG8T!x|B=n)?MYLQCg;HX%&{9gReF+Up67@k5|Ih~!QRm!EG{`V#&Ntu8 zcjlaXFO~i*^&K}qJ9Q%aPM={cU2Yf^A&HJ*81^YM{^QMNGAGyxY%N_;qpC~nn!2U# zszLSGN6$ck1!0ImjgO@Q(vX2HG{J|^1}or;sn`JrIBZ43KjR4gfmeKL5JzRMk&0{OLY(BMRyKG?BfRGoD!vNx$AQ2mP=cS}q@RCY zu6?r-Ql-y?^>9=LisDo!kCCC2dZ8I=paR~IxQtrplQ*3{x7wSC{HEYBJ>#p1DjrV+ z-g2641&nF)Cgwge%?^3gg$`|`Ewp1=j&{=lwOb=_ec=*2u}-s>kHoU3l52J#ouq!* zY)oRW8lVB_!CpEeWBnlUobHh*BXhgGT7DVbvoZi<^b`Hcg+L-gzti6&U%6~FCj8oW zX`F7V<8)WsG^K`S8lK@x_IX}ZJu8R?7-Rtdo0xARJJp}^!JN(C)ExD?Ym_OezHBSc z%SCu+GR7kdZ1EbNpI8s_Bk@1+IJY)Ayek>?xvL3VIwJM8BAt|M$ZM)yYjSn2k~b7x z{y!h(eRWa(F7pwO7qyi3kk^^oW|5We@$%-&UNHAUSYS2wZTUCq=74GWY0!6L~rurMhq>cK3iATbpZ3bT^& z#Wb>qkU-ev22n&>K_r6Fi?CR+=|iD`WDg}0HutWkuQ8mN^UXKs&Nt`WcTGc0ciPml zj+;4at}9AWzM{l9BsvvEadxPlfyphTeq^8RWYefNrqzm#Ym?fP)}zf@Xbx1+!2!wO zvanQu5Bv~>LMVZ4upP=5VHLLc;D24-RaR4iDMh?}B2 zEQ1zn*MobsTHG(I3TyDxB3q|*<0WjwR%{ohQ&#ss?g5Id71oQP706^b-kuo$6kp<7 z9JQz(91~rGG2_ufjPP%Jj{eO=_}$2lIiPcy%~k`d;GY<=^7GN!WlunH7UM9*Q4*-+ zrnPbzeoEK=m<(mpM*JeNh)QY4@=1%^YeW)WX=9XM1-*#U!8r+)7GX=5y%)yB)0`@CMP4zF_#H;Ew^|ig8{Ev{j8)u_nP^O>PuTfTR-Q4Roq~W0 za=j;&52v{~C@*YW{TD|E21oz^ diff --git a/lucene/analysis/icu/src/resources/org/apache/lucene/analysis/icu/segmentation/Lao.brk b/lucene/analysis/icu/src/resources/org/apache/lucene/analysis/icu/segmentation/Lao.brk deleted file mode 100644 index 571b0163441d46f9922ef744c3fb22d3bd564904..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47344 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 diff --git a/lucene/analysis/icu/src/resources/org/apache/lucene/analysis/icu/segmentation/Myanmar.brk b/lucene/analysis/icu/src/resources/org/apache/lucene/analysis/icu/segmentation/Myanmar.brk index 1bab7a616ef6280f7907465f1763b74a60fe16c1..dcaeb57178968fd7f93135cc0882193dfb3663e2 100644 GIT binary patch delta 1112 zcmb7ASx8i26u$RA=f6&q%#2e_YU((f%bjVmaTJ@;EZU=>jS|`hq981a?4cCXhF-GB z>_87@Akl+CQF4Qb9xQr^0+XPH7Ay)1de8_eqNH>0xYT1D{&UXve`g=+R9|$eXHTgO zU8lo2Hx#A5K~b`Pv0bDnN^X}rr~iGeLmj1J=kB)0;<-q%ycQqCXVD|RTIeSTuz?di zkZ)m*03Vb?7%CwNOJFIi8Mm8YtA%%s<3_ekphF9!`Co?)#^*RbV|C~@F<0w_KGxSt z;HKFC?!bN458(;xm+%fg!6EiW;Tw#hh7L-(bb%hK$Vs$e5f(w8nJzA12?&f%jEGek z59=Upc|EvHq;L(tjkpzejkArM*M!ZO#tvq>_=P69^Vl;{&9c3C`5&AT zkVj_e!ACsTz_g)EAU>rZIpM4~Cc<|{g?mF5Eplo*KrsG|xk z20}Wehfh#0XNWPAkp(g+BWx>WQZAm#w76Bq+q`?C{<|F0_+0-b*;CQR+k!8ux{i+> zEtU;3CHG9Uk^AIfanMAdTMb*N*t=6rQ@b~;3SNH`$_{ykooz*!7TxkZq%keKdE85E zub4S(c@N( z*LR&d19piDD3Xr(^HikvzzWK%%H{tPMoU1bbii+?1@Rhc^gC#8X)XW**BFq~5AR@+MYu(ZPg|TSVwq!bKwqJMB;K PzI?Zn0o@2BuVw!MtTGuB delta 1014 zcmb7ATS!z<6usx}y`6kC;|z);YBP<__?Xl|vusq9UIz9MD+37?!5{l6`^q1iPq9)t z_+d&JeJE69U4rn(3L+}X0+Y;0LCA>63VK0O``npv>N7U?ti8_Kk9E(>KJlzi^!JMT zfir&lxTaOtYntU3W4Wej&H<5eW2w?AK1jE%z5A&?tG9B@>r483eMJ9avY#Np0#-|r`7oq7PrC?Xd|vf| zp%%a-+~e~hJm+%`7GW7qaJB+pVHFA2%hu!q9aCk%9_+>}%z`o1t`DOZ1Qtdu;^uIM zl@Kzs5!|V_VjX`C*o18nwS)UQ@f3!zhn0T*a@Mp#9F9&iaTG8A!&`M}vpZ~8@Fq?o zTjm(SN9=1VemY!;GxCSsZ+Wd4E*b$xgGJWZ;+jD)U&a~pekEKRJMlaIHkA}*jw~R^ zN~!z=dF0Snl|mVmO@77_3Q|q1)717Di|Kdu>Tk3f2mcv~v3g@M^Ro~K__2%Jbc9-{ zJ-UXD(MkQdVvuhx?2>L*iwMcnF24}``-hNv=qx8kH(*FVPlFJ`5Dl^2ON`^Hhmn6p z)^FSgDWH0G$H5#;&}|v8WhT=UJ)kFR`(Ci#m_x7VjowRdRYWCy^zWdL^3KNVHq;;z z#E7!lmo7-UJ+;Py=YrsL!j~qeeMOvQR;A0SQim+g@yWVP3DV_l0MfXkG=nRg(qEMj z(XDdM>*S74TeeDDxx=XNHL6i=PpNS~_uV>qxUk5W56prcwb*{;1Lb~iwk-BI5-pk~ z>Wlkaa>3)2+scwG5x2(PvRfFhEUQqX)6D&keVMX0SYRq@v{H7-sbF$qY!S(GxmgiA J{)%f!e*pAR;er4F diff --git a/lucene/analysis/icu/src/resources/org/apache/lucene/analysis/icu/utr30.nrm b/lucene/analysis/icu/src/resources/org/apache/lucene/analysis/icu/utr30.nrm index 6e85a18dbf13e73b8bb1a5d68eaf22d5416503d2..efbbb9e490c3990043e33ee20a775fd863130c43 100644 GIT binary patch delta 28 jcmX>wgZaP=<_V&V%p1kBRT#H!Zc>Tn15)>ll4b$`l|%}n delta 28 kcmX>wgZaP=<_V&Vj2p$WRTvpIH>pJPF>c#@&nRgo0E_bp>;M1& diff --git a/lucene/analysis/icu/src/test/org/apache/lucene/analysis/icu/segmentation/TestICUTokenizer.java b/lucene/analysis/icu/src/test/org/apache/lucene/analysis/icu/segmentation/TestICUTokenizer.java index a7c02688b54..1d9a901fb1e 100644 --- a/lucene/analysis/icu/src/test/org/apache/lucene/analysis/icu/segmentation/TestICUTokenizer.java +++ b/lucene/analysis/icu/src/test/org/apache/lucene/analysis/icu/segmentation/TestICUTokenizer.java @@ -42,7 +42,7 @@ public class TestICUTokenizer extends BaseTokenStreamTestCase { sb.append(whitespace); sb.append("testing 1234"); String input = sb.toString(); - ICUTokenizer tokenizer = new ICUTokenizer(new StringReader(input)); + ICUTokenizer tokenizer = new ICUTokenizer(new StringReader(input), new DefaultICUTokenizerConfig(false)); assertTokenStreamContents(tokenizer, new String[] { "testing", "1234" }); } @@ -52,7 +52,7 @@ public class TestICUTokenizer extends BaseTokenStreamTestCase { sb.append('a'); } String input = sb.toString(); - ICUTokenizer tokenizer = new ICUTokenizer(new StringReader(input)); + ICUTokenizer tokenizer = new ICUTokenizer(new StringReader(input), new DefaultICUTokenizerConfig(false)); char token[] = new char[4096]; Arrays.fill(token, 'a'); String expectedToken = new String(token); @@ -69,7 +69,7 @@ public class TestICUTokenizer extends BaseTokenStreamTestCase { @Override protected TokenStreamComponents createComponents(String fieldName, Reader reader) { - Tokenizer tokenizer = new ICUTokenizer(reader); + Tokenizer tokenizer = new ICUTokenizer(reader, new DefaultICUTokenizerConfig(false)); TokenFilter filter = new ICUNormalizer2Filter(tokenizer); return new TokenStreamComponents(tokenizer, filter); } @@ -118,6 +118,7 @@ public class TestICUTokenizer extends BaseTokenStreamTestCase { public void testLao() throws Exception { assertAnalyzesTo(a, "ກວ່າດອກ", new String[] { "ກວ່າ", "ດອກ" }); + assertAnalyzesTo(a, "ພາສາລາວ", new String[] { "ພາສາ", "ລາວ"}, new String[] { "", "" }); } public void testThai() throws Exception { @@ -138,6 +139,13 @@ public class TestICUTokenizer extends BaseTokenStreamTestCase { new String[] { "我", "是", "中", "国", "人", "1234", "tests"}); } + public void testHebrew() throws Exception { + assertAnalyzesTo(a, "דנקנר תקף את הדו\"ח", + new String[] { "דנקנר", "תקף", "את", "הדו\"ח" }); + assertAnalyzesTo(a, "חברת בת של מודי'ס", + new String[] { "חברת", "בת", "של", "מודי'ס" }); + } + public void testEmpty() throws Exception { assertAnalyzesTo(a, "", new String[] {}); assertAnalyzesTo(a, ".", new String[] {}); diff --git a/lucene/analysis/icu/src/test/org/apache/lucene/analysis/icu/segmentation/TestICUTokenizerCJK.java b/lucene/analysis/icu/src/test/org/apache/lucene/analysis/icu/segmentation/TestICUTokenizerCJK.java new file mode 100644 index 00000000000..2e60717d064 --- /dev/null +++ b/lucene/analysis/icu/src/test/org/apache/lucene/analysis/icu/segmentation/TestICUTokenizerCJK.java @@ -0,0 +1,91 @@ +package org.apache.lucene.analysis.icu.segmentation; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.Reader; +import java.util.Random; + +import org.apache.lucene.analysis.Analyzer; +import org.apache.lucene.analysis.BaseTokenStreamTestCase; + +/** + * test ICUTokenizer with dictionary-based CJ segmentation + */ +public class TestICUTokenizerCJK extends BaseTokenStreamTestCase { + Analyzer a = new Analyzer() { + @Override + protected TokenStreamComponents createComponents(String fieldName, Reader reader) { + return new TokenStreamComponents(new ICUTokenizer(reader)); + } + }; + + /** + * test stolen from smartcn + */ + public void testSimpleChinese() throws Exception { + assertAnalyzesTo(a, "我购买了道具和服装。", + new String[] { "我", "购买", "了", "道具", "和", "服装" } + ); + } + + public void testChineseNumerics() throws Exception { + assertAnalyzesTo(a, "9483", new String[] { "9483" }); + assertAnalyzesTo(a, "院內分機9483。", + new String[] { "院", "內", "分機", "9483" }); + assertAnalyzesTo(a, "院內分機9483。", + new String[] { "院", "內", "分機", "9483" }); + } + + /** + * test stolen from kuromoji + */ + public void testSimpleJapanese() throws Exception { + assertAnalyzesTo(a, "それはまだ実験段階にあります", + new String[] { "それ", "は", "まだ", "実験", "段階", "に", "あり", "ます" } + ); + } + + public void testJapaneseTypes() throws Exception { + assertAnalyzesTo(a, "仮名遣い カタカナ", + new String[] { "仮名遣い", "カタカナ" }, + new String[] { "", "" }); + } + + public void testKorean() throws Exception { + // Korean words + assertAnalyzesTo(a, "안녕하세요 한글입니다", new String[]{"안녕하세요", "한글입니다"}); + } + + /** make sure that we still tag korean as HANGUL (for further decomposition/ngram/whatever) */ + public void testKoreanTypes() throws Exception { + assertAnalyzesTo(a, "훈민정음", + new String[] { "훈민정음" }, + new String[] { "" }); + } + + /** blast some random strings through the analyzer */ + public void testRandomStrings() throws Exception { + checkRandomData(random(), a, 10000*RANDOM_MULTIPLIER); + } + + /** blast some random large strings through the analyzer */ + public void testRandomHugeStrings() throws Exception { + Random random = random(); + checkRandomData(random, a, 100*RANDOM_MULTIPLIER, 8192); + } +} diff --git a/lucene/analysis/icu/src/test/org/apache/lucene/analysis/icu/segmentation/TestLaoBreakIterator.java b/lucene/analysis/icu/src/test/org/apache/lucene/analysis/icu/segmentation/TestLaoBreakIterator.java deleted file mode 100644 index 27179aa1bcd..00000000000 --- a/lucene/analysis/icu/src/test/org/apache/lucene/analysis/icu/segmentation/TestLaoBreakIterator.java +++ /dev/null @@ -1,90 +0,0 @@ -package org.apache.lucene.analysis.icu.segmentation; - -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import java.io.InputStream; - -import org.apache.lucene.util.LuceneTestCase; - -import com.ibm.icu.lang.UCharacter; -import com.ibm.icu.text.BreakIterator; -import com.ibm.icu.text.RuleBasedBreakIterator; -import com.ibm.icu.text.UTF16; - -/** - * Tests LaoBreakIterator and its RBBI rules - */ -public class TestLaoBreakIterator extends LuceneTestCase { - private BreakIterator wordIterator; - - @Override - public void setUp() throws Exception { - super.setUp(); - InputStream is = getClass().getResourceAsStream("Lao.brk"); - wordIterator = new LaoBreakIterator(RuleBasedBreakIterator.getInstanceFromCompiledRules(is)); - is.close(); - } - - private void assertBreaksTo(BreakIterator iterator, String sourceText, String tokens[]) { - char text[] = sourceText.toCharArray(); - CharArrayIterator ci = new CharArrayIterator(); - ci.setText(text, 0, text.length); - iterator.setText(ci); - - for (int i = 0; i < tokens.length; i++) { - int start, end; - do { - start = iterator.current(); - end = iterator.next(); - } while (end != BreakIterator.DONE && !isWord(text, start, end)); - assertTrue(start != BreakIterator.DONE); - assertTrue(end != BreakIterator.DONE); - assertEquals(tokens[i], new String(text, start, end - start)); - } - - assertTrue(iterator.next() == BreakIterator.DONE); - } - - protected boolean isWord(char text[], int start, int end) { - int codepoint; - for (int i = start; i < end; i += UTF16.getCharCount(codepoint)) { - codepoint = UTF16.charAt(text, 0, end, start); - - if (UCharacter.isLetterOrDigit(codepoint)) - return true; - } - - return false; - } - - public void testBasicUsage() throws Exception { - assertBreaksTo(wordIterator, "ກວ່າດອກ", new String[] { "ກວ່າ", "ດອກ" }); - assertBreaksTo(wordIterator, "ຜູ້​ເຂົ້າ", new String[] { "ຜູ້", "ເຂົ້າ" }); - assertBreaksTo(wordIterator, "", new String[] {}); - assertBreaksTo(wordIterator, "ສະບາຍດີ", new String[] { "ສະ", "ບາຍ", "ດີ" }); - } - - public void testNumerics() throws Exception { - assertBreaksTo(wordIterator, "໐໑໒໓", new String[] { "໐໑໒໓" }); - assertBreaksTo(wordIterator, "໐໑໒໓.໕໖", new String[] { "໐໑໒໓.໕໖" }); - } - - public void testTextAndNumerics() throws Exception { - assertBreaksTo(wordIterator, "ກວ່າດອກ໐໑໒໓", new String[] { "ກວ່າ", "ດອກ", "໐໑໒໓" }); - } -} diff --git a/lucene/analysis/icu/src/test/org/apache/lucene/analysis/icu/segmentation/TestWithCJKBigramFilter.java b/lucene/analysis/icu/src/test/org/apache/lucene/analysis/icu/segmentation/TestWithCJKBigramFilter.java index ca25597ce78..2840d238968 100644 --- a/lucene/analysis/icu/src/test/org/apache/lucene/analysis/icu/segmentation/TestWithCJKBigramFilter.java +++ b/lucene/analysis/icu/src/test/org/apache/lucene/analysis/icu/segmentation/TestWithCJKBigramFilter.java @@ -41,7 +41,7 @@ public class TestWithCJKBigramFilter extends BaseTokenStreamTestCase { private Analyzer analyzer = new Analyzer() { @Override protected TokenStreamComponents createComponents(String fieldName, Reader reader) { - Tokenizer source = new ICUTokenizer(reader); + Tokenizer source = new ICUTokenizer(reader, new DefaultICUTokenizerConfig(false)); TokenStream result = new CJKBigramFilter(source); return new TokenStreamComponents(source, new StopFilter(TEST_VERSION_CURRENT, result, CharArraySet.EMPTY_SET)); } @@ -56,7 +56,7 @@ public class TestWithCJKBigramFilter extends BaseTokenStreamTestCase { private Analyzer analyzer2 = new Analyzer() { @Override protected TokenStreamComponents createComponents(String fieldName, Reader reader) { - Tokenizer source = new ICUTokenizer(reader); + Tokenizer source = new ICUTokenizer(reader, new DefaultICUTokenizerConfig(false)); // we put this before the CJKBigramFilter, because the normalization might combine // some halfwidth katakana forms, which will affect the bigramming. TokenStream result = new ICUNormalizer2Filter(source); diff --git a/lucene/analysis/icu/src/tools/java/org/apache/lucene/analysis/icu/GenerateUTR30DataFiles.java b/lucene/analysis/icu/src/tools/java/org/apache/lucene/analysis/icu/GenerateUTR30DataFiles.java index a91a9ddbb7b..9fb5cee5c89 100644 --- a/lucene/analysis/icu/src/tools/java/org/apache/lucene/analysis/icu/GenerateUTR30DataFiles.java +++ b/lucene/analysis/icu/src/tools/java/org/apache/lucene/analysis/icu/GenerateUTR30DataFiles.java @@ -62,7 +62,7 @@ import java.util.regex.Pattern; public class GenerateUTR30DataFiles { private static final String ICU_SVN_TAG_URL = "http://source.icu-project.org/repos/icu/icu/tags"; - private static final String ICU_RELEASE_TAG = "release-49-1-2"; + private static final String ICU_RELEASE_TAG = "release-52-1"; private static final String ICU_DATA_NORM2_PATH = "source/data/unidata/norm2"; private static final String NFC_TXT = "nfc.txt"; private static final String NFKC_TXT = "nfkc.txt"; diff --git a/lucene/ivy-versions.properties b/lucene/ivy-versions.properties index cf088e44b38..78c1973b82b 100644 --- a/lucene/ivy-versions.properties +++ b/lucene/ivy-versions.properties @@ -46,7 +46,7 @@ com.google.inject.guice.version = 3.0 /com.googlecode.concurrentlinkedhashmap/concurrentlinkedhashmap-lru = 1.2 /com.googlecode.juniversalchardet/juniversalchardet = 1.0.3 /com.googlecode.mp4parser/isoparser = 1.0-RC-1 -/com.ibm.icu/icu4j = 49.1 +/com.ibm.icu/icu4j = 52.1 /com.spatial4j/spatial4j = 0.3 com.sun.jersey.version = 1.8 diff --git a/lucene/licenses/icu4j-49.1.jar.sha1 b/lucene/licenses/icu4j-49.1.jar.sha1 deleted file mode 100644 index 12d3fb3cce1..00000000000 --- a/lucene/licenses/icu4j-49.1.jar.sha1 +++ /dev/null @@ -1 +0,0 @@ -fbf7a438e6bf3660e0da2fd77dd1df1635fe503c diff --git a/lucene/licenses/icu4j-52.1.jar.sha1 b/lucene/licenses/icu4j-52.1.jar.sha1 new file mode 100644 index 00000000000..d3551e8380b --- /dev/null +++ b/lucene/licenses/icu4j-52.1.jar.sha1 @@ -0,0 +1 @@ +7dbc327670673acd14b487d120f05747d712c1c0 diff --git a/lucene/test-framework/src/java/org/apache/lucene/analysis/BaseTokenStreamTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/analysis/BaseTokenStreamTestCase.java index b085257e3b2..abd751d350f 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/analysis/BaseTokenStreamTestCase.java +++ b/lucene/test-framework/src/java/org/apache/lucene/analysis/BaseTokenStreamTestCase.java @@ -635,7 +635,7 @@ public abstract class BaseTokenStreamTestCase extends LuceneTestCase { int charUpto = 0; final StringBuilder sb = new StringBuilder(); while (charUpto < s.length()) { - final int c = s.codePointAt(charUpto); + final int c = s.charAt(charUpto); if (c == 0xa) { // Strangely, you cannot put \ u000A into Java // sources (not in a comment nor a string @@ -655,7 +655,7 @@ public abstract class BaseTokenStreamTestCase extends LuceneTestCase { // don't escape... sb.append(String.format(Locale.ROOT, "\\u%04x", c)); } - charUpto += Character.charCount(c); + charUpto++; } return sb.toString(); } diff --git a/solr/licenses/icu4j-49.1.jar.sha1 b/solr/licenses/icu4j-49.1.jar.sha1 deleted file mode 100644 index 12d3fb3cce1..00000000000 --- a/solr/licenses/icu4j-49.1.jar.sha1 +++ /dev/null @@ -1 +0,0 @@ -fbf7a438e6bf3660e0da2fd77dd1df1635fe503c diff --git a/solr/licenses/icu4j-52.1.jar.sha1 b/solr/licenses/icu4j-52.1.jar.sha1 new file mode 100644 index 00000000000..d3551e8380b --- /dev/null +++ b/solr/licenses/icu4j-52.1.jar.sha1 @@ -0,0 +1 @@ +7dbc327670673acd14b487d120f05747d712c1c0 From 5416a09e738f88149c474a26801ce9590ee74793 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Tue, 3 Dec 2013 18:43:26 +0000 Subject: [PATCH 175/223] SOLR-5502: Fix inadvertently removed changes entry git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1547522 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 961a2e1e9be..5caa0cc51c8 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -223,6 +223,9 @@ Other Changes * SOLR-5499: Log a warning if /get is not registered when using SolrCloud. (Daniel Collins via shalin) +* SOLR-5517: Return HTTP error on POST requests with no Content-Type. + (Ryan Ernst, Uwe Schindler) + ================== 4.6.0 ================== Versions of Major Components From dab93e43ccfddb76e90b7138d1ec189309015a17 Mon Sep 17 00:00:00 2001 From: Noble Paul Date: Tue, 3 Dec 2013 20:20:48 +0000 Subject: [PATCH 176/223] SOLR-5525 git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1547565 13f79535-47bb-0310-9956-ffa450edef68 --- .../java/org/apache/solr/cloud/Overseer.java | 2 +- .../cloud/OverseerCollectionProcessor.java | 2 +- .../CollectionsAPIDistributedZkTest.java | 19 ++++++++++--------- .../org/apache/solr/cloud/OverseerTest.java | 3 ++- .../solr/cloud/UnloadDistributedZkTest.java | 4 ++-- .../solr/common/cloud/ClusterState.java | 5 +++++ .../cloud/AbstractFullDistribZkTestBase.java | 12 ++++++------ 7 files changed, 27 insertions(+), 20 deletions(-) diff --git a/solr/core/src/java/org/apache/solr/cloud/Overseer.java b/solr/core/src/java/org/apache/solr/cloud/Overseer.java index eca5032d611..2793db92a9f 100644 --- a/solr/core/src/java/org/apache/solr/cloud/Overseer.java +++ b/solr/core/src/java/org/apache/solr/cloud/Overseer.java @@ -464,7 +464,7 @@ public class Overseer { //request new shardId if (collectionExists) { // use existing numShards - numShards = state.getCollectionStates().get(collection).getSlices().size(); + numShards = state.getCollection(collection).getSlices().size(); log.info("Collection already exists with " + ZkStateReader.NUM_SHARDS_PROP + "=" + numShards); } sliceName = Assign.assignShard(collection, state, numShards); diff --git a/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java b/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java index 1a74bf4772a..68ed988d119 100644 --- a/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java +++ b/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java @@ -1106,7 +1106,7 @@ public class OverseerCollectionProcessor implements Runnable, ClosableThread { private void migrateKey(ClusterState clusterState, DocCollection sourceCollection, Slice sourceSlice, DocCollection targetCollection, Slice targetSlice, String splitKey, int timeout, NamedList results) throws KeeperException, InterruptedException { String tempSourceCollectionName = "split_" + sourceSlice.getName() + "_temp_" + targetSlice.getName(); - if (clusterState.getCollectionStates().containsKey(tempSourceCollectionName)) { + if (clusterState.hasCollection(tempSourceCollectionName)) { log.info("Deleting temporary collection: " + tempSourceCollectionName); Map props = ZkNodeProps.makeMap( QUEUE_OPERATION, DELETECOLLECTION, diff --git a/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIDistributedZkTest.java b/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIDistributedZkTest.java index 5c8c498bc64..d2379fff899 100644 --- a/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIDistributedZkTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIDistributedZkTest.java @@ -1009,10 +1009,11 @@ public class CollectionsAPIDistributedZkTest extends AbstractFullDistribZkTestBa private void collectStartTimes(String collectionName, Map urlToTime) throws SolrServerException, IOException { - Map collections = getCommonCloudSolrServer().getZkStateReader() - .getClusterState().getCollectionStates(); - if (collections.containsKey(collectionName)) { - Map slices = collections.get(collectionName).getSlicesMap(); + ClusterState clusterState = getCommonCloudSolrServer().getZkStateReader() + .getClusterState(); +// Map collections = clusterState.getCollectionStates(); + if (clusterState.hasCollection(collectionName)) { + Map slices = clusterState.getSlicesMap(collectionName); Iterator> it = slices.entrySet().iterator(); while (it.hasNext()) { @@ -1036,13 +1037,13 @@ public class CollectionsAPIDistributedZkTest extends AbstractFullDistribZkTestBa } } else { throw new IllegalArgumentException("Could not find collection in :" - + collections.keySet()); + + clusterState.getCollections()); } } private String getUrlFromZk(String collection) { ClusterState clusterState = getCommonCloudSolrServer().getZkStateReader().getClusterState(); - Map slices = clusterState.getCollectionStates().get(collection).getSlicesMap(); + Map slices = clusterState.getSlicesMap(collection); if (slices == null) { throw new SolrException(ErrorCode.BAD_REQUEST, "Could not find collection:" + collection); @@ -1097,9 +1098,9 @@ public class CollectionsAPIDistributedZkTest extends AbstractFullDistribZkTestBa while (System.currentTimeMillis() < timeoutAt) { getCommonCloudSolrServer().getZkStateReader().updateClusterState(true); ClusterState clusterState = getCommonCloudSolrServer().getZkStateReader().getClusterState(); - Map collections = clusterState - .getCollectionStates(); - if (!collections.containsKey(collectionName)) { +// Map collections = clusterState +// .getCollectionStates(); + if (! clusterState.hasCollection(collectionName)) { found = false; break; } diff --git a/solr/core/src/test/org/apache/solr/cloud/OverseerTest.java b/solr/core/src/test/org/apache/solr/cloud/OverseerTest.java index 68446b36264..7f3c06e2bae 100644 --- a/solr/core/src/test/org/apache/solr/cloud/OverseerTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/OverseerTest.java @@ -744,7 +744,8 @@ public class OverseerTest extends SolrTestCaseJ4 { ClusterState state = reader.getClusterState(); int numFound = 0; - for (DocCollection collection : state.getCollectionStates().values()) { + for (String c : state.getCollections()) { + DocCollection collection = state.getCollection(c); for (Slice slice : collection.getSlices()) { if (slice.getReplicasMap().get("core_node1") != null) { numFound++; diff --git a/solr/core/src/test/org/apache/solr/cloud/UnloadDistributedZkTest.java b/solr/core/src/test/org/apache/solr/cloud/UnloadDistributedZkTest.java index 9cf3d3dc516..dbc69718db1 100644 --- a/solr/core/src/test/org/apache/solr/cloud/UnloadDistributedZkTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/UnloadDistributedZkTest.java @@ -172,7 +172,7 @@ public class UnloadDistributedZkTest extends BasicDistributedZkTest { zkStateReader.updateClusterState(true); - int slices = zkStateReader.getClusterState().getCollectionStates().get("unloadcollection").getSlices().size(); + int slices = zkStateReader.getClusterState().getCollection("unloadcollection").getSlices().size(); assertEquals(1, slices); client = clients.get(1); @@ -187,7 +187,7 @@ public class UnloadDistributedZkTest extends BasicDistributedZkTest { server.request(createCmd); zkStateReader.updateClusterState(true); - slices = zkStateReader.getClusterState().getCollectionStates().get("unloadcollection").getSlices().size(); + slices = zkStateReader.getClusterState().getCollection("unloadcollection").getSlices().size(); assertEquals(1, slices); waitForRecoveriesToFinish("unloadcollection", zkStateReader, false); diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java b/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java index 93fb1264d0c..d4d2ad95aad 100644 --- a/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java +++ b/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java @@ -136,6 +136,10 @@ public class ClusterState implements JSONWriter.Writable { return coll.getActiveSlices(); } + public DocCollection getCollectionOrNull(String collection) { + return collectionStates.get(collection); + + } /** * Get the named DocCollection object, or throw an exception if it doesn't exist. */ @@ -156,6 +160,7 @@ public class ClusterState implements JSONWriter.Writable { /** * @return Map<collectionName, Map<sliceName,Slice>> + * @deprecated */ public Map getCollectionStates() { return Collections.unmodifiableMap(collectionStates); diff --git a/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java b/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java index 9fd762a0a79..9b118fbe9a9 100644 --- a/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java +++ b/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java @@ -440,7 +440,7 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes /* Total number of replicas (number of cores serving an index to the collection) shown by the cluster state */ protected int getTotalReplicas(String collection) { ZkStateReader zkStateReader = cloudClient.getZkStateReader(); - DocCollection coll = zkStateReader.getClusterState().getCollectionStates().get(collection); + DocCollection coll = zkStateReader.getClusterState().getCollectionOrNull(collection); if (coll == null) return 0; // support for when collection hasn't been created yet int cnt = 0; for (Slice slices : coll.getSlices()) { @@ -1690,10 +1690,10 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes int expectedShardsPerSlice = numShardsNumReplicaList.get(1); int expectedTotalShards = expectedSlices * expectedShardsPerSlice; - Map collections = clusterState - .getCollectionStates(); - if (collections.containsKey(collectionName)) { - Map slices = collections.get(collectionName).getSlicesMap(); +// Map collections = clusterState +// .getCollectionStates(); + if (clusterState.hasCollection(collectionName)) { + Map slices = clusterState.getCollection(collectionName).getSlicesMap(); // did we find expectedSlices slices/shards? if (slices.size() != expectedSlices) { return "Found new collection " + collectionName + ", but mismatch on number of slices. Expected: " + expectedSlices + ", actual: " + slices.size(); @@ -1758,7 +1758,7 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes return commondCloudSolrServer; } public static String getUrlFromZk(ClusterState clusterState, String collection) { - Map slices = clusterState.getCollectionStates().get(collection).getSlicesMap(); + Map slices = clusterState.getCollection(collection).getSlicesMap(); if (slices == null) { throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Could not find collection:" + collection); From 56e6b5752ace7d845a81d2a79e82524af302b1b9 Mon Sep 17 00:00:00 2001 From: Yonik Seeley Date: Tue, 3 Dec 2013 20:22:21 +0000 Subject: [PATCH 177/223] SOLR-552: change scale function to use itself as context key instead of source git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1547568 13f79535-47bb-0310-9956-ffa450edef68 --- .../queries/function/valuesource/ScaleFloatFunction.java | 4 ++-- solr/CHANGES.txt | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/ScaleFloatFunction.java b/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/ScaleFloatFunction.java index 388f3a2c982..4771e3291cb 100644 --- a/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/ScaleFloatFunction.java +++ b/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/ScaleFloatFunction.java @@ -94,14 +94,14 @@ public class ScaleFloatFunction extends ValueSource { ScaleInfo scaleInfo = new ScaleInfo(); scaleInfo.minVal = minVal; scaleInfo.maxVal = maxVal; - context.put(this.source, scaleInfo); + context.put(ScaleFloatFunction.this, scaleInfo); return scaleInfo; } @Override public FunctionValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { - ScaleInfo scaleInfo = (ScaleInfo)context.get(source); + ScaleInfo scaleInfo = (ScaleInfo)context.get(ScaleFloatFunction.this); if (scaleInfo == null) { scaleInfo = createScaleInfo(context, readerContext); } diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 5caa0cc51c8..9954a95bd92 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -191,6 +191,9 @@ Bug Fixes * SOLR-5502: A "/" in a document id will cause an exception to be thrown when using the composite id router. (Anshum Gupta via Mark Miller) + +* SOLR-552: Exception when using Query Function inside Scale Function. + (Trey Grainger, yonik) Optimizations ---------------------- From f47d26a49e97f4c9904a597b3bf2165acbc042a1 Mon Sep 17 00:00:00 2001 From: Yonik Seeley Date: Tue, 3 Dec 2013 20:40:35 +0000 Subject: [PATCH 178/223] docs: SOLR-552 should be SOLR-5524 git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1547581 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 9954a95bd92..0d9bd902b80 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -192,7 +192,7 @@ Bug Fixes * SOLR-5502: A "/" in a document id will cause an exception to be thrown when using the composite id router. (Anshum Gupta via Mark Miller) -* SOLR-552: Exception when using Query Function inside Scale Function. +* SOLR-5524: Exception when using Query Function inside Scale Function. (Trey Grainger, yonik) Optimizations From 7bf6ee0a9268014d034598d17ea52ae2ef74d54d Mon Sep 17 00:00:00 2001 From: Uwe Schindler Date: Tue, 3 Dec 2013 22:56:56 +0000 Subject: [PATCH 179/223] Fix annotation git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1547631 13f79535-47bb-0310-9956-ffa450edef68 --- .../src/java/org/apache/solr/common/cloud/ClusterState.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java b/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java index d4d2ad95aad..a6719cc010f 100644 --- a/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java +++ b/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java @@ -160,8 +160,8 @@ public class ClusterState implements JSONWriter.Writable { /** * @return Map<collectionName, Map<sliceName,Slice>> - * @deprecated */ + @Deprecated public Map getCollectionStates() { return Collections.unmodifiableMap(collectionStates); } From de81d96cc0af3efad15c14d12d18bbce5856e60d Mon Sep 17 00:00:00 2001 From: Uwe Schindler Date: Wed, 4 Dec 2013 00:54:08 +0000 Subject: [PATCH 180/223] Update some ANT plugins: - make SVN version configurable: As svnkit 1.8 does not support svn 1.7 WCs and vice versa, if you use an 1.8 WC, you have to manually pass -Dsvnkit.version=1.8.0 (unless I find a better solution...) - Update Groovy - Update Pegdown - LUCENE-5243: Update Clover to released version 3.2.0 (no more snapshot) git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1547661 13f79535-47bb-0310-9956-ffa450edef68 --- extra-targets.xml | 4 +++- lucene/common-build.xml | 6 +++--- lucene/ivy-settings.xml | 8 ++++---- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/extra-targets.xml b/extra-targets.xml index 214c17d911e..cdf861df86e 100644 --- a/extra-targets.xml +++ b/extra-targets.xml @@ -91,11 +91,13 @@ + + - diff --git a/lucene/common-build.xml b/lucene/common-build.xml index 63df8074a47..ef292950c6e 100644 --- a/lucene/common-build.xml +++ b/lucene/common-build.xml @@ -1363,7 +1363,7 @@ ${tests-output}/junit4-*.suites - per-JVM executed suites ]]> Code coverage with Atlassian Clover enabled. - @@ -2200,7 +2200,7 @@ ${ant.project.name}.test.dependencies=${test.classpath.list} - - diff --git a/lucene/ivy-settings.xml b/lucene/ivy-settings.xml index 4b8b8c57a5c..0edbd0b4f2d 100644 --- a/lucene/ivy-settings.xml +++ b/lucene/ivy-settings.xml @@ -35,13 +35,13 @@ + + + - - - - + Solr map-reduce index construction. @@ -29,7 +29,7 @@ - @@ -39,20 +39,20 @@ - - - + + - - - + + @@ -63,14 +63,14 @@ - - + + - - + + @@ -79,9 +79,9 @@ - + - + @@ -92,7 +92,7 @@ - + @@ -106,7 +106,7 @@ - + @@ -129,19 +129,19 @@ - - + + - - + + - + diff --git a/solr/contrib/solr-mr/ivy.xml b/solr/contrib/map-reduce/ivy.xml similarity index 96% rename from solr/contrib/solr-mr/ivy.xml rename to solr/contrib/map-reduce/ivy.xml index d51fd3b020e..179b39d666e 100644 --- a/solr/contrib/solr-mr/ivy.xml +++ b/solr/contrib/map-reduce/ivy.xml @@ -17,7 +17,7 @@ under the License. --> - + diff --git a/solr/contrib/solr-mr/src/java/assembly/hadoop-job.xml b/solr/contrib/map-reduce/src/java/assembly/hadoop-job.xml similarity index 100% rename from solr/contrib/solr-mr/src/java/assembly/hadoop-job.xml rename to solr/contrib/map-reduce/src/java/assembly/hadoop-job.xml diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/BatchWriter.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/BatchWriter.java similarity index 100% rename from solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/BatchWriter.java rename to solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/BatchWriter.java diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/DataInputInputStream.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/DataInputInputStream.java similarity index 100% rename from solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/DataInputInputStream.java rename to solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/DataInputInputStream.java diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/DataOutputOutputStream.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/DataOutputOutputStream.java similarity index 100% rename from solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/DataOutputOutputStream.java rename to solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/DataOutputOutputStream.java diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/DryRunDocumentLoader.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/DryRunDocumentLoader.java similarity index 100% rename from solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/DryRunDocumentLoader.java rename to solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/DryRunDocumentLoader.java diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/GoLive.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/GoLive.java similarity index 100% rename from solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/GoLive.java rename to solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/GoLive.java diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/HdfsFileFieldNames.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/HdfsFileFieldNames.java similarity index 100% rename from solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/HdfsFileFieldNames.java rename to solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/HdfsFileFieldNames.java diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/HeartBeater.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/HeartBeater.java similarity index 100% rename from solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/HeartBeater.java rename to solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/HeartBeater.java diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/LineRandomizerMapper.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/LineRandomizerMapper.java similarity index 100% rename from solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/LineRandomizerMapper.java rename to solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/LineRandomizerMapper.java diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/LineRandomizerReducer.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/LineRandomizerReducer.java similarity index 100% rename from solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/LineRandomizerReducer.java rename to solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/LineRandomizerReducer.java diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/MapReduceIndexerTool.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/MapReduceIndexerTool.java similarity index 100% rename from solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/MapReduceIndexerTool.java rename to solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/MapReduceIndexerTool.java diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/PathArgumentType.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/PathArgumentType.java similarity index 100% rename from solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/PathArgumentType.java rename to solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/PathArgumentType.java diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/PathParts.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/PathParts.java similarity index 100% rename from solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/PathParts.java rename to solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/PathParts.java diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrCloudPartitioner.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/SolrCloudPartitioner.java similarity index 100% rename from solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrCloudPartitioner.java rename to solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/SolrCloudPartitioner.java diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrCounters.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/SolrCounters.java similarity index 100% rename from solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrCounters.java rename to solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/SolrCounters.java diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrInputDocumentWritable.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/SolrInputDocumentWritable.java similarity index 100% rename from solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrInputDocumentWritable.java rename to solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/SolrInputDocumentWritable.java diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrMapper.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/SolrMapper.java similarity index 100% rename from solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrMapper.java rename to solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/SolrMapper.java diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrOutputFormat.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/SolrOutputFormat.java similarity index 100% rename from solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrOutputFormat.java rename to solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/SolrOutputFormat.java diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrRecordWriter.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/SolrRecordWriter.java similarity index 100% rename from solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrRecordWriter.java rename to solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/SolrRecordWriter.java diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrReducer.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/SolrReducer.java similarity index 100% rename from solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/SolrReducer.java rename to solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/SolrReducer.java diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/ToolRunnerHelpFormatter.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/ToolRunnerHelpFormatter.java similarity index 100% rename from solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/ToolRunnerHelpFormatter.java rename to solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/ToolRunnerHelpFormatter.java diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/TreeMergeMapper.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/TreeMergeMapper.java similarity index 100% rename from solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/TreeMergeMapper.java rename to solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/TreeMergeMapper.java diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/TreeMergeOutputFormat.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/TreeMergeOutputFormat.java similarity index 100% rename from solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/TreeMergeOutputFormat.java rename to solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/TreeMergeOutputFormat.java diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/UnbufferedDataInputInputStream.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/UnbufferedDataInputInputStream.java similarity index 100% rename from solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/UnbufferedDataInputInputStream.java rename to solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/UnbufferedDataInputInputStream.java diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/Utils.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/Utils.java similarity index 100% rename from solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/Utils.java rename to solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/Utils.java diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/ZooKeeperInspector.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/ZooKeeperInspector.java similarity index 100% rename from solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/ZooKeeperInspector.java rename to solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/ZooKeeperInspector.java diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/NoChangeUpdateConflictResolver.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/dedup/NoChangeUpdateConflictResolver.java similarity index 100% rename from solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/NoChangeUpdateConflictResolver.java rename to solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/dedup/NoChangeUpdateConflictResolver.java diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/RejectingUpdateConflictResolver.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/dedup/RejectingUpdateConflictResolver.java similarity index 100% rename from solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/RejectingUpdateConflictResolver.java rename to solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/dedup/RejectingUpdateConflictResolver.java diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/RetainMostRecentUpdateConflictResolver.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/dedup/RetainMostRecentUpdateConflictResolver.java similarity index 100% rename from solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/RetainMostRecentUpdateConflictResolver.java rename to solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/dedup/RetainMostRecentUpdateConflictResolver.java diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/SolrInputDocumentComparator.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/dedup/SolrInputDocumentComparator.java similarity index 100% rename from solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/SolrInputDocumentComparator.java rename to solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/dedup/SolrInputDocumentComparator.java diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/SortingUpdateConflictResolver.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/dedup/SortingUpdateConflictResolver.java similarity index 100% rename from solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/SortingUpdateConflictResolver.java rename to solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/dedup/SortingUpdateConflictResolver.java diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/UpdateConflictResolver.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/dedup/UpdateConflictResolver.java similarity index 100% rename from solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/UpdateConflictResolver.java rename to solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/dedup/UpdateConflictResolver.java diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/package.html b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/dedup/package.html similarity index 100% rename from solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/dedup/package.html rename to solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/dedup/package.html diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/morphline/MorphlineCounters.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/morphline/MorphlineCounters.java similarity index 100% rename from solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/morphline/MorphlineCounters.java rename to solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/morphline/MorphlineCounters.java diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/morphline/MorphlineMapRunner.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/morphline/MorphlineMapRunner.java similarity index 100% rename from solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/morphline/MorphlineMapRunner.java rename to solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/morphline/MorphlineMapRunner.java diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/morphline/MorphlineMapper.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/morphline/MorphlineMapper.java similarity index 100% rename from solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/morphline/MorphlineMapper.java rename to solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/morphline/MorphlineMapper.java diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/morphline/package.html b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/morphline/package.html similarity index 100% rename from solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/morphline/package.html rename to solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/morphline/package.html diff --git a/solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/package.html b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/package.html similarity index 100% rename from solr/contrib/solr-mr/src/java/org/apache/solr/hadoop/package.html rename to solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/package.html diff --git a/solr/contrib/solr-mr/src/java/overview.html b/solr/contrib/map-reduce/src/java/overview.html similarity index 92% rename from solr/contrib/solr-mr/src/java/overview.html rename to solr/contrib/map-reduce/src/java/overview.html index c97f378ca2e..ad7c1c0c3fe 100644 --- a/solr/contrib/solr-mr/src/java/overview.html +++ b/solr/contrib/map-reduce/src/java/overview.html @@ -16,6 +16,6 @@ --> -Apache Solr Search Server: Solr MapReduce index building contrib +Apache Solr Search Server: Solr MapReduce contrib diff --git a/solr/contrib/solr-mr/src/test-files/custom-mimetypes.xml b/solr/contrib/map-reduce/src/test-files/custom-mimetypes.xml similarity index 100% rename from solr/contrib/solr-mr/src/test-files/custom-mimetypes.xml rename to solr/contrib/map-reduce/src/test-files/custom-mimetypes.xml diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/currency.xml b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/currency.xml similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/currency.xml rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/currency.xml diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/elevate.xml b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/elevate.xml similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/elevate.xml rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/elevate.xml diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/contractions_ca.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/contractions_ca.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/contractions_ca.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/contractions_ca.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/contractions_fr.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/contractions_fr.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/contractions_fr.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/contractions_fr.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/contractions_ga.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/contractions_ga.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/contractions_ga.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/contractions_ga.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/contractions_it.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/contractions_it.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/contractions_it.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/contractions_it.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/hyphenations_ga.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/hyphenations_ga.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/hyphenations_ga.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/hyphenations_ga.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stemdict_nl.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stemdict_nl.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stemdict_nl.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stemdict_nl.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stoptags_ja.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stoptags_ja.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stoptags_ja.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stoptags_ja.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ar.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_ar.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ar.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_ar.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_bg.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_bg.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_bg.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_bg.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ca.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_ca.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ca.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_ca.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_cz.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_cz.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_cz.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_cz.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_da.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_da.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_da.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_da.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_de.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_de.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_de.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_de.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_el.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_el.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_el.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_el.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_en.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_en.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_en.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_en.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_es.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_es.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_es.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_es.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_eu.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_eu.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_eu.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_eu.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_fa.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_fa.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_fa.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_fa.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_fi.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_fi.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_fi.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_fi.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_fr.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_fr.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_fr.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_fr.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ga.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_ga.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ga.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_ga.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_gl.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_gl.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_gl.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_gl.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_hi.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_hi.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_hi.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_hi.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_hu.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_hu.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_hu.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_hu.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_hy.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_hy.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_hy.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_hy.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_id.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_id.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_id.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_id.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_it.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_it.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_it.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_it.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ja.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_ja.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ja.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_ja.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_lv.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_lv.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_lv.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_lv.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_nl.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_nl.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_nl.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_nl.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_no.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_no.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_no.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_no.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_pt.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_pt.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_pt.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_pt.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ro.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_ro.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ro.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_ro.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ru.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_ru.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ru.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_ru.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_sv.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_sv.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_sv.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_sv.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_th.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_th.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_th.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_th.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_tr.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_tr.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_tr.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/stopwords_tr.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/userdict_ja.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/userdict_ja.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/lang/userdict_ja.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/lang/userdict_ja.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/protwords.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/protwords.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/protwords.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/protwords.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/schema.xml b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/schema.xml similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/schema.xml rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/schema.xml diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/solrconfig.xml b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/solrconfig.xml similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/solrconfig.xml rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/solrconfig.xml diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/stopwords.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/stopwords.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/stopwords.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/stopwords.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/synonyms.txt b/solr/contrib/map-reduce/src/test-files/solr/collection1/conf/synonyms.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/collection1/conf/synonyms.txt rename to solr/contrib/map-reduce/src/test-files/solr/collection1/conf/synonyms.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/currency.xml b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/currency.xml similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/currency.xml rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/currency.xml diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/elevate.xml b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/elevate.xml similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/elevate.xml rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/elevate.xml diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/contractions_ca.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/contractions_ca.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/contractions_ca.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/contractions_ca.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/contractions_fr.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/contractions_fr.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/contractions_fr.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/contractions_fr.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/contractions_ga.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/contractions_ga.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/contractions_ga.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/contractions_ga.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/contractions_it.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/contractions_it.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/contractions_it.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/contractions_it.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/hyphenations_ga.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/hyphenations_ga.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/hyphenations_ga.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/hyphenations_ga.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stemdict_nl.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stemdict_nl.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stemdict_nl.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stemdict_nl.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stoptags_ja.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stoptags_ja.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stoptags_ja.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stoptags_ja.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ar.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_ar.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ar.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_ar.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_bg.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_bg.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_bg.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_bg.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ca.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_ca.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ca.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_ca.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_cz.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_cz.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_cz.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_cz.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_da.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_da.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_da.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_da.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_de.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_de.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_de.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_de.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_el.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_el.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_el.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_el.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_en.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_en.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_en.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_en.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_es.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_es.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_es.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_es.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_eu.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_eu.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_eu.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_eu.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_fa.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_fa.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_fa.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_fa.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_fi.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_fi.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_fi.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_fi.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_fr.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_fr.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_fr.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_fr.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ga.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_ga.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ga.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_ga.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_gl.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_gl.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_gl.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_gl.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_hi.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_hi.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_hi.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_hi.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_hu.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_hu.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_hu.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_hu.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_hy.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_hy.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_hy.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_hy.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_id.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_id.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_id.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_id.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_it.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_it.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_it.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_it.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ja.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_ja.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ja.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_ja.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_lv.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_lv.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_lv.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_lv.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_nl.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_nl.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_nl.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_nl.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_no.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_no.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_no.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_no.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_pt.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_pt.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_pt.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_pt.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ro.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_ro.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ro.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_ro.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ru.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_ru.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ru.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_ru.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_sv.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_sv.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_sv.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_sv.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_th.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_th.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_th.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_th.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_tr.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_tr.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_tr.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/stopwords_tr.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/userdict_ja.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/userdict_ja.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/lang/userdict_ja.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/lang/userdict_ja.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/protwords.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/protwords.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/protwords.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/protwords.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/schema.xml b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/schema.xml similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/schema.xml rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/schema.xml diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/solrconfig.xml b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/solrconfig.xml similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/solrconfig.xml rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/solrconfig.xml diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/stopwords.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/stopwords.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/stopwords.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/stopwords.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/synonyms.txt b/solr/contrib/map-reduce/src/test-files/solr/minimr/conf/synonyms.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/conf/synonyms.txt rename to solr/contrib/map-reduce/src/test-files/solr/minimr/conf/synonyms.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/solr.xml b/solr/contrib/map-reduce/src/test-files/solr/minimr/solr.xml similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/minimr/solr.xml rename to solr/contrib/map-reduce/src/test-files/solr/minimr/solr.xml diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/currency.xml b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/currency.xml similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/currency.xml rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/currency.xml diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/elevate.xml b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/elevate.xml similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/elevate.xml rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/elevate.xml diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/contractions_ca.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/contractions_ca.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/contractions_ca.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/contractions_ca.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/contractions_fr.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/contractions_fr.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/contractions_fr.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/contractions_fr.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/contractions_ga.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/contractions_ga.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/contractions_ga.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/contractions_ga.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/contractions_it.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/contractions_it.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/contractions_it.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/contractions_it.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/hyphenations_ga.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/hyphenations_ga.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/hyphenations_ga.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/hyphenations_ga.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stemdict_nl.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stemdict_nl.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stemdict_nl.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stemdict_nl.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stoptags_ja.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stoptags_ja.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stoptags_ja.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stoptags_ja.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ar.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_ar.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ar.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_ar.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_bg.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_bg.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_bg.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_bg.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ca.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_ca.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ca.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_ca.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_cz.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_cz.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_cz.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_cz.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_da.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_da.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_da.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_da.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_de.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_de.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_de.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_de.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_el.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_el.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_el.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_el.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_en.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_en.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_en.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_en.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_es.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_es.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_es.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_es.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_eu.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_eu.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_eu.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_eu.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_fa.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_fa.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_fa.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_fa.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_fi.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_fi.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_fi.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_fi.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_fr.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_fr.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_fr.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_fr.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ga.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_ga.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ga.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_ga.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_gl.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_gl.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_gl.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_gl.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_hi.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_hi.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_hi.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_hi.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_hu.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_hu.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_hu.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_hu.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_hy.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_hy.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_hy.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_hy.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_id.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_id.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_id.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_id.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_it.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_it.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_it.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_it.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ja.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_ja.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ja.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_ja.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_lv.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_lv.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_lv.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_lv.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_nl.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_nl.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_nl.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_nl.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_no.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_no.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_no.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_no.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_pt.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_pt.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_pt.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_pt.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ro.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_ro.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ro.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_ro.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ru.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_ru.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ru.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_ru.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_sv.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_sv.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_sv.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_sv.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_th.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_th.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_th.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_th.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_tr.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_tr.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_tr.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/stopwords_tr.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/userdict_ja.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/userdict_ja.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/lang/userdict_ja.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/lang/userdict_ja.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/protwords.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/protwords.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/protwords.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/protwords.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/schema.xml b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/schema.xml similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/schema.xml rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/schema.xml diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/solrconfig.xml b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/solrconfig.xml similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/solrconfig.xml rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/solrconfig.xml diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/stopwords.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/stopwords.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/stopwords.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/stopwords.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/synonyms.txt b/solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/synonyms.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/conf/synonyms.txt rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/conf/synonyms.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/solr.xml b/solr/contrib/map-reduce/src/test-files/solr/mrunit/solr.xml similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/mrunit/solr.xml rename to solr/contrib/map-reduce/src/test-files/solr/mrunit/solr.xml diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solr.xml b/solr/contrib/map-reduce/src/test-files/solr/solr.xml similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solr.xml rename to solr/contrib/map-reduce/src/test-files/solr/solr.xml diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/currency.xml b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/currency.xml similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/currency.xml rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/currency.xml diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/elevate.xml b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/elevate.xml similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/elevate.xml rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/elevate.xml diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_ca.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_ca.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_ca.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_ca.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_fr.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_fr.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_fr.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_fr.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_ga.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_ga.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_ga.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_ga.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_it.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_it.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_it.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_it.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/hyphenations_ga.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/hyphenations_ga.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/hyphenations_ga.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/hyphenations_ga.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stemdict_nl.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stemdict_nl.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stemdict_nl.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stemdict_nl.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stoptags_ja.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stoptags_ja.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stoptags_ja.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stoptags_ja.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ar.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ar.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ar.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ar.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_bg.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_bg.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_bg.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_bg.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ca.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ca.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ca.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ca.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_cz.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_cz.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_cz.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_cz.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_da.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_da.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_da.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_da.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_de.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_de.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_de.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_de.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_el.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_el.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_el.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_el.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_en.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_en.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_en.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_en.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_es.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_es.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_es.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_es.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_eu.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_eu.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_eu.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_eu.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fa.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fa.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fa.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fa.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fi.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fi.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fi.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fi.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fr.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fr.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fr.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fr.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ga.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ga.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ga.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ga.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_gl.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_gl.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_gl.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_gl.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hi.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hi.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hi.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hi.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hu.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hu.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hu.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hu.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hy.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hy.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hy.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hy.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_id.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_id.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_id.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_id.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_it.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_it.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_it.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_it.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ja.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ja.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ja.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ja.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_lv.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_lv.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_lv.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_lv.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_nl.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_nl.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_nl.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_nl.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_no.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_no.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_no.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_no.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_pt.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_pt.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_pt.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_pt.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ro.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ro.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ro.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ro.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ru.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ru.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ru.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ru.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_sv.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_sv.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_sv.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_sv.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_th.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_th.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_th.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_th.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_tr.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_tr.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_tr.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_tr.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/userdict_ja.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/userdict_ja.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/userdict_ja.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/lang/userdict_ja.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/protwords.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/protwords.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/protwords.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/protwords.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/schema.xml b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/schema.xml similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/schema.xml rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/schema.xml diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/solrconfig.xml b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/solrconfig.xml similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/solrconfig.xml rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/solrconfig.xml diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/stopwords.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/stopwords.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/stopwords.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/stopwords.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/synonyms.txt b/solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/synonyms.txt similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/synonyms.txt rename to solr/contrib/map-reduce/src/test-files/solr/solrcelltest/collection1/conf/synonyms.txt diff --git a/solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcloud/conf/solrconfig.xml b/solr/contrib/map-reduce/src/test-files/solr/solrcloud/conf/solrconfig.xml similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test-files/solr/solrcloud/conf/solrconfig.xml rename to solr/contrib/map-reduce/src/test-files/solr/solrcloud/conf/solrconfig.xml diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/NullHeader.docx b/solr/contrib/map-reduce/src/test-files/test-documents/NullHeader.docx similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/NullHeader.docx rename to solr/contrib/map-reduce/src/test-files/test-documents/NullHeader.docx diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/boilerplate.html b/solr/contrib/map-reduce/src/test-files/test-documents/boilerplate.html similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/boilerplate.html rename to solr/contrib/map-reduce/src/test-files/test-documents/boilerplate.html diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/complex.mbox b/solr/contrib/map-reduce/src/test-files/test-documents/complex.mbox similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/complex.mbox rename to solr/contrib/map-reduce/src/test-files/test-documents/complex.mbox diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/rsstest.rss b/solr/contrib/map-reduce/src/test-files/test-documents/rsstest.rss similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/rsstest.rss rename to solr/contrib/map-reduce/src/test-files/test-documents/rsstest.rss diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/sample-statuses-20120521-100919.avro b/solr/contrib/map-reduce/src/test-files/test-documents/sample-statuses-20120521-100919.avro similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/sample-statuses-20120521-100919.avro rename to solr/contrib/map-reduce/src/test-files/test-documents/sample-statuses-20120521-100919.avro diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/sample-statuses-20120906-141433 b/solr/contrib/map-reduce/src/test-files/test-documents/sample-statuses-20120906-141433 similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/sample-statuses-20120906-141433 rename to solr/contrib/map-reduce/src/test-files/test-documents/sample-statuses-20120906-141433 diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/sample-statuses-20120906-141433-medium.avro b/solr/contrib/map-reduce/src/test-files/test-documents/sample-statuses-20120906-141433-medium.avro similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/sample-statuses-20120906-141433-medium.avro rename to solr/contrib/map-reduce/src/test-files/test-documents/sample-statuses-20120906-141433-medium.avro diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/sample-statuses-20120906-141433.avro b/solr/contrib/map-reduce/src/test-files/test-documents/sample-statuses-20120906-141433.avro similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/sample-statuses-20120906-141433.avro rename to solr/contrib/map-reduce/src/test-files/test-documents/sample-statuses-20120906-141433.avro diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/sample-statuses-20120906-141433.bz2 b/solr/contrib/map-reduce/src/test-files/test-documents/sample-statuses-20120906-141433.bz2 similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/sample-statuses-20120906-141433.bz2 rename to solr/contrib/map-reduce/src/test-files/test-documents/sample-statuses-20120906-141433.bz2 diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/sample-statuses-20120906-141433.gz b/solr/contrib/map-reduce/src/test-files/test-documents/sample-statuses-20120906-141433.gz similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/sample-statuses-20120906-141433.gz rename to solr/contrib/map-reduce/src/test-files/test-documents/sample-statuses-20120906-141433.gz diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/test-outlook.msg b/solr/contrib/map-reduce/src/test-files/test-documents/test-outlook.msg similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/test-outlook.msg rename to solr/contrib/map-reduce/src/test-files/test-documents/test-outlook.msg diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testAIFF.aif b/solr/contrib/map-reduce/src/test-files/test-documents/testAIFF.aif similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/testAIFF.aif rename to solr/contrib/map-reduce/src/test-files/test-documents/testAIFF.aif diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testBMP.bmp b/solr/contrib/map-reduce/src/test-files/test-documents/testBMP.bmp similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/testBMP.bmp rename to solr/contrib/map-reduce/src/test-files/test-documents/testBMP.bmp diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testBMPfp.txt b/solr/contrib/map-reduce/src/test-files/test-documents/testBMPfp.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/testBMPfp.txt rename to solr/contrib/map-reduce/src/test-files/test-documents/testBMPfp.txt diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testEMLX.emlx b/solr/contrib/map-reduce/src/test-files/test-documents/testEMLX.emlx similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/testEMLX.emlx rename to solr/contrib/map-reduce/src/test-files/test-documents/testEMLX.emlx diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testEXCEL.xls b/solr/contrib/map-reduce/src/test-files/test-documents/testEXCEL.xls similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/testEXCEL.xls rename to solr/contrib/map-reduce/src/test-files/test-documents/testEXCEL.xls diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testEXCEL.xlsx b/solr/contrib/map-reduce/src/test-files/test-documents/testEXCEL.xlsx similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/testEXCEL.xlsx rename to solr/contrib/map-reduce/src/test-files/test-documents/testEXCEL.xlsx diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testFLAC.flac b/solr/contrib/map-reduce/src/test-files/test-documents/testFLAC.flac similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/testFLAC.flac rename to solr/contrib/map-reduce/src/test-files/test-documents/testFLAC.flac diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testFLV.flv b/solr/contrib/map-reduce/src/test-files/test-documents/testFLV.flv similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/testFLV.flv rename to solr/contrib/map-reduce/src/test-files/test-documents/testFLV.flv diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testJPEG_EXIF.jpg b/solr/contrib/map-reduce/src/test-files/test-documents/testJPEG_EXIF.jpg similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/testJPEG_EXIF.jpg rename to solr/contrib/map-reduce/src/test-files/test-documents/testJPEG_EXIF.jpg diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testJPEG_EXIF.jpg.gz b/solr/contrib/map-reduce/src/test-files/test-documents/testJPEG_EXIF.jpg.gz similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/testJPEG_EXIF.jpg.gz rename to solr/contrib/map-reduce/src/test-files/test-documents/testJPEG_EXIF.jpg.gz diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testJPEG_EXIF.jpg.tar.gz b/solr/contrib/map-reduce/src/test-files/test-documents/testJPEG_EXIF.jpg.tar.gz similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/testJPEG_EXIF.jpg.tar.gz rename to solr/contrib/map-reduce/src/test-files/test-documents/testJPEG_EXIF.jpg.tar.gz diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testMP3i18n.mp3 b/solr/contrib/map-reduce/src/test-files/test-documents/testMP3i18n.mp3 similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/testMP3i18n.mp3 rename to solr/contrib/map-reduce/src/test-files/test-documents/testMP3i18n.mp3 diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testMP4.m4a b/solr/contrib/map-reduce/src/test-files/test-documents/testMP4.m4a similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/testMP4.m4a rename to solr/contrib/map-reduce/src/test-files/test-documents/testMP4.m4a diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testPDF.pdf b/solr/contrib/map-reduce/src/test-files/test-documents/testPDF.pdf similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/testPDF.pdf rename to solr/contrib/map-reduce/src/test-files/test-documents/testPDF.pdf diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testPNG.png b/solr/contrib/map-reduce/src/test-files/test-documents/testPNG.png similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/testPNG.png rename to solr/contrib/map-reduce/src/test-files/test-documents/testPNG.png diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testPPT_various.ppt b/solr/contrib/map-reduce/src/test-files/test-documents/testPPT_various.ppt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/testPPT_various.ppt rename to solr/contrib/map-reduce/src/test-files/test-documents/testPPT_various.ppt diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testPPT_various.pptx b/solr/contrib/map-reduce/src/test-files/test-documents/testPPT_various.pptx similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/testPPT_various.pptx rename to solr/contrib/map-reduce/src/test-files/test-documents/testPPT_various.pptx diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testPSD.psd b/solr/contrib/map-reduce/src/test-files/test-documents/testPSD.psd similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/testPSD.psd rename to solr/contrib/map-reduce/src/test-files/test-documents/testPSD.psd diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testPages.pages b/solr/contrib/map-reduce/src/test-files/test-documents/testPages.pages similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/testPages.pages rename to solr/contrib/map-reduce/src/test-files/test-documents/testPages.pages diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testRTFVarious.rtf b/solr/contrib/map-reduce/src/test-files/test-documents/testRTFVarious.rtf similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/testRTFVarious.rtf rename to solr/contrib/map-reduce/src/test-files/test-documents/testRTFVarious.rtf diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testSVG.svg b/solr/contrib/map-reduce/src/test-files/test-documents/testSVG.svg similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/testSVG.svg rename to solr/contrib/map-reduce/src/test-files/test-documents/testSVG.svg diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testTIFF.tif b/solr/contrib/map-reduce/src/test-files/test-documents/testTIFF.tif similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/testTIFF.tif rename to solr/contrib/map-reduce/src/test-files/test-documents/testTIFF.tif diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testVISIO.vsd b/solr/contrib/map-reduce/src/test-files/test-documents/testVISIO.vsd similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/testVISIO.vsd rename to solr/contrib/map-reduce/src/test-files/test-documents/testVISIO.vsd diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testWAV.wav b/solr/contrib/map-reduce/src/test-files/test-documents/testWAV.wav similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/testWAV.wav rename to solr/contrib/map-reduce/src/test-files/test-documents/testWAV.wav diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testWORD_various.doc b/solr/contrib/map-reduce/src/test-files/test-documents/testWORD_various.doc similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/testWORD_various.doc rename to solr/contrib/map-reduce/src/test-files/test-documents/testWORD_various.doc diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testXML.xml b/solr/contrib/map-reduce/src/test-files/test-documents/testXML.xml similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/testXML.xml rename to solr/contrib/map-reduce/src/test-files/test-documents/testXML.xml diff --git a/solr/contrib/solr-mr/src/test-files/test-documents/testXML2.xml b/solr/contrib/map-reduce/src/test-files/test-documents/testXML2.xml similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-documents/testXML2.xml rename to solr/contrib/map-reduce/src/test-files/test-documents/testXML2.xml diff --git a/solr/contrib/solr-mr/src/test-files/test-morphlines/loadSolrBasic.conf b/solr/contrib/map-reduce/src/test-files/test-morphlines/loadSolrBasic.conf similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-morphlines/loadSolrBasic.conf rename to solr/contrib/map-reduce/src/test-files/test-morphlines/loadSolrBasic.conf diff --git a/solr/contrib/solr-mr/src/test-files/test-morphlines/solrCellDocumentTypes.conf b/solr/contrib/map-reduce/src/test-files/test-morphlines/solrCellDocumentTypes.conf similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-morphlines/solrCellDocumentTypes.conf rename to solr/contrib/map-reduce/src/test-files/test-morphlines/solrCellDocumentTypes.conf diff --git a/solr/contrib/solr-mr/src/test-files/test-morphlines/solrCellJPGCompressed.conf b/solr/contrib/map-reduce/src/test-files/test-morphlines/solrCellJPGCompressed.conf similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-morphlines/solrCellJPGCompressed.conf rename to solr/contrib/map-reduce/src/test-files/test-morphlines/solrCellJPGCompressed.conf diff --git a/solr/contrib/solr-mr/src/test-files/test-morphlines/solrCellXML.conf b/solr/contrib/map-reduce/src/test-files/test-morphlines/solrCellXML.conf similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-morphlines/solrCellXML.conf rename to solr/contrib/map-reduce/src/test-files/test-morphlines/solrCellXML.conf diff --git a/solr/contrib/solr-mr/src/test-files/test-morphlines/tokenizeText.conf b/solr/contrib/map-reduce/src/test-files/test-morphlines/tokenizeText.conf similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-morphlines/tokenizeText.conf rename to solr/contrib/map-reduce/src/test-files/test-morphlines/tokenizeText.conf diff --git a/solr/contrib/solr-mr/src/test-files/test-morphlines/tutorialReadAvroContainer.conf b/solr/contrib/map-reduce/src/test-files/test-morphlines/tutorialReadAvroContainer.conf similarity index 100% rename from solr/contrib/solr-mr/src/test-files/test-morphlines/tutorialReadAvroContainer.conf rename to solr/contrib/map-reduce/src/test-files/test-morphlines/tutorialReadAvroContainer.conf diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/IdentityMapper.java b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/IdentityMapper.java similarity index 100% rename from solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/IdentityMapper.java rename to solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/IdentityMapper.java diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/IdentityReducer.java b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/IdentityReducer.java similarity index 100% rename from solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/IdentityReducer.java rename to solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/IdentityReducer.java diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/LineRandomizerMapperReducerTest.java b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/LineRandomizerMapperReducerTest.java similarity index 100% rename from solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/LineRandomizerMapperReducerTest.java rename to solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/LineRandomizerMapperReducerTest.java diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MRUnitBase.java b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MRUnitBase.java similarity index 98% rename from solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MRUnitBase.java rename to solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MRUnitBase.java index 6238c225748..c47858232c4 100644 --- a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MRUnitBase.java +++ b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MRUnitBase.java @@ -29,7 +29,7 @@ import org.junit.BeforeClass; public abstract class MRUnitBase extends SolrTestCaseJ4 { - protected static final String RESOURCES_DIR = ExternalPaths.SOURCE_HOME + "/contrib/solr-mr/src/test-files"; + protected static final String RESOURCES_DIR = ExternalPaths.SOURCE_HOME + "/contrib/map-reduce/src/test-files"; protected static final String DOCUMENTS_DIR = RESOURCES_DIR + "/test-documents"; protected static File solrHomeZip; diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MapReduceIndexerToolArgumentParserTest.java b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MapReduceIndexerToolArgumentParserTest.java similarity index 99% rename from solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MapReduceIndexerToolArgumentParserTest.java rename to solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MapReduceIndexerToolArgumentParserTest.java index e95ebb851d7..c559e0c9cfb 100644 --- a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MapReduceIndexerToolArgumentParserTest.java +++ b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MapReduceIndexerToolArgumentParserTest.java @@ -49,7 +49,7 @@ public class MapReduceIndexerToolArgumentParserTest extends LuceneTestCase { private ByteArrayOutputStream bout; private ByteArrayOutputStream berr; - private static final String RESOURCES_DIR = ExternalPaths.SOURCE_HOME + "/contrib/solr-mr/src/test-files"; + private static final String RESOURCES_DIR = ExternalPaths.SOURCE_HOME + "/contrib/map-reduce/src/test-files"; private static final File MINIMR_INSTANCE_DIR = new File(RESOURCES_DIR + "/solr/minimr"); private static final String MORPHLINE_FILE = RESOURCES_DIR + "/test-morphlines/solrCellDocumentTypes.conf"; diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineBasicMiniMRTest.java b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineBasicMiniMRTest.java similarity index 99% rename from solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineBasicMiniMRTest.java rename to solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineBasicMiniMRTest.java index 1a0101e171f..b4aad76a452 100644 --- a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineBasicMiniMRTest.java +++ b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineBasicMiniMRTest.java @@ -66,7 +66,7 @@ import com.carrotsearch.randomizedtesting.annotations.ThreadLeakZombies.Conseque public class MorphlineBasicMiniMRTest extends SolrTestCaseJ4 { private static final boolean ENABLE_LOCAL_JOB_RUNNER = false; // for debugging only - private static final String RESOURCES_DIR = ExternalPaths.SOURCE_HOME + "/contrib/solr-mr/src/test-files"; + private static final String RESOURCES_DIR = ExternalPaths.SOURCE_HOME + "/contrib/map-reduce/src/test-files"; private static final String DOCUMENTS_DIR = RESOURCES_DIR + "/test-documents"; private static final File MINIMR_CONF_DIR = new File(RESOURCES_DIR + "/solr/minimr"); diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineGoLiveMiniMRTest.java b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineGoLiveMiniMRTest.java similarity index 99% rename from solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineGoLiveMiniMRTest.java rename to solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineGoLiveMiniMRTest.java index 5b654bcc6d7..b2477acaf4f 100644 --- a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineGoLiveMiniMRTest.java +++ b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineGoLiveMiniMRTest.java @@ -86,7 +86,7 @@ import com.carrotsearch.randomizedtesting.annotations.ThreadLeakZombies.Conseque @Slow public class MorphlineGoLiveMiniMRTest extends AbstractFullDistribZkTestBase { - private static final String RESOURCES_DIR = ExternalPaths.SOURCE_HOME + "/contrib/solr-mr/src/test-files"; + private static final String RESOURCES_DIR = ExternalPaths.SOURCE_HOME + "/contrib/map-reduce/src/test-files"; private static final String DOCUMENTS_DIR = RESOURCES_DIR + "/test-documents"; private static final File MINIMR_INSTANCE_DIR = new File(RESOURCES_DIR + "/solr/minimr"); private static final File MINIMR_CONF_DIR = new File(RESOURCES_DIR + "/solr/minimr"); diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineMapperTest.java b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineMapperTest.java similarity index 100% rename from solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineMapperTest.java rename to solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineMapperTest.java diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineReducerTest.java b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineReducerTest.java similarity index 100% rename from solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/MorphlineReducerTest.java rename to solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineReducerTest.java diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/UtilsForTests.java b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/UtilsForTests.java similarity index 97% rename from solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/UtilsForTests.java rename to solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/UtilsForTests.java index b21d8d204e7..f31237e3cc4 100644 --- a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/UtilsForTests.java +++ b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/UtilsForTests.java @@ -33,7 +33,7 @@ import org.apache.solr.util.ExternalPaths; public class UtilsForTests { - protected static final String RESOURCES_DIR = ExternalPaths.SOURCE_HOME + "/contrib/solr-mr/src/test-files"; + protected static final String RESOURCES_DIR = ExternalPaths.SOURCE_HOME + "/contrib/map-reduce/src/test-files"; public static void validateSolrServerDocumentCount(File solrHomeDir, FileSystem fs, Path outDir, int expectedDocs, int expectedShards) throws IOException, SolrServerException { diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/hack/MiniMRClientCluster.java b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/hack/MiniMRClientCluster.java similarity index 100% rename from solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/hack/MiniMRClientCluster.java rename to solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/hack/MiniMRClientCluster.java diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/hack/MiniMRClientClusterFactory.java b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/hack/MiniMRClientClusterFactory.java similarity index 100% rename from solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/hack/MiniMRClientClusterFactory.java rename to solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/hack/MiniMRClientClusterFactory.java diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/hack/MiniMRCluster.java b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/hack/MiniMRCluster.java similarity index 100% rename from solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/hack/MiniMRCluster.java rename to solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/hack/MiniMRCluster.java diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/hack/MiniMRYarnCluster.java b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/hack/MiniMRYarnCluster.java similarity index 100% rename from solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/hack/MiniMRYarnCluster.java rename to solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/hack/MiniMRYarnCluster.java diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/hack/MiniMRYarnClusterAdapter.java b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/hack/MiniMRYarnClusterAdapter.java similarity index 100% rename from solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/hack/MiniMRYarnClusterAdapter.java rename to solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/hack/MiniMRYarnClusterAdapter.java diff --git a/solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/hack/MiniYARNCluster.java b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/hack/MiniYARNCluster.java similarity index 100% rename from solr/contrib/solr-mr/src/test/org/apache/solr/hadoop/hack/MiniYARNCluster.java rename to solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/hack/MiniYARNCluster.java diff --git a/solr/contrib/solr-morphlines-cell/build.xml b/solr/contrib/morphlines-cell/build.xml similarity index 71% rename from solr/contrib/solr-morphlines-cell/build.xml rename to solr/contrib/morphlines-cell/build.xml index e0da709634a..352e7cf106a 100644 --- a/solr/contrib/solr-morphlines-cell/build.xml +++ b/solr/contrib/morphlines-cell/build.xml @@ -25,34 +25,34 @@ - - + - - - + + - + - - + - + @@ -63,14 +63,14 @@ - - + + - - + + @@ -79,9 +79,9 @@ - - - + + + @@ -93,7 +93,7 @@ - + @@ -107,7 +107,7 @@ - + @@ -131,13 +131,13 @@ - - + + - + diff --git a/solr/contrib/solr-morphlines-cell/ivy.xml b/solr/contrib/morphlines-cell/ivy.xml similarity index 96% rename from solr/contrib/solr-morphlines-cell/ivy.xml rename to solr/contrib/morphlines-cell/ivy.xml index ee652bd8363..1394c71b7b6 100644 --- a/solr/contrib/solr-morphlines-cell/ivy.xml +++ b/solr/contrib/morphlines-cell/ivy.xml @@ -17,7 +17,7 @@ under the License. --> - + diff --git a/solr/contrib/solr-morphlines-cell/src/java/org/apache/solr/morphlines/cell/SolrCellBuilder.java b/solr/contrib/morphlines-cell/src/java/org/apache/solr/morphlines/cell/SolrCellBuilder.java similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/java/org/apache/solr/morphlines/cell/SolrCellBuilder.java rename to solr/contrib/morphlines-cell/src/java/org/apache/solr/morphlines/cell/SolrCellBuilder.java diff --git a/solr/contrib/solr-morphlines-cell/src/java/org/apache/solr/morphlines/cell/StripNonCharSolrContentHandlerFactory.java b/solr/contrib/morphlines-cell/src/java/org/apache/solr/morphlines/cell/StripNonCharSolrContentHandlerFactory.java similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/java/org/apache/solr/morphlines/cell/StripNonCharSolrContentHandlerFactory.java rename to solr/contrib/morphlines-cell/src/java/org/apache/solr/morphlines/cell/StripNonCharSolrContentHandlerFactory.java diff --git a/solr/contrib/solr-morphlines-cell/src/java/org/apache/solr/morphlines/cell/TrimSolrContentHandlerFactory.java b/solr/contrib/morphlines-cell/src/java/org/apache/solr/morphlines/cell/TrimSolrContentHandlerFactory.java similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/java/org/apache/solr/morphlines/cell/TrimSolrContentHandlerFactory.java rename to solr/contrib/morphlines-cell/src/java/org/apache/solr/morphlines/cell/TrimSolrContentHandlerFactory.java diff --git a/solr/contrib/solr-morphlines-cell/src/java/org/apache/solr/morphlines/cell/package.html b/solr/contrib/morphlines-cell/src/java/org/apache/solr/morphlines/cell/package.html similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/java/org/apache/solr/morphlines/cell/package.html rename to solr/contrib/morphlines-cell/src/java/org/apache/solr/morphlines/cell/package.html diff --git a/solr/contrib/solr-morphlines-cell/src/java/overview.html b/solr/contrib/morphlines-cell/src/java/overview.html similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/java/overview.html rename to solr/contrib/morphlines-cell/src/java/overview.html diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/currency.xml b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/currency.xml similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/currency.xml rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/currency.xml diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/elevate.xml b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/elevate.xml similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/elevate.xml rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/elevate.xml diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/contractions_ca.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/contractions_ca.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/contractions_ca.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/contractions_ca.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/contractions_fr.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/contractions_fr.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/contractions_fr.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/contractions_fr.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/contractions_ga.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/contractions_ga.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/contractions_ga.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/contractions_ga.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/contractions_it.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/contractions_it.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/contractions_it.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/contractions_it.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/hyphenations_ga.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/hyphenations_ga.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/hyphenations_ga.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/hyphenations_ga.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stemdict_nl.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stemdict_nl.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stemdict_nl.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stemdict_nl.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stoptags_ja.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stoptags_ja.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stoptags_ja.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stoptags_ja.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_ar.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ar.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_ar.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ar.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_bg.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_bg.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_bg.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_bg.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_ca.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ca.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_ca.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ca.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_cz.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_cz.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_cz.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_cz.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_da.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_da.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_da.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_da.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_de.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_de.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_de.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_de.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_el.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_el.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_el.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_el.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_en.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_en.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_en.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_en.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_es.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_es.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_es.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_es.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_eu.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_eu.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_eu.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_eu.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_fa.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_fa.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_fa.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_fa.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_fi.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_fi.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_fi.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_fi.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_fr.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_fr.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_fr.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_fr.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_ga.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ga.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_ga.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ga.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_gl.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_gl.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_gl.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_gl.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_hi.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_hi.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_hi.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_hi.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_hu.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_hu.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_hu.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_hu.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_hy.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_hy.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_hy.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_hy.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_id.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_id.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_id.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_id.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_it.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_it.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_it.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_it.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_ja.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ja.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_ja.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ja.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_lv.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_lv.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_lv.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_lv.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_nl.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_nl.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_nl.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_nl.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_no.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_no.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_no.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_no.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_pt.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_pt.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_pt.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_pt.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_ro.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ro.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_ro.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ro.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_ru.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ru.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_ru.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_ru.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_sv.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_sv.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_sv.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_sv.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_th.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_th.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_th.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_th.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_tr.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_tr.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/stopwords_tr.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/stopwords_tr.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/userdict_ja.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/userdict_ja.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/lang/userdict_ja.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/lang/userdict_ja.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/protwords.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/protwords.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/protwords.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/protwords.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/schema.xml b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/schema.xml similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/schema.xml rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/schema.xml diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/solrconfig.xml b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/solrconfig.xml similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/solrconfig.xml rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/solrconfig.xml diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/stopwords.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/stopwords.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/stopwords.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/stopwords.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/collection1/conf/synonyms.txt b/solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/synonyms.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/collection1/conf/synonyms.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/collection1/conf/synonyms.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/currency.xml b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/currency.xml similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/currency.xml rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/currency.xml diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/elevate.xml b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/elevate.xml similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/elevate.xml rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/elevate.xml diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/contractions_ca.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/contractions_ca.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/contractions_ca.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/contractions_ca.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/contractions_fr.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/contractions_fr.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/contractions_fr.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/contractions_fr.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/contractions_ga.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/contractions_ga.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/contractions_ga.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/contractions_ga.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/contractions_it.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/contractions_it.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/contractions_it.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/contractions_it.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/hyphenations_ga.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/hyphenations_ga.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/hyphenations_ga.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/hyphenations_ga.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stemdict_nl.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stemdict_nl.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stemdict_nl.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stemdict_nl.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stoptags_ja.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stoptags_ja.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stoptags_ja.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stoptags_ja.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_ar.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ar.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_ar.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ar.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_bg.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_bg.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_bg.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_bg.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_ca.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ca.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_ca.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ca.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_cz.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_cz.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_cz.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_cz.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_da.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_da.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_da.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_da.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_de.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_de.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_de.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_de.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_el.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_el.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_el.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_el.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_en.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_en.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_en.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_en.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_es.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_es.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_es.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_es.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_eu.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_eu.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_eu.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_eu.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_fa.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_fa.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_fa.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_fa.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_fi.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_fi.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_fi.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_fi.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_fr.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_fr.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_fr.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_fr.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_ga.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ga.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_ga.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ga.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_gl.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_gl.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_gl.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_gl.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_hi.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_hi.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_hi.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_hi.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_hu.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_hu.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_hu.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_hu.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_hy.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_hy.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_hy.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_hy.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_id.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_id.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_id.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_id.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_it.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_it.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_it.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_it.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_ja.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ja.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_ja.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ja.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_lv.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_lv.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_lv.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_lv.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_nl.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_nl.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_nl.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_nl.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_no.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_no.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_no.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_no.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_pt.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_pt.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_pt.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_pt.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_ro.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ro.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_ro.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ro.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_ru.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ru.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_ru.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_ru.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_sv.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_sv.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_sv.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_sv.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_th.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_th.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_th.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_th.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_tr.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_tr.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/stopwords_tr.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/stopwords_tr.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/userdict_ja.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/userdict_ja.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/lang/userdict_ja.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/lang/userdict_ja.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/protwords.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/protwords.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/protwords.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/protwords.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/schema.xml b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/schema.xml similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/schema.xml rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/schema.xml diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/solrconfig.xml b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/solrconfig.xml similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/solrconfig.xml rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/solrconfig.xml diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/stopwords.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/stopwords.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/stopwords.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/stopwords.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/conf/synonyms.txt b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/synonyms.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/conf/synonyms.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/conf/synonyms.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/minimr/solr.xml b/solr/contrib/morphlines-cell/src/test-files/solr/minimr/solr.xml similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/minimr/solr.xml rename to solr/contrib/morphlines-cell/src/test-files/solr/minimr/solr.xml diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/currency.xml b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/currency.xml similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/currency.xml rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/currency.xml diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/elevate.xml b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/elevate.xml similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/elevate.xml rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/elevate.xml diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/contractions_ca.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/contractions_ca.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/contractions_ca.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/contractions_ca.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/contractions_fr.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/contractions_fr.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/contractions_fr.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/contractions_fr.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/contractions_ga.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/contractions_ga.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/contractions_ga.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/contractions_ga.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/contractions_it.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/contractions_it.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/contractions_it.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/contractions_it.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/hyphenations_ga.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/hyphenations_ga.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/hyphenations_ga.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/hyphenations_ga.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stemdict_nl.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stemdict_nl.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stemdict_nl.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stemdict_nl.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stoptags_ja.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stoptags_ja.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stoptags_ja.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stoptags_ja.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_ar.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ar.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_ar.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ar.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_bg.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_bg.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_bg.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_bg.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_ca.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ca.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_ca.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ca.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_cz.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_cz.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_cz.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_cz.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_da.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_da.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_da.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_da.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_de.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_de.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_de.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_de.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_el.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_el.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_el.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_el.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_en.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_en.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_en.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_en.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_es.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_es.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_es.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_es.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_eu.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_eu.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_eu.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_eu.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_fa.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_fa.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_fa.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_fa.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_fi.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_fi.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_fi.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_fi.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_fr.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_fr.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_fr.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_fr.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_ga.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ga.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_ga.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ga.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_gl.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_gl.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_gl.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_gl.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_hi.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_hi.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_hi.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_hi.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_hu.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_hu.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_hu.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_hu.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_hy.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_hy.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_hy.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_hy.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_id.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_id.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_id.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_id.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_it.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_it.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_it.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_it.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_ja.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ja.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_ja.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ja.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_lv.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_lv.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_lv.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_lv.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_nl.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_nl.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_nl.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_nl.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_no.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_no.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_no.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_no.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_pt.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_pt.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_pt.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_pt.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_ro.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ro.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_ro.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ro.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_ru.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ru.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_ru.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_ru.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_sv.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_sv.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_sv.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_sv.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_th.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_th.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_th.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_th.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_tr.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_tr.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/stopwords_tr.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/stopwords_tr.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/userdict_ja.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/userdict_ja.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/lang/userdict_ja.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/lang/userdict_ja.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/protwords.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/protwords.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/protwords.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/protwords.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/schema.xml b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/schema.xml similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/schema.xml rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/schema.xml diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/solrconfig.xml b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/solrconfig.xml similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/solrconfig.xml rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/solrconfig.xml diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/stopwords.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/stopwords.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/stopwords.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/stopwords.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/synonyms.txt b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/synonyms.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/conf/synonyms.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/conf/synonyms.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/mrunit/solr.xml b/solr/contrib/morphlines-cell/src/test-files/solr/mrunit/solr.xml similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/mrunit/solr.xml rename to solr/contrib/morphlines-cell/src/test-files/solr/mrunit/solr.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/solr.xml b/solr/contrib/morphlines-cell/src/test-files/solr/solr.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/solr.xml rename to solr/contrib/morphlines-cell/src/test-files/solr/solr.xml diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/currency.xml b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/currency.xml similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/currency.xml rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/currency.xml diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/elevate.xml b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/elevate.xml similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/elevate.xml rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/elevate.xml diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_ca.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_ca.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_ca.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_ca.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_fr.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_fr.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_fr.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_fr.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_ga.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_ga.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_ga.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_ga.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_it.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_it.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_it.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/contractions_it.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/hyphenations_ga.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/hyphenations_ga.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/hyphenations_ga.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/hyphenations_ga.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stemdict_nl.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stemdict_nl.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stemdict_nl.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stemdict_nl.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stoptags_ja.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stoptags_ja.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stoptags_ja.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stoptags_ja.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ar.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ar.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ar.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ar.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_bg.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_bg.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_bg.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_bg.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ca.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ca.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ca.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ca.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_cz.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_cz.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_cz.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_cz.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_da.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_da.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_da.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_da.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_de.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_de.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_de.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_de.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_el.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_el.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_el.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_el.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_en.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_en.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_en.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_en.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_es.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_es.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_es.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_es.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_eu.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_eu.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_eu.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_eu.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fa.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fa.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fa.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fa.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fi.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fi.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fi.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fi.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fr.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fr.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fr.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_fr.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ga.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ga.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ga.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ga.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_gl.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_gl.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_gl.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_gl.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hi.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hi.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hi.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hi.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hu.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hu.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hu.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hu.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hy.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hy.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hy.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_hy.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_id.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_id.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_id.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_id.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_it.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_it.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_it.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_it.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ja.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ja.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ja.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ja.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_lv.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_lv.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_lv.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_lv.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_nl.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_nl.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_nl.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_nl.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_no.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_no.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_no.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_no.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_pt.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_pt.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_pt.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_pt.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ro.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ro.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ro.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ro.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ru.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ru.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ru.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_ru.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_sv.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_sv.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_sv.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_sv.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_th.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_th.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_th.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_th.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_tr.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_tr.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_tr.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/stopwords_tr.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/userdict_ja.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/userdict_ja.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/lang/userdict_ja.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/lang/userdict_ja.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/protwords.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/protwords.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/protwords.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/protwords.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/schema.xml b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/schema.xml similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/schema.xml rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/schema.xml diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/solrconfig.xml b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/solrconfig.xml similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/solrconfig.xml rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/solrconfig.xml diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/stopwords.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/stopwords.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/stopwords.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/stopwords.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/synonyms.txt b/solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/synonyms.txt similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcelltest/collection1/conf/synonyms.txt rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcelltest/collection1/conf/synonyms.txt diff --git a/solr/contrib/solr-mr/src/test-files/solr/solrcloud/conf/solrconfig.xml b/solr/contrib/morphlines-cell/src/test-files/solr/solrcloud/conf/solrconfig.xml similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solrcloud/conf/solrconfig.xml rename to solr/contrib/morphlines-cell/src/test-files/solr/solrcloud/conf/solrconfig.xml diff --git a/solr/contrib/solr-morphlines-cell/src/test/org/apache/solr/morphlines/cell/SolrCellMorphlineTest.java b/solr/contrib/morphlines-cell/src/test/org/apache/solr/morphlines/cell/SolrCellMorphlineTest.java similarity index 100% rename from solr/contrib/solr-morphlines-cell/src/test/org/apache/solr/morphlines/cell/SolrCellMorphlineTest.java rename to solr/contrib/morphlines-cell/src/test/org/apache/solr/morphlines/cell/SolrCellMorphlineTest.java diff --git a/solr/contrib/solr-morphlines-core/build.xml b/solr/contrib/morphlines-core/build.xml similarity index 98% rename from solr/contrib/solr-morphlines-core/build.xml rename to solr/contrib/morphlines-core/build.xml index ad11be1226c..859b0322e2b 100644 --- a/solr/contrib/solr-morphlines-core/build.xml +++ b/solr/contrib/morphlines-core/build.xml @@ -27,7 +27,7 @@ - diff --git a/solr/contrib/solr-morphlines-core/ivy.xml b/solr/contrib/morphlines-core/ivy.xml similarity index 98% rename from solr/contrib/solr-morphlines-core/ivy.xml rename to solr/contrib/morphlines-core/ivy.xml index abefff79135..c3712b7270c 100644 --- a/solr/contrib/solr-morphlines-core/ivy.xml +++ b/solr/contrib/morphlines-core/ivy.xml @@ -17,9 +17,9 @@ under the License. --> - + - + diff --git a/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/DocumentLoader.java b/solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/DocumentLoader.java similarity index 100% rename from solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/DocumentLoader.java rename to solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/DocumentLoader.java diff --git a/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/GenerateSolrSequenceKeyBuilder.java b/solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/GenerateSolrSequenceKeyBuilder.java similarity index 100% rename from solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/GenerateSolrSequenceKeyBuilder.java rename to solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/GenerateSolrSequenceKeyBuilder.java diff --git a/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/LoadSolrBuilder.java b/solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/LoadSolrBuilder.java similarity index 100% rename from solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/LoadSolrBuilder.java rename to solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/LoadSolrBuilder.java diff --git a/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/SafeConcurrentUpdateSolrServer.java b/solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/SafeConcurrentUpdateSolrServer.java similarity index 100% rename from solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/SafeConcurrentUpdateSolrServer.java rename to solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/SafeConcurrentUpdateSolrServer.java diff --git a/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/SanitizeUnknownSolrFieldsBuilder.java b/solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/SanitizeUnknownSolrFieldsBuilder.java similarity index 100% rename from solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/SanitizeUnknownSolrFieldsBuilder.java rename to solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/SanitizeUnknownSolrFieldsBuilder.java diff --git a/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/SolrLocator.java b/solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/SolrLocator.java similarity index 100% rename from solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/SolrLocator.java rename to solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/SolrLocator.java diff --git a/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/SolrMorphlineContext.java b/solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/SolrMorphlineContext.java similarity index 100% rename from solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/SolrMorphlineContext.java rename to solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/SolrMorphlineContext.java diff --git a/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/SolrServerDocumentLoader.java b/solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/SolrServerDocumentLoader.java similarity index 100% rename from solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/SolrServerDocumentLoader.java rename to solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/SolrServerDocumentLoader.java diff --git a/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/TokenizeTextBuilder.java b/solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/TokenizeTextBuilder.java similarity index 100% rename from solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/TokenizeTextBuilder.java rename to solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/TokenizeTextBuilder.java diff --git a/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/ZooKeeperDownloader.java b/solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/ZooKeeperDownloader.java similarity index 100% rename from solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/ZooKeeperDownloader.java rename to solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/ZooKeeperDownloader.java diff --git a/solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/package.html b/solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/package.html similarity index 100% rename from solr/contrib/solr-morphlines-core/src/java/org/apache/solr/morphlines/solr/package.html rename to solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/package.html diff --git a/solr/contrib/solr-morphlines-core/src/java/overview.html b/solr/contrib/morphlines-core/src/java/overview.html similarity index 100% rename from solr/contrib/solr-morphlines-core/src/java/overview.html rename to solr/contrib/morphlines-core/src/java/overview.html diff --git a/solr/contrib/solr-morphlines-core/src/test-files/README b/solr/contrib/morphlines-core/src/test-files/README similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/README rename to solr/contrib/morphlines-core/src/test-files/README diff --git a/solr/contrib/solr-morphlines-core/src/test-files/books_numeric_ids.csv b/solr/contrib/morphlines-core/src/test-files/books_numeric_ids.csv similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/books_numeric_ids.csv rename to solr/contrib/morphlines-core/src/test-files/books_numeric_ids.csv diff --git a/solr/contrib/solr-morphlines-core/src/test-files/exampledocs/example.html b/solr/contrib/morphlines-core/src/test-files/exampledocs/example.html similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/exampledocs/example.html rename to solr/contrib/morphlines-core/src/test-files/exampledocs/example.html diff --git a/solr/contrib/solr-morphlines-core/src/test-files/exampledocs/example.txt b/solr/contrib/morphlines-core/src/test-files/exampledocs/example.txt similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/exampledocs/example.txt rename to solr/contrib/morphlines-core/src/test-files/exampledocs/example.txt diff --git a/solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/README b/solr/contrib/morphlines-core/src/test-files/lib-dirs/README similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/README rename to solr/contrib/morphlines-core/src/test-files/lib-dirs/README diff --git a/solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/a/a1/empty-file-a1.txt b/solr/contrib/morphlines-core/src/test-files/lib-dirs/a/a1/empty-file-a1.txt similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/a/a1/empty-file-a1.txt rename to solr/contrib/morphlines-core/src/test-files/lib-dirs/a/a1/empty-file-a1.txt diff --git a/solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/a/a2/empty-file-a2.txt b/solr/contrib/morphlines-core/src/test-files/lib-dirs/a/a2/empty-file-a2.txt similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/a/a2/empty-file-a2.txt rename to solr/contrib/morphlines-core/src/test-files/lib-dirs/a/a2/empty-file-a2.txt diff --git a/solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/b/b1/empty-file-b1.txt b/solr/contrib/morphlines-core/src/test-files/lib-dirs/b/b1/empty-file-b1.txt similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/b/b1/empty-file-b1.txt rename to solr/contrib/morphlines-core/src/test-files/lib-dirs/b/b1/empty-file-b1.txt diff --git a/solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/b/b2/empty-file-b2.txt b/solr/contrib/morphlines-core/src/test-files/lib-dirs/b/b2/empty-file-b2.txt similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/b/b2/empty-file-b2.txt rename to solr/contrib/morphlines-core/src/test-files/lib-dirs/b/b2/empty-file-b2.txt diff --git a/solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/c/c1/empty-file-c1.txt b/solr/contrib/morphlines-core/src/test-files/lib-dirs/c/c1/empty-file-c1.txt similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/c/c1/empty-file-c1.txt rename to solr/contrib/morphlines-core/src/test-files/lib-dirs/c/c1/empty-file-c1.txt diff --git a/solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/c/c2/empty-file-c2.txt b/solr/contrib/morphlines-core/src/test-files/lib-dirs/c/c2/empty-file-c2.txt similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/c/c2/empty-file-c2.txt rename to solr/contrib/morphlines-core/src/test-files/lib-dirs/c/c2/empty-file-c2.txt diff --git a/solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/d/d1/empty-file-d1.txt b/solr/contrib/morphlines-core/src/test-files/lib-dirs/d/d1/empty-file-d1.txt similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/d/d1/empty-file-d1.txt rename to solr/contrib/morphlines-core/src/test-files/lib-dirs/d/d1/empty-file-d1.txt diff --git a/solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/d/d2/empty-file-d2.txt b/solr/contrib/morphlines-core/src/test-files/lib-dirs/d/d2/empty-file-d2.txt similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/lib-dirs/d/d2/empty-file-d2.txt rename to solr/contrib/morphlines-core/src/test-files/lib-dirs/d/d2/empty-file-d2.txt diff --git a/solr/contrib/solr-morphlines-core/src/test-files/log4j.properties b/solr/contrib/morphlines-core/src/test-files/log4j.properties similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/log4j.properties rename to solr/contrib/morphlines-core/src/test-files/log4j.properties diff --git a/solr/contrib/solr-morphlines-core/src/test-files/mailing_lists.pdf b/solr/contrib/morphlines-core/src/test-files/mailing_lists.pdf similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/mailing_lists.pdf rename to solr/contrib/morphlines-core/src/test-files/mailing_lists.pdf diff --git a/solr/contrib/solr-morphlines-core/src/test-files/old-solr-example/README.txt b/solr/contrib/morphlines-core/src/test-files/old-solr-example/README.txt similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/old-solr-example/README.txt rename to solr/contrib/morphlines-core/src/test-files/old-solr-example/README.txt diff --git a/solr/contrib/solr-morphlines-core/src/test-files/old-solr-example/solr.xml b/solr/contrib/morphlines-core/src/test-files/old-solr-example/solr.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/old-solr-example/solr.xml rename to solr/contrib/morphlines-core/src/test-files/old-solr-example/solr.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/addfields.updateprocessor.js b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/addfields.updateprocessor.js similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/addfields.updateprocessor.js rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/addfields.updateprocessor.js diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/analyzingInfixSuggest.txt b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/analyzingInfixSuggest.txt similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/analyzingInfixSuggest.txt rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/analyzingInfixSuggest.txt diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-currency.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-currency.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-currency.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-currency.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-mp-solrconfig.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-mp-solrconfig.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-mp-solrconfig.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-mp-solrconfig.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-analyzer-class-and-nested.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-analyzer-class-and-nested.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-analyzer-class-and-nested.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-analyzer-class-and-nested.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-bogus-analysis-parameters.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-bogus-analysis-parameters.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-bogus-analysis-parameters.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-bogus-analysis-parameters.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-bogus-field-parameters.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-bogus-field-parameters.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-bogus-field-parameters.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-bogus-field-parameters.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-codec-global-vs-ft-mismatch.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-codec-global-vs-ft-mismatch.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-codec-global-vs-ft-mismatch.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-codec-global-vs-ft-mismatch.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-dynamic-multivalued.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-dynamic-multivalued.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-dynamic-multivalued.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-dynamic-multivalued.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-ft-bogus-code-in-xml.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-ft-bogus-code-in-xml.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-ft-bogus-code-in-xml.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-ft-bogus-code-in-xml.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-ft-bogus-default-code.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-ft-bogus-default-code.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-ft-bogus-default-code.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-ft-bogus-default-code.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-ft-multivalued.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-ft-multivalued.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-ft-multivalued.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-ft-multivalued.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-ft-oer-norates.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-ft-oer-norates.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-ft-oer-norates.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-ft-oer-norates.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-multivalued.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-multivalued.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-multivalued.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-currency-multivalued.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dup-dynamicField.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dup-dynamicField.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dup-dynamicField.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dup-dynamicField.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dup-field.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dup-field.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dup-field.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dup-field.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dup-fieldType.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dup-fieldType.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dup-fieldType.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dup-fieldType.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dynamicfield-default-val.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dynamicfield-default-val.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dynamicfield-default-val.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dynamicfield-default-val.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dynamicfield-required.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dynamicfield-required.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dynamicfield-required.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-dynamicfield-required.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-external-filefield.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-external-filefield.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-external-filefield.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-external-filefield.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-misplaced-asterisk-copyfield-dest-should-fail-test.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-misplaced-asterisk-copyfield-dest-should-fail-test.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-misplaced-asterisk-copyfield-dest-should-fail-test.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-misplaced-asterisk-copyfield-dest-should-fail-test.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-misplaced-asterisk-copyfield-source-should-fail-test.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-misplaced-asterisk-copyfield-source-should-fail-test.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-misplaced-asterisk-copyfield-source-should-fail-test.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-misplaced-asterisk-copyfield-source-should-fail-test.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-multiple-asterisk-copyfield-dest-should-fail-test.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-multiple-asterisk-copyfield-dest-should-fail-test.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-multiple-asterisk-copyfield-dest-should-fail-test.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-multiple-asterisk-copyfield-dest-should-fail-test.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-multiple-asterisk-copyfield-source-should-fail-test.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-multiple-asterisk-copyfield-source-should-fail-test.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-multiple-asterisk-copyfield-source-should-fail-test.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-multiple-asterisk-copyfield-source-should-fail-test.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-non-glob-copyfield-source-matching-nothing-should-fail-test.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-non-glob-copyfield-source-matching-nothing-should-fail-test.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-non-glob-copyfield-source-matching-nothing-should-fail-test.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-non-glob-copyfield-source-matching-nothing-should-fail-test.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-nontext-analyzer.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-nontext-analyzer.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-nontext-analyzer.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-nontext-analyzer.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-not-indexed-but-norms.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-not-indexed-but-norms.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-not-indexed-but-norms.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-not-indexed-but-norms.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-not-indexed-but-pos.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-not-indexed-but-pos.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-not-indexed-but-pos.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-not-indexed-but-pos.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-not-indexed-but-tf.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-not-indexed-but-tf.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-not-indexed-but-tf.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-not-indexed-but-tf.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-omit-tf-but-not-pos.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-omit-tf-but-not-pos.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-omit-tf-but-not-pos.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-omit-tf-but-not-pos.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sim-global-vs-ft-mismatch.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sim-global-vs-ft-mismatch.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sim-global-vs-ft-mismatch.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sim-global-vs-ft-mismatch.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sweetspot-both-tf.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sweetspot-both-tf.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sweetspot-both-tf.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sweetspot-both-tf.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sweetspot-partial-baseline.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sweetspot-partial-baseline.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sweetspot-partial-baseline.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sweetspot-partial-baseline.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sweetspot-partial-hyperbolic.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sweetspot-partial-hyperbolic.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sweetspot-partial-hyperbolic.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sweetspot-partial-hyperbolic.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sweetspot-partial-norms.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sweetspot-partial-norms.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sweetspot-partial-norms.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-sweetspot-partial-norms.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-uniquekey-is-copyfield-dest.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-uniquekey-is-copyfield-dest.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-uniquekey-is-copyfield-dest.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-uniquekey-is-copyfield-dest.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-uniquekey-multivalued.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-uniquekey-multivalued.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-uniquekey-multivalued.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-uniquekey-multivalued.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-uniquekey-uses-default.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-uniquekey-uses-default.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-uniquekey-uses-default.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-uniquekey-uses-default.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-unsupported-docValues.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-unsupported-docValues.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-schema-unsupported-docValues.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-schema-unsupported-docValues.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-bogus-scriptengine-name.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-bogus-scriptengine-name.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-bogus-scriptengine-name.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-bogus-scriptengine-name.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-invalid-scriptfile.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-invalid-scriptfile.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-invalid-scriptfile.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-invalid-scriptfile.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-managed-schema-named-schema.xml.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-managed-schema-named-schema.xml.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-managed-schema-named-schema.xml.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-managed-schema-named-schema.xml.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-missing-scriptfile.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-missing-scriptfile.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-missing-scriptfile.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-missing-scriptfile.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-multiple-cfs.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-multiple-cfs.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-multiple-cfs.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-multiple-cfs.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-multiple-dirfactory.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-multiple-dirfactory.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-multiple-dirfactory.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-multiple-dirfactory.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-multiple-indexconfigs.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-multiple-indexconfigs.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-multiple-indexconfigs.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-multiple-indexconfigs.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-schema-mutable-but-not-managed.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-schema-mutable-but-not-managed.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-schema-mutable-but-not-managed.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-schema-mutable-but-not-managed.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-unexpected-schema-attribute.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-unexpected-schema-attribute.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-unexpected-schema-attribute.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-unexpected-schema-attribute.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-warmer-no-reopen.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-warmer-no-reopen.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-warmer-no-reopen.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad-solrconfig-warmer-no-reopen.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad_solrconfig.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad_solrconfig.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/bad_solrconfig.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/bad_solrconfig.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/compoundDictionary.txt b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/compoundDictionary.txt similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/compoundDictionary.txt rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/compoundDictionary.txt diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/conditional.updateprocessor.js b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/conditional.updateprocessor.js similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/conditional.updateprocessor.js rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/conditional.updateprocessor.js diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/currency.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/currency.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/currency.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/currency.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/da_UTF8.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/da_UTF8.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/da_UTF8.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/da_UTF8.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/da_compoundDictionary.txt b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/da_compoundDictionary.txt similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/da_compoundDictionary.txt rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/da_compoundDictionary.txt diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/elevate.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/elevate.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/elevate.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/elevate.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/frenchArticles.txt b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/frenchArticles.txt similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/frenchArticles.txt rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/frenchArticles.txt diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/fuzzysuggest.txt b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/fuzzysuggest.txt similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/fuzzysuggest.txt rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/fuzzysuggest.txt diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/hunspell-test.aff b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/hunspell-test.aff similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/hunspell-test.aff rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/hunspell-test.aff diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/hunspell-test.dic b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/hunspell-test.dic similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/hunspell-test.dic rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/hunspell-test.dic diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/hyphenation.dtd b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/hyphenation.dtd similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/hyphenation.dtd rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/hyphenation.dtd diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/jasuggest.txt b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/jasuggest.txt similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/jasuggest.txt rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/jasuggest.txt diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/keep-1.txt b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/keep-1.txt similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/keep-1.txt rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/keep-1.txt diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/keep-2.txt b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/keep-2.txt similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/keep-2.txt rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/keep-2.txt diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/mapping-ISOLatin1Accent.txt b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/mapping-ISOLatin1Accent.txt similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/mapping-ISOLatin1Accent.txt rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/mapping-ISOLatin1Accent.txt diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/missing.functions.updateprocessor.js b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/missing.functions.updateprocessor.js similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/missing.functions.updateprocessor.js rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/missing.functions.updateprocessor.js diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/missleading.extension.updateprocessor.js.txt b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/missleading.extension.updateprocessor.js.txt similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/missleading.extension.updateprocessor.js.txt rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/missleading.extension.updateprocessor.js.txt diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/old_synonyms.txt b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/old_synonyms.txt similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/old_synonyms.txt rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/old_synonyms.txt diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/open-exchange-rates.json b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/open-exchange-rates.json similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/open-exchange-rates.json rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/open-exchange-rates.json diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/phrasesuggest.txt b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/phrasesuggest.txt similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/phrasesuggest.txt rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/phrasesuggest.txt diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/protwords.txt b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/protwords.txt similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/protwords.txt rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/protwords.txt diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/regex-boost-processor-test.txt b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/regex-boost-processor-test.txt similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/regex-boost-processor-test.txt rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/regex-boost-processor-test.txt diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-add-schema-fields-update-processor.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-add-schema-fields-update-processor.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-add-schema-fields-update-processor.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-add-schema-fields-update-processor.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-behavior.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-behavior.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-behavior.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-behavior.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-binaryfield.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-binaryfield.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-binaryfield.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-binaryfield.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-bm25.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-bm25.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-bm25.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-bm25.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-charfilters.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-charfilters.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-charfilters.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-charfilters.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-class-name-shortening-on-serialization.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-class-name-shortening-on-serialization.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-class-name-shortening-on-serialization.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-class-name-shortening-on-serialization.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-collate.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-collate.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-collate.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-collate.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-copyfield-test.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-copyfield-test.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-copyfield-test.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-copyfield-test.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-dfr.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-dfr.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-dfr.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-dfr.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-docValues.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-docValues.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-docValues.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-docValues.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-docValuesFaceting.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-docValuesFaceting.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-docValuesFaceting.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-docValuesFaceting.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-docValuesMissing.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-docValuesMissing.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-docValuesMissing.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-docValuesMissing.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-docValuesMulti.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-docValuesMulti.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-docValuesMulti.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-docValuesMulti.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-eff.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-eff.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-eff.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-eff.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-folding.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-folding.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-folding.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-folding.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-ib.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-ib.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-ib.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-ib.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-id-and-version-fields-only.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-id-and-version-fields-only.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-id-and-version-fields-only.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-id-and-version-fields-only.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-lmdirichlet.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-lmdirichlet.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-lmdirichlet.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-lmdirichlet.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-lmjelinekmercer.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-lmjelinekmercer.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-lmjelinekmercer.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-lmjelinekmercer.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-luceneMatchVersion.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-luceneMatchVersion.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-luceneMatchVersion.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-luceneMatchVersion.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-minimal.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-minimal.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-minimal.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-minimal.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-not-required-unique-key.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-not-required-unique-key.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-not-required-unique-key.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-not-required-unique-key.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-numeric.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-numeric.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-numeric.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-numeric.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-one-field-no-dynamic-field-unique-key.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-one-field-no-dynamic-field-unique-key.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-one-field-no-dynamic-field-unique-key.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-one-field-no-dynamic-field-unique-key.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-one-field-no-dynamic-field.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-one-field-no-dynamic-field.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-one-field-no-dynamic-field.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-one-field-no-dynamic-field.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-phrasesuggest.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-phrasesuggest.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-phrasesuggest.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-phrasesuggest.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-postingshighlight.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-postingshighlight.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-postingshighlight.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-postingshighlight.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-replication1.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-replication1.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-replication1.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-replication1.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-replication2.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-replication2.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-replication2.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-replication2.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-required-fields.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-required-fields.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-required-fields.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-required-fields.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-rest-lucene-match-version.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-rest-lucene-match-version.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-rest-lucene-match-version.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-rest-lucene-match-version.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-rest.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-rest.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-rest.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-rest.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-reversed.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-reversed.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-reversed.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-reversed.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-sim.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-sim.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-sim.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-sim.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-snippet-field.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-snippet-field.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-snippet-field.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-snippet-field.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-snippet-type.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-snippet-type.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-snippet-type.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-snippet-type.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-snippet-types.incl b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-snippet-types.incl similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-snippet-types.incl rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-snippet-types.incl diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-spatial.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-spatial.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-spatial.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-spatial.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-spellchecker.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-spellchecker.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-spellchecker.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-spellchecker.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-stop-keep.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-stop-keep.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-stop-keep.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-stop-keep.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-sweetspot.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-sweetspot.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-sweetspot.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-sweetspot.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-synonym-tokenizer.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-synonym-tokenizer.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-synonym-tokenizer.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-synonym-tokenizer.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-tfidf.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-tfidf.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-tfidf.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-tfidf.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-tiny.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-tiny.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-tiny.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-tiny.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-trie.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-trie.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-trie.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-trie.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-xinclude.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-xinclude.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema-xinclude.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema-xinclude.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema11.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema11.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema11.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema11.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema12.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema12.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema12.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema12.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema15.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema15.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema15.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema15.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema_codec.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema_codec.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schema_codec.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schema_codec.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schemasurround.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schemasurround.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/schemasurround.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/schemasurround.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-SOLR-749.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-SOLR-749.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-SOLR-749.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-SOLR-749.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-add-schema-fields-update-processor-chains.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-add-schema-fields-update-processor-chains.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-add-schema-fields-update-processor-chains.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-add-schema-fields-update-processor-chains.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-altdirectory.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-altdirectory.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-altdirectory.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-altdirectory.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-basic.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-basic.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-basic.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-basic.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-caching.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-caching.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-caching.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-caching.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-components-name.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-components-name.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-components-name.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-components-name.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-defaults.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-defaults.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-defaults.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-defaults.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-delpolicy1.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-delpolicy1.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-delpolicy1.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-delpolicy1.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-delpolicy2.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-delpolicy2.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-delpolicy2.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-delpolicy2.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-elevate.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-elevate.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-elevate.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-elevate.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-functionquery.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-functionquery.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-functionquery.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-functionquery.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-highlight.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-highlight.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-highlight.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-highlight.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-implicitproperties.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-implicitproperties.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-implicitproperties.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-implicitproperties.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-indexconfig.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-indexconfig.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-indexconfig.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-indexconfig.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-infostream-logging.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-infostream-logging.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-infostream-logging.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-infostream-logging.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-lazywriter.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-lazywriter.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-lazywriter.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-lazywriter.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-logmergepolicy.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-logmergepolicy.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-logmergepolicy.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-logmergepolicy.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-managed-schema.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-managed-schema.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-managed-schema.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-managed-schema.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master1-keepOneBackup.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master1-keepOneBackup.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master1-keepOneBackup.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master1-keepOneBackup.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master1.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master1.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master1.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master1.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master2.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master2.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master2.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master2.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master3.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master3.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master3.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-master3.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-mergepolicy-defaults.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-mergepolicy-defaults.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-mergepolicy-defaults.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-mergepolicy-defaults.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-mergepolicy-legacy.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-mergepolicy-legacy.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-mergepolicy-legacy.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-mergepolicy-legacy.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-minimal.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-minimal.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-minimal.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-minimal.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-nocache.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-nocache.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-nocache.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-nocache.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-noopregen.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-noopregen.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-noopregen.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-noopregen.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-parsing-update-processor-chains.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-parsing-update-processor-chains.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-parsing-update-processor-chains.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-parsing-update-processor-chains.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-phrasesuggest.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-phrasesuggest.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-phrasesuggest.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-phrasesuggest.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-postingshighlight.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-postingshighlight.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-postingshighlight.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-postingshighlight.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-querysender-noquery.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-querysender-noquery.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-querysender-noquery.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-querysender-noquery.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-querysender.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-querysender.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-querysender.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-querysender.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-repeater.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-repeater.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-repeater.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-repeater.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-reqHandler.incl b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-reqHandler.incl similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-reqHandler.incl rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-reqHandler.incl diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-response-log-component.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-response-log-component.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-response-log-component.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-response-log-component.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-script-updateprocessor.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-script-updateprocessor.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-script-updateprocessor.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-script-updateprocessor.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-slave.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-slave.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-slave.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-slave.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-slave1.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-slave1.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-slave1.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-slave1.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-snippet-processor.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-snippet-processor.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-snippet-processor.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-snippet-processor.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-solcoreproperties.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-solcoreproperties.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-solcoreproperties.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-solcoreproperties.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-spellcheckcomponent.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-spellcheckcomponent.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-spellcheckcomponent.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-spellcheckcomponent.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-spellchecker.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-spellchecker.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-spellchecker.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-spellchecker.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-test-misc.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-test-misc.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-test-misc.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-test-misc.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-tieredmergepolicy.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-tieredmergepolicy.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-tieredmergepolicy.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-tieredmergepolicy.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-tlog.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-tlog.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-tlog.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-tlog.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-transformers.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-transformers.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-transformers.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-transformers.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-update-processor-chains.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-update-processor-chains.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-update-processor-chains.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-update-processor-chains.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-warmer.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-warmer.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-warmer.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-warmer.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-xinclude.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-xinclude.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig-xinclude.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig-xinclude.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig.snippet.randomindexconfig.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig.snippet.randomindexconfig.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig.snippet.randomindexconfig.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig.snippet.randomindexconfig.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig_codec.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig_codec.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig_codec.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig_codec.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig_perf.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig_perf.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/solrconfig_perf.xml rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig_perf.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stemdict.txt b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/stemdict.txt similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stemdict.txt rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/stemdict.txt diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stop-1.txt b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/stop-1.txt similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stop-1.txt rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/stop-1.txt diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stop-2.txt b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/stop-2.txt similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stop-2.txt rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/stop-2.txt diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stop-snowball.txt b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/stop-snowball.txt similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stop-snowball.txt rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/stop-snowball.txt diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stoptypes-1.txt b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/stoptypes-1.txt similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stoptypes-1.txt rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/stoptypes-1.txt diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stoptypes-2.txt b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/stoptypes-2.txt similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stoptypes-2.txt rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/stoptypes-2.txt diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stopwithbom.txt b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/stopwithbom.txt similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stopwithbom.txt rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/stopwithbom.txt diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stopwords.txt b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/stopwords.txt similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stopwords.txt rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/stopwords.txt diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stopwordsWrongEncoding.txt b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/stopwordsWrongEncoding.txt similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/stopwordsWrongEncoding.txt rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/stopwordsWrongEncoding.txt diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/synonyms.txt b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/synonyms.txt similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/synonyms.txt rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/synonyms.txt diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/throw.error.on.add.updateprocessor.js b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/throw.error.on.add.updateprocessor.js similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/throw.error.on.add.updateprocessor.js rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/throw.error.on.add.updateprocessor.js diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/trivial.updateprocessor0.js b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/trivial.updateprocessor0.js similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/trivial.updateprocessor0.js rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/trivial.updateprocessor0.js diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/trivial.updateprocessor1.js b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/trivial.updateprocessor1.js similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/trivial.updateprocessor1.js rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/trivial.updateprocessor1.js diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/wdftypes.txt b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/wdftypes.txt similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/wdftypes.txt rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/wdftypes.txt diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/xslt/dummy-using-include.xsl b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/xslt/dummy-using-include.xsl similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/xslt/dummy-using-include.xsl rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/xslt/dummy-using-include.xsl diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/xslt/dummy.xsl b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/xslt/dummy.xsl similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/xslt/dummy.xsl rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/xslt/dummy.xsl diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/xslt/xsl-update-handler-test.xsl b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/xslt/xsl-update-handler-test.xsl similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/conf/xslt/xsl-update-handler-test.xsl rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/xslt/xsl-update-handler-test.xsl diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/lib/README b/solr/contrib/morphlines-core/src/test-files/solr/collection1/lib/README similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/lib/README rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/lib/README diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/lib/classes/empty-file-main-lib.txt b/solr/contrib/morphlines-core/src/test-files/solr/collection1/lib/classes/empty-file-main-lib.txt similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/collection1/lib/classes/empty-file-main-lib.txt rename to solr/contrib/morphlines-core/src/test-files/solr/collection1/lib/classes/empty-file-main-lib.txt diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/conf/core.properties b/solr/contrib/morphlines-core/src/test-files/solr/conf/core.properties similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/conf/core.properties rename to solr/contrib/morphlines-core/src/test-files/solr/conf/core.properties diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/crazy-path-to-config.xml b/solr/contrib/morphlines-core/src/test-files/solr/crazy-path-to-config.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/crazy-path-to-config.xml rename to solr/contrib/morphlines-core/src/test-files/solr/crazy-path-to-config.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/crazy-path-to-schema.xml b/solr/contrib/morphlines-core/src/test-files/solr/crazy-path-to-schema.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/crazy-path-to-schema.xml rename to solr/contrib/morphlines-core/src/test-files/solr/crazy-path-to-schema.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/external_eff b/solr/contrib/morphlines-core/src/test-files/solr/external_eff similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/external_eff rename to solr/contrib/morphlines-core/src/test-files/solr/external_eff diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/solr-50-all.xml b/solr/contrib/morphlines-core/src/test-files/solr/solr-50-all.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/solr-50-all.xml rename to solr/contrib/morphlines-core/src/test-files/solr/solr-50-all.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/solr-multicore.xml b/solr/contrib/morphlines-core/src/test-files/solr/solr-multicore.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/solr-multicore.xml rename to solr/contrib/morphlines-core/src/test-files/solr/solr-multicore.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/solr-no-core.xml b/solr/contrib/morphlines-core/src/test-files/solr/solr-no-core.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/solr-no-core.xml rename to solr/contrib/morphlines-core/src/test-files/solr/solr-no-core.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/solr-shardhandler-old.xml b/solr/contrib/morphlines-core/src/test-files/solr/solr-shardhandler-old.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/solr-shardhandler-old.xml rename to solr/contrib/morphlines-core/src/test-files/solr/solr-shardhandler-old.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/solr-shardhandler.xml b/solr/contrib/morphlines-core/src/test-files/solr/solr-shardhandler.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/solr-shardhandler.xml rename to solr/contrib/morphlines-core/src/test-files/solr/solr-shardhandler.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/solr-stress-new.xml b/solr/contrib/morphlines-core/src/test-files/solr/solr-stress-new.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/solr-stress-new.xml rename to solr/contrib/morphlines-core/src/test-files/solr/solr-stress-new.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/solr/solr-stress-old.xml b/solr/contrib/morphlines-core/src/test-files/solr/solr-stress-old.xml similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/solr/solr-stress-old.xml rename to solr/contrib/morphlines-core/src/test-files/solr/solr-stress-old.xml diff --git a/solr/contrib/solr-mr/src/test-files/solr/solr.xml b/solr/contrib/morphlines-core/src/test-files/solr/solr.xml similarity index 100% rename from solr/contrib/solr-mr/src/test-files/solr/solr.xml rename to solr/contrib/morphlines-core/src/test-files/solr/solr.xml diff --git a/solr/contrib/solr-morphlines-core/src/test-files/spellings.txt b/solr/contrib/morphlines-core/src/test-files/spellings.txt similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test-files/spellings.txt rename to solr/contrib/morphlines-core/src/test-files/spellings.txt diff --git a/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/AbstractSolrMorphlineTestBase.java b/solr/contrib/morphlines-core/src/test/org/apache/solr/morphlines/solr/AbstractSolrMorphlineTestBase.java similarity index 99% rename from solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/AbstractSolrMorphlineTestBase.java rename to solr/contrib/morphlines-core/src/test/org/apache/solr/morphlines/solr/AbstractSolrMorphlineTestBase.java index ac562e66ac7..9ffe6f63220 100644 --- a/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/AbstractSolrMorphlineTestBase.java +++ b/solr/contrib/morphlines-core/src/test/org/apache/solr/morphlines/solr/AbstractSolrMorphlineTestBase.java @@ -68,7 +68,7 @@ public class AbstractSolrMorphlineTestBase extends SolrTestCaseJ4 { protected static final String EXTERNAL_SOLR_SERVER_URL = System.getProperty("externalSolrServer"); // protected static final String EXTERNAL_SOLR_SERVER_URL = "http://127.0.0.1:8983/solr"; - protected static final String RESOURCES_DIR = ExternalPaths.SOURCE_HOME + "/contrib/solr-mr/src/test-files"; + protected static final String RESOURCES_DIR = ExternalPaths.SOURCE_HOME + "/contrib/map-reduce/src/test-files"; protected static final String DEFAULT_BASE_DIR = "solr"; protected static final AtomicInteger SEQ_NUM = new AtomicInteger(); protected static final AtomicInteger SEQ_NUM2 = new AtomicInteger(); diff --git a/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/AbstractSolrMorphlineZkTestBase.java b/solr/contrib/morphlines-core/src/test/org/apache/solr/morphlines/solr/AbstractSolrMorphlineZkTestBase.java similarity index 99% rename from solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/AbstractSolrMorphlineZkTestBase.java rename to solr/contrib/morphlines-core/src/test/org/apache/solr/morphlines/solr/AbstractSolrMorphlineZkTestBase.java index 62cf325d5a7..615c2ccc733 100644 --- a/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/AbstractSolrMorphlineZkTestBase.java +++ b/solr/contrib/morphlines-core/src/test/org/apache/solr/morphlines/solr/AbstractSolrMorphlineZkTestBase.java @@ -49,7 +49,7 @@ import com.typesafe.config.Config; public abstract class AbstractSolrMorphlineZkTestBase extends AbstractFullDistribZkTestBase { private static final File solrHomeDirectory = new File(TEMP_DIR, AbstractSolrMorphlineZkTestBase.class.getName()); - protected static final String RESOURCES_DIR = ExternalPaths.SOURCE_HOME + "/contrib/solr-mr/src/test-files"; + protected static final String RESOURCES_DIR = ExternalPaths.SOURCE_HOME + "/contrib/map-reduce/src/test-files"; private static final File SOLR_INSTANCE_DIR = new File(RESOURCES_DIR + "/solr"); private static final File SOLR_CONF_DIR = new File(RESOURCES_DIR + "/solr/collection1"); diff --git a/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/CollectingDocumentLoader.java b/solr/contrib/morphlines-core/src/test/org/apache/solr/morphlines/solr/CollectingDocumentLoader.java similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/CollectingDocumentLoader.java rename to solr/contrib/morphlines-core/src/test/org/apache/solr/morphlines/solr/CollectingDocumentLoader.java diff --git a/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/EmbeddedTestSolrServer.java b/solr/contrib/morphlines-core/src/test/org/apache/solr/morphlines/solr/EmbeddedTestSolrServer.java similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/EmbeddedTestSolrServer.java rename to solr/contrib/morphlines-core/src/test/org/apache/solr/morphlines/solr/EmbeddedTestSolrServer.java diff --git a/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineTest.java b/solr/contrib/morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineTest.java similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineTest.java rename to solr/contrib/morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineTest.java diff --git a/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkAliasTest.java b/solr/contrib/morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkAliasTest.java similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkAliasTest.java rename to solr/contrib/morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkAliasTest.java diff --git a/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkAvroTest.java b/solr/contrib/morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkAvroTest.java similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkAvroTest.java rename to solr/contrib/morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkAvroTest.java diff --git a/solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkTest.java b/solr/contrib/morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkTest.java similarity index 100% rename from solr/contrib/solr-morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkTest.java rename to solr/contrib/morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkTest.java diff --git a/solr/example/scripts/map-reduce/map-reduce-indexer.bat b/solr/example/scripts/map-reduce/map-reduce-indexer.bat new file mode 100644 index 00000000000..0817dee7880 --- /dev/null +++ b/solr/example/scripts/map-reduce/map-reduce-indexer.bat @@ -0,0 +1,9 @@ + +set JVM=java + +REM Find location of this script + +set SDIR=%~dp0 +if "%SDIR:~-1%"=="\" set SDIR=%SDIR:~0,-1% + +"%JVM%" -classpath "%SDIR%\..\..\..\dist\*:%SDIR%\..\..\..\contrib\map-reduce\lib\*:%SDIR%\..\..\..\contrib\morphlines-core\lib\*:%SDIR%\..\..\..\contrib\morphlines-cell\lib\*:%SDIR%\..\..\..\contrib\extraction\lib\*:%SDIR%\..\..\solr-webapp\webapp\WEB-INF\lib\*:%SDIR%\..\..\lib\ext\*" org.apache.solr.hadoop.MapReduceIndexerTool %* diff --git a/solr/example/scripts/map-reduce/map-reduce-indexer.sh b/solr/example/scripts/map-reduce/map-reduce-indexer.sh new file mode 100644 index 00000000000..db361ed2614 --- /dev/null +++ b/solr/example/scripts/map-reduce/map-reduce-indexer.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +JVM="java" + +# Find location of this script + +sdir="`dirname \"$0\"`" + +PATH=$JAVA_HOME/bin:$PATH $JVM -cp "$sdir/../../../dist/*:$sdir/../../../contrib/map-reduce/lib/*:$sdir/../../../contrib/morphlines-core/lib/*:$sdir/../../../contrib/morphlines-cell/lib/*:$sdir/../../../contrib/extraction/lib/*:$sdir/../../solr-webapp/webapp/WEB-INF/lib/*:$sdir/../../lib/ext/*" org.apache.solr.hadoop.MapReduceIndexerTool ${1+"$@"} + diff --git a/solr/example/scripts/solr-mr/solr-mr.bat b/solr/example/scripts/solr-mr/solr-mr.bat deleted file mode 100644 index 89f934628bd..00000000000 --- a/solr/example/scripts/solr-mr/solr-mr.bat +++ /dev/null @@ -1,9 +0,0 @@ - -set JVM=java - -REM Find location of this script - -set SDIR=%~dp0 -if "%SDIR:~-1%"=="\" set SDIR=%SDIR:~0,-1% - -"%JVM%" -classpath "%SDIR%\..\..\..\dist\*:%SDIR%\..\..\..\contrib\solr-mr\lib\*:%SDIR%\..\..\..\contrib\solr-morphlines-core\lib\*:%SDIR%\..\..\..\contrib\solr-morphlines-cell\lib\*:%SDIR%\..\..\..\contrib\extraction\lib\*:%SDIR%\..\..\solr-webapp\solr\WEB-INF\lib\*:%SDIR%\..\..\lib\ext\*" org.apache.solr.hadoop.MapReduceIndexerTool %* diff --git a/solr/example/scripts/solr-mr/solr-mr.sh b/solr/example/scripts/solr-mr/solr-mr.sh deleted file mode 100644 index f48eaae336b..00000000000 --- a/solr/example/scripts/solr-mr/solr-mr.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bash - -JVM="java" - -# Find location of this script - -sdir="`dirname \"$0\"`" - -PATH=$JAVA_HOME/bin:$PATH $JVM -cp "$sdir/../../../dist/*:$sdir/../../../contrib/solr-mr/lib/*:$sdir/../../../contrib/solr-morphlines-core/lib/*:$sdir/../../../contrib/solr-morphlines-cell/lib/*:$sdir/../../../contrib/extraction/lib/*:$sdir/../../solr-webapp/solr/WEB-INF/lib/*:$sdir/../../lib/ext/*" org.apache.solr.hadoop.MapReduceIndexerTool ${1+"$@"} - From 1ae2e523dff8ae4603f3669d532c1beb9b4f35ae Mon Sep 17 00:00:00 2001 From: Shalin Shekhar Mangar Date: Wed, 4 Dec 2013 15:54:06 +0000 Subject: [PATCH 182/223] SOLR-5502: Moving change log entry to the other section because this bug hasn't been released yet git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1547835 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 0d9bd902b80..f5effc0c60b 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -189,9 +189,6 @@ Bug Fixes * SOLR-5527: DIH logs spurious warning for special commands. (shalin) -* SOLR-5502: A "/" in a document id will cause an exception to be thrown - when using the composite id router. (Anshum Gupta via Mark Miller) - * SOLR-5524: Exception when using Query Function inside Scale Function. (Trey Grainger, yonik) @@ -229,6 +226,9 @@ Other Changes * SOLR-5517: Return HTTP error on POST requests with no Content-Type. (Ryan Ernst, Uwe Schindler) +* SOLR-5502: Added a test for tri-level compositeId routing with documents + having a "/" in a document id. (Anshum Gupta via Mark Miller) + ================== 4.6.0 ================== Versions of Major Components From b2a253a93011fd74e27d52c7e808ff4d390026d0 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Wed, 4 Dec 2013 18:28:45 +0000 Subject: [PATCH 183/223] SOLR-1301: Merge in latest solr-map-reduce updates. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1547871 13f79535-47bb-0310-9956-ffa450edef68 --- .../solr/hadoop/AlphaNumericComparator.java | 76 ++++++++ .../org/apache/solr/hadoop/BatchWriter.java | 8 +- .../solr/hadoop/MapReduceIndexerTool.java | 168 +++++++++++++++--- .../org/apache/solr/hadoop/SolrReducer.java | 20 +++ .../apache/solr/hadoop/TreeMergeMapper.java | 2 + .../solr/hadoop/TreeMergeOutputFormat.java | 33 +++- .../solr/hadoop/ZooKeeperInspector.java | 4 +- .../hadoop/AlphaNumericComparatorTest.java | 46 +++++ .../org/apache/solr/hadoop/MRUnitBase.java | 1 + .../solr/hadoop/MorphlineBasicMiniMRTest.java | 3 +- .../hadoop/MorphlineGoLiveMiniMRTest.java | 147 +++++++++++---- .../solr/hadoop/MorphlineReducerTest.java | 61 ++++--- 12 files changed, 481 insertions(+), 88 deletions(-) create mode 100644 solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/AlphaNumericComparator.java create mode 100644 solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/AlphaNumericComparatorTest.java diff --git a/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/AlphaNumericComparator.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/AlphaNumericComparator.java new file mode 100644 index 00000000000..cd8f183cee1 --- /dev/null +++ b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/AlphaNumericComparator.java @@ -0,0 +1,76 @@ +//The MIT License +// +// Copyright (c) 2003 Ron Alford, Mike Grove, Bijan Parsia, Evren Sirin +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +package org.apache.solr.hadoop; + +import java.util.Comparator; + +/** + * This is a comparator to perform a mix of alphabetical+numeric comparison. For + * example, if there is a list {"test10", "test2", "test150", "test25", "test1"} + * then what we generally expect from the ordering is the result {"test1", + * "test2", "test10", "test25", "test150"}. However, standard lexigraphic + * ordering does not do that and "test10" comes before "test2". This class is + * provided to overcome that problem. This functionality is useful to sort the + * benchmark files (like the ones in in DL-benchmark-suite) from smallest to the + * largest. Comparisons are done on the String values retuned by toString() so + * care should be taken when this comparator is used to sort arbitrary Java + * objects. + * + */ +final class AlphaNumericComparator implements Comparator { + + public AlphaNumericComparator() { + } + + public int compare(Object o1, Object o2) { + String s1 = o1.toString(); + String s2 = o2.toString(); + int n1 = s1.length(), n2 = s2.length(); + int i1 = 0, i2 = 0; + while (i1 < n1 && i2 < n2) { + int p1 = i1; + int p2 = i2; + char c1 = s1.charAt(i1++); + char c2 = s2.charAt(i2++); + if(c1 != c2) { + if (Character.isDigit(c1) && Character.isDigit(c2)) { + int value1 = 0, value2 = 0; + while (i1 < n1 && Character.isDigit(c1 = s1.charAt(i1))) { + i1++; + } + value1 = Integer.parseInt(s1.substring(p1, i1)); + while (i2 < n2 && Character.isDigit(c2 = s2.charAt(i2))) { + i2++; + } + value2 = Integer.parseInt(s2.substring(p2, i2)); + if (value1 != value2) { + return value1 - value2; + } + } + return c1 - c2; + } + } + + return n1 - n2; + } +} \ No newline at end of file diff --git a/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/BatchWriter.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/BatchWriter.java index 6b650b6cc7b..06818ec4c8f 100644 --- a/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/BatchWriter.java +++ b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/BatchWriter.java @@ -196,8 +196,8 @@ class BatchWriter { batchPool.awaitTermination(5, TimeUnit.SECONDS); } } - //reporter.setStatus("Committing Solr"); - //solr.commit(true, false); + context.setStatus("Committing Solr Phase 1"); + solr.commit(true, false); context.setStatus("Optimizing Solr"); int maxSegments = context.getConfiguration().getInt(SolrOutputFormat.SOLR_RECORD_WRITER_MAX_SEGMENTS, 1); LOG.info("Optimizing Solr: forcing merge down to {} segments", maxSegments); @@ -206,9 +206,9 @@ class BatchWriter { context.getCounter(SolrCounters.class.getName(), SolrCounters.PHYSICAL_REDUCER_MERGE_TIME.toString()).increment(System.currentTimeMillis() - start); float secs = (System.currentTimeMillis() - start) / 1000.0f; LOG.info("Optimizing Solr: done forcing merge down to {} segments in {} secs", maxSegments, secs); + context.setStatus("Committing Solr Phase 2"); + solr.commit(true, false); context.setStatus("Shutting down Solr"); - // TODO is core close needed? - according to TestEmbeddedSolrServer it's not... - //core.close(); solr.shutdown(); } diff --git a/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/MapReduceIndexerTool.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/MapReduceIndexerTool.java index e0e3e62709f..b6b432ad705 100644 --- a/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/MapReduceIndexerTool.java +++ b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/MapReduceIndexerTool.java @@ -33,10 +33,13 @@ import java.io.Writer; import java.net.URISyntaxException; import java.net.URL; import java.net.URLClassLoader; +import java.text.NumberFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.Comparator; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Random; @@ -80,6 +83,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.cloudera.cdk.morphline.base.Fields; +import com.google.common.base.Charsets; +import com.google.common.base.Preconditions; +import com.google.common.io.ByteStreams; /** @@ -107,6 +113,10 @@ public class MapReduceIndexerTool extends Configured implements Tool { */ static final class MyArgumentParser { + private static final String SHOW_NON_SOLR_CLOUD = "--show-non-solr-cloud"; + + private boolean showNonSolrCloud = false; + /** * Parses the given command line arguments. * @@ -123,6 +133,8 @@ public class MapReduceIndexerTool extends Configured implements Tool { args = new String[] { "--help" }; } + showNonSolrCloud = Arrays.asList(args).contains(SHOW_NON_SOLR_CLOUD); // intercept it first + ArgumentParser parser = ArgumentParsers .newArgumentParser("hadoop [GenericOptions]... jar search-mr-*-job.jar " + MapReduceIndexerTool.class.getName(), false) .defaultHelp(true) @@ -297,7 +309,7 @@ public class MapReduceIndexerTool extends Configured implements Tool { "specified by --morphline-file. If the --morphline-id option is ommitted the first (i.e. " + "top-most) morphline within the config file is used. Example: morphline1"); - Argument solrHomeDirArg = parser.addArgument("--solr-home-dir") + Argument solrHomeDirArg = nonSolrCloud(parser.addArgument("--solr-home-dir") .metavar("DIR") .type(new FileArgumentType() { @Override @@ -312,7 +324,7 @@ public class MapReduceIndexerTool extends Configured implements Tool { .required(false) .help("Relative or absolute path to a local dir containing Solr conf/ dir and in particular " + "conf/solrconfig.xml and optionally also lib/ dir. This directory will be uploaded to each MR task. " + - "Example: src/test/resources/solr/minimr"); + "Example: src/test/resources/solr/minimr")); Argument updateConflictResolverArg = parser.addArgument("--update-conflict-resolver") .metavar("FQCN") @@ -404,25 +416,20 @@ public class MapReduceIndexerTool extends Configured implements Tool { .action(Arguments.storeTrue()) .help("Turn on verbose output."); + parser.addArgument(SHOW_NON_SOLR_CLOUD) + .action(Arguments.storeTrue()) + .help("Also show options for Non-SolrCloud mode as part of --help."); + ArgumentGroup clusterInfoGroup = parser .addArgumentGroup("Cluster arguments") .description( "Arguments that provide information about your Solr cluster. " - + "If you are not using --go-live, pass the --shards argument. If you are building shards for " - + "a Non-SolrCloud cluster, pass the --shard-url argument one or more times. To build indexes for" - + " a replicated cluster with --shard-url, pass replica urls consecutively and also pass --shards. " - + "If you are building shards for a SolrCloud cluster, pass the --zk-host argument. " - + "Using --go-live requires either --shard-url or --zk-host."); + + nonSolrCloud("If you are building shards for a SolrCloud cluster, pass the --zk-host argument. " + + "If you are building shards for " + + "a Non-SolrCloud cluster, pass the --shard-url argument one or more times. To build indexes for " + + "a replicated Non-SolrCloud cluster with --shard-url, pass replica urls consecutively and also pass --shards. " + + "Using --go-live requires either --zk-host or --shard-url.")); - Argument shardUrlsArg = clusterInfoGroup.addArgument("--shard-url") - .metavar("URL") - .type(String.class) - .action(Arguments.append()) - .help("Solr URL to merge resulting shard into if using --go-live. " + - "Example: http://solr001.mycompany.com:8983/solr/collection1. " + - "Multiple --shard-url arguments can be specified, one for each desired shard. " + - "If you are merging shards into a SolrCloud cluster, use --zk-host instead."); - Argument zkHostArg = clusterInfoGroup.addArgument("--zk-host") .metavar("STRING") .type(String.class) @@ -444,15 +451,24 @@ public class MapReduceIndexerTool extends Configured implements Tool { + "would be relative to this root - i.e. getting/setting/etc... " + "'/foo/bar' would result in operations being run on " + "'/solr/foo/bar' (from the server perspective).\n" - + "\n" + + nonSolrCloud("\n" + "If --solr-home-dir is not specified, the Solr home directory for the collection " - + "will be downloaded from this ZooKeeper ensemble."); + + "will be downloaded from this ZooKeeper ensemble.")); - Argument shardsArg = clusterInfoGroup.addArgument("--shards") + Argument shardUrlsArg = nonSolrCloud(clusterInfoGroup.addArgument("--shard-url") + .metavar("URL") + .type(String.class) + .action(Arguments.append()) + .help("Solr URL to merge resulting shard into if using --go-live. " + + "Example: http://solr001.mycompany.com:8983/solr/collection1. " + + "Multiple --shard-url arguments can be specified, one for each desired shard. " + + "If you are merging shards into a SolrCloud cluster, use --zk-host instead.")); + + Argument shardsArg = nonSolrCloud(clusterInfoGroup.addArgument("--shards") .metavar("INTEGER") .type(Integer.class) .choices(new RangeArgumentChoice(1, Integer.MAX_VALUE)) - .help("Number of output shards to generate."); + .help("Number of output shards to generate.")); ArgumentGroup goLiveGroup = parser.addArgumentGroup("Go live arguments") .description("Arguments for merging the shards that are built into a live Solr cluster. " + @@ -462,8 +478,8 @@ public class MapReduceIndexerTool extends Configured implements Tool { .action(Arguments.storeTrue()) .help("Allows you to optionally merge the final index shards into a live Solr cluster after they are built. " + "You can pass the ZooKeeper address with --zk-host and the relevant cluster information will be auto detected. " + - "If you are not using a SolrCloud cluster, --shard-url arguments can be used to specify each SolrCore to merge " + - "each shard into."); + nonSolrCloud("If you are not using a SolrCloud cluster, --shard-url arguments can be used to specify each SolrCore to merge " + + "each shard into.")); Argument collectionArg = goLiveGroup.addArgument("--collection") .metavar("STRING") @@ -538,6 +554,15 @@ public class MapReduceIndexerTool extends Configured implements Tool { return null; } + // make it a "hidden" option, i.e. the option is functional and enabled but not shown in --help output + private Argument nonSolrCloud(Argument arg) { + return showNonSolrCloud ? arg : arg.help(FeatureControl.SUPPRESS); + } + + private String nonSolrCloud(String msg) { + return showNonSolrCloud ? msg : ""; + } + /** Marker trick to prevent processing of any remaining arguments once --help option has been parsed */ private static final class FoundHelpArgument extends RuntimeException { } @@ -785,7 +810,7 @@ public class MapReduceIndexerTool extends Configured implements Tool { job.setOutputValueClass(SolrInputDocumentWritable.class); LOG.info("Indexing {} files using {} real mappers into {} reducers", new Object[] {numFiles, realMappers, reducers}); startTime = System.currentTimeMillis(); - if (!waitForCompletion(job, true)) { + if (!waitForCompletion(job, options.isVerbose)) { return -1; // job failed } @@ -826,6 +851,9 @@ public class MapReduceIndexerTool extends Configured implements Tool { if (!waitForCompletion(job, options.isVerbose)) { return -1; // job failed } + if (!renameTreeMergeShardDirs(outputTreeMergeStep, job, fs)) { + return -1; + } secs = (System.currentTimeMillis() - startTime) / 1000.0f; LOG.info("MTree merge iteration {}/{}: Done. Merging {} shards into {} shards using fanout {} took {} secs", new Object[] {mtreeMergeIteration, mtreeMergeIterations, reducers, (reducers / options.fanout), options.fanout, secs}); @@ -1182,10 +1210,102 @@ public class MapReduceIndexerTool extends Configured implements Tool { throw new IllegalStateException("Not a directory: " + dir.getPath()); } } - Arrays.sort(dirs); // FIXME: handle more than 99999 shards (need numeric sort rather than lexicographical sort) + + // use alphanumeric sort (rather than lexicographical sort) to properly handle more than 99999 shards + Arrays.sort(dirs, new Comparator() { + @Override + public int compare(FileStatus f1, FileStatus f2) { + return new AlphaNumericComparator().compare(f1.getPath().getName(), f2.getPath().getName()); + } + }); + return dirs; } + /* + * You can run MapReduceIndexerTool in Solrcloud mode, and once the MR job completes, you can use + * the standard solrj Solrcloud API to send doc updates and deletes to SolrCloud, and those updates + * and deletes will go to the right Solr shards, and it will work just fine. + * + * The MapReduce framework doesn't guarantee that input split N goes to the map task with the + * taskId = N. The job tracker and Yarn schedule and assign tasks, considering data locality + * aspects, but without regard of the input split# withing the overall list of input splits. In + * other words, split# != taskId can be true. + * + * To deal with this issue, our mapper tasks write a little auxiliary metadata file (per task) + * that tells the job driver which taskId processed which split#. Once the mapper-only job is + * completed, the job driver renames the output dirs such that the dir name contains the true solr + * shard id, based on these auxiliary files. + * + * This way each doc gets assigned to the right Solr shard even with #reducers > #solrshards + * + * Example for a merge with two shards: + * + * part-m-00000 and part-m-00001 goes to outputShardNum = 0 and will end up in merged part-m-00000 + * part-m-00002 and part-m-00003 goes to outputShardNum = 1 and will end up in merged part-m-00001 + * part-m-00004 and part-m-00005 goes to outputShardNum = 2 and will end up in merged part-m-00002 + * ... and so on + * + * Also see run() method above where it uses NLineInputFormat.setNumLinesPerSplit(job, + * options.fanout) + * + * Also see TreeMergeOutputFormat.TreeMergeRecordWriter.writeShardNumberFile() + */ + private boolean renameTreeMergeShardDirs(Path outputTreeMergeStep, Job job, FileSystem fs) throws IOException { + final String dirPrefix = SolrOutputFormat.getOutputName(job); + FileStatus[] dirs = fs.listStatus(outputTreeMergeStep, new PathFilter() { + @Override + public boolean accept(Path path) { + return path.getName().startsWith(dirPrefix); + } + }); + + for (FileStatus dir : dirs) { + if (!dir.isDirectory()) { + throw new IllegalStateException("Not a directory: " + dir.getPath()); + } + } + + // Example: rename part-m-00004 to _part-m-00004 + for (FileStatus dir : dirs) { + Path path = dir.getPath(); + Path renamedPath = new Path(path.getParent(), "_" + path.getName()); + if (!rename(path, renamedPath, fs)) { + return false; + } + } + + // Example: rename _part-m-00004 to part-m-00002 + for (FileStatus dir : dirs) { + Path path = dir.getPath(); + Path renamedPath = new Path(path.getParent(), "_" + path.getName()); + + // read auxiliary metadata file (per task) that tells which taskId + // processed which split# aka solrShard + Path solrShardNumberFile = new Path(renamedPath, TreeMergeMapper.SOLR_SHARD_NUMBER); + InputStream in = fs.open(solrShardNumberFile); + byte[] bytes = ByteStreams.toByteArray(in); + in.close(); + Preconditions.checkArgument(bytes.length > 0); + int solrShard = Integer.parseInt(new String(bytes, Charsets.UTF_8)); + if (!delete(solrShardNumberFile, false, fs)) { + return false; + } + + // same as FileOutputFormat.NUMBER_FORMAT + NumberFormat numberFormat = NumberFormat.getInstance(Locale.ENGLISH); + numberFormat.setMinimumIntegerDigits(5); + numberFormat.setGroupingUsed(false); + Path finalPath = new Path(renamedPath.getParent(), dirPrefix + "-m-" + numberFormat.format(solrShard)); + + LOG.info("MTree merge renaming solr shard: " + solrShard + " from dir: " + dir.getPath() + " to dir: " + finalPath); + if (!rename(renamedPath, finalPath, fs)) { + return false; + } + } + return true; + } + private static void verifyGoLiveArgs(Options opts, ArgumentParser parser) throws ArgumentParserException { if (opts.zkHost == null && opts.solrHomeDir == null) { throw new ArgumentParserException("At least one of --zk-host or --solr-home-dir is required", parser); diff --git a/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/SolrReducer.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/SolrReducer.java index 59f64ee493f..cf291bdc956 100644 --- a/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/SolrReducer.java +++ b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/SolrReducer.java @@ -32,6 +32,7 @@ import org.slf4j.LoggerFactory; import com.cloudera.cdk.morphline.api.ExceptionHandler; import com.cloudera.cdk.morphline.base.FaultTolerance; +import com.google.common.base.Preconditions; /** * This class loads the mapper's SolrInputDocuments into one EmbeddedSolrServer @@ -54,6 +55,7 @@ public class SolrReducer extends Reducer resolverClass = context.getConfiguration().getClass( UPDATE_CONFLICT_RESOLVER, RetainMostRecentUpdateConflictResolver.class, UpdateConflictResolver.class); @@ -107,6 +109,24 @@ public class SolrReducer extends Reducer @Override public void close(TaskAttemptContext context) throws IOException { - LOG.debug("Merging into dstDir: " + workDir + ", srcDirs: {}", shards); + LOG.debug("Task " + context.getTaskAttemptID() + " merging into dstDir: " + workDir + ", srcDirs: " + shards); + writeShardNumberFile(context); heartBeater.needHeartBeat(); try { Directory mergedIndex = new HdfsDirectory(workDir, context.getConfiguration()); + // TODO: shouldn't we pull the Version from the solrconfig.xml? IndexWriterConfig writerConfig = new IndexWriterConfig(Version.LUCENE_CURRENT, null) - .setOpenMode(OpenMode.CREATE) + .setOpenMode(OpenMode.CREATE).setUseCompoundFile(false) //.setMergePolicy(mergePolicy) // TODO: grab tuned MergePolicy from solrconfig.xml? //.setMergeScheduler(...) // TODO: grab tuned MergeScheduler from solrconfig.xml? ; @@ -162,6 +170,27 @@ public class TreeMergeOutputFormat extends FileOutputFormat heartBeater.cancelHeartBeat(); heartBeater.close(); } + } + + /* + * For background see MapReduceIndexerTool.renameTreeMergeShardDirs() + * + * Also see MapReduceIndexerTool.run() method where it uses + * NLineInputFormat.setNumLinesPerSplit(job, options.fanout) + */ + private void writeShardNumberFile(TaskAttemptContext context) throws IOException { + Preconditions.checkArgument(shards.size() > 0); + String shard = shards.get(0).getParent().getParent().getName(); // move up from "data/index" + String taskId = shard.substring("part-m-".length(), shard.length()); // e.g. part-m-00001 + int taskNum = Integer.parseInt(taskId); + int outputShardNum = taskNum / shards.size(); + LOG.debug("Merging into outputShardNum: " + outputShardNum + " from taskId: " + taskId); + Path shardNumberFile = new Path(workDir.getParent().getParent(), TreeMergeMapper.SOLR_SHARD_NUMBER); + OutputStream out = shardNumberFile.getFileSystem(context.getConfiguration()).create(shardNumberFile); + Writer writer = new OutputStreamWriter(out, Charsets.UTF_8); + writer.write(String.valueOf(outputShardNum)); + writer.flush(); + writer.close(); } } } diff --git a/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/ZooKeeperInspector.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/ZooKeeperInspector.java index ed916a33c93..c8de94cda5d 100644 --- a/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/ZooKeeperInspector.java +++ b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/ZooKeeperInspector.java @@ -117,9 +117,11 @@ final class ZooKeeperInspector { Collections.sort(sorted, new Comparator() { @Override public int compare(Slice slice1, Slice slice2) { - return slice1.getName().compareTo(slice2.getName()); + Comparator c = new AlphaNumericComparator(); + return c.compare(slice1.getName(), slice2.getName()); } }); + LOG.trace("Sorted slices: {}", sorted); return sorted; } diff --git a/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/AlphaNumericComparatorTest.java b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/AlphaNumericComparatorTest.java new file mode 100644 index 00000000000..cab29e7796c --- /dev/null +++ b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/AlphaNumericComparatorTest.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.hadoop; + +import java.util.Comparator; + +import org.junit.Assert; +import org.junit.Test; + +public class AlphaNumericComparatorTest extends Assert { + + @Test + public void testBasic() { + Comparator c = new AlphaNumericComparator(); + assertTrue(c.compare("a", "b") < 0); + assertTrue(c.compare("shard1", "shard1") == 0); + //assertTrue(c.compare("shard01", "shard1") == 0); + assertTrue(c.compare("shard10", "shard10") == 0); + assertTrue(c.compare("shard1", "shard2") < 0); + assertTrue(c.compare("shard9", "shard10") < 0); + assertTrue(c.compare("shard09", "shard10") < 0); + assertTrue(c.compare("shard019", "shard10") > 0); + assertTrue(c.compare("shard10", "shard11") < 0); + assertTrue(c.compare("shard10z", "shard10z") == 0); + assertTrue(c.compare("shard10z", "shard11z") < 0); + assertTrue(c.compare("shard10a", "shard10z") < 0); + assertTrue(c.compare("shard10z", "shard10a") > 0); + assertTrue(c.compare("shard1z", "shard1z") == 0); + assertTrue(c.compare("shard2", "shard1") > 0); + } + +} diff --git a/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MRUnitBase.java b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MRUnitBase.java index c47858232c4..68f32cb07b0 100644 --- a/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MRUnitBase.java +++ b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MRUnitBase.java @@ -54,6 +54,7 @@ public abstract class MRUnitBase extends SolrTestCaseJ4 { setupMorphline(tempDir, "test-morphlines/solrCellDocumentTypes"); config.set(MorphlineMapRunner.MORPHLINE_FILE_PARAM, tempDir + "/test-morphlines/solrCellDocumentTypes.conf"); + config.set(SolrOutputFormat.ZIP_NAME, solrHomeZip.getName()); } public static void setupMorphline(String tempDir, String file) throws IOException { diff --git a/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineBasicMiniMRTest.java b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineBasicMiniMRTest.java index b4aad76a452..f500878e596 100644 --- a/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineBasicMiniMRTest.java +++ b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineBasicMiniMRTest.java @@ -43,6 +43,7 @@ import org.apache.lucene.util.LuceneTestCase.Slow; import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.cloud.AbstractZkTestCase; import org.apache.solr.hadoop.hack.MiniMRCluster; +import org.apache.solr.handler.extraction.ExtractingParams; import org.apache.solr.util.ExternalPaths; import org.junit.After; import org.junit.AfterClass; @@ -323,7 +324,7 @@ public class MorphlineBasicMiniMRTest extends SolrTestCaseJ4 { jobConf.setMaxMapAttempts(1); jobConf.setMaxReduceAttempts(1); jobConf.setJar(SEARCH_ARCHIVES_JAR); - jobConf.setBoolean("ignoreTikaException", false); + jobConf.setBoolean(ExtractingParams.IGNORE_TIKA_EXCEPTION, false); int shards = 2; int maxReducers = Integer.MAX_VALUE; diff --git a/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineGoLiveMiniMRTest.java b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineGoLiveMiniMRTest.java index b2477acaf4f..72aa3e87bec 100644 --- a/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineGoLiveMiniMRTest.java +++ b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineGoLiveMiniMRTest.java @@ -25,9 +25,11 @@ import java.io.Writer; import java.lang.reflect.Array; import java.net.URI; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import org.apache.commons.io.FileUtils; @@ -36,16 +38,16 @@ import org.apache.hadoop.fs.Path; import org.apache.hadoop.fs.permission.FsPermission; import org.apache.hadoop.hdfs.MiniDFSCluster; import org.apache.hadoop.mapred.JobConf; -import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.security.authorize.ProxyUsers; import org.apache.hadoop.util.JarFinder; import org.apache.hadoop.util.ToolRunner; import org.apache.hadoop.yarn.conf.YarnConfiguration; import org.apache.lucene.util.Constants; -import org.apache.lucene.util.LuceneTestCase; import org.apache.lucene.util.LuceneTestCase.Slow; import org.apache.lucene.util.LuceneTestCase.SuppressCodecs; import org.apache.solr.client.solrj.SolrQuery; +import org.apache.solr.client.solrj.SolrQuery.ORDER; +import org.apache.solr.client.solrj.SolrServer; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.embedded.JettySolrRunner; import org.apache.solr.client.solrj.impl.HttpSolrServer; @@ -53,6 +55,9 @@ import org.apache.solr.client.solrj.request.QueryRequest; import org.apache.solr.client.solrj.response.QueryResponse; import org.apache.solr.cloud.AbstractFullDistribZkTestBase; import org.apache.solr.cloud.AbstractZkTestCase; +import org.apache.solr.common.SolrDocument; +import org.apache.solr.common.SolrDocumentList; +import org.apache.solr.common.SolrInputDocument; import org.apache.solr.common.cloud.Replica; import org.apache.solr.common.cloud.Slice; import org.apache.solr.common.cloud.SolrZkClient; @@ -62,12 +67,12 @@ import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.util.NamedList; import org.apache.solr.hadoop.hack.MiniMRClientCluster; import org.apache.solr.hadoop.hack.MiniMRClientClusterFactory; +import org.apache.solr.handler.extraction.ExtractingParams; import org.apache.solr.util.ExternalPaths; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; -import org.junit.Ignore; import org.junit.Test; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakAction; @@ -86,16 +91,16 @@ import com.carrotsearch.randomizedtesting.annotations.ThreadLeakZombies.Conseque @Slow public class MorphlineGoLiveMiniMRTest extends AbstractFullDistribZkTestBase { + private static final int RECORD_COUNT = 2104; private static final String RESOURCES_DIR = ExternalPaths.SOURCE_HOME + "/contrib/map-reduce/src/test-files"; private static final String DOCUMENTS_DIR = RESOURCES_DIR + "/test-documents"; private static final File MINIMR_INSTANCE_DIR = new File(RESOURCES_DIR + "/solr/minimr"); private static final File MINIMR_CONF_DIR = new File(RESOURCES_DIR + "/solr/minimr"); - + private static final String SEARCH_ARCHIVES_JAR = JarFinder.getJar(MapReduceIndexerTool.class); private static MiniDFSCluster dfsCluster = null; private static MiniMRClientCluster mrCluster = null; - private static int numRuns = 0; private static String tempDir; private final String inputAvroFile1; @@ -115,17 +120,8 @@ public class MorphlineGoLiveMiniMRTest extends AbstractFullDistribZkTestBase { this.inputAvroFile3 = "sample-statuses-20120906-141433-medium.avro"; fixShardCount = true; - sliceCount = TEST_NIGHTLY ? 3 : 3; - shardCount = TEST_NIGHTLY ? 3 : 3; - } - - private static boolean isYarn() { - try { - Job.class.getMethod("getCluster"); - return true; - } catch (NoSuchMethodException e) { - return false; - } + sliceCount = TEST_NIGHTLY ? 7 : 3; + shardCount = TEST_NIGHTLY ? 7 : 3; } @BeforeClass @@ -371,7 +367,7 @@ public class MorphlineGoLiveMiniMRTest extends AbstractFullDistribZkTestBase { jobConf.setMaxMapAttempts(1); jobConf.setMaxReduceAttempts(1); jobConf.setJar(SEARCH_ARCHIVES_JAR); - jobConf.setBoolean("ignoreTikaException", false); + jobConf.setBoolean(ExtractingParams.IGNORE_TIKA_EXCEPTION, false); MapReduceIndexerTool tool; int res; @@ -384,7 +380,7 @@ public class MorphlineGoLiveMiniMRTest extends AbstractFullDistribZkTestBase { "--output-dir=" + outDir.toString(), "--log4j=" + ExternalPaths.SOURCE_HOME + "/core/src/test-files/log4j.properties", "--mappers=3", - ++numRuns % 2 == 0 ? "--input-list=" + INPATH.toString() : dataDir.toString(), + random().nextBoolean() ? "--input-list=" + INPATH.toString() : dataDir.toString(), "--go-live-threads", Integer.toString(random().nextInt(15) + 1), "--verbose", "--go-live" @@ -396,9 +392,7 @@ public class MorphlineGoLiveMiniMRTest extends AbstractFullDistribZkTestBase { if (true) { tool = new MapReduceIndexerTool(); - res = ToolRunner.run(jobConf, tool, args); - assertEquals(0, res); assertTrue(tool.job.isComplete()); assertTrue(tool.job.isSuccessful()); @@ -418,7 +412,7 @@ public class MorphlineGoLiveMiniMRTest extends AbstractFullDistribZkTestBase { "--mappers=3", "--verbose", "--go-live", - ++numRuns % 2 == 0 ? "--input-list=" + INPATH.toString() : dataDir.toString(), + random().nextBoolean() ? "--input-list=" + INPATH.toString() : dataDir.toString(), "--go-live-threads", Integer.toString(random().nextInt(15) + 1) }; args = prependInitialArgs(args); @@ -449,14 +443,19 @@ public class MorphlineGoLiveMiniMRTest extends AbstractFullDistribZkTestBase { fs.delete(outDir, true); fs.delete(dataDir, true); INPATH = upAvroFile(fs, inDir, DATADIR, dataDir, inputAvroFile3); - + + cloudClient.deleteByQuery("*:*"); + cloudClient.commit(); + assertEquals(0, cloudClient.query(new SolrQuery("*:*")).getResults().getNumFound()); + args = new String[] { "--output-dir=" + outDir.toString(), "--mappers=3", - "--reducers=6", + "--reducers=12", + "--fanout=2", "--verbose", "--go-live", - ++numRuns % 2 == 0 ? "--input-list=" + INPATH.toString() : dataDir.toString(), + random().nextBoolean() ? "--input-list=" + INPATH.toString() : dataDir.toString(), "--zk-host", zkServer.getZkAddress(), "--collection", collection }; @@ -469,15 +468,55 @@ public class MorphlineGoLiveMiniMRTest extends AbstractFullDistribZkTestBase { assertTrue(tool.job.isComplete()); assertTrue(tool.job.isSuccessful()); - results = server.query(new SolrQuery("*:*")); - assertEquals(2126, results.getResults().getNumFound()); + SolrDocumentList resultDocs = executeSolrQuery(cloudClient, "*:*"); + assertEquals(RECORD_COUNT, resultDocs.getNumFound()); + assertEquals(RECORD_COUNT, resultDocs.size()); + + // perform updates + for (int i = 0; i < RECORD_COUNT; i++) { + SolrDocument doc = resultDocs.get(i); + SolrInputDocument update = new SolrInputDocument(); + for (Map.Entry entry : doc.entrySet()) { + update.setField(entry.getKey(), entry.getValue()); + } + update.setField("user_screen_name", "Nadja" + i); + update.removeField("_version_"); + cloudClient.add(update); + } + cloudClient.commit(); + + // verify updates + SolrDocumentList resultDocs2 = executeSolrQuery(cloudClient, "*:*"); + assertEquals(RECORD_COUNT, resultDocs2.getNumFound()); + assertEquals(RECORD_COUNT, resultDocs2.size()); + for (int i = 0; i < RECORD_COUNT; i++) { + SolrDocument doc = resultDocs.get(i); + SolrDocument doc2 = resultDocs2.get(i); + assertEquals(doc.getFirstValue("id"), doc2.getFirstValue("id")); + assertEquals("Nadja" + i, doc2.getFirstValue("user_screen_name")); + assertEquals(doc.getFirstValue("text"), doc2.getFirstValue("text")); + + // perform delete + cloudClient.deleteById((String)doc.getFirstValue("id")); + } + cloudClient.commit(); + + // verify deletes + assertEquals(0, executeSolrQuery(cloudClient, "*:*").size()); } + cloudClient.deleteByQuery("*:*"); + cloudClient.commit(); + assertEquals(0, cloudClient.query(new SolrQuery("*:*")).getResults().getNumFound()); server.shutdown(); // try using zookeeper with replication String replicatedCollection = "replicated_collection"; - createCollection(replicatedCollection, 2, 3, 2); + if (TEST_NIGHTLY) { + createCollection(replicatedCollection, 11, 3, 11); + } else { + createCollection(replicatedCollection, 2, 3, 2); + } waitForRecoveriesToFinish(false); cloudClient.setDefaultCollection(replicatedCollection); fs.delete(inDir, true); @@ -490,7 +529,8 @@ public class MorphlineGoLiveMiniMRTest extends AbstractFullDistribZkTestBase { "--solr-home-dir=" + MINIMR_CONF_DIR.getAbsolutePath(), "--output-dir=" + outDir.toString(), "--mappers=3", - "--reducers=6", + "--reducers=22", + "--fanout=2", "--verbose", "--go-live", "--zk-host", zkServer.getZkAddress(), @@ -505,15 +545,51 @@ public class MorphlineGoLiveMiniMRTest extends AbstractFullDistribZkTestBase { assertTrue(tool.job.isComplete()); assertTrue(tool.job.isSuccessful()); - results = cloudClient.query(new SolrQuery("*:*")); - assertEquals(2104, results.getResults().getNumFound()); + SolrDocumentList resultDocs = executeSolrQuery(cloudClient, "*:*"); + assertEquals(RECORD_COUNT, resultDocs.getNumFound()); + assertEquals(RECORD_COUNT, resultDocs.size()); checkConsistency(replicatedCollection); - } + + // perform updates + for (int i = 0; i < RECORD_COUNT; i++) { + SolrDocument doc = resultDocs.get(i); + SolrInputDocument update = new SolrInputDocument(); + for (Map.Entry entry : doc.entrySet()) { + update.setField(entry.getKey(), entry.getValue()); + } + update.setField("user_screen_name", "@Nadja" + i); + update.removeField("_version_"); + cloudClient.add(update); + } + cloudClient.commit(); + + // verify updates + SolrDocumentList resultDocs2 = executeSolrQuery(cloudClient, "*:*"); + assertEquals(RECORD_COUNT, resultDocs2.getNumFound()); + assertEquals(RECORD_COUNT, resultDocs2.size()); + for (int i = 0; i < RECORD_COUNT; i++) { + SolrDocument doc = resultDocs.get(i); + SolrDocument doc2 = resultDocs2.get(i); + assertEquals(doc.getFieldValues("id"), doc2.getFieldValues("id")); + assertEquals(1, doc.getFieldValues("id").size()); + assertEquals(Arrays.asList("@Nadja" + i), doc2.getFieldValues("user_screen_name")); + assertEquals(doc.getFieldValues("text"), doc2.getFieldValues("text")); + + // perform delete + cloudClient.deleteById((String)doc.getFirstValue("id")); + } + cloudClient.commit(); + + // verify deletes + assertEquals(0, executeSolrQuery(cloudClient, "*:*").size()); + } // try using solr_url with replication cloudClient.deleteByQuery("*:*"); cloudClient.commit(); + assertEquals(0, executeSolrQuery(cloudClient, "*:*").getNumFound()); + assertEquals(0, executeSolrQuery(cloudClient, "*:*").size()); fs.delete(inDir, true); fs.delete(dataDir, true); assertTrue(fs.mkdirs(dataDir)); @@ -543,8 +619,7 @@ public class MorphlineGoLiveMiniMRTest extends AbstractFullDistribZkTestBase { checkConsistency(replicatedCollection); - results = cloudClient.query(new SolrQuery("*:*")); - assertEquals(2104, results.getResults().getNumFound()); + assertEquals(RECORD_COUNT, executeSolrQuery(cloudClient, "*:*").size()); } } @@ -555,6 +630,12 @@ public class MorphlineGoLiveMiniMRTest extends AbstractFullDistribZkTestBase { args.add(cloudJettys.get(i).url); } } + + private SolrDocumentList executeSolrQuery(SolrServer collection, String queryString) throws SolrServerException { + SolrQuery query = new SolrQuery(queryString).setRows(2 * RECORD_COUNT).addSort("id", ORDER.asc); + QueryResponse response = collection.query(query); + return response.getResults(); + } private void checkConsistency(String replicatedCollection) throws SolrServerException { diff --git a/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineReducerTest.java b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineReducerTest.java index 844aff09ace..e33c651042f 100644 --- a/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineReducerTest.java +++ b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineReducerTest.java @@ -34,6 +34,7 @@ import org.apache.hadoop.mapreduce.TaskAttemptID; import org.apache.hadoop.mrunit.mapreduce.ReduceDriver; import org.apache.lucene.util.Constants; import org.apache.solr.common.SolrInputDocument; +import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.mockito.invocation.InvocationOnMock; @@ -44,10 +45,17 @@ import com.google.common.collect.Lists; public class MorphlineReducerTest extends MRUnitBase { @BeforeClass - public static void beforeClass() { + public static void beforeClass2() { assumeFalse("Does not work on Windows, because it uses UNIX shell commands or POSIX paths", Constants.WINDOWS); assumeFalse("FIXME: This test fails under Java 8 due to the Saxon dependency - see SOLR-1301", Constants.JRE_IS_MINIMUM_JAVA8); assumeFalse("FIXME: This test fails under J9 due to the Saxon dependency - see SOLR-1301", System.getProperty("java.vm.info", "").contains("IBM J9")); + + System.setProperty("verifyPartitionAssignment", "false"); + } + + @AfterClass + public static void afterClass2() { + System.clearProperty("verifyPartitionAssignment"); } public static class MySolrReducer extends SolrReducer { @@ -89,28 +97,35 @@ public class MorphlineReducerTest extends MRUnitBase { @Test public void testReducer() throws Exception { MySolrReducer myReducer = new MySolrReducer(); - ReduceDriver reduceDriver = ReduceDriver.newReduceDriver(myReducer); - - Configuration config = reduceDriver.getConfiguration(); - setupHadoopConfig(config); - - List values = new ArrayList(); - SolrInputDocument sid = new SolrInputDocument(); - String id = "myid1"; - sid.addField("id", id); - sid.addField("text", "some unique text"); - SolrInputDocumentWritable sidw = new SolrInputDocumentWritable(sid); - values.add(sidw); - reduceDriver.withInput(new Text(id), values); - - reduceDriver.withCacheArchive(solrHomeZip.getAbsolutePath()); - - reduceDriver.withOutputFormat(SolrOutputFormat.class, NullInputFormat.class); - - reduceDriver.run(); - - assertEquals("Expected 1 counter increment", 1, reduceDriver.getCounters() - .findCounter(SolrCounters.class.getName(), SolrCounters.DOCUMENTS_WRITTEN.toString()).getValue()); + try { + ReduceDriver reduceDriver = ReduceDriver + .newReduceDriver(myReducer); + + Configuration config = reduceDriver.getConfiguration(); + setupHadoopConfig(config); + + List values = new ArrayList(); + SolrInputDocument sid = new SolrInputDocument(); + String id = "myid1"; + sid.addField("id", id); + sid.addField("text", "some unique text"); + SolrInputDocumentWritable sidw = new SolrInputDocumentWritable(sid); + values.add(sidw); + reduceDriver.withInput(new Text(id), values); + + reduceDriver.withCacheArchive(solrHomeZip.getAbsolutePath()); + + reduceDriver.withOutputFormat(SolrOutputFormat.class, + NullInputFormat.class); + + reduceDriver.run(); + + assertEquals("Expected 1 counter increment", 1, + reduceDriver.getCounters().findCounter(SolrCounters.class.getName(), + SolrCounters.DOCUMENTS_WRITTEN.toString()).getValue()); + } finally { + myReducer.cleanup(myReducer.context); + } } } From e4f83aa1a0183361edb7bfcc40846552297a0635 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Wed, 4 Dec 2013 19:11:41 +0000 Subject: [PATCH 184/223] SOLR-1301: Merge in latest morphlines module updates. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1547879 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/solr/morphlines/cell/SolrCellBuilder.java | 9 +++++---- .../morphlines/solr/GenerateSolrSequenceKeyBuilder.java | 6 +++--- .../org/apache/solr/morphlines/solr/LoadSolrBuilder.java | 9 +++++---- .../solr/SanitizeUnknownSolrFieldsBuilder.java | 6 +++--- .../apache/solr/morphlines/solr/TokenizeTextBuilder.java | 6 +++--- .../solr/morphlines/solr/SolrMorphlineZkAliasTest.java | 2 -- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/solr/contrib/morphlines-cell/src/java/org/apache/solr/morphlines/cell/SolrCellBuilder.java b/solr/contrib/morphlines-cell/src/java/org/apache/solr/morphlines/cell/SolrCellBuilder.java index af50c7cfd12..dc1ae418255 100644 --- a/solr/contrib/morphlines-cell/src/java/org/apache/solr/morphlines/cell/SolrCellBuilder.java +++ b/solr/contrib/morphlines-cell/src/java/org/apache/solr/morphlines/cell/SolrCellBuilder.java @@ -61,6 +61,7 @@ import com.cloudera.cdk.morphline.api.MorphlineCompilationException; import com.cloudera.cdk.morphline.api.MorphlineContext; import com.cloudera.cdk.morphline.api.MorphlineRuntimeException; import com.cloudera.cdk.morphline.api.Record; +import com.cloudera.cdk.morphline.base.Configs; import com.cloudera.cdk.morphline.base.Fields; import com.cloudera.cdk.morphline.stdio.AbstractParser; import com.google.common.base.Joiner; @@ -87,7 +88,7 @@ public final class SolrCellBuilder implements CommandBuilder { @Override public Command build(Config config, Command parent, Command child, MorphlineContext context) { - return new SolrCell(config, parent, child, context); + return new SolrCell(this, config, parent, child, context); } @@ -109,8 +110,8 @@ public final class SolrCellBuilder implements CommandBuilder { public static final String ADDITIONAL_SUPPORTED_MIME_TYPES = "additionalSupportedMimeTypes"; - public SolrCell(Config config, Command parent, Command child, MorphlineContext context) { - super(config, parent, child, context); + public SolrCell(CommandBuilder builder, Config config, Command parent, Command child, MorphlineContext context) { + super(builder, config, parent, child, context); Config solrLocatorConfig = getConfigs().getConfig(config, "solrLocator"); SolrLocator locator = new SolrLocator(solrLocatorConfig, context); @@ -129,7 +130,7 @@ public final class SolrCellBuilder implements CommandBuilder { } Config fmapConfig = getConfigs().getConfig(config, "fmap", null); if (fmapConfig != null) { - for (Map.Entry entry : fmapConfig.root().unwrapped().entrySet()) { + for (Map.Entry entry : new Configs().getEntrySet(fmapConfig)) { cellParams.put(ExtractingParams.MAP_PREFIX + entry.getKey(), entry.getValue().toString()); } } diff --git a/solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/GenerateSolrSequenceKeyBuilder.java b/solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/GenerateSolrSequenceKeyBuilder.java index 251d016634c..badf99ec3e7 100644 --- a/solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/GenerateSolrSequenceKeyBuilder.java +++ b/solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/GenerateSolrSequenceKeyBuilder.java @@ -60,7 +60,7 @@ public final class GenerateSolrSequenceKeyBuilder implements CommandBuilder { @Override public Command build(Config config, Command parent, Command child, MorphlineContext context) { - return new GenerateSolrSequenceKey(config, parent, child, context); + return new GenerateSolrSequenceKey(this, config, parent, child, context); } @@ -77,8 +77,8 @@ public final class GenerateSolrSequenceKeyBuilder implements CommandBuilder { private final String idPrefix; // for load testing only; enables adding same document many times with a different unique key private final Random randomIdPrefix; // for load testing only; enables adding same document many times with a different unique key - public GenerateSolrSequenceKey(Config config, Command parent, Command child, MorphlineContext context) { - super(config, parent, child, context); + public GenerateSolrSequenceKey(CommandBuilder builder, Config config, Command parent, Command child, MorphlineContext context) { + super(builder, config, parent, child, context); this.baseIdFieldName = getConfigs().getString(config, "baseIdField", Fields.BASE_ID); this.preserveExisting = getConfigs().getBoolean(config, "preserveExisting", true); diff --git a/solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/LoadSolrBuilder.java b/solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/LoadSolrBuilder.java index 019dfcf0f52..ff27cd09e6f 100644 --- a/solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/LoadSolrBuilder.java +++ b/solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/LoadSolrBuilder.java @@ -31,6 +31,7 @@ import com.cloudera.cdk.morphline.api.MorphlineContext; import com.cloudera.cdk.morphline.api.MorphlineRuntimeException; import com.cloudera.cdk.morphline.api.Record; import com.cloudera.cdk.morphline.base.AbstractCommand; +import com.cloudera.cdk.morphline.base.Configs; import com.cloudera.cdk.morphline.base.Metrics; import com.cloudera.cdk.morphline.base.Notifications; import com.codahale.metrics.Timer; @@ -49,7 +50,7 @@ public final class LoadSolrBuilder implements CommandBuilder { @Override public Command build(Config config, Command parent, Command child, MorphlineContext context) { - return new LoadSolr(config, parent, child, context); + return new LoadSolr(this, config, parent, child, context); } @@ -62,14 +63,14 @@ public final class LoadSolrBuilder implements CommandBuilder { private final Map boosts = new HashMap(); private final Timer elapsedTime; - public LoadSolr(Config config, Command parent, Command child, MorphlineContext context) { - super(config, parent, child, context); + public LoadSolr(CommandBuilder builder, Config config, Command parent, Command child, MorphlineContext context) { + super(builder, config, parent, child, context); Config solrLocatorConfig = getConfigs().getConfig(config, "solrLocator"); SolrLocator locator = new SolrLocator(solrLocatorConfig, context); LOG.debug("solrLocator: {}", locator); this.loader = locator.getLoader(); Config boostsConfig = getConfigs().getConfig(config, "boosts", ConfigFactory.empty()); - for (Map.Entry entry : boostsConfig.root().unwrapped().entrySet()) { + for (Map.Entry entry : new Configs().getEntrySet(boostsConfig)) { String fieldName = entry.getKey(); float boost = Float.parseFloat(entry.getValue().toString().trim()); boosts.put(fieldName, boost); diff --git a/solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/SanitizeUnknownSolrFieldsBuilder.java b/solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/SanitizeUnknownSolrFieldsBuilder.java index fbc8de21bda..79ecec34b64 100644 --- a/solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/SanitizeUnknownSolrFieldsBuilder.java +++ b/solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/SanitizeUnknownSolrFieldsBuilder.java @@ -50,7 +50,7 @@ public final class SanitizeUnknownSolrFieldsBuilder implements CommandBuilder { @Override public Command build(Config config, Command parent, Command child, MorphlineContext context) { - return new SanitizeUnknownSolrFields(config, parent, child, context); + return new SanitizeUnknownSolrFields(this, config, parent, child, context); } @@ -62,8 +62,8 @@ public final class SanitizeUnknownSolrFieldsBuilder implements CommandBuilder { private final IndexSchema schema; private final String renameToPrefix; - public SanitizeUnknownSolrFields(Config config, Command parent, Command child, MorphlineContext context) { - super(config, parent, child, context); + public SanitizeUnknownSolrFields(CommandBuilder builder, Config config, Command parent, Command child, MorphlineContext context) { + super(builder, config, parent, child, context); Config solrLocatorConfig = getConfigs().getConfig(config, "solrLocator"); SolrLocator locator = new SolrLocator(solrLocatorConfig, context); diff --git a/solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/TokenizeTextBuilder.java b/solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/TokenizeTextBuilder.java index 58c1bb5536c..323eedd27de 100644 --- a/solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/TokenizeTextBuilder.java +++ b/solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/TokenizeTextBuilder.java @@ -51,7 +51,7 @@ public final class TokenizeTextBuilder implements CommandBuilder { @Override public Command build(Config config, Command parent, Command child, MorphlineContext context) { - return new TokenizeText(config, parent, child, context); + return new TokenizeText(this, config, parent, child, context); } @@ -66,8 +66,8 @@ public final class TokenizeTextBuilder implements CommandBuilder { private final CharTermAttribute token; // cached private final ReusableStringReader reader = new ReusableStringReader(); // cached - public TokenizeText(Config config, Command parent, Command child, MorphlineContext context) { - super(config, parent, child, context); + public TokenizeText(CommandBuilder builder, Config config, Command parent, Command child, MorphlineContext context) { + super(builder, config, parent, child, context); this.inputFieldName = getConfigs().getString(config, "inputField"); this.outputFieldName = getConfigs().getString(config, "outputField"); String solrFieldType = getConfigs().getString(config, "solrFieldType"); diff --git a/solr/contrib/morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkAliasTest.java b/solr/contrib/morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkAliasTest.java index 939ef199c89..35fbdf1486d 100644 --- a/solr/contrib/morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkAliasTest.java +++ b/solr/contrib/morphlines-core/src/test/org/apache/solr/morphlines/solr/SolrMorphlineZkAliasTest.java @@ -118,8 +118,6 @@ public class SolrMorphlineZkAliasTest extends AbstractSolrMorphlineZkTestBase { } catch (IllegalArgumentException e) { } - - cloudClient.shutdown(); } private NamedList createAlias(String alias, String collections) throws SolrServerException, IOException { From 6350b2d709f764e427dc88f6e9738a355304bcf8 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Wed, 4 Dec 2013 23:28:50 +0000 Subject: [PATCH 185/223] SOLR-1301: Clean up. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1547962 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/solr/hadoop/MapReduceIndexerTool.java | 12 ++++++------ .../apache/solr/hadoop/MorphlineBasicMiniMRTest.java | 4 ---- .../solr/hadoop/MorphlineGoLiveMiniMRTest.java | 2 -- .../scripts/map-reduce/map-reduce-indexer.bat | 9 --------- .../example/scripts/map-reduce/map-reduce-indexer.sh | 10 ---------- .../scripts/map-reduce/set-map-reduce-classpath.sh | 3 +++ 6 files changed, 9 insertions(+), 31 deletions(-) delete mode 100644 solr/example/scripts/map-reduce/map-reduce-indexer.bat delete mode 100644 solr/example/scripts/map-reduce/map-reduce-indexer.sh create mode 100644 solr/example/scripts/map-reduce/set-map-reduce-classpath.sh diff --git a/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/MapReduceIndexerTool.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/MapReduceIndexerTool.java index b6b432ad705..6fbdaf3a316 100644 --- a/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/MapReduceIndexerTool.java +++ b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/MapReduceIndexerTool.java @@ -136,7 +136,7 @@ public class MapReduceIndexerTool extends Configured implements Tool { showNonSolrCloud = Arrays.asList(args).contains(SHOW_NON_SOLR_CLOUD); // intercept it first ArgumentParser parser = ArgumentParsers - .newArgumentParser("hadoop [GenericOptions]... jar search-mr-*-job.jar " + MapReduceIndexerTool.class.getName(), false) + .newArgumentParser("hadoop [GenericOptions]... jar solr-map-reduce-*.jar ", false) .defaultHelp(true) .description( "MapReduce batch job driver that takes a morphline and creates a set of Solr index shards from a set of input files " + @@ -197,7 +197,7 @@ public class MapReduceIndexerTool extends Configured implements Tool { "# (Re)index an Avro based Twitter tweet file:\n" + "sudo -u hdfs hadoop \\\n" + " --config /etc/hadoop/conf.cloudera.mapreduce1 \\\n" + - " jar target/search-mr-*-job.jar " + MapReduceIndexerTool.class.getName() + " \\\n" + + " jar target/solr-map-reduce-*.jar \\\n" + " -D 'mapred.child.java.opts=-Xmx500m' \\\n" + // " -D 'mapreduce.child.java.opts=-Xmx500m' \\\n" + " --log4j src/test/resources/log4j.properties \\\n" + @@ -213,7 +213,7 @@ public class MapReduceIndexerTool extends Configured implements Tool { "# 3) file was last modified less than 100000 minutes ago\n" + "# 4) file size is between 1 MB and 1 GB\n" + "# Also include extra library jar file containing JSON tweet Java parser:\n" + - "hadoop jar target/search-mr-*-job.jar " + "com.cloudera.cdk.morphline.hadoop.find.HdfsFindTool" + " \\\n" + + "hadoop jar target/solr-map-reduce-*.jar " + "com.cloudera.cdk.morphline.hadoop.find.HdfsFindTool" + " \\\n" + " -find hdfs:///user/$USER/solrloadtest/twitter/tweets \\\n" + " -type f \\\n" + " -name 'sample-statuses*.gz' \\\n" + @@ -222,7 +222,7 @@ public class MapReduceIndexerTool extends Configured implements Tool { " -size +1000000c \\\n" + "| sudo -u hdfs hadoop \\\n" + " --config /etc/hadoop/conf.cloudera.mapreduce1 \\\n" + - " jar target/search-mr-*-job.jar " + MapReduceIndexerTool.class.getName() + " \\\n" + + " jar target/solr-map-reduce-*.jar \\\n" + " -D 'mapred.child.java.opts=-Xmx500m' \\\n" + // " -D 'mapreduce.child.java.opts=-Xmx500m' \\\n" + " --log4j src/test/resources/log4j.properties \\\n" + @@ -236,7 +236,7 @@ public class MapReduceIndexerTool extends Configured implements Tool { "# (explicitly specify Solr URLs - for a SolrCloud cluster see next example):\n" + "sudo -u hdfs hadoop \\\n" + " --config /etc/hadoop/conf.cloudera.mapreduce1 \\\n" + - " jar target/search-mr-*-job.jar " + MapReduceIndexerTool.class.getName() + " \\\n" + + " jar target/solr-map-reduce-*.jar \\\n" + " -D 'mapred.child.java.opts=-Xmx500m' \\\n" + // " -D 'mapreduce.child.java.opts=-Xmx500m' \\\n" + " --log4j src/test/resources/log4j.properties \\\n" + @@ -252,7 +252,7 @@ public class MapReduceIndexerTool extends Configured implements Tool { "# (discover shards and Solr URLs through ZooKeeper):\n" + "sudo -u hdfs hadoop \\\n" + " --config /etc/hadoop/conf.cloudera.mapreduce1 \\\n" + - " jar target/search-mr-*-job.jar " + MapReduceIndexerTool.class.getName() + " \\\n" + + " jar target/solr-map-reduce-*.jar \\\n" + " -D 'mapred.child.java.opts=-Xmx500m' \\\n" + // " -D 'mapreduce.child.java.opts=-Xmx500m' \\\n" + " --log4j src/test/resources/log4j.properties \\\n" + diff --git a/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineBasicMiniMRTest.java b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineBasicMiniMRTest.java index f500878e596..9f53a0333c5 100644 --- a/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineBasicMiniMRTest.java +++ b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineBasicMiniMRTest.java @@ -38,17 +38,14 @@ import org.apache.hadoop.util.JarFinder; import org.apache.hadoop.util.ToolRunner; import org.apache.hadoop.yarn.conf.YarnConfiguration; import org.apache.lucene.util.Constants; -import org.apache.lucene.util.LuceneTestCase; import org.apache.lucene.util.LuceneTestCase.Slow; import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.cloud.AbstractZkTestCase; import org.apache.solr.hadoop.hack.MiniMRCluster; -import org.apache.solr.handler.extraction.ExtractingParams; import org.apache.solr.util.ExternalPaths; import org.junit.After; import org.junit.AfterClass; import org.junit.BeforeClass; -import org.junit.Ignore; import org.junit.Test; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakAction; @@ -324,7 +321,6 @@ public class MorphlineBasicMiniMRTest extends SolrTestCaseJ4 { jobConf.setMaxMapAttempts(1); jobConf.setMaxReduceAttempts(1); jobConf.setJar(SEARCH_ARCHIVES_JAR); - jobConf.setBoolean(ExtractingParams.IGNORE_TIKA_EXCEPTION, false); int shards = 2; int maxReducers = Integer.MAX_VALUE; diff --git a/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineGoLiveMiniMRTest.java b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineGoLiveMiniMRTest.java index 72aa3e87bec..bc6b1634f3c 100644 --- a/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineGoLiveMiniMRTest.java +++ b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineGoLiveMiniMRTest.java @@ -67,7 +67,6 @@ import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.util.NamedList; import org.apache.solr.hadoop.hack.MiniMRClientCluster; import org.apache.solr.hadoop.hack.MiniMRClientClusterFactory; -import org.apache.solr.handler.extraction.ExtractingParams; import org.apache.solr.util.ExternalPaths; import org.junit.After; import org.junit.AfterClass; @@ -367,7 +366,6 @@ public class MorphlineGoLiveMiniMRTest extends AbstractFullDistribZkTestBase { jobConf.setMaxMapAttempts(1); jobConf.setMaxReduceAttempts(1); jobConf.setJar(SEARCH_ARCHIVES_JAR); - jobConf.setBoolean(ExtractingParams.IGNORE_TIKA_EXCEPTION, false); MapReduceIndexerTool tool; int res; diff --git a/solr/example/scripts/map-reduce/map-reduce-indexer.bat b/solr/example/scripts/map-reduce/map-reduce-indexer.bat deleted file mode 100644 index 0817dee7880..00000000000 --- a/solr/example/scripts/map-reduce/map-reduce-indexer.bat +++ /dev/null @@ -1,9 +0,0 @@ - -set JVM=java - -REM Find location of this script - -set SDIR=%~dp0 -if "%SDIR:~-1%"=="\" set SDIR=%SDIR:~0,-1% - -"%JVM%" -classpath "%SDIR%\..\..\..\dist\*:%SDIR%\..\..\..\contrib\map-reduce\lib\*:%SDIR%\..\..\..\contrib\morphlines-core\lib\*:%SDIR%\..\..\..\contrib\morphlines-cell\lib\*:%SDIR%\..\..\..\contrib\extraction\lib\*:%SDIR%\..\..\solr-webapp\webapp\WEB-INF\lib\*:%SDIR%\..\..\lib\ext\*" org.apache.solr.hadoop.MapReduceIndexerTool %* diff --git a/solr/example/scripts/map-reduce/map-reduce-indexer.sh b/solr/example/scripts/map-reduce/map-reduce-indexer.sh deleted file mode 100644 index db361ed2614..00000000000 --- a/solr/example/scripts/map-reduce/map-reduce-indexer.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bash - -JVM="java" - -# Find location of this script - -sdir="`dirname \"$0\"`" - -PATH=$JAVA_HOME/bin:$PATH $JVM -cp "$sdir/../../../dist/*:$sdir/../../../contrib/map-reduce/lib/*:$sdir/../../../contrib/morphlines-core/lib/*:$sdir/../../../contrib/morphlines-cell/lib/*:$sdir/../../../contrib/extraction/lib/*:$sdir/../../solr-webapp/webapp/WEB-INF/lib/*:$sdir/../../lib/ext/*" org.apache.solr.hadoop.MapReduceIndexerTool ${1+"$@"} - diff --git a/solr/example/scripts/map-reduce/set-map-reduce-classpath.sh b/solr/example/scripts/map-reduce/set-map-reduce-classpath.sh new file mode 100644 index 00000000000..f8284807e7c --- /dev/null +++ b/solr/example/scripts/map-reduce/set-map-reduce-classpath.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +export HADOOP_CLASSPATH="$sdir/../../../dist/*:$sdir/../../../contrib/map-reduce/lib/*:$sdir/../../../contrib/morphlines-core/lib/*:$sdir/../../../contrib/morphlines-cell/lib/*:$sdir/../../../contrib/extraction/lib/*:$sdir/../../solr-webapp/webapp/WEB-INF/lib/*:$sdir/../../lib/ext/*" \ No newline at end of file From 325637c2cfbf4977fe8a4f72d2de2661585ec94a Mon Sep 17 00:00:00 2001 From: Steven Rowe Date: Thu, 5 Dec 2013 22:16:17 +0000 Subject: [PATCH 186/223] SOLR-1301: ignore '*.iml' in new Solr contribs' directories; put new Solr contribs' lib/ and test-lib/ directories under Subversion control; ignore '*.jar' in these directories git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1548319 13f79535-47bb-0310-9956-ffa450edef68 From ad4b95a353317bde4f4284fc66dc4b8ed5863e05 Mon Sep 17 00:00:00 2001 From: Stefan Matheis Date: Fri, 6 Dec 2013 09:53:03 +0000 Subject: [PATCH 187/223] SOLR-5539: Admin UI - Remove ability to create/modify files git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1548477 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 2 + solr/webapp/web/css/styles/files.css | 114 -------------------- solr/webapp/web/js/scripts/files.js | 156 +-------------------------- solr/webapp/web/tpl/files.html | 51 --------- 4 files changed, 4 insertions(+), 319 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index f5effc0c60b..7db6b5587ee 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -229,6 +229,8 @@ Other Changes * SOLR-5502: Added a test for tri-level compositeId routing with documents having a "/" in a document id. (Anshum Gupta via Mark Miller) +* SOLR-5539: Admin UI - Remove ability to create/modify files (steffkes) + ================== 4.6.0 ================== Versions of Major Components diff --git a/solr/webapp/web/css/styles/files.css b/solr/webapp/web/css/styles/files.css index 74e14bdfc8d..ba5991b8298 100644 --- a/solr/webapp/web/css/styles/files.css +++ b/solr/webapp/web/css/styles/files.css @@ -23,54 +23,11 @@ limitations under the License. width: 20%; } -#content #files #new-file-holder -{ - margin-top: 20px; - padding-bottom: 10px; -} - -#content #files #new-file-holder button span -{ - background-image: url( ../../img/ico/plus-button.png ); -} - -#content #files #new-file-holder form -{ - box-shadow: 5px 5px 10px #c0c0c0; - -moz-box-shadow: 5px 5px 10px #c0c0c0; - -webkit-box-shadow: 5px 5px 10px #c0c0c0; - display: none; - padding: 10px; -} - -#content #files #new-file-holder form input -{ - margin-bottom: 3px; - width: 98%; -} - -#content #files #new-file-holder .note -{ - color: #c0c0c0; - margin-bottom: 5px; -} - #content #files form .buttons button { float: right; } -#content #files .modify-file, -#content #files .modify-file .view-file -{ - display: none; -} - -#content #files .modify-file .modify-file -{ - display: block; -} - #content #files #file-content { display: none; @@ -80,84 +37,13 @@ limitations under the License. min-height: 100px } -#content #files .top #url -{ - float: left; - width: 80%; -} - -#content #files .top .buttons -{ - float: right; - width: 15%; -} - -#content #files .top .buttons button -{ - float: right; -} - -#content #files .top .buttons button.view-file span -{ - background-image: url( ../../img/ico/pencil.png ); -} - -#content #files .top .buttons button.modify-file span -{ - background-image: url( ../../img/ico/document-text.png ); -} - #content #files .show #file-content { display: block; } -#content #files #new-file-note -{ - background-color: #ffa662; - background-image: url( ../../img/ico/exclamation-button.png ); - background-position: 10px 50%; - display: none; - margin-bottom: 10px; - padding: 10px; - padding-left: 31px; -} - #content #files #file-content .response { border: 1px solid transparent; padding: 2px; -} - -#content #files #file-content textarea -{ - display: block; - font-family: monospace; - height: 500px; - margin-bottom: 10px; - width: 99%; -} - -#content #files #file-content form button span -{ - background-image: url( ../../img/ico/disk-black.png ); -} - -#content #files #file-content form.upload -{ - border-top: 1px solid #c0c0c0; - margin-top: 20px; - padding-top: 20px; - padding-bottom: 20px; -} - -#content #files #file-content .upload input -{ - border: 0; - float: left; -} - -#content #files #file-content .upload button span -{ - background-image: url( ../../img/ico/drive-upload.png ); } \ No newline at end of file diff --git a/solr/webapp/web/js/scripts/files.js b/solr/webapp/web/js/scripts/files.js index 401bb0484a1..5d939b8b90e 100644 --- a/solr/webapp/web/js/scripts/files.js +++ b/solr/webapp/web/js/scripts/files.js @@ -27,7 +27,6 @@ sammy.get var content_element = $( '#content' ); var file_endpoint = core_basepath + '/admin/file'; - var file_exists = null; var path = context.path.split( '?' ); var selected_file = null; @@ -144,34 +143,6 @@ sammy.get }; load_tree(); - var new_file_form = $( '#new-file-holder form' ); - - $( '#new-file-holder > button' ) - .on - ( - 'click', - function( event ) - { - new_file_form.toggle(); - return false; - } - ); - - new_file_form - .on - ( - 'submit', - function( event ) - { - $( 'body' ) - .animate( { scrollTop: 0 }, 500 ); - - window.location.href = '#/' + current_core + '/files?file=' + $( 'input', this ).val(); - - return false; - } - ); - if( selected_file ) { $( '#new-file-holder input' ) @@ -200,57 +171,6 @@ sammy.get .text( public_url ) .attr( 'href', public_url ); - var form = $( 'form.modify', frame_element ); - - form - .attr( 'action', file_endpoint + '?wt=json&op=write&file=' + selected_file ) - .ajaxForm - ( - { - context : form, - beforeSubmit: function( arr, form, options ) - { - $( 'button span', form ) - .addClass( 'loader' ); - }, - success : function( response, status, xhr ) - { - $( 'button span', this ) - .removeClass( 'loader' ); - - var button = $( 'button', this ); - - button - .addClass( 'success' ); - - load_file( !file_exists ); - - window.setTimeout - ( - function() - { - button - .removeClass( 'success' ); - }, - 1000 - ); - } - } - ); - - var change_button_label = function( form, label ) - { - $( 'span[data-' + label + ']', form ) - .each - ( - function( index, element ) - { - var self = $( this ); - self.text( self.data( label ) ); - } - ); - } - var load_file = function( load_tree ) { if( load_tree ) @@ -277,8 +197,6 @@ sammy.get }, success : function( response, text_status, xhr ) { - change_button_label( this, 'existing-title' ); - var content_type = xhr.getResponseHeader( 'Content-Type' ) || ''; var highlight = null; @@ -310,86 +228,16 @@ sammy.get }, error : function( xhr, text_status, error_thrown) { - change_button_label( this, 'new-title' ); + $( '.view-file .response', this ) + .text( 'No such file exists.' ); }, complete : function( xhr, text_status ) { - file_exists = 200 === xhr.status; - $( '#new-file-note' ) - .toggle( !file_exists ); } } ); } load_file(); - - $( '.top button', frame_element ) - .on - ( - 'click', - function( event ) - { - $( '#file-content', frame_element ) - .toggleClass( 'modify-file' ); - - return false; - } - ); - - $( 'form.upload', frame_element ) - .on - ( - 'submit', - function( event ) - { - $( 'form input', frame_element ) - .ajaxfileupload - ( - { - action: endpoint + '&op=write&wt=json', - validate_extensions: false, - upload_now: true, - onStart: function () - { - $( 'form.upload button span', frame_element ) - .addClass( 'loader' ); - }, - onCancel: function () - { - $( 'form.upload button span', frame_element ) - .removeClass( 'loader' ); - }, - onComplete: function( response ) - { - $( 'form.upload button span', frame_element ) - .removeClass( 'loader' ); - - var button = $( 'form.upload button', frame_element ); - - button - .addClass( 'success' ); - - load_file( !file_exists ); - - $( 'body' ) - .animate( { scrollTop: 0 }, 500 ); - - window.setTimeout - ( - function() - { - button - .removeClass( 'success' ); - }, - 1000 - ); - } - } - ); - - return false; - } - ); } } ); diff --git a/solr/webapp/web/tpl/files.html b/solr/webapp/web/tpl/files.html index 93ffca897ca..0a27f24a95e 100644 --- a/solr/webapp/web/tpl/files.html +++ b/solr/webapp/web/tpl/files.html @@ -22,24 +22,6 @@ limitations under the License.
    #tree
    -
    - - - -
    - -

    Enter filename, on the next page you can input content or upload a file.

    - - - -
    - -
    - -
    - -
    -
    @@ -47,13 +29,6 @@ limitations under the License. -
    - - - - -
    -
    @@ -62,32 +37,6 @@ limitations under the License.
    -
    - -

    The requested file does (not yet) exist. Save file or Upload new file will create it.

    - -
    - - - -
    - -
    - -
    - -
    - - - -
    - -
    - -
    - -
    - From 0754f884a1ffd42c6129e7565207ecae0024e734 Mon Sep 17 00:00:00 2001 From: Noble Paul Date: Fri, 6 Dec 2013 12:58:35 +0000 Subject: [PATCH 188/223] SOLR-5525 git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1548503 13f79535-47bb-0310-9956-ffa450edef68 --- .../java/org/apache/solr/cloud/Overseer.java | 49 ++++++++++------- .../apache/solr/cloud/ClusterStateTest.java | 6 +-- .../org/apache/solr/cloud/SliceStateTest.java | 2 +- .../solr/cloud/SliceStateUpdateTest.java | 9 ++-- .../solr/common/cloud/ClusterState.java | 53 ++++++++++++++----- .../solr/common/cloud/ZkStateReader.java | 14 ++--- 6 files changed, 88 insertions(+), 45 deletions(-) diff --git a/solr/core/src/java/org/apache/solr/cloud/Overseer.java b/solr/core/src/java/org/apache/solr/cloud/Overseer.java index 2793db92a9f..9298216f301 100644 --- a/solr/core/src/java/org/apache/solr/cloud/Overseer.java +++ b/solr/core/src/java/org/apache/solr/cloud/Overseer.java @@ -46,6 +46,8 @@ import org.apache.zookeeper.KeeperException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import static java.util.Collections.singletonMap; + /** * Cluster leader. Responsible node assignments, cluster state file? */ @@ -611,11 +613,11 @@ public class Overseer { List ranges = router.partitionRange(shards.size(), router.fullRange()); - Map newCollections = new LinkedHashMap(); +// Map newCollections = new LinkedHashMap(); Map newSlices = new LinkedHashMap(); - newCollections.putAll(state.getCollectionStates()); +// newCollections.putAll(state.getCollectionStates()); for (int i = 0; i < shards.size(); i++) { String sliceName = shards.get(i); /*} @@ -643,9 +645,10 @@ public class Overseer { if(message.getStr("fromApi") == null) collectionProps.put("autoCreated","true"); DocCollection newCollection = new DocCollection(collectionName, newSlices, collectionProps, router); - newCollections.put(collectionName, newCollection); - ClusterState newClusterState = new ClusterState(state.getLiveNodes(), newCollections); - return newClusterState; +// newCollections.put(collectionName, newCollection); + return state.copyWith(singletonMap(newCollection.getName(), newCollection)); +// ClusterState newClusterState = new ClusterState(state.getLiveNodes(), newCollections); +// return newClusterState; } /* @@ -771,6 +774,9 @@ public class Overseer { newCollections.put(collectionName, newCollection); return new ClusterState(state.getLiveNodes(), newCollections); } + private ClusterState newState(ClusterState state, Map colls) { + return state.copyWith(colls); + } /* * Remove collection from cloudstate @@ -779,11 +785,11 @@ public class Overseer { final String collection = message.getStr("name"); - final Map newCollections = new LinkedHashMap(clusterState.getCollectionStates()); // shallow copy - newCollections.remove(collection); +// final Map newCollections = new LinkedHashMap(clusterState.getCollectionStates()); // shallow copy +// newCollections.remove(collection); - ClusterState newState = new ClusterState(clusterState.getLiveNodes(), newCollections); - return newState; +// ClusterState newState = new ClusterState(clusterState.getLiveNodes(), newCollections); + return clusterState.copyWith(singletonMap(collection, (DocCollection)null)); } /* @@ -795,16 +801,17 @@ public class Overseer { log.info("Removing collection: " + collection + " shard: " + sliceId + " from clusterstate"); - final Map newCollections = new LinkedHashMap(clusterState.getCollectionStates()); // shallow copy - DocCollection coll = newCollections.get(collection); +// final Map newCollections = new LinkedHashMap(clusterState.getCollectionStates()); // shallow copy + DocCollection coll = clusterState.getCollection(collection); Map newSlices = new LinkedHashMap(coll.getSlicesMap()); newSlices.remove(sliceId); DocCollection newCollection = new DocCollection(coll.getName(), newSlices, coll.getProperties(), coll.getRouter()); - newCollections.put(newCollection.getName(), newCollection); +// newCollections.put(newCollection.getName(), newCollection); + return newState(clusterState, singletonMap(collection,newCollection)); - return new ClusterState(clusterState.getLiveNodes(), newCollections); +// return new ClusterState(clusterState.getLiveNodes(), newCollections); } /* @@ -816,8 +823,9 @@ public class Overseer { final String collection = message.getStr(ZkStateReader.COLLECTION_PROP); - final Map newCollections = new LinkedHashMap(clusterState.getCollectionStates()); // shallow copy - DocCollection coll = newCollections.get(collection); +// final Map newCollections = new LinkedHashMap(clusterState.getCollectionStates()); // shallow copy +// DocCollection coll = newCollections.get(collection); + DocCollection coll = clusterState.getCollectionOrNull(collection) ; if (coll == null) { // TODO: log/error that we didn't find it? // just in case, remove the zk collection node @@ -866,7 +874,7 @@ public class Overseer { // if there are no slices left in the collection, remove it? if (newSlices.size() == 0) { - newCollections.remove(coll.getName()); +// newCollections.remove(coll.getName()); // TODO: it might be better logically to have this in ZkController // but for tests (it's easier) it seems better for the moment to leave CoreContainer and/or @@ -879,15 +887,18 @@ public class Overseer { } catch (KeeperException e) { SolrException.log(log, "Problem cleaning up collection in zk:" + collection, e); } + return newState(clusterState,singletonMap(collection, (DocCollection) null)); + } else { DocCollection newCollection = new DocCollection(coll.getName(), newSlices, coll.getProperties(), coll.getRouter()); - newCollections.put(newCollection.getName(), newCollection); + return newState(clusterState,singletonMap(collection,newCollection)); +// newCollections.put(newCollection.getName(), newCollection); } - ClusterState newState = new ClusterState(clusterState.getLiveNodes(), newCollections); - return newState; +// ClusterState newState = new ClusterState(clusterState.getLiveNodes(), newCollections); +// return newState; } @Override diff --git a/solr/core/src/test/org/apache/solr/cloud/ClusterStateTest.java b/solr/core/src/test/org/apache/solr/cloud/ClusterStateTest.java index 092f647b879..0af40e11da4 100644 --- a/solr/core/src/test/org/apache/solr/cloud/ClusterStateTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/ClusterStateTest.java @@ -58,7 +58,7 @@ public class ClusterStateTest extends SolrTestCaseJ4 { ClusterState clusterState = new ClusterState(liveNodes, collectionStates); byte[] bytes = ZkStateReader.toJSON(clusterState); // System.out.println("#################### " + new String(bytes)); - ClusterState loadedClusterState = ClusterState.load(null, bytes, liveNodes); + ClusterState loadedClusterState = ClusterState.load(null, bytes, liveNodes,null); assertEquals("Provided liveNodes not used properly", 2, loadedClusterState .getLiveNodes().size()); @@ -66,13 +66,13 @@ public class ClusterStateTest extends SolrTestCaseJ4 { assertEquals("Poperties not copied properly", replica.getStr("prop1"), loadedClusterState.getSlice("collection1", "shard1").getReplicasMap().get("node1").getStr("prop1")); assertEquals("Poperties not copied properly", replica.getStr("prop2"), loadedClusterState.getSlice("collection1", "shard1").getReplicasMap().get("node1").getStr("prop2")); - loadedClusterState = ClusterState.load(null, new byte[0], liveNodes); + loadedClusterState = ClusterState.load(null, new byte[0], liveNodes,null); assertEquals("Provided liveNodes not used properly", 2, loadedClusterState .getLiveNodes().size()); assertEquals("Should not have collections", 0, loadedClusterState.getCollections().size()); - loadedClusterState = ClusterState.load(null, (byte[])null, liveNodes); + loadedClusterState = ClusterState.load(null, (byte[])null, liveNodes,null); assertEquals("Provided liveNodes not used properly", 2, loadedClusterState .getLiveNodes().size()); diff --git a/solr/core/src/test/org/apache/solr/cloud/SliceStateTest.java b/solr/core/src/test/org/apache/solr/cloud/SliceStateTest.java index 85b54daef60..2206f060981 100644 --- a/solr/core/src/test/org/apache/solr/cloud/SliceStateTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/SliceStateTest.java @@ -51,7 +51,7 @@ public class SliceStateTest extends SolrTestCaseJ4 { ClusterState clusterState = new ClusterState(liveNodes, collectionStates); byte[] bytes = ZkStateReader.toJSON(clusterState); - ClusterState loadedClusterState = ClusterState.load(null, bytes, liveNodes); + ClusterState loadedClusterState = ClusterState.load(null, bytes, liveNodes, null); assertEquals("Default state not set to active", "active", loadedClusterState.getSlice("collection1", "shard1").getState()); } diff --git a/solr/core/src/test/org/apache/solr/cloud/SliceStateUpdateTest.java b/solr/core/src/test/org/apache/solr/cloud/SliceStateUpdateTest.java index c72273efafe..8dde806418b 100644 --- a/solr/core/src/test/org/apache/solr/cloud/SliceStateUpdateTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/SliceStateUpdateTest.java @@ -37,6 +37,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; +import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; @@ -142,8 +143,8 @@ public class SliceStateUpdateTest extends SolrTestCaseJ4 { closeThread(updaterThread); ClusterState clusterState = container1.getZkController().getClusterState(); - Map collectionStates = - new LinkedHashMap(clusterState.getCollectionStates()); +// Map collectionStates = +// new LinkedHashMap(clusterState.getCollectionStates()); Map slicesMap = clusterState.getSlicesMap("collection1"); Map props = new HashMap(1); @@ -155,11 +156,11 @@ public class SliceStateUpdateTest extends SolrTestCaseJ4 { props.put(DocCollection.DOC_ROUTER, ZkNodeProps.makeMap("name", ImplicitDocRouter.NAME)); DocCollection coll = new DocCollection("collection1", slicesMap, props, DocRouter.DEFAULT); - collectionStates.put("collection1", coll); +// collectionStates.put("collection1", coll); SolrZkClient zkClient = new SolrZkClient(zkServer.getZkAddress(), AbstractZkTestCase.TIMEOUT); - ClusterState newState = new ClusterState(clusterState.getLiveNodes(), collectionStates); + ClusterState newState = clusterState.copyWith(Collections.singletonMap(coll.getName(), coll) ); zkClient.setData(ZkStateReader.CLUSTER_STATE, ZkStateReader.toJSON(newState), true); zkClient.close(); diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java b/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java index a6719cc010f..29c6a87e8e7 100644 --- a/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java +++ b/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java @@ -45,7 +45,9 @@ public class ClusterState implements JSONWriter.Writable { private Integer zkClusterStateVersion; private final Map collectionStates; // Map> - private final Set liveNodes; + private Set liveNodes; + private final ZkStateReader stateReader; + /** * Use this constr when ClusterState is meant for publication. @@ -54,19 +56,43 @@ public class ClusterState implements JSONWriter.Writable { */ public ClusterState(Set liveNodes, Map collectionStates) { - this(null, liveNodes, collectionStates); + this(null, liveNodes, collectionStates, null); + } + + /** + * @deprecated + */ + public ClusterState(Integer zkClusterStateVersion, Set liveNodes, + Map collectionStates) { + this(zkClusterStateVersion, liveNodes, collectionStates,null); + } /** * Use this constr when ClusterState is meant for consumption. */ public ClusterState(Integer zkClusterStateVersion, Set liveNodes, - Map collectionStates) { + Map collectionStates, ZkStateReader stateReader) { this.zkClusterStateVersion = zkClusterStateVersion; this.liveNodes = new HashSet(liveNodes.size()); this.liveNodes.addAll(liveNodes); - this.collectionStates = new HashMap(collectionStates.size()); + this.collectionStates = new LinkedHashMap(collectionStates.size()); this.collectionStates.putAll(collectionStates); + this.stateReader = stateReader; + + } + + public ClusterState copyWith(Map modified){ + ClusterState result = new ClusterState(zkClusterStateVersion, liveNodes,collectionStates,stateReader); + for (Entry e : modified.entrySet()) { + DocCollection c = e.getValue(); + if(c == null) { + result.collectionStates.remove(e.getKey()); + continue; + } + result.collectionStates.put(c.getName(), c); + } + return result; } @@ -208,29 +234,28 @@ public class ClusterState implements JSONWriter.Writable { /** * Create ClusterState by reading the current state from zookeeper. */ - public static ClusterState load(SolrZkClient zkClient, Set liveNodes) throws KeeperException, InterruptedException { + public static ClusterState load(SolrZkClient zkClient, Set liveNodes, ZkStateReader stateReader) throws KeeperException, InterruptedException { Stat stat = new Stat(); byte[] state = zkClient.getData(ZkStateReader.CLUSTER_STATE, null, stat, true); - return load(stat.getVersion(), state, liveNodes); + return load(stat.getVersion(), state, liveNodes, stateReader); } /** * Create ClusterState from json string that is typically stored in zookeeper. * - * Use {@link ClusterState#load(SolrZkClient, Set)} instead, unless you want to + * Use {@link ClusterState#load(SolrZkClient, Set, ZkStateReader)} instead, unless you want to * do something more when getting the data - such as get the stat, set watch, etc. - * * @param version zk version of the clusterstate.json file (bytes) * @param bytes clusterstate.json as a byte array * @param liveNodes list of live nodes * @return the ClusterState */ - public static ClusterState load(Integer version, byte[] bytes, Set liveNodes) { + public static ClusterState load(Integer version, byte[] bytes, Set liveNodes, ZkStateReader stateReader) { // System.out.println("######## ClusterState.load:" + (bytes==null ? null : new String(bytes))); if (bytes == null || bytes.length == 0) { - return new ClusterState(version, liveNodes, Collections.emptyMap()); + return new ClusterState(version, liveNodes, Collections.emptyMap(),stateReader); } Map stateMap = (Map) ZkStateReader.fromJSON(bytes); Map collections = new LinkedHashMap(stateMap.size()); @@ -337,7 +362,11 @@ public class ClusterState implements JSONWriter.Writable { return true; } - - + /**Internal API used only by ZkStateReader + * @param liveNodes + */ + void setLiveNodes(Set liveNodes){ + this.liveNodes = liveNodes; + } } diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java b/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java index ee17f8ab270..e67a68776aa 100644 --- a/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java +++ b/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java @@ -254,7 +254,7 @@ public class ZkStateReader { byte[] data = zkClient.getData(CLUSTER_STATE, thisWatch, stat , true); Set ln = ZkStateReader.this.clusterState.getLiveNodes(); - ClusterState clusterState = ClusterState.load(stat.getVersion(), data, ln); + ClusterState clusterState = ClusterState.load(stat.getVersion(), data, ln,ZkStateReader.this); // update volatile ZkStateReader.this.clusterState = clusterState; } @@ -326,7 +326,7 @@ public class ZkStateReader { Set liveNodeSet = new HashSet(); liveNodeSet.addAll(liveNodes); - ClusterState clusterState = ClusterState.load(zkClient, liveNodeSet); + ClusterState clusterState = ClusterState.load(zkClient, liveNodeSet, ZkStateReader.this); this.clusterState = clusterState; zkClient.exists(ALIASES, @@ -393,12 +393,14 @@ public class ZkStateReader { if (!onlyLiveNodes) { log.info("Updating cloud state from ZooKeeper... "); - clusterState = ClusterState.load(zkClient, liveNodesSet); + clusterState = ClusterState.load(zkClient, liveNodesSet,this); } else { log.info("Updating live nodes from ZooKeeper... ({})", liveNodesSet.size()); - clusterState = new ClusterState( + clusterState = this.clusterState; + clusterState.setLiveNodes(liveNodesSet); + /*clusterState = new ClusterState( ZkStateReader.this.clusterState.getZkClusterStateVersion(), liveNodesSet, - ZkStateReader.this.clusterState.getCollectionStates()); + ZkStateReader.this.clusterState.getCollectionStates());*/ } this.clusterState = clusterState; } @@ -427,7 +429,7 @@ public class ZkStateReader { if (!onlyLiveNodes) { log.info("Updating cloud state from ZooKeeper... "); - clusterState = ClusterState.load(zkClient, liveNodesSet); + clusterState = ClusterState.load(zkClient, liveNodesSet,ZkStateReader.this); } else { log.info("Updating live nodes from ZooKeeper... "); clusterState = new ClusterState(ZkStateReader.this.clusterState.getZkClusterStateVersion(), liveNodesSet, ZkStateReader.this.clusterState.getCollectionStates()); From a758823bbe7a8711d47a2276d4a1688bdc9d837f Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Fri, 6 Dec 2013 16:41:08 +0000 Subject: [PATCH 189/223] Clean up. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1548587 13f79535-47bb-0310-9956-ffa450edef68 --- .../java/org/apache/solr/common/cloud/ClusterState.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java b/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java index 29c6a87e8e7..52f7bda768a 100644 --- a/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java +++ b/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java @@ -60,11 +60,11 @@ public class ClusterState implements JSONWriter.Writable { } /** - * @deprecated + * @deprecated prefer another constructor */ public ClusterState(Integer zkClusterStateVersion, Set liveNodes, Map collectionStates) { - this(zkClusterStateVersion, liveNodes, collectionStates,null); + this(zkClusterStateVersion, liveNodes, collectionStates, null); } @@ -362,8 +362,8 @@ public class ClusterState implements JSONWriter.Writable { return true; } - /**Internal API used only by ZkStateReader - * @param liveNodes + /** + * Internal API used only by ZkStateReader */ void setLiveNodes(Set liveNodes){ this.liveNodes = liveNodes; From 0c8d47a00e7053b1d3e419d6bc48b3325f0dd6f7 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Fri, 6 Dec 2013 16:44:53 +0000 Subject: [PATCH 190/223] SOLR-5540: HdfsLockFactory should explicitly create the lock parent directory if necessary. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1548590 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 3 +++ .../org/apache/solr/store/hdfs/HdfsLockFactory.java | 13 +++++++++++-- .../apache/solr/store/hdfs/HdfsLockFactoryTest.java | 2 +- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 7db6b5587ee..a84f60e33bb 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -191,6 +191,9 @@ Bug Fixes * SOLR-5524: Exception when using Query Function inside Scale Function. (Trey Grainger, yonik) + +* SOLR-5540: HdfsLockFactory should explicitly create the lock parent directory if + necessary. (Mark Miller) Optimizations ---------------------- diff --git a/solr/core/src/java/org/apache/solr/store/hdfs/HdfsLockFactory.java b/solr/core/src/java/org/apache/solr/store/hdfs/HdfsLockFactory.java index ecf113ace17..d46965511e5 100644 --- a/solr/core/src/java/org/apache/solr/store/hdfs/HdfsLockFactory.java +++ b/solr/core/src/java/org/apache/solr/store/hdfs/HdfsLockFactory.java @@ -21,14 +21,18 @@ import java.io.IOException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FSDataOutputStream; +import org.apache.hadoop.fs.FileAlreadyExistsException; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.lucene.store.Lock; import org.apache.lucene.store.LockFactory; import org.apache.lucene.store.LockReleaseFailedException; import org.apache.solr.util.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class HdfsLockFactory extends LockFactory { + public static Logger log = LoggerFactory.getLogger(HdfsLockFactory.class); private Path lockPath; private Configuration configuration; @@ -98,9 +102,14 @@ public class HdfsLockFactory extends LockFactory { FileSystem fs = null; try { fs = FileSystem.newInstance(lockPath.toUri(), conf); - + if (!fs.exists(lockPath)) { + fs.mkdirs(lockPath); + } file = fs.create(new Path(lockPath, lockName), false); - } catch (IOException e) { + } catch (FileAlreadyExistsException e) { + return false; + }catch (IOException e) { + log.error("Error creating lock file", e); return false; } finally { IOUtils.closeQuietly(file); diff --git a/solr/core/src/test/org/apache/solr/store/hdfs/HdfsLockFactoryTest.java b/solr/core/src/test/org/apache/solr/store/hdfs/HdfsLockFactoryTest.java index 4f9637427df..39493dbf5cd 100644 --- a/solr/core/src/test/org/apache/solr/store/hdfs/HdfsLockFactoryTest.java +++ b/solr/core/src/test/org/apache/solr/store/hdfs/HdfsLockFactoryTest.java @@ -68,7 +68,7 @@ public class HdfsLockFactoryTest extends SolrTestCaseJ4 { @Test public void testBasic() throws IOException { URI uri = dfsCluster.getURI(); - Path lockPath = new Path(uri.toString(), "/lock"); + Path lockPath = new Path(uri.toString(), "/basedir/lock"); HdfsLockFactory lockFactory = new HdfsLockFactory(lockPath, new Configuration()); Lock lock = lockFactory.makeLock("testlock"); boolean success = lock.obtain(); From 618f6b876d08270c778849c785ff12fd13803164 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Fri, 6 Dec 2013 16:49:18 +0000 Subject: [PATCH 191/223] SOLR-5533: Improve out of the box support for running Solr on hdfs with SolrCloud. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1548593 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 3 +++ solr/example/solr/collection1/conf/solrconfig.xml | 15 ++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index a84f60e33bb..d51fcb0df65 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -234,6 +234,9 @@ Other Changes * SOLR-5539: Admin UI - Remove ability to create/modify files (steffkes) +* SOLR-5533: Improve out of the box support for running Solr on hdfs with + SolrCloud. (Mark Miller) + ================== 4.6.0 ================== Versions of Major Components diff --git a/solr/example/solr/collection1/conf/solrconfig.xml b/solr/example/solr/collection1/conf/solrconfig.xml index c770599b7e2..3126c21d74d 100755 --- a/solr/example/solr/collection1/conf/solrconfig.xml +++ b/solr/example/solr/collection1/conf/solrconfig.xml @@ -117,7 +117,20 @@ persistent, and doesn't work with replication. --> + class="${solr.directoryFactory:solr.NRTCachingDirectoryFactory}"> + + + + + ${solr.hdfs.home:} + + ${solr.hdfs.confdir:} + + ${solr.hdfs.blockcache.enabled:true} + + - + nobak="on" inputstreamctor="false"/> + - + match="/\*\*\s*\*\s*Creates a new scanner\s*\*\s*\*\s*@param\s*in\s*the java.io.Reader to read input from\.\s*\*/\s*public HTMLStripCharFilter\(java\.io\.Reader in\)\s*\{\s*this.zzReader = in;\s*\}" + replace="" flags="s"/> @@ -96,15 +92,7 @@ - - - + diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/charfilter/HTMLStripCharFilter.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/charfilter/HTMLStripCharFilter.java index 315c0eba500..4163a8f8c5d 100644 --- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/charfilter/HTMLStripCharFilter.java +++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/charfilter/HTMLStripCharFilter.java @@ -1,4 +1,4 @@ -/* The following code was generated by JFlex. */ +/* The following code was generated by JFlex 1.5.0-SNAPSHOT */ package org.apache.lucene.analysis.charfilter; @@ -152,77 +152,77 @@ public final class HTMLStripCharFilter extends BaseCharFilter { "\21\1\1\41\32\1\5\0\113\1\3\0\3\1\17\0\15\1\1\0"+ "\4\1\3\2\13\0\22\1\3\2\13\0\22\1\2\2\14\0\15\1"+ "\1\0\3\1\1\0\2\2\14\0\64\1\40\2\3\0\1\1\4\0"+ - "\1\1\1\2\2\0\12\274\41\0\3\2\1\41\1\0\12\274\6\0"+ - "\130\1\10\0\51\1\1\2\1\1\5\0\106\1\12\0\35\1\3\0"+ - "\14\2\4\0\14\2\12\0\12\274\36\1\2\0\5\1\13\0\54\1"+ - "\4\0\21\2\7\1\2\2\6\0\12\274\1\2\45\0\27\1\5\2"+ - "\4\0\65\1\12\2\1\0\35\2\2\0\1\2\12\274\6\0\12\274"+ - "\15\0\1\1\130\0\5\2\57\1\21\2\7\1\4\0\12\274\21\0"+ - "\11\2\14\0\3\2\36\1\15\2\2\1\12\274\54\1\16\2\14\0"+ - "\44\1\24\2\10\0\12\274\3\0\3\1\12\274\44\1\122\0\3\2"+ - "\1\0\25\2\4\1\1\2\4\1\3\2\2\1\11\0\300\1\47\2"+ - "\25\0\4\2\u0116\1\2\0\6\1\2\0\46\1\2\0\6\1\2\0"+ - "\10\1\1\0\1\1\1\0\1\1\1\0\1\1\1\0\37\1\2\0"+ - "\65\1\1\0\7\1\1\0\1\1\3\0\3\1\1\0\7\1\3\0"+ - "\4\1\2\0\6\1\4\0\15\1\5\0\3\1\1\0\7\1\3\0"+ - "\13\41\35\0\2\41\5\0\1\41\17\0\2\2\23\0\1\2\12\0"+ - "\1\41\21\0\1\1\15\0\1\1\20\0\15\1\63\0\15\2\4\0"+ - "\1\2\3\0\14\2\21\0\1\1\4\0\1\1\2\0\12\1\1\0"+ - "\1\1\2\0\6\1\6\0\1\1\1\0\1\1\1\0\1\1\1\0"+ - "\20\1\2\0\4\1\5\0\5\1\4\0\1\1\21\0\51\1\u0a77\0"+ - "\57\1\1\0\57\1\1\0\205\1\6\0\4\1\3\2\2\1\14\0"+ - "\46\1\1\0\1\1\5\0\1\1\2\0\70\1\7\0\1\1\17\0"+ - "\1\2\27\1\11\0\7\1\1\0\7\1\1\0\7\1\1\0\7\1"+ - "\1\0\7\1\1\0\7\1\1\0\7\1\1\0\7\1\1\0\40\2"+ - "\u0200\0\1\41\4\0\3\1\31\0\11\1\6\2\1\0\5\1\2\0"+ - "\5\1\4\0\126\1\2\0\2\2\5\1\1\0\132\1\1\0\4\1"+ - "\5\0\51\1\3\0\136\1\21\0\33\1\65\0\20\1\u0200\0\u19b6\1"+ - "\112\0\u51cd\1\63\0\u048d\1\103\0\56\1\2\0\u010d\1\3\0\20\1"+ - "\12\274\2\1\24\0\57\1\1\2\4\0\12\2\1\0\31\1\7\0"+ - "\1\2\120\1\2\2\45\0\11\1\2\0\147\1\2\0\4\1\1\0"+ - "\4\1\14\0\13\1\115\0\12\1\1\2\3\1\1\2\4\1\1\2"+ - "\27\1\5\2\30\0\64\1\14\0\2\2\62\1\21\2\13\0\12\274"+ - "\6\0\22\2\6\1\3\0\1\1\4\0\12\274\34\1\10\2\2\0"+ - "\27\1\15\2\14\0\35\1\3\0\4\2\57\1\16\2\16\0\1\1"+ - "\12\274\46\0\51\1\16\2\11\0\3\1\1\2\10\1\2\2\2\0"+ - "\12\274\6\0\27\1\3\0\1\1\1\2\4\0\60\1\1\2\1\1"+ - "\3\2\2\1\2\2\5\1\2\2\1\1\1\2\1\1\30\0\3\1"+ - "\2\0\13\1\5\2\2\0\3\1\2\2\12\0\6\1\2\0\6\1"+ - "\2\0\6\1\11\0\7\1\1\0\7\1\221\0\43\1\10\2\1\0"+ - "\2\2\2\0\12\274\6\0\u2ba4\1\14\0\27\1\4\0\61\1\4\0"+ - "\1\170\1\223\1\103\1\165\1\136\1\214\2\0\1\160\1\153\2\0"+ - "\1\120\1\210\14\0\1\105\1\127\20\0\1\122\7\0\1\256\1\112"+ - "\5\0\1\143\4\0\51\120\1\110\3\120\1\124\1\220\17\0\1\133"+ - "\u02c1\0\1\252\277\0\2\123\1\212\3\222\2\211\1\222\1\211\2\222"+ - "\1\221\21\222\11\213\1\157\7\213\7\204\1\156\1\204\1\246\2\207"+ - "\1\166\1\246\1\207\1\166\10\246\2\167\5\203\2\155\5\203\1\107"+ - "\10\202\5\154\3\224\12\251\20\224\3\225\32\227\1\226\2\200\2\234"+ - "\1\235\2\234\2\235\2\234\1\235\3\200\1\177\2\200\12\250\1\247"+ - "\1\176\1\171\7\176\1\171\13\176\31\200\7\176\12\250\1\176\5\134"+ - "\3\245\3\142\1\140\4\142\2\140\10\142\1\140\7\141\1\137\2\141"+ - "\7\142\16\245\1\135\4\245\1\106\4\244\1\106\5\255\1\254\1\255"+ - "\3\254\7\255\1\254\23\255\5\264\3\255\6\264\2\255\6\253\5\263"+ - "\3\262\2\142\7\257\36\142\4\257\5\142\5\245\6\244\2\245\1\244"+ - "\4\141\13\253\12\244\26\253\15\134\1\243\2\134\1\152\3\237\1\134"+ - "\2\237\5\151\4\237\4\152\1\151\3\152\1\151\5\152\2\147\1\116"+ - "\2\147\1\116\1\147\2\116\1\147\1\116\12\147\1\116\4\146\1\115"+ - "\1\236\1\240\1\150\3\164\1\240\2\164\1\260\2\261\2\164\1\150"+ - "\1\164\1\150\1\164\1\150\1\164\3\150\1\164\2\150\1\164\1\150"+ - "\2\164\1\150\1\164\1\150\1\164\1\150\1\164\1\150\1\164\1\150"+ - "\1\162\2\145\1\162\1\145\2\162\4\145\1\162\7\145\1\162\4\145"+ - "\1\162\4\145\1\164\1\150\1\164\12\216\1\217\21\216\1\217\3\215"+ - "\1\217\3\216\1\217\1\216\2\144\2\216\1\217\15\241\4\201\4\206"+ - "\1\242\1\161\10\242\7\206\6\164\4\113\1\121\37\113\1\121\4\113"+ - "\25\174\1\131\11\174\21\130\5\174\1\104\12\117\5\174\6\205\4\162"+ - "\1\163\1\130\5\231\12\232\17\231\1\125\3\114\14\230\1\126\11\173"+ - "\1\172\5\173\4\233\13\175\2\132\11\173\1\172\31\173\1\172\4\126"+ - "\4\173\2\172\2\265\1\111\5\265\52\111\u1900\0\u016e\1\2\0\152\1"+ - "\46\0\7\1\14\0\5\1\5\0\1\1\1\2\12\1\1\0\15\1"+ - "\1\0\5\1\1\0\1\1\1\0\2\1\1\0\2\1\1\0\154\1"+ - "\41\0\u016b\1\22\0\100\1\2\0\66\1\50\0\14\1\4\0\20\2"+ - "\20\0\7\2\14\0\2\2\30\0\3\2\40\0\5\1\1\0\207\1"+ - "\23\0\12\274\7\0\32\1\4\0\1\2\1\0\32\1\13\0\131\1"+ - "\3\0\6\1\2\0\6\1\2\0\6\1\2\0\3\1\43\0"; + "\1\1\1\2\2\0\12\274\41\0\3\2\2\0\12\274\6\0\130\1"+ + "\10\0\51\1\1\2\1\1\5\0\106\1\12\0\35\1\3\0\14\2"+ + "\4\0\14\2\12\0\12\274\36\1\2\0\5\1\13\0\54\1\4\0"+ + "\21\2\7\1\2\2\6\0\12\274\1\2\45\0\27\1\5\2\4\0"+ + "\65\1\12\2\1\0\35\2\2\0\1\2\12\274\6\0\12\274\15\0"+ + "\1\1\130\0\5\2\57\1\21\2\7\1\4\0\12\274\21\0\11\2"+ + "\14\0\3\2\36\1\15\2\2\1\12\274\54\1\16\2\14\0\44\1"+ + "\24\2\10\0\12\274\3\0\3\1\12\274\44\1\122\0\3\2\1\0"+ + "\25\2\4\1\1\2\4\1\3\2\2\1\11\0\300\1\47\2\25\0"+ + "\4\2\u0116\1\2\0\6\1\2\0\46\1\2\0\6\1\2\0\10\1"+ + "\1\0\1\1\1\0\1\1\1\0\1\1\1\0\37\1\2\0\65\1"+ + "\1\0\7\1\1\0\1\1\3\0\3\1\1\0\7\1\3\0\4\1"+ + "\2\0\6\1\4\0\15\1\5\0\3\1\1\0\7\1\3\0\13\41"+ + "\35\0\2\41\5\0\1\41\17\0\2\2\23\0\1\2\12\0\1\41"+ + "\21\0\1\1\15\0\1\1\20\0\15\1\63\0\15\2\4\0\1\2"+ + "\3\0\14\2\21\0\1\1\4\0\1\1\2\0\12\1\1\0\1\1"+ + "\2\0\6\1\6\0\1\1\1\0\1\1\1\0\1\1\1\0\20\1"+ + "\2\0\4\1\5\0\5\1\4\0\1\1\21\0\51\1\u0a77\0\57\1"+ + "\1\0\57\1\1\0\205\1\6\0\4\1\3\2\2\1\14\0\46\1"+ + "\1\0\1\1\5\0\1\1\2\0\70\1\7\0\1\1\17\0\1\2"+ + "\27\1\11\0\7\1\1\0\7\1\1\0\7\1\1\0\7\1\1\0"+ + "\7\1\1\0\7\1\1\0\7\1\1\0\7\1\1\0\40\2\u0200\0"+ + "\1\41\4\0\3\1\31\0\11\1\6\2\1\0\5\1\2\0\5\1"+ + "\4\0\126\1\2\0\2\2\5\1\1\0\132\1\1\0\4\1\5\0"+ + "\51\1\3\0\136\1\21\0\33\1\65\0\20\1\u0200\0\u19b6\1\112\0"+ + "\u51cd\1\63\0\u048d\1\103\0\56\1\2\0\u010d\1\3\0\20\1\12\274"+ + "\2\1\24\0\57\1\1\2\4\0\12\2\1\0\31\1\7\0\1\2"+ + "\120\1\2\2\45\0\11\1\2\0\147\1\2\0\4\1\1\0\4\1"+ + "\14\0\13\1\115\0\12\1\1\2\3\1\1\2\4\1\1\2\27\1"+ + "\5\2\30\0\64\1\14\0\2\2\62\1\21\2\13\0\12\274\6\0"+ + "\22\2\6\1\3\0\1\1\4\0\12\274\34\1\10\2\2\0\27\1"+ + "\15\2\14\0\35\1\3\0\4\2\57\1\16\2\16\0\1\1\12\274"+ + "\46\0\51\1\16\2\11\0\3\1\1\2\10\1\2\2\2\0\12\274"+ + "\6\0\27\1\3\0\1\1\1\2\4\0\60\1\1\2\1\1\3\2"+ + "\2\1\2\2\5\1\2\2\1\1\1\2\1\1\30\0\3\1\2\0"+ + "\13\1\5\2\2\0\3\1\2\2\12\0\6\1\2\0\6\1\2\0"+ + "\6\1\11\0\7\1\1\0\7\1\221\0\43\1\10\2\1\0\2\2"+ + "\2\0\12\274\6\0\u2ba4\1\14\0\27\1\4\0\61\1\4\0\1\170"+ + "\1\223\1\103\1\165\1\136\1\214\2\0\1\160\1\153\2\0\1\120"+ + "\1\210\14\0\1\105\1\127\20\0\1\122\7\0\1\256\1\112\5\0"+ + "\1\143\4\0\51\120\1\110\3\120\1\124\1\220\17\0\1\133\u02c1\0"+ + "\1\252\277\0\2\123\1\212\3\222\2\211\1\222\1\211\2\222\1\221"+ + "\21\222\11\213\1\157\7\213\7\204\1\156\1\204\1\246\2\207\1\166"+ + "\1\246\1\207\1\166\10\246\2\167\5\203\2\155\5\203\1\107\10\202"+ + "\5\154\3\224\12\251\20\224\3\225\32\227\1\226\2\200\2\234\1\235"+ + "\2\234\2\235\2\234\1\235\3\200\1\177\2\200\12\250\1\247\1\176"+ + "\1\171\7\176\1\171\13\176\31\200\7\176\12\250\1\176\5\134\3\245"+ + "\3\142\1\140\4\142\2\140\10\142\1\140\7\141\1\137\2\141\7\142"+ + "\16\245\1\135\4\245\1\106\4\244\1\106\5\255\1\254\1\255\3\254"+ + "\7\255\1\254\23\255\5\264\3\255\6\264\2\255\6\253\5\263\3\262"+ + "\2\142\7\257\36\142\4\257\5\142\5\245\6\244\2\245\1\244\4\141"+ + "\13\253\12\244\26\253\15\134\1\243\2\134\1\152\3\237\1\134\2\237"+ + "\5\151\4\237\4\152\1\151\3\152\1\151\5\152\2\147\1\116\2\147"+ + "\1\116\1\147\2\116\1\147\1\116\12\147\1\116\4\146\1\115\1\236"+ + "\1\240\1\150\3\164\1\240\2\164\1\260\2\261\2\164\1\150\1\164"+ + "\1\150\1\164\1\150\1\164\3\150\1\164\2\150\1\164\1\150\2\164"+ + "\1\150\1\164\1\150\1\164\1\150\1\164\1\150\1\164\1\150\1\162"+ + "\2\145\1\162\1\145\2\162\4\145\1\162\7\145\1\162\4\145\1\162"+ + "\4\145\1\164\1\150\1\164\12\216\1\217\21\216\1\217\3\215\1\217"+ + "\3\216\1\217\1\216\2\144\2\216\1\217\15\241\4\201\4\206\1\242"+ + "\1\161\10\242\7\206\6\164\4\113\1\121\37\113\1\121\4\113\25\174"+ + "\1\131\11\174\21\130\5\174\1\104\12\117\5\174\6\205\4\162\1\163"+ + "\1\130\5\231\12\232\17\231\1\125\3\114\14\230\1\126\11\173\1\172"+ + "\5\173\4\233\13\175\2\132\11\173\1\172\31\173\1\172\4\126\4\173"+ + "\2\172\2\265\1\111\5\265\52\111\u1900\0\u016e\1\2\0\152\1\46\0"+ + "\7\1\14\0\5\1\5\0\1\1\1\2\12\1\1\0\15\1\1\0"+ + "\5\1\1\0\1\1\1\0\2\1\1\0\2\1\1\0\154\1\41\0"+ + "\u016b\1\22\0\100\1\2\0\66\1\50\0\14\1\4\0\20\2\20\0"+ + "\7\2\14\0\2\2\30\0\3\2\40\0\5\1\1\0\207\1\23\0"+ + "\12\274\7\0\32\1\4\0\1\2\1\0\32\1\13\0\131\1\3\0"+ + "\6\1\2\0\6\1\2\0\6\1\2\0\3\1\43\0"; /** * Translates characters to character classes @@ -30895,6 +30895,7 @@ public final class HTMLStripCharFilter extends BaseCharFilter { + /** * Unpacks the compressed character translation table. * @@ -30905,7 +30906,7 @@ public final class HTMLStripCharFilter extends BaseCharFilter { char [] map = new char[0x10000]; int i = 0; /* index in packed string */ int j = 0; /* index in unpacked array */ - while (i < 2778) { + while (i < 2776) { int count = packed.charAt(i++); char value = packed.charAt(i++); do map[j++] = value; while (--count > 0); diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/charfilter/HTMLStripCharFilter.jflex b/lucene/analysis/common/src/java/org/apache/lucene/analysis/charfilter/HTMLStripCharFilter.jflex index 655b427a1ad..2a19332590f 100755 --- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/charfilter/HTMLStripCharFilter.jflex +++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/charfilter/HTMLStripCharFilter.jflex @@ -34,7 +34,7 @@ import org.apache.lucene.analysis.util.OpenStringBuilder; */ %% -%unicode 6.1 +%unicode 6.3 %apiprivate %type int %final diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/ASCIITLD.jflex-macro b/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/ASCIITLD.jflex-macro index b907d1438cf..5d78558a20d 100644 --- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/ASCIITLD.jflex-macro +++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/ASCIITLD.jflex-macro @@ -1,11 +1,12 @@ /* - * Copyright 2001-2005 The Apache Software Foundation. + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -13,10 +14,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - // Generated from IANA Root Zone Database -// file version from Saturday, July 14, 2012 4:34:14 AM UTC -// generated on Sunday, July 15, 2012 12:59:44 AM UTC +// file version from Friday, December 6, 2013 4:34:10 AM UTC +// generated on Friday, December 6, 2013 3:21:59 PM UTC // by org.apache.lucene.analysis.standard.GenerateJflexTLDMacros ASCIITLD = "." ( @@ -49,6 +49,7 @@ ASCIITLD = "." ( | [bB][gG] | [bB][hH] | [bB][iI] + | [bB][iI][kK][eE] | [bB][iI][zZ] | [bB][jJ] | [bB][mM] @@ -62,6 +63,7 @@ ASCIITLD = "." ( | [bB][yY] | [bB][zZ] | [cC][aA] + | [cC][aA][mM][eE][rR][aA] | [cC][aA][tT] | [cC][cC] | [cC][dD] @@ -71,10 +73,13 @@ ASCIITLD = "." ( | [cC][iI] | [cC][kK] | [cC][lL] + | [cC][lL][oO][tT][hH][iI][nN][gG] | [cC][mM] | [cC][nN] | [cC][oO] | [cC][oO][mM] + | [cC][oO][nN][sS][tT][rR][uU][cC][tT][iI][oO][nN] + | [cC][oO][nN][tT][rR][aA][cC][tT][oO][rR][sS] | [cC][oO][oO][pP] | [cC][rR] | [cC][uU] @@ -84,6 +89,8 @@ ASCIITLD = "." ( | [cC][yY] | [cC][zZ] | [dD][eE] + | [dD][iI][aA][mM][oO][nN][dD][sS] + | [dD][iI][rR][eE][cC][tT][oO][rR][yY] | [dD][jJ] | [dD][kK] | [dD][mM] @@ -93,8 +100,11 @@ ASCIITLD = "." ( | [eE][dD][uU] | [eE][eE] | [eE][gG] + | [eE][nN][tT][eE][rR][pP][rR][iI][sS][eE][sS] + | [eE][qQ][uU][iI][pP][mM][eE][nN][tT] | [eE][rR] | [eE][sS] + | [eE][sS][tT][aA][tT][eE] | [eE][tT] | [eE][uU] | [fF][iI] @@ -104,6 +114,7 @@ ASCIITLD = "." ( | [fF][oO] | [fF][rR] | [gG][aA] + | [gG][aA][lL][lL][eE][rR][yY] | [gG][bB] | [gG][dD] | [gG][eE] @@ -118,14 +129,17 @@ ASCIITLD = "." ( | [gG][pP] | [gG][qQ] | [gG][rR] + | [gG][rR][aA][pP][hH][iI][cC][sS] | [gG][sS] | [gG][tT] | [gG][uU] + | [gG][uU][rR][uU] | [gG][wW] | [gG][yY] | [hH][kK] | [hH][mM] | [hH][nN] + | [hH][oO][lL][dD][iI][nN][gG][sS] | [hH][rR] | [hH][tT] | [hH][uU] @@ -150,6 +164,7 @@ ASCIITLD = "." ( | [kK][gG] | [kK][hH] | [kK][iI] + | [kK][iI][tT][cC][hH][eE][nN] | [kK][mM] | [kK][nN] | [kK][pP] @@ -158,9 +173,11 @@ ASCIITLD = "." ( | [kK][yY] | [kK][zZ] | [lL][aA] + | [lL][aA][nN][dD] | [lL][bB] | [lL][cC] | [lL][iI] + | [lL][iI][gG][hH][tT][iI][nN][gG] | [lL][kK] | [lL][rR] | [lL][sS] @@ -172,6 +189,7 @@ ASCIITLD = "." ( | [mM][cC] | [mM][dD] | [mM][eE] + | [mM][eE][nN][uU] | [mM][gG] | [mM][hH] | [mM][iI][lL] @@ -214,10 +232,13 @@ ASCIITLD = "." ( | [pP][fF] | [pP][gG] | [pP][hH] + | [pP][hH][oO][tT][oO][gG][rR][aA][pP][hH][yY] | [pP][kK] | [pP][lL] + | [pP][lL][uU][mM][bB][iI][nN][gG] | [pP][mM] | [pP][nN] + | [pP][oO][sS][tT] | [pP][rR] | [pP][rR][oO] | [pP][sS] @@ -235,9 +256,11 @@ ASCIITLD = "." ( | [sS][cC] | [sS][dD] | [sS][eE] + | [sS][eE][xX][yY] | [sS][gG] | [sS][hH] | [sS][iI] + | [sS][iI][nN][gG][lL][eE][sS] | [sS][jJ] | [sS][kK] | [sS][lL] @@ -251,18 +274,22 @@ ASCIITLD = "." ( | [sS][xX] | [sS][yY] | [sS][zZ] + | [tT][aA][tT][tT][oO][oO] | [tT][cC] | [tT][dD] + | [tT][eE][cC][hH][nN][oO][lL][oO][gG][yY] | [tT][eE][lL] | [tT][fF] | [tT][gG] | [tT][hH] + | [tT][iI][pP][sS] | [tT][jJ] | [tT][kK] | [tT][lL] | [tT][mM] | [tT][nN] | [tT][oO] + | [tT][oO][dD][aA][yY] | [tT][pP] | [tT][rR] | [tT][rR][aA][vV][eE][lL] @@ -273,61 +300,62 @@ ASCIITLD = "." ( | [uU][aA] | [uU][gG] | [uU][kK] + | [uU][nN][oO] | [uU][sS] | [uU][yY] | [uU][zZ] | [vV][aA] | [vV][cC] | [vV][eE] + | [vV][eE][nN][tT][uU][rR][eE][sS] | [vV][gG] | [vV][iI] | [vV][nN] + | [vV][oO][yY][aA][gG][eE] | [vV][uU] | [wW][fF] | [wW][sS] - | [xX][nN]--0[zZ][wW][mM]56[dD] - | [xX][nN]--11[bB]5[bB][sS]3[aA]9[aA][jJ]6[gG] | [xX][nN]--3[eE]0[bB]707[eE] | [xX][nN]--45[bB][rR][jJ]9[cC] - | [xX][nN]--80[aA][kK][hH][bB][yY][kK][nN][jJ]4[fF] | [xX][nN]--80[aA][oO]21[aA] + | [xX][nN]--80[aA][sS][eE][hH][dD][bB] + | [xX][nN]--80[aA][sS][wW][gG] | [xX][nN]--90[aA]3[aA][cC] - | [xX][nN]--9[tT]4[bB]11[yY][iI]5[aA] | [xX][nN]--[cC][lL][cC][hH][cC]0[eE][aA]0[bB]2[gG]2[aA]9[gG][cC][dD] - | [xX][nN]--[dD][eE][bB][aA]0[aA][dD] | [xX][nN]--[fF][iI][qQ][sS]8[sS] | [xX][nN]--[fF][iI][qQ][zZ]9[sS] | [xX][nN]--[fF][pP][cC][rR][jJ]9[cC]3[dD] | [xX][nN]--[fF][zZ][cC]2[cC]9[eE]2[cC] - | [xX][nN]--[gG]6[wW]251[dD] | [xX][nN]--[gG][eE][cC][rR][jJ]9[cC] | [xX][nN]--[hH]2[bB][rR][jJ]9[cC] - | [xX][nN]--[hH][gG][bB][kK]6[aA][jJ]7[fF]53[bB][bB][aA] - | [xX][nN]--[hH][lL][cC][jJ]6[aA][yY][aA]9[eE][sS][cC]7[aA] + | [xX][nN]--[jJ]1[aA][mM][hH] | [xX][nN]--[jJ]6[wW]193[gG] - | [xX][nN]--[jJ][xX][aA][lL][pP][dD][lL][pP] - | [xX][nN]--[kK][gG][bB][eE][cC][hH][tT][vV] | [xX][nN]--[kK][pP][rR][wW]13[dD] | [xX][nN]--[kK][pP][rR][yY]57[dD] + | [xX][nN]--[lL]1[aA][cC][cC] | [xX][nN]--[lL][gG][bB][bB][aA][tT]1[aA][dD]8[jJ] | [xX][nN]--[mM][gG][bB]9[aA][wW][bB][fF] + | [xX][nN]--[mM][gG][bB][aA]3[aA]4[fF]16[aA] | [xX][nN]--[mM][gG][bB][aA][aA][mM]7[aA]8[hH] | [xX][nN]--[mM][gG][bB][aA][yY][hH]7[gG][pP][aA] | [xX][nN]--[mM][gG][bB][bB][hH]1[aA]71[eE] | [xX][nN]--[mM][gG][bB][cC]0[aA]9[aA][zZ][cC][gG] | [xX][nN]--[mM][gG][bB][eE][rR][pP]4[aA]5[dD]4[aA][rR] + | [xX][nN]--[mM][gG][bB][xX]4[cC][dD]0[aA][bB] + | [xX][nN]--[nN][gG][bB][cC]5[aA][zZ][dD] | [xX][nN]--[oO]3[cC][wW]4[hH] | [xX][nN]--[oO][gG][bB][pP][fF]8[fF][lL] | [xX][nN]--[pP]1[aA][iI] | [xX][nN]--[pP][gG][bB][sS]0[dD][hH] + | [xX][nN]--[qQ]9[jJ][yY][bB]4[cC] | [xX][nN]--[sS]9[bB][rR][jJ]9[cC] + | [xX][nN]--[uU][nN][uU][pP]4[yY] | [xX][nN]--[wW][gG][bB][hH]1[cC] | [xX][nN]--[wW][gG][bB][lL]6[aA] | [xX][nN]--[xX][kK][cC]2[aA][lL]3[hH][yY][eE]2[aA] | [xX][nN]--[xX][kK][cC]2[dD][lL]3[aA]5[eE][eE]0[hH] | [xX][nN]--[yY][fF][rR][oO]4[iI]67[oO] | [xX][nN]--[yY][gG][bB][iI]2[aA][mM][mM][xX] - | [xX][nN]--[zZ][cC][kK][zZ][aA][hH] | [xX][xX][xX] | [yY][eE] | [yY][tT] diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/ClassicTokenizerImpl.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/ClassicTokenizerImpl.java index 3ce589754cf..27062911945 100644 --- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/ClassicTokenizerImpl.java +++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/ClassicTokenizerImpl.java @@ -1,4 +1,4 @@ -/* The following code was generated by JFlex. */ +/* The following code was generated by JFlex 1.5.0-SNAPSHOT */ package org.apache.lucene.analysis.standard; @@ -58,64 +58,63 @@ class ClassicTokenizerImpl implements StandardTokenizerInterface { * Translates characters to character classes */ private static final String ZZ_CMAP_PACKED = - "\11\0\1\0\1\15\1\0\1\0\1\14\22\0\1\0\5\0\1\5"+ - "\1\3\4\0\1\11\1\7\1\4\1\11\12\2\6\0\1\6\32\12"+ - "\4\0\1\10\1\0\32\12\57\0\1\12\12\0\1\12\4\0\1\12"+ - "\5\0\27\12\1\0\37\12\1\0\u0128\12\2\0\22\12\34\0\136\12"+ - "\2\0\11\12\2\0\7\12\16\0\2\12\16\0\5\12\11\0\1\12"+ - "\213\0\1\12\13\0\1\12\1\0\3\12\1\0\1\12\1\0\24\12"+ - "\1\0\54\12\1\0\10\12\2\0\32\12\14\0\202\12\12\0\71\12"+ - "\2\0\2\12\2\0\2\12\3\0\46\12\2\0\2\12\67\0\46\12"+ - "\2\0\1\12\7\0\47\12\110\0\33\12\5\0\3\12\56\0\32\12"+ - "\5\0\13\12\25\0\12\2\7\0\143\12\1\0\1\12\17\0\2\12"+ - "\11\0\12\2\3\12\23\0\1\12\1\0\33\12\123\0\46\12\u015f\0"+ - "\65\12\3\0\1\12\22\0\1\12\7\0\12\12\4\0\12\2\25\0"+ - "\10\12\2\0\2\12\2\0\26\12\1\0\7\12\1\0\1\12\3\0"+ - "\4\12\42\0\2\12\1\0\3\12\4\0\12\2\2\12\23\0\6\12"+ - "\4\0\2\12\2\0\26\12\1\0\7\12\1\0\2\12\1\0\2\12"+ - "\1\0\2\12\37\0\4\12\1\0\1\12\7\0\12\2\2\0\3\12"+ - "\20\0\7\12\1\0\1\12\1\0\3\12\1\0\26\12\1\0\7\12"+ - "\1\0\2\12\1\0\5\12\3\0\1\12\22\0\1\12\17\0\1\12"+ - "\5\0\12\2\25\0\10\12\2\0\2\12\2\0\26\12\1\0\7\12"+ - "\1\0\2\12\2\0\4\12\3\0\1\12\36\0\2\12\1\0\3\12"+ - "\4\0\12\2\25\0\6\12\3\0\3\12\1\0\4\12\3\0\2\12"+ - "\1\0\1\12\1\0\2\12\3\0\2\12\3\0\3\12\3\0\10\12"+ - "\1\0\3\12\55\0\11\2\25\0\10\12\1\0\3\12\1\0\27\12"+ - "\1\0\12\12\1\0\5\12\46\0\2\12\4\0\12\2\25\0\10\12"+ - "\1\0\3\12\1\0\27\12\1\0\12\12\1\0\5\12\44\0\1\12"+ - "\1\0\2\12\4\0\12\2\25\0\10\12\1\0\3\12\1\0\27\12"+ - "\1\0\20\12\46\0\2\12\4\0\12\2\25\0\22\12\3\0\30\12"+ - "\1\0\11\12\1\0\1\12\2\0\7\12\71\0\1\1\60\12\1\1"+ - "\2\12\14\1\7\12\11\1\12\2\47\0\2\12\1\0\1\12\2\0"+ - "\2\12\1\0\1\12\2\0\1\12\6\0\4\12\1\0\7\12\1\0"+ - "\3\12\1\0\1\12\1\0\1\12\2\0\2\12\1\0\4\12\1\0"+ - "\2\12\11\0\1\12\2\0\5\12\1\0\1\12\11\0\12\2\2\0"+ - "\2\12\42\0\1\12\37\0\12\2\26\0\10\12\1\0\42\12\35\0"+ - "\4\12\164\0\42\12\1\0\5\12\1\0\2\12\25\0\12\2\6\0"+ - "\6\12\112\0\46\12\12\0\47\12\11\0\132\12\5\0\104\12\5\0"+ - "\122\12\6\0\7\12\1\0\77\12\1\0\1\12\1\0\4\12\2\0"+ - "\7\12\1\0\1\12\1\0\4\12\2\0\47\12\1\0\1\12\1\0"+ - "\4\12\2\0\37\12\1\0\1\12\1\0\4\12\2\0\7\12\1\0"+ - "\1\12\1\0\4\12\2\0\7\12\1\0\7\12\1\0\27\12\1\0"+ - "\37\12\1\0\1\12\1\0\4\12\2\0\7\12\1\0\47\12\1\0"+ - "\23\12\16\0\11\2\56\0\125\12\14\0\u026c\12\2\0\10\12\12\0"+ - "\32\12\5\0\113\12\225\0\64\12\54\0\12\2\46\0\12\2\6\0"+ - "\130\12\10\0\51\12\u0557\0\234\12\4\0\132\12\6\0\26\12\2\0"+ - "\6\12\2\0\46\12\2\0\6\12\2\0\10\12\1\0\1\12\1\0"+ - "\1\12\1\0\1\12\1\0\37\12\2\0\65\12\1\0\7\12\1\0"+ - "\1\12\3\0\3\12\1\0\7\12\3\0\4\12\2\0\6\12\4\0"+ - "\15\12\5\0\3\12\1\0\7\12\202\0\1\12\202\0\1\12\4\0"+ - "\1\12\2\0\12\12\1\0\1\12\3\0\5\12\6\0\1\12\1\0"+ - "\1\12\1\0\1\12\1\0\4\12\1\0\3\12\1\0\7\12\u0ecb\0"+ - "\2\12\52\0\5\12\12\0\1\13\124\13\10\13\2\13\2\13\132\13"+ - "\1\13\3\13\6\13\50\13\3\13\1\0\136\12\21\0\30\12\70\0"+ - "\20\13\u0100\0\200\13\200\0\u19b6\13\12\13\100\0\u51a6\13\132\13\u048d\12"+ - "\u0773\0\u2ba4\12\u215c\0\u012e\13\322\13\7\12\14\0\5\12\5\0\1\12"+ - "\1\0\12\12\1\0\15\12\1\0\5\12\1\0\1\12\1\0\2\12"+ - "\1\0\2\12\1\0\154\12\41\0\u016b\12\22\0\100\12\2\0\66\12"+ - "\50\0\14\12\164\0\3\12\1\0\1\12\1\0\207\12\23\0\12\2"+ - "\7\0\32\12\6\0\32\12\12\0\1\13\72\13\37\12\3\0\6\12"+ - "\2\0\6\12\2\0\6\12\2\0\3\12\43\0"; + "\46\0\1\5\1\3\4\0\1\11\1\7\1\4\1\11\12\2\6\0"+ + "\1\6\32\12\4\0\1\10\1\0\32\12\57\0\1\12\12\0\1\12"+ + "\4\0\1\12\5\0\27\12\1\0\37\12\1\0\u0128\12\2\0\22\12"+ + "\34\0\136\12\2\0\11\12\2\0\7\12\16\0\2\12\16\0\5\12"+ + "\11\0\1\12\213\0\1\12\13\0\1\12\1\0\3\12\1\0\1\12"+ + "\1\0\24\12\1\0\54\12\1\0\10\12\2\0\32\12\14\0\202\12"+ + "\12\0\71\12\2\0\2\12\2\0\2\12\3\0\46\12\2\0\2\12"+ + "\67\0\46\12\2\0\1\12\7\0\47\12\110\0\33\12\5\0\3\12"+ + "\56\0\32\12\5\0\13\12\25\0\12\2\7\0\143\12\1\0\1\12"+ + "\17\0\2\12\11\0\12\2\3\12\23\0\1\12\1\0\33\12\123\0"+ + "\46\12\u015f\0\65\12\3\0\1\12\22\0\1\12\7\0\12\12\4\0"+ + "\12\2\25\0\10\12\2\0\2\12\2\0\26\12\1\0\7\12\1\0"+ + "\1\12\3\0\4\12\42\0\2\12\1\0\3\12\4\0\12\2\2\12"+ + "\23\0\6\12\4\0\2\12\2\0\26\12\1\0\7\12\1\0\2\12"+ + "\1\0\2\12\1\0\2\12\37\0\4\12\1\0\1\12\7\0\12\2"+ + "\2\0\3\12\20\0\7\12\1\0\1\12\1\0\3\12\1\0\26\12"+ + "\1\0\7\12\1\0\2\12\1\0\5\12\3\0\1\12\22\0\1\12"+ + "\17\0\1\12\5\0\12\2\25\0\10\12\2\0\2\12\2\0\26\12"+ + "\1\0\7\12\1\0\2\12\2\0\4\12\3\0\1\12\36\0\2\12"+ + "\1\0\3\12\4\0\12\2\25\0\6\12\3\0\3\12\1\0\4\12"+ + "\3\0\2\12\1\0\1\12\1\0\2\12\3\0\2\12\3\0\3\12"+ + "\3\0\10\12\1\0\3\12\55\0\11\2\25\0\10\12\1\0\3\12"+ + "\1\0\27\12\1\0\12\12\1\0\5\12\46\0\2\12\4\0\12\2"+ + "\25\0\10\12\1\0\3\12\1\0\27\12\1\0\12\12\1\0\5\12"+ + "\44\0\1\12\1\0\2\12\4\0\12\2\25\0\10\12\1\0\3\12"+ + "\1\0\27\12\1\0\20\12\46\0\2\12\4\0\12\2\25\0\22\12"+ + "\3\0\30\12\1\0\11\12\1\0\1\12\2\0\7\12\71\0\1\1"+ + "\60\12\1\1\2\12\14\1\7\12\11\1\12\2\47\0\2\12\1\0"+ + "\1\12\2\0\2\12\1\0\1\12\2\0\1\12\6\0\4\12\1\0"+ + "\7\12\1\0\3\12\1\0\1\12\1\0\1\12\2\0\2\12\1\0"+ + "\4\12\1\0\2\12\11\0\1\12\2\0\5\12\1\0\1\12\11\0"+ + "\12\2\2\0\2\12\42\0\1\12\37\0\12\2\26\0\10\12\1\0"+ + "\42\12\35\0\4\12\164\0\42\12\1\0\5\12\1\0\2\12\25\0"+ + "\12\2\6\0\6\12\112\0\46\12\12\0\47\12\11\0\132\12\5\0"+ + "\104\12\5\0\122\12\6\0\7\12\1\0\77\12\1\0\1\12\1\0"+ + "\4\12\2\0\7\12\1\0\1\12\1\0\4\12\2\0\47\12\1\0"+ + "\1\12\1\0\4\12\2\0\37\12\1\0\1\12\1\0\4\12\2\0"+ + "\7\12\1\0\1\12\1\0\4\12\2\0\7\12\1\0\7\12\1\0"+ + "\27\12\1\0\37\12\1\0\1\12\1\0\4\12\2\0\7\12\1\0"+ + "\47\12\1\0\23\12\16\0\11\2\56\0\125\12\14\0\u026c\12\2\0"+ + "\10\12\12\0\32\12\5\0\113\12\225\0\64\12\54\0\12\2\46\0"+ + "\12\2\6\0\130\12\10\0\51\12\u0557\0\234\12\4\0\132\12\6\0"+ + "\26\12\2\0\6\12\2\0\46\12\2\0\6\12\2\0\10\12\1\0"+ + "\1\12\1\0\1\12\1\0\1\12\1\0\37\12\2\0\65\12\1\0"+ + "\7\12\1\0\1\12\3\0\3\12\1\0\7\12\3\0\4\12\2\0"+ + "\6\12\4\0\15\12\5\0\3\12\1\0\7\12\202\0\1\12\202\0"+ + "\1\12\4\0\1\12\2\0\12\12\1\0\1\12\3\0\5\12\6\0"+ + "\1\12\1\0\1\12\1\0\1\12\1\0\4\12\1\0\3\12\1\0"+ + "\7\12\u0ecb\0\2\12\52\0\5\12\12\0\1\13\124\13\10\13\2\13"+ + "\2\13\132\13\1\13\3\13\6\13\50\13\3\13\1\0\136\12\21\0"+ + "\30\12\70\0\20\13\u0100\0\200\13\200\0\u19b6\13\12\13\100\0\u51a6\13"+ + "\132\13\u048d\12\u0773\0\u2ba4\12\u215c\0\u012e\13\322\13\7\12\14\0\5\12"+ + "\5\0\1\12\1\0\12\12\1\0\15\12\1\0\5\12\1\0\1\12"+ + "\1\0\2\12\1\0\2\12\1\0\154\12\41\0\u016b\12\22\0\100\12"+ + "\2\0\66\12\50\0\14\12\164\0\3\12\1\0\1\12\1\0\207\12"+ + "\23\0\12\2\7\0\32\12\6\0\32\12\12\0\1\13\72\13\37\12"+ + "\3\0\6\12\2\0\6\12\2\0\6\12\2\0\3\12\43\0"; /** * Translates characters to character classes @@ -128,13 +127,12 @@ class ClassicTokenizerImpl implements StandardTokenizerInterface { private static final int [] ZZ_ACTION = zzUnpackAction(); private static final String ZZ_ACTION_PACKED_0 = - "\1\0\1\1\3\2\1\3\1\1\13\0\1\2\3\4"+ - "\2\0\1\5\1\0\1\5\3\4\6\5\1\6\1\4"+ - "\2\7\1\10\1\0\1\10\3\0\2\10\1\11\1\12"+ - "\1\4"; + "\1\0\1\1\3\2\1\3\13\0\1\2\3\4\2\0"+ + "\1\5\1\0\1\5\3\4\6\5\1\6\1\4\2\7"+ + "\1\10\1\0\1\10\3\0\2\10\1\11\1\12\1\4"; private static int [] zzUnpackAction() { - int [] result = new int[51]; + int [] result = new int[50]; int offset = 0; offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); return result; @@ -159,16 +157,16 @@ class ClassicTokenizerImpl implements StandardTokenizerInterface { private static final int [] ZZ_ROWMAP = zzUnpackRowMap(); private static final String ZZ_ROWMAP_PACKED_0 = - "\0\0\0\16\0\34\0\52\0\70\0\16\0\106\0\124"+ - "\0\142\0\160\0\176\0\214\0\232\0\250\0\266\0\304"+ - "\0\322\0\340\0\356\0\374\0\u010a\0\u0118\0\u0126\0\u0134"+ - "\0\u0142\0\u0150\0\u015e\0\u016c\0\u017a\0\u0188\0\u0196\0\u01a4"+ - "\0\u01b2\0\u01c0\0\u01ce\0\u01dc\0\u01ea\0\u01f8\0\322\0\u0206"+ - "\0\u0214\0\u0222\0\u0230\0\u023e\0\u024c\0\u025a\0\124\0\214"+ - "\0\u0268\0\u0276\0\u0284"; + "\0\0\0\14\0\30\0\44\0\60\0\14\0\74\0\110"+ + "\0\124\0\140\0\154\0\170\0\204\0\220\0\234\0\250"+ + "\0\264\0\300\0\314\0\330\0\344\0\360\0\374\0\u0108"+ + "\0\u0114\0\u0120\0\u012c\0\u0138\0\u0144\0\u0150\0\u015c\0\u0168"+ + "\0\u0174\0\u0180\0\u018c\0\u0198\0\u01a4\0\250\0\u01b0\0\u01bc"+ + "\0\u01c8\0\u01d4\0\u01e0\0\u01ec\0\u01f8\0\74\0\154\0\u0204"+ + "\0\u0210\0\u021c"; private static int [] zzUnpackRowMap() { - int [] result = new int[51]; + int [] result = new int[50]; int offset = 0; offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); return result; @@ -191,49 +189,49 @@ class ClassicTokenizerImpl implements StandardTokenizerInterface { private static final int [] ZZ_TRANS = zzUnpackTrans(); private static final String ZZ_TRANS_PACKED_0 = - "\1\2\1\3\1\4\7\2\1\5\1\6\1\7\1\2"+ - "\17\0\2\3\1\0\1\10\1\0\1\11\2\12\1\13"+ - "\1\3\4\0\1\3\1\4\1\0\1\14\1\0\1\11"+ - "\2\15\1\16\1\4\4\0\1\3\1\4\1\17\1\20"+ - "\1\21\1\22\2\12\1\13\1\23\20\0\1\2\1\0"+ - "\1\24\1\25\7\0\1\26\4\0\2\27\7\0\1\27"+ - "\4\0\1\30\1\31\7\0\1\32\5\0\1\33\7\0"+ - "\1\13\4\0\1\34\1\35\7\0\1\36\4\0\1\37"+ - "\1\40\7\0\1\41\4\0\1\42\1\43\7\0\1\44"+ - "\15\0\1\45\4\0\1\24\1\25\7\0\1\46\15\0"+ - "\1\47\4\0\2\27\7\0\1\50\4\0\1\3\1\4"+ - "\1\17\1\10\1\21\1\22\2\12\1\13\1\23\4\0"+ - "\2\24\1\0\1\51\1\0\1\11\2\52\1\0\1\24"+ - "\4\0\1\24\1\25\1\0\1\53\1\0\1\11\2\54"+ - "\1\55\1\25\4\0\1\24\1\25\1\0\1\51\1\0"+ - "\1\11\2\52\1\0\1\26\4\0\2\27\1\0\1\56"+ - "\2\0\1\56\2\0\1\27\4\0\2\30\1\0\1\52"+ - "\1\0\1\11\2\52\1\0\1\30\4\0\1\30\1\31"+ - "\1\0\1\54\1\0\1\11\2\54\1\55\1\31\4\0"+ - "\1\30\1\31\1\0\1\52\1\0\1\11\2\52\1\0"+ - "\1\32\5\0\1\33\1\0\1\55\2\0\3\55\1\33"+ - "\4\0\2\34\1\0\1\57\1\0\1\11\2\12\1\13"+ - "\1\34\4\0\1\34\1\35\1\0\1\60\1\0\1\11"+ - "\2\15\1\16\1\35\4\0\1\34\1\35\1\0\1\57"+ - "\1\0\1\11\2\12\1\13\1\36\4\0\2\37\1\0"+ - "\1\12\1\0\1\11\2\12\1\13\1\37\4\0\1\37"+ - "\1\40\1\0\1\15\1\0\1\11\2\15\1\16\1\40"+ - "\4\0\1\37\1\40\1\0\1\12\1\0\1\11\2\12"+ - "\1\13\1\41\4\0\2\42\1\0\1\13\2\0\3\13"+ - "\1\42\4\0\1\42\1\43\1\0\1\16\2\0\3\16"+ - "\1\43\4\0\1\42\1\43\1\0\1\13\2\0\3\13"+ - "\1\44\6\0\1\17\6\0\1\45\4\0\1\24\1\25"+ - "\1\0\1\61\1\0\1\11\2\52\1\0\1\26\4\0"+ - "\2\27\1\0\1\56\2\0\1\56\2\0\1\50\4\0"+ - "\2\24\7\0\1\24\4\0\2\30\7\0\1\30\4\0"+ - "\2\34\7\0\1\34\4\0\2\37\7\0\1\37\4\0"+ - "\2\42\7\0\1\42\4\0\2\62\7\0\1\62\4\0"+ - "\2\24\7\0\1\63\4\0\2\62\1\0\1\56\2\0"+ - "\1\56\2\0\1\62\4\0\2\24\1\0\1\61\1\0"+ - "\1\11\2\52\1\0\1\24\3\0"; + "\1\2\1\3\1\4\7\2\1\5\1\6\15\0\2\3"+ + "\1\0\1\7\1\0\1\10\2\11\1\12\1\3\2\0"+ + "\1\3\1\4\1\0\1\13\1\0\1\10\2\14\1\15"+ + "\1\4\2\0\1\3\1\4\1\16\1\17\1\20\1\21"+ + "\2\11\1\12\1\22\2\0\1\23\1\24\7\0\1\25"+ + "\2\0\2\26\7\0\1\26\2\0\1\27\1\30\7\0"+ + "\1\31\3\0\1\32\7\0\1\12\2\0\1\33\1\34"+ + "\7\0\1\35\2\0\1\36\1\37\7\0\1\40\2\0"+ + "\1\41\1\42\7\0\1\43\13\0\1\44\2\0\1\23"+ + "\1\24\7\0\1\45\13\0\1\46\2\0\2\26\7\0"+ + "\1\47\2\0\1\3\1\4\1\16\1\7\1\20\1\21"+ + "\2\11\1\12\1\22\2\0\2\23\1\0\1\50\1\0"+ + "\1\10\2\51\1\0\1\23\2\0\1\23\1\24\1\0"+ + "\1\52\1\0\1\10\2\53\1\54\1\24\2\0\1\23"+ + "\1\24\1\0\1\50\1\0\1\10\2\51\1\0\1\25"+ + "\2\0\2\26\1\0\1\55\2\0\1\55\2\0\1\26"+ + "\2\0\2\27\1\0\1\51\1\0\1\10\2\51\1\0"+ + "\1\27\2\0\1\27\1\30\1\0\1\53\1\0\1\10"+ + "\2\53\1\54\1\30\2\0\1\27\1\30\1\0\1\51"+ + "\1\0\1\10\2\51\1\0\1\31\3\0\1\32\1\0"+ + "\1\54\2\0\3\54\1\32\2\0\2\33\1\0\1\56"+ + "\1\0\1\10\2\11\1\12\1\33\2\0\1\33\1\34"+ + "\1\0\1\57\1\0\1\10\2\14\1\15\1\34\2\0"+ + "\1\33\1\34\1\0\1\56\1\0\1\10\2\11\1\12"+ + "\1\35\2\0\2\36\1\0\1\11\1\0\1\10\2\11"+ + "\1\12\1\36\2\0\1\36\1\37\1\0\1\14\1\0"+ + "\1\10\2\14\1\15\1\37\2\0\1\36\1\37\1\0"+ + "\1\11\1\0\1\10\2\11\1\12\1\40\2\0\2\41"+ + "\1\0\1\12\2\0\3\12\1\41\2\0\1\41\1\42"+ + "\1\0\1\15\2\0\3\15\1\42\2\0\1\41\1\42"+ + "\1\0\1\12\2\0\3\12\1\43\4\0\1\16\6\0"+ + "\1\44\2\0\1\23\1\24\1\0\1\60\1\0\1\10"+ + "\2\51\1\0\1\25\2\0\2\26\1\0\1\55\2\0"+ + "\1\55\2\0\1\47\2\0\2\23\7\0\1\23\2\0"+ + "\2\27\7\0\1\27\2\0\2\33\7\0\1\33\2\0"+ + "\2\36\7\0\1\36\2\0\2\41\7\0\1\41\2\0"+ + "\2\61\7\0\1\61\2\0\2\23\7\0\1\62\2\0"+ + "\2\61\1\0\1\55\2\0\1\55\2\0\1\61\2\0"+ + "\2\23\1\0\1\60\1\0\1\10\2\51\1\0\1\23"+ + "\1\0"; private static int [] zzUnpackTrans() { - int [] result = new int[658]; + int [] result = new int[552]; int offset = 0; offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); return result; @@ -271,11 +269,11 @@ class ClassicTokenizerImpl implements StandardTokenizerInterface { private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); private static final String ZZ_ATTRIBUTE_PACKED_0 = - "\1\0\1\11\3\1\1\11\1\1\13\0\4\1\2\0"+ - "\1\1\1\0\17\1\1\0\1\1\3\0\5\1"; + "\1\0\1\11\3\1\1\11\13\0\4\1\2\0\1\1"+ + "\1\0\17\1\1\0\1\1\3\0\5\1"; private static int [] zzUnpackAttribute() { - int [] result = new int[51]; + int [] result = new int[50]; int offset = 0; offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); return result; @@ -372,7 +370,6 @@ public final void getText(CharTermAttribute t) { /** * Creates a new scanner - * There is also a java.io.InputStream version of this constructor. * * @param in the java.io.Reader to read input from. */ @@ -380,7 +377,6 @@ public final void getText(CharTermAttribute t) { this.zzReader = in; } - /** * Unpacks the compressed character translation table. @@ -392,7 +388,7 @@ public final void getText(CharTermAttribute t) { char [] map = new char[0x10000]; int i = 0; /* index in packed string */ int j = 0; /* index in unpacked array */ - while (i < 1154) { + while (i < 1138) { int count = packed.charAt(i++); char value = packed.charAt(i++); do map[j++] = value; while (--count > 0); diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/ClassicTokenizerImpl.jflex b/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/ClassicTokenizerImpl.jflex index 4d408b91073..3e4d48e6045 100644 --- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/ClassicTokenizerImpl.jflex +++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/ClassicTokenizerImpl.jflex @@ -116,8 +116,6 @@ LETTER = !(![:letter:]|{CJ}) // Chinese and Japanese (but NOT Korean, which is included in [:letter:]) CJ = [\u3100-\u312f\u3040-\u309F\u30A0-\u30FF\u31F0-\u31FF\u3300-\u337f\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff\uff65-\uff9f] -WHITESPACE = \r\n | [ \r\n\t\f] - %% {ALPHANUM} { return ALPHANUM; } @@ -131,4 +129,4 @@ WHITESPACE = \r\n | [ \r\n\t\f] {ACRONYM_DEP} { return ACRONYM_DEP; } /** Ignore the rest */ -. | {WHITESPACE} { /* Break so we don't hit fall-through warning: */ break;/* ignore */ } +[^] { /* Break so we don't hit fall-through warning: */ break;/* ignore */ } diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/READ_BEFORE_REGENERATING.txt b/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/READ_BEFORE_REGENERATING.txt index a39d97c3dcd..2aaa082d6e6 100644 --- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/READ_BEFORE_REGENERATING.txt +++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/READ_BEFORE_REGENERATING.txt @@ -18,4 +18,4 @@ WARNING: if you change StandardTokenizerImpl*.jflex or UAX29URLEmailTokenizer and need to regenerate the tokenizer, only use the trunk version - of JFlex 1.5 (with a minimum SVN revision 607) at the moment! + of JFlex 1.5 (with a minimum SVN revision 722) at the moment! diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/SUPPLEMENTARY.jflex-macro b/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/SUPPLEMENTARY.jflex-macro index 4ad87b7cb00..f5bf68e254b 100644 --- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/SUPPLEMENTARY.jflex-macro +++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/SUPPLEMENTARY.jflex-macro @@ -1,11 +1,12 @@ /* - * Copyright 2010 The Apache Software Foundation. + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -13,7 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - // Generated using ICU4J 52.1.0.0 // by org.apache.lucene.analysis.icu.GenerateJFlexSupplementaryMacros @@ -39,6 +39,12 @@ FormatSupp = ( | ([\ud834][\uDD73-\uDD7A]) | ([\udb40][\uDC01\uDC20-\uDC7F]) ) +NumericSupp = ( + ([\ud805][\uDEC0-\uDEC9]) + | ([\ud804][\uDC66-\uDC6F\uDCF0-\uDCF9\uDD36-\uDD3F\uDDD0-\uDDD9]) + | ([\ud835][\uDFCE-\uDFFF]) + | ([\ud801][\uDCA0-\uDCA9]) +) ExtendSupp = ( ([\ud81b][\uDF51-\uDF7E\uDF8F-\uDF92]) | ([\ud805][\uDEAB-\uDEB7]) @@ -48,12 +54,6 @@ ExtendSupp = ( | ([\udb40][\uDD00-\uDDEF]) | ([\ud802][\uDE01-\uDE03\uDE05\uDE06\uDE0C-\uDE0F\uDE38-\uDE3A\uDE3F]) ) -NumericSupp = ( - ([\ud805][\uDEC0-\uDEC9]) - | ([\ud804][\uDC66-\uDC6F\uDCF0-\uDCF9\uDD36-\uDD3F\uDDD0-\uDDD9]) - | ([\ud835][\uDFCE-\uDFFF]) - | ([\ud801][\uDCA0-\uDCA9]) -) KatakanaSupp = ( ([\ud82c][\uDC00]) ) @@ -129,3 +129,15 @@ HiraganaSupp = ( ([\ud83c][\uDE00]) | ([\ud82c][\uDC01]) ) +SingleQuoteSupp = ( + [] +) +DoubleQuoteSupp = ( + [] +) +HebrewLetterSupp = ( + [] +) +RegionalIndicatorSupp = ( + ([\ud83c][\uDDE6-\uDDFF]) +) diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/StandardTokenizerImpl.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/StandardTokenizerImpl.java index f5ff0319c46..974ed9de84a 100644 --- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/StandardTokenizerImpl.java +++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/StandardTokenizerImpl.java @@ -1,4 +1,4 @@ -/* The following code was generated by JFlex. */ +/* The following code was generated by JFlex 1.5.0-SNAPSHOT */ package org.apache.lucene.analysis.standard; @@ -34,6 +34,8 @@ import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; * Asian languages, including Thai, Lao, Myanmar, and Khmer *
  • <IDEOGRAPHIC>: A single CJKV ideographic character
  • *
  • <HIRAGANA>: A single hiragana character
  • + *
  • <KATAKANA>: A sequence of katakana characters
  • + *
  • <HANGUL>: A sequence of Hangul characters
  • * */ @@ -62,149 +64,149 @@ public final class StandardTokenizerImpl implements StandardTokenizerInterface { * Translates characters to character classes */ private static final String ZZ_CMAP_PACKED = - "\47\0\1\202\4\0\1\201\1\0\1\202\1\0\12\176\1\200\1\201"+ - "\5\0\32\174\4\0\1\203\1\0\32\174\57\0\1\174\2\0\1\175"+ - "\7\0\1\174\1\0\1\200\2\0\1\174\5\0\27\174\1\0\37\174"+ - "\1\0\u01ca\174\4\0\14\174\16\0\5\174\7\0\1\174\1\0\1\174"+ - "\21\0\160\175\5\174\1\0\2\174\2\0\4\174\1\201\7\0\1\174"+ - "\1\200\3\174\1\0\1\174\1\0\24\174\1\0\123\174\1\0\213\174"+ - "\1\0\7\175\236\174\11\0\46\174\2\0\1\174\7\0\47\174\1\0"+ - "\1\201\7\0\55\175\1\0\1\175\1\0\2\175\1\0\2\175\1\0"+ - "\1\175\10\0\33\174\5\0\4\174\1\200\13\0\5\175\7\0\2\201"+ - "\2\0\13\175\5\0\53\174\25\175\12\176\1\0\1\176\1\201\1\0"+ - "\2\174\1\175\143\174\1\0\1\174\7\175\1\175\1\0\6\175\2\174"+ - "\2\175\1\0\4\175\2\174\12\176\3\174\2\0\1\174\17\0\1\175"+ - "\1\174\1\175\36\174\33\175\2\0\131\174\13\175\1\174\16\0\12\176"+ - "\41\174\11\175\2\174\2\0\1\201\1\0\1\174\5\0\26\174\4\175"+ - "\1\174\11\175\1\174\3\175\1\174\5\175\22\0\31\174\3\175\104\0"+ - "\1\174\1\0\13\174\67\0\33\175\1\0\4\175\66\174\3\175\1\174"+ - "\22\175\1\174\7\175\12\174\2\175\2\0\12\176\1\0\7\174\1\0"+ - "\7\174\1\0\3\175\1\0\10\174\2\0\2\174\2\0\26\174\1\0"+ - "\7\174\1\0\1\174\3\0\4\174\2\0\1\175\1\174\7\175\2\0"+ - "\2\175\2\0\3\175\1\174\10\0\1\175\4\0\2\174\1\0\3\174"+ - "\2\175\2\0\12\176\2\174\17\0\3\175\1\0\6\174\4\0\2\174"+ - "\2\0\26\174\1\0\7\174\1\0\2\174\1\0\2\174\1\0\2\174"+ - "\2\0\1\175\1\0\5\175\4\0\2\175\2\0\3\175\3\0\1\175"+ - "\7\0\4\174\1\0\1\174\7\0\12\176\2\175\3\174\1\175\13\0"+ - "\3\175\1\0\11\174\1\0\3\174\1\0\26\174\1\0\7\174\1\0"+ - "\2\174\1\0\5\174\2\0\1\175\1\174\10\175\1\0\3\175\1\0"+ - "\3\175\2\0\1\174\17\0\2\174\2\175\2\0\12\176\21\0\3\175"+ - "\1\0\10\174\2\0\2\174\2\0\26\174\1\0\7\174\1\0\2\174"+ - "\1\0\5\174\2\0\1\175\1\174\7\175\2\0\2\175\2\0\3\175"+ - "\10\0\2\175\4\0\2\174\1\0\3\174\2\175\2\0\12\176\1\0"+ - "\1\174\20\0\1\175\1\174\1\0\6\174\3\0\3\174\1\0\4\174"+ - "\3\0\2\174\1\0\1\174\1\0\2\174\3\0\2\174\3\0\3\174"+ - "\3\0\14\174\4\0\5\175\3\0\3\175\1\0\4\175\2\0\1\174"+ - "\6\0\1\175\16\0\12\176\21\0\3\175\1\0\10\174\1\0\3\174"+ - "\1\0\27\174\1\0\12\174\1\0\5\174\3\0\1\174\7\175\1\0"+ - "\3\175\1\0\4\175\7\0\2\175\1\0\2\174\6\0\2\174\2\175"+ - "\2\0\12\176\22\0\2\175\1\0\10\174\1\0\3\174\1\0\27\174"+ - "\1\0\12\174\1\0\5\174\2\0\1\175\1\174\7\175\1\0\3\175"+ - "\1\0\4\175\7\0\2\175\7\0\1\174\1\0\2\174\2\175\2\0"+ - "\12\176\1\0\2\174\17\0\2\175\1\0\10\174\1\0\3\174\1\0"+ - "\51\174\2\0\1\174\7\175\1\0\3\175\1\0\4\175\1\174\10\0"+ - "\1\175\10\0\2\174\2\175\2\0\12\176\12\0\6\174\2\0\2\175"+ - "\1\0\22\174\3\0\30\174\1\0\11\174\1\0\1\174\2\0\7\174"+ - "\3\0\1\175\4\0\6\175\1\0\1\175\1\0\10\175\22\0\2\175"+ - "\15\0\60\204\1\205\2\204\7\205\5\0\7\204\10\205\1\0\12\176"+ - "\47\0\2\204\1\0\1\204\2\0\2\204\1\0\1\204\2\0\1\204"+ - "\6\0\4\204\1\0\7\204\1\0\3\204\1\0\1\204\1\0\1\204"+ - "\2\0\2\204\1\0\4\204\1\205\2\204\6\205\1\0\2\205\1\204"+ - "\2\0\5\204\1\0\1\204\1\0\6\205\2\0\12\176\2\0\4\204"+ - "\40\0\1\174\27\0\2\175\6\0\12\176\13\0\1\175\1\0\1\175"+ - "\1\0\1\175\4\0\2\175\10\174\1\0\44\174\4\0\24\175\1\0"+ - "\2\175\5\174\13\175\1\0\44\175\11\0\1\175\71\0\53\204\24\205"+ - "\1\204\12\176\6\0\6\204\4\205\4\204\3\205\1\204\3\205\2\204"+ - "\7\205\3\204\4\205\15\204\14\205\1\204\1\205\12\176\4\205\2\204"+ - "\46\174\1\0\1\174\5\0\1\174\2\0\53\174\1\0\4\174\u0100\210"+ - "\111\174\1\0\4\174\2\0\7\174\1\0\1\174\1\0\4\174\2\0"+ - "\51\174\1\0\4\174\2\0\41\174\1\0\4\174\2\0\7\174\1\0"+ - "\1\174\1\0\4\174\2\0\17\174\1\0\71\174\1\0\4\174\2\0"+ - "\103\174\2\0\3\175\40\0\20\174\20\0\125\174\14\0\u026c\174\2\0"+ - "\21\174\1\0\32\174\5\0\113\174\3\0\3\174\17\0\15\174\1\0"+ - "\4\174\3\175\13\0\22\174\3\175\13\0\22\174\2\175\14\0\15\174"+ - "\1\0\3\174\1\0\2\175\14\0\64\204\40\205\3\0\1\204\4\0"+ - "\1\204\1\205\2\0\12\176\41\0\3\175\2\0\12\176\6\0\130\174"+ - "\10\0\51\174\1\175\1\174\5\0\106\174\12\0\35\174\3\0\14\175"+ - "\4\0\14\175\12\0\12\176\36\204\2\0\5\204\13\0\54\204\4\0"+ - "\21\205\7\204\2\205\6\0\12\176\1\204\3\0\2\204\40\0\27\174"+ - "\5\175\4\0\65\204\12\205\1\0\35\205\2\0\1\175\12\176\6\0"+ - "\12\176\6\0\16\204\122\0\5\175\57\174\21\175\7\174\4\0\12\176"+ - "\21\0\11\175\14\0\3\175\36\174\15\175\2\174\12\176\54\174\16\175"+ - "\14\0\44\174\24\175\10\0\12\176\3\0\3\174\12\176\44\174\122\0"+ - "\3\175\1\0\25\175\4\174\1\175\4\174\3\175\2\174\11\0\300\174"+ - "\47\175\25\0\4\175\u0116\174\2\0\6\174\2\0\46\174\2\0\6\174"+ - "\2\0\10\174\1\0\1\174\1\0\1\174\1\0\1\174\1\0\37\174"+ - "\2\0\65\174\1\0\7\174\1\0\1\174\3\0\3\174\1\0\7\174"+ - "\3\0\4\174\2\0\6\174\4\0\15\174\5\0\3\174\1\0\7\174"+ - "\17\0\2\175\2\175\10\0\2\202\12\0\1\202\2\0\1\200\2\0"+ - "\5\175\20\0\2\203\3\0\1\201\17\0\1\203\13\0\5\175\5\0"+ - "\6\175\1\0\1\174\15\0\1\174\20\0\15\174\63\0\41\175\21\0"+ - "\1\174\4\0\1\174\2\0\12\174\1\0\1\174\3\0\5\174\6\0"+ - "\1\174\1\0\1\174\1\0\1\174\1\0\4\174\1\0\13\174\2\0"+ - "\4\174\5\0\5\174\4\0\1\174\21\0\51\174\u032d\0\64\174\u0716\0"+ - "\57\174\1\0\57\174\1\0\205\174\6\0\4\174\3\175\2\174\14\0"+ - "\46\174\1\0\1\174\5\0\1\174\2\0\70\174\7\0\1\174\17\0"+ - "\1\175\27\174\11\0\7\174\1\0\7\174\1\0\7\174\1\0\7\174"+ - "\1\0\7\174\1\0\7\174\1\0\7\174\1\0\7\174\1\0\40\175"+ - "\57\0\1\174\120\0\32\206\1\0\131\206\14\0\326\206\57\0\1\174"+ - "\1\0\1\206\31\0\11\206\4\175\2\175\1\0\5\177\2\0\3\206"+ - "\1\174\1\174\4\0\126\207\2\0\2\175\2\177\3\207\133\177\1\0"+ - "\4\177\5\0\51\174\3\0\136\210\21\0\33\174\65\0\20\177\37\0"+ - "\101\0\37\0\121\0\57\177\1\0\130\177\250\0\u19b6\206\112\0\u51cd\206"+ - "\63\0\u048d\174\103\0\56\174\2\0\u010d\174\3\0\20\174\12\176\2\174"+ - "\24\0\57\174\4\175\1\0\12\175\1\0\31\174\7\0\1\175\120\174"+ - "\2\175\45\0\11\174\2\0\147\174\2\0\4\174\1\0\4\174\14\0"+ - "\13\174\115\0\12\174\1\175\3\174\1\175\4\174\1\175\27\174\5\175"+ - "\30\0\64\174\14\0\2\175\62\174\21\175\13\0\12\176\6\0\22\175"+ - "\6\174\3\0\1\174\4\0\12\176\34\174\10\175\2\0\27\174\15\175"+ - "\14\0\35\210\3\0\4\175\57\174\16\175\16\0\1\174\12\176\46\0"+ - "\51\174\16\175\11\0\3\174\1\175\10\174\2\175\2\0\12\176\6\0"+ - "\33\204\1\205\4\0\60\204\1\205\1\204\3\205\2\204\2\205\5\204"+ - "\2\205\1\204\1\205\1\204\30\0\5\204\13\174\5\175\2\0\3\174"+ - "\2\175\12\0\6\174\2\0\6\174\2\0\6\174\11\0\7\174\1\0"+ - "\7\174\221\0\43\174\10\175\1\0\2\175\2\0\12\176\6\0\u2ba4\210"+ - "\14\0\27\210\4\0\61\210\4\0\1\44\1\40\1\67\1\64\1\33"+ - "\1\30\2\0\1\24\1\21\2\0\1\17\1\15\14\0\1\3\1\6"+ - "\20\0\1\156\7\0\1\111\1\10\5\0\1\1\1\172\3\0\1\163"+ + "\42\0\1\213\4\0\1\212\4\0\1\203\1\0\1\204\1\0\12\200"+ + "\1\202\1\203\5\0\32\176\4\0\1\205\1\0\32\176\57\0\1\176"+ + "\2\0\1\177\7\0\1\176\1\0\1\202\2\0\1\176\5\0\27\176"+ + "\1\0\37\176\1\0\u01ca\176\4\0\14\176\5\0\1\202\10\0\5\176"+ + "\7\0\1\176\1\0\1\176\21\0\160\177\5\176\1\0\2\176\2\0"+ + "\4\176\1\203\7\0\1\176\1\202\3\176\1\0\1\176\1\0\24\176"+ + "\1\0\123\176\1\0\213\176\1\0\7\177\236\176\11\0\46\176\2\0"+ + "\1\176\7\0\47\176\1\0\1\203\7\0\55\177\1\0\1\177\1\0"+ + "\2\177\1\0\2\177\1\0\1\177\10\0\33\214\5\0\3\214\1\176"+ + "\1\202\13\0\5\177\7\0\2\203\2\0\13\177\1\0\1\177\3\0"+ + "\53\176\25\177\12\200\1\0\1\200\1\203\1\0\2\176\1\177\143\176"+ + "\1\0\1\176\7\177\1\177\1\0\6\177\2\176\2\177\1\0\4\177"+ + "\2\176\12\200\3\176\2\0\1\176\17\0\1\177\1\176\1\177\36\176"+ + "\33\177\2\0\131\176\13\177\1\176\16\0\12\200\41\176\11\177\2\176"+ + "\2\0\1\203\1\0\1\176\5\0\26\176\4\177\1\176\11\177\1\176"+ + "\3\177\1\176\5\177\22\0\31\176\3\177\104\0\1\176\1\0\13\176"+ + "\67\0\33\177\1\0\4\177\66\176\3\177\1\176\22\177\1\176\7\177"+ + "\12\176\2\177\2\0\12\200\1\0\7\176\1\0\7\176\1\0\3\177"+ + "\1\0\10\176\2\0\2\176\2\0\26\176\1\0\7\176\1\0\1\176"+ + "\3\0\4\176\2\0\1\177\1\176\7\177\2\0\2\177\2\0\3\177"+ + "\1\176\10\0\1\177\4\0\2\176\1\0\3\176\2\177\2\0\12\200"+ + "\2\176\17\0\3\177\1\0\6\176\4\0\2\176\2\0\26\176\1\0"+ + "\7\176\1\0\2\176\1\0\2\176\1\0\2\176\2\0\1\177\1\0"+ + "\5\177\4\0\2\177\2\0\3\177\3\0\1\177\7\0\4\176\1\0"+ + "\1\176\7\0\12\200\2\177\3\176\1\177\13\0\3\177\1\0\11\176"+ + "\1\0\3\176\1\0\26\176\1\0\7\176\1\0\2\176\1\0\5\176"+ + "\2\0\1\177\1\176\10\177\1\0\3\177\1\0\3\177\2\0\1\176"+ + "\17\0\2\176\2\177\2\0\12\200\21\0\3\177\1\0\10\176\2\0"+ + "\2\176\2\0\26\176\1\0\7\176\1\0\2\176\1\0\5\176\2\0"+ + "\1\177\1\176\7\177\2\0\2\177\2\0\3\177\10\0\2\177\4\0"+ + "\2\176\1\0\3\176\2\177\2\0\12\200\1\0\1\176\20\0\1\177"+ + "\1\176\1\0\6\176\3\0\3\176\1\0\4\176\3\0\2\176\1\0"+ + "\1\176\1\0\2\176\3\0\2\176\3\0\3\176\3\0\14\176\4\0"+ + "\5\177\3\0\3\177\1\0\4\177\2\0\1\176\6\0\1\177\16\0"+ + "\12\200\21\0\3\177\1\0\10\176\1\0\3\176\1\0\27\176\1\0"+ + "\12\176\1\0\5\176\3\0\1\176\7\177\1\0\3\177\1\0\4\177"+ + "\7\0\2\177\1\0\2\176\6\0\2\176\2\177\2\0\12\200\22\0"+ + "\2\177\1\0\10\176\1\0\3\176\1\0\27\176\1\0\12\176\1\0"+ + "\5\176\2\0\1\177\1\176\7\177\1\0\3\177\1\0\4\177\7\0"+ + "\2\177\7\0\1\176\1\0\2\176\2\177\2\0\12\200\1\0\2\176"+ + "\17\0\2\177\1\0\10\176\1\0\3\176\1\0\51\176\2\0\1\176"+ + "\7\177\1\0\3\177\1\0\4\177\1\176\10\0\1\177\10\0\2\176"+ + "\2\177\2\0\12\200\12\0\6\176\2\0\2\177\1\0\22\176\3\0"+ + "\30\176\1\0\11\176\1\0\1\176\2\0\7\176\3\0\1\177\4\0"+ + "\6\177\1\0\1\177\1\0\10\177\22\0\2\177\15\0\60\206\1\207"+ + "\2\206\7\207\5\0\7\206\10\207\1\0\12\200\47\0\2\206\1\0"+ + "\1\206\2\0\2\206\1\0\1\206\2\0\1\206\6\0\4\206\1\0"+ + "\7\206\1\0\3\206\1\0\1\206\1\0\1\206\2\0\2\206\1\0"+ + "\4\206\1\207\2\206\6\207\1\0\2\207\1\206\2\0\5\206\1\0"+ + "\1\206\1\0\6\207\2\0\12\200\2\0\4\206\40\0\1\176\27\0"+ + "\2\177\6\0\12\200\13\0\1\177\1\0\1\177\1\0\1\177\4\0"+ + "\2\177\10\176\1\0\44\176\4\0\24\177\1\0\2\177\5\176\13\177"+ + "\1\0\44\177\11\0\1\177\71\0\53\206\24\207\1\206\12\200\6\0"+ + "\6\206\4\207\4\206\3\207\1\206\3\207\2\206\7\207\3\206\4\207"+ + "\15\206\14\207\1\206\1\207\12\200\4\207\2\206\46\176\1\0\1\176"+ + "\5\0\1\176\2\0\53\176\1\0\4\176\u0100\215\111\176\1\0\4\176"+ + "\2\0\7\176\1\0\1\176\1\0\4\176\2\0\51\176\1\0\4\176"+ + "\2\0\41\176\1\0\4\176\2\0\7\176\1\0\1\176\1\0\4\176"+ + "\2\0\17\176\1\0\71\176\1\0\4\176\2\0\103\176\2\0\3\177"+ + "\40\0\20\176\20\0\125\176\14\0\u026c\176\2\0\21\176\1\0\32\176"+ + "\5\0\113\176\3\0\3\176\17\0\15\176\1\0\4\176\3\177\13\0"+ + "\22\176\3\177\13\0\22\176\2\177\14\0\15\176\1\0\3\176\1\0"+ + "\2\177\14\0\64\206\40\207\3\0\1\206\4\0\1\206\1\207\2\0"+ + "\12\200\41\0\3\177\1\177\1\0\12\200\6\0\130\176\10\0\51\176"+ + "\1\177\1\176\5\0\106\176\12\0\35\176\3\0\14\177\4\0\14\177"+ + "\12\0\12\200\36\206\2\0\5\206\13\0\54\206\4\0\21\207\7\206"+ + "\2\207\6\0\12\200\1\206\3\0\2\206\40\0\27\176\5\177\4\0"+ + "\65\206\12\207\1\0\35\207\2\0\1\177\12\200\6\0\12\200\6\0"+ + "\16\206\122\0\5\177\57\176\21\177\7\176\4\0\12\200\21\0\11\177"+ + "\14\0\3\177\36\176\15\177\2\176\12\200\54\176\16\177\14\0\44\176"+ + "\24\177\10\0\12\200\3\0\3\176\12\200\44\176\122\0\3\177\1\0"+ + "\25\177\4\176\1\177\4\176\3\177\2\176\11\0\300\176\47\177\25\0"+ + "\4\177\u0116\176\2\0\6\176\2\0\46\176\2\0\6\176\2\0\10\176"+ + "\1\0\1\176\1\0\1\176\1\0\1\176\1\0\37\176\2\0\65\176"+ + "\1\0\7\176\1\0\1\176\3\0\3\176\1\0\7\176\3\0\4\176"+ + "\2\0\6\176\4\0\15\176\5\0\3\176\1\0\7\176\17\0\2\177"+ + "\2\177\10\0\2\204\12\0\1\204\2\0\1\202\2\0\5\177\20\0"+ + "\2\205\3\0\1\203\17\0\1\205\13\0\5\177\1\0\12\177\1\0"+ + "\1\176\15\0\1\176\20\0\15\176\63\0\41\177\21\0\1\176\4\0"+ + "\1\176\2\0\12\176\1\0\1\176\3\0\5\176\6\0\1\176\1\0"+ + "\1\176\1\0\1\176\1\0\4\176\1\0\13\176\2\0\4\176\5\0"+ + "\5\176\4\0\1\176\21\0\51\176\u032d\0\64\176\u0716\0\57\176\1\0"+ + "\57\176\1\0\205\176\6\0\4\176\3\177\2\176\14\0\46\176\1\0"+ + "\1\176\5\0\1\176\2\0\70\176\7\0\1\176\17\0\1\177\27\176"+ + "\11\0\7\176\1\0\7\176\1\0\7\176\1\0\7\176\1\0\7\176"+ + "\1\0\7\176\1\0\7\176\1\0\7\176\1\0\40\177\57\0\1\176"+ + "\120\0\32\210\1\0\131\210\14\0\326\210\57\0\1\176\1\0\1\210"+ + "\31\0\11\210\6\177\1\0\5\201\2\0\3\210\1\176\1\176\4\0"+ + "\126\211\2\0\2\177\2\201\3\211\133\201\1\0\4\201\5\0\51\176"+ + "\3\0\136\215\21\0\33\176\65\0\20\201\320\0\57\201\1\0\130\201"+ + "\250\0\u19b6\210\112\0\u51cd\210\63\0\u048d\176\103\0\56\176\2\0\u010d\176"+ + "\3\0\20\176\12\200\2\176\24\0\57\176\4\177\1\0\12\177\1\0"+ + "\31\176\7\0\1\177\120\176\2\177\45\0\11\176\2\0\147\176\2\0"+ + "\4\176\1\0\4\176\14\0\13\176\115\0\12\176\1\177\3\176\1\177"+ + "\4\176\1\177\27\176\5\177\30\0\64\176\14\0\2\177\62\176\21\177"+ + "\13\0\12\200\6\0\22\177\6\176\3\0\1\176\4\0\12\200\34\176"+ + "\10\177\2\0\27\176\15\177\14\0\35\215\3\0\4\177\57\176\16\177"+ + "\16\0\1\176\12\200\46\0\51\176\16\177\11\0\3\176\1\177\10\176"+ + "\2\177\2\0\12\200\6\0\33\206\1\207\4\0\60\206\1\207\1\206"+ + "\3\207\2\206\2\207\5\206\2\207\1\206\1\207\1\206\30\0\5\206"+ + "\13\176\5\177\2\0\3\176\2\177\12\0\6\176\2\0\6\176\2\0"+ + "\6\176\11\0\7\176\1\0\7\176\221\0\43\176\10\177\1\0\2\177"+ + "\2\0\12\200\6\0\u2ba4\215\14\0\27\215\4\0\61\215\4\0\1\44"+ + "\1\40\1\67\1\64\1\33\1\30\2\0\1\24\1\21\2\0\1\17"+ + "\1\15\14\0\1\3\1\6\20\0\1\156\7\0\1\111\1\10\5\0"+ + "\1\1\1\172\3\0\1\163\1\163\1\163\1\163\1\163\1\163\1\163"+ "\1\163\1\163\1\163\1\163\1\163\1\163\1\163\1\163\1\163\1\163"+ "\1\163\1\163\1\163\1\163\1\163\1\163\1\163\1\163\1\163\1\163"+ "\1\163\1\163\1\163\1\163\1\163\1\163\1\163\1\163\1\163\1\163"+ - "\1\163\1\163\1\163\1\163\1\163\1\163\1\163\1\163\1\163\1\163"+ - "\1\164\1\163\1\163\1\163\1\170\1\166\17\0\1\160\u02c1\0\1\114"+ - "\277\0\1\157\1\115\1\16\3\167\2\62\1\167\1\62\2\167\1\36"+ - "\21\167\2\106\7\117\1\116\7\117\7\102\1\37\1\102\1\130\2\66"+ - "\1\65\1\130\1\66\1\65\10\130\2\107\5\103\2\75\5\103\1\22"+ - "\10\53\5\23\3\41\12\147\20\41\3\63\32\43\1\42\2\61\2\154"+ - "\1\155\2\154\2\155\2\154\1\155\3\61\1\60\2\61\12\110\1\126"+ - "\1\50\1\45\1\110\6\50\1\45\13\50\31\61\7\50\12\150\1\50"+ - "\5\13\3\127\3\101\1\100\4\101\2\100\10\101\1\100\7\35\1\34"+ - "\2\35\7\101\16\127\1\141\4\152\1\4\4\151\1\4\5\140\1\137"+ - "\1\140\3\137\7\140\1\137\23\140\5\113\3\140\6\113\2\113\6\112"+ - "\5\112\3\134\2\101\7\133\36\101\4\133\5\101\5\127\6\125\2\127"+ - "\1\125\4\35\13\136\12\151\26\136\15\13\1\135\2\13\1\173\3\142"+ - "\1\13\2\142\5\161\4\142\4\162\1\161\3\162\1\161\5\162\2\70"+ - "\1\73\2\70\1\73\1\70\2\73\1\70\1\73\12\70\1\73\4\5"+ - "\1\144\1\143\1\145\1\12\3\165\1\145\2\165\1\131\2\132\2\165"+ - "\1\12\1\165\1\12\1\165\1\12\1\165\3\12\1\165\2\12\1\165"+ - "\1\12\2\165\1\12\1\165\1\12\1\165\1\12\1\165\1\12\1\165"+ - "\1\12\1\76\2\72\1\76\1\72\2\76\4\72\1\76\7\72\1\76"+ - "\4\72\1\76\4\72\1\165\1\12\1\165\12\31\1\57\21\31\1\57"+ - "\3\32\1\57\3\31\1\57\1\31\2\2\2\31\1\57\15\124\4\47"+ - "\4\54\1\146\1\56\10\146\7\54\6\165\4\25\1\27\37\25\1\27"+ - "\4\25\25\105\1\171\11\105\21\26\5\105\1\7\12\55\5\105\6\104"+ - "\4\76\1\77\1\26\5\123\12\121\17\123\1\74\3\71\14\120\1\11"+ - "\11\46\1\52\5\46\4\122\13\51\2\14\11\46\1\52\31\46\1\52"+ - "\4\11\4\46\2\52\2\153\1\20\5\153\52\20\u1900\0\u016e\206\2\0"+ - "\152\206\46\0\7\174\14\0\5\174\5\0\1\174\1\175\12\174\1\0"+ - "\15\174\1\0\5\174\1\0\1\174\1\0\2\174\1\0\2\174\1\0"+ - "\154\174\41\0\u016b\174\22\0\100\174\2\0\66\174\50\0\14\174\4\0"+ - "\20\175\1\201\2\0\1\200\1\201\13\0\7\175\14\0\2\203\30\0"+ - "\3\203\1\201\1\0\1\202\1\0\1\201\1\200\32\0\5\174\1\0"+ - "\207\174\2\0\1\175\7\0\1\202\4\0\1\201\1\0\1\202\1\0"+ - "\12\176\1\200\1\201\5\0\32\174\4\0\1\203\1\0\32\174\13\0"+ - "\70\177\2\175\37\210\3\0\6\210\2\0\6\210\2\0\6\210\2\0"+ - "\3\210\34\0\3\175\4\0"; + "\1\163\1\163\1\163\1\163\1\164\1\163\1\163\1\163\1\170\1\166"+ + "\17\0\1\160\u02c1\0\1\114\277\0\1\157\1\115\1\16\3\167\2\62"+ + "\1\167\1\62\2\167\1\36\21\167\2\106\7\117\1\116\7\117\7\102"+ + "\1\37\1\102\1\140\2\66\1\65\1\140\1\66\1\65\10\140\2\107"+ + "\5\103\2\75\5\103\1\22\10\53\5\23\3\41\12\122\20\41\3\63"+ + "\32\43\1\42\2\61\2\126\1\127\2\126\2\127\2\126\1\127\3\61"+ + "\1\60\2\61\12\110\1\136\1\50\1\45\1\110\6\50\1\45\13\50"+ + "\31\61\7\50\12\123\1\50\5\13\3\137\3\101\1\100\4\101\2\100"+ + "\10\101\1\100\7\35\1\34\2\35\7\101\16\137\1\151\4\124\1\4"+ + "\4\121\1\4\5\150\1\147\1\150\3\147\7\150\1\147\23\150\5\113"+ + "\3\150\6\113\2\113\6\112\5\112\3\144\2\101\7\143\36\101\4\143"+ + "\5\101\5\137\6\135\2\137\1\135\4\35\13\146\12\121\14\146\12\175"+ + "\15\174\1\145\2\174\1\173\3\152\1\13\2\152\5\161\4\152\4\162"+ + "\1\161\3\162\1\161\5\162\2\70\1\73\2\70\1\73\1\70\2\73"+ + "\1\70\1\73\12\70\1\73\4\5\1\154\1\153\1\155\1\12\3\165"+ + "\1\155\2\165\1\141\2\142\2\165\1\12\1\165\1\12\1\165\1\12"+ + "\1\165\3\12\1\165\2\12\1\165\1\12\2\165\1\12\1\165\1\12"+ + "\1\165\1\12\1\165\1\12\1\165\1\12\1\76\2\72\1\76\1\72"+ + "\2\76\4\72\1\76\7\72\1\76\4\72\1\76\4\72\1\165\1\12"+ + "\1\165\12\31\1\57\21\31\1\57\3\32\1\57\3\31\1\57\1\31"+ + "\2\2\2\31\1\57\15\134\4\47\4\54\1\120\1\56\10\120\7\54"+ + "\6\165\4\25\1\27\37\25\1\27\4\25\25\105\1\171\11\105\21\26"+ + "\5\105\1\7\12\55\5\105\6\104\4\76\1\77\1\26\5\133\12\131"+ + "\17\133\1\74\3\71\14\130\1\11\11\46\1\52\5\46\4\132\13\51"+ + "\2\14\11\46\1\52\31\46\1\52\4\11\4\46\2\52\2\125\1\20"+ + "\5\125\52\20\u1900\0\u016e\210\2\0\152\210\46\0\7\176\14\0\5\176"+ + "\5\0\1\214\1\177\12\214\1\0\15\214\1\0\5\214\1\0\1\214"+ + "\1\0\2\214\1\0\2\214\1\0\12\214\142\176\41\0\u016b\176\22\0"+ + "\100\176\2\0\66\176\50\0\14\176\4\0\20\177\1\203\2\0\1\202"+ + "\1\203\13\0\7\177\14\0\2\205\30\0\3\205\1\203\1\0\1\204"+ + "\1\0\1\203\1\202\32\0\5\176\1\0\207\176\2\0\1\177\7\0"+ + "\1\204\4\0\1\203\1\0\1\204\1\0\12\200\1\202\1\203\5\0"+ + "\32\176\4\0\1\205\1\0\32\176\13\0\70\201\2\177\37\215\3\0"+ + "\6\215\2\0\6\215\2\0\6\215\2\0\3\215\34\0\3\177\4\0"; /** * Translates characters to character classes @@ -218,11 +220,12 @@ public final class StandardTokenizerImpl implements StandardTokenizerInterface { private static final String ZZ_ACTION_PACKED_0 = "\1\0\26\1\1\2\1\3\1\4\1\1\1\5\1\6"+ - "\1\7\1\10\20\0\1\2\1\0\1\2\12\0\1\3"+ - "\21\0\1\2\115\0"; + "\1\7\1\2\1\10\21\0\1\2\1\0\1\2\12\0"+ + "\1\3\10\0\1\4\1\2\11\0\1\2\55\0\1\2"+ + "\74\0\1\2\1\1\36\0"; private static int [] zzUnpackAction() { - int [] result = new int[156]; + int [] result = new int[221]; int offset = 0; offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); return result; @@ -247,29 +250,37 @@ public final class StandardTokenizerImpl implements StandardTokenizerInterface { private static final int [] ZZ_ROWMAP = zzUnpackRowMap(); private static final String ZZ_ROWMAP_PACKED_0 = - "\0\0\0\211\0\u0112\0\u019b\0\u0224\0\u02ad\0\u0336\0\u03bf"+ - "\0\u0448\0\u04d1\0\u055a\0\u05e3\0\u066c\0\u06f5\0\u077e\0\u0807"+ - "\0\u0890\0\u0919\0\u09a2\0\u0a2b\0\u0ab4\0\u0b3d\0\u0bc6\0\u0c4f"+ - "\0\u0cd8\0\u0d61\0\u0dea\0\u0e73\0\u0efc\0\u0f85\0\u100e\0\u0112"+ - "\0\u019b\0\u1097\0\u1120\0\u0336\0\u03bf\0\u0448\0\u04d1\0\u11a9"+ - "\0\u1232\0\u12bb\0\u1344\0\u077e\0\u13cd\0\u1456\0\u14df\0\u1568"+ - "\0\u15f1\0\u167a\0\u1703\0\u02ad\0\u178c\0\u1815\0\u066c\0\u189e"+ - "\0\u1927\0\u19b0\0\u1a39\0\u1ac2\0\u1b4b\0\u1bd4\0\u1c5d\0\u1ce6"+ - "\0\u1d6f\0\u1df8\0\u1e81\0\u1f0a\0\u1f93\0\u201c\0\u20a5\0\u212e"+ - "\0\u21b7\0\u2240\0\u22c9\0\u2352\0\u23db\0\u0dea\0\u2464\0\u24ed"+ - "\0\u2576\0\u25ff\0\u2688\0\u2711\0\u279a\0\u2823\0\u28ac\0\u2935"+ - "\0\u29be\0\u2a47\0\u2ad0\0\u2b59\0\u2be2\0\u2c6b\0\u2cf4\0\u2d7d"+ - "\0\u2e06\0\u2e8f\0\u2f18\0\u2fa1\0\u302a\0\u30b3\0\u313c\0\u31c5"+ - "\0\u324e\0\u32d7\0\u3360\0\u33e9\0\u3472\0\u34fb\0\u3584\0\u360d"+ - "\0\u3696\0\u371f\0\u37a8\0\u3831\0\u38ba\0\u3943\0\u39cc\0\u3a55"+ - "\0\u3ade\0\u3b67\0\u3bf0\0\u3c79\0\u3d02\0\u3d8b\0\u3e14\0\u3e9d"+ - "\0\u3f26\0\u3faf\0\u4038\0\u40c1\0\u414a\0\u41d3\0\u425c\0\u42e5"+ - "\0\u436e\0\u43f7\0\u4480\0\u4509\0\u4592\0\u461b\0\u46a4\0\u472d"+ - "\0\u47b6\0\u483f\0\u48c8\0\u4951\0\u49da\0\u4a63\0\u4aec\0\u4b75"+ - "\0\u4bfe\0\u4c87\0\u4d10\0\u4d99"; + "\0\0\0\216\0\u011c\0\u01aa\0\u0238\0\u02c6\0\u0354\0\u03e2"+ + "\0\u0470\0\u04fe\0\u058c\0\u061a\0\u06a8\0\u0736\0\u07c4\0\u0852"+ + "\0\u08e0\0\u096e\0\u09fc\0\u0a8a\0\u0b18\0\u0ba6\0\u0c34\0\u0cc2"+ + "\0\u0d50\0\u0dde\0\u0e6c\0\u0efa\0\u0f88\0\u1016\0\u10a4\0\u1132"+ + "\0\u11c0\0\u011c\0\u01aa\0\u124e\0\u12dc\0\u0354\0\u03e2\0\u0470"+ + "\0\u04fe\0\u136a\0\u13f8\0\u1486\0\u1514\0\u07c4\0\u15a2\0\u1630"+ + "\0\u16be\0\u174c\0\u17da\0\u1868\0\u18f6\0\u02c6\0\u1984\0\u1a12"+ + "\0\u06a8\0\u1aa0\0\u1b2e\0\u1bbc\0\u1c4a\0\u1cd8\0\u1d66\0\u1df4"+ + "\0\u1e82\0\u1f10\0\u1f9e\0\u202c\0\u20ba\0\u2148\0\u21d6\0\u2264"+ + "\0\u22f2\0\u2380\0\u240e\0\u249c\0\u252a\0\u25b8\0\u2646\0\u26d4"+ + "\0\u2762\0\u0e6c\0\u27f0\0\u287e\0\u290c\0\u299a\0\u2a28\0\u2ab6"+ + "\0\u2b44\0\u2bd2\0\u2c60\0\u2cee\0\u2d7c\0\u2e0a\0\u2e98\0\u2f26"+ + "\0\u2fb4\0\u3042\0\u30d0\0\u315e\0\u31ec\0\u327a\0\u3308\0\u3396"+ + "\0\u3424\0\u34b2\0\u3540\0\u35ce\0\u365c\0\u36ea\0\u3778\0\u3806"+ + "\0\u3894\0\u3922\0\u39b0\0\u3a3e\0\u3acc\0\u3b5a\0\u3be8\0\u3c76"+ + "\0\u3d04\0\u3d92\0\u3e20\0\u3eae\0\u3f3c\0\u3fca\0\u4058\0\u40e6"+ + "\0\u4174\0\u4202\0\u4290\0\u431e\0\u43ac\0\u443a\0\u44c8\0\u4556"+ + "\0\u45e4\0\u4672\0\u4700\0\u478e\0\u481c\0\u48aa\0\u4938\0\u49c6"+ + "\0\u4a54\0\u4ae2\0\u4b70\0\u4bfe\0\u4c8c\0\u4d1a\0\u4da8\0\u4e36"+ + "\0\u4ec4\0\u4f52\0\u4fe0\0\u506e\0\u50fc\0\u518a\0\u5218\0\u52a6"+ + "\0\u5334\0\u53c2\0\u5450\0\u54de\0\u556c\0\u55fa\0\u5688\0\u5716"+ + "\0\u57a4\0\u5832\0\u58c0\0\u594e\0\u59dc\0\u5a6a\0\u5af8\0\u5b86"+ + "\0\u5c14\0\u5ca2\0\u5d30\0\u5dbe\0\u5e4c\0\u5eda\0\u5f68\0\u5ff6"+ + "\0\u6084\0\u6112\0\u61a0\0\u622e\0\u62bc\0\u634a\0\u63d8\0\u6466"+ + "\0\u64f4\0\u6582\0\u6610\0\u669e\0\u672c\0\u67ba\0\u6848\0\u68d6"+ + "\0\u6964\0\u69f2\0\u6a80\0\u6b0e\0\u6b9c\0\u6c2a\0\u6cb8\0\u6d46"+ + "\0\u6dd4\0\u6e62\0\u6ef0\0\u6f7e\0\u700c\0\u709a\0\u7128\0\u71b6"+ + "\0\u7244\0\u72d2\0\u7360\0\u73ee\0\u747c"; private static int [] zzUnpackRowMap() { - int [] result = new int[156]; + int [] result = new int[221]; int offset = 0; offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); return result; @@ -297,419 +308,589 @@ public final class StandardTokenizerImpl implements StandardTokenizerInterface { "\3\2\1\13\2\2\1\14\4\2\1\15\3\2\1\16"+ "\17\2\1\17\2\2\1\20\66\2\1\21\1\2\1\22"+ "\2\2\1\23\1\24\1\2\1\25\1\2\1\26\1\2"+ - "\1\27\1\2\1\30\1\2\1\31\1\32\3\2\1\33"+ - "\2\34\1\35\1\36\1\37\213\0\1\30\2\0\1\30"+ - "\4\0\1\30\16\0\1\30\15\0\1\30\20\0\1\30"+ - "\1\0\1\30\31\0\1\30\4\0\1\30\10\0\2\30"+ - "\15\0\2\30\10\0\1\30\21\0\2\30\5\0\1\30"+ - "\2\0\1\30\3\0\2\30\10\0\4\30\1\0\3\30"+ - "\1\0\1\30\2\0\1\30\2\0\1\30\4\0\4\30"+ - "\1\0\2\30\1\0\1\30\2\0\1\30\1\0\1\30"+ - "\2\0\4\30\2\0\3\30\1\0\2\30\1\0\3\30"+ - "\5\0\4\30\2\0\10\30\1\0\1\30\2\0\4\30"+ - "\1\0\2\30\1\0\1\30\1\0\2\30\4\0\1\30"+ - "\3\0\1\30\24\0\1\30\4\0\1\30\11\0\1\30"+ - "\22\0\1\30\3\0\1\30\27\0\1\30\63\0\1\30"+ - "\24\0\1\30\3\0\4\30\1\0\1\30\1\0\1\31"+ - "\2\0\1\30\1\0\2\30\2\0\2\30\2\0\3\30"+ - "\1\0\1\30\1\0\1\30\2\0\4\30\1\0\3\30"+ - "\1\0\1\30\1\0\3\30\1\0\2\30\1\0\4\30"+ - "\1\0\2\30\2\0\10\30\1\0\2\30\1\0\11\30"+ - "\1\0\10\30\1\0\13\30\1\31\1\0\1\30\1\0"+ - "\1\30\1\0\2\30\2\0\1\30\1\0\1\30\3\0"+ - "\1\30\33\0\1\30\17\0\1\30\23\0\1\30\23\0"+ - "\1\30\6\0\3\30\37\0\1\30\7\0\1\30\23\0"+ - "\1\30\1\0\2\30\1\0\1\30\1\0\4\30\1\0"+ - "\1\30\1\0\1\30\1\0\2\30\1\0\3\30\1\0"+ - "\2\30\1\0\4\30\1\0\3\30\1\0\17\30\1\0"+ - "\2\30\1\0\21\30\1\0\2\30\1\0\41\30\1\0"+ - "\1\30\1\0\2\30\2\0\1\30\1\0\1\30\1\0"+ - "\1\30\1\0\1\30\33\0\1\30\3\0\2\30\12\0"+ - "\2\30\13\0\1\30\6\0\1\30\2\0\2\30\6\0"+ - "\1\30\4\0\2\30\2\0\2\30\5\0\3\30\10\0"+ - "\1\30\26\0\1\30\7\0\1\30\23\0\1\30\1\0"+ - "\2\30\1\0\1\30\2\0\2\30\2\0\1\30\3\0"+ - "\2\30\1\0\3\30\1\0\2\30\1\0\4\30\1\0"+ - "\3\30\1\0\1\30\1\0\2\30\2\0\11\30\1\0"+ - "\2\30\1\0\1\30\1\0\2\30\1\0\14\30\1\0"+ - "\2\30\1\0\3\30\1\0\1\30\1\0\30\30\1\0"+ - "\2\30\1\0\1\30\1\0\2\30\2\0\1\30\1\0"+ - "\1\30\1\0\1\30\1\0\1\30\17\0\1\30\26\0"+ - "\2\30\23\0\1\31\1\30\66\0\1\31\46\0\1\31"+ - "\27\0\4\30\2\0\2\30\14\0\3\30\15\0\3\30"+ - "\3\0\1\30\7\0\2\30\13\0\1\30\13\0\4\31"+ - "\1\0\2\30\11\0\1\30\37\0\1\30\3\0\2\30"+ - "\12\0\2\30\1\0\3\30\7\0\1\30\6\0\2\30"+ - "\1\0\2\30\6\0\1\30\4\0\2\30\2\0\2\30"+ - "\5\0\3\30\10\0\1\30\16\0\1\30\4\0\2\31"+ - "\1\0\1\30\7\0\1\30\23\0\1\30\4\0\1\30"+ - "\6\0\1\30\3\0\1\30\6\0\1\30\5\0\1\30"+ - "\2\0\2\30\1\0\17\30\2\0\1\30\13\0\7\30"+ - "\2\0\1\30\1\0\1\30\1\0\1\30\2\0\1\30"+ - "\1\0\1\30\1\0\1\30\1\0\1\30\6\0\2\30"+ - "\5\0\1\30\1\0\1\30\2\0\3\30\1\0\1\30"+ - "\7\0\1\30\1\0\1\30\35\0\1\30\17\0\2\30"+ + "\1\27\3\2\1\30\1\2\1\31\1\32\3\2\1\33"+ + "\2\34\1\35\1\36\2\2\1\37\1\40\220\0\1\30"+ + "\2\0\1\30\4\0\1\30\16\0\1\30\15\0\1\30"+ + "\20\0\1\30\1\0\1\30\41\0\1\30\4\0\1\30"+ + "\10\0\2\30\5\0\2\30\10\0\1\30\26\0\2\30"+ + "\5\0\1\30\2\0\1\30\3\0\2\30\10\0\4\30"+ + "\1\0\3\30\1\0\1\30\2\0\1\30\2\0\1\30"+ + "\4\0\4\30\1\0\2\30\1\0\1\30\2\0\1\30"+ + "\1\0\1\30\2\0\4\30\2\0\3\30\1\0\2\30"+ + "\1\0\3\30\1\0\4\30\1\0\2\30\5\0\4\30"+ + "\2\0\10\30\1\0\1\30\2\0\1\30\1\0\2\30"+ + "\4\0\1\30\3\0\3\30\27\0\1\30\4\0\1\30"+ + "\11\0\1\30\22\0\1\30\3\0\1\30\27\0\1\30"+ + "\63\0\1\30\31\0\1\30\3\0\4\30\1\0\1\30"+ + "\1\0\1\31\2\0\1\30\1\0\2\30\2\0\2\30"+ + "\2\0\3\30\1\0\1\30\1\0\1\30\2\0\4\30"+ + "\1\0\3\30\1\0\1\30\1\0\3\30\1\0\2\30"+ + "\1\0\4\30\1\0\2\30\2\0\10\30\1\0\2\30"+ + "\1\0\10\30\1\31\1\0\7\30\1\0\10\30\1\0"+ + "\6\30\1\0\1\30\1\0\2\30\2\0\1\30\1\0"+ + "\1\30\3\0\3\30\36\0\1\30\17\0\1\30\23\0"+ + "\1\30\23\0\1\30\6\0\3\30\37\0\1\30\7\0"+ + "\1\30\30\0\1\30\1\0\2\30\1\0\1\30\1\0"+ + "\4\30\1\0\1\30\1\0\1\30\1\0\2\30\1\0"+ + "\3\30\1\0\2\30\1\0\4\30\1\0\3\30\1\0"+ + "\17\30\1\0\2\30\1\0\21\30\1\0\2\30\1\0"+ + "\41\30\1\0\1\30\1\0\2\30\2\0\1\30\1\0"+ + "\1\30\1\0\1\30\1\0\3\30\36\0\1\30\3\0"+ + "\2\30\12\0\2\30\13\0\1\30\6\0\1\30\2\0"+ + "\2\30\6\0\1\30\4\0\2\30\2\0\2\30\5\0"+ + "\3\30\20\0\1\30\16\0\1\30\7\0\1\30\30\0"+ + "\1\30\1\0\2\30\1\0\1\30\2\0\2\30\2\0"+ + "\1\30\3\0\2\30\1\0\3\30\1\0\2\30\1\0"+ + "\4\30\1\0\3\30\1\0\1\30\1\0\2\30\2\0"+ + "\11\30\1\0\2\30\1\0\1\30\1\0\2\30\1\0"+ + "\14\30\1\0\2\30\1\0\10\30\1\0\2\30\1\0"+ + "\1\30\1\0\23\30\1\0\1\30\1\0\2\30\2\0"+ + "\1\30\1\0\1\30\1\0\1\30\1\0\3\30\22\0"+ + "\1\30\26\0\2\30\23\0\1\31\1\30\40\0\1\31"+ + "\101\0\1\31\27\0\4\30\2\0\2\30\14\0\3\30"+ + "\15\0\3\30\3\0\1\30\7\0\2\30\1\0\4\31"+ + "\1\0\2\30\13\0\1\30\23\0\1\30\44\0\1\30"+ + "\3\0\2\30\12\0\2\30\1\0\3\30\7\0\1\30"+ + "\6\0\2\30\1\0\2\30\6\0\1\30\4\0\2\30"+ + "\2\0\2\30\5\0\3\30\2\0\1\30\3\0\2\31"+ + "\10\0\1\30\16\0\1\30\7\0\1\30\30\0\1\30"+ + "\4\0\1\30\6\0\1\30\3\0\1\30\6\0\1\30"+ + "\5\0\1\30\2\0\2\30\1\0\17\30\2\0\1\30"+ + "\13\0\7\30\2\0\1\30\1\0\1\30\1\0\2\30"+ + "\2\0\1\30\1\0\3\30\2\0\1\30\1\0\1\30"+ + "\1\0\1\30\1\0\1\30\6\0\2\30\6\0\1\30"+ + "\7\0\1\30\1\0\1\30\42\0\1\30\17\0\2\30"+ "\22\0\1\30\2\0\2\30\13\0\1\30\3\0\2\30"+ - "\5\0\3\30\10\0\1\30\26\0\1\30\7\0\1\30"+ - "\30\0\1\30\6\0\1\30\3\0\1\30\3\0\1\30"+ - "\7\0\1\30\31\0\20\30\5\0\3\30\3\0\1\30"+ - "\3\0\2\30\2\0\2\30\4\0\1\30\10\0\1\30"+ - "\4\0\1\30\2\0\1\30\4\0\1\30\1\0\1\30"+ - "\1\0\1\30\132\0\1\36\41\0\1\32\35\0\1\35"+ + "\5\0\3\30\20\0\1\30\16\0\1\30\7\0\1\30"+ + "\35\0\1\30\6\0\1\30\3\0\1\30\3\0\1\30"+ + "\7\0\1\30\31\0\20\30\5\0\3\30\4\0\1\30"+ + "\6\0\1\30\3\0\2\30\2\0\2\30\4\0\1\30"+ + "\5\0\1\30\2\0\1\30\4\0\1\30\1\0\1\30"+ + "\1\0\1\30\137\0\1\36\41\0\1\32\42\0\1\35"+ "\6\0\1\35\2\0\1\35\3\0\2\35\10\0\4\35"+ "\1\0\3\35\1\0\1\35\2\0\1\35\2\0\1\35"+ "\4\0\4\35\1\0\2\35\6\0\1\35\2\0\4\35"+ - "\2\0\3\35\1\0\2\35\1\0\3\35\5\0\4\35"+ - "\2\0\10\35\4\0\4\35\1\0\2\35\1\0\1\35"+ - "\1\0\2\35\4\0\1\35\3\0\1\35\17\0\1\35"+ + "\2\0\3\35\1\0\2\35\1\0\3\35\1\0\4\35"+ + "\1\0\2\35\5\0\4\35\2\0\10\35\4\0\1\35"+ + "\1\0\2\35\4\0\1\35\3\0\3\35\22\0\1\35"+ "\1\0\2\35\1\0\1\35\1\0\4\35\1\0\1\35"+ "\1\0\1\35\1\0\2\35\1\0\3\35\1\0\2\35"+ "\1\0\4\35\1\0\3\35\1\0\17\35\1\0\2\35"+ "\1\0\21\35\1\0\2\35\1\0\41\35\1\0\1\35"+ "\1\0\2\35\2\0\1\35\1\0\1\35\1\0\1\35"+ - "\1\0\1\35\17\0\1\35\1\0\2\35\1\0\1\35"+ + "\1\0\3\35\22\0\1\35\1\0\2\35\1\0\1\35"+ "\1\0\4\35\1\0\1\35\1\0\1\35\1\0\2\35"+ "\2\0\1\35\2\0\2\35\1\0\4\35\1\0\3\35"+ "\1\0\17\35\1\0\2\35\1\0\21\35\1\0\2\35"+ "\1\0\41\35\1\0\1\35\1\0\2\35\2\0\1\35"+ - "\1\0\1\35\1\0\1\35\1\0\1\35\33\0\1\35"+ + "\1\0\1\35\1\0\1\35\1\0\3\35\36\0\1\35"+ "\17\0\1\35\23\0\1\35\32\0\1\35\41\0\1\35"+ - "\7\0\1\35\23\0\1\35\1\0\2\35\3\0\4\35"+ + "\7\0\1\35\30\0\1\35\1\0\2\35\3\0\4\35"+ "\1\0\1\35\1\0\1\35\1\0\2\35\1\0\3\35"+ "\1\0\2\35\1\0\4\35\1\0\3\35\1\0\10\35"+ "\1\0\6\35\1\0\2\35\1\0\21\35\1\0\2\35"+ "\1\0\41\35\1\0\1\35\1\0\2\35\2\0\1\35"+ - "\1\0\1\35\1\0\1\35\1\0\1\35\210\0\1\36"+ - "\16\0\1\40\1\0\1\41\2\0\1\42\1\0\1\43"+ - "\4\0\1\44\1\0\1\45\1\0\1\46\2\0\1\47"+ - "\3\0\1\50\2\0\1\51\4\0\1\52\3\0\1\53"+ - "\17\0\1\54\2\0\1\55\21\0\1\56\2\0\1\57"+ - "\57\0\2\30\1\60\1\0\1\61\1\0\1\61\1\62"+ - "\1\0\1\30\2\0\1\30\1\0\1\40\1\0\1\41"+ - "\2\0\1\63\1\0\1\64\4\0\1\44\1\0\1\45"+ - "\1\0\1\46\2\0\1\47\3\0\1\65\2\0\1\66"+ - "\4\0\1\67\3\0\1\70\17\0\1\54\2\0\1\71"+ - "\21\0\1\72\2\0\1\73\57\0\1\30\2\31\2\0"+ - "\2\74\1\75\1\0\1\31\2\0\1\30\6\0\1\76"+ - "\21\0\1\77\2\0\1\100\10\0\1\101\22\0\1\102"+ - "\21\0\1\103\2\0\1\104\41\0\1\105\16\0\1\32"+ - "\1\0\1\32\3\0\1\62\1\0\1\32\4\0\1\40"+ - "\1\0\1\41\2\0\1\106\1\0\1\64\4\0\1\44"+ - "\1\0\1\45\1\0\1\46\2\0\1\47\3\0\1\107"+ - "\2\0\1\110\4\0\1\67\3\0\1\111\17\0\1\54"+ - "\2\0\1\112\21\0\1\113\2\0\1\114\41\0\1\115"+ - "\15\0\1\30\1\116\1\31\1\117\3\0\1\116\1\0"+ - "\1\116\2\0\1\30\204\0\2\34\11\0\1\120\21\0"+ - "\1\121\2\0\1\122\10\0\1\123\22\0\1\124\21\0"+ - "\1\125\2\0\1\126\60\0\1\35\7\0\1\35\11\0"+ - "\1\127\21\0\1\130\2\0\1\131\10\0\1\132\22\0"+ - "\1\133\21\0\1\134\2\0\1\135\60\0\1\36\7\0"+ - "\1\36\4\0\1\40\1\0\1\41\2\0\1\136\1\0"+ - "\1\43\4\0\1\44\1\0\1\45\1\0\1\46\2\0"+ - "\1\47\3\0\1\137\2\0\1\140\4\0\1\52\3\0"+ - "\1\141\17\0\1\54\2\0\1\142\21\0\1\143\2\0"+ - "\1\144\57\0\1\30\1\37\1\60\1\0\1\61\1\0"+ - "\1\61\1\62\1\0\1\37\2\0\1\37\7\0\1\30"+ + "\1\0\1\35\1\0\1\35\1\0\3\35\165\0\1\41"+ + "\25\0\1\36\2\41\21\0\1\42\1\0\1\43\2\0"+ + "\1\44\1\0\1\45\4\0\1\46\1\0\1\47\1\0"+ + "\1\50\2\0\1\51\3\0\1\52\2\0\1\53\4\0"+ + "\1\54\3\0\1\55\17\0\1\56\2\0\1\57\21\0"+ + "\1\60\2\0\1\61\61\0\2\30\1\62\1\0\1\63"+ + "\1\0\1\63\1\64\1\0\1\30\2\0\1\63\1\0"+ + "\1\37\1\30\1\0\1\42\1\0\1\43\2\0\1\65"+ + "\1\0\1\66\4\0\1\46\1\0\1\47\1\0\1\50"+ + "\2\0\1\51\3\0\1\67\2\0\1\70\4\0\1\71"+ + "\3\0\1\72\17\0\1\56\2\0\1\73\21\0\1\74"+ + "\2\0\1\75\61\0\1\30\2\31\2\0\2\76\1\77"+ + "\1\0\1\31\2\0\1\76\1\0\1\37\1\30\6\0"+ + "\1\100\21\0\1\101\2\0\1\102\10\0\1\103\22\0"+ + "\1\104\21\0\1\105\2\0\1\106\41\0\1\107\20\0"+ + "\1\32\1\0\1\110\3\0\1\111\1\0\1\32\7\0"+ + "\1\42\1\0\1\43\2\0\1\112\1\0\1\66\4\0"+ + "\1\46\1\0\1\47\1\0\1\50\2\0\1\51\3\0"+ + "\1\113\2\0\1\114\4\0\1\71\3\0\1\115\17\0"+ + "\1\56\2\0\1\116\21\0\1\117\2\0\1\120\41\0"+ + "\1\121\17\0\1\30\1\122\1\31\1\123\3\0\1\122"+ + "\1\0\1\122\4\0\1\37\1\30\206\0\2\34\14\0"+ + "\1\124\21\0\1\125\2\0\1\126\10\0\1\127\22\0"+ + "\1\130\21\0\1\131\2\0\1\132\62\0\1\35\7\0"+ + "\1\35\14\0\1\133\21\0\1\134\2\0\1\135\10\0"+ + "\1\136\22\0\1\137\21\0\1\140\2\0\1\141\62\0"+ + "\1\36\7\0\1\36\7\0\1\42\1\0\1\43\2\0"+ + "\1\142\1\0\1\45\4\0\1\46\1\0\1\47\1\0"+ + "\1\50\2\0\1\51\3\0\1\143\2\0\1\144\4\0"+ + "\1\54\3\0\1\145\17\0\1\56\2\0\1\146\21\0"+ + "\1\147\2\0\1\150\61\0\1\30\1\37\1\62\1\0"+ + "\1\63\1\0\1\63\1\64\1\0\1\37\2\0\1\30"+ + "\1\151\1\37\1\30\1\0\1\42\1\0\1\43\2\0"+ + "\1\152\1\0\1\45\4\0\1\46\1\0\1\47\1\0"+ + "\1\50\2\0\1\51\3\0\1\153\2\0\1\154\4\0"+ + "\1\54\3\0\1\155\17\0\1\56\2\0\1\156\21\0"+ + "\1\157\2\0\1\160\61\0\1\30\1\40\1\62\1\0"+ + "\1\63\1\0\1\63\1\64\1\0\1\40\2\0\1\63"+ + "\1\0\1\37\1\40\6\0\1\161\21\0\1\162\2\0"+ + "\1\163\10\0\1\164\22\0\1\165\21\0\1\166\2\0"+ + "\1\167\55\0\1\170\4\0\1\41\7\0\1\41\15\0"+ + "\1\30\4\0\1\30\11\0\1\30\22\0\1\30\3\0"+ + "\1\30\13\0\1\30\2\0\1\30\10\0\1\30\22\0"+ + "\4\30\35\0\1\30\31\0\1\30\3\0\4\30\1\0"+ + "\1\30\1\0\1\62\2\0\1\30\1\0\2\30\2\0"+ + "\2\30\2\0\3\30\1\0\1\30\1\0\1\30\2\0"+ + "\4\30\1\0\3\30\1\0\1\30\1\0\3\30\1\0"+ + "\2\30\1\0\4\30\1\0\2\30\2\0\10\30\1\0"+ + "\2\30\1\0\10\30\1\62\1\0\7\30\1\0\10\30"+ + "\1\0\6\30\1\0\1\30\1\0\2\30\2\0\1\30"+ + "\1\0\1\30\3\0\3\30\22\0\1\30\26\0\2\30"+ + "\23\0\1\62\1\30\40\0\1\62\13\0\1\30\65\0"+ + "\1\62\11\0\1\30\15\0\4\30\2\0\2\30\14\0"+ + "\4\30\1\0\2\30\11\0\3\30\3\0\1\30\1\0"+ + "\1\30\4\0\3\30\1\0\4\62\1\0\2\30\5\0"+ + "\4\30\2\0\2\30\12\0\1\30\7\0\1\30\44\0"+ + "\1\30\3\0\2\30\12\0\2\30\1\0\3\30\7\0"+ + "\1\30\6\0\2\30\1\0\2\30\6\0\1\30\4\0"+ + "\2\30\2\0\2\30\5\0\3\30\2\0\1\30\3\0"+ + "\2\62\10\0\1\30\16\0\1\30\7\0\1\30\30\0"+ + "\1\30\4\0\1\30\6\0\1\30\3\0\1\30\6\0"+ + "\1\30\5\0\1\30\2\0\2\30\1\0\17\30\2\0"+ + "\1\30\13\0\7\30\2\0\1\30\1\0\1\30\1\0"+ + "\2\30\2\0\1\30\1\0\3\30\2\0\1\30\1\0"+ + "\1\30\1\0\1\30\1\0\1\30\4\0\1\30\1\0"+ + "\2\30\6\0\1\30\7\0\1\30\1\0\1\30\33\0"+ + "\1\30\6\0\1\30\3\0\1\30\3\0\1\30\7\0"+ + "\1\30\31\0\20\30\5\0\3\30\4\0\1\30\6\0"+ + "\1\30\3\0\2\30\2\0\2\30\4\0\5\30\1\0"+ + "\1\30\2\0\1\30\4\0\1\30\1\0\1\30\1\0"+ + "\1\30\134\0\2\30\25\0\4\30\55\0\1\30\15\0"+ + "\2\30\10\0\2\30\1\0\1\30\1\0\1\30\11\0"+ + "\1\30\11\0\2\30\6\0\1\30\2\0\4\30\3\0"+ + "\1\30\2\0\2\30\1\0\3\30\1\0\2\30\1\0"+ + "\1\30\10\0\1\30\1\0\2\30\2\0\2\30\1\0"+ + "\4\30\23\0\1\30\21\0\1\42\1\0\1\43\2\0"+ + "\1\171\1\0\1\45\4\0\1\46\1\0\1\47\1\0"+ + "\1\50\2\0\1\51\3\0\1\172\2\0\1\173\4\0"+ + "\1\54\3\0\1\174\17\0\1\56\2\0\1\175\21\0"+ + "\1\176\2\0\1\177\61\0\1\30\2\62\2\0\2\200"+ + "\1\201\1\0\1\62\2\0\1\200\1\0\1\37\1\30"+ + "\1\0\1\42\1\0\1\43\2\0\1\202\1\0\1\203"+ + "\4\0\1\46\1\0\1\47\1\0\1\50\2\0\1\51"+ + "\3\0\1\204\2\0\1\205\4\0\1\206\3\0\1\207"+ + "\17\0\1\56\2\0\1\210\21\0\1\211\2\0\1\212"+ + "\61\0\1\30\1\63\2\0\1\63\1\0\2\63\1\0"+ + "\1\63\2\0\1\63\1\0\2\30\1\0\1\42\1\0"+ + "\1\43\2\0\1\213\1\0\1\45\4\0\1\46\1\0"+ + "\1\47\1\0\1\50\2\0\1\51\3\0\1\214\2\0"+ + "\1\215\4\0\1\54\3\0\1\216\17\0\1\56\2\0"+ + "\1\217\21\0\1\220\2\0\1\221\41\0\1\121\17\0"+ + "\1\30\1\64\1\62\1\123\1\63\1\0\1\63\1\64"+ + "\1\0\1\64\2\0\1\63\1\0\1\37\1\30\7\0"+ + "\1\30\4\0\1\30\11\0\1\30\22\0\1\30\3\0"+ + "\1\30\13\0\1\31\2\0\1\31\10\0\1\30\22\0"+ + "\4\31\35\0\1\30\26\0\1\30\26\0\2\30\23\0"+ + "\1\31\1\30\40\0\1\31\13\0\1\31\65\0\1\31"+ + "\11\0\1\31\15\0\4\30\2\0\2\30\14\0\3\30"+ + "\1\31\1\0\2\31\11\0\3\30\3\0\1\30\1\0"+ + "\1\31\4\0\1\31\2\30\1\0\4\31\1\0\2\30"+ + "\5\0\4\31\2\0\1\30\1\31\12\0\1\31\7\0"+ + "\1\30\30\0\1\30\4\0\1\30\6\0\1\30\3\0"+ + "\1\30\6\0\1\30\5\0\1\30\2\0\2\30\1\0"+ + "\17\30\2\0\1\30\13\0\7\30\2\0\1\30\1\0"+ + "\1\30\1\0\2\30\2\0\1\30\1\0\3\30\2\0"+ + "\1\30\1\0\1\30\1\0\1\30\1\0\1\30\4\0"+ + "\1\31\1\0\2\30\6\0\1\30\7\0\1\30\1\0"+ + "\1\30\33\0\1\30\6\0\1\30\3\0\1\30\3\0"+ + "\1\30\7\0\1\30\31\0\20\30\5\0\3\30\4\0"+ + "\1\30\6\0\1\30\3\0\2\30\2\0\2\30\4\0"+ + "\1\30\4\31\1\0\1\30\2\0\1\30\4\0\1\30"+ + "\1\0\1\30\1\0\1\30\134\0\2\31\25\0\4\31"+ + "\55\0\1\31\15\0\2\31\10\0\2\31\1\0\1\31"+ + "\1\0\1\31\11\0\1\31\11\0\2\31\6\0\1\31"+ + "\2\0\4\31\3\0\1\31\2\0\2\31\1\0\3\31"+ + "\1\0\2\31\1\0\1\31\10\0\1\31\1\0\2\31"+ + "\2\0\2\31\1\0\4\31\23\0\1\31\26\0\1\222"+ + "\1\0\1\223\17\0\1\224\2\0\1\225\4\0\1\226"+ + "\3\0\1\227\22\0\1\230\21\0\1\231\2\0\1\232"+ + "\62\0\1\76\1\31\2\0\3\200\1\0\1\76\2\0"+ + "\1\200\4\0\1\42\1\0\1\43\2\0\1\233\1\0"+ + "\1\66\4\0\1\46\1\0\1\47\1\0\1\50\2\0"+ + "\1\51\3\0\1\234\2\0\1\235\4\0\1\71\3\0"+ + "\1\236\17\0\1\56\2\0\1\237\21\0\1\240\2\0"+ + "\1\241\41\0\1\121\17\0\1\30\1\77\1\31\1\123"+ + "\1\0\2\200\1\77\1\0\1\77\2\0\1\200\1\0"+ + "\1\37\1\30\71\0\1\32\2\0\1\32\33\0\4\32"+ + "\216\0\1\32\77\0\1\32\44\0\1\32\1\0\2\32"+ + "\21\0\1\32\4\0\1\32\17\0\4\32\3\0\1\32"+ + "\12\0\1\32\203\0\1\32\222\0\4\32\152\0\2\32"+ + "\25\0\4\32\55\0\1\32\15\0\2\32\10\0\2\32"+ + "\1\0\1\32\1\0\1\32\11\0\1\32\11\0\2\32"+ + "\6\0\1\32\2\0\4\32\3\0\1\32\2\0\2\32"+ + "\1\0\3\32\1\0\2\32\1\0\1\32\10\0\1\32"+ + "\1\0\2\32\2\0\2\32\1\0\4\32\23\0\1\32"+ + "\177\0\1\110\44\0\1\242\21\0\1\243\2\0\1\244"+ + "\10\0\1\245\22\0\1\246\21\0\1\247\2\0\1\250"+ + "\41\0\1\107\20\0\1\110\1\0\1\110\5\0\1\110"+ + "\7\0\1\42\1\0\1\43\2\0\1\251\1\0\1\45"+ + "\4\0\1\46\1\0\1\47\1\0\1\50\2\0\1\51"+ + "\3\0\1\252\2\0\1\253\4\0\1\54\3\0\1\254"+ + "\17\0\1\56\2\0\1\255\21\0\1\256\2\0\1\257"+ + "\41\0\1\121\17\0\1\30\1\111\1\62\1\123\3\0"+ + "\1\111\1\0\1\111\4\0\1\37\1\30\7\0\1\30"+ "\4\0\1\30\11\0\1\30\22\0\1\30\3\0\1\30"+ - "\13\0\1\30\2\0\1\30\10\0\1\30\12\0\4\30"+ - "\45\0\1\30\24\0\1\30\3\0\4\30\1\0\1\30"+ - "\1\0\1\60\2\0\1\30\1\0\2\30\2\0\2\30"+ - "\2\0\3\30\1\0\1\30\1\0\1\30\2\0\4\30"+ - "\1\0\3\30\1\0\1\30\1\0\3\30\1\0\2\30"+ - "\1\0\4\30\1\0\2\30\2\0\10\30\1\0\2\30"+ - "\1\0\11\30\1\0\10\30\1\0\13\30\1\60\1\0"+ - "\1\30\1\0\1\30\1\0\2\30\2\0\1\30\1\0"+ - "\1\30\3\0\1\30\17\0\1\30\26\0\2\30\23\0"+ - "\1\60\1\30\44\0\1\30\21\0\1\60\46\0\1\60"+ - "\11\0\1\30\15\0\4\30\2\0\2\30\14\0\4\30"+ - "\1\0\2\30\11\0\3\30\3\0\1\30\1\0\1\30"+ - "\4\0\3\30\5\0\4\30\2\0\2\30\12\0\4\60"+ - "\1\0\2\30\1\0\1\30\7\0\1\30\37\0\1\30"+ - "\3\0\2\30\12\0\2\30\1\0\3\30\7\0\1\30"+ - "\6\0\2\30\1\0\2\30\6\0\1\30\4\0\2\30"+ - "\2\0\2\30\5\0\3\30\10\0\1\30\16\0\1\30"+ - "\4\0\2\60\1\0\1\30\7\0\1\30\23\0\1\30"+ - "\4\0\1\30\6\0\1\30\3\0\1\30\6\0\1\30"+ - "\5\0\1\30\2\0\2\30\1\0\17\30\2\0\1\30"+ - "\13\0\7\30\2\0\1\30\1\0\1\30\1\0\1\30"+ - "\2\0\1\30\1\0\1\30\1\0\1\30\1\0\1\30"+ - "\4\0\1\30\1\0\2\30\5\0\1\30\1\0\1\30"+ - "\2\0\3\30\1\0\1\30\7\0\1\30\1\0\1\30"+ - "\26\0\1\30\6\0\1\30\3\0\1\30\3\0\1\30"+ - "\7\0\1\30\31\0\20\30\5\0\3\30\3\0\1\30"+ - "\3\0\2\30\2\0\2\30\4\0\5\30\4\0\1\30"+ - "\4\0\1\30\2\0\1\30\4\0\1\30\1\0\1\30"+ - "\1\0\1\30\127\0\2\30\15\0\4\30\60\0\1\30"+ - "\15\0\2\30\10\0\2\30\1\0\1\30\1\0\1\30"+ - "\11\0\1\30\11\0\2\30\6\0\1\30\2\0\4\30"+ - "\3\0\1\30\2\0\2\30\1\0\3\30\5\0\1\30"+ - "\1\0\2\30\2\0\2\30\1\0\4\30\5\0\1\30"+ - "\1\0\2\30\37\0\1\40\1\0\1\41\2\0\1\145"+ - "\1\0\1\43\4\0\1\44\1\0\1\45\1\0\1\46"+ - "\2\0\1\47\3\0\1\146\2\0\1\147\4\0\1\52"+ - "\3\0\1\150\17\0\1\54\2\0\1\151\21\0\1\152"+ - "\2\0\1\153\57\0\1\30\2\60\2\0\2\154\1\62"+ - "\1\0\1\60\2\0\1\30\1\0\1\40\1\0\1\41"+ - "\2\0\1\155\1\0\1\156\4\0\1\44\1\0\1\45"+ - "\1\0\1\46\2\0\1\47\3\0\1\157\2\0\1\160"+ - "\4\0\1\161\3\0\1\162\17\0\1\54\2\0\1\163"+ - "\21\0\1\164\2\0\1\165\57\0\1\30\1\61\7\0"+ - "\1\61\2\0\1\30\1\0\1\40\1\0\1\41\2\0"+ - "\1\166\1\0\1\43\4\0\1\44\1\0\1\45\1\0"+ - "\1\46\2\0\1\47\3\0\1\167\2\0\1\170\4\0"+ - "\1\52\3\0\1\171\17\0\1\54\2\0\1\172\21\0"+ - "\1\173\2\0\1\174\41\0\1\115\15\0\1\30\1\62"+ - "\1\60\1\117\3\0\1\62\1\0\1\62\2\0\1\30"+ - "\7\0\1\30\4\0\1\30\11\0\1\30\22\0\1\30"+ - "\3\0\1\30\13\0\1\31\2\0\1\31\10\0\1\30"+ - "\12\0\4\31\45\0\1\30\21\0\1\30\26\0\2\30"+ - "\23\0\1\31\1\30\44\0\1\31\21\0\1\31\46\0"+ - "\1\31\11\0\1\31\15\0\4\30\2\0\2\30\14\0"+ - "\3\30\1\31\1\0\2\31\11\0\3\30\3\0\1\30"+ - "\1\0\1\31\4\0\1\31\2\30\5\0\4\31\2\0"+ - "\1\30\1\31\12\0\4\31\1\0\2\30\1\0\1\31"+ - "\7\0\1\30\23\0\1\30\4\0\1\30\6\0\1\30"+ - "\3\0\1\30\6\0\1\30\5\0\1\30\2\0\2\30"+ - "\1\0\17\30\2\0\1\30\13\0\7\30\2\0\1\30"+ - "\1\0\1\30\1\0\1\30\2\0\1\30\1\0\1\30"+ - "\1\0\1\30\1\0\1\30\4\0\1\31\1\0\2\30"+ - "\5\0\1\30\1\0\1\30\2\0\3\30\1\0\1\30"+ - "\7\0\1\30\1\0\1\30\26\0\1\30\6\0\1\30"+ - "\3\0\1\30\3\0\1\30\7\0\1\30\31\0\20\30"+ - "\5\0\3\30\3\0\1\30\3\0\2\30\2\0\2\30"+ - "\4\0\1\30\4\31\4\0\1\30\4\0\1\30\2\0"+ - "\1\30\4\0\1\30\1\0\1\30\1\0\1\30\127\0"+ - "\2\31\15\0\4\31\60\0\1\31\15\0\2\31\10\0"+ - "\2\31\1\0\1\31\1\0\1\31\11\0\1\31\11\0"+ - "\2\31\6\0\1\31\2\0\4\31\3\0\1\31\2\0"+ - "\2\31\1\0\3\31\5\0\1\31\1\0\2\31\2\0"+ - "\2\31\1\0\4\31\5\0\1\31\1\0\2\31\44\0"+ - "\1\175\1\0\1\176\17\0\1\177\2\0\1\200\4\0"+ - "\1\201\3\0\1\202\22\0\1\203\21\0\1\204\2\0"+ - "\1\205\60\0\1\74\1\31\6\0\1\74\4\0\1\40"+ - "\1\0\1\41\2\0\1\206\1\0\1\64\4\0\1\44"+ - "\1\0\1\45\1\0\1\46\2\0\1\47\3\0\1\207"+ - "\2\0\1\210\4\0\1\67\3\0\1\211\17\0\1\54"+ - "\2\0\1\212\21\0\1\213\2\0\1\214\41\0\1\115"+ - "\15\0\1\30\1\75\1\31\1\117\3\0\1\75\1\0"+ - "\1\75\2\0\1\30\71\0\1\32\2\0\1\32\23\0"+ - "\4\32\211\0\1\32\102\0\1\32\44\0\1\32\1\0"+ - "\2\32\21\0\1\32\4\0\1\32\7\0\4\32\3\0"+ - "\1\32\22\0\1\32\166\0\1\32\215\0\4\32\155\0"+ - "\2\32\15\0\4\32\60\0\1\32\15\0\2\32\10\0"+ - "\2\32\1\0\1\32\1\0\1\32\11\0\1\32\11\0"+ - "\2\32\6\0\1\32\2\0\4\32\3\0\1\32\2\0"+ - "\2\32\1\0\3\32\5\0\1\32\1\0\2\32\2\0"+ - "\2\32\1\0\4\32\5\0\1\32\1\0\2\32\215\0"+ - "\1\32\40\0\1\30\4\0\1\30\11\0\1\30\22\0"+ - "\1\30\3\0\1\30\13\0\1\116\2\0\1\116\10\0"+ - "\1\30\12\0\4\116\45\0\1\30\21\0\1\30\26\0"+ - "\2\30\23\0\1\31\1\30\44\0\1\116\21\0\1\31"+ - "\46\0\1\31\11\0\1\116\15\0\4\30\2\0\2\30"+ - "\14\0\3\30\1\116\1\0\2\116\11\0\3\30\3\0"+ - "\1\30\1\0\1\116\4\0\1\116\2\30\5\0\4\116"+ - "\2\0\1\30\1\116\12\0\4\31\1\0\2\30\1\0"+ - "\1\116\7\0\1\30\23\0\1\30\4\0\1\30\6\0"+ - "\1\30\3\0\1\30\6\0\1\30\5\0\1\30\2\0"+ - "\2\30\1\0\17\30\2\0\1\30\13\0\7\30\2\0"+ - "\1\30\1\0\1\30\1\0\1\30\2\0\1\30\1\0"+ - "\1\30\1\0\1\30\1\0\1\30\4\0\1\116\1\0"+ - "\2\30\5\0\1\30\1\0\1\30\2\0\3\30\1\0"+ - "\1\30\7\0\1\30\1\0\1\30\26\0\1\30\6\0"+ - "\1\30\3\0\1\30\3\0\1\30\7\0\1\30\31\0"+ - "\20\30\5\0\3\30\3\0\1\30\3\0\2\30\2\0"+ - "\2\30\4\0\1\30\4\116\4\0\1\30\4\0\1\30"+ - "\2\0\1\30\4\0\1\30\1\0\1\30\1\0\1\30"+ - "\127\0\2\116\15\0\4\116\60\0\1\116\15\0\2\116"+ - "\10\0\2\116\1\0\1\116\1\0\1\116\11\0\1\116"+ - "\11\0\2\116\6\0\1\116\2\0\4\116\3\0\1\116"+ - "\2\0\2\116\1\0\3\116\5\0\1\116\1\0\2\116"+ - "\2\0\2\116\1\0\4\116\5\0\1\116\1\0\2\116"+ - "\215\0\1\117\37\0\1\215\21\0\1\216\2\0\1\217"+ - "\10\0\1\220\22\0\1\221\21\0\1\222\2\0\1\223"+ - "\41\0\1\115\16\0\1\117\1\0\1\117\3\0\1\62"+ - "\1\0\1\117\74\0\1\35\2\0\1\35\23\0\4\35"+ - "\211\0\1\35\102\0\1\35\44\0\1\35\1\0\2\35"+ - "\21\0\1\35\4\0\1\35\7\0\4\35\3\0\1\35"+ - "\22\0\1\35\166\0\1\35\215\0\4\35\155\0\2\35"+ - "\15\0\4\35\60\0\1\35\15\0\2\35\10\0\2\35"+ - "\1\0\1\35\1\0\1\35\11\0\1\35\11\0\2\35"+ - "\6\0\1\35\2\0\4\35\3\0\1\35\2\0\2\35"+ - "\1\0\3\35\5\0\1\35\1\0\2\35\2\0\2\35"+ - "\1\0\4\35\5\0\1\35\1\0\2\35\127\0\1\36"+ - "\2\0\1\36\23\0\4\36\211\0\1\36\102\0\1\36"+ - "\44\0\1\36\1\0\2\36\21\0\1\36\4\0\1\36"+ - "\7\0\4\36\3\0\1\36\22\0\1\36\166\0\1\36"+ - "\215\0\4\36\155\0\2\36\15\0\4\36\60\0\1\36"+ - "\15\0\2\36\10\0\2\36\1\0\1\36\1\0\1\36"+ - "\11\0\1\36\11\0\2\36\6\0\1\36\2\0\4\36"+ - "\3\0\1\36\2\0\2\36\1\0\3\36\5\0\1\36"+ - "\1\0\2\36\2\0\2\36\1\0\4\36\5\0\1\36"+ - "\1\0\2\36\45\0\1\30\4\0\1\30\11\0\1\30"+ - "\22\0\1\30\3\0\1\30\13\0\1\37\2\0\1\37"+ - "\10\0\1\30\12\0\4\37\45\0\1\30\21\0\1\30"+ - "\26\0\2\30\23\0\1\60\1\30\44\0\1\37\21\0"+ - "\1\60\46\0\1\60\11\0\1\37\15\0\4\30\2\0"+ - "\2\30\14\0\3\30\1\37\1\0\2\37\11\0\3\30"+ - "\3\0\1\30\1\0\1\37\4\0\1\37\2\30\5\0"+ - "\4\37\2\0\1\30\1\37\12\0\4\60\1\0\2\30"+ - "\1\0\1\37\7\0\1\30\23\0\1\30\4\0\1\30"+ + "\13\0\1\122\2\0\1\122\10\0\1\30\22\0\4\122"+ + "\35\0\1\30\26\0\1\30\26\0\2\30\23\0\1\31"+ + "\1\30\40\0\1\31\13\0\1\122\65\0\1\31\11\0"+ + "\1\122\15\0\4\30\2\0\2\30\14\0\3\30\1\122"+ + "\1\0\2\122\11\0\3\30\3\0\1\30\1\0\1\122"+ + "\4\0\1\122\2\30\1\0\4\31\1\0\2\30\5\0"+ + "\4\122\2\0\1\30\1\122\12\0\1\122\7\0\1\30"+ + "\30\0\1\30\4\0\1\30\6\0\1\30\3\0\1\30"+ + "\6\0\1\30\5\0\1\30\2\0\2\30\1\0\17\30"+ + "\2\0\1\30\13\0\7\30\2\0\1\30\1\0\1\30"+ + "\1\0\2\30\2\0\1\30\1\0\3\30\2\0\1\30"+ + "\1\0\1\30\1\0\1\30\1\0\1\30\4\0\1\122"+ + "\1\0\2\30\6\0\1\30\7\0\1\30\1\0\1\30"+ + "\33\0\1\30\6\0\1\30\3\0\1\30\3\0\1\30"+ + "\7\0\1\30\31\0\20\30\5\0\3\30\4\0\1\30"+ + "\6\0\1\30\3\0\2\30\2\0\2\30\4\0\1\30"+ + "\4\122\1\0\1\30\2\0\1\30\4\0\1\30\1\0"+ + "\1\30\1\0\1\30\134\0\2\122\25\0\4\122\55\0"+ + "\1\122\15\0\2\122\10\0\2\122\1\0\1\122\1\0"+ + "\1\122\11\0\1\122\11\0\2\122\6\0\1\122\2\0"+ + "\4\122\3\0\1\122\2\0\2\122\1\0\3\122\1\0"+ + "\2\122\1\0\1\122\10\0\1\122\1\0\2\122\2\0"+ + "\2\122\1\0\4\122\23\0\1\122\177\0\1\123\44\0"+ + "\1\260\21\0\1\261\2\0\1\262\10\0\1\263\22\0"+ + "\1\264\21\0\1\265\2\0\1\266\62\0\1\123\5\0"+ + "\1\111\1\0\1\123\77\0\1\35\2\0\1\35\33\0"+ + "\4\35\216\0\1\35\77\0\1\35\44\0\1\35\1\0"+ + "\2\35\21\0\1\35\4\0\1\35\17\0\4\35\3\0"+ + "\1\35\12\0\1\35\203\0\1\35\222\0\4\35\152\0"+ + "\2\35\25\0\4\35\55\0\1\35\15\0\2\35\10\0"+ + "\2\35\1\0\1\35\1\0\1\35\11\0\1\35\11\0"+ + "\2\35\6\0\1\35\2\0\4\35\3\0\1\35\2\0"+ + "\2\35\1\0\3\35\1\0\2\35\1\0\1\35\10\0"+ + "\1\35\1\0\2\35\2\0\2\35\1\0\4\35\23\0"+ + "\1\35\111\0\1\36\2\0\1\36\33\0\4\36\216\0"+ + "\1\36\77\0\1\36\44\0\1\36\1\0\2\36\21\0"+ + "\1\36\4\0\1\36\17\0\4\36\3\0\1\36\12\0"+ + "\1\36\203\0\1\36\222\0\4\36\152\0\2\36\25\0"+ + "\4\36\55\0\1\36\15\0\2\36\10\0\2\36\1\0"+ + "\1\36\1\0\1\36\11\0\1\36\11\0\2\36\6\0"+ + "\1\36\2\0\4\36\3\0\1\36\2\0\2\36\1\0"+ + "\3\36\1\0\2\36\1\0\1\36\10\0\1\36\1\0"+ + "\2\36\2\0\2\36\1\0\4\36\23\0\1\36\27\0"+ + "\1\30\4\0\1\30\11\0\1\30\22\0\1\30\3\0"+ + "\1\30\13\0\1\37\2\0\1\37\10\0\1\30\22\0"+ + "\4\37\35\0\1\30\26\0\1\30\26\0\2\30\23\0"+ + "\1\62\1\30\40\0\1\62\13\0\1\37\65\0\1\62"+ + "\11\0\1\37\15\0\4\30\2\0\2\30\14\0\3\30"+ + "\1\37\1\0\2\37\11\0\3\30\3\0\1\30\1\0"+ + "\1\37\4\0\1\37\2\30\1\0\4\62\1\0\2\30"+ + "\5\0\4\37\2\0\1\30\1\37\12\0\1\37\7\0"+ + "\1\30\30\0\1\30\4\0\1\30\6\0\1\30\3\0"+ + "\1\30\6\0\1\30\5\0\1\30\2\0\2\30\1\0"+ + "\17\30\2\0\1\30\13\0\7\30\2\0\1\30\1\0"+ + "\1\30\1\0\2\30\2\0\1\30\1\0\3\30\2\0"+ + "\1\30\1\0\1\30\1\0\1\30\1\0\1\30\4\0"+ + "\1\37\1\0\2\30\6\0\1\30\7\0\1\30\1\0"+ + "\1\30\33\0\1\30\6\0\1\30\3\0\1\30\3\0"+ + "\1\30\7\0\1\30\31\0\20\30\5\0\3\30\4\0"+ + "\1\30\6\0\1\30\3\0\2\30\2\0\2\30\4\0"+ + "\1\30\4\37\1\0\1\30\2\0\1\30\4\0\1\30"+ + "\1\0\1\30\1\0\1\30\134\0\2\37\25\0\4\37"+ + "\55\0\1\37\15\0\2\37\10\0\2\37\1\0\1\37"+ + "\1\0\1\37\11\0\1\37\11\0\2\37\6\0\1\37"+ + "\2\0\4\37\3\0\1\37\2\0\2\37\1\0\3\37"+ + "\1\0\2\37\1\0\1\37\10\0\1\37\1\0\2\37"+ + "\2\0\2\37\1\0\4\37\23\0\1\37\26\0\1\267"+ + "\21\0\1\270\2\0\1\271\10\0\1\272\22\0\1\273"+ + "\21\0\1\274\2\0\1\275\62\0\1\151\7\0\1\151"+ + "\4\0\1\276\10\0\1\30\4\0\1\30\11\0\1\30"+ + "\22\0\1\30\3\0\1\30\13\0\1\40\2\0\1\40"+ + "\10\0\1\30\22\0\4\40\35\0\1\30\26\0\1\30"+ + "\26\0\2\30\23\0\1\62\1\30\40\0\1\62\13\0"+ + "\1\40\65\0\1\62\11\0\1\40\15\0\4\30\2\0"+ + "\2\30\14\0\3\30\1\40\1\0\2\40\11\0\3\30"+ + "\3\0\1\30\1\0\1\40\4\0\1\40\2\30\1\0"+ + "\4\62\1\0\2\30\5\0\4\40\2\0\1\30\1\40"+ + "\12\0\1\40\7\0\1\30\30\0\1\30\4\0\1\30"+ "\6\0\1\30\3\0\1\30\6\0\1\30\5\0\1\30"+ "\2\0\2\30\1\0\17\30\2\0\1\30\13\0\7\30"+ - "\2\0\1\30\1\0\1\30\1\0\1\30\2\0\1\30"+ - "\1\0\1\30\1\0\1\30\1\0\1\30\4\0\1\37"+ - "\1\0\2\30\5\0\1\30\1\0\1\30\2\0\3\30"+ - "\1\0\1\30\7\0\1\30\1\0\1\30\26\0\1\30"+ - "\6\0\1\30\3\0\1\30\3\0\1\30\7\0\1\30"+ - "\31\0\20\30\5\0\3\30\3\0\1\30\3\0\2\30"+ - "\2\0\2\30\4\0\1\30\4\37\4\0\1\30\4\0"+ - "\1\30\2\0\1\30\4\0\1\30\1\0\1\30\1\0"+ - "\1\30\127\0\2\37\15\0\4\37\60\0\1\37\15\0"+ - "\2\37\10\0\2\37\1\0\1\37\1\0\1\37\11\0"+ - "\1\37\11\0\2\37\6\0\1\37\2\0\4\37\3\0"+ - "\1\37\2\0\2\37\1\0\3\37\5\0\1\37\1\0"+ - "\2\37\2\0\2\37\1\0\4\37\5\0\1\37\1\0"+ - "\2\37\45\0\1\30\4\0\1\30\11\0\1\30\22\0"+ - "\1\30\3\0\1\30\13\0\1\60\2\0\1\60\10\0"+ - "\1\30\12\0\4\60\45\0\1\30\21\0\1\30\26\0"+ - "\2\30\23\0\1\60\1\30\44\0\1\60\21\0\1\60"+ - "\46\0\1\60\11\0\1\60\15\0\4\30\2\0\2\30"+ - "\14\0\3\30\1\60\1\0\2\60\11\0\3\30\3\0"+ - "\1\30\1\0\1\60\4\0\1\60\2\30\5\0\4\60"+ - "\2\0\1\30\1\60\12\0\4\60\1\0\2\30\1\0"+ - "\1\60\7\0\1\30\23\0\1\30\4\0\1\30\6\0"+ - "\1\30\3\0\1\30\6\0\1\30\5\0\1\30\2\0"+ - "\2\30\1\0\17\30\2\0\1\30\13\0\7\30\2\0"+ - "\1\30\1\0\1\30\1\0\1\30\2\0\1\30\1\0"+ - "\1\30\1\0\1\30\1\0\1\30\4\0\1\60\1\0"+ - "\2\30\5\0\1\30\1\0\1\30\2\0\3\30\1\0"+ - "\1\30\7\0\1\30\1\0\1\30\26\0\1\30\6\0"+ - "\1\30\3\0\1\30\3\0\1\30\7\0\1\30\31\0"+ - "\20\30\5\0\3\30\3\0\1\30\3\0\2\30\2\0"+ - "\2\30\4\0\1\30\4\60\4\0\1\30\4\0\1\30"+ - "\2\0\1\30\4\0\1\30\1\0\1\30\1\0\1\30"+ - "\127\0\2\60\15\0\4\60\60\0\1\60\15\0\2\60"+ - "\10\0\2\60\1\0\1\60\1\0\1\60\11\0\1\60"+ - "\11\0\2\60\6\0\1\60\2\0\4\60\3\0\1\60"+ - "\2\0\2\60\1\0\3\60\5\0\1\60\1\0\2\60"+ - "\2\0\2\60\1\0\4\60\5\0\1\60\1\0\2\60"+ - "\44\0\1\224\1\0\1\225\17\0\1\226\2\0\1\227"+ - "\4\0\1\230\3\0\1\231\22\0\1\232\21\0\1\233"+ - "\2\0\1\234\60\0\1\154\1\60\6\0\1\154\12\0"+ - "\1\30\4\0\1\30\11\0\1\30\22\0\1\30\3\0"+ - "\1\30\13\0\1\61\2\0\1\61\10\0\1\30\12\0"+ - "\4\61\45\0\1\30\24\0\1\30\3\0\4\30\1\0"+ - "\1\30\4\0\1\30\1\0\2\30\2\0\2\30\2\0"+ - "\3\30\1\0\1\30\1\0\1\30\2\0\4\30\1\0"+ - "\3\30\1\0\1\30\1\0\3\30\1\0\2\30\1\0"+ - "\4\30\1\0\2\30\2\0\10\30\1\0\2\30\1\0"+ - "\11\30\1\0\10\30\1\0\13\30\2\0\1\30\1\0"+ - "\1\30\1\0\2\30\2\0\1\30\1\0\1\30\3\0"+ - "\1\30\17\0\1\30\26\0\2\30\24\0\1\30\44\0"+ - "\1\61\102\0\1\61\15\0\4\30\2\0\2\30\14\0"+ - "\3\30\1\61\1\0\2\61\11\0\3\30\3\0\1\30"+ - "\1\0\1\61\4\0\1\61\2\30\5\0\4\61\2\0"+ - "\1\30\1\61\17\0\2\30\1\0\1\61\7\0\1\30"+ - "\37\0\1\30\3\0\2\30\12\0\2\30\1\0\3\30"+ - "\7\0\1\30\6\0\2\30\1\0\2\30\6\0\1\30"+ - "\4\0\2\30\2\0\2\30\5\0\3\30\10\0\1\30"+ - "\16\0\1\30\7\0\1\30\7\0\1\30\23\0\1\30"+ - "\4\0\1\30\6\0\1\30\3\0\1\30\6\0\1\30"+ - "\5\0\1\30\2\0\2\30\1\0\17\30\2\0\1\30"+ - "\13\0\7\30\2\0\1\30\1\0\1\30\1\0\1\30"+ - "\2\0\1\30\1\0\1\30\1\0\1\30\1\0\1\30"+ - "\4\0\1\61\1\0\2\30\5\0\1\30\1\0\1\30"+ - "\2\0\3\30\1\0\1\30\7\0\1\30\1\0\1\30"+ - "\26\0\1\30\6\0\1\30\3\0\1\30\3\0\1\30"+ - "\7\0\1\30\31\0\20\30\5\0\3\30\3\0\1\30"+ - "\3\0\2\30\2\0\2\30\4\0\1\30\4\61\4\0"+ - "\1\30\4\0\1\30\2\0\1\30\4\0\1\30\1\0"+ - "\1\30\1\0\1\30\127\0\2\61\15\0\4\61\60\0"+ - "\1\61\15\0\2\61\10\0\2\61\1\0\1\61\1\0"+ - "\1\61\11\0\1\61\11\0\2\61\6\0\1\61\2\0"+ - "\4\61\3\0\1\61\2\0\2\61\1\0\3\61\5\0"+ - "\1\61\1\0\2\61\2\0\2\61\1\0\4\61\5\0"+ - "\1\61\1\0\2\61\45\0\1\30\4\0\1\30\11\0"+ + "\2\0\1\30\1\0\1\30\1\0\2\30\2\0\1\30"+ + "\1\0\3\30\2\0\1\30\1\0\1\30\1\0\1\30"+ + "\1\0\1\30\4\0\1\40\1\0\2\30\6\0\1\30"+ + "\7\0\1\30\1\0\1\30\33\0\1\30\6\0\1\30"+ + "\3\0\1\30\3\0\1\30\7\0\1\30\31\0\20\30"+ + "\5\0\3\30\4\0\1\30\6\0\1\30\3\0\2\30"+ + "\2\0\2\30\4\0\1\30\4\40\1\0\1\30\2\0"+ + "\1\30\4\0\1\30\1\0\1\30\1\0\1\30\134\0"+ + "\2\40\25\0\4\40\55\0\1\40\15\0\2\40\10\0"+ + "\2\40\1\0\1\40\1\0\1\40\11\0\1\40\11\0"+ + "\2\40\6\0\1\40\2\0\4\40\3\0\1\40\2\0"+ + "\2\40\1\0\3\40\1\0\2\40\1\0\1\40\10\0"+ + "\1\40\1\0\2\40\2\0\2\40\1\0\4\40\23\0"+ + "\1\40\111\0\1\41\2\0\1\41\33\0\4\41\216\0"+ + "\1\41\77\0\1\41\44\0\1\41\1\0\2\41\21\0"+ + "\1\41\4\0\1\41\17\0\4\41\3\0\1\41\12\0"+ + "\1\41\203\0\1\41\222\0\4\41\152\0\2\41\25\0"+ + "\4\41\55\0\1\41\15\0\2\41\10\0\2\41\1\0"+ + "\1\41\1\0\1\41\11\0\1\41\11\0\2\41\6\0"+ + "\1\41\2\0\4\41\3\0\1\41\2\0\2\41\1\0"+ + "\3\41\1\0\2\41\1\0\1\41\10\0\1\41\1\0"+ + "\2\41\2\0\2\41\1\0\4\41\23\0\1\41\165\0"+ + "\1\277\26\0\2\277\27\0\1\30\4\0\1\30\11\0"+ "\1\30\22\0\1\30\3\0\1\30\13\0\1\62\2\0"+ - "\1\62\10\0\1\30\12\0\4\62\45\0\1\30\21\0"+ - "\1\30\26\0\2\30\23\0\1\60\1\30\44\0\1\62"+ - "\21\0\1\60\46\0\1\60\11\0\1\62\15\0\4\30"+ + "\1\62\10\0\1\30\22\0\4\62\35\0\1\30\26\0"+ + "\1\30\26\0\2\30\23\0\1\62\1\30\40\0\1\62"+ + "\13\0\1\62\65\0\1\62\11\0\1\62\15\0\4\30"+ "\2\0\2\30\14\0\3\30\1\62\1\0\2\62\11\0"+ "\3\30\3\0\1\30\1\0\1\62\4\0\1\62\2\30"+ - "\5\0\4\62\2\0\1\30\1\62\12\0\4\60\1\0"+ - "\2\30\1\0\1\62\7\0\1\30\23\0\1\30\4\0"+ + "\1\0\4\62\1\0\2\30\5\0\4\62\2\0\1\30"+ + "\1\62\12\0\1\62\7\0\1\30\30\0\1\30\4\0"+ "\1\30\6\0\1\30\3\0\1\30\6\0\1\30\5\0"+ "\1\30\2\0\2\30\1\0\17\30\2\0\1\30\13\0"+ - "\7\30\2\0\1\30\1\0\1\30\1\0\1\30\2\0"+ - "\1\30\1\0\1\30\1\0\1\30\1\0\1\30\4\0"+ - "\1\62\1\0\2\30\5\0\1\30\1\0\1\30\2\0"+ - "\3\30\1\0\1\30\7\0\1\30\1\0\1\30\26\0"+ + "\7\30\2\0\1\30\1\0\1\30\1\0\2\30\2\0"+ + "\1\30\1\0\3\30\2\0\1\30\1\0\1\30\1\0"+ + "\1\30\1\0\1\30\4\0\1\62\1\0\2\30\6\0"+ + "\1\30\7\0\1\30\1\0\1\30\33\0\1\30\6\0"+ + "\1\30\3\0\1\30\3\0\1\30\7\0\1\30\31\0"+ + "\20\30\5\0\3\30\4\0\1\30\6\0\1\30\3\0"+ + "\2\30\2\0\2\30\4\0\1\30\4\62\1\0\1\30"+ + "\2\0\1\30\4\0\1\30\1\0\1\30\1\0\1\30"+ + "\134\0\2\62\25\0\4\62\55\0\1\62\15\0\2\62"+ + "\10\0\2\62\1\0\1\62\1\0\1\62\11\0\1\62"+ + "\11\0\2\62\6\0\1\62\2\0\4\62\3\0\1\62"+ + "\2\0\2\62\1\0\3\62\1\0\2\62\1\0\1\62"+ + "\10\0\1\62\1\0\2\62\2\0\2\62\1\0\4\62"+ + "\23\0\1\62\26\0\1\300\1\0\1\301\17\0\1\302"+ + "\2\0\1\303\4\0\1\304\3\0\1\305\22\0\1\306"+ + "\21\0\1\307\2\0\1\310\62\0\1\200\1\62\2\0"+ + "\3\200\1\0\1\200\2\0\1\200\4\0\1\42\1\0"+ + "\1\43\2\0\1\311\1\0\1\45\4\0\1\46\1\0"+ + "\1\47\1\0\1\50\2\0\1\51\3\0\1\312\2\0"+ + "\1\313\4\0\1\54\3\0\1\314\17\0\1\56\2\0"+ + "\1\315\21\0\1\316\2\0\1\317\41\0\1\121\17\0"+ + "\1\30\1\201\1\62\1\123\1\0\2\200\1\201\1\0"+ + "\1\201\2\0\1\200\1\0\1\37\1\30\7\0\1\30"+ + "\4\0\1\30\11\0\1\30\22\0\1\30\3\0\1\30"+ + "\13\0\1\63\2\0\1\63\10\0\1\30\22\0\4\63"+ + "\35\0\1\30\31\0\1\30\3\0\4\30\1\0\1\30"+ + "\4\0\1\30\1\0\2\30\2\0\2\30\2\0\3\30"+ + "\1\0\1\30\1\0\1\30\2\0\4\30\1\0\3\30"+ + "\1\0\1\30\1\0\3\30\1\0\2\30\1\0\4\30"+ + "\1\0\2\30\2\0\10\30\1\0\2\30\1\0\10\30"+ + "\2\0\7\30\1\0\10\30\1\0\6\30\1\0\1\30"+ + "\1\0\2\30\2\0\1\30\1\0\1\30\3\0\3\30"+ + "\22\0\1\30\26\0\2\30\24\0\1\30\54\0\1\63"+ + "\77\0\1\63\15\0\4\30\2\0\2\30\14\0\3\30"+ + "\1\63\1\0\2\63\11\0\3\30\3\0\1\30\1\0"+ + "\1\63\4\0\1\63\2\30\6\0\2\30\5\0\4\63"+ + "\2\0\1\30\1\63\12\0\1\63\7\0\1\30\44\0"+ + "\1\30\3\0\2\30\12\0\2\30\1\0\3\30\7\0"+ + "\1\30\6\0\2\30\1\0\2\30\6\0\1\30\4\0"+ + "\2\30\2\0\2\30\5\0\3\30\2\0\1\30\15\0"+ + "\1\30\16\0\1\30\7\0\1\30\30\0\1\30\4\0"+ + "\1\30\6\0\1\30\3\0\1\30\6\0\1\30\5\0"+ + "\1\30\2\0\2\30\1\0\17\30\2\0\1\30\13\0"+ + "\7\30\2\0\1\30\1\0\1\30\1\0\2\30\2\0"+ + "\1\30\1\0\3\30\2\0\1\30\1\0\1\30\1\0"+ + "\1\30\1\0\1\30\4\0\1\63\1\0\2\30\6\0"+ + "\1\30\7\0\1\30\1\0\1\30\33\0\1\30\6\0"+ + "\1\30\3\0\1\30\3\0\1\30\7\0\1\30\31\0"+ + "\20\30\5\0\3\30\4\0\1\30\6\0\1\30\3\0"+ + "\2\30\2\0\2\30\4\0\1\30\4\63\1\0\1\30"+ + "\2\0\1\30\4\0\1\30\1\0\1\30\1\0\1\30"+ + "\134\0\2\63\25\0\4\63\55\0\1\63\15\0\2\63"+ + "\10\0\2\63\1\0\1\63\1\0\1\63\11\0\1\63"+ + "\11\0\2\63\6\0\1\63\2\0\4\63\3\0\1\63"+ + "\2\0\2\63\1\0\3\63\1\0\2\63\1\0\1\63"+ + "\10\0\1\63\1\0\2\63\2\0\2\63\1\0\4\63"+ + "\23\0\1\63\27\0\1\30\4\0\1\30\11\0\1\30"+ + "\22\0\1\30\3\0\1\30\13\0\1\64\2\0\1\64"+ + "\10\0\1\30\22\0\4\64\35\0\1\30\26\0\1\30"+ + "\26\0\2\30\23\0\1\62\1\30\40\0\1\62\13\0"+ + "\1\64\65\0\1\62\11\0\1\64\15\0\4\30\2\0"+ + "\2\30\14\0\3\30\1\64\1\0\2\64\11\0\3\30"+ + "\3\0\1\30\1\0\1\64\4\0\1\64\2\30\1\0"+ + "\4\62\1\0\2\30\5\0\4\64\2\0\1\30\1\64"+ + "\12\0\1\64\7\0\1\30\30\0\1\30\4\0\1\30"+ + "\6\0\1\30\3\0\1\30\6\0\1\30\5\0\1\30"+ + "\2\0\2\30\1\0\17\30\2\0\1\30\13\0\7\30"+ + "\2\0\1\30\1\0\1\30\1\0\2\30\2\0\1\30"+ + "\1\0\3\30\2\0\1\30\1\0\1\30\1\0\1\30"+ + "\1\0\1\30\4\0\1\64\1\0\2\30\6\0\1\30"+ + "\7\0\1\30\1\0\1\30\33\0\1\30\6\0\1\30"+ + "\3\0\1\30\3\0\1\30\7\0\1\30\31\0\20\30"+ + "\5\0\3\30\4\0\1\30\6\0\1\30\3\0\2\30"+ + "\2\0\2\30\4\0\1\30\4\64\1\0\1\30\2\0"+ + "\1\30\4\0\1\30\1\0\1\30\1\0\1\30\134\0"+ + "\2\64\25\0\4\64\55\0\1\64\15\0\2\64\10\0"+ + "\2\64\1\0\1\64\1\0\1\64\11\0\1\64\11\0"+ + "\2\64\6\0\1\64\2\0\4\64\3\0\1\64\2\0"+ + "\2\64\1\0\3\64\1\0\2\64\1\0\1\64\10\0"+ + "\1\64\1\0\2\64\2\0\2\64\1\0\4\64\23\0"+ + "\1\64\111\0\1\76\2\0\1\76\33\0\4\76\102\0"+ + "\1\31\104\0\1\31\146\0\1\31\41\0\1\31\13\0"+ + "\1\76\65\0\1\31\11\0\1\76\44\0\1\76\1\0"+ + "\2\76\21\0\1\76\4\0\1\76\3\0\4\31\10\0"+ + "\4\76\3\0\1\76\12\0\1\76\164\0\2\31\233\0"+ + "\1\76\222\0\4\76\152\0\2\76\25\0\4\76\55\0"+ + "\1\76\15\0\2\76\10\0\2\76\1\0\1\76\1\0"+ + "\1\76\11\0\1\76\11\0\2\76\6\0\1\76\2\0"+ + "\4\76\3\0\1\76\2\0\2\76\1\0\3\76\1\0"+ + "\2\76\1\0\1\76\10\0\1\76\1\0\2\76\2\0"+ + "\2\76\1\0\4\76\23\0\1\76\27\0\1\30\4\0"+ + "\1\30\11\0\1\30\22\0\1\30\3\0\1\30\13\0"+ + "\1\77\2\0\1\77\10\0\1\30\22\0\4\77\35\0"+ + "\1\30\26\0\1\30\26\0\2\30\23\0\1\31\1\30"+ + "\40\0\1\31\13\0\1\77\65\0\1\31\11\0\1\77"+ + "\15\0\4\30\2\0\2\30\14\0\3\30\1\77\1\0"+ + "\2\77\11\0\3\30\3\0\1\30\1\0\1\77\4\0"+ + "\1\77\2\30\1\0\4\31\1\0\2\30\5\0\4\77"+ + "\2\0\1\30\1\77\12\0\1\77\7\0\1\30\30\0"+ + "\1\30\4\0\1\30\6\0\1\30\3\0\1\30\6\0"+ + "\1\30\5\0\1\30\2\0\2\30\1\0\17\30\2\0"+ + "\1\30\13\0\7\30\2\0\1\30\1\0\1\30\1\0"+ + "\2\30\2\0\1\30\1\0\3\30\2\0\1\30\1\0"+ + "\1\30\1\0\1\30\1\0\1\30\4\0\1\77\1\0"+ + "\2\30\6\0\1\30\7\0\1\30\1\0\1\30\33\0"+ "\1\30\6\0\1\30\3\0\1\30\3\0\1\30\7\0"+ - "\1\30\31\0\20\30\5\0\3\30\3\0\1\30\3\0"+ - "\2\30\2\0\2\30\4\0\1\30\4\62\4\0\1\30"+ - "\4\0\1\30\2\0\1\30\4\0\1\30\1\0\1\30"+ - "\1\0\1\30\127\0\2\62\15\0\4\62\60\0\1\62"+ - "\15\0\2\62\10\0\2\62\1\0\1\62\1\0\1\62"+ - "\11\0\1\62\11\0\2\62\6\0\1\62\2\0\4\62"+ - "\3\0\1\62\2\0\2\62\1\0\3\62\5\0\1\62"+ - "\1\0\2\62\2\0\2\62\1\0\4\62\5\0\1\62"+ - "\1\0\2\62\127\0\1\74\2\0\1\74\23\0\4\74"+ - "\105\0\1\31\132\0\1\31\113\0\1\31\45\0\1\74"+ - "\21\0\1\31\46\0\1\31\11\0\1\74\44\0\1\74"+ - "\1\0\2\74\21\0\1\74\4\0\1\74\7\0\4\74"+ - "\3\0\1\74\12\0\4\31\4\0\1\74\205\0\2\31"+ - "\170\0\1\74\215\0\4\74\155\0\2\74\15\0\4\74"+ - "\60\0\1\74\15\0\2\74\10\0\2\74\1\0\1\74"+ - "\1\0\1\74\11\0\1\74\11\0\2\74\6\0\1\74"+ - "\2\0\4\74\3\0\1\74\2\0\2\74\1\0\3\74"+ - "\5\0\1\74\1\0\2\74\2\0\2\74\1\0\4\74"+ - "\5\0\1\74\1\0\2\74\45\0\1\30\4\0\1\30"+ - "\11\0\1\30\22\0\1\30\3\0\1\30\13\0\1\75"+ - "\2\0\1\75\10\0\1\30\12\0\4\75\45\0\1\30"+ - "\21\0\1\30\26\0\2\30\23\0\1\31\1\30\44\0"+ - "\1\75\21\0\1\31\46\0\1\31\11\0\1\75\15\0"+ - "\4\30\2\0\2\30\14\0\3\30\1\75\1\0\2\75"+ - "\11\0\3\30\3\0\1\30\1\0\1\75\4\0\1\75"+ - "\2\30\5\0\4\75\2\0\1\30\1\75\12\0\4\31"+ - "\1\0\2\30\1\0\1\75\7\0\1\30\23\0\1\30"+ - "\4\0\1\30\6\0\1\30\3\0\1\30\6\0\1\30"+ - "\5\0\1\30\2\0\2\30\1\0\17\30\2\0\1\30"+ - "\13\0\7\30\2\0\1\30\1\0\1\30\1\0\1\30"+ + "\1\30\31\0\20\30\5\0\3\30\4\0\1\30\6\0"+ + "\1\30\3\0\2\30\2\0\2\30\4\0\1\30\4\77"+ + "\1\0\1\30\2\0\1\30\4\0\1\30\1\0\1\30"+ + "\1\0\1\30\134\0\2\77\25\0\4\77\55\0\1\77"+ + "\15\0\2\77\10\0\2\77\1\0\1\77\1\0\1\77"+ + "\11\0\1\77\11\0\2\77\6\0\1\77\2\0\4\77"+ + "\3\0\1\77\2\0\2\77\1\0\3\77\1\0\2\77"+ + "\1\0\1\77\10\0\1\77\1\0\2\77\2\0\2\77"+ + "\1\0\4\77\23\0\1\77\111\0\1\110\2\0\1\110"+ + "\33\0\4\110\216\0\1\110\77\0\1\110\44\0\1\110"+ + "\1\0\2\110\21\0\1\110\4\0\1\110\17\0\4\110"+ + "\3\0\1\110\12\0\1\110\203\0\1\110\222\0\4\110"+ + "\152\0\2\110\25\0\4\110\55\0\1\110\15\0\2\110"+ + "\10\0\2\110\1\0\1\110\1\0\1\110\11\0\1\110"+ + "\11\0\2\110\6\0\1\110\2\0\4\110\3\0\1\110"+ + "\2\0\2\110\1\0\3\110\1\0\2\110\1\0\1\110"+ + "\10\0\1\110\1\0\2\110\2\0\2\110\1\0\4\110"+ + "\23\0\1\110\27\0\1\30\4\0\1\30\11\0\1\30"+ + "\22\0\1\30\3\0\1\30\13\0\1\111\2\0\1\111"+ + "\10\0\1\30\22\0\4\111\35\0\1\30\26\0\1\30"+ + "\26\0\2\30\23\0\1\62\1\30\40\0\1\62\13\0"+ + "\1\111\65\0\1\62\11\0\1\111\15\0\4\30\2\0"+ + "\2\30\14\0\3\30\1\111\1\0\2\111\11\0\3\30"+ + "\3\0\1\30\1\0\1\111\4\0\1\111\2\30\1\0"+ + "\4\62\1\0\2\30\5\0\4\111\2\0\1\30\1\111"+ + "\12\0\1\111\7\0\1\30\30\0\1\30\4\0\1\30"+ + "\6\0\1\30\3\0\1\30\6\0\1\30\5\0\1\30"+ + "\2\0\2\30\1\0\17\30\2\0\1\30\13\0\7\30"+ + "\2\0\1\30\1\0\1\30\1\0\2\30\2\0\1\30"+ + "\1\0\3\30\2\0\1\30\1\0\1\30\1\0\1\30"+ + "\1\0\1\30\4\0\1\111\1\0\2\30\6\0\1\30"+ + "\7\0\1\30\1\0\1\30\33\0\1\30\6\0\1\30"+ + "\3\0\1\30\3\0\1\30\7\0\1\30\31\0\20\30"+ + "\5\0\3\30\4\0\1\30\6\0\1\30\3\0\2\30"+ + "\2\0\2\30\4\0\1\30\4\111\1\0\1\30\2\0"+ + "\1\30\4\0\1\30\1\0\1\30\1\0\1\30\134\0"+ + "\2\111\25\0\4\111\55\0\1\111\15\0\2\111\10\0"+ + "\2\111\1\0\1\111\1\0\1\111\11\0\1\111\11\0"+ + "\2\111\6\0\1\111\2\0\4\111\3\0\1\111\2\0"+ + "\2\111\1\0\3\111\1\0\2\111\1\0\1\111\10\0"+ + "\1\111\1\0\2\111\2\0\2\111\1\0\4\111\23\0"+ + "\1\111\111\0\1\123\2\0\1\123\33\0\4\123\216\0"+ + "\1\123\77\0\1\123\44\0\1\123\1\0\2\123\21\0"+ + "\1\123\4\0\1\123\17\0\4\123\3\0\1\123\12\0"+ + "\1\123\203\0\1\123\222\0\4\123\152\0\2\123\25\0"+ + "\4\123\55\0\1\123\15\0\2\123\10\0\2\123\1\0"+ + "\1\123\1\0\1\123\11\0\1\123\11\0\2\123\6\0"+ + "\1\123\2\0\4\123\3\0\1\123\2\0\2\123\1\0"+ + "\3\123\1\0\2\123\1\0\1\123\10\0\1\123\1\0"+ + "\2\123\2\0\2\123\1\0\4\123\23\0\1\123\111\0"+ + "\1\151\2\0\1\151\33\0\4\151\216\0\1\151\77\0"+ + "\1\151\44\0\1\151\1\0\2\151\21\0\1\151\4\0"+ + "\1\151\17\0\4\151\3\0\1\151\12\0\1\151\203\0"+ + "\1\151\222\0\4\151\152\0\2\151\25\0\4\151\55\0"+ + "\1\151\15\0\2\151\10\0\2\151\1\0\1\151\1\0"+ + "\1\151\11\0\1\151\11\0\2\151\6\0\1\151\2\0"+ + "\4\151\3\0\1\151\2\0\2\151\1\0\3\151\1\0"+ + "\2\151\1\0\1\151\10\0\1\151\1\0\2\151\2\0"+ + "\2\151\1\0\4\151\23\0\1\151\21\0\1\42\1\0"+ + "\1\43\2\0\1\320\1\0\1\45\4\0\1\46\1\0"+ + "\1\47\1\0\1\50\2\0\1\51\3\0\1\321\2\0"+ + "\1\322\4\0\1\54\3\0\1\323\17\0\1\56\2\0"+ + "\1\324\21\0\1\325\2\0\1\326\61\0\1\30\1\276"+ + "\1\62\4\0\1\111\1\0\1\276\4\0\1\37\1\30"+ + "\6\0\1\327\21\0\1\330\2\0\1\331\10\0\1\332"+ + "\22\0\1\333\21\0\1\334\2\0\1\335\55\0\1\170"+ + "\4\0\1\277\7\0\1\277\77\0\1\200\2\0\1\200"+ + "\33\0\4\200\102\0\1\62\104\0\1\62\146\0\1\62"+ + "\41\0\1\62\13\0\1\200\65\0\1\62\11\0\1\200"+ + "\44\0\1\200\1\0\2\200\21\0\1\200\4\0\1\200"+ + "\3\0\4\62\10\0\4\200\3\0\1\200\12\0\1\200"+ + "\164\0\2\62\233\0\1\200\222\0\4\200\152\0\2\200"+ + "\25\0\4\200\55\0\1\200\15\0\2\200\10\0\2\200"+ + "\1\0\1\200\1\0\1\200\11\0\1\200\11\0\2\200"+ + "\6\0\1\200\2\0\4\200\3\0\1\200\2\0\2\200"+ + "\1\0\3\200\1\0\2\200\1\0\1\200\10\0\1\200"+ + "\1\0\2\200\2\0\2\200\1\0\4\200\23\0\1\200"+ + "\27\0\1\30\4\0\1\30\11\0\1\30\22\0\1\30"+ + "\3\0\1\30\13\0\1\201\2\0\1\201\10\0\1\30"+ + "\22\0\4\201\35\0\1\30\26\0\1\30\26\0\2\30"+ + "\23\0\1\62\1\30\40\0\1\62\13\0\1\201\65\0"+ + "\1\62\11\0\1\201\15\0\4\30\2\0\2\30\14\0"+ + "\3\30\1\201\1\0\2\201\11\0\3\30\3\0\1\30"+ + "\1\0\1\201\4\0\1\201\2\30\1\0\4\62\1\0"+ + "\2\30\5\0\4\201\2\0\1\30\1\201\12\0\1\201"+ + "\7\0\1\30\30\0\1\30\4\0\1\30\6\0\1\30"+ + "\3\0\1\30\6\0\1\30\5\0\1\30\2\0\2\30"+ + "\1\0\17\30\2\0\1\30\13\0\7\30\2\0\1\30"+ + "\1\0\1\30\1\0\2\30\2\0\1\30\1\0\3\30"+ "\2\0\1\30\1\0\1\30\1\0\1\30\1\0\1\30"+ - "\4\0\1\75\1\0\2\30\5\0\1\30\1\0\1\30"+ - "\2\0\3\30\1\0\1\30\7\0\1\30\1\0\1\30"+ - "\26\0\1\30\6\0\1\30\3\0\1\30\3\0\1\30"+ - "\7\0\1\30\31\0\20\30\5\0\3\30\3\0\1\30"+ - "\3\0\2\30\2\0\2\30\4\0\1\30\4\75\4\0"+ - "\1\30\4\0\1\30\2\0\1\30\4\0\1\30\1\0"+ - "\1\30\1\0\1\30\127\0\2\75\15\0\4\75\60\0"+ - "\1\75\15\0\2\75\10\0\2\75\1\0\1\75\1\0"+ - "\1\75\11\0\1\75\11\0\2\75\6\0\1\75\2\0"+ - "\4\75\3\0\1\75\2\0\2\75\1\0\3\75\5\0"+ - "\1\75\1\0\2\75\2\0\2\75\1\0\4\75\5\0"+ - "\1\75\1\0\2\75\127\0\1\117\2\0\1\117\23\0"+ - "\4\117\211\0\1\117\102\0\1\117\44\0\1\117\1\0"+ - "\2\117\21\0\1\117\4\0\1\117\7\0\4\117\3\0"+ - "\1\117\22\0\1\117\166\0\1\117\215\0\4\117\155\0"+ - "\2\117\15\0\4\117\60\0\1\117\15\0\2\117\10\0"+ - "\2\117\1\0\1\117\1\0\1\117\11\0\1\117\11\0"+ - "\2\117\6\0\1\117\2\0\4\117\3\0\1\117\2\0"+ - "\2\117\1\0\3\117\5\0\1\117\1\0\2\117\2\0"+ - "\2\117\1\0\4\117\5\0\1\117\1\0\2\117\127\0"+ - "\1\154\2\0\1\154\23\0\4\154\105\0\1\60\132\0"+ - "\1\60\113\0\1\60\45\0\1\154\21\0\1\60\46\0"+ - "\1\60\11\0\1\154\44\0\1\154\1\0\2\154\21\0"+ - "\1\154\4\0\1\154\7\0\4\154\3\0\1\154\12\0"+ - "\4\60\4\0\1\154\205\0\2\60\170\0\1\154\215\0"+ - "\4\154\155\0\2\154\15\0\4\154\60\0\1\154\15\0"+ - "\2\154\10\0\2\154\1\0\1\154\1\0\1\154\11\0"+ - "\1\154\11\0\2\154\6\0\1\154\2\0\4\154\3\0"+ - "\1\154\2\0\2\154\1\0\3\154\5\0\1\154\1\0"+ - "\2\154\2\0\2\154\1\0\4\154\5\0\1\154\1\0"+ - "\2\154\36\0"; + "\4\0\1\201\1\0\2\30\6\0\1\30\7\0\1\30"+ + "\1\0\1\30\33\0\1\30\6\0\1\30\3\0\1\30"+ + "\3\0\1\30\7\0\1\30\31\0\20\30\5\0\3\30"+ + "\4\0\1\30\6\0\1\30\3\0\2\30\2\0\2\30"+ + "\4\0\1\30\4\201\1\0\1\30\2\0\1\30\4\0"+ + "\1\30\1\0\1\30\1\0\1\30\134\0\2\201\25\0"+ + "\4\201\55\0\1\201\15\0\2\201\10\0\2\201\1\0"+ + "\1\201\1\0\1\201\11\0\1\201\11\0\2\201\6\0"+ + "\1\201\2\0\4\201\3\0\1\201\2\0\2\201\1\0"+ + "\3\201\1\0\2\201\1\0\1\201\10\0\1\201\1\0"+ + "\2\201\2\0\2\201\1\0\4\201\23\0\1\201\27\0"+ + "\1\30\4\0\1\30\11\0\1\30\22\0\1\30\3\0"+ + "\1\30\13\0\1\276\2\0\1\276\10\0\1\30\22\0"+ + "\4\276\35\0\1\30\26\0\1\30\26\0\2\30\23\0"+ + "\1\62\1\30\40\0\1\62\13\0\1\276\65\0\1\62"+ + "\11\0\1\276\15\0\4\30\2\0\2\30\14\0\3\30"+ + "\1\276\1\0\2\276\11\0\3\30\3\0\1\30\1\0"+ + "\1\276\4\0\1\276\2\30\1\0\4\62\1\0\2\30"+ + "\5\0\4\276\2\0\1\30\1\276\12\0\1\276\7\0"+ + "\1\30\30\0\1\30\4\0\1\30\6\0\1\30\3\0"+ + "\1\30\6\0\1\30\5\0\1\30\2\0\2\30\1\0"+ + "\17\30\2\0\1\30\13\0\7\30\2\0\1\30\1\0"+ + "\1\30\1\0\2\30\2\0\1\30\1\0\3\30\2\0"+ + "\1\30\1\0\1\30\1\0\1\30\1\0\1\30\4\0"+ + "\1\276\1\0\2\30\6\0\1\30\7\0\1\30\1\0"+ + "\1\30\33\0\1\30\6\0\1\30\3\0\1\30\3\0"+ + "\1\30\7\0\1\30\31\0\20\30\5\0\3\30\4\0"+ + "\1\30\6\0\1\30\3\0\2\30\2\0\2\30\4\0"+ + "\1\30\4\276\1\0\1\30\2\0\1\30\4\0\1\30"+ + "\1\0\1\30\1\0\1\30\134\0\2\276\25\0\4\276"+ + "\55\0\1\276\15\0\2\276\10\0\2\276\1\0\1\276"+ + "\1\0\1\276\11\0\1\276\11\0\2\276\6\0\1\276"+ + "\2\0\4\276\3\0\1\276\2\0\2\276\1\0\3\276"+ + "\1\0\2\276\1\0\1\276\10\0\1\276\1\0\2\276"+ + "\2\0\2\276\1\0\4\276\23\0\1\276\111\0\1\277"+ + "\2\0\1\277\33\0\4\277\216\0\1\277\77\0\1\277"+ + "\44\0\1\277\1\0\2\277\21\0\1\277\4\0\1\277"+ + "\17\0\4\277\3\0\1\277\12\0\1\277\203\0\1\277"+ + "\222\0\4\277\152\0\2\277\25\0\4\277\55\0\1\277"+ + "\15\0\2\277\10\0\2\277\1\0\1\277\1\0\1\277"+ + "\11\0\1\277\11\0\2\277\6\0\1\277\2\0\4\277"+ + "\3\0\1\277\2\0\2\277\1\0\3\277\1\0\2\277"+ + "\1\0\1\277\10\0\1\277\1\0\2\277\2\0\2\277"+ + "\1\0\4\277\23\0\1\277\20\0"; private static int [] zzUnpackTrans() { - int [] result = new int[20002]; + int [] result = new int[29962]; int offset = 0; offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); return result; @@ -747,11 +928,12 @@ public final class StandardTokenizerImpl implements StandardTokenizerInterface { private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); private static final String ZZ_ATTRIBUTE_PACKED_0 = - "\1\0\1\11\35\1\20\0\1\1\1\0\1\1\12\0"+ - "\1\1\21\0\1\1\115\0"; + "\1\0\1\11\36\1\21\0\1\1\1\0\1\1\12\0"+ + "\1\1\10\0\2\1\11\0\1\1\55\0\1\1\74\0"+ + "\2\1\36\0"; private static int [] zzUnpackAttribute() { - int [] result = new int[156]; + int [] result = new int[221]; int offset = 0; offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); return result; @@ -858,7 +1040,6 @@ public final class StandardTokenizerImpl implements StandardTokenizerInterface { /** * Creates a new scanner - * There is also a java.io.InputStream version of this constructor. * * @param in the java.io.Reader to read input from. */ @@ -866,7 +1047,6 @@ public final class StandardTokenizerImpl implements StandardTokenizerInterface { this.zzReader = in; } - /** * Unpacks the compressed character translation table. @@ -878,7 +1058,7 @@ public final class StandardTokenizerImpl implements StandardTokenizerInterface { char [] map = new char[0x10000]; int i = 0; /* index in packed string */ int j = 0; /* index in unpacked array */ - while (i < 2848) { + while (i < 2860) { int count = packed.charAt(i++); char value = packed.charAt(i++); do map[j++] = value; while (--count > 0); diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/StandardTokenizerImpl.jflex b/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/StandardTokenizerImpl.jflex index 8ca3b8054f5..76af5f4c937 100644 --- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/StandardTokenizerImpl.jflex +++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/StandardTokenizerImpl.jflex @@ -32,11 +32,13 @@ import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; * Asian languages, including Thai, Lao, Myanmar, and Khmer *
  • <IDEOGRAPHIC>: A single CJKV ideographic character
  • *
  • <HIRAGANA>: A single hiragana character
  • + *
  • <KATAKANA>: A sequence of katakana characters
  • + *
  • <HANGUL>: A sequence of Hangul characters
  • * */ %% -%unicode 6.1 +%unicode 6.3 %integer %final %public @@ -47,33 +49,40 @@ import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; %buffer 4096 %include SUPPLEMENTARY.jflex-macro -ALetter = ([\p{WB:ALetter}] | {ALetterSupp}) -Format = ([\p{WB:Format}] | {FormatSupp}) -Numeric = ([\p{WB:Numeric}] | {NumericSupp}) -Extend = ([\p{WB:Extend}] | {ExtendSupp}) -Katakana = ([\p{WB:Katakana}] | {KatakanaSupp}) -MidLetter = ([\p{WB:MidLetter}] | {MidLetterSupp}) -MidNum = ([\p{WB:MidNum}] | {MidNumSupp}) -MidNumLet = ([\p{WB:MidNumLet}] | {MidNumLetSupp}) -ExtendNumLet = ([\p{WB:ExtendNumLet}] | {ExtendNumLetSupp}) -ComplexContext = ([\p{LB:Complex_Context}] | {ComplexContextSupp}) -Han = ([\p{Script:Han}] | {HanSupp}) -Hiragana = ([\p{Script:Hiragana}] | {HiraganaSupp}) +ALetter = (\p{WB:ALetter} | {ALetterSupp}) +Format = (\p{WB:Format} | {FormatSupp}) +Numeric = ([\p{WB:Numeric}[\p{Blk:HalfAndFullForms}&&\p{Nd}]] | {NumericSupp}) +Extend = (\p{WB:Extend} | {ExtendSupp}) +Katakana = (\p{WB:Katakana} | {KatakanaSupp}) +MidLetter = (\p{WB:MidLetter} | {MidLetterSupp}) +MidNum = (\p{WB:MidNum} | {MidNumSupp}) +MidNumLet = (\p{WB:MidNumLet} | {MidNumLetSupp}) +ExtendNumLet = (\p{WB:ExtendNumLet} | {ExtendNumLetSupp}) +ComplexContext = (\p{LB:Complex_Context} | {ComplexContextSupp}) +Han = (\p{Script:Han} | {HanSupp}) +Hiragana = (\p{Script:Hiragana} | {HiraganaSupp}) +SingleQuote = (\p{WB:Single_Quote} | {SingleQuoteSupp}) +DoubleQuote = (\p{WB:Double_Quote} | {DoubleQuoteSupp}) +HebrewLetter = (\p{WB:Hebrew_Letter} | {HebrewLetterSupp}) +RegionalIndicator = (\p{WB:Regional_Indicator} | {RegionalIndicatorSupp}) +HebrewOrALetter = ({HebrewLetter} | {ALetter}) -// Script=Hangul & Aletter -HangulEx = (!(!\p{Script:Hangul}|!\p{WB:ALetter})) ({Format} | {Extend})* // UAX#29 WB4. X (Extend | Format)* --> X // -ALetterEx = {ALetter} ({Format} | {Extend})* -// TODO: Convert hard-coded full-width numeric range to property intersection (something like [\p{Full-Width}&&\p{Numeric}]) once JFlex supports it -NumericEx = ({Numeric} | [\uFF10-\uFF19]) ({Format} | {Extend})* -KatakanaEx = {Katakana} ({Format} | {Extend})* -MidLetterEx = ({MidLetter} | {MidNumLet}) ({Format} | {Extend})* -MidNumericEx = ({MidNum} | {MidNumLet}) ({Format} | {Extend})* -ExtendNumLetEx = {ExtendNumLet} ({Format} | {Extend})* +HangulEx = [\p{Script:Hangul}&&[\p{WB:ALetter}\p{WB:Hebrew_Letter}]] ({Format} | {Extend})* +HebrewOrALetterEx = {HebrewOrALetter} ({Format} | {Extend})* +NumericEx = {Numeric} ({Format} | {Extend})* +KatakanaEx = {Katakana} ({Format} | {Extend})* +MidLetterEx = ({MidLetter} | {MidNumLet} | {SingleQuote}) ({Format} | {Extend})* +MidNumericEx = ({MidNum} | {MidNumLet} | {SingleQuote}) ({Format} | {Extend})* +ExtendNumLetEx = {ExtendNumLet} ({Format} | {Extend})* +HanEx = {Han} ({Format} | {Extend})* +HiraganaEx = {Hiragana} ({Format} | {Extend})* +SingleQuoteEx = {SingleQuote} ({Format} | {Extend})* +DoubleQuoteEx = {DoubleQuote} ({Format} | {Extend})* +HebrewLetterEx = {HebrewLetter} ({Format} | {Extend})* +RegionalIndicatorEx = {RegionalIndicator} ({Format} | {Extend})* -HanEx = {Han} ({Format} | {Extend})* -HiraganaEx = {Hiragana} ({Format} | {Extend})* %{ /** Alphanumeric sequences */ @@ -121,15 +130,12 @@ HiraganaEx = {Hiragana} ({Format} | {Extend})* <> { return StandardTokenizerInterface.YYEOF; } // UAX#29 WB8. Numeric × Numeric -// WB11. Numeric (MidNum | MidNumLet) × Numeric -// WB12. Numeric × (MidNum | MidNumLet) Numeric -// WB13a. (ALetter | Numeric | Katakana | ExtendNumLet) × ExtendNumLet -// WB13b. ExtendNumLet × (ALetter | Numeric | Katakana) +// WB11. Numeric (MidNum | MidNumLet | Single_Quote) × Numeric +// WB12. Numeric × (MidNum | MidNumLet | Single_Quote) Numeric +// WB13a. (ALetter | Hebrew_Letter | Numeric | Katakana | ExtendNumLet) × ExtendNumLet +// WB13b. ExtendNumLet × (ALetter | Hebrew_Letter | Numeric | Katakana) // -{ExtendNumLetEx}* {NumericEx} ({ExtendNumLetEx}+ {NumericEx} - | {MidNumericEx} {NumericEx} - | {NumericEx})* -{ExtendNumLetEx}* +{ExtendNumLetEx}* {NumericEx} ( ( {ExtendNumLetEx}* | {MidNumericEx} ) {NumericEx} )* {ExtendNumLetEx}* { return NUMERIC_TYPE; } // subset of the below for typing purposes only! @@ -139,22 +145,32 @@ HiraganaEx = {Hiragana} ({Format} | {Extend})* {KatakanaEx}+ { return KATAKANA_TYPE; } -// UAX#29 WB5. ALetter × ALetter -// WB6. ALetter × (MidLetter | MidNumLet) ALetter -// WB7. ALetter (MidLetter | MidNumLet) × ALetter -// WB9. ALetter × Numeric -// WB10. Numeric × ALetter +// UAX#29 WB5. (ALetter | Hebrew_Letter) × (ALetter | Hebrew_Letter) +// WB6. (ALetter | Hebrew_Letter) × (MidLetter | MidNumLet | Single_Quote) (ALetter | Hebrew_Letter) +// WB7. (ALetter | Hebrew_Letter) (MidLetter | MidNumLet | Single_Quote) × (ALetter | Hebrew_Letter) +// WB7a. Hebrew_Letter × Single_Quote +// WB7b. Hebrew_Letter × Double_Quote Hebrew_Letter +// WB7c. Hebrew_Letter Double_Quote × Hebrew_Letter +// WB9. (ALetter | Hebrew_Letter) × Numeric +// WB10. Numeric × (ALetter | Hebrew_Letter) // WB13. Katakana × Katakana -// WB13a. (ALetter | Numeric | Katakana | ExtendNumLet) × ExtendNumLet -// WB13b. ExtendNumLet × (ALetter | Numeric | Katakana) +// WB13a. (ALetter | Hebrew_Letter | Numeric | Katakana | ExtendNumLet) × ExtendNumLet +// WB13b. ExtendNumLet × (ALetter | Hebrew_Letter | Numeric | Katakana) // -{ExtendNumLetEx}* ( {KatakanaEx} ({ExtendNumLetEx}* {KatakanaEx})* - | ( {NumericEx} ({ExtendNumLetEx}+ {NumericEx} | {MidNumericEx} {NumericEx} | {NumericEx})* - | {ALetterEx} ({ExtendNumLetEx}+ {ALetterEx} | {MidLetterEx} {ALetterEx} | {ALetterEx})* )+ ) -({ExtendNumLetEx}+ ( {KatakanaEx} ({ExtendNumLetEx}* {KatakanaEx})* - | ( {NumericEx} ({ExtendNumLetEx}+ {NumericEx} | {MidNumericEx} {NumericEx} | {NumericEx})* - | {ALetterEx} ({ExtendNumLetEx}+ {ALetterEx} | {MidLetterEx} {ALetterEx} | {ALetterEx})* )+ ) )* -{ExtendNumLetEx}* +{ExtendNumLetEx}* ( {KatakanaEx} + | ( {HebrewLetterEx} ( {SingleQuoteEx} | {DoubleQuoteEx} {HebrewLetterEx} ) + | {NumericEx} ( ( {ExtendNumLetEx}* | {MidNumericEx} )* {NumericEx} )* + | {HebrewOrALetterEx} ( ( {ExtendNumLetEx}* | {MidLetterEx} )* {HebrewOrALetterEx} )* + )+ + ) +({ExtendNumLetEx}+ ( {KatakanaEx} + | ( {HebrewLetterEx} ( {SingleQuoteEx} | {DoubleQuoteEx} {HebrewLetterEx} ) + | {NumericEx} ( ( {ExtendNumLetEx}* | {MidNumericEx} )* {NumericEx} )* + | {HebrewOrALetterEx} ( ( {ExtendNumLetEx}* | {MidLetterEx} )* {HebrewOrALetterEx} )* + )+ + ) +)* +{ExtendNumLetEx}* { return WORD_TYPE; } @@ -166,7 +182,7 @@ HiraganaEx = {Hiragana} ({Format} | {Extend})* // annex. That means that satisfactory treatment of languages like Chinese // or Thai requires special handling. // -// In Unicode 6.1, only one character has the \p{Line_Break = Contingent_Break} +// In Unicode 6.3, only one character has the \p{Line_Break = Contingent_Break} // property: U+FFFC (  ) OBJECT REPLACEMENT CHARACTER. // // In the ICU implementation of UAX#29, \p{Line_Break = Complex_Context} @@ -188,6 +204,8 @@ HiraganaEx = {Hiragana} ({Format} | {Extend})* // UAX#29 WB3. CR × LF // WB3a. (Newline | CR | LF) ÷ // WB3b. ÷ (Newline | CR | LF) +// WB13c. Regional_Indicator × Regional_Indicator // WB14. Any ÷ Any // -[^] { /* Break so we don't hit fall-through warning: */ break; /* Not numeric, word, ideographic, hiragana, or SE Asian -- ignore it. */ } +{RegionalIndicatorEx} {RegionalIndicatorEx}+ | [^] + { /* Break so we don't hit fall-through warning: */ break; /* Not numeric, word, ideographic, hiragana, or SE Asian -- ignore it. */ } diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/UAX29URLEmailTokenizerImpl.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/UAX29URLEmailTokenizerImpl.java index 1619e45e392..0ab1b0ad18e 100644 --- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/UAX29URLEmailTokenizerImpl.java +++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/UAX29URLEmailTokenizerImpl.java @@ -1,4 +1,4 @@ -/* The following code was generated by JFlex. */ +/* The following code was generated by JFlex 1.5.0-SNAPSHOT */ package org.apache.lucene.analysis.standard; @@ -37,6 +37,8 @@ import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; * Asian languages, including Thai, Lao, Myanmar, and Khmer *
  • <IDEOGRAPHIC>: A single CJKV ideographic character
  • *
  • <HIRAGANA>: A single hiragana character
  • + *
  • <KATAKANA>: A sequence of katakana characters
  • + *
  • <HANGUL>: A sequence of Hangul characters
  • * */ @@ -65,157 +67,157 @@ public final class UAX29URLEmailTokenizerImpl implements StandardTokenizerInterf * Translates characters to character classes */ private static final String ZZ_CMAP_PACKED = - "\1\301\10\277\2\301\2\277\1\301\23\277\1\302\1\276\1\271\1\302"+ - "\1\262\1\260\1\265\2\263\2\302\1\264\1\244\1\211\1\270\1\245"+ - "\1\250\1\256\1\251\1\254\1\246\1\247\1\253\1\255\1\252\1\257"+ - "\1\274\1\277\1\275\1\277\1\267\1\266\1\212\1\236\1\213\1\214"+ - "\1\215\1\220\1\221\1\237\1\222\1\240\1\243\1\223\1\224\1\225"+ - "\1\217\1\227\1\226\1\216\1\230\1\231\1\232\1\241\1\233\1\234"+ - "\1\242\1\235\1\272\1\300\1\273\1\303\1\261\1\303\1\212\1\236"+ - "\1\213\1\214\1\215\1\220\1\221\1\237\1\222\1\240\1\243\1\223"+ - "\1\224\1\225\1\217\1\227\1\226\1\216\1\230\1\231\1\232\1\241"+ - "\1\233\1\234\1\242\1\235\3\303\1\260\1\304\52\0\1\174\2\0"+ - "\1\175\7\0\1\174\1\0\1\200\2\0\1\174\5\0\27\174\1\0"+ - "\37\174\1\0\u01ca\174\4\0\14\174\16\0\5\174\7\0\1\174\1\0"+ - "\1\174\21\0\160\175\5\174\1\0\2\174\2\0\4\174\1\201\7\0"+ - "\1\174\1\200\3\174\1\0\1\174\1\0\24\174\1\0\123\174\1\0"+ - "\213\174\1\0\7\175\236\174\11\0\46\174\2\0\1\174\7\0\47\174"+ - "\1\0\1\201\7\0\55\175\1\0\1\175\1\0\2\175\1\0\2\175"+ - "\1\0\1\175\10\0\33\174\5\0\4\174\1\200\13\0\5\175\7\0"+ - "\2\201\2\0\13\175\5\0\53\174\25\175\12\176\1\0\1\176\1\201"+ - "\1\0\2\174\1\175\143\174\1\0\1\174\7\175\1\175\1\0\6\175"+ - "\2\174\2\175\1\0\4\175\2\174\12\176\3\174\2\0\1\174\17\0"+ - "\1\175\1\174\1\175\36\174\33\175\2\0\131\174\13\175\1\174\16\0"+ - "\12\176\41\174\11\175\2\174\2\0\1\201\1\0\1\174\5\0\26\174"+ - "\4\175\1\174\11\175\1\174\3\175\1\174\5\175\22\0\31\174\3\175"+ - "\104\0\1\174\1\0\13\174\67\0\33\175\1\0\4\175\66\174\3\175"+ - "\1\174\22\175\1\174\7\175\12\174\2\175\2\0\12\176\1\0\7\174"+ - "\1\0\7\174\1\0\3\175\1\0\10\174\2\0\2\174\2\0\26\174"+ - "\1\0\7\174\1\0\1\174\3\0\4\174\2\0\1\175\1\174\7\175"+ - "\2\0\2\175\2\0\3\175\1\174\10\0\1\175\4\0\2\174\1\0"+ - "\3\174\2\175\2\0\12\176\2\174\17\0\3\175\1\0\6\174\4\0"+ - "\2\174\2\0\26\174\1\0\7\174\1\0\2\174\1\0\2\174\1\0"+ - "\2\174\2\0\1\175\1\0\5\175\4\0\2\175\2\0\3\175\3\0"+ - "\1\175\7\0\4\174\1\0\1\174\7\0\12\176\2\175\3\174\1\175"+ - "\13\0\3\175\1\0\11\174\1\0\3\174\1\0\26\174\1\0\7\174"+ - "\1\0\2\174\1\0\5\174\2\0\1\175\1\174\10\175\1\0\3\175"+ - "\1\0\3\175\2\0\1\174\17\0\2\174\2\175\2\0\12\176\21\0"+ - "\3\175\1\0\10\174\2\0\2\174\2\0\26\174\1\0\7\174\1\0"+ - "\2\174\1\0\5\174\2\0\1\175\1\174\7\175\2\0\2\175\2\0"+ - "\3\175\10\0\2\175\4\0\2\174\1\0\3\174\2\175\2\0\12\176"+ - "\1\0\1\174\20\0\1\175\1\174\1\0\6\174\3\0\3\174\1\0"+ - "\4\174\3\0\2\174\1\0\1\174\1\0\2\174\3\0\2\174\3\0"+ - "\3\174\3\0\14\174\4\0\5\175\3\0\3\175\1\0\4\175\2\0"+ - "\1\174\6\0\1\175\16\0\12\176\21\0\3\175\1\0\10\174\1\0"+ - "\3\174\1\0\27\174\1\0\12\174\1\0\5\174\3\0\1\174\7\175"+ - "\1\0\3\175\1\0\4\175\7\0\2\175\1\0\2\174\6\0\2\174"+ - "\2\175\2\0\12\176\22\0\2\175\1\0\10\174\1\0\3\174\1\0"+ - "\27\174\1\0\12\174\1\0\5\174\2\0\1\175\1\174\7\175\1\0"+ - "\3\175\1\0\4\175\7\0\2\175\7\0\1\174\1\0\2\174\2\175"+ - "\2\0\12\176\1\0\2\174\17\0\2\175\1\0\10\174\1\0\3\174"+ - "\1\0\51\174\2\0\1\174\7\175\1\0\3\175\1\0\4\175\1\174"+ - "\10\0\1\175\10\0\2\174\2\175\2\0\12\176\12\0\6\174\2\0"+ - "\2\175\1\0\22\174\3\0\30\174\1\0\11\174\1\0\1\174\2\0"+ - "\7\174\3\0\1\175\4\0\6\175\1\0\1\175\1\0\10\175\22\0"+ - "\2\175\15\0\60\204\1\205\2\204\7\205\5\0\7\204\10\205\1\0"+ - "\12\176\47\0\2\204\1\0\1\204\2\0\2\204\1\0\1\204\2\0"+ - "\1\204\6\0\4\204\1\0\7\204\1\0\3\204\1\0\1\204\1\0"+ - "\1\204\2\0\2\204\1\0\4\204\1\205\2\204\6\205\1\0\2\205"+ - "\1\204\2\0\5\204\1\0\1\204\1\0\6\205\2\0\12\176\2\0"+ - "\4\204\40\0\1\174\27\0\2\175\6\0\12\176\13\0\1\175\1\0"+ - "\1\175\1\0\1\175\4\0\2\175\10\174\1\0\44\174\4\0\24\175"+ - "\1\0\2\175\5\174\13\175\1\0\44\175\11\0\1\175\71\0\53\204"+ - "\24\205\1\204\12\176\6\0\6\204\4\205\4\204\3\205\1\204\3\205"+ - "\2\204\7\205\3\204\4\205\15\204\14\205\1\204\1\205\12\176\4\205"+ - "\2\204\46\174\1\0\1\174\5\0\1\174\2\0\53\174\1\0\4\174"+ - "\u0100\210\111\174\1\0\4\174\2\0\7\174\1\0\1\174\1\0\4\174"+ - "\2\0\51\174\1\0\4\174\2\0\41\174\1\0\4\174\2\0\7\174"+ - "\1\0\1\174\1\0\4\174\2\0\17\174\1\0\71\174\1\0\4\174"+ - "\2\0\103\174\2\0\3\175\40\0\20\174\20\0\125\174\14\0\u026c\174"+ - "\2\0\21\174\1\0\32\174\5\0\113\174\3\0\3\174\17\0\15\174"+ - "\1\0\4\174\3\175\13\0\22\174\3\175\13\0\22\174\2\175\14\0"+ - "\15\174\1\0\3\174\1\0\2\175\14\0\64\204\40\205\3\0\1\204"+ - "\4\0\1\204\1\205\2\0\12\176\41\0\3\175\2\0\12\176\6\0"+ - "\130\174\10\0\51\174\1\175\1\174\5\0\106\174\12\0\35\174\3\0"+ - "\14\175\4\0\14\175\12\0\12\176\36\204\2\0\5\204\13\0\54\204"+ - "\4\0\21\205\7\204\2\205\6\0\12\176\1\204\3\0\2\204\40\0"+ - "\27\174\5\175\4\0\65\204\12\205\1\0\35\205\2\0\1\175\12\176"+ - "\6\0\12\176\6\0\16\204\122\0\5\175\57\174\21\175\7\174\4\0"+ - "\12\176\21\0\11\175\14\0\3\175\36\174\15\175\2\174\12\176\54\174"+ - "\16\175\14\0\44\174\24\175\10\0\12\176\3\0\3\174\12\176\44\174"+ - "\122\0\3\175\1\0\25\175\4\174\1\175\4\174\3\175\2\174\11\0"+ - "\300\174\47\175\25\0\4\175\u0116\174\2\0\6\174\2\0\46\174\2\0"+ - "\6\174\2\0\10\174\1\0\1\174\1\0\1\174\1\0\1\174\1\0"+ - "\37\174\2\0\65\174\1\0\7\174\1\0\1\174\3\0\3\174\1\0"+ - "\7\174\3\0\4\174\2\0\6\174\4\0\15\174\5\0\3\174\1\0"+ - "\7\174\17\0\2\175\2\175\10\0\2\202\12\0\1\202\2\0\1\200"+ - "\2\0\5\175\20\0\2\203\3\0\1\201\17\0\1\203\13\0\5\175"+ - "\5\0\6\175\1\0\1\174\15\0\1\174\20\0\15\174\63\0\41\175"+ - "\21\0\1\174\4\0\1\174\2\0\12\174\1\0\1\174\3\0\5\174"+ - "\6\0\1\174\1\0\1\174\1\0\1\174\1\0\4\174\1\0\13\174"+ - "\2\0\4\174\5\0\5\174\4\0\1\174\21\0\51\174\u032d\0\64\174"+ - "\u0716\0\57\174\1\0\57\174\1\0\205\174\6\0\4\174\3\175\2\174"+ - "\14\0\46\174\1\0\1\174\5\0\1\174\2\0\70\174\7\0\1\174"+ - "\17\0\1\175\27\174\11\0\7\174\1\0\7\174\1\0\7\174\1\0"+ - "\7\174\1\0\7\174\1\0\7\174\1\0\7\174\1\0\7\174\1\0"+ - "\40\175\57\0\1\174\120\0\32\206\1\0\131\206\14\0\326\206\57\0"+ - "\1\174\1\0\1\206\31\0\11\206\4\175\2\175\1\0\5\177\2\0"+ - "\3\206\1\174\1\174\4\0\126\207\2\0\2\175\2\177\3\207\133\177"+ - "\1\0\4\177\5\0\51\174\3\0\136\210\21\0\33\174\65\0\20\177"+ - "\37\0\101\0\37\0\121\0\57\177\1\0\130\177\250\0\u19b6\206\112\0"+ - "\u51cd\206\63\0\u048d\174\103\0\56\174\2\0\u010d\174\3\0\20\174\12\176"+ - "\2\174\24\0\57\174\4\175\1\0\12\175\1\0\31\174\7\0\1\175"+ - "\120\174\2\175\45\0\11\174\2\0\147\174\2\0\4\174\1\0\4\174"+ - "\14\0\13\174\115\0\12\174\1\175\3\174\1\175\4\174\1\175\27\174"+ - "\5\175\30\0\64\174\14\0\2\175\62\174\21\175\13\0\12\176\6\0"+ - "\22\175\6\174\3\0\1\174\4\0\12\176\34\174\10\175\2\0\27\174"+ - "\15\175\14\0\35\210\3\0\4\175\57\174\16\175\16\0\1\174\12\176"+ - "\46\0\51\174\16\175\11\0\3\174\1\175\10\174\2\175\2\0\12\176"+ - "\6\0\33\204\1\205\4\0\60\204\1\205\1\204\3\205\2\204\2\205"+ - "\5\204\2\205\1\204\1\205\1\204\30\0\5\204\13\174\5\175\2\0"+ - "\3\174\2\175\12\0\6\174\2\0\6\174\2\0\6\174\11\0\7\174"+ - "\1\0\7\174\221\0\43\174\10\175\1\0\2\175\2\0\12\176\6\0"+ - "\u2ba4\210\14\0\27\210\4\0\61\210\4\0\1\44\1\40\1\67\1\64"+ - "\1\33\1\30\2\0\1\24\1\21\2\0\1\17\1\15\14\0\1\3"+ - "\1\6\20\0\1\156\7\0\1\111\1\10\5\0\1\1\1\172\3\0"+ + "\1\304\10\302\2\304\2\302\1\304\23\302\1\305\1\213\1\275\1\305"+ + "\1\267\1\265\1\212\2\270\2\305\1\271\1\251\1\216\1\274\1\253"+ + "\1\262\1\261\1\252\1\255\1\256\1\263\1\254\1\260\1\257\1\264"+ + "\1\300\1\302\1\301\1\302\1\273\1\272\1\217\1\243\1\220\1\221"+ + "\1\222\1\225\1\226\1\244\1\227\1\246\1\245\1\230\1\231\1\232"+ + "\1\224\1\234\1\233\1\223\1\235\1\236\1\237\1\247\1\240\1\241"+ + "\1\250\1\242\1\276\1\303\1\277\1\306\1\266\1\306\1\217\1\243"+ + "\1\220\1\221\1\222\1\225\1\226\1\244\1\227\1\246\1\245\1\230"+ + "\1\231\1\232\1\224\1\234\1\233\1\223\1\235\1\236\1\237\1\247"+ + "\1\240\1\241\1\250\1\242\3\306\1\265\1\307\52\0\1\176\2\0"+ + "\1\177\7\0\1\176\1\0\1\202\2\0\1\176\5\0\27\176\1\0"+ + "\37\176\1\0\u01ca\176\4\0\14\176\5\0\1\202\10\0\5\176\7\0"+ + "\1\176\1\0\1\176\21\0\160\177\5\176\1\0\2\176\2\0\4\176"+ + "\1\203\7\0\1\176\1\202\3\176\1\0\1\176\1\0\24\176\1\0"+ + "\123\176\1\0\213\176\1\0\7\177\236\176\11\0\46\176\2\0\1\176"+ + "\7\0\47\176\1\0\1\203\7\0\55\177\1\0\1\177\1\0\2\177"+ + "\1\0\2\177\1\0\1\177\10\0\33\214\5\0\3\214\1\176\1\202"+ + "\13\0\5\177\7\0\2\203\2\0\13\177\1\0\1\177\3\0\53\176"+ + "\25\177\12\200\1\0\1\200\1\203\1\0\2\176\1\177\143\176\1\0"+ + "\1\176\7\177\1\177\1\0\6\177\2\176\2\177\1\0\4\177\2\176"+ + "\12\200\3\176\2\0\1\176\17\0\1\177\1\176\1\177\36\176\33\177"+ + "\2\0\131\176\13\177\1\176\16\0\12\200\41\176\11\177\2\176\2\0"+ + "\1\203\1\0\1\176\5\0\26\176\4\177\1\176\11\177\1\176\3\177"+ + "\1\176\5\177\22\0\31\176\3\177\104\0\1\176\1\0\13\176\67\0"+ + "\33\177\1\0\4\177\66\176\3\177\1\176\22\177\1\176\7\177\12\176"+ + "\2\177\2\0\12\200\1\0\7\176\1\0\7\176\1\0\3\177\1\0"+ + "\10\176\2\0\2\176\2\0\26\176\1\0\7\176\1\0\1\176\3\0"+ + "\4\176\2\0\1\177\1\176\7\177\2\0\2\177\2\0\3\177\1\176"+ + "\10\0\1\177\4\0\2\176\1\0\3\176\2\177\2\0\12\200\2\176"+ + "\17\0\3\177\1\0\6\176\4\0\2\176\2\0\26\176\1\0\7\176"+ + "\1\0\2\176\1\0\2\176\1\0\2\176\2\0\1\177\1\0\5\177"+ + "\4\0\2\177\2\0\3\177\3\0\1\177\7\0\4\176\1\0\1\176"+ + "\7\0\12\200\2\177\3\176\1\177\13\0\3\177\1\0\11\176\1\0"+ + "\3\176\1\0\26\176\1\0\7\176\1\0\2\176\1\0\5\176\2\0"+ + "\1\177\1\176\10\177\1\0\3\177\1\0\3\177\2\0\1\176\17\0"+ + "\2\176\2\177\2\0\12\200\21\0\3\177\1\0\10\176\2\0\2\176"+ + "\2\0\26\176\1\0\7\176\1\0\2\176\1\0\5\176\2\0\1\177"+ + "\1\176\7\177\2\0\2\177\2\0\3\177\10\0\2\177\4\0\2\176"+ + "\1\0\3\176\2\177\2\0\12\200\1\0\1\176\20\0\1\177\1\176"+ + "\1\0\6\176\3\0\3\176\1\0\4\176\3\0\2\176\1\0\1\176"+ + "\1\0\2\176\3\0\2\176\3\0\3\176\3\0\14\176\4\0\5\177"+ + "\3\0\3\177\1\0\4\177\2\0\1\176\6\0\1\177\16\0\12\200"+ + "\21\0\3\177\1\0\10\176\1\0\3\176\1\0\27\176\1\0\12\176"+ + "\1\0\5\176\3\0\1\176\7\177\1\0\3\177\1\0\4\177\7\0"+ + "\2\177\1\0\2\176\6\0\2\176\2\177\2\0\12\200\22\0\2\177"+ + "\1\0\10\176\1\0\3\176\1\0\27\176\1\0\12\176\1\0\5\176"+ + "\2\0\1\177\1\176\7\177\1\0\3\177\1\0\4\177\7\0\2\177"+ + "\7\0\1\176\1\0\2\176\2\177\2\0\12\200\1\0\2\176\17\0"+ + "\2\177\1\0\10\176\1\0\3\176\1\0\51\176\2\0\1\176\7\177"+ + "\1\0\3\177\1\0\4\177\1\176\10\0\1\177\10\0\2\176\2\177"+ + "\2\0\12\200\12\0\6\176\2\0\2\177\1\0\22\176\3\0\30\176"+ + "\1\0\11\176\1\0\1\176\2\0\7\176\3\0\1\177\4\0\6\177"+ + "\1\0\1\177\1\0\10\177\22\0\2\177\15\0\60\206\1\207\2\206"+ + "\7\207\5\0\7\206\10\207\1\0\12\200\47\0\2\206\1\0\1\206"+ + "\2\0\2\206\1\0\1\206\2\0\1\206\6\0\4\206\1\0\7\206"+ + "\1\0\3\206\1\0\1\206\1\0\1\206\2\0\2\206\1\0\4\206"+ + "\1\207\2\206\6\207\1\0\2\207\1\206\2\0\5\206\1\0\1\206"+ + "\1\0\6\207\2\0\12\200\2\0\4\206\40\0\1\176\27\0\2\177"+ + "\6\0\12\200\13\0\1\177\1\0\1\177\1\0\1\177\4\0\2\177"+ + "\10\176\1\0\44\176\4\0\24\177\1\0\2\177\5\176\13\177\1\0"+ + "\44\177\11\0\1\177\71\0\53\206\24\207\1\206\12\200\6\0\6\206"+ + "\4\207\4\206\3\207\1\206\3\207\2\206\7\207\3\206\4\207\15\206"+ + "\14\207\1\206\1\207\12\200\4\207\2\206\46\176\1\0\1\176\5\0"+ + "\1\176\2\0\53\176\1\0\4\176\u0100\215\111\176\1\0\4\176\2\0"+ + "\7\176\1\0\1\176\1\0\4\176\2\0\51\176\1\0\4\176\2\0"+ + "\41\176\1\0\4\176\2\0\7\176\1\0\1\176\1\0\4\176\2\0"+ + "\17\176\1\0\71\176\1\0\4\176\2\0\103\176\2\0\3\177\40\0"+ + "\20\176\20\0\125\176\14\0\u026c\176\2\0\21\176\1\0\32\176\5\0"+ + "\113\176\3\0\3\176\17\0\15\176\1\0\4\176\3\177\13\0\22\176"+ + "\3\177\13\0\22\176\2\177\14\0\15\176\1\0\3\176\1\0\2\177"+ + "\14\0\64\206\40\207\3\0\1\206\4\0\1\206\1\207\2\0\12\200"+ + "\41\0\3\177\1\177\1\0\12\200\6\0\130\176\10\0\51\176\1\177"+ + "\1\176\5\0\106\176\12\0\35\176\3\0\14\177\4\0\14\177\12\0"+ + "\12\200\36\206\2\0\5\206\13\0\54\206\4\0\21\207\7\206\2\207"+ + "\6\0\12\200\1\206\3\0\2\206\40\0\27\176\5\177\4\0\65\206"+ + "\12\207\1\0\35\207\2\0\1\177\12\200\6\0\12\200\6\0\16\206"+ + "\122\0\5\177\57\176\21\177\7\176\4\0\12\200\21\0\11\177\14\0"+ + "\3\177\36\176\15\177\2\176\12\200\54\176\16\177\14\0\44\176\24\177"+ + "\10\0\12\200\3\0\3\176\12\200\44\176\122\0\3\177\1\0\25\177"+ + "\4\176\1\177\4\176\3\177\2\176\11\0\300\176\47\177\25\0\4\177"+ + "\u0116\176\2\0\6\176\2\0\46\176\2\0\6\176\2\0\10\176\1\0"+ + "\1\176\1\0\1\176\1\0\1\176\1\0\37\176\2\0\65\176\1\0"+ + "\7\176\1\0\1\176\3\0\3\176\1\0\7\176\3\0\4\176\2\0"+ + "\6\176\4\0\15\176\5\0\3\176\1\0\7\176\17\0\2\177\2\177"+ + "\10\0\2\204\12\0\1\204\2\0\1\202\2\0\5\177\20\0\2\205"+ + "\3\0\1\203\17\0\1\205\13\0\5\177\1\0\12\177\1\0\1\176"+ + "\15\0\1\176\20\0\15\176\63\0\41\177\21\0\1\176\4\0\1\176"+ + "\2\0\12\176\1\0\1\176\3\0\5\176\6\0\1\176\1\0\1\176"+ + "\1\0\1\176\1\0\4\176\1\0\13\176\2\0\4\176\5\0\5\176"+ + "\4\0\1\176\21\0\51\176\u032d\0\64\176\u0716\0\57\176\1\0\57\176"+ + "\1\0\205\176\6\0\4\176\3\177\2\176\14\0\46\176\1\0\1\176"+ + "\5\0\1\176\2\0\70\176\7\0\1\176\17\0\1\177\27\176\11\0"+ + "\7\176\1\0\7\176\1\0\7\176\1\0\7\176\1\0\7\176\1\0"+ + "\7\176\1\0\7\176\1\0\7\176\1\0\40\177\57\0\1\176\120\0"+ + "\32\210\1\0\131\210\14\0\326\210\57\0\1\176\1\0\1\210\31\0"+ + "\11\210\6\177\1\0\5\201\2\0\3\210\1\176\1\176\4\0\126\211"+ + "\2\0\2\177\2\201\3\211\133\201\1\0\4\201\5\0\51\176\3\0"+ + "\136\215\21\0\33\176\65\0\20\201\320\0\57\201\1\0\130\201\250\0"+ + "\u19b6\210\112\0\u51cd\210\63\0\u048d\176\103\0\56\176\2\0\u010d\176\3\0"+ + "\20\176\12\200\2\176\24\0\57\176\4\177\1\0\12\177\1\0\31\176"+ + "\7\0\1\177\120\176\2\177\45\0\11\176\2\0\147\176\2\0\4\176"+ + "\1\0\4\176\14\0\13\176\115\0\12\176\1\177\3\176\1\177\4\176"+ + "\1\177\27\176\5\177\30\0\64\176\14\0\2\177\62\176\21\177\13\0"+ + "\12\200\6\0\22\177\6\176\3\0\1\176\4\0\12\200\34\176\10\177"+ + "\2\0\27\176\15\177\14\0\35\215\3\0\4\177\57\176\16\177\16\0"+ + "\1\176\12\200\46\0\51\176\16\177\11\0\3\176\1\177\10\176\2\177"+ + "\2\0\12\200\6\0\33\206\1\207\4\0\60\206\1\207\1\206\3\207"+ + "\2\206\2\207\5\206\2\207\1\206\1\207\1\206\30\0\5\206\13\176"+ + "\5\177\2\0\3\176\2\177\12\0\6\176\2\0\6\176\2\0\6\176"+ + "\11\0\7\176\1\0\7\176\221\0\43\176\10\177\1\0\2\177\2\0"+ + "\12\200\6\0\u2ba4\215\14\0\27\215\4\0\61\215\4\0\1\44\1\40"+ + "\1\67\1\64\1\33\1\30\2\0\1\24\1\21\2\0\1\17\1\15"+ + "\14\0\1\3\1\6\20\0\1\156\7\0\1\111\1\10\5\0\1\1"+ + "\1\172\3\0\1\163\1\163\1\163\1\163\1\163\1\163\1\163\1\163"+ "\1\163\1\163\1\163\1\163\1\163\1\163\1\163\1\163\1\163\1\163"+ "\1\163\1\163\1\163\1\163\1\163\1\163\1\163\1\163\1\163\1\163"+ "\1\163\1\163\1\163\1\163\1\163\1\163\1\163\1\163\1\163\1\163"+ - "\1\163\1\163\1\163\1\163\1\163\1\163\1\163\1\163\1\163\1\163"+ - "\1\163\1\164\1\163\1\163\1\163\1\170\1\166\17\0\1\160\u02c1\0"+ - "\1\114\277\0\1\157\1\115\1\16\3\167\2\62\1\167\1\62\2\167"+ - "\1\36\21\167\2\106\7\117\1\116\7\117\7\102\1\37\1\102\1\130"+ - "\2\66\1\65\1\130\1\66\1\65\10\130\2\107\5\103\2\75\5\103"+ - "\1\22\10\53\5\23\3\41\12\147\20\41\3\63\32\43\1\42\2\61"+ - "\2\154\1\155\2\154\2\155\2\154\1\155\3\61\1\60\2\61\12\110"+ - "\1\126\1\50\1\45\1\110\6\50\1\45\13\50\31\61\7\50\12\150"+ - "\1\50\5\13\3\127\3\101\1\100\4\101\2\100\10\101\1\100\7\35"+ - "\1\34\2\35\7\101\16\127\1\141\4\152\1\4\4\151\1\4\5\140"+ - "\1\137\1\140\3\137\7\140\1\137\23\140\5\113\3\140\6\113\2\113"+ - "\6\112\5\112\3\134\2\101\7\133\36\101\4\133\5\101\5\127\6\125"+ - "\2\127\1\125\4\35\13\136\12\151\26\136\15\13\1\135\2\13\1\173"+ - "\3\142\1\13\2\142\5\161\4\142\4\162\1\161\3\162\1\161\5\162"+ - "\2\70\1\73\2\70\1\73\1\70\2\73\1\70\1\73\12\70\1\73"+ - "\4\5\1\144\1\143\1\145\1\12\3\165\1\145\2\165\1\131\2\132"+ - "\2\165\1\12\1\165\1\12\1\165\1\12\1\165\3\12\1\165\2\12"+ - "\1\165\1\12\2\165\1\12\1\165\1\12\1\165\1\12\1\165\1\12"+ - "\1\165\1\12\1\76\2\72\1\76\1\72\2\76\4\72\1\76\7\72"+ - "\1\76\4\72\1\76\4\72\1\165\1\12\1\165\12\31\1\57\21\31"+ - "\1\57\3\32\1\57\3\31\1\57\1\31\2\2\2\31\1\57\15\124"+ - "\4\47\4\54\1\146\1\56\10\146\7\54\6\165\4\25\1\27\37\25"+ - "\1\27\4\25\25\105\1\171\11\105\21\26\5\105\1\7\12\55\5\105"+ - "\6\104\4\76\1\77\1\26\5\123\12\121\17\123\1\74\3\71\14\120"+ - "\1\11\11\46\1\52\5\46\4\122\13\51\2\14\11\46\1\52\31\46"+ - "\1\52\4\11\4\46\2\52\2\153\1\20\5\153\52\20\u1900\0\u016e\206"+ - "\2\0\152\206\46\0\7\174\14\0\5\174\5\0\1\174\1\175\12\174"+ - "\1\0\15\174\1\0\5\174\1\0\1\174\1\0\2\174\1\0\2\174"+ - "\1\0\154\174\41\0\u016b\174\22\0\100\174\2\0\66\174\50\0\14\174"+ - "\4\0\20\175\1\201\2\0\1\200\1\201\13\0\7\175\14\0\2\203"+ - "\30\0\3\203\1\201\1\0\1\202\1\0\1\201\1\200\32\0\5\174"+ - "\1\0\207\174\2\0\1\175\7\0\1\202\4\0\1\201\1\0\1\202"+ - "\1\0\12\176\1\200\1\201\5\0\32\174\4\0\1\203\1\0\32\174"+ - "\13\0\70\177\2\175\37\210\3\0\6\210\2\0\6\210\2\0\6\210"+ - "\2\0\3\210\34\0\3\175\4\0"; + "\1\163\1\163\1\163\1\164\1\163\1\163\1\163\1\170\1\166\17\0"+ + "\1\160\u02c1\0\1\114\277\0\1\157\1\115\1\16\3\167\2\62\1\167"+ + "\1\62\2\167\1\36\21\167\2\106\7\117\1\116\7\117\7\102\1\37"+ + "\1\102\1\140\2\66\1\65\1\140\1\66\1\65\10\140\2\107\5\103"+ + "\2\75\5\103\1\22\10\53\5\23\3\41\12\122\20\41\3\63\32\43"+ + "\1\42\2\61\2\126\1\127\2\126\2\127\2\126\1\127\3\61\1\60"+ + "\2\61\12\110\1\136\1\50\1\45\1\110\6\50\1\45\13\50\31\61"+ + "\7\50\12\123\1\50\5\13\3\137\3\101\1\100\4\101\2\100\10\101"+ + "\1\100\7\35\1\34\2\35\7\101\16\137\1\151\4\124\1\4\4\121"+ + "\1\4\5\150\1\147\1\150\3\147\7\150\1\147\23\150\5\113\3\150"+ + "\6\113\2\113\6\112\5\112\3\144\2\101\7\143\36\101\4\143\5\101"+ + "\5\137\6\135\2\137\1\135\4\35\13\146\12\121\14\146\12\175\15\174"+ + "\1\145\2\174\1\173\3\152\1\13\2\152\5\161\4\152\4\162\1\161"+ + "\3\162\1\161\5\162\2\70\1\73\2\70\1\73\1\70\2\73\1\70"+ + "\1\73\12\70\1\73\4\5\1\154\1\153\1\155\1\12\3\165\1\155"+ + "\2\165\1\141\2\142\2\165\1\12\1\165\1\12\1\165\1\12\1\165"+ + "\3\12\1\165\2\12\1\165\1\12\2\165\1\12\1\165\1\12\1\165"+ + "\1\12\1\165\1\12\1\165\1\12\1\76\2\72\1\76\1\72\2\76"+ + "\4\72\1\76\7\72\1\76\4\72\1\76\4\72\1\165\1\12\1\165"+ + "\12\31\1\57\21\31\1\57\3\32\1\57\3\31\1\57\1\31\2\2"+ + "\2\31\1\57\15\134\4\47\4\54\1\120\1\56\10\120\7\54\6\165"+ + "\4\25\1\27\37\25\1\27\4\25\25\105\1\171\11\105\21\26\5\105"+ + "\1\7\12\55\5\105\6\104\4\76\1\77\1\26\5\133\12\131\17\133"+ + "\1\74\3\71\14\130\1\11\11\46\1\52\5\46\4\132\13\51\2\14"+ + "\11\46\1\52\31\46\1\52\4\11\4\46\2\52\2\125\1\20\5\125"+ + "\52\20\u1900\0\u016e\210\2\0\152\210\46\0\7\176\14\0\5\176\5\0"+ + "\1\214\1\177\12\214\1\0\15\214\1\0\5\214\1\0\1\214\1\0"+ + "\2\214\1\0\2\214\1\0\12\214\142\176\41\0\u016b\176\22\0\100\176"+ + "\2\0\66\176\50\0\14\176\4\0\20\177\1\203\2\0\1\202\1\203"+ + "\13\0\7\177\14\0\2\205\30\0\3\205\1\203\1\0\1\204\1\0"+ + "\1\203\1\202\32\0\5\176\1\0\207\176\2\0\1\177\7\0\1\204"+ + "\4\0\1\203\1\0\1\204\1\0\12\200\1\202\1\203\5\0\32\176"+ + "\4\0\1\205\1\0\32\176\13\0\70\201\2\177\37\215\3\0\6\215"+ + "\2\0\6\215\2\0\6\215\2\0\3\215\34\0\3\177\4\0"; /** * Translates characters to character classes @@ -229,27 +231,35 @@ public final class UAX29URLEmailTokenizerImpl implements StandardTokenizerInterf private static final String ZZ_ACTION_PACKED_0 = "\1\0\26\1\1\2\1\3\1\4\1\1\1\5\1\6"+ - "\1\7\1\10\1\1\4\2\3\3\3\1\20\0\1\2"+ - "\1\0\1\2\12\0\1\3\21\0\1\2\32\0\2\2"+ - "\1\0\4\2\1\0\1\3\1\0\2\3\1\2\1\3"+ - "\67\0\32\2\3\0\5\2\32\0\4\3\21\0\1\11"+ - "\1\0\6\12\3\2\2\12\1\2\4\12\2\2\2\12"+ - "\2\0\1\2\1\0\2\2\6\12\3\0\2\12\1\0"+ - "\4\12\2\0\2\12\1\0\2\3\10\0\1\12\32\0"+ - "\1\12\1\0\3\12\6\2\1\0\1\2\2\0\2\2"+ - "\1\0\1\12\10\0\3\3\15\0\3\12\6\11\3\0"+ - "\2\11\1\0\4\11\2\0\2\11\2\12\1\0\2\12"+ - "\1\0\2\12\1\0\1\12\2\2\3\0\1\2\4\0"+ - "\2\3\20\0\1\11\10\0\1\12\3\0\1\2\40\0"+ - "\3\12\23\0\1\12\40\0\1\12\4\0\1\12\6\0"+ - "\1\2\2\0\1\12\4\0\2\12\43\0\1\12\57\0"+ - "\2\2\10\0\1\12\53\0\1\12\72\0\1\12\150\0"+ - "\1\13\1\0\1\12\177\0\1\12\132\0\6\13\3\0"+ - "\2\13\1\0\4\13\2\0\2\13\1\12\112\0\1\13"+ - "\10\0\1\12\64\0\1\12\u01eb\0"; + "\1\7\2\1\1\2\1\10\4\2\3\3\2\1\21\0"+ + "\1\2\1\0\1\2\12\0\1\3\10\0\1\2\11\0"+ + "\1\2\46\0\6\2\2\0\3\3\1\2\1\3\23\0"+ + "\1\2\70\0\1\2\1\0\32\2\3\0\6\2\33\0"+ + "\4\3\4\0\1\1\22\0\1\11\10\0\7\12\4\2"+ + "\1\12\1\2\2\12\1\2\6\12\1\2\4\12\1\2"+ + "\4\12\2\2\2\12\4\2\1\12\1\2\3\12\1\2"+ + "\1\0\1\2\1\0\2\2\7\12\4\0\1\12\1\0"+ + "\2\12\1\0\6\12\1\0\4\12\1\0\4\12\2\0"+ + "\2\12\4\0\1\12\1\0\3\12\2\0\2\3\10\0"+ + "\1\12\41\0\1\12\1\0\3\12\32\2\1\0\4\2"+ + "\2\0\2\2\1\0\1\12\37\0\3\3\15\0\3\12"+ + "\7\11\4\0\1\11\1\0\2\11\1\0\6\11\1\0"+ + "\4\11\1\0\4\11\2\0\2\11\4\0\1\11\1\0"+ + "\3\11\1\0\2\12\1\0\2\12\1\0\2\12\1\0"+ + "\1\12\23\2\1\0\4\2\2\0\1\2\31\0\2\3"+ + "\20\0\1\11\37\0\1\12\3\0\15\2\25\0\3\2"+ + "\31\0\3\12\50\0\1\12\12\2\32\0\2\2\1\0"+ + "\1\12\4\0\1\12\7\0\1\2\2\0\1\12\20\0"+ + "\2\12\61\0\1\12\6\2\53\0\2\2\6\0\1\12"+ + "\70\0\1\12\5\2\66\0\1\2\1\12\62\0\3\2"+ + "\65\0\1\13\1\0\1\12\64\0\1\2\113\0\1\12"+ + "\125\0\7\13\4\0\1\13\1\0\2\13\1\0\6\13"+ + "\1\0\4\13\1\0\4\13\2\0\2\13\4\0\1\13"+ + "\1\0\3\13\1\0\1\12\104\0\1\13\37\0\1\12"+ + "\56\0\1\12\u01e5\0"; private static int [] zzUnpackAction() { - int [] result = new int[1750]; + int [] result = new int[2125]; int offset = 0; offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); return result; @@ -274,228 +284,275 @@ public final class UAX29URLEmailTokenizerImpl implements StandardTokenizerInterf private static final int [] ZZ_ROWMAP = zzUnpackRowMap(); private static final String ZZ_ROWMAP_PACKED_0 = - "\0\0\0\305\0\u018a\0\u024f\0\u0314\0\u03d9\0\u049e\0\u0563"+ - "\0\u0628\0\u06ed\0\u07b2\0\u0877\0\u093c\0\u0a01\0\u0ac6\0\u0b8b"+ - "\0\u0c50\0\u0d15\0\u0dda\0\u0e9f\0\u0f64\0\u1029\0\u10ee\0\u11b3"+ - "\0\u1278\0\u133d\0\u1402\0\u14c7\0\u158c\0\u1651\0\u1716\0\u17db"+ - "\0\u18a0\0\u1965\0\u1a2a\0\u1aef\0\u1bb4\0\u1c79\0\u1d3e\0\u1e03"+ - "\0\u1ec8\0\u1f8d\0\u018a\0\u024f\0\u2052\0\u2117\0\u049e\0\u0563"+ - "\0\u0628\0\u06ed\0\u21dc\0\u22a1\0\u2366\0\u242b\0\u0ac6\0\u24f0"+ - "\0\u25b5\0\u267a\0\u273f\0\u2804\0\u28c9\0\u298e\0\u03d9\0\u2a53"+ - "\0\u2b18\0\u093c\0\u2bdd\0\u2ca2\0\u2d67\0\u2e2c\0\u2ef1\0\u2fb6"+ - "\0\u307b\0\u3140\0\u3205\0\u32ca\0\u338f\0\u3454\0\u3519\0\u35de"+ - "\0\u36a3\0\u3768\0\u382d\0\u38f2\0\u39b7\0\u3a7c\0\u3b41\0\u3c06"+ - "\0\u1402\0\u3ccb\0\u3d90\0\u3e55\0\u3f1a\0\u3fdf\0\u40a4\0\u4169"+ - "\0\u422e\0\u42f3\0\u43b8\0\u447d\0\u4542\0\u4607\0\u46cc\0\u4791"+ - "\0\u4856\0\u491b\0\u49e0\0\u4aa5\0\u4b6a\0\u4c2f\0\u4cf4\0\u4db9"+ - "\0\u17db\0\u4e7e\0\u4f43\0\u5008\0\u50cd\0\u5192\0\u5257\0\u531c"+ - "\0\u53e1\0\u54a6\0\u556b\0\u5630\0\u56f5\0\u57ba\0\u587f\0\u5944"+ - "\0\u5a09\0\u5ace\0\u1e03\0\u5b93\0\u5c58\0\u1f8d\0\u5d1d\0\u5de2"+ - "\0\u5ea7\0\u5f6c\0\u6031\0\u60f6\0\u61bb\0\u6280\0\u6345\0\u640a"+ - "\0\u64cf\0\u6594\0\u6659\0\u671e\0\u67e3\0\u68a8\0\u696d\0\u6a32"+ - "\0\u6af7\0\u6bbc\0\u6c81\0\u6d46\0\u6e0b\0\u6ed0\0\u6f95\0\u705a"+ - "\0\u711f\0\u71e4\0\u72a9\0\u736e\0\u7433\0\u74f8\0\u75bd\0\u7682"+ - "\0\u7747\0\u780c\0\u78d1\0\u7996\0\u7a5b\0\u7b20\0\u7be5\0\u7caa"+ - "\0\u7d6f\0\u7e34\0\u7ef9\0\u7fbe\0\u8083\0\u8148\0\u820d\0\u82d2"+ - "\0\u8397\0\u845c\0\u8521\0\u85e6\0\u86ab\0\u8770\0\u8835\0\u88fa"+ - "\0\u89bf\0\u8a84\0\u8b49\0\u8c0e\0\u8cd3\0\u8d98\0\u8e5d\0\u8f22"+ - "\0\u8fe7\0\u90ac\0\u9171\0\u9236\0\u92fb\0\u93c0\0\u9485\0\u954a"+ - "\0\u960f\0\u96d4\0\u9799\0\u985e\0\u9923\0\u99e8\0\u9aad\0\u9b72"+ - "\0\u9c37\0\u9cfc\0\u9dc1\0\u9e86\0\u9f4b\0\ua010\0\ua0d5\0\ua19a"+ - "\0\ua25f\0\ua324\0\ua3e9\0\ua4ae\0\ua573\0\ua638\0\ua6fd\0\ua7c2"+ - "\0\ua887\0\ua94c\0\uaa11\0\uaad6\0\uab9b\0\uac60\0\uad25\0\uadea"+ - "\0\uaeaf\0\uaf74\0\ub039\0\ub0fe\0\ub1c3\0\ub288\0\ub34d\0\ub412"+ - "\0\ub4d7\0\ub59c\0\ub661\0\ub726\0\ub7eb\0\ub8b0\0\ub975\0\uba3a"+ - "\0\ubaff\0\ubbc4\0\ubc89\0\ubd4e\0\ube13\0\ubed8\0\ubf9d\0\uc062"+ - "\0\uc127\0\uc1ec\0\305\0\uc2b1\0\uc376\0\uc43b\0\uc500\0\uc5c5"+ - "\0\uc68a\0\uc74f\0\uc814\0\uc8d9\0\uc99e\0\uca63\0\ucb28\0\ucbed"+ - "\0\uccb2\0\ucd77\0\uce3c\0\ucf01\0\ucfc6\0\ud08b\0\ud150\0\ud215"+ - "\0\ud2da\0\ud39f\0\ud464\0\ud529\0\ud5ee\0\ud6b3\0\ud778\0\ud83d"+ - "\0\ud902\0\ud9c7\0\uda8c\0\udb51\0\udc16\0\udcdb\0\udda0\0\ude65"+ - "\0\udf2a\0\udfef\0\ue0b4\0\ue179\0\ue23e\0\ue303\0\ue3c8\0\ue48d"+ - "\0\ue552\0\ue617\0\ue6dc\0\ue7a1\0\ue866\0\ue92b\0\ue9f0\0\ueab5"+ - "\0\ueb7a\0\uec3f\0\ued04\0\uedc9\0\uee8e\0\uef53\0\uf018\0\uf0dd"+ - "\0\uf1a2\0\uf267\0\uf32c\0\uf3f1\0\uf4b6\0\uf57b\0\uf640\0\uf705"+ - "\0\uf7ca\0\uf88f\0\uf954\0\ufa19\0\ufade\0\ufba3\0\ufc68\0\ufd2d"+ - "\0\ufdf2\0\ufeb7\0\uff7c\1\101\1\u0106\1\u01cb\1\u0290\1\u0355"+ - "\1\u041a\1\u04df\1\u05a4\1\u0669\1\u072e\1\u07f3\1\u08b8\1\u097d"+ - "\1\u0a42\1\u0b07\1\u0bcc\1\u0c91\1\u0d56\1\u0e1b\1\u0ee0\1\u0fa5"+ - "\1\u106a\1\u112f\1\u11f4\1\u12b9\1\u137e\1\u1443\1\u1508\1\u15cd"+ - "\1\u1692\1\u1757\1\u181c\1\u18e1\1\u19a6\1\u1a6b\1\u1b30\1\u1bf5"+ - "\1\u1cba\1\u1d7f\1\u1e44\1\u1f09\1\u1fce\1\u2093\1\u2158\1\u221d"+ - "\1\u22e2\1\u23a7\1\u246c\1\u2531\1\u25f6\1\u26bb\1\u2780\1\u2845"+ - "\1\u290a\1\u29cf\1\u2a94\1\u2b59\1\u2c1e\1\u2ce3\1\u2da8\1\u2e6d"+ - "\1\u2f32\1\u2ff7\1\u30bc\1\u3181\1\u3246\1\u330b\1\u33d0\1\u3495"+ - "\1\u355a\1\u361f\1\u36e4\1\u37a9\1\u386e\1\u3933\1\u39f8\1\u3abd"+ - "\1\u3b82\1\u3c47\1\u3d0c\1\u3dd1\1\u3e96\1\u3f5b\1\u4020\1\u40e5"+ - "\1\u41aa\1\u426f\1\u4334\1\u43f9\1\u44be\1\u4583\1\u4648\1\u470d"+ - "\1\u47d2\1\u4897\1\u495c\1\u4a21\1\u4ae6\1\u4bab\1\u4c70\1\u4d35"+ - "\1\u4dfa\1\u4ebf\1\u4f84\1\u5049\1\u510e\1\u51d3\1\u5298\1\u535d"+ - "\0\uc127\1\u5422\1\u54e7\1\u55ac\1\u5671\1\u5736\1\u57fb\1\u58c0"+ - "\1\u5985\1\u5a4a\1\u5b0f\1\u5bd4\1\u5c99\1\u5d5e\1\u5e23\1\u5ee8"+ - "\1\u5fad\1\u6072\1\u6137\1\u61fc\1\u62c1\1\u6386\1\u644b\1\u6510"+ - "\1\u65d5\1\u669a\1\u675f\1\u6824\1\u68e9\1\u69ae\1\u6a73\1\u6b38"+ - "\1\u6bfd\1\u6cc2\1\u6d87\1\u6e4c\1\u6f11\1\u6fd6\1\u709b\1\u7160"+ - "\1\u7225\1\u72ea\1\u73af\1\u7474\1\u7539\1\u75fe\1\u76c3\1\u7788"+ - "\1\u784d\1\u7912\1\u79d7\1\u7a9c\1\u7b61\1\u7c26\1\u7ceb\1\u7db0"+ - "\1\u7e75\1\u7f3a\1\u7fff\1\u80c4\1\u8189\1\u824e\1\u8313\1\u83d8"+ - "\1\u849d\1\u8562\1\u8627\1\u86ec\1\u87b1\1\u8876\1\u893b\1\u8a00"+ - "\1\u8ac5\1\u8b8a\1\u8c4f\1\u8d14\1\u8dd9\1\u8e9e\1\u8f63\1\u9028"+ - "\1\u90ed\1\u91b2\1\u9277\1\u933c\1\u9401\1\u94c6\1\u958b\1\u9650"+ - "\1\u9715\1\u97da\1\u989f\1\u9964\1\u9a29\1\u9aee\1\u9bb3\1\u9c78"+ - "\1\u9d3d\1\u9e02\1\u9ec7\1\u9f8c\1\ua051\1\ua116\1\ua1db\1\ua2a0"+ - "\1\ua365\1\ua42a\1\ua4ef\1\ua5b4\1\ua679\1\ua73e\1\ua803\1\ua8c8"+ - "\1\ua98d\1\uaa52\1\uab17\1\uabdc\1\uaca1\1\uad66\1\uae2b\1\uaef0"+ - "\0\u1ec8\1\uafb5\1\ub07a\1\ub13f\1\ub204\1\ub2c9\1\ub38e\1\ub453"+ - "\1\ub518\1\ub5dd\1\ub6a2\1\ub767\1\ub82c\1\ub8f1\1\ub9b6\1\uba7b"+ - "\1\ubb40\1\ubc05\1\ubcca\1\ubd8f\1\ube54\1\ubf19\1\ubfde\1\uc0a3"+ - "\1\uc168\1\uc22d\1\uc2f2\1\uc3b7\1\uc47c\1\uc541\1\uc606\1\uc6cb"+ - "\1\uc790\1\uc855\1\uc91a\1\uc9df\1\ucaa4\1\ucb69\1\ucc2e\1\uccf3"+ - "\1\ucdb8\1\uce7d\1\ucf42\1\ud007\1\ud0cc\1\ud191\1\ud256\1\ud31b"+ - "\1\ud3e0\1\ud4a5\1\ud56a\1\ud62f\1\ud6f4\1\ud7b9\1\ud87e\1\ud943"+ - "\1\uda08\1\udacd\1\udb92\1\udc57\1\udd1c\1\udde1\1\udea6\1\udf6b"+ - "\1\ue030\1\ue0f5\1\ue1ba\1\ue27f\1\ue344\1\ue409\1\ue4ce\1\ue593"+ - "\1\ue658\1\ue71d\1\ue7e2\1\ue8a7\1\ue96c\1\uea31\1\ueaf6\1\uebbb"+ - "\1\uec80\1\ued45\1\uee0a\1\ueecf\1\uef94\1\uf059\1\uf11e\1\uf1e3"+ - "\1\uf2a8\1\uf36d\1\uf432\1\uf4f7\1\uf5bc\1\uf681\1\uf746\1\uf80b"+ - "\1\uf8d0\1\uf995\1\ufa5a\1\ufb1f\1\ufbe4\1\ufca9\1\ufd6e\1\ufe33"+ - "\1\ufef8\1\uffbd\2\202\2\u0147\2\u020c\2\u02d1\2\u0396\2\u045b"+ - "\2\u0520\2\u05e5\2\u06aa\2\u076f\2\u0834\2\u08f9\2\u09be\2\u0a83"+ - "\2\u0b48\2\u0c0d\2\u0cd2\2\u0d97\2\u0e5c\2\u0f21\2\u0fe6\2\u10ab"+ - "\2\u1170\2\u1235\2\u12fa\2\u13bf\2\u1484\2\u1549\2\u160e\2\u16d3"+ - "\2\u1798\2\u185d\2\u1922\2\u19e7\2\u1aac\2\u1b71\2\u1c36\2\u1cfb"+ - "\2\u1dc0\2\u1e85\2\u1f4a\2\u200f\2\u20d4\2\u2199\2\u225e\2\u2323"+ - "\2\u23e8\2\u24ad\2\u2572\2\u2637\2\u26fc\2\u27c1\2\u2886\2\u294b"+ - "\2\u2a10\2\u2ad5\2\u2b9a\2\u2c5f\2\u2d24\2\u2de9\2\u2eae\2\u2f73"+ - "\2\u3038\2\u30fd\2\u31c2\2\u3287\2\u334c\2\u3411\2\u34d6\2\u359b"+ - "\2\u3660\2\u3725\2\u37ea\2\u38af\2\u3974\2\u3a39\2\u3afe\2\u3bc3"+ - "\2\u3c88\2\u3d4d\2\u3e12\2\u3ed7\2\u3f9c\2\u4061\2\u4126\2\u41eb"+ - "\2\u42b0\2\u4375\2\u443a\2\u44ff\2\u45c4\2\u4689\2\u474e\2\u4813"+ - "\2\u48d8\2\u499d\2\u4a62\2\u4b27\2\u4bec\2\u4cb1\2\u4d76\2\u4e3b"+ - "\2\u4f00\2\u4fc5\2\u508a\2\u514f\2\u5214\2\u52d9\2\u539e\2\u5463"+ - "\2\u5528\2\u55ed\2\u56b2\2\u5777\2\u583c\2\u5901\2\u59c6\2\u5a8b"+ - "\2\u5b50\2\u5c15\2\u5cda\2\u5d9f\2\u5e64\2\u5f29\2\u5fee\2\u60b3"+ - "\2\u6178\2\u623d\2\u6302\2\u63c7\2\u648c\2\u6551\2\u6616\2\u66db"+ - "\2\u67a0\2\u6865\2\u692a\2\u69ef\2\u6ab4\2\u6b79\2\u6c3e\2\u6d03"+ - "\2\u6dc8\2\u6e8d\2\u6f52\2\u7017\2\u70dc\2\u71a1\2\u7266\2\u732b"+ - "\2\u73f0\2\u74b5\2\u757a\2\u763f\2\u7704\2\u77c9\2\u788e\2\u7953"+ - "\2\u7a18\2\u7add\2\u7ba2\2\u7c67\2\u7d2c\2\u7df1\2\u7eb6\2\u7f7b"+ - "\2\u8040\2\u8105\2\u81ca\2\u828f\2\u8354\2\u8419\2\u84de\2\u85a3"+ - "\2\u8668\2\u872d\2\u87f2\2\u88b7\2\u897c\2\u8a41\2\u8b06\2\u8bcb"+ - "\2\u8c90\2\u8d55\2\u8e1a\2\u8edf\2\u8fa4\2\u9069\2\u912e\2\u91f3"+ - "\2\u92b8\2\u937d\2\u9442\2\u9507\2\u95cc\2\u9691\2\u9756\2\u981b"+ - "\0\305\2\u98e0\2\u99a5\2\u9a6a\2\u9b2f\2\u9bf4\2\u9cb9\2\u9d7e"+ - "\2\u9e43\2\u9f08\2\u9fcd\2\ua092\2\ua157\2\ua21c\2\ua2e1\2\ua3a6"+ - "\2\ua46b\2\ua530\2\ua5f5\2\ua6ba\2\ua77f\2\ua844\2\ua909\2\ua9ce"+ - "\2\uaa93\2\uab58\2\uac1d\2\uace2\2\uada7\2\uae6c\2\uaf31\2\uaff6"+ - "\2\ub0bb\2\ub180\2\ub245\2\ub30a\2\ub3cf\2\ub494\2\ub559\2\ub61e"+ - "\2\ub6e3\2\ub7a8\2\ub86d\2\ub932\2\ub9f7\2\ubabc\2\ubb81\2\ubc46"+ - "\2\ubd0b\2\ubdd0\2\ube95\2\ubf5a\2\uc01f\2\uc0e4\2\uc1a9\2\uc26e"+ - "\2\uc333\2\uc3f8\2\uc4bd\2\uc582\2\uc647\2\uc70c\2\uc7d1\2\uc896"+ - "\2\uc95b\2\uca20\2\ucae5\2\ucbaa\2\ucc6f\2\ucd34\2\ucdf9\2\ucebe"+ - "\2\ucf83\2\ud048\2\ud10d\2\ud1d2\2\ud297\2\ud35c\2\ud421\2\ud4e6"+ - "\2\ud5ab\2\ud670\2\ud735\2\ud7fa\2\ud8bf\2\ud984\2\uda49\2\udb0e"+ - "\2\udbd3\2\udc98\2\udd5d\2\ude22\2\udee7\2\udfac\2\ue071\2\ue136"+ - "\2\ue1fb\2\ue2c0\2\ue385\2\ue44a\2\ue50f\2\ue5d4\2\ue699\2\ue75e"+ - "\2\ue823\2\ue8e8\2\ue9ad\2\uea72\2\ueb37\2\uebfc\2\uecc1\2\ued86"+ - "\2\uee4b\2\uef10\2\uefd5\2\uf09a\2\uf15f\2\uf224\2\uf2e9\2\uf3ae"+ - "\2\uf473\2\uf538\2\uf5fd\2\uf6c2\2\uf787\2\uf84c\2\uf911\2\uf9d6"+ - "\2\ufa9b\2\ufb60\2\ufc25\2\ufcea\2\ufdaf\2\ufe74\2\uff39\2\ufffe"+ - "\3\303\3\u0188\3\u024d\3\u0312\3\u03d7\3\u049c\3\u0561\3\u0626"+ - "\3\u06eb\3\u07b0\3\u0875\3\u093a\3\u09ff\3\u0ac4\3\u0b89\3\u0c4e"+ - "\3\u0d13\3\u0dd8\3\u0e9d\3\u0f62\3\u1027\3\u10ec\3\u11b1\3\u1276"+ - "\3\u133b\3\u1400\3\u14c5\3\u158a\3\u164f\3\u1714\3\u17d9\3\u189e"+ - "\3\u1963\3\u1a28\3\u1aed\3\u1bb2\3\u1c77\3\u1d3c\3\u1e01\3\u1ec6"+ - "\3\u1f8b\3\u2050\3\u2115\3\u21da\3\u229f\3\u2364\3\u2429\3\u24ee"+ - "\3\u25b3\3\u2678\3\u273d\3\u2802\3\u28c7\3\u298c\3\u2a51\3\u2b16"+ - "\3\u2bdb\3\u2ca0\3\u2d65\3\u2e2a\3\u2eef\3\u2fb4\3\u3079\3\u313e"+ - "\3\u3203\3\u32c8\3\u338d\3\u3452\3\u3517\3\u35dc\3\u36a1\3\u3766"+ - "\3\u382b\3\u38f0\3\u39b5\3\u3a7a\3\u3b3f\3\u3c04\3\u3cc9\3\u3d8e"+ - "\3\u3e53\3\u3f18\3\u3fdd\3\u40a2\3\u4167\3\u422c\3\u42f1\3\u43b6"+ - "\3\u447b\3\u4540\3\u4605\3\u46ca\3\u478f\3\u4854\3\u4919\3\u49de"+ - "\3\u4aa3\3\u4b68\3\u4c2d\3\u4cf2\3\u4db7\3\u4e7c\3\u4f41\3\u5006"+ - "\3\u50cb\3\u5190\3\u5255\3\u531a\3\u53df\3\u54a4\3\u5569\3\u562e"+ - "\3\u56f3\3\u57b8\3\u587d\3\u5942\3\u5a07\3\u5acc\3\u5b91\3\u5c56"+ - "\3\u5d1b\3\u5de0\3\u5ea5\3\u5f6a\3\u602f\3\u60f4\3\u61b9\3\u627e"+ - "\3\u6343\3\u6408\3\u64cd\3\u6592\3\u6657\3\u671c\3\u67e1\3\u68a6"+ - "\3\u696b\3\u6a30\3\u6af5\3\u6bba\3\u6c7f\3\u6d44\3\u6e09\3\u6ece"+ - "\3\u6f93\3\u7058\3\u711d\3\u71e2\3\u72a7\3\u736c\3\u7431\3\u74f6"+ - "\3\u75bb\3\u7680\3\u7745\3\u780a\3\u78cf\3\u7994\3\u7a59\3\u7b1e"+ - "\3\u7be3\3\u7ca8\3\u7d6d\3\u7e32\3\u7ef7\3\u7fbc\3\u8081\3\u8146"+ - "\3\u820b\3\u82d0\3\u8395\3\u845a\3\u851f\3\u85e4\3\u86a9\3\u876e"+ - "\3\u8833\3\u88f8\3\u89bd\3\u8a82\2\u9756\3\u8b47\3\u8c0c\3\u8cd1"+ - "\3\u8d96\3\u8e5b\3\u8f20\3\u8fe5\3\u90aa\3\u916f\3\u9234\3\u92f9"+ - "\3\u93be\3\u9483\3\u9548\3\u960d\3\u96d2\3\u9797\3\u985c\3\u9921"+ - "\3\u99e6\3\u9aab\3\u9b70\3\u9c35\3\u9cfa\3\u9dbf\3\u9e84\3\u9f49"+ - "\3\ua00e\3\ua0d3\3\ua198\3\ua25d\3\ua322\3\ua3e7\3\ua4ac\3\ua571"+ - "\3\ua636\3\ua6fb\3\ua7c0\3\ua885\3\ua94a\3\uaa0f\3\uaad4\3\uab99"+ - "\3\uac5e\3\uad23\3\uade8\3\uaead\3\uaf72\3\ub037\3\ub0fc\3\ub1c1"+ - "\3\ub286\3\ub34b\3\ub410\3\ub4d5\3\ub59a\3\ub65f\3\ub724\3\ub7e9"+ - "\3\ub8ae\3\ub973\3\uba38\3\ubafd\3\ubbc2\3\ubc87\3\ubd4c\3\ube11"+ - "\3\ubed6\3\ubf9b\3\uc060\3\uc125\3\uc1ea\3\uc2af\3\uc374\3\uc439"+ - "\3\uc4fe\3\uc5c3\3\uc688\3\uc74d\3\uc812\3\uc8d7\3\uc99c\3\uca61"+ - "\3\ucb26\3\ucbeb\3\uccb0\3\ucd75\3\uce3a\3\uceff\3\ucfc4\3\ud089"+ - "\3\ud14e\3\ud213\3\ud2d8\3\ud39d\3\ud462\3\ud527\3\ud5ec\3\ud6b1"+ - "\3\ud776\3\ud83b\3\ud900\3\ud9c5\3\uda8a\3\udb4f\3\udc14\3\udcd9"+ - "\3\udd9e\3\ude63\3\udf28\3\udfed\3\ue0b2\3\ue177\3\ue23c\3\ue301"+ - "\3\ue3c6\3\ue48b\3\ue550\3\ue615\3\ue6da\3\ue79f\3\ue864\3\ue929"+ - "\3\ue9ee\3\ueab3\3\ueb78\3\uec3d\3\ued02\3\uedc7\3\uee8c\3\uef51"+ - "\3\uf016\3\uf0db\3\uf1a0\3\uf265\3\uf32a\3\uf3ef\3\uf4b4\3\uf579"+ - "\3\uf63e\3\uf703\3\uf7c8\3\uf88d\3\uf952\3\ufa17\3\ufadc\3\ufba1"+ - "\3\ufc66\3\ufd2b\3\ufdf0\3\ufeb5\3\uff7a\4\77\4\u0104\4\u01c9"+ - "\4\u028e\4\u0353\4\u0418\4\u04dd\4\u05a2\4\u0667\4\u072c\4\u07f1"+ - "\4\u08b6\4\u097b\4\u0a40\4\u0b05\4\u0bca\4\u0c8f\4\u0d54\4\u0e19"+ - "\4\u0ede\4\u0fa3\4\u1068\4\u112d\4\u11f2\4\u12b7\4\u137c\4\u1441"+ - "\4\u1506\4\u15cb\4\u1690\4\u1755\4\u181a\4\u18df\4\u19a4\4\u1a69"+ - "\4\u1b2e\4\u1bf3\4\u1cb8\4\u1d7d\4\u1e42\4\u1f07\4\u1fcc\4\u2091"+ - "\4\u2156\4\u221b\4\u22e0\4\u23a5\4\u246a\4\u252f\4\u25f4\4\u26b9"+ - "\4\u277e\4\u2843\4\u2908\4\u29cd\4\u2a92\4\u2b57\4\u2c1c\4\u2ce1"+ - "\4\u2da6\4\u2e6b\4\u2f30\4\u2ff5\4\u30ba\4\u317f\4\u3244\4\u3309"+ - "\4\u33ce\4\u3493\4\u3558\4\u361d\4\u36e2\4\u37a7\4\u386c\4\u3931"+ - "\4\u39f6\4\u3abb\4\u3b80\4\u3c45\4\u3d0a\4\u3dcf\4\u3e94\4\u3f59"+ - "\4\u401e\4\u40e3\4\u41a8\4\u426d\4\u4332\4\u43f7\4\u44bc\4\u4581"+ - "\4\u4646\4\u470b\4\u47d0\4\u4895\4\u495a\4\u4a1f\4\u4ae4\4\u4ba9"+ - "\4\u4c6e\4\u4d33\4\u4df8\4\u4ebd\4\u4f82\4\u5047\4\u510c\4\u51d1"+ - "\4\u5296\4\u535b\4\u5420\4\u54e5\4\u55aa\4\u566f\4\u5734\4\u57f9"+ - "\4\u58be\4\u5983\4\u5a48\4\u5b0d\4\u5bd2\4\u5c97\4\u5d5c\4\u5e21"+ - "\4\u5ee6\4\u5fab\4\u6070\4\u6135\4\u61fa\4\u62bf\4\u6384\4\u6449"+ - "\4\u650e\4\u65d3\4\u6698\4\u675d\4\u6822\4\u68e7\4\u69ac\4\u6a71"+ - "\4\u6b36\4\u6bfb\4\u6cc0\4\u6d85\4\u6e4a\4\u6f0f\4\u6fd4\4\u7099"+ - "\4\u715e\4\u7223\4\u72e8\4\u73ad\4\u7472\4\u7537\4\u75fc\4\u76c1"+ - "\4\u7786\4\u784b\4\u7910\4\u79d5\4\u7a9a\4\u7b5f\4\u7c24\4\u7ce9"+ - "\4\u7dae\4\u7e73\4\u7f38\4\u7ffd\4\u80c2\4\u8187\4\u824c\4\u8311"+ - "\4\u83d6\4\u849b\4\u8560\4\u8625\4\u86ea\4\u87af\4\u8874\4\u8939"+ - "\4\u89fe\4\u8ac3\4\u8b88\4\u8c4d\4\u8d12\4\u8dd7\4\u8e9c\4\u8f61"+ - "\4\u9026\4\u90eb\4\u91b0\4\u9275\4\u933a\4\u93ff\4\u94c4\4\u9589"+ - "\4\u964e\4\u9713\4\u97d8\4\u989d\4\u9962\4\u9a27\4\u9aec\4\u9bb1"+ - "\4\u9c76\4\u9d3b\4\u9e00\4\u9ec5\4\u9f8a\4\ua04f\4\ua114\4\ua1d9"+ - "\4\ua29e\4\ua363\4\ua428\4\ua4ed\4\ua5b2\4\ua677\4\ua73c\4\ua801"+ - "\4\ua8c6\4\ua98b\4\uaa50\4\uab15\4\uabda\4\uac9f\4\uad64\4\uae29"+ - "\4\uaeee\4\uafb3\4\ub078\4\ub13d\4\ub202\4\ub2c7\4\ub38c\4\ub451"+ - "\4\ub516\4\ub5db\4\ub6a0\4\ub765\4\ub82a\4\ub8ef\4\ub9b4\4\uba79"+ - "\4\ubb3e\4\ubc03\4\ubcc8\4\ubd8d\4\ube52\4\ubf17\4\ubfdc\4\uc0a1"+ - "\4\uc166\4\uc22b\4\uc2f0\4\uc3b5\4\uc47a\4\uc53f\4\uc604\4\uc6c9"+ - "\4\uc78e\4\uc853\4\uc918\4\uc9dd\4\ucaa2\4\ucb67\4\ucc2c\4\uccf1"+ - "\4\ucdb6\4\uce7b\4\ucf40\4\ud005\4\ud0ca\4\ud18f\4\ud254\4\ud319"+ - "\4\ud3de\4\ud4a3\4\ud568\4\ud62d\4\ud6f2\4\ud7b7\4\ud87c\4\ud941"+ - "\4\uda06\4\udacb\4\udb90\4\udc55\4\udd1a\4\udddf\4\udea4\4\udf69"+ - "\4\ue02e\4\ue0f3\4\ue1b8\4\ue27d\4\ue342\4\ue407\4\ue4cc\4\ue591"+ - "\4\ue656\4\ue71b\4\ue7e0\4\ue8a5\4\ue96a\4\uea2f\4\ueaf4\4\uebb9"+ - "\4\uec7e\4\ued43\4\uee08\4\ueecd\4\uef92\4\uf057\4\uf11c\4\uf1e1"+ - "\4\uf2a6\4\uf36b\4\uf430\4\uf4f5\4\uf5ba\4\uf67f\4\uf744\4\uf809"+ - "\4\uf8ce\4\uf993\4\ufa58\4\ufb1d\4\ufbe2\4\ufca7\4\ufd6c\4\ufe31"+ - "\4\ufef6\4\uffbb\5\200\5\u0145\5\u020a\5\u02cf\5\u0394\5\u0459"+ - "\5\u051e\5\u05e3\5\u06a8\5\u076d\5\u0832\5\u08f7\5\u09bc\5\u0a81"+ - "\5\u0b46\5\u0c0b\5\u0cd0\5\u0d95\5\u0e5a\5\u0f1f\5\u0fe4\5\u10a9"+ - "\5\u116e\5\u1233\5\u12f8\5\u13bd\5\u1482\5\u1547\5\u160c\5\u16d1"+ - "\5\u1796\5\u185b\5\u1920\5\u19e5\5\u1aaa\5\u1b6f\5\u1c34\5\u1cf9"+ - "\5\u1dbe\5\u1e83\5\u1f48\5\u200d\5\u20d2\5\u2197\5\u225c\5\u2321"+ - "\5\u23e6\5\u24ab\5\u2570\5\u2635\5\u26fa\5\u27bf\5\u2884\5\u2949"+ - "\5\u2a0e\5\u2ad3\5\u2b98\5\u2c5d\5\u2d22\5\u2de7\5\u2eac\5\u2f71"+ - "\5\u3036\5\u30fb\5\u31c0\5\u3285\5\u334a\5\u340f"; + "\0\0\0\310\0\u0190\0\u0258\0\u0320\0\u03e8\0\u04b0\0\u0578"+ + "\0\u0640\0\u0708\0\u07d0\0\u0898\0\u0960\0\u0a28\0\u0af0\0\u0bb8"+ + "\0\u0c80\0\u0d48\0\u0e10\0\u0ed8\0\u0fa0\0\u1068\0\u1130\0\u11f8"+ + "\0\u12c0\0\u1388\0\u1450\0\u1518\0\u15e0\0\u16a8\0\u1770\0\u1838"+ + "\0\u1900\0\u19c8\0\u1a90\0\u1b58\0\u1c20\0\u1ce8\0\u1db0\0\u1e78"+ + "\0\u1f40\0\u2008\0\u20d0\0\u2198\0\u0190\0\u0258\0\u2260\0\u2328"+ + "\0\u04b0\0\u0578\0\u0640\0\u0708\0\u23f0\0\u24b8\0\u2580\0\u2648"+ + "\0\u0af0\0\u2710\0\u27d8\0\u28a0\0\u2968\0\u2a30\0\u2af8\0\u2bc0"+ + "\0\u03e8\0\u2c88\0\u2d50\0\u0960\0\u2e18\0\u2ee0\0\u2fa8\0\u3070"+ + "\0\u3138\0\u3200\0\u32c8\0\u3390\0\u3458\0\u3520\0\u35e8\0\u36b0"+ + "\0\u3778\0\u3840\0\u3908\0\u39d0\0\u3a98\0\u3b60\0\u3c28\0\u3cf0"+ + "\0\u3db8\0\u3e80\0\u3f48\0\u1450\0\u4010\0\u40d8\0\u41a0\0\u4268"+ + "\0\u4330\0\u43f8\0\u44c0\0\u4588\0\u4650\0\u4718\0\u47e0\0\u48a8"+ + "\0\u4970\0\u4a38\0\u4b00\0\u1770\0\u4bc8\0\u4c90\0\u1838\0\u4d58"+ + "\0\u4e20\0\u4ee8\0\u4fb0\0\u5078\0\u5140\0\u5208\0\u52d0\0\u5398"+ + "\0\u5460\0\u5528\0\u55f0\0\u56b8\0\u5780\0\u5848\0\u5910\0\u59d8"+ + "\0\u5aa0\0\u5b68\0\u5c30\0\u5cf8\0\u5dc0\0\u5e88\0\u5f50\0\u6018"+ + "\0\u60e0\0\u61a8\0\u6270\0\u6338\0\u6400\0\u64c8\0\u6590\0\u6658"+ + "\0\u2008\0\u6720\0\u67e8\0\u68b0\0\u6978\0\u6a40\0\u6b08\0\u6bd0"+ + "\0\u6c98\0\u6d60\0\u6e28\0\u6ef0\0\u6fb8\0\u7080\0\u7148\0\u7210"+ + "\0\u72d8\0\u73a0\0\u7468\0\u7530\0\u75f8\0\u76c0\0\u7788\0\u7850"+ + "\0\u7918\0\u79e0\0\u7aa8\0\u7b70\0\u7c38\0\u7d00\0\u7dc8\0\u7e90"+ + "\0\u7f58\0\u8020\0\u80e8\0\u81b0\0\u8278\0\u8340\0\u8408\0\u84d0"+ + "\0\u8598\0\u8660\0\u8728\0\u87f0\0\u88b8\0\u8980\0\u8a48\0\u8b10"+ + "\0\u8bd8\0\u8ca0\0\u8d68\0\u8e30\0\u8ef8\0\u8fc0\0\u9088\0\u9150"+ + "\0\u9218\0\u92e0\0\u93a8\0\u9470\0\u9538\0\u9600\0\u96c8\0\u9790"+ + "\0\u9858\0\u9920\0\u99e8\0\u9ab0\0\u9b78\0\u9c40\0\u9d08\0\u9dd0"+ + "\0\u9e98\0\u9f60\0\ua028\0\ua0f0\0\ua1b8\0\ua280\0\ua348\0\ua410"+ + "\0\ua4d8\0\ua5a0\0\ua668\0\ua730\0\ua7f8\0\ua8c0\0\ua988\0\uaa50"+ + "\0\uab18\0\uabe0\0\uaca8\0\uad70\0\uae38\0\uaf00\0\uafc8\0\ub090"+ + "\0\ub158\0\ub220\0\ub2e8\0\ub3b0\0\ub478\0\ub540\0\ub608\0\ub6d0"+ + "\0\ub798\0\ub860\0\ub928\0\ub9f0\0\ubab8\0\ubb80\0\ubc48\0\ubd10"+ + "\0\ubdd8\0\ubea0\0\ubf68\0\uc030\0\uc0f8\0\uc1c0\0\uc288\0\uc350"+ + "\0\uc418\0\uc4e0\0\uc5a8\0\uc670\0\uc738\0\uc800\0\uc8c8\0\uc990"+ + "\0\uca58\0\ucb20\0\ucbe8\0\uccb0\0\ucd78\0\uce40\0\ucf08\0\ucfd0"+ + "\0\ud098\0\ud160\0\ud228\0\ud2f0\0\ud3b8\0\ud480\0\ud548\0\ud610"+ + "\0\ud6d8\0\ud7a0\0\ud868\0\ud930\0\ud9f8\0\udac0\0\udb88\0\udc50"+ + "\0\udd18\0\udde0\0\udea8\0\udf70\0\ue038\0\ue100\0\ue1c8\0\ue290"+ + "\0\ue358\0\ue420\0\ue4e8\0\ue5b0\0\ue678\0\ue740\0\ue808\0\310"+ + "\0\ue8d0\0\ue998\0\uea60\0\ueb28\0\uebf0\0\uecb8\0\ued80\0\uee48"+ + "\0\uef10\0\uefd8\0\uf0a0\0\uf168\0\uf230\0\uf2f8\0\uf3c0\0\uf488"+ + "\0\uf550\0\uf618\0\uf6e0\0\uf7a8\0\uf870\0\uf938\0\ufa00\0\ufac8"+ + "\0\ufb90\0\ufc58\0\ufd20\0\ufde8\0\ufeb0\0\uff78\1\100\1\u0108"+ + "\1\u01d0\1\u0298\1\u0360\1\u0428\1\u04f0\1\u05b8\1\u0680\1\u0748"+ + "\1\u0810\1\u08d8\1\u09a0\1\u0a68\1\u0b30\1\u0bf8\1\u0cc0\1\u0d88"+ + "\1\u0e50\1\u0f18\1\u0fe0\1\u10a8\1\u1170\1\u1238\1\u1300\1\u13c8"+ + "\1\u1490\1\u1558\1\u1620\1\u16e8\1\u17b0\1\u1878\1\u1940\1\u1a08"+ + "\1\u1ad0\1\u1b98\1\u1c60\1\u1d28\1\u1df0\1\u1eb8\1\u1f80\1\u2048"+ + "\1\u2110\1\u21d8\1\u22a0\1\u2368\1\u2430\1\u24f8\1\u25c0\1\u2688"+ + "\1\u2750\1\u2818\1\u28e0\1\u29a8\1\u2a70\1\u2b38\1\u2c00\1\u2cc8"+ + "\1\u2d90\1\u2e58\1\u2f20\1\u2fe8\1\u30b0\1\u3178\1\u3240\1\u3308"+ + "\1\u33d0\1\u3498\1\u3560\1\u3628\1\u36f0\1\u37b8\1\u3880\1\u3948"+ + "\1\u3a10\1\u3ad8\1\u3ba0\1\u3c68\1\u3d30\1\u3df8\1\u3ec0\1\u3f88"+ + "\1\u4050\1\u4118\1\u41e0\1\u42a8\1\u4370\1\u4438\1\u4500\1\u45c8"+ + "\1\u4690\1\u4758\1\u4820\1\u48e8\1\u49b0\1\u4a78\1\u4b40\1\u4c08"+ + "\1\u4cd0\1\u4d98\1\u4e60\1\u4f28\1\u4ff0\1\u50b8\1\u5180\1\u5248"+ + "\1\u5310\1\u53d8\1\u54a0\1\u5568\1\u5630\1\u56f8\1\u57c0\1\u5888"+ + "\1\u5950\1\u5a18\1\u5ae0\1\u5ba8\1\u5c70\1\u5d38\1\u5e00\1\u5ec8"+ + "\1\u5f90\1\u6058\1\u6120\1\u61e8\1\u62b0\1\u6378\1\u6440\1\u6508"+ + "\1\u65d0\1\u6698\1\u6760\1\u6828\1\u68f0\1\u69b8\1\u6a80\1\u6b48"+ + "\1\u6c10\1\u6cd8\1\u6da0\1\u6e68\1\u6f30\1\u6ff8\1\u70c0\1\u7188"+ + "\1\u7250\1\u7318\1\u73e0\1\u74a8\1\u7570\1\u7638\1\u7700\1\u77c8"+ + "\1\u7890\1\u7958\1\u7a20\1\u7ae8\1\u7bb0\1\u7c78\1\u7d40\1\u7e08"+ + "\1\u7ed0\1\u7f98\1\u8060\1\u8128\1\u81f0\1\u82b8\1\u8380\1\u8448"+ + "\1\u8510\1\u85d8\1\u86a0\1\u8768\1\u8830\1\u88f8\1\u89c0\1\u8a88"+ + "\1\u8b50\1\u8c18\1\u8ce0\1\u8da8\1\u8e70\1\u8f38\1\u9000\1\u90c8"+ + "\1\u9190\1\u9258\1\u9320\1\u93e8\1\u94b0\1\u9578\1\u9640\1\u9708"+ + "\1\u97d0\1\u9898\1\u9960\1\u9a28\1\u9af0\1\u9bb8\1\u9c80\1\u9d48"+ + "\1\u9e10\1\u9ed8\1\u9fa0\1\ua068\1\ua130\1\ua1f8\1\ua2c0\1\ua388"+ + "\1\ua450\1\ua518\1\ua5e0\1\ua6a8\1\ua770\1\ua838\1\ua900\1\ua9c8"+ + "\1\uaa90\1\uab58\1\uac20\1\uace8\1\uadb0\1\uae78\1\uaf40\1\ub008"+ + "\1\ub0d0\1\ub198\1\ub260\1\ub328\1\ub3f0\1\ub4b8\1\ub580\1\ub648"+ + "\1\ub710\1\ub7d8\1\ub8a0\1\ub968\1\uba30\1\ubaf8\1\ubbc0\1\ubc88"+ + "\1\ubd50\1\ube18\1\ubee0\1\ubfa8\1\uc070\1\uc138\1\uc200\1\uc2c8"+ + "\1\uc390\1\uc458\1\uc520\1\uc5e8\1\uc6b0\1\uc778\1\uc840\1\uc908"+ + "\1\uc9d0\1\uca98\1\ucb60\1\ucc28\1\uccf0\1\ucdb8\1\uce80\1\ucf48"+ + "\1\ud010\1\ud0d8\1\ud1a0\1\ud268\1\ud330\1\ud3f8\1\ud4c0\1\ud588"+ + "\1\ud650\1\ud718\1\ud7e0\1\ud8a8\1\ud970\1\uda38\1\udb00\1\udbc8"+ + "\1\udc90\1\udd58\1\ude20\1\udee8\1\udfb0\1\ue078\1\ue140\1\ue208"+ + "\1\ue2d0\1\ue398\1\ue460\1\ue528\1\ue5f0\1\ue6b8\1\ue780\1\ue848"+ + "\1\ue910\1\ue9d8\1\ueaa0\1\ueb68\1\uec30\1\uecf8\1\uedc0\1\uee88"+ + "\1\uef50\1\uf018\1\uf0e0\1\uf1a8\1\uf270\1\uf338\1\uf400\1\uf4c8"+ + "\1\uf590\1\uf658\1\uf720\1\uf7e8\1\uf8b0\1\uf978\1\ufa40\1\ufb08"+ + "\1\ufbd0\1\ufc98\1\ufd60\1\ufe28\1\ufef0\1\uffb8\2\200\2\u0148"+ + "\2\u0210\2\u02d8\2\u03a0\2\u0468\2\u0530\2\u05f8\2\u06c0\2\u0788"+ + "\0\ue740\2\u0850\2\u0918\2\u09e0\2\u0aa8\2\u0b70\2\u0c38\2\u0d00"+ + "\2\u0dc8\2\u0e90\2\u0f58\2\u1020\2\u10e8\2\u11b0\2\u1278\2\u1340"+ + "\2\u1408\2\u14d0\2\u1598\2\u1660\2\u1728\2\u17f0\2\u18b8\2\u1980"+ + "\2\u1a48\2\u1b10\2\u1bd8\2\u1ca0\2\u1d68\2\u1e30\2\u1ef8\2\u1fc0"+ + "\2\u2088\2\u2150\2\u2218\2\u22e0\2\u23a8\2\u2470\2\u2538\2\u2600"+ + "\2\u26c8\2\u2790\2\u2858\2\u2920\2\u29e8\2\u2ab0\2\u2b78\2\u2c40"+ + "\2\u2d08\2\u2dd0\2\u2e98\2\u2f60\2\u3028\2\u30f0\2\u31b8\2\u3280"+ + "\2\u3348\2\u3410\2\u34d8\2\u35a0\2\u3668\2\u3730\2\u37f8\2\u38c0"+ + "\2\u3988\2\u3a50\2\u3b18\2\u3be0\2\u3ca8\2\u3d70\2\u3e38\2\u3f00"+ + "\2\u3fc8\2\u4090\2\u4158\2\u4220\2\u42e8\2\u43b0\2\u4478\2\u4540"+ + "\2\u4608\2\u46d0\2\u4798\2\u4860\2\u4928\2\u49f0\2\u4ab8\2\u4b80"+ + "\2\u4c48\2\u4d10\2\u4dd8\2\u4ea0\2\u4f68\2\u5030\2\u50f8\2\u51c0"+ + "\2\u5288\2\u5350\2\u5418\2\u54e0\2\u55a8\2\u5670\2\u5738\2\u5800"+ + "\2\u58c8\2\u5990\2\u5a58\2\u5b20\2\u5be8\2\u5cb0\2\u5d78\2\u5e40"+ + "\2\u5f08\2\u5fd0\2\u6098\2\u6160\2\u6228\2\u62f0\2\u63b8\2\u6480"+ + "\2\u6548\2\u6610\2\u66d8\2\u67a0\2\u6868\2\u6930\2\u69f8\2\u6ac0"+ + "\2\u6b88\2\u6c50\2\u6d18\2\u6de0\2\u6ea8\2\u6f70\2\u7038\2\u7100"+ + "\2\u71c8\2\u7290\2\u7358\2\u7420\2\u74e8\2\u75b0\2\u7678\2\u7740"+ + "\2\u7808\2\u78d0\2\u7998\2\u7a60\2\u7b28\2\u7bf0\2\u7cb8\2\u7d80"+ + "\2\u7e48\2\u7f10\2\u7fd8\2\u80a0\2\u8168\2\u8230\2\u82f8\2\u83c0"+ + "\2\u8488\2\u8550\2\u8618\2\u86e0\2\u87a8\2\u8870\2\u8938\2\u8a00"+ + "\2\u8ac8\2\u8b90\2\u8c58\2\u8d20\2\u8de8\2\u8eb0\2\u8f78\2\u9040"+ + "\2\u9108\2\u91d0\2\u9298\2\u9360\2\u9428\2\u94f0\2\u95b8\2\u9680"+ + "\2\u9748\2\u9810\2\u98d8\2\u99a0\2\u9a68\2\u9b30\2\u9bf8\2\u9cc0"+ + "\2\u9d88\2\u9e50\2\u9f18\2\u9fe0\2\ua0a8\2\ua170\2\ua238\2\ua300"+ + "\2\ua3c8\0\u20d0\2\ua490\2\ua558\2\ua620\2\ua6e8\2\ua7b0\2\ua878"+ + "\2\ua940\2\uaa08\2\uaad0\2\uab98\2\uac60\2\uad28\2\uadf0\2\uaeb8"+ + "\2\uaf80\2\ub048\2\ub110\2\ub1d8\2\ub2a0\2\ub368\2\ub430\2\ub4f8"+ + "\2\ub5c0\2\ub688\2\ub750\2\ub818\2\ub8e0\2\ub9a8\2\uba70\2\ubb38"+ + "\2\ubc00\2\ubcc8\2\ubd90\2\ube58\2\ubf20\2\ubfe8\2\uc0b0\2\uc178"+ + "\2\uc240\2\uc308\2\uc3d0\2\uc498\2\uc560\2\uc628\2\uc6f0\2\uc7b8"+ + "\2\uc880\2\uc948\2\uca10\2\ucad8\2\ucba0\2\ucc68\2\ucd30\2\ucdf8"+ + "\2\ucec0\2\ucf88\2\ud050\2\ud118\2\ud1e0\2\ud2a8\2\ud370\2\ud438"+ + "\2\ud500\2\ud5c8\2\ud690\2\ud758\2\ud820\2\ud8e8\2\ud9b0\2\uda78"+ + "\2\udb40\2\udc08\2\udcd0\2\udd98\2\ude60\2\udf28\2\udff0\2\ue0b8"+ + "\2\ue180\2\ue248\2\ue310\2\ue3d8\2\ue4a0\2\ue568\2\ue630\2\ue6f8"+ + "\2\ue7c0\2\ue888\2\ue950\2\uea18\2\ueae0\2\ueba8\2\uec70\2\ued38"+ + "\2\uee00\2\ueec8\2\uef90\2\uf058\2\uf120\2\uf1e8\2\uf2b0\2\uf378"+ + "\2\uf440\2\uf508\2\uf5d0\2\uf698\2\uf760\2\uf828\2\uf8f0\2\uf9b8"+ + "\2\ufa80\2\ufb48\2\ufc10\2\ufcd8\2\ufda0\2\ufe68\2\uff30\2\ufff8"+ + "\3\300\3\u0188\3\u0250\3\u0318\3\u03e0\3\u04a8\3\u0570\3\u0638"+ + "\3\u0700\3\u07c8\3\u0890\3\u0958\3\u0a20\3\u0ae8\3\u0bb0\3\u0c78"+ + "\3\u0d40\3\u0e08\3\u0ed0\3\u0f98\3\u1060\3\u1128\3\u11f0\3\u12b8"+ + "\3\u1380\3\u1448\3\u1510\3\u15d8\3\u16a0\3\u1768\3\u1830\3\u18f8"+ + "\3\u19c0\3\u1a88\3\u1b50\3\u1c18\3\u1ce0\3\u1da8\3\u1e70\3\u1f38"+ + "\3\u2000\3\u20c8\3\u2190\3\u2258\3\u2320\3\u23e8\3\u24b0\3\u2578"+ + "\3\u2640\3\u2708\3\u27d0\3\u2898\3\u2960\3\u2a28\3\u2af0\3\u2bb8"+ + "\3\u2c80\3\u2d48\3\u2e10\3\u2ed8\3\u2fa0\3\u3068\3\u3130\3\u31f8"+ + "\3\u32c0\3\u3388\3\u3450\3\u3518\3\u35e0\3\u36a8\3\u3770\3\u3838"+ + "\3\u3900\3\u39c8\3\u3a90\3\u3b58\3\u3c20\3\u3ce8\3\u3db0\3\u3e78"+ + "\3\u3f40\3\u4008\3\u40d0\3\u4198\3\u4260\3\u4328\3\u43f0\3\u44b8"+ + "\3\u4580\3\u4648\3\u4710\3\u47d8\3\u48a0\3\u4968\3\u4a30\3\u4af8"+ + "\3\u4bc0\3\u4c88\3\u4d50\3\u4e18\3\u4ee0\3\u4fa8\3\u5070\3\u5138"+ + "\3\u5200\3\u52c8\3\u5390\3\u5458\3\u5520\3\u55e8\3\u56b0\3\u5778"+ + "\3\u5840\3\u5908\3\u59d0\3\u5a98\3\u5b60\3\u5c28\3\u5cf0\3\u5db8"+ + "\3\u5e80\3\u5f48\3\u6010\3\u60d8\3\u61a0\3\u6268\3\u6330\3\u63f8"+ + "\3\u64c0\3\u6588\3\u6650\3\u6718\3\u67e0\3\u68a8\3\u6970\3\u6a38"+ + "\3\u6b00\3\u6bc8\3\u6c90\3\u6d58\3\u6e20\3\u6ee8\3\u6fb0\3\u7078"+ + "\3\u7140\3\u7208\3\u72d0\3\u7398\3\u7460\3\u7528\3\u75f0\3\u76b8"+ + "\3\u7780\3\u7848\3\u7910\3\u79d8\3\u7aa0\3\u7b68\3\u7c30\3\u7cf8"+ + "\3\u7dc0\3\u7e88\3\u7f50\3\u8018\3\u80e0\3\u81a8\3\u8270\3\u8338"+ + "\3\u8400\3\u84c8\3\u8590\3\u8658\3\u8720\3\u87e8\3\u88b0\3\u8978"+ + "\3\u8a40\3\u8b08\3\u8bd0\3\u8c98\3\u8d60\3\u8e28\3\u8ef0\3\u8fb8"+ + "\3\u9080\3\u9148\3\u9210\3\u92d8\3\u93a0\3\u9468\3\u9530\3\u95f8"+ + "\3\u96c0\3\u9788\3\u9850\3\u9918\3\u99e0\3\u9aa8\3\u9b70\3\u9c38"+ + "\3\u9d00\3\u9dc8\3\u9e90\3\u9f58\3\ua020\3\ua0e8\3\ua1b0\3\ua278"+ + "\3\ua340\3\ua408\3\ua4d0\3\ua598\3\ua660\3\ua728\3\ua7f0\3\ua8b8"+ + "\3\ua980\3\uaa48\3\uab10\3\uabd8\3\uaca0\3\uad68\3\uae30\3\uaef8"+ + "\3\uafc0\3\ub088\3\ub150\3\ub218\0\310\3\ub2e0\3\ub3a8\3\ub470"+ + "\3\ub538\3\ub600\3\ub6c8\3\ub790\3\ub858\3\ub920\3\ub9e8\3\ubab0"+ + "\3\ubb78\3\ubc40\3\ubd08\3\ubdd0\3\ube98\3\ubf60\3\uc028\3\uc0f0"+ + "\3\uc1b8\3\uc280\3\uc348\3\uc410\3\uc4d8\3\uc5a0\3\uc668\3\uc730"+ + "\3\uc7f8\3\uc8c0\3\uc988\3\uca50\3\ucb18\3\ucbe0\3\ucca8\3\ucd70"+ + "\3\uce38\3\ucf00\3\ucfc8\3\ud090\3\ud158\3\ud220\3\ud2e8\3\ud3b0"+ + "\3\ud478\3\ud540\3\ud608\3\ud6d0\3\ud798\3\ud860\3\ud928\3\ud9f0"+ + "\3\udab8\3\udb80\3\udc48\3\udd10\3\uddd8\3\udea0\3\udf68\3\ue030"+ + "\3\ue0f8\3\ue1c0\3\ue288\3\ue350\3\ue418\3\ue4e0\3\ue5a8\3\ue670"+ + "\3\ue738\3\ue800\3\ue8c8\3\ue990\3\uea58\3\ueb20\3\uebe8\3\uecb0"+ + "\3\ued78\3\uee40\3\uef08\3\uefd0\3\uf098\3\uf160\3\uf228\3\uf2f0"+ + "\3\uf3b8\3\uf480\3\uf548\3\uf610\3\uf6d8\3\uf7a0\3\uf868\3\uf930"+ + "\3\uf9f8\3\ufac0\3\ufb88\3\ufc50\3\ufd18\3\ufde0\3\ufea8\3\uff70"+ + "\4\70\4\u0100\4\u01c8\4\u0290\4\u0358\4\u0420\4\u04e8\4\u05b0"+ + "\4\u0678\4\u0740\4\u0808\4\u08d0\4\u0998\4\u0a60\4\u0b28\4\u0bf0"+ + "\4\u0cb8\4\u0d80\4\u0e48\4\u0f10\4\u0fd8\4\u10a0\4\u1168\4\u1230"+ + "\4\u12f8\4\u13c0\4\u1488\4\u1550\4\u1618\4\u16e0\4\u17a8\4\u1870"+ + "\4\u1938\4\u1a00\4\u1ac8\4\u1b90\4\u1c58\4\u1d20\4\u1de8\4\u1eb0"+ + "\4\u1f78\4\u2040\4\u2108\4\u21d0\4\u2298\4\u2360\4\u2428\4\u24f0"+ + "\4\u25b8\4\u2680\4\u2748\4\u2810\4\u28d8\4\u29a0\4\u2a68\4\u2b30"+ + "\4\u2bf8\4\u2cc0\4\u2d88\4\u2e50\4\u2f18\4\u2fe0\4\u30a8\4\u3170"+ + "\4\u3238\4\u3300\4\u33c8\4\u3490\4\u3558\4\u3620\4\u36e8\4\u37b0"+ + "\4\u3878\4\u3940\4\u3a08\4\u3ad0\4\u3b98\4\u3c60\4\u3d28\4\u3df0"+ + "\4\u3eb8\4\u3f80\4\u4048\4\u4110\4\u41d8\4\u42a0\4\u4368\4\u4430"+ + "\4\u44f8\4\u45c0\4\u4688\4\u4750\4\u4818\4\u48e0\4\u49a8\4\u4a70"+ + "\4\u4b38\4\u4c00\4\u4cc8\4\u4d90\4\u4e58\4\u4f20\4\u4fe8\4\u50b0"+ + "\4\u5178\4\u5240\4\u5308\4\u53d0\4\u5498\4\u5560\4\u5628\4\u56f0"+ + "\4\u57b8\4\u5880\4\u5948\4\u5a10\4\u5ad8\4\u5ba0\4\u5c68\4\u5d30"+ + "\4\u5df8\4\u5ec0\4\u5f88\4\u6050\4\u6118\4\u61e0\4\u62a8\4\u6370"+ + "\4\u6438\4\u6500\4\u65c8\4\u6690\4\u6758\4\u6820\4\u68e8\4\u69b0"+ + "\4\u6a78\4\u6b40\4\u6c08\4\u6cd0\4\u6d98\4\u6e60\4\u6f28\4\u6ff0"+ + "\4\u70b8\4\u7180\4\u7248\4\u7310\4\u73d8\4\u74a0\4\u7568\4\u7630"+ + "\4\u76f8\4\u77c0\4\u7888\4\u7950\4\u7a18\4\u7ae0\4\u7ba8\4\u7c70"+ + "\4\u7d38\4\u7e00\4\u7ec8\4\u7f90\4\u8058\4\u8120\4\u81e8\4\u82b0"+ + "\4\u8378\4\u8440\4\u8508\4\u85d0\4\u8698\4\u8760\4\u8828\4\u88f0"+ + "\4\u89b8\4\u8a80\4\u8b48\4\u8c10\4\u8cd8\4\u8da0\4\u8e68\4\u8f30"+ + "\4\u8ff8\4\u90c0\4\u9188\4\u9250\4\u9318\4\u93e0\4\u94a8\4\u9570"+ + "\4\u9638\4\u9700\4\u97c8\4\u9890\4\u9958\4\u9a20\4\u9ae8\4\u9bb0"+ + "\4\u9c78\4\u9d40\4\u9e08\4\u9ed0\4\u9f98\4\ua060\4\ua128\4\ua1f0"+ + "\4\ua2b8\4\ua380\4\ua448\4\ua510\4\ua5d8\4\ua6a0\4\ua768\4\ua830"+ + "\4\ua8f8\4\ua9c0\4\uaa88\4\uab50\4\uac18\4\uace0\4\uada8\4\uae70"+ + "\4\uaf38\4\ub000\4\ub0c8\4\ub190\4\ub258\4\ub320\4\ub3e8\4\ub4b0"+ + "\3\ub150\4\ub578\4\ub640\4\ub708\4\ub7d0\4\ub898\4\ub960\4\uba28"+ + "\4\ubaf0\4\ubbb8\4\ubc80\4\ubd48\4\ube10\4\ubed8\4\ubfa0\4\uc068"+ + "\4\uc130\4\uc1f8\4\uc2c0\4\uc388\4\uc450\4\uc518\4\uc5e0\4\uc6a8"+ + "\4\uc770\4\uc838\4\uc900\4\uc9c8\4\uca90\4\ucb58\4\ucc20\4\ucce8"+ + "\4\ucdb0\4\uce78\4\ucf40\4\ud008\4\ud0d0\4\ud198\4\ud260\4\ud328"+ + "\4\ud3f0\4\ud4b8\4\ud580\4\ud648\4\ud710\4\ud7d8\4\ud8a0\4\ud968"+ + "\4\uda30\4\udaf8\4\udbc0\4\udc88\4\udd50\4\ude18\4\udee0\4\udfa8"+ + "\4\ue070\4\ue138\4\ue200\4\ue2c8\4\ue390\4\ue458\4\ue520\4\ue5e8"+ + "\4\ue6b0\4\ue778\4\ue840\4\ue908\4\ue9d0\4\uea98\4\ueb60\4\uec28"+ + "\4\uecf0\4\uedb8\4\uee80\4\uef48\4\uf010\4\uf0d8\4\uf1a0\4\uf268"+ + "\4\uf330\4\uf3f8\4\uf4c0\4\uf588\4\uf650\4\uf718\4\uf7e0\4\uf8a8"+ + "\4\uf970\4\ufa38\4\ufb00\4\ufbc8\4\ufc90\4\ufd58\4\ufe20\4\ufee8"+ + "\4\uffb0\5\170\5\u0140\5\u0208\5\u02d0\5\u0398\5\u0460\5\u0528"+ + "\5\u05f0\5\u06b8\5\u0780\5\u0848\5\u0910\5\u09d8\5\u0aa0\5\u0b68"+ + "\5\u0c30\5\u0cf8\5\u0dc0\5\u0e88\5\u0f50\5\u1018\5\u10e0\5\u11a8"+ + "\5\u1270\5\u1338\5\u1400\5\u14c8\5\u1590\5\u1658\5\u1720\5\u17e8"+ + "\5\u18b0\5\u1978\5\u1a40\5\u1b08\5\u1bd0\5\u1c98\5\u1d60\5\u1e28"+ + "\5\u1ef0\5\u1fb8\5\u2080\5\u2148\5\u2210\5\u22d8\5\u23a0\5\u2468"+ + "\5\u2530\5\u25f8\5\u26c0\5\u2788\5\u2850\5\u2918\5\u29e0\5\u2aa8"+ + "\5\u2b70\5\u2c38\5\u2d00\5\u2dc8\5\u2e90\5\u2f58\5\u3020\5\u30e8"+ + "\5\u31b0\5\u3278\5\u3340\5\u3408\5\u34d0\5\u3598\5\u3660\5\u3728"+ + "\5\u37f0\5\u38b8\5\u3980\5\u3a48\5\u3b10\5\u3bd8\5\u3ca0\5\u3d68"+ + "\5\u3e30\5\u3ef8\5\u3fc0\5\u4088\5\u4150\5\u4218\5\u42e0\5\u43a8"+ + "\5\u4470\5\u4538\5\u4600\5\u46c8\5\u4790\5\u4858\5\u4920\5\u49e8"+ + "\5\u4ab0\5\u4b78\5\u4c40\5\u4d08\5\u4dd0\5\u4e98\5\u4f60\5\u5028"+ + "\5\u50f0\5\u51b8\5\u5280\5\u5348\5\u5410\5\u54d8\5\u55a0\5\u5668"+ + "\5\u5730\5\u57f8\5\u58c0\5\u5988\5\u5a50\5\u5b18\5\u5be0\5\u5ca8"+ + "\5\u5d70\5\u5e38\5\u5f00\5\u5fc8\5\u6090\5\u6158\5\u6220\5\u62e8"+ + "\5\u63b0\5\u6478\5\u6540\5\u6608\5\u66d0\5\u6798\5\u6860\5\u6928"+ + "\5\u69f0\5\u6ab8\5\u6b80\5\u6c48\5\u6d10\5\u6dd8\5\u6ea0\5\u6f68"+ + "\5\u7030\5\u70f8\5\u71c0\5\u7288\5\u7350\5\u7418\5\u74e0\5\u75a8"+ + "\5\u7670\5\u7738\5\u7800\5\u78c8\5\u7990\5\u7a58\5\u7b20\5\u7be8"+ + "\5\u7cb0\5\u7d78\5\u7e40\5\u7f08\5\u7fd0\5\u8098\5\u8160\5\u8228"+ + "\5\u82f0\5\u83b8\5\u8480\5\u8548\5\u8610\5\u86d8\5\u87a0\5\u8868"+ + "\5\u8930\5\u89f8\5\u8ac0\5\u8b88\5\u8c50\5\u8d18\5\u8de0\5\u8ea8"+ + "\5\u8f70\5\u9038\5\u9100\5\u91c8\5\u9290\5\u9358\5\u9420\5\u94e8"+ + "\5\u95b0\5\u9678\5\u9740\5\u9808\5\u98d0\5\u9998\5\u9a60\5\u9b28"+ + "\5\u9bf0\5\u9cb8\5\u9d80\5\u9e48\5\u9f10\5\u9fd8\5\ua0a0\5\ua168"+ + "\5\ua230\5\ua2f8\5\ua3c0\5\ua488\5\ua550\5\ua618\5\ua6e0\5\ua7a8"+ + "\5\ua870\5\ua938\5\uaa00\5\uaac8\5\uab90\5\uac58\5\uad20\5\uade8"+ + "\5\uaeb0\5\uaf78\5\ub040\5\ub108\5\ub1d0\5\ub298\5\ub360\5\ub428"+ + "\5\ub4f0\5\ub5b8\5\ub680\5\ub748\5\ub810\5\ub8d8\5\ub9a0\5\uba68"+ + "\5\ubb30\5\ubbf8\5\ubcc0\5\ubd88\5\ube50\5\ubf18\5\ubfe0\5\uc0a8"+ + "\5\uc170\5\uc238\5\uc300\5\uc3c8\5\uc490\5\uc558\5\uc620\5\uc6e8"+ + "\5\uc7b0\5\uc878\5\uc940\5\uca08\5\ucad0\5\ucb98\5\ucc60\5\ucd28"+ + "\5\ucdf0\5\uceb8\5\ucf80\5\ud048\5\ud110\5\ud1d8\5\ud2a0\5\ud368"+ + "\5\ud430\5\ud4f8\5\ud5c0\5\ud688\5\ud750\5\ud818\5\ud8e0\5\ud9a8"+ + "\5\uda70\5\udb38\5\udc00\5\udcc8\5\udd90\5\ude58\5\udf20\5\udfe8"+ + "\5\ue0b0\5\ue178\5\ue240\5\ue308\5\ue3d0\5\ue498\5\ue560\5\ue628"+ + "\5\ue6f0\5\ue7b8\5\ue880\5\ue948\5\uea10\5\uead8\5\ueba0\5\uec68"+ + "\5\ued30\5\uedf8\5\ueec0\5\uef88\5\uf050\5\uf118\5\uf1e0\5\uf2a8"+ + "\5\uf370\5\uf438\5\uf500\5\uf5c8\5\uf690\5\uf758\5\uf820\5\uf8e8"+ + "\5\uf9b0\5\ufa78\5\ufb40\5\ufc08\5\ufcd0\5\ufd98\5\ufe60\5\uff28"+ + "\5\ufff0\6\270\6\u0180\6\u0248\6\u0310\6\u03d8\6\u04a0\6\u0568"+ + "\6\u0630\6\u06f8\6\u07c0\6\u0888\6\u0950\6\u0a18\6\u0ae0\6\u0ba8"+ + "\6\u0c70\6\u0d38\6\u0e00\6\u0ec8\6\u0f90\6\u1058\6\u1120\6\u11e8"+ + "\6\u12b0\6\u1378\6\u1440\6\u1508\6\u15d0\6\u1698\6\u1760\6\u1828"+ + "\6\u18f0\6\u19b8\6\u1a80\6\u1b48\6\u1c10\6\u1cd8\6\u1da0\6\u1e68"+ + "\6\u1f30\6\u1ff8\6\u20c0\6\u2188\6\u2250\6\u2318\6\u23e0\6\u24a8"+ + "\6\u2570\6\u2638\6\u2700\6\u27c8\6\u2890\6\u2958\6\u2a20\6\u2ae8"+ + "\6\u2bb0\6\u2c78\6\u2d40\6\u2e08\6\u2ed0\6\u2f98\6\u3060\6\u3128"+ + "\6\u31f0\6\u32b8\6\u3380\6\u3448\6\u3510\6\u35d8\6\u36a0\6\u3768"+ + "\6\u3830\6\u38f8\6\u39c0\6\u3a88\6\u3b50\6\u3c18\6\u3ce0\6\u3da8"+ + "\6\u3e70\6\u3f38\6\u4000\6\u40c8\6\u4190\6\u4258\6\u4320\6\u43e8"+ + "\6\u44b0\6\u4578\6\u4640\6\u4708\6\u47d0\6\u4898\6\u4960\6\u4a28"+ + "\6\u4af0\6\u4bb8\6\u4c80\6\u4d48\6\u4e10\6\u4ed8\6\u4fa0\6\u5068"+ + "\6\u5130\6\u51f8\6\u52c0\6\u5388\6\u5450\6\u5518\6\u55e0\6\u56a8"+ + "\6\u5770\6\u5838\6\u5900\6\u59c8\6\u5a90\6\u5b58\6\u5c20\6\u5ce8"+ + "\6\u5db0\6\u5e78\6\u5f40\6\u6008\6\u60d0\6\u6198\6\u6260\6\u6328"+ + "\6\u63f0\6\u64b8\6\u6580\6\u6648\6\u6710\6\u67d8\6\u68a0\6\u6968"+ + "\6\u6a30\6\u6af8\6\u6bc0\6\u6c88\6\u6d50"; private static int [] zzUnpackRowMap() { - int [] result = new int[1750]; + int [] result = new int[2125]; int offset = 0; offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); return result; @@ -523,3364 +580,4900 @@ public final class UAX29URLEmailTokenizerImpl implements StandardTokenizerInterf "\3\2\1\13\2\2\1\14\4\2\1\15\3\2\1\16"+ "\17\2\1\17\2\2\1\20\66\2\1\21\1\2\1\22"+ "\2\2\1\23\1\24\1\2\1\25\1\2\1\26\1\2"+ - "\1\27\1\2\1\30\1\2\1\31\1\32\3\2\1\33"+ - "\2\34\1\35\1\36\1\37\1\40\6\41\1\42\3\41"+ - "\1\43\12\41\1\44\4\41\1\40\1\45\2\46\1\45"+ - "\5\46\1\47\1\2\1\40\1\50\1\40\1\2\2\40"+ - "\1\2\3\40\1\51\2\2\1\40\1\52\3\2\2\40"+ - "\1\2\307\0\1\30\2\0\1\30\4\0\1\30\16\0"+ - "\1\30\15\0\1\30\20\0\1\30\1\0\1\30\31\0"+ - "\1\30\4\0\1\30\10\0\2\30\15\0\2\30\10\0"+ - "\1\30\115\0\2\30\5\0\1\30\2\0\1\30\3\0"+ - "\2\30\10\0\4\30\1\0\3\30\1\0\1\30\2\0"+ - "\1\30\2\0\1\30\4\0\4\30\1\0\2\30\1\0"+ - "\1\30\2\0\1\30\1\0\1\30\2\0\4\30\2\0"+ - "\3\30\1\0\2\30\1\0\3\30\5\0\4\30\2\0"+ - "\10\30\1\0\1\30\2\0\4\30\1\0\2\30\1\0"+ - "\1\30\1\0\2\30\4\0\1\30\3\0\1\30\120\0"+ - "\1\30\4\0\1\30\11\0\1\30\22\0\1\30\3\0"+ - "\1\30\27\0\1\30\63\0\1\30\120\0\1\30\3\0"+ - "\4\30\1\0\1\30\1\0\1\31\2\0\1\30\1\0"+ - "\2\30\2\0\2\30\2\0\3\30\1\0\1\30\1\0"+ - "\1\30\2\0\4\30\1\0\3\30\1\0\1\30\1\0"+ - "\3\30\1\0\2\30\1\0\4\30\1\0\2\30\2\0"+ - "\10\30\1\0\2\30\1\0\11\30\1\0\10\30\1\0"+ - "\13\30\1\31\1\0\1\30\1\0\1\30\1\0\2\30"+ - "\2\0\1\30\1\0\1\30\3\0\1\30\127\0\1\30"+ - "\17\0\1\30\23\0\1\30\23\0\1\30\6\0\3\30"+ - "\37\0\1\30\7\0\1\30\117\0\1\30\1\0\2\30"+ - "\1\0\1\30\1\0\4\30\1\0\1\30\1\0\1\30"+ - "\1\0\2\30\1\0\3\30\1\0\2\30\1\0\4\30"+ - "\1\0\3\30\1\0\17\30\1\0\2\30\1\0\21\30"+ - "\1\0\2\30\1\0\41\30\1\0\1\30\1\0\2\30"+ - "\2\0\1\30\1\0\1\30\1\0\1\30\1\0\1\30"+ - "\127\0\1\30\3\0\2\30\12\0\2\30\13\0\1\30"+ - "\6\0\1\30\2\0\2\30\6\0\1\30\4\0\2\30"+ - "\2\0\2\30\5\0\3\30\10\0\1\30\26\0\1\30"+ - "\7\0\1\30\117\0\1\30\1\0\2\30\1\0\1\30"+ - "\2\0\2\30\2\0\1\30\3\0\2\30\1\0\3\30"+ - "\1\0\2\30\1\0\4\30\1\0\3\30\1\0\1\30"+ - "\1\0\2\30\2\0\11\30\1\0\2\30\1\0\1\30"+ - "\1\0\2\30\1\0\14\30\1\0\2\30\1\0\3\30"+ - "\1\0\1\30\1\0\30\30\1\0\2\30\1\0\1\30"+ - "\1\0\2\30\2\0\1\30\1\0\1\30\1\0\1\30"+ - "\1\0\1\30\113\0\1\30\26\0\2\30\23\0\1\31"+ - "\1\30\66\0\1\31\142\0\1\31\27\0\4\30\2\0"+ - "\2\30\14\0\3\30\15\0\3\30\3\0\1\30\7\0"+ - "\2\30\13\0\1\30\13\0\4\31\1\0\2\30\11\0"+ - "\1\30\133\0\1\30\3\0\2\30\12\0\2\30\1\0"+ - "\3\30\7\0\1\30\6\0\2\30\1\0\2\30\6\0"+ - "\1\30\4\0\2\30\2\0\2\30\5\0\3\30\10\0"+ - "\1\30\16\0\1\30\4\0\2\31\1\0\1\30\7\0"+ - "\1\30\117\0\1\30\4\0\1\30\6\0\1\30\3\0"+ - "\1\30\6\0\1\30\5\0\1\30\2\0\2\30\1\0"+ - "\17\30\2\0\1\30\13\0\7\30\2\0\1\30\1\0"+ - "\1\30\1\0\1\30\2\0\1\30\1\0\1\30\1\0"+ - "\1\30\1\0\1\30\6\0\2\30\5\0\1\30\1\0"+ - "\1\30\2\0\3\30\1\0\1\30\7\0\1\30\1\0"+ - "\1\30\131\0\1\30\17\0\2\30\22\0\1\30\2\0"+ - "\2\30\13\0\1\30\3\0\2\30\5\0\3\30\10\0"+ - "\1\30\26\0\1\30\7\0\1\30\124\0\1\30\6\0"+ - "\1\30\3\0\1\30\3\0\1\30\7\0\1\30\31\0"+ - "\20\30\5\0\3\30\3\0\1\30\3\0\2\30\2\0"+ - "\2\30\4\0\1\30\10\0\1\30\4\0\1\30\2\0"+ - "\1\30\4\0\1\30\1\0\1\30\1\0\1\30\226\0"+ - "\1\36\41\0\1\32\131\0\1\35\6\0\1\35\2\0"+ - "\1\35\3\0\2\35\10\0\4\35\1\0\3\35\1\0"+ - "\1\35\2\0\1\35\2\0\1\35\4\0\4\35\1\0"+ - "\2\35\6\0\1\35\2\0\4\35\2\0\3\35\1\0"+ - "\2\35\1\0\3\35\5\0\4\35\2\0\10\35\4\0"+ - "\4\35\1\0\2\35\1\0\1\35\1\0\2\35\4\0"+ - "\1\35\3\0\1\35\113\0\1\35\1\0\2\35\1\0"+ - "\1\35\1\0\4\35\1\0\1\35\1\0\1\35\1\0"+ - "\2\35\1\0\3\35\1\0\2\35\1\0\4\35\1\0"+ - "\3\35\1\0\17\35\1\0\2\35\1\0\21\35\1\0"+ - "\2\35\1\0\41\35\1\0\1\35\1\0\2\35\2\0"+ - "\1\35\1\0\1\35\1\0\1\35\1\0\1\35\113\0"+ - "\1\35\1\0\2\35\1\0\1\35\1\0\4\35\1\0"+ - "\1\35\1\0\1\35\1\0\2\35\2\0\1\35\2\0"+ - "\2\35\1\0\4\35\1\0\3\35\1\0\17\35\1\0"+ - "\2\35\1\0\21\35\1\0\2\35\1\0\41\35\1\0"+ - "\1\35\1\0\2\35\2\0\1\35\1\0\1\35\1\0"+ - "\1\35\1\0\1\35\127\0\1\35\17\0\1\35\23\0"+ - "\1\35\32\0\1\35\41\0\1\35\7\0\1\35\117\0"+ - "\1\35\1\0\2\35\3\0\4\35\1\0\1\35\1\0"+ - "\1\35\1\0\2\35\1\0\3\35\1\0\2\35\1\0"+ - "\4\35\1\0\3\35\1\0\10\35\1\0\6\35\1\0"+ - "\2\35\1\0\21\35\1\0\2\35\1\0\41\35\1\0"+ - "\1\35\1\0\2\35\2\0\1\35\1\0\1\35\1\0"+ - "\1\35\1\0\1\35\304\0\1\36\112\0\1\53\1\0"+ - "\1\54\2\0\1\55\1\0\1\56\4\0\1\57\1\0"+ - "\1\60\1\0\1\61\2\0\1\62\3\0\1\63\2\0"+ - "\1\64\4\0\1\65\3\0\1\66\17\0\1\67\2\0"+ - "\1\70\21\0\1\71\2\0\1\72\57\0\2\30\1\73"+ - "\1\0\1\74\1\0\1\74\1\75\1\0\1\30\2\0"+ - "\1\30\1\74\32\30\1\0\12\73\1\74\1\0\1\75"+ - "\3\0\1\74\20\0\1\53\1\0\1\54\2\0\1\76"+ - "\1\0\1\77\4\0\1\57\1\0\1\60\1\0\1\61"+ - "\2\0\1\62\3\0\1\100\2\0\1\101\4\0\1\102"+ - "\3\0\1\103\17\0\1\67\2\0\1\104\21\0\1\105"+ - "\2\0\1\106\57\0\1\30\2\31\2\0\2\107\1\110"+ - "\1\0\1\31\2\0\1\30\1\107\32\30\1\0\12\31"+ - "\2\0\1\110\2\0\2\107\6\0\1\107\16\0\1\111"+ - "\21\0\1\112\2\0\1\113\10\0\1\114\22\0\1\115"+ - "\21\0\1\116\2\0\1\117\41\0\1\120\16\0\1\32"+ - "\1\0\1\32\3\0\1\75\1\0\1\32\53\0\1\75"+ - "\24\0\1\53\1\0\1\54\2\0\1\121\1\0\1\77"+ - "\4\0\1\57\1\0\1\60\1\0\1\61\2\0\1\62"+ - "\3\0\1\122\2\0\1\123\4\0\1\102\3\0\1\124"+ - "\17\0\1\67\2\0\1\125\21\0\1\126\2\0\1\127"+ - "\41\0\1\130\15\0\1\30\1\131\1\31\1\132\3\0"+ - "\1\131\1\0\1\131\2\0\1\30\1\0\32\30\1\0"+ - "\12\31\2\0\1\131\227\0\2\34\105\0\1\133\21\0"+ - "\1\134\2\0\1\135\10\0\1\136\22\0\1\137\21\0"+ - "\1\140\2\0\1\141\60\0\1\35\7\0\1\35\105\0"+ - "\1\142\21\0\1\143\2\0\1\144\10\0\1\145\22\0"+ - "\1\146\21\0\1\147\2\0\1\150\60\0\1\36\7\0"+ - "\1\36\100\0\1\53\1\0\1\54\2\0\1\151\1\0"+ - "\1\56\4\0\1\57\1\0\1\60\1\0\1\61\2\0"+ - "\1\62\3\0\1\152\2\0\1\153\4\0\1\65\3\0"+ - "\1\154\17\0\1\67\2\0\1\155\21\0\1\156\2\0"+ - "\1\157\57\0\1\30\1\37\1\73\1\0\1\74\1\0"+ - "\1\74\1\75\1\0\1\37\2\0\1\37\1\74\32\30"+ - "\1\0\12\73\1\74\1\0\1\75\3\0\1\74\230\0"+ - "\1\160\45\161\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\2\0\1\53\1\0\1\54"+ - "\2\0\1\55\1\0\1\56\4\0\1\57\1\0\1\60"+ - "\1\0\1\61\2\0\1\62\3\0\1\63\2\0\1\64"+ - "\4\0\1\65\3\0\1\66\17\0\1\67\2\0\1\70"+ - "\21\0\1\71\2\0\1\72\57\0\2\30\1\73\1\0"+ - "\1\74\1\0\1\74\1\75\1\0\1\30\2\0\1\30"+ - "\1\163\32\41\1\164\12\165\1\74\1\161\1\166\1\161"+ - "\1\0\1\161\1\167\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\2\0\1\53\1\0\1\54\2\0\1\55\1\0"+ - "\1\56\4\0\1\57\1\0\1\60\1\0\1\61\2\0"+ - "\1\62\3\0\1\63\2\0\1\64\4\0\1\65\3\0"+ - "\1\66\17\0\1\67\2\0\1\70\21\0\1\71\2\0"+ - "\1\72\57\0\2\30\1\73\1\0\1\74\1\0\1\74"+ - "\1\75\1\0\1\30\2\0\1\30\1\163\10\41\1\170"+ - "\6\41\1\171\12\41\1\164\12\165\1\74\1\161\1\166"+ - "\1\161\1\0\1\161\1\167\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\2\0\1\53\1\0\1\54\2\0\1\55"+ - "\1\0\1\56\4\0\1\57\1\0\1\60\1\0\1\61"+ - "\2\0\1\62\3\0\1\63\2\0\1\64\4\0\1\65"+ - "\3\0\1\66\17\0\1\67\2\0\1\70\21\0\1\71"+ - "\2\0\1\72\57\0\2\30\1\73\1\0\1\74\1\0"+ - "\1\74\1\75\1\0\1\30\2\0\1\30\1\163\1\172"+ - "\31\41\1\164\12\165\1\74\1\161\1\166\1\161\1\0"+ - "\1\161\1\167\1\162\3\161\3\0\1\161\4\0\2\161"+ - "\2\0\1\53\1\0\1\54\2\0\1\55\1\0\1\56"+ - "\4\0\1\57\1\0\1\60\1\0\1\61\2\0\1\62"+ - "\3\0\1\63\2\0\1\64\4\0\1\65\3\0\1\66"+ - "\17\0\1\67\2\0\1\70\21\0\1\71\2\0\1\72"+ - "\57\0\2\30\1\73\1\0\1\74\1\0\1\74\1\75"+ - "\1\0\1\30\2\0\1\30\1\163\17\41\1\173\12\41"+ - "\1\164\12\165\1\74\1\161\1\166\1\161\1\0\1\161"+ - "\1\167\1\162\3\161\3\0\1\161\4\0\2\161\2\0"+ - "\1\53\1\0\1\54\2\0\1\76\1\0\1\77\4\0"+ - "\1\57\1\0\1\60\1\0\1\61\2\0\1\62\3\0"+ - "\1\100\2\0\1\101\4\0\1\102\3\0\1\103\17\0"+ - "\1\67\2\0\1\104\21\0\1\105\2\0\1\106\57\0"+ - "\1\30\2\31\2\0\2\107\1\110\1\0\1\31\2\0"+ - "\1\30\1\174\32\41\1\164\12\46\1\0\1\161\1\175"+ - "\1\161\1\0\2\176\1\162\3\161\2\0\1\107\1\161"+ - "\4\0\2\161\2\0\1\53\1\0\1\54\2\0\1\76"+ - "\1\0\1\77\4\0\1\57\1\0\1\60\1\0\1\61"+ - "\2\0\1\62\3\0\1\100\2\0\1\101\4\0\1\102"+ - "\3\0\1\103\17\0\1\67\2\0\1\104\21\0\1\105"+ - "\2\0\1\106\57\0\1\30\2\31\2\0\2\107\1\110"+ - "\1\0\1\31\2\0\1\30\1\174\32\41\1\164\12\177"+ - "\1\0\1\161\1\175\1\161\1\0\2\176\1\162\3\161"+ - "\2\0\1\107\1\161\4\0\2\161\2\0\1\53\1\0"+ - "\1\54\2\0\1\76\1\0\1\77\4\0\1\57\1\0"+ - "\1\60\1\0\1\61\2\0\1\62\3\0\1\100\2\0"+ - "\1\101\4\0\1\102\3\0\1\103\17\0\1\67\2\0"+ - "\1\104\21\0\1\105\2\0\1\106\57\0\1\30\2\31"+ - "\2\0\2\107\1\110\1\0\1\31\2\0\1\30\1\174"+ - "\32\41\1\164\1\46\1\200\1\177\2\46\2\177\1\46"+ - "\1\177\1\46\1\0\1\161\1\175\1\161\1\0\2\176"+ - "\1\162\3\161\2\0\1\107\1\161\4\0\2\161\2\0"+ - "\1\53\1\0\1\54\2\0\1\121\1\0\1\77\4\0"+ - "\1\57\1\0\1\60\1\0\1\61\2\0\1\62\3\0"+ - "\1\122\2\0\1\123\4\0\1\102\3\0\1\124\17\0"+ - "\1\67\2\0\1\125\21\0\1\126\2\0\1\127\41\0"+ - "\1\130\15\0\1\30\1\131\1\31\1\132\3\0\1\131"+ - "\1\0\1\131\2\0\1\30\1\160\32\201\1\161\12\202"+ - "\1\0\1\161\1\203\1\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\213\0\4\204\2\0\1\204"+ - "\15\0\1\204\6\0\12\204\1\205\236\0\65\206\1\207"+ - "\1\206\1\210\1\0\2\206\10\0\1\30\4\0\1\30"+ - "\11\0\1\30\22\0\1\30\3\0\1\30\13\0\1\30"+ - "\2\0\1\30\10\0\1\30\12\0\4\30\45\0\1\30"+ - "\120\0\1\30\3\0\4\30\1\0\1\30\1\0\1\73"+ + "\1\27\3\2\1\30\1\2\1\31\1\32\3\2\1\33"+ + "\2\34\1\35\1\36\1\37\1\40\1\41\1\42\1\37"+ + "\6\43\1\44\3\43\1\45\12\43\1\46\4\43\1\37"+ + "\1\47\1\50\5\47\1\51\1\50\1\47\1\2\1\37"+ + "\1\52\1\37\1\2\1\37\1\2\3\37\1\53\2\2"+ + "\1\37\3\2\2\37\1\2\312\0\1\30\2\0\1\30"+ + "\4\0\1\30\16\0\1\30\15\0\1\30\20\0\1\30"+ + "\1\0\1\30\41\0\1\30\4\0\1\30\10\0\2\30"+ + "\5\0\2\30\10\0\1\30\120\0\2\30\5\0\1\30"+ + "\2\0\1\30\3\0\2\30\10\0\4\30\1\0\3\30"+ + "\1\0\1\30\2\0\1\30\2\0\1\30\4\0\4\30"+ + "\1\0\2\30\1\0\1\30\2\0\1\30\1\0\1\30"+ + "\2\0\4\30\2\0\3\30\1\0\2\30\1\0\3\30"+ + "\1\0\4\30\1\0\2\30\5\0\4\30\2\0\10\30"+ + "\1\0\1\30\2\0\1\30\1\0\2\30\4\0\1\30"+ + "\3\0\3\30\121\0\1\30\4\0\1\30\11\0\1\30"+ + "\22\0\1\30\3\0\1\30\27\0\1\30\63\0\1\30"+ + "\123\0\1\30\3\0\4\30\1\0\1\30\1\0\1\31"+ "\2\0\1\30\1\0\2\30\2\0\2\30\2\0\3\30"+ "\1\0\1\30\1\0\1\30\2\0\4\30\1\0\3\30"+ "\1\0\1\30\1\0\3\30\1\0\2\30\1\0\4\30"+ - "\1\0\2\30\2\0\10\30\1\0\2\30\1\0\11\30"+ - "\1\0\10\30\1\0\13\30\1\73\1\0\1\30\1\0"+ + "\1\0\2\30\2\0\10\30\1\0\2\30\1\0\10\30"+ + "\1\31\1\0\7\30\1\0\10\30\1\0\6\30\1\0"+ "\1\30\1\0\2\30\2\0\1\30\1\0\1\30\3\0"+ - "\1\30\113\0\1\30\26\0\2\30\23\0\1\73\1\30"+ - "\44\0\1\30\21\0\1\73\142\0\1\73\11\0\1\30"+ - "\15\0\4\30\2\0\2\30\14\0\4\30\1\0\2\30"+ - "\11\0\3\30\3\0\1\30\1\0\1\30\4\0\3\30"+ - "\5\0\4\30\2\0\2\30\12\0\4\73\1\0\2\30"+ - "\1\0\1\30\7\0\1\30\133\0\1\30\3\0\2\30"+ + "\3\30\130\0\1\30\17\0\1\30\23\0\1\30\23\0"+ + "\1\30\6\0\3\30\37\0\1\30\7\0\1\30\122\0"+ + "\1\30\1\0\2\30\1\0\1\30\1\0\4\30\1\0"+ + "\1\30\1\0\1\30\1\0\2\30\1\0\3\30\1\0"+ + "\2\30\1\0\4\30\1\0\3\30\1\0\17\30\1\0"+ + "\2\30\1\0\21\30\1\0\2\30\1\0\41\30\1\0"+ + "\1\30\1\0\2\30\2\0\1\30\1\0\1\30\1\0"+ + "\1\30\1\0\3\30\130\0\1\30\3\0\2\30\12\0"+ + "\2\30\13\0\1\30\6\0\1\30\2\0\2\30\6\0"+ + "\1\30\4\0\2\30\2\0\2\30\5\0\3\30\20\0"+ + "\1\30\16\0\1\30\7\0\1\30\122\0\1\30\1\0"+ + "\2\30\1\0\1\30\2\0\2\30\2\0\1\30\3\0"+ + "\2\30\1\0\3\30\1\0\2\30\1\0\4\30\1\0"+ + "\3\30\1\0\1\30\1\0\2\30\2\0\11\30\1\0"+ + "\2\30\1\0\1\30\1\0\2\30\1\0\14\30\1\0"+ + "\2\30\1\0\10\30\1\0\2\30\1\0\1\30\1\0"+ + "\23\30\1\0\1\30\1\0\2\30\2\0\1\30\1\0"+ + "\1\30\1\0\1\30\1\0\3\30\114\0\1\30\26\0"+ + "\2\30\23\0\1\31\1\30\40\0\1\31\173\0\1\31"+ + "\27\0\4\30\2\0\2\30\14\0\3\30\15\0\3\30"+ + "\3\0\1\30\7\0\2\30\1\0\4\31\1\0\2\30"+ + "\13\0\1\30\23\0\1\30\136\0\1\30\3\0\2\30"+ "\12\0\2\30\1\0\3\30\7\0\1\30\6\0\2\30"+ "\1\0\2\30\6\0\1\30\4\0\2\30\2\0\2\30"+ - "\5\0\3\30\10\0\1\30\16\0\1\30\4\0\2\73"+ - "\1\0\1\30\7\0\1\30\117\0\1\30\4\0\1\30"+ + "\5\0\3\30\2\0\1\30\3\0\2\31\10\0\1\30"+ + "\16\0\1\30\7\0\1\30\122\0\1\30\4\0\1\30"+ "\6\0\1\30\3\0\1\30\6\0\1\30\5\0\1\30"+ "\2\0\2\30\1\0\17\30\2\0\1\30\13\0\7\30"+ - "\2\0\1\30\1\0\1\30\1\0\1\30\2\0\1\30"+ - "\1\0\1\30\1\0\1\30\1\0\1\30\4\0\1\30"+ - "\1\0\2\30\5\0\1\30\1\0\1\30\2\0\3\30"+ - "\1\0\1\30\7\0\1\30\1\0\1\30\122\0\1\30"+ + "\2\0\1\30\1\0\1\30\1\0\2\30\2\0\1\30"+ + "\1\0\3\30\2\0\1\30\1\0\1\30\1\0\1\30"+ + "\1\0\1\30\6\0\2\30\6\0\1\30\7\0\1\30"+ + "\1\0\1\30\134\0\1\30\17\0\2\30\22\0\1\30"+ + "\2\0\2\30\13\0\1\30\3\0\2\30\5\0\3\30"+ + "\20\0\1\30\16\0\1\30\7\0\1\30\127\0\1\30"+ "\6\0\1\30\3\0\1\30\3\0\1\30\7\0\1\30"+ - "\31\0\20\30\5\0\3\30\3\0\1\30\3\0\2\30"+ - "\2\0\2\30\4\0\5\30\4\0\1\30\4\0\1\30"+ + "\31\0\20\30\5\0\3\30\4\0\1\30\6\0\1\30"+ + "\3\0\2\30\2\0\2\30\4\0\1\30\5\0\1\30"+ "\2\0\1\30\4\0\1\30\1\0\1\30\1\0\1\30"+ - "\223\0\2\30\15\0\4\30\154\0\1\30\15\0\2\30"+ - "\10\0\2\30\1\0\1\30\1\0\1\30\11\0\1\30"+ - "\11\0\2\30\6\0\1\30\2\0\4\30\3\0\1\30"+ - "\2\0\2\30\1\0\3\30\5\0\1\30\1\0\2\30"+ - "\2\0\2\30\1\0\4\30\5\0\1\30\1\0\2\30"+ - "\133\0\1\53\1\0\1\54\2\0\1\211\1\0\1\56"+ - "\4\0\1\57\1\0\1\60\1\0\1\61\2\0\1\62"+ - "\3\0\1\212\2\0\1\213\4\0\1\65\3\0\1\214"+ - "\17\0\1\67\2\0\1\215\21\0\1\216\2\0\1\217"+ - "\57\0\1\30\2\73\2\0\2\220\1\75\1\0\1\73"+ - "\2\0\1\30\1\220\32\30\1\0\12\73\2\0\1\75"+ - "\2\0\2\220\6\0\1\220\11\0\1\53\1\0\1\54"+ - "\2\0\1\221\1\0\1\222\4\0\1\57\1\0\1\60"+ - "\1\0\1\61\2\0\1\62\3\0\1\223\2\0\1\224"+ - "\4\0\1\225\3\0\1\226\17\0\1\67\2\0\1\227"+ - "\21\0\1\230\2\0\1\231\57\0\1\30\1\74\7\0"+ - "\1\74\2\0\1\30\1\0\32\30\42\0\1\53\1\0"+ - "\1\54\2\0\1\232\1\0\1\56\4\0\1\57\1\0"+ - "\1\60\1\0\1\61\2\0\1\62\3\0\1\233\2\0"+ - "\1\234\4\0\1\65\3\0\1\235\17\0\1\67\2\0"+ - "\1\236\21\0\1\237\2\0\1\240\41\0\1\130\15\0"+ - "\1\30\1\75\1\73\1\132\3\0\1\75\1\0\1\75"+ - "\2\0\1\30\1\0\32\30\1\0\12\73\2\0\1\75"+ - "\32\0\1\30\4\0\1\30\11\0\1\30\22\0\1\30"+ - "\3\0\1\30\13\0\1\31\2\0\1\31\10\0\1\30"+ - "\12\0\4\31\45\0\1\30\115\0\1\30\26\0\2\30"+ - "\23\0\1\31\1\30\44\0\1\31\21\0\1\31\142\0"+ - "\1\31\11\0\1\31\15\0\4\30\2\0\2\30\14\0"+ - "\3\30\1\31\1\0\2\31\11\0\3\30\3\0\1\30"+ - "\1\0\1\31\4\0\1\31\2\30\5\0\4\31\2\0"+ - "\1\30\1\31\12\0\4\31\1\0\2\30\1\0\1\31"+ - "\7\0\1\30\117\0\1\30\4\0\1\30\6\0\1\30"+ - "\3\0\1\30\6\0\1\30\5\0\1\30\2\0\2\30"+ - "\1\0\17\30\2\0\1\30\13\0\7\30\2\0\1\30"+ - "\1\0\1\30\1\0\1\30\2\0\1\30\1\0\1\30"+ - "\1\0\1\30\1\0\1\30\4\0\1\31\1\0\2\30"+ - "\5\0\1\30\1\0\1\30\2\0\3\30\1\0\1\30"+ - "\7\0\1\30\1\0\1\30\122\0\1\30\6\0\1\30"+ - "\3\0\1\30\3\0\1\30\7\0\1\30\31\0\20\30"+ - "\5\0\3\30\3\0\1\30\3\0\2\30\2\0\2\30"+ - "\4\0\1\30\4\31\4\0\1\30\4\0\1\30\2\0"+ - "\1\30\4\0\1\30\1\0\1\30\1\0\1\30\223\0"+ - "\2\31\15\0\4\31\154\0\1\31\15\0\2\31\10\0"+ - "\2\31\1\0\1\31\1\0\1\31\11\0\1\31\11\0"+ - "\2\31\6\0\1\31\2\0\4\31\3\0\1\31\2\0"+ - "\2\31\1\0\3\31\5\0\1\31\1\0\2\31\2\0"+ - "\2\31\1\0\4\31\5\0\1\31\1\0\2\31\140\0"+ - "\1\241\1\0\1\242\17\0\1\243\2\0\1\244\4\0"+ - "\1\245\3\0\1\246\22\0\1\247\21\0\1\250\2\0"+ - "\1\251\60\0\1\107\1\31\6\0\1\107\37\0\12\31"+ - "\27\0\1\53\1\0\1\54\2\0\1\252\1\0\1\77"+ - "\4\0\1\57\1\0\1\60\1\0\1\61\2\0\1\62"+ - "\3\0\1\253\2\0\1\254\4\0\1\102\3\0\1\255"+ - "\17\0\1\67\2\0\1\256\21\0\1\257\2\0\1\260"+ - "\41\0\1\130\15\0\1\30\1\110\1\31\1\132\3\0"+ - "\1\110\1\0\1\110\2\0\1\30\1\0\32\30\1\0"+ - "\12\31\2\0\1\110\114\0\1\32\2\0\1\32\23\0"+ - "\4\32\305\0\1\32\176\0\1\32\44\0\1\32\1\0"+ - "\2\32\21\0\1\32\4\0\1\32\7\0\4\32\3\0"+ - "\1\32\22\0\1\32\262\0\1\32\311\0\4\32\251\0"+ - "\2\32\15\0\4\32\154\0\1\32\15\0\2\32\10\0"+ - "\2\32\1\0\1\32\1\0\1\32\11\0\1\32\11\0"+ - "\2\32\6\0\1\32\2\0\4\32\3\0\1\32\2\0"+ - "\2\32\1\0\3\32\5\0\1\32\1\0\2\32\2\0"+ - "\2\32\1\0\4\32\5\0\1\32\1\0\2\32\311\0"+ - "\1\32\134\0\1\30\4\0\1\30\11\0\1\30\22\0"+ - "\1\30\3\0\1\30\13\0\1\131\2\0\1\131\10\0"+ - "\1\30\12\0\4\131\45\0\1\30\115\0\1\30\26\0"+ - "\2\30\23\0\1\31\1\30\44\0\1\131\21\0\1\31"+ - "\142\0\1\31\11\0\1\131\15\0\4\30\2\0\2\30"+ - "\14\0\3\30\1\131\1\0\2\131\11\0\3\30\3\0"+ - "\1\30\1\0\1\131\4\0\1\131\2\30\5\0\4\131"+ - "\2\0\1\30\1\131\12\0\4\31\1\0\2\30\1\0"+ - "\1\131\7\0\1\30\117\0\1\30\4\0\1\30\6\0"+ + "\231\0\1\36\41\0\1\32\134\0\1\35\6\0\1\35"+ + "\2\0\1\35\3\0\2\35\10\0\4\35\1\0\3\35"+ + "\1\0\1\35\2\0\1\35\2\0\1\35\4\0\4\35"+ + "\1\0\2\35\6\0\1\35\2\0\4\35\2\0\3\35"+ + "\1\0\2\35\1\0\3\35\1\0\4\35\1\0\2\35"+ + "\5\0\4\35\2\0\10\35\4\0\1\35\1\0\2\35"+ + "\4\0\1\35\3\0\3\35\114\0\1\35\1\0\2\35"+ + "\1\0\1\35\1\0\4\35\1\0\1\35\1\0\1\35"+ + "\1\0\2\35\1\0\3\35\1\0\2\35\1\0\4\35"+ + "\1\0\3\35\1\0\17\35\1\0\2\35\1\0\21\35"+ + "\1\0\2\35\1\0\41\35\1\0\1\35\1\0\2\35"+ + "\2\0\1\35\1\0\1\35\1\0\1\35\1\0\3\35"+ + "\114\0\1\35\1\0\2\35\1\0\1\35\1\0\4\35"+ + "\1\0\1\35\1\0\1\35\1\0\2\35\2\0\1\35"+ + "\2\0\2\35\1\0\4\35\1\0\3\35\1\0\17\35"+ + "\1\0\2\35\1\0\21\35\1\0\2\35\1\0\41\35"+ + "\1\0\1\35\1\0\2\35\2\0\1\35\1\0\1\35"+ + "\1\0\1\35\1\0\3\35\130\0\1\35\17\0\1\35"+ + "\23\0\1\35\32\0\1\35\41\0\1\35\7\0\1\35"+ + "\122\0\1\35\1\0\2\35\3\0\4\35\1\0\1\35"+ + "\1\0\1\35\1\0\2\35\1\0\3\35\1\0\2\35"+ + "\1\0\4\35\1\0\3\35\1\0\10\35\1\0\6\35"+ + "\1\0\2\35\1\0\21\35\1\0\2\35\1\0\41\35"+ + "\1\0\1\35\1\0\2\35\2\0\1\35\1\0\1\35"+ + "\1\0\1\35\1\0\3\35\257\0\1\54\25\0\1\36"+ + "\2\54\113\0\1\55\1\0\1\56\2\0\1\57\1\0"+ + "\1\60\4\0\1\61\1\0\1\62\1\0\1\63\2\0"+ + "\1\64\3\0\1\65\2\0\1\66\4\0\1\67\3\0"+ + "\1\70\17\0\1\71\2\0\1\72\21\0\1\73\2\0"+ + "\1\74\61\0\2\30\1\75\1\0\1\76\1\0\1\76"+ + "\1\77\1\0\1\30\2\0\1\76\1\0\1\41\1\30"+ + "\1\76\32\30\1\0\12\75\1\76\1\0\1\77\22\0"+ + "\1\55\1\0\1\56\2\0\1\100\1\0\1\101\4\0"+ + "\1\61\1\0\1\62\1\0\1\63\2\0\1\64\3\0"+ + "\1\102\2\0\1\103\4\0\1\104\3\0\1\105\17\0"+ + "\1\71\2\0\1\106\21\0\1\107\2\0\1\110\61\0"+ + "\1\30\2\31\2\0\2\111\1\112\1\0\1\31\2\0"+ + "\1\111\1\0\1\41\1\30\1\111\32\30\1\0\12\31"+ + "\2\0\1\112\2\0\1\111\6\0\1\111\15\0\1\113"+ + "\21\0\1\114\2\0\1\115\10\0\1\116\22\0\1\117"+ + "\21\0\1\120\2\0\1\121\41\0\1\122\20\0\1\32"+ + "\1\0\1\32\3\0\1\123\1\0\1\32\56\0\1\123"+ + "\22\0\1\55\1\0\1\56\2\0\1\124\1\0\1\101"+ + "\4\0\1\61\1\0\1\62\1\0\1\63\2\0\1\64"+ + "\3\0\1\125\2\0\1\126\4\0\1\104\3\0\1\127"+ + "\17\0\1\71\2\0\1\130\21\0\1\131\2\0\1\132"+ + "\41\0\1\133\17\0\1\30\1\134\1\31\1\135\3\0"+ + "\1\134\1\0\1\134\4\0\1\41\1\30\1\0\32\30"+ + "\1\0\12\31\2\0\1\134\227\0\2\34\106\0\1\136"+ + "\21\0\1\137\2\0\1\140\10\0\1\141\22\0\1\142"+ + "\21\0\1\143\2\0\1\144\62\0\1\35\7\0\1\35"+ + "\106\0\1\145\21\0\1\146\2\0\1\147\10\0\1\150"+ + "\22\0\1\151\21\0\1\152\2\0\1\153\62\0\1\36"+ + "\7\0\1\36\312\0\1\154\3\0\1\155\45\154\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\157\1\160\2\0\65\157\1\161\1\0"+ + "\2\157\2\0\1\55\1\0\1\56\2\0\1\162\1\0"+ + "\1\60\4\0\1\61\1\0\1\62\1\0\1\63\2\0"+ + "\1\64\3\0\1\163\2\0\1\164\4\0\1\67\3\0"+ + "\1\165\17\0\1\71\2\0\1\166\21\0\1\167\2\0"+ + "\1\170\61\0\1\30\1\41\1\75\1\0\1\76\1\0"+ + "\1\76\1\77\1\0\1\41\2\0\1\30\1\171\1\41"+ + "\1\30\1\76\32\30\1\0\12\75\1\76\1\0\1\77"+ + "\22\0\1\55\1\0\1\56\2\0\1\172\1\0\1\60"+ + "\4\0\1\61\1\0\1\62\1\0\1\63\2\0\1\64"+ + "\3\0\1\173\2\0\1\174\4\0\1\67\3\0\1\175"+ + "\17\0\1\71\2\0\1\176\21\0\1\177\2\0\1\200"+ + "\61\0\1\30\1\42\1\75\1\0\1\76\1\0\1\76"+ + "\1\77\1\0\1\42\2\0\1\76\1\0\1\41\1\42"+ + "\1\76\32\30\1\0\12\75\1\76\1\0\1\77\22\0"+ + "\1\55\1\0\1\56\2\0\1\57\1\0\1\60\4\0"+ + "\1\61\1\0\1\62\1\0\1\63\2\0\1\64\3\0"+ + "\1\65\2\0\1\66\4\0\1\67\3\0\1\70\17\0"+ + "\1\71\2\0\1\72\21\0\1\73\2\0\1\74\61\0"+ + "\2\30\1\75\1\0\1\76\1\0\1\76\1\77\1\0"+ + "\1\30\2\0\1\201\1\0\1\41\1\30\1\202\32\43"+ + "\1\203\12\204\1\76\1\154\1\205\1\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\2\0\1\55"+ + "\1\0\1\56\2\0\1\57\1\0\1\60\4\0\1\61"+ + "\1\0\1\62\1\0\1\63\2\0\1\64\3\0\1\65"+ + "\2\0\1\66\4\0\1\67\3\0\1\70\17\0\1\71"+ + "\2\0\1\72\21\0\1\73\2\0\1\74\61\0\2\30"+ + "\1\75\1\0\1\76\1\0\1\76\1\77\1\0\1\30"+ + "\2\0\1\201\1\0\1\41\1\30\1\202\10\43\1\206"+ + "\6\43\1\207\12\43\1\203\12\204\1\76\1\154\1\205"+ + "\1\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\2\0\1\55\1\0\1\56\2\0\1\57\1\0"+ + "\1\60\4\0\1\61\1\0\1\62\1\0\1\63\2\0"+ + "\1\64\3\0\1\65\2\0\1\66\4\0\1\67\3\0"+ + "\1\70\17\0\1\71\2\0\1\72\21\0\1\73\2\0"+ + "\1\74\61\0\2\30\1\75\1\0\1\76\1\0\1\76"+ + "\1\77\1\0\1\30\2\0\1\201\1\0\1\41\1\30"+ + "\1\202\1\210\31\43\1\203\12\204\1\76\1\154\1\205"+ + "\1\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\2\0\1\55\1\0\1\56\2\0\1\57\1\0"+ + "\1\60\4\0\1\61\1\0\1\62\1\0\1\63\2\0"+ + "\1\64\3\0\1\65\2\0\1\66\4\0\1\67\3\0"+ + "\1\70\17\0\1\71\2\0\1\72\21\0\1\73\2\0"+ + "\1\74\61\0\2\30\1\75\1\0\1\76\1\0\1\76"+ + "\1\77\1\0\1\30\2\0\1\201\1\0\1\41\1\30"+ + "\1\202\17\43\1\211\12\43\1\203\12\204\1\76\1\154"+ + "\1\205\1\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\2\0\1\55\1\0\1\56\2\0\1\100"+ + "\1\0\1\101\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\102\2\0\1\103\4\0\1\104"+ + "\3\0\1\105\17\0\1\71\2\0\1\106\21\0\1\107"+ + "\2\0\1\110\61\0\1\30\2\31\2\0\2\111\1\112"+ + "\1\0\1\31\2\0\1\212\1\0\1\41\1\30\1\213"+ + "\32\43\1\203\12\214\1\0\1\154\1\215\1\154\1\0"+ + "\1\212\1\156\3\154\2\0\1\111\1\154\3\0\2\154"+ + "\2\0\1\55\1\0\1\56\2\0\1\100\1\0\1\101"+ + "\4\0\1\61\1\0\1\62\1\0\1\63\2\0\1\64"+ + "\3\0\1\102\2\0\1\103\4\0\1\104\3\0\1\105"+ + "\17\0\1\71\2\0\1\106\21\0\1\107\2\0\1\110"+ + "\61\0\1\30\2\31\2\0\2\111\1\112\1\0\1\31"+ + "\2\0\1\212\1\0\1\41\1\30\1\213\32\43\1\203"+ + "\12\47\1\0\1\154\1\215\1\154\1\0\1\212\1\156"+ + "\3\154\2\0\1\111\1\154\3\0\2\154\2\0\1\55"+ + "\1\0\1\56\2\0\1\100\1\0\1\101\4\0\1\61"+ + "\1\0\1\62\1\0\1\63\2\0\1\64\3\0\1\102"+ + "\2\0\1\103\4\0\1\104\3\0\1\105\17\0\1\71"+ + "\2\0\1\106\21\0\1\107\2\0\1\110\61\0\1\30"+ + "\2\31\2\0\2\111\1\112\1\0\1\31\2\0\1\212"+ + "\1\0\1\41\1\30\1\213\32\43\1\203\2\47\1\214"+ + "\1\47\1\216\2\214\2\47\1\214\1\0\1\154\1\215"+ + "\1\154\1\0\1\212\1\156\3\154\2\0\1\111\1\154"+ + "\3\0\2\154\2\0\1\55\1\0\1\56\2\0\1\124"+ + "\1\0\1\101\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\125\2\0\1\126\4\0\1\104"+ + "\3\0\1\127\17\0\1\71\2\0\1\130\21\0\1\131"+ + "\2\0\1\132\41\0\1\133\17\0\1\30\1\134\1\31"+ + "\1\135\3\0\1\134\1\0\1\134\2\0\1\154\1\0"+ + "\1\41\1\30\1\155\32\217\1\154\12\220\1\0\1\154"+ + "\1\221\1\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\220\0\4\222\2\0\1\222\15\0\1\222"+ + "\6\0\12\222\1\223\31\0\1\224\21\0\1\225\2\0"+ + "\1\226\10\0\1\227\22\0\1\230\21\0\1\231\2\0"+ + "\1\232\55\0\1\233\4\0\1\54\7\0\1\54\107\0"+ + "\1\30\4\0\1\30\11\0\1\30\22\0\1\30\3\0"+ + "\1\30\13\0\1\30\2\0\1\30\10\0\1\30\22\0"+ + "\4\30\35\0\1\30\123\0\1\30\3\0\4\30\1\0"+ + "\1\30\1\0\1\75\2\0\1\30\1\0\2\30\2\0"+ + "\2\30\2\0\3\30\1\0\1\30\1\0\1\30\2\0"+ + "\4\30\1\0\3\30\1\0\1\30\1\0\3\30\1\0"+ + "\2\30\1\0\4\30\1\0\2\30\2\0\10\30\1\0"+ + "\2\30\1\0\10\30\1\75\1\0\7\30\1\0\10\30"+ + "\1\0\6\30\1\0\1\30\1\0\2\30\2\0\1\30"+ + "\1\0\1\30\3\0\3\30\114\0\1\30\26\0\2\30"+ + "\23\0\1\75\1\30\40\0\1\75\13\0\1\30\157\0"+ + "\1\75\11\0\1\30\15\0\4\30\2\0\2\30\14\0"+ + "\4\30\1\0\2\30\11\0\3\30\3\0\1\30\1\0"+ + "\1\30\4\0\3\30\1\0\4\75\1\0\2\30\5\0"+ + "\4\30\2\0\2\30\12\0\1\30\7\0\1\30\136\0"+ + "\1\30\3\0\2\30\12\0\2\30\1\0\3\30\7\0"+ + "\1\30\6\0\2\30\1\0\2\30\6\0\1\30\4\0"+ + "\2\30\2\0\2\30\5\0\3\30\2\0\1\30\3\0"+ + "\2\75\10\0\1\30\16\0\1\30\7\0\1\30\122\0"+ + "\1\30\4\0\1\30\6\0\1\30\3\0\1\30\6\0"+ + "\1\30\5\0\1\30\2\0\2\30\1\0\17\30\2\0"+ + "\1\30\13\0\7\30\2\0\1\30\1\0\1\30\1\0"+ + "\2\30\2\0\1\30\1\0\3\30\2\0\1\30\1\0"+ + "\1\30\1\0\1\30\1\0\1\30\4\0\1\30\1\0"+ + "\2\30\6\0\1\30\7\0\1\30\1\0\1\30\125\0"+ + "\1\30\6\0\1\30\3\0\1\30\3\0\1\30\7\0"+ + "\1\30\31\0\20\30\5\0\3\30\4\0\1\30\6\0"+ + "\1\30\3\0\2\30\2\0\2\30\4\0\5\30\1\0"+ + "\1\30\2\0\1\30\4\0\1\30\1\0\1\30\1\0"+ + "\1\30\226\0\2\30\25\0\4\30\147\0\1\30\15\0"+ + "\2\30\10\0\2\30\1\0\1\30\1\0\1\30\11\0"+ + "\1\30\11\0\2\30\6\0\1\30\2\0\4\30\3\0"+ + "\1\30\2\0\2\30\1\0\3\30\1\0\2\30\1\0"+ + "\1\30\10\0\1\30\1\0\2\30\2\0\2\30\1\0"+ + "\4\30\23\0\1\30\113\0\1\55\1\0\1\56\2\0"+ + "\1\234\1\0\1\60\4\0\1\61\1\0\1\62\1\0"+ + "\1\63\2\0\1\64\3\0\1\235\2\0\1\236\4\0"+ + "\1\67\3\0\1\237\17\0\1\71\2\0\1\240\21\0"+ + "\1\241\2\0\1\242\61\0\1\30\2\75\2\0\2\243"+ + "\1\244\1\0\1\75\2\0\1\243\1\0\1\41\1\30"+ + "\1\243\32\30\1\0\12\75\2\0\1\244\2\0\1\243"+ + "\6\0\1\243\10\0\1\55\1\0\1\56\2\0\1\245"+ + "\1\0\1\246\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\247\2\0\1\250\4\0\1\251"+ + "\3\0\1\252\17\0\1\71\2\0\1\253\21\0\1\254"+ + "\2\0\1\255\61\0\1\30\1\76\2\0\1\76\1\0"+ + "\2\76\1\0\1\76\2\0\1\76\1\0\2\30\1\76"+ + "\32\30\13\0\1\76\1\0\1\76\22\0\1\55\1\0"+ + "\1\56\2\0\1\256\1\0\1\60\4\0\1\61\1\0"+ + "\1\62\1\0\1\63\2\0\1\64\3\0\1\257\2\0"+ + "\1\260\4\0\1\67\3\0\1\261\17\0\1\71\2\0"+ + "\1\262\21\0\1\263\2\0\1\264\41\0\1\133\17\0"+ + "\1\30\1\77\1\75\1\135\1\76\1\0\1\76\1\77"+ + "\1\0\1\77\2\0\1\76\1\0\1\41\1\30\1\76"+ + "\32\30\1\0\12\75\1\76\1\0\1\77\30\0\1\30"+ + "\4\0\1\30\11\0\1\30\22\0\1\30\3\0\1\30"+ + "\13\0\1\31\2\0\1\31\10\0\1\30\22\0\4\31"+ + "\35\0\1\30\120\0\1\30\26\0\2\30\23\0\1\31"+ + "\1\30\40\0\1\31\13\0\1\31\157\0\1\31\11\0"+ + "\1\31\15\0\4\30\2\0\2\30\14\0\3\30\1\31"+ + "\1\0\2\31\11\0\3\30\3\0\1\30\1\0\1\31"+ + "\4\0\1\31\2\30\1\0\4\31\1\0\2\30\5\0"+ + "\4\31\2\0\1\30\1\31\12\0\1\31\7\0\1\30"+ + "\122\0\1\30\4\0\1\30\6\0\1\30\3\0\1\30"+ + "\6\0\1\30\5\0\1\30\2\0\2\30\1\0\17\30"+ + "\2\0\1\30\13\0\7\30\2\0\1\30\1\0\1\30"+ + "\1\0\2\30\2\0\1\30\1\0\3\30\2\0\1\30"+ + "\1\0\1\30\1\0\1\30\1\0\1\30\4\0\1\31"+ + "\1\0\2\30\6\0\1\30\7\0\1\30\1\0\1\30"+ + "\125\0\1\30\6\0\1\30\3\0\1\30\3\0\1\30"+ + "\7\0\1\30\31\0\20\30\5\0\3\30\4\0\1\30"+ + "\6\0\1\30\3\0\2\30\2\0\2\30\4\0\1\30"+ + "\4\31\1\0\1\30\2\0\1\30\4\0\1\30\1\0"+ + "\1\30\1\0\1\30\226\0\2\31\25\0\4\31\147\0"+ + "\1\31\15\0\2\31\10\0\2\31\1\0\1\31\1\0"+ + "\1\31\11\0\1\31\11\0\2\31\6\0\1\31\2\0"+ + "\4\31\3\0\1\31\2\0\2\31\1\0\3\31\1\0"+ + "\2\31\1\0\1\31\10\0\1\31\1\0\2\31\2\0"+ + "\2\31\1\0\4\31\23\0\1\31\120\0\1\265\1\0"+ + "\1\266\17\0\1\267\2\0\1\270\4\0\1\271\3\0"+ + "\1\272\22\0\1\273\21\0\1\274\2\0\1\275\62\0"+ + "\1\111\1\31\2\0\3\243\1\0\1\111\2\0\1\243"+ + "\3\0\1\243\33\0\12\31\2\0\1\243\2\0\1\243"+ + "\6\0\1\243\10\0\1\55\1\0\1\56\2\0\1\276"+ + "\1\0\1\101\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\277\2\0\1\300\4\0\1\104"+ + "\3\0\1\301\17\0\1\71\2\0\1\302\21\0\1\303"+ + "\2\0\1\304\41\0\1\133\17\0\1\30\1\112\1\31"+ + "\1\135\1\0\2\243\1\112\1\0\1\112\2\0\1\243"+ + "\1\0\1\41\1\30\1\243\32\30\1\0\12\31\2\0"+ + "\1\112\2\0\1\243\6\0\1\243\100\0\1\32\2\0"+ + "\1\32\33\0\4\32\310\0\1\32\171\0\1\32\44\0"+ + "\1\32\1\0\2\32\21\0\1\32\4\0\1\32\17\0"+ + "\4\32\3\0\1\32\12\0\1\32\275\0\1\32\314\0"+ + "\4\32\244\0\2\32\25\0\4\32\147\0\1\32\15\0"+ + "\2\32\10\0\2\32\1\0\1\32\1\0\1\32\11\0"+ + "\1\32\11\0\2\32\6\0\1\32\2\0\4\32\3\0"+ + "\1\32\2\0\2\32\1\0\3\32\1\0\2\32\1\0"+ + "\1\32\10\0\1\32\1\0\2\32\2\0\2\32\1\0"+ + "\4\32\23\0\1\32\271\0\1\32\131\0\1\55\1\0"+ + "\1\56\2\0\1\305\1\0\1\60\4\0\1\61\1\0"+ + "\1\62\1\0\1\63\2\0\1\64\3\0\1\306\2\0"+ + "\1\307\4\0\1\67\3\0\1\310\17\0\1\71\2\0"+ + "\1\311\21\0\1\312\2\0\1\313\41\0\1\133\17\0"+ + "\1\30\1\123\1\75\1\135\3\0\1\123\1\0\1\123"+ + "\4\0\1\41\1\30\1\0\32\30\1\0\12\75\2\0"+ + "\1\123\30\0\1\30\4\0\1\30\11\0\1\30\22\0"+ + "\1\30\3\0\1\30\13\0\1\134\2\0\1\134\10\0"+ + "\1\30\22\0\4\134\35\0\1\30\120\0\1\30\26\0"+ + "\2\30\23\0\1\31\1\30\40\0\1\31\13\0\1\134"+ + "\157\0\1\31\11\0\1\134\15\0\4\30\2\0\2\30"+ + "\14\0\3\30\1\134\1\0\2\134\11\0\3\30\3\0"+ + "\1\30\1\0\1\134\4\0\1\134\2\30\1\0\4\31"+ + "\1\0\2\30\5\0\4\134\2\0\1\30\1\134\12\0"+ + "\1\134\7\0\1\30\122\0\1\30\4\0\1\30\6\0"+ "\1\30\3\0\1\30\6\0\1\30\5\0\1\30\2\0"+ "\2\30\1\0\17\30\2\0\1\30\13\0\7\30\2\0"+ - "\1\30\1\0\1\30\1\0\1\30\2\0\1\30\1\0"+ - "\1\30\1\0\1\30\1\0\1\30\4\0\1\131\1\0"+ - "\2\30\5\0\1\30\1\0\1\30\2\0\3\30\1\0"+ - "\1\30\7\0\1\30\1\0\1\30\122\0\1\30\6\0"+ - "\1\30\3\0\1\30\3\0\1\30\7\0\1\30\31\0"+ - "\20\30\5\0\3\30\3\0\1\30\3\0\2\30\2\0"+ - "\2\30\4\0\1\30\4\131\4\0\1\30\4\0\1\30"+ - "\2\0\1\30\4\0\1\30\1\0\1\30\1\0\1\30"+ - "\223\0\2\131\15\0\4\131\154\0\1\131\15\0\2\131"+ - "\10\0\2\131\1\0\1\131\1\0\1\131\11\0\1\131"+ - "\11\0\2\131\6\0\1\131\2\0\4\131\3\0\1\131"+ - "\2\0\2\131\1\0\3\131\5\0\1\131\1\0\2\131"+ - "\2\0\2\131\1\0\4\131\5\0\1\131\1\0\2\131"+ - "\311\0\1\132\133\0\1\261\21\0\1\262\2\0\1\263"+ - "\10\0\1\264\22\0\1\265\21\0\1\266\2\0\1\267"+ - "\41\0\1\130\16\0\1\132\1\0\1\132\3\0\1\75"+ - "\1\0\1\132\53\0\1\75\114\0\1\35\2\0\1\35"+ - "\23\0\4\35\305\0\1\35\176\0\1\35\44\0\1\35"+ - "\1\0\2\35\21\0\1\35\4\0\1\35\7\0\4\35"+ - "\3\0\1\35\22\0\1\35\262\0\1\35\311\0\4\35"+ - "\251\0\2\35\15\0\4\35\154\0\1\35\15\0\2\35"+ + "\1\30\1\0\1\30\1\0\2\30\2\0\1\30\1\0"+ + "\3\30\2\0\1\30\1\0\1\30\1\0\1\30\1\0"+ + "\1\30\4\0\1\134\1\0\2\30\6\0\1\30\7\0"+ + "\1\30\1\0\1\30\125\0\1\30\6\0\1\30\3\0"+ + "\1\30\3\0\1\30\7\0\1\30\31\0\20\30\5\0"+ + "\3\30\4\0\1\30\6\0\1\30\3\0\2\30\2\0"+ + "\2\30\4\0\1\30\4\134\1\0\1\30\2\0\1\30"+ + "\4\0\1\30\1\0\1\30\1\0\1\30\226\0\2\134"+ + "\25\0\4\134\147\0\1\134\15\0\2\134\10\0\2\134"+ + "\1\0\1\134\1\0\1\134\11\0\1\134\11\0\2\134"+ + "\6\0\1\134\2\0\4\134\3\0\1\134\2\0\2\134"+ + "\1\0\3\134\1\0\2\134\1\0\1\134\10\0\1\134"+ + "\1\0\2\134\2\0\2\134\1\0\4\134\23\0\1\134"+ + "\271\0\1\135\136\0\1\314\21\0\1\315\2\0\1\316"+ + "\10\0\1\317\22\0\1\320\21\0\1\321\2\0\1\322"+ + "\41\0\1\133\20\0\1\135\1\0\1\135\3\0\1\123"+ + "\1\0\1\135\56\0\1\123\112\0\1\35\2\0\1\35"+ + "\33\0\4\35\310\0\1\35\171\0\1\35\44\0\1\35"+ + "\1\0\2\35\21\0\1\35\4\0\1\35\17\0\4\35"+ + "\3\0\1\35\12\0\1\35\275\0\1\35\314\0\4\35"+ + "\244\0\2\35\25\0\4\35\147\0\1\35\15\0\2\35"+ "\10\0\2\35\1\0\1\35\1\0\1\35\11\0\1\35"+ "\11\0\2\35\6\0\1\35\2\0\4\35\3\0\1\35"+ - "\2\0\2\35\1\0\3\35\5\0\1\35\1\0\2\35"+ - "\2\0\2\35\1\0\4\35\5\0\1\35\1\0\2\35"+ - "\223\0\1\36\2\0\1\36\23\0\4\36\305\0\1\36"+ - "\176\0\1\36\44\0\1\36\1\0\2\36\21\0\1\36"+ - "\4\0\1\36\7\0\4\36\3\0\1\36\22\0\1\36"+ - "\262\0\1\36\311\0\4\36\251\0\2\36\15\0\4\36"+ - "\154\0\1\36\15\0\2\36\10\0\2\36\1\0\1\36"+ - "\1\0\1\36\11\0\1\36\11\0\2\36\6\0\1\36"+ - "\2\0\4\36\3\0\1\36\2\0\2\36\1\0\3\36"+ - "\5\0\1\36\1\0\2\36\2\0\2\36\1\0\4\36"+ - "\5\0\1\36\1\0\2\36\141\0\1\30\4\0\1\30"+ - "\11\0\1\30\22\0\1\30\3\0\1\30\13\0\1\37"+ - "\2\0\1\37\10\0\1\30\12\0\4\37\45\0\1\30"+ - "\115\0\1\30\26\0\2\30\23\0\1\73\1\30\44\0"+ - "\1\37\21\0\1\73\142\0\1\73\11\0\1\37\15\0"+ - "\4\30\2\0\2\30\14\0\3\30\1\37\1\0\2\37"+ - "\11\0\3\30\3\0\1\30\1\0\1\37\4\0\1\37"+ - "\2\30\5\0\4\37\2\0\1\30\1\37\12\0\4\73"+ - "\1\0\2\30\1\0\1\37\7\0\1\30\117\0\1\30"+ + "\2\0\2\35\1\0\3\35\1\0\2\35\1\0\1\35"+ + "\10\0\1\35\1\0\2\35\2\0\2\35\1\0\4\35"+ + "\23\0\1\35\203\0\1\36\2\0\1\36\33\0\4\36"+ + "\310\0\1\36\171\0\1\36\44\0\1\36\1\0\2\36"+ + "\21\0\1\36\4\0\1\36\17\0\4\36\3\0\1\36"+ + "\12\0\1\36\275\0\1\36\314\0\4\36\244\0\2\36"+ + "\25\0\4\36\147\0\1\36\15\0\2\36\10\0\2\36"+ + "\1\0\1\36\1\0\1\36\11\0\1\36\11\0\2\36"+ + "\6\0\1\36\2\0\4\36\3\0\1\36\2\0\2\36"+ + "\1\0\3\36\1\0\2\36\1\0\1\36\10\0\1\36"+ + "\1\0\2\36\2\0\2\36\1\0\4\36\23\0\1\36"+ + "\324\0\1\154\1\157\2\0\1\155\45\154\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\220\0\32\323\1\0\12\323\12\0\1\324\227\0\1\325"+ + "\53\0\1\156\227\0\2\157\2\0\72\157\7\0\1\30"+ + "\4\0\1\30\11\0\1\30\22\0\1\30\3\0\1\30"+ + "\13\0\1\41\2\0\1\41\10\0\1\30\22\0\4\41"+ + "\35\0\1\30\120\0\1\30\26\0\2\30\23\0\1\75"+ + "\1\30\40\0\1\75\13\0\1\41\157\0\1\75\11\0"+ + "\1\41\15\0\4\30\2\0\2\30\14\0\3\30\1\41"+ + "\1\0\2\41\11\0\3\30\3\0\1\30\1\0\1\41"+ + "\4\0\1\41\2\30\1\0\4\75\1\0\2\30\5\0"+ + "\4\41\2\0\1\30\1\41\12\0\1\41\7\0\1\30"+ + "\122\0\1\30\4\0\1\30\6\0\1\30\3\0\1\30"+ + "\6\0\1\30\5\0\1\30\2\0\2\30\1\0\17\30"+ + "\2\0\1\30\13\0\7\30\2\0\1\30\1\0\1\30"+ + "\1\0\2\30\2\0\1\30\1\0\3\30\2\0\1\30"+ + "\1\0\1\30\1\0\1\30\1\0\1\30\4\0\1\41"+ + "\1\0\2\30\6\0\1\30\7\0\1\30\1\0\1\30"+ + "\125\0\1\30\6\0\1\30\3\0\1\30\3\0\1\30"+ + "\7\0\1\30\31\0\20\30\5\0\3\30\4\0\1\30"+ + "\6\0\1\30\3\0\2\30\2\0\2\30\4\0\1\30"+ + "\4\41\1\0\1\30\2\0\1\30\4\0\1\30\1\0"+ + "\1\30\1\0\1\30\226\0\2\41\25\0\4\41\147\0"+ + "\1\41\15\0\2\41\10\0\2\41\1\0\1\41\1\0"+ + "\1\41\11\0\1\41\11\0\2\41\6\0\1\41\2\0"+ + "\4\41\3\0\1\41\2\0\2\41\1\0\3\41\1\0"+ + "\2\41\1\0\1\41\10\0\1\41\1\0\2\41\2\0"+ + "\2\41\1\0\4\41\23\0\1\41\120\0\1\326\21\0"+ + "\1\327\2\0\1\330\10\0\1\331\22\0\1\332\21\0"+ + "\1\333\2\0\1\334\62\0\1\171\7\0\1\171\4\0"+ + "\1\335\102\0\1\30\4\0\1\30\11\0\1\30\22\0"+ + "\1\30\3\0\1\30\13\0\1\42\2\0\1\42\10\0"+ + "\1\30\22\0\4\42\35\0\1\30\120\0\1\30\26\0"+ + "\2\30\23\0\1\75\1\30\40\0\1\75\13\0\1\42"+ + "\157\0\1\75\11\0\1\42\15\0\4\30\2\0\2\30"+ + "\14\0\3\30\1\42\1\0\2\42\11\0\3\30\3\0"+ + "\1\30\1\0\1\42\4\0\1\42\2\30\1\0\4\75"+ + "\1\0\2\30\5\0\4\42\2\0\1\30\1\42\12\0"+ + "\1\42\7\0\1\30\122\0\1\30\4\0\1\30\6\0"+ + "\1\30\3\0\1\30\6\0\1\30\5\0\1\30\2\0"+ + "\2\30\1\0\17\30\2\0\1\30\13\0\7\30\2\0"+ + "\1\30\1\0\1\30\1\0\2\30\2\0\1\30\1\0"+ + "\3\30\2\0\1\30\1\0\1\30\1\0\1\30\1\0"+ + "\1\30\4\0\1\42\1\0\2\30\6\0\1\30\7\0"+ + "\1\30\1\0\1\30\125\0\1\30\6\0\1\30\3\0"+ + "\1\30\3\0\1\30\7\0\1\30\31\0\20\30\5\0"+ + "\3\30\4\0\1\30\6\0\1\30\3\0\2\30\2\0"+ + "\2\30\4\0\1\30\4\42\1\0\1\30\2\0\1\30"+ + "\4\0\1\30\1\0\1\30\1\0\1\30\226\0\2\42"+ + "\25\0\4\42\147\0\1\42\15\0\2\42\10\0\2\42"+ + "\1\0\1\42\1\0\1\42\11\0\1\42\11\0\2\42"+ + "\6\0\1\42\2\0\4\42\3\0\1\42\2\0\2\42"+ + "\1\0\3\42\1\0\2\42\1\0\1\42\10\0\1\42"+ + "\1\0\2\42\2\0\2\42\1\0\4\42\23\0\1\42"+ + "\113\0\1\55\1\0\1\56\2\0\1\245\1\0\1\246"+ + "\4\0\1\61\1\0\1\62\1\0\1\63\2\0\1\64"+ + "\3\0\1\247\2\0\1\250\4\0\1\251\3\0\1\252"+ + "\17\0\1\71\2\0\1\253\21\0\1\254\2\0\1\255"+ + "\61\0\1\30\1\76\2\0\1\76\1\0\2\76\1\0"+ + "\1\76\2\0\1\201\1\0\2\30\1\336\32\217\13\154"+ + "\1\76\1\154\1\201\1\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\2\0\1\55\1\0\1\56"+ + "\2\0\1\245\1\0\1\246\4\0\1\61\1\0\1\62"+ + "\1\0\1\63\2\0\1\64\3\0\1\247\2\0\1\250"+ + "\4\0\1\251\3\0\1\252\17\0\1\71\2\0\1\253"+ + "\21\0\1\254\2\0\1\255\61\0\1\30\1\76\2\0"+ + "\1\76\1\0\2\76\1\0\1\76\2\0\1\201\1\157"+ + "\2\30\1\336\1\337\1\340\1\341\1\342\1\343\1\344"+ + "\1\345\1\346\1\347\1\350\1\351\1\352\1\353\1\354"+ + "\1\355\1\356\1\357\1\360\1\361\1\362\1\363\1\364"+ + "\1\365\1\366\1\367\1\370\1\154\12\371\1\76\1\154"+ + "\1\201\1\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\155\32\371\1\203"+ + "\12\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\2\0\1\55\1\0\1\56\2\0"+ + "\1\234\1\0\1\60\4\0\1\61\1\0\1\62\1\0"+ + "\1\63\2\0\1\64\3\0\1\235\2\0\1\236\4\0"+ + "\1\67\3\0\1\237\17\0\1\71\2\0\1\240\21\0"+ + "\1\241\2\0\1\242\61\0\1\30\2\75\2\0\2\243"+ + "\1\244\1\0\1\75\2\0\1\372\1\0\1\41\1\30"+ + "\1\373\32\43\1\203\12\204\1\0\1\154\1\374\1\154"+ + "\1\0\1\372\1\156\3\154\2\0\1\243\1\154\3\0"+ + "\2\154\2\0\1\55\1\0\1\56\2\0\1\256\1\0"+ + "\1\60\4\0\1\61\1\0\1\62\1\0\1\63\2\0"+ + "\1\64\3\0\1\257\2\0\1\260\4\0\1\67\3\0"+ + "\1\261\17\0\1\71\2\0\1\262\21\0\1\263\2\0"+ + "\1\264\41\0\1\133\17\0\1\30\1\77\1\75\1\135"+ + "\1\76\1\0\1\76\1\77\1\0\1\77\2\0\1\201"+ + "\1\0\1\41\1\30\1\336\32\217\1\154\12\375\1\76"+ + "\1\154\1\205\1\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\2\0\1\55\1\0\1\56\2\0"+ + "\1\57\1\0\1\60\4\0\1\61\1\0\1\62\1\0"+ + "\1\63\2\0\1\64\3\0\1\65\2\0\1\66\4\0"+ + "\1\67\3\0\1\70\17\0\1\71\2\0\1\72\21\0"+ + "\1\73\2\0\1\74\61\0\2\30\1\75\1\0\1\76"+ + "\1\0\1\76\1\77\1\0\1\30\2\0\1\201\1\0"+ + "\1\41\1\30\1\202\11\43\1\376\20\43\1\203\12\204"+ + "\1\76\1\154\1\205\1\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\2\0\1\55\1\0\1\56"+ + "\2\0\1\57\1\0\1\60\4\0\1\61\1\0\1\62"+ + "\1\0\1\63\2\0\1\64\3\0\1\65\2\0\1\66"+ + "\4\0\1\67\3\0\1\70\17\0\1\71\2\0\1\72"+ + "\21\0\1\73\2\0\1\74\61\0\2\30\1\75\1\0"+ + "\1\76\1\0\1\76\1\77\1\0\1\30\2\0\1\201"+ + "\1\0\1\41\1\30\1\202\15\43\1\377\14\43\1\203"+ + "\12\204\1\76\1\154\1\205\1\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\2\0\1\55\1\0"+ + "\1\56\2\0\1\57\1\0\1\60\4\0\1\61\1\0"+ + "\1\62\1\0\1\63\2\0\1\64\3\0\1\65\2\0"+ + "\1\66\4\0\1\67\3\0\1\70\17\0\1\71\2\0"+ + "\1\72\21\0\1\73\2\0\1\74\61\0\2\30\1\75"+ + "\1\0\1\76\1\0\1\76\1\77\1\0\1\30\2\0"+ + "\1\201\1\0\1\41\1\30\1\202\10\43\1\u0100\21\43"+ + "\1\203\12\204\1\76\1\154\1\205\1\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\2\0\1\55"+ + "\1\0\1\56\2\0\1\57\1\0\1\60\4\0\1\61"+ + "\1\0\1\62\1\0\1\63\2\0\1\64\3\0\1\65"+ + "\2\0\1\66\4\0\1\67\3\0\1\70\17\0\1\71"+ + "\2\0\1\72\21\0\1\73\2\0\1\74\61\0\2\30"+ + "\1\75\1\0\1\76\1\0\1\76\1\77\1\0\1\30"+ + "\2\0\1\201\1\0\1\41\1\30\1\202\17\43\1\u0101"+ + "\12\43\1\203\12\204\1\76\1\154\1\205\1\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\7\0"+ + "\1\265\1\0\1\266\17\0\1\267\2\0\1\270\4\0"+ + "\1\271\3\0\1\272\22\0\1\273\21\0\1\274\2\0"+ + "\1\275\62\0\1\111\1\31\2\0\3\243\1\0\1\111"+ + "\2\0\1\372\3\0\1\u0102\33\154\12\220\1\0\1\154"+ + "\1\372\1\154\1\0\1\372\1\156\3\154\2\0\1\243"+ + "\1\154\3\0\2\154\7\0\1\265\1\0\1\266\17\0"+ + "\1\267\2\0\1\270\4\0\1\271\3\0\1\272\22\0"+ + "\1\273\21\0\1\274\2\0\1\275\62\0\1\111\1\31"+ + "\2\0\3\243\1\0\1\111\2\0\1\372\1\157\2\0"+ + "\1\u0102\1\u0103\1\u0104\1\u0105\1\u0106\1\u0107\1\u0108\1\u0109"+ + "\1\u010a\1\u010b\1\u010c\1\u010d\1\u010e\1\u010f\1\u0110\1\u0111"+ + "\1\u0112\1\u0113\1\u0114\1\u0115\1\u0116\1\u0117\1\u0118\1\u0119"+ + "\1\u011a\1\u011b\1\u011c\1\154\1\u011d\1\u011e\5\u011d\1\u011f"+ + "\1\u011e\1\u011d\1\0\1\154\1\372\1\154\1\0\1\372"+ + "\1\156\3\154\2\0\1\243\1\154\3\0\2\154\2\0"+ + "\1\55\1\0\1\56\2\0\1\100\1\0\1\101\4\0"+ + "\1\61\1\0\1\62\1\0\1\63\2\0\1\64\3\0"+ + "\1\102\2\0\1\103\4\0\1\104\3\0\1\105\17\0"+ + "\1\71\2\0\1\106\21\0\1\107\2\0\1\110\61\0"+ + "\1\30\2\31\2\0\2\111\1\112\1\0\1\31\2\0"+ + "\1\212\1\0\1\41\1\30\1\213\32\43\1\203\12\u0120"+ + "\1\0\1\154\1\215\1\154\1\0\1\212\1\156\3\154"+ + "\2\0\1\111\1\154\3\0\2\154\2\0\1\55\1\0"+ + "\1\56\2\0\1\276\1\0\1\101\4\0\1\61\1\0"+ + "\1\62\1\0\1\63\2\0\1\64\3\0\1\277\2\0"+ + "\1\300\4\0\1\104\3\0\1\301\17\0\1\71\2\0"+ + "\1\302\21\0\1\303\2\0\1\304\41\0\1\133\17\0"+ + "\1\30\1\112\1\31\1\135\1\0\2\243\1\112\1\0"+ + "\1\112\2\0\1\372\1\0\1\41\1\30\1\u0102\32\217"+ + "\1\154\12\220\1\0\1\154\1\215\1\154\1\0\1\372"+ + "\1\156\3\154\2\0\1\243\1\154\3\0\2\154\2\0"+ + "\1\55\1\0\1\56\2\0\1\100\1\0\1\101\4\0"+ + "\1\61\1\0\1\62\1\0\1\63\2\0\1\64\3\0"+ + "\1\102\2\0\1\103\4\0\1\104\3\0\1\105\17\0"+ + "\1\71\2\0\1\106\21\0\1\107\2\0\1\110\61\0"+ + "\1\30\2\31\2\0\2\111\1\112\1\0\1\31\2\0"+ + "\1\212\1\0\1\41\1\30\1\213\32\43\1\203\2\214"+ + "\1\u0120\2\214\2\u0120\2\214\1\u0120\1\0\1\154\1\215"+ + "\1\154\1\0\1\212\1\156\3\154\2\0\1\111\1\154"+ + "\3\0\2\154\2\0\1\55\1\0\1\56\2\0\1\57"+ + "\1\0\1\60\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\65\2\0\1\66\4\0\1\67"+ + "\3\0\1\70\17\0\1\71\2\0\1\72\21\0\1\73"+ + "\2\0\1\74\61\0\2\30\1\75\1\0\1\76\1\0"+ + "\1\76\1\77\1\0\1\30\2\0\1\201\1\0\1\41"+ + "\1\30\1\336\32\217\1\154\12\375\1\76\1\154\1\205"+ + "\1\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\2\0\1\55\1\0\1\56\2\0\1\100\1\0"+ + "\1\101\4\0\1\61\1\0\1\62\1\0\1\63\2\0"+ + "\1\64\3\0\1\102\2\0\1\103\4\0\1\104\3\0"+ + "\1\105\17\0\1\71\2\0\1\106\21\0\1\107\2\0"+ + "\1\110\61\0\1\30\2\31\2\0\2\111\1\112\1\0"+ + "\1\31\2\0\1\212\1\0\1\41\1\30\1\u0121\32\217"+ + "\1\154\12\220\1\0\1\154\1\215\1\154\1\0\1\212"+ + "\1\156\3\154\2\0\1\111\1\154\3\0\2\154\220\0"+ + "\4\u0122\2\0\1\u0122\15\0\1\u0122\6\0\12\u0122\1\u0123"+ + "\307\0\1\u0124\114\0\1\54\2\0\1\54\33\0\4\54"+ + "\310\0\1\54\171\0\1\54\44\0\1\54\1\0\2\54"+ + "\21\0\1\54\4\0\1\54\17\0\4\54\3\0\1\54"+ + "\12\0\1\54\275\0\1\54\314\0\4\54\244\0\2\54"+ + "\25\0\4\54\147\0\1\54\15\0\2\54\10\0\2\54"+ + "\1\0\1\54\1\0\1\54\11\0\1\54\11\0\2\54"+ + "\6\0\1\54\2\0\4\54\3\0\1\54\2\0\2\54"+ + "\1\0\3\54\1\0\2\54\1\0\1\54\10\0\1\54"+ + "\1\0\2\54\2\0\2\54\1\0\4\54\23\0\1\54"+ + "\257\0\1\u0125\26\0\2\u0125\121\0\1\30\4\0\1\30"+ + "\11\0\1\30\22\0\1\30\3\0\1\30\13\0\1\75"+ + "\2\0\1\75\10\0\1\30\22\0\4\75\35\0\1\30"+ + "\120\0\1\30\26\0\2\30\23\0\1\75\1\30\40\0"+ + "\1\75\13\0\1\75\157\0\1\75\11\0\1\75\15\0"+ + "\4\30\2\0\2\30\14\0\3\30\1\75\1\0\2\75"+ + "\11\0\3\30\3\0\1\30\1\0\1\75\4\0\1\75"+ + "\2\30\1\0\4\75\1\0\2\30\5\0\4\75\2\0"+ + "\1\30\1\75\12\0\1\75\7\0\1\30\122\0\1\30"+ "\4\0\1\30\6\0\1\30\3\0\1\30\6\0\1\30"+ "\5\0\1\30\2\0\2\30\1\0\17\30\2\0\1\30"+ - "\13\0\7\30\2\0\1\30\1\0\1\30\1\0\1\30"+ + "\13\0\7\30\2\0\1\30\1\0\1\30\1\0\2\30"+ + "\2\0\1\30\1\0\3\30\2\0\1\30\1\0\1\30"+ + "\1\0\1\30\1\0\1\30\4\0\1\75\1\0\2\30"+ + "\6\0\1\30\7\0\1\30\1\0\1\30\125\0\1\30"+ + "\6\0\1\30\3\0\1\30\3\0\1\30\7\0\1\30"+ + "\31\0\20\30\5\0\3\30\4\0\1\30\6\0\1\30"+ + "\3\0\2\30\2\0\2\30\4\0\1\30\4\75\1\0"+ + "\1\30\2\0\1\30\4\0\1\30\1\0\1\30\1\0"+ + "\1\30\226\0\2\75\25\0\4\75\147\0\1\75\15\0"+ + "\2\75\10\0\2\75\1\0\1\75\1\0\1\75\11\0"+ + "\1\75\11\0\2\75\6\0\1\75\2\0\4\75\3\0"+ + "\1\75\2\0\2\75\1\0\3\75\1\0\2\75\1\0"+ + "\1\75\10\0\1\75\1\0\2\75\2\0\2\75\1\0"+ + "\4\75\23\0\1\75\120\0\1\u0126\1\0\1\u0127\17\0"+ + "\1\u0128\2\0\1\u0129\4\0\1\u012a\3\0\1\u012b\22\0"+ + "\1\u012c\21\0\1\u012d\2\0\1\u012e\62\0\1\243\1\75"+ + "\2\0\3\243\1\0\1\243\2\0\1\243\3\0\1\243"+ + "\33\0\12\75\2\0\1\243\2\0\1\243\6\0\1\243"+ + "\10\0\1\55\1\0\1\56\2\0\1\u012f\1\0\1\60"+ + "\4\0\1\61\1\0\1\62\1\0\1\63\2\0\1\64"+ + "\3\0\1\u0130\2\0\1\u0131\4\0\1\67\3\0\1\u0132"+ + "\17\0\1\71\2\0\1\u0133\21\0\1\u0134\2\0\1\u0135"+ + "\41\0\1\133\17\0\1\30\1\244\1\75\1\135\1\0"+ + "\2\243\1\244\1\0\1\244\2\0\1\243\1\0\1\41"+ + "\1\30\1\243\32\30\1\0\12\75\2\0\1\244\2\0"+ + "\1\243\6\0\1\243\16\0\1\30\4\0\1\30\11\0"+ + "\1\30\22\0\1\30\3\0\1\30\13\0\1\76\2\0"+ + "\1\76\10\0\1\30\22\0\4\76\35\0\1\30\123\0"+ + "\1\30\3\0\4\30\1\0\1\30\4\0\1\30\1\0"+ + "\2\30\2\0\2\30\2\0\3\30\1\0\1\30\1\0"+ + "\1\30\2\0\4\30\1\0\3\30\1\0\1\30\1\0"+ + "\3\30\1\0\2\30\1\0\4\30\1\0\2\30\2\0"+ + "\10\30\1\0\2\30\1\0\10\30\2\0\7\30\1\0"+ + "\10\30\1\0\6\30\1\0\1\30\1\0\2\30\2\0"+ + "\1\30\1\0\1\30\3\0\3\30\114\0\1\30\26\0"+ + "\2\30\24\0\1\30\54\0\1\76\171\0\1\76\15\0"+ + "\4\30\2\0\2\30\14\0\3\30\1\76\1\0\2\76"+ + "\11\0\3\30\3\0\1\30\1\0\1\76\4\0\1\76"+ + "\2\30\6\0\2\30\5\0\4\76\2\0\1\30\1\76"+ + "\12\0\1\76\7\0\1\30\136\0\1\30\3\0\2\30"+ + "\12\0\2\30\1\0\3\30\7\0\1\30\6\0\2\30"+ + "\1\0\2\30\6\0\1\30\4\0\2\30\2\0\2\30"+ + "\5\0\3\30\2\0\1\30\15\0\1\30\16\0\1\30"+ + "\7\0\1\30\122\0\1\30\4\0\1\30\6\0\1\30"+ + "\3\0\1\30\6\0\1\30\5\0\1\30\2\0\2\30"+ + "\1\0\17\30\2\0\1\30\13\0\7\30\2\0\1\30"+ + "\1\0\1\30\1\0\2\30\2\0\1\30\1\0\3\30"+ "\2\0\1\30\1\0\1\30\1\0\1\30\1\0\1\30"+ - "\4\0\1\37\1\0\2\30\5\0\1\30\1\0\1\30"+ - "\2\0\3\30\1\0\1\30\7\0\1\30\1\0\1\30"+ - "\122\0\1\30\6\0\1\30\3\0\1\30\3\0\1\30"+ - "\7\0\1\30\31\0\20\30\5\0\3\30\3\0\1\30"+ - "\3\0\2\30\2\0\2\30\4\0\1\30\4\37\4\0"+ - "\1\30\4\0\1\30\2\0\1\30\4\0\1\30\1\0"+ - "\1\30\1\0\1\30\223\0\2\37\15\0\4\37\154\0"+ - "\1\37\15\0\2\37\10\0\2\37\1\0\1\37\1\0"+ - "\1\37\11\0\1\37\11\0\2\37\6\0\1\37\2\0"+ - "\4\37\3\0\1\37\2\0\2\37\1\0\3\37\5\0"+ - "\1\37\1\0\2\37\2\0\2\37\1\0\4\37\5\0"+ - "\1\37\1\0\2\37\343\0\1\160\45\161\1\0\3\161"+ - "\1\0\2\161\1\162\3\161\3\0\1\161\1\206\3\0"+ - "\2\161\213\0\32\270\1\0\12\270\13\0\1\271\13\0"+ - "\1\53\1\0\1\54\2\0\1\221\1\0\1\222\4\0"+ - "\1\57\1\0\1\60\1\0\1\61\2\0\1\62\3\0"+ - "\1\223\2\0\1\224\4\0\1\225\3\0\1\226\17\0"+ - "\1\67\2\0\1\227\21\0\1\230\2\0\1\231\57\0"+ - "\1\30\1\74\7\0\1\74\2\0\1\30\1\160\1\272"+ - "\1\273\1\274\1\275\1\276\1\277\1\300\1\301\1\302"+ - "\1\303\1\304\1\305\1\306\1\307\1\310\1\311\1\312"+ - "\1\313\1\314\1\315\1\316\1\317\1\320\1\321\1\322"+ - "\1\323\1\161\12\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\1\206\3\0\2\161\212\0\1\160"+ - "\32\324\1\164\12\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\2\0\1\53\1\0"+ - "\1\54\2\0\1\211\1\0\1\56\4\0\1\57\1\0"+ - "\1\60\1\0\1\61\2\0\1\62\3\0\1\212\2\0"+ - "\1\213\4\0\1\65\3\0\1\214\17\0\1\67\2\0"+ - "\1\215\21\0\1\216\2\0\1\217\57\0\1\30\2\73"+ - "\2\0\2\220\1\75\1\0\1\73\2\0\1\30\1\325"+ - "\32\41\1\164\12\165\1\0\1\161\1\166\1\161\1\0"+ - "\2\326\1\162\3\161\2\0\1\220\1\161\4\0\2\161"+ - "\2\0\1\53\1\0\1\54\2\0\1\232\1\0\1\56"+ - "\4\0\1\57\1\0\1\60\1\0\1\61\2\0\1\62"+ - "\3\0\1\233\2\0\1\234\4\0\1\65\3\0\1\235"+ - "\17\0\1\67\2\0\1\236\21\0\1\237\2\0\1\240"+ - "\41\0\1\130\15\0\1\30\1\75\1\73\1\132\3\0"+ - "\1\75\1\0\1\75\2\0\1\30\1\160\32\201\1\161"+ - "\12\327\1\0\1\161\1\166\1\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\2\0\1\53\1\0"+ - "\1\54\2\0\1\221\1\0\1\222\4\0\1\57\1\0"+ - "\1\60\1\0\1\61\2\0\1\62\3\0\1\223\2\0"+ - "\1\224\4\0\1\225\3\0\1\226\17\0\1\67\2\0"+ - "\1\227\21\0\1\230\2\0\1\231\57\0\1\30\1\74"+ - "\7\0\1\74\2\0\1\30\1\160\32\201\13\161\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\2\0\1\53\1\0\1\54\2\0\1\55\1\0"+ - "\1\56\4\0\1\57\1\0\1\60\1\0\1\61\2\0"+ - "\1\62\3\0\1\63\2\0\1\64\4\0\1\65\3\0"+ - "\1\66\17\0\1\67\2\0\1\70\21\0\1\71\2\0"+ - "\1\72\57\0\2\30\1\73\1\0\1\74\1\0\1\74"+ - "\1\75\1\0\1\30\2\0\1\30\1\163\11\41\1\330"+ - "\20\41\1\164\12\165\1\74\1\161\1\166\1\161\1\0"+ - "\1\161\1\167\1\162\3\161\3\0\1\161\4\0\2\161"+ - "\2\0\1\53\1\0\1\54\2\0\1\55\1\0\1\56"+ - "\4\0\1\57\1\0\1\60\1\0\1\61\2\0\1\62"+ - "\3\0\1\63\2\0\1\64\4\0\1\65\3\0\1\66"+ - "\17\0\1\67\2\0\1\70\21\0\1\71\2\0\1\72"+ - "\57\0\2\30\1\73\1\0\1\74\1\0\1\74\1\75"+ - "\1\0\1\30\2\0\1\30\1\163\15\41\1\331\14\41"+ - "\1\164\12\165\1\74\1\161\1\166\1\161\1\0\1\161"+ - "\1\167\1\162\3\161\3\0\1\161\4\0\2\161\2\0"+ - "\1\53\1\0\1\54\2\0\1\55\1\0\1\56\4\0"+ - "\1\57\1\0\1\60\1\0\1\61\2\0\1\62\3\0"+ - "\1\63\2\0\1\64\4\0\1\65\3\0\1\66\17\0"+ - "\1\67\2\0\1\70\21\0\1\71\2\0\1\72\57\0"+ - "\2\30\1\73\1\0\1\74\1\0\1\74\1\75\1\0"+ - "\1\30\2\0\1\30\1\163\10\41\1\332\21\41\1\164"+ - "\12\165\1\74\1\161\1\166\1\161\1\0\1\161\1\167"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\2\0\1\53"+ - "\1\0\1\54\2\0\1\55\1\0\1\56\4\0\1\57"+ - "\1\0\1\60\1\0\1\61\2\0\1\62\3\0\1\63"+ - "\2\0\1\64\4\0\1\65\3\0\1\66\17\0\1\67"+ - "\2\0\1\70\21\0\1\71\2\0\1\72\57\0\2\30"+ - "\1\73\1\0\1\74\1\0\1\74\1\75\1\0\1\30"+ - "\2\0\1\30\1\163\17\41\1\333\12\41\1\164\12\165"+ - "\1\74\1\161\1\166\1\161\1\0\1\161\1\167\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\7\0\1\241\1\0"+ - "\1\242\17\0\1\243\2\0\1\244\4\0\1\245\3\0"+ - "\1\246\22\0\1\247\21\0\1\250\2\0\1\251\60\0"+ - "\1\107\1\31\6\0\1\107\3\0\1\160\1\334\1\335"+ + "\4\0\1\76\1\0\2\30\6\0\1\30\7\0\1\30"+ + "\1\0\1\30\125\0\1\30\6\0\1\30\3\0\1\30"+ + "\3\0\1\30\7\0\1\30\31\0\20\30\5\0\3\30"+ + "\4\0\1\30\6\0\1\30\3\0\2\30\2\0\2\30"+ + "\4\0\1\30\4\76\1\0\1\30\2\0\1\30\4\0"+ + "\1\30\1\0\1\30\1\0\1\30\226\0\2\76\25\0"+ + "\4\76\147\0\1\76\15\0\2\76\10\0\2\76\1\0"+ + "\1\76\1\0\1\76\11\0\1\76\11\0\2\76\6\0"+ + "\1\76\2\0\4\76\3\0\1\76\2\0\2\76\1\0"+ + "\3\76\1\0\2\76\1\0\1\76\10\0\1\76\1\0"+ + "\2\76\2\0\2\76\1\0\4\76\23\0\1\76\121\0"+ + "\1\30\4\0\1\30\11\0\1\30\22\0\1\30\3\0"+ + "\1\30\13\0\1\77\2\0\1\77\10\0\1\30\22\0"+ + "\4\77\35\0\1\30\120\0\1\30\26\0\2\30\23\0"+ + "\1\75\1\30\40\0\1\75\13\0\1\77\157\0\1\75"+ + "\11\0\1\77\15\0\4\30\2\0\2\30\14\0\3\30"+ + "\1\77\1\0\2\77\11\0\3\30\3\0\1\30\1\0"+ + "\1\77\4\0\1\77\2\30\1\0\4\75\1\0\2\30"+ + "\5\0\4\77\2\0\1\30\1\77\12\0\1\77\7\0"+ + "\1\30\122\0\1\30\4\0\1\30\6\0\1\30\3\0"+ + "\1\30\6\0\1\30\5\0\1\30\2\0\2\30\1\0"+ + "\17\30\2\0\1\30\13\0\7\30\2\0\1\30\1\0"+ + "\1\30\1\0\2\30\2\0\1\30\1\0\3\30\2\0"+ + "\1\30\1\0\1\30\1\0\1\30\1\0\1\30\4\0"+ + "\1\77\1\0\2\30\6\0\1\30\7\0\1\30\1\0"+ + "\1\30\125\0\1\30\6\0\1\30\3\0\1\30\3\0"+ + "\1\30\7\0\1\30\31\0\20\30\5\0\3\30\4\0"+ + "\1\30\6\0\1\30\3\0\2\30\2\0\2\30\4\0"+ + "\1\30\4\77\1\0\1\30\2\0\1\30\4\0\1\30"+ + "\1\0\1\30\1\0\1\30\226\0\2\77\25\0\4\77"+ + "\147\0\1\77\15\0\2\77\10\0\2\77\1\0\1\77"+ + "\1\0\1\77\11\0\1\77\11\0\2\77\6\0\1\77"+ + "\2\0\4\77\3\0\1\77\2\0\2\77\1\0\3\77"+ + "\1\0\2\77\1\0\1\77\10\0\1\77\1\0\2\77"+ + "\2\0\2\77\1\0\4\77\23\0\1\77\203\0\1\111"+ + "\2\0\1\111\33\0\4\111\174\0\1\31\104\0\1\31"+ + "\240\0\1\31\41\0\1\31\13\0\1\111\157\0\1\31"+ + "\11\0\1\111\44\0\1\111\1\0\2\111\21\0\1\111"+ + "\4\0\1\111\3\0\4\31\10\0\4\111\3\0\1\111"+ + "\12\0\1\111\256\0\2\31\325\0\1\111\314\0\4\111"+ + "\244\0\2\111\25\0\4\111\147\0\1\111\15\0\2\111"+ + "\10\0\2\111\1\0\1\111\1\0\1\111\11\0\1\111"+ + "\11\0\2\111\6\0\1\111\2\0\4\111\3\0\1\111"+ + "\2\0\2\111\1\0\3\111\1\0\2\111\1\0\1\111"+ + "\10\0\1\111\1\0\2\111\2\0\2\111\1\0\4\111"+ + "\23\0\1\111\121\0\1\30\4\0\1\30\11\0\1\30"+ + "\22\0\1\30\3\0\1\30\13\0\1\112\2\0\1\112"+ + "\10\0\1\30\22\0\4\112\35\0\1\30\120\0\1\30"+ + "\26\0\2\30\23\0\1\31\1\30\40\0\1\31\13\0"+ + "\1\112\157\0\1\31\11\0\1\112\15\0\4\30\2\0"+ + "\2\30\14\0\3\30\1\112\1\0\2\112\11\0\3\30"+ + "\3\0\1\30\1\0\1\112\4\0\1\112\2\30\1\0"+ + "\4\31\1\0\2\30\5\0\4\112\2\0\1\30\1\112"+ + "\12\0\1\112\7\0\1\30\122\0\1\30\4\0\1\30"+ + "\6\0\1\30\3\0\1\30\6\0\1\30\5\0\1\30"+ + "\2\0\2\30\1\0\17\30\2\0\1\30\13\0\7\30"+ + "\2\0\1\30\1\0\1\30\1\0\2\30\2\0\1\30"+ + "\1\0\3\30\2\0\1\30\1\0\1\30\1\0\1\30"+ + "\1\0\1\30\4\0\1\112\1\0\2\30\6\0\1\30"+ + "\7\0\1\30\1\0\1\30\125\0\1\30\6\0\1\30"+ + "\3\0\1\30\3\0\1\30\7\0\1\30\31\0\20\30"+ + "\5\0\3\30\4\0\1\30\6\0\1\30\3\0\2\30"+ + "\2\0\2\30\4\0\1\30\4\112\1\0\1\30\2\0"+ + "\1\30\4\0\1\30\1\0\1\30\1\0\1\30\226\0"+ + "\2\112\25\0\4\112\147\0\1\112\15\0\2\112\10\0"+ + "\2\112\1\0\1\112\1\0\1\112\11\0\1\112\11\0"+ + "\2\112\6\0\1\112\2\0\4\112\3\0\1\112\2\0"+ + "\2\112\1\0\3\112\1\0\2\112\1\0\1\112\10\0"+ + "\1\112\1\0\2\112\2\0\2\112\1\0\4\112\23\0"+ + "\1\112\121\0\1\30\4\0\1\30\11\0\1\30\22\0"+ + "\1\30\3\0\1\30\13\0\1\123\2\0\1\123\10\0"+ + "\1\30\22\0\4\123\35\0\1\30\120\0\1\30\26\0"+ + "\2\30\23\0\1\75\1\30\40\0\1\75\13\0\1\123"+ + "\157\0\1\75\11\0\1\123\15\0\4\30\2\0\2\30"+ + "\14\0\3\30\1\123\1\0\2\123\11\0\3\30\3\0"+ + "\1\30\1\0\1\123\4\0\1\123\2\30\1\0\4\75"+ + "\1\0\2\30\5\0\4\123\2\0\1\30\1\123\12\0"+ + "\1\123\7\0\1\30\122\0\1\30\4\0\1\30\6\0"+ + "\1\30\3\0\1\30\6\0\1\30\5\0\1\30\2\0"+ + "\2\30\1\0\17\30\2\0\1\30\13\0\7\30\2\0"+ + "\1\30\1\0\1\30\1\0\2\30\2\0\1\30\1\0"+ + "\3\30\2\0\1\30\1\0\1\30\1\0\1\30\1\0"+ + "\1\30\4\0\1\123\1\0\2\30\6\0\1\30\7\0"+ + "\1\30\1\0\1\30\125\0\1\30\6\0\1\30\3\0"+ + "\1\30\3\0\1\30\7\0\1\30\31\0\20\30\5\0"+ + "\3\30\4\0\1\30\6\0\1\30\3\0\2\30\2\0"+ + "\2\30\4\0\1\30\4\123\1\0\1\30\2\0\1\30"+ + "\4\0\1\30\1\0\1\30\1\0\1\30\226\0\2\123"+ + "\25\0\4\123\147\0\1\123\15\0\2\123\10\0\2\123"+ + "\1\0\1\123\1\0\1\123\11\0\1\123\11\0\2\123"+ + "\6\0\1\123\2\0\4\123\3\0\1\123\2\0\2\123"+ + "\1\0\3\123\1\0\2\123\1\0\1\123\10\0\1\123"+ + "\1\0\2\123\2\0\2\123\1\0\4\123\23\0\1\123"+ + "\203\0\1\135\2\0\1\135\33\0\4\135\310\0\1\135"+ + "\171\0\1\135\44\0\1\135\1\0\2\135\21\0\1\135"+ + "\4\0\1\135\17\0\4\135\3\0\1\135\12\0\1\135"+ + "\275\0\1\135\314\0\4\135\244\0\2\135\25\0\4\135"+ + "\147\0\1\135\15\0\2\135\10\0\2\135\1\0\1\135"+ + "\1\0\1\135\11\0\1\135\11\0\2\135\6\0\1\135"+ + "\2\0\4\135\3\0\1\135\2\0\2\135\1\0\3\135"+ + "\1\0\2\135\1\0\1\135\10\0\1\135\1\0\2\135"+ + "\2\0\2\135\1\0\4\135\23\0\1\135\330\0\1\u0136"+ + "\32\323\1\u0137\12\323\236\0\2\324\2\0\60\324\1\0"+ + "\1\u0138\3\324\1\u0139\1\0\3\324\212\0\1\154\1\157"+ + "\2\0\46\154\1\0\3\154\1\0\1\154\1\0\3\154"+ + "\3\0\1\154\3\0\2\154\72\0\1\171\2\0\1\171"+ + "\33\0\4\171\310\0\1\171\171\0\1\171\44\0\1\171"+ + "\1\0\2\171\21\0\1\171\4\0\1\171\17\0\4\171"+ + "\3\0\1\171\12\0\1\171\275\0\1\171\314\0\4\171"+ + "\244\0\2\171\25\0\4\171\147\0\1\171\15\0\2\171"+ + "\10\0\2\171\1\0\1\171\1\0\1\171\11\0\1\171"+ + "\11\0\2\171\6\0\1\171\2\0\4\171\3\0\1\171"+ + "\2\0\2\171\1\0\3\171\1\0\2\171\1\0\1\171"+ + "\10\0\1\171\1\0\2\171\2\0\2\171\1\0\4\171"+ + "\23\0\1\171\113\0\1\55\1\0\1\56\2\0\1\u013a"+ + "\1\0\1\60\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\u013b\2\0\1\u013c\4\0\1\67"+ + "\3\0\1\u013d\17\0\1\71\2\0\1\u013e\21\0\1\u013f"+ + "\2\0\1\u0140\61\0\1\30\1\335\1\75\4\0\1\123"+ + "\1\0\1\335\4\0\1\41\1\30\1\0\32\30\1\0"+ + "\12\75\2\0\1\123\22\0\1\55\1\0\1\56\2\0"+ + "\1\245\1\0\1\246\4\0\1\61\1\0\1\62\1\0"+ + "\1\63\2\0\1\64\3\0\1\247\2\0\1\250\4\0"+ + "\1\251\3\0\1\252\17\0\1\71\2\0\1\253\21\0"+ + "\1\254\2\0\1\255\61\0\1\30\1\76\2\0\1\76"+ + "\1\0\2\76\1\0\1\76\2\0\1\201\1\157\2\30"+ + "\1\336\32\217\13\154\1\76\1\154\1\201\1\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\2\0"+ + "\1\55\1\0\1\56\2\0\1\57\1\0\1\60\4\0"+ + "\1\61\1\0\1\62\1\0\1\63\2\0\1\64\3\0"+ + "\1\65\2\0\1\66\4\0\1\67\3\0\1\70\17\0"+ + "\1\71\2\0\1\72\21\0\1\73\2\0\1\74\61\0"+ + "\2\30\1\75\1\0\1\76\1\0\1\76\1\77\1\0"+ + "\1\30\2\0\1\201\1\0\1\41\1\30\1\202\1\43"+ + "\2\u0141\1\u0142\1\u0143\10\u0141\1\43\1\u0144\5\u0141\6\43"+ + "\1\203\12\204\1\76\1\154\1\205\1\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\2\0\1\55"+ + "\1\0\1\56\2\0\1\57\1\0\1\60\4\0\1\61"+ + "\1\0\1\62\1\0\1\63\2\0\1\64\3\0\1\65"+ + "\2\0\1\66\4\0\1\67\3\0\1\70\17\0\1\71"+ + "\2\0\1\72\21\0\1\73\2\0\1\74\61\0\2\30"+ + "\1\75\1\0\1\76\1\0\1\76\1\77\1\0\1\30"+ + "\2\0\1\201\1\0\1\41\1\30\1\202\1\u0145\2\u0141"+ + "\1\43\1\u0141\1\u0146\3\u0141\1\u0147\2\u0141\4\43\4\u0141"+ + "\1\43\2\u0141\1\43\2\u0141\1\203\12\204\1\76\1\154"+ + "\1\205\1\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\2\0\1\55\1\0\1\56\2\0\1\57"+ + "\1\0\1\60\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\65\2\0\1\66\4\0\1\67"+ + "\3\0\1\70\17\0\1\71\2\0\1\72\21\0\1\73"+ + "\2\0\1\74\61\0\2\30\1\75\1\0\1\76\1\0"+ + "\1\76\1\77\1\0\1\30\2\0\1\201\1\0\1\41"+ + "\1\30\1\202\3\43\1\u0141\1\43\1\u0141\2\43\1\u0148"+ + "\1\43\1\u0141\10\43\1\u0141\2\43\2\u0141\2\43\1\203"+ + "\12\204\1\76\1\154\1\205\1\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\2\0\1\55\1\0"+ + "\1\56\2\0\1\57\1\0\1\60\4\0\1\61\1\0"+ + "\1\62\1\0\1\63\2\0\1\64\3\0\1\65\2\0"+ + "\1\66\4\0\1\67\3\0\1\70\17\0\1\71\2\0"+ + "\1\72\21\0\1\73\2\0\1\74\61\0\2\30\1\75"+ + "\1\0\1\76\1\0\1\76\1\77\1\0\1\30\2\0"+ + "\1\201\1\0\1\41\1\30\1\202\1\43\1\u0141\1\u0149"+ + "\2\u0141\2\43\1\u0141\3\43\1\u014a\1\u014b\1\43\1\u014c"+ + "\2\u0141\11\43\1\203\12\204\1\76\1\154\1\205\1\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\2\0\1\55\1\0\1\56\2\0\1\57\1\0\1\60"+ + "\4\0\1\61\1\0\1\62\1\0\1\63\2\0\1\64"+ + "\3\0\1\65\2\0\1\66\4\0\1\67\3\0\1\70"+ + "\17\0\1\71\2\0\1\72\21\0\1\73\2\0\1\74"+ + "\61\0\2\30\1\75\1\0\1\76\1\0\1\76\1\77"+ + "\1\0\1\30\2\0\1\201\1\0\1\41\1\30\1\202"+ + "\3\43\1\u0141\1\43\1\u0141\10\43\1\u0141\1\43\2\u0141"+ + "\10\43\1\203\12\204\1\76\1\154\1\205\1\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\2\0"+ + "\1\55\1\0\1\56\2\0\1\57\1\0\1\60\4\0"+ + "\1\61\1\0\1\62\1\0\1\63\2\0\1\64\3\0"+ + "\1\65\2\0\1\66\4\0\1\67\3\0\1\70\17\0"+ + "\1\71\2\0\1\72\21\0\1\73\2\0\1\74\61\0"+ + "\2\30\1\75\1\0\1\76\1\0\1\76\1\77\1\0"+ + "\1\30\2\0\1\201\1\0\1\41\1\30\1\202\4\43"+ + "\1\u014d\5\43\1\u0141\17\43\1\203\12\204\1\76\1\154"+ + "\1\205\1\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\2\0\1\55\1\0\1\56\2\0\1\57"+ + "\1\0\1\60\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\65\2\0\1\66\4\0\1\67"+ + "\3\0\1\70\17\0\1\71\2\0\1\72\21\0\1\73"+ + "\2\0\1\74\61\0\2\30\1\75\1\0\1\76\1\0"+ + "\1\76\1\77\1\0\1\30\2\0\1\201\1\0\1\41"+ + "\1\30\1\202\4\43\2\u0141\2\43\1\u0141\1\43\1\u0141"+ + "\13\43\2\u0141\2\43\1\203\12\204\1\76\1\154\1\205"+ + "\1\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\2\0\1\55\1\0\1\56\2\0\1\57\1\0"+ + "\1\60\4\0\1\61\1\0\1\62\1\0\1\63\2\0"+ + "\1\64\3\0\1\65\2\0\1\66\4\0\1\67\3\0"+ + "\1\70\17\0\1\71\2\0\1\72\21\0\1\73\2\0"+ + "\1\74\61\0\2\30\1\75\1\0\1\76\1\0\1\76"+ + "\1\77\1\0\1\30\2\0\1\201\1\0\1\41\1\30"+ + "\1\202\1\u014e\1\43\2\u0141\1\u014f\1\u0150\12\u0141\1\u0151"+ + "\1\u0141\2\43\2\u0141\3\43\1\u0141\1\203\12\204\1\76"+ + "\1\154\1\205\1\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\2\0\1\55\1\0\1\56\2\0"+ + "\1\57\1\0\1\60\4\0\1\61\1\0\1\62\1\0"+ + "\1\63\2\0\1\64\3\0\1\65\2\0\1\66\4\0"+ + "\1\67\3\0\1\70\17\0\1\71\2\0\1\72\21\0"+ + "\1\73\2\0\1\74\61\0\2\30\1\75\1\0\1\76"+ + "\1\0\1\76\1\77\1\0\1\30\2\0\1\201\1\0"+ + "\1\41\1\30\1\202\2\43\4\u0141\3\43\2\u0141\1\u0152"+ + "\1\u0141\1\43\2\u0141\12\43\1\203\12\204\1\76\1\154"+ + "\1\205\1\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\2\0\1\55\1\0\1\56\2\0\1\57"+ + "\1\0\1\60\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\65\2\0\1\66\4\0\1\67"+ + "\3\0\1\70\17\0\1\71\2\0\1\72\21\0\1\73"+ + "\2\0\1\74\61\0\2\30\1\75\1\0\1\76\1\0"+ + "\1\76\1\77\1\0\1\30\2\0\1\201\1\0\1\41"+ + "\1\30\1\202\1\u0153\1\u0141\2\43\1\u0141\3\43\1\u0154"+ + "\5\43\3\u0141\3\43\1\u0141\1\43\1\u0141\1\43\2\u0141"+ + "\1\203\12\204\1\76\1\154\1\205\1\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\2\0\1\55"+ + "\1\0\1\56\2\0\1\57\1\0\1\60\4\0\1\61"+ + "\1\0\1\62\1\0\1\63\2\0\1\64\3\0\1\65"+ + "\2\0\1\66\4\0\1\67\3\0\1\70\17\0\1\71"+ + "\2\0\1\72\21\0\1\73\2\0\1\74\61\0\2\30"+ + "\1\75\1\0\1\76\1\0\1\76\1\77\1\0\1\30"+ + "\2\0\1\201\1\0\1\41\1\30\1\202\3\u0141\1\u0155"+ + "\1\u0141\1\u0156\1\43\1\u0141\1\u0157\7\u0141\1\u0158\3\u0141"+ + "\1\43\2\u0141\1\43\2\u0141\1\203\12\204\1\76\1\154"+ + "\1\205\1\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\2\0\1\55\1\0\1\56\2\0\1\57"+ + "\1\0\1\60\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\65\2\0\1\66\4\0\1\67"+ + "\3\0\1\70\17\0\1\71\2\0\1\72\21\0\1\73"+ + "\2\0\1\74\61\0\2\30\1\75\1\0\1\76\1\0"+ + "\1\76\1\77\1\0\1\30\2\0\1\201\1\0\1\41"+ + "\1\30\1\202\1\u0159\1\u0141\1\43\1\u015a\6\u0141\3\43"+ + "\1\u0141\2\43\1\u0141\2\43\1\u0141\6\43\1\203\12\204"+ + "\1\76\1\154\1\205\1\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\2\0\1\55\1\0\1\56"+ + "\2\0\1\57\1\0\1\60\4\0\1\61\1\0\1\62"+ + "\1\0\1\63\2\0\1\64\3\0\1\65\2\0\1\66"+ + "\4\0\1\67\3\0\1\70\17\0\1\71\2\0\1\72"+ + "\21\0\1\73\2\0\1\74\61\0\2\30\1\75\1\0"+ + "\1\76\1\0\1\76\1\77\1\0\1\30\2\0\1\201"+ + "\1\0\1\41\1\30\1\202\1\u0141\31\43\1\203\12\204"+ + "\1\76\1\154\1\205\1\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\2\0\1\55\1\0\1\56"+ + "\2\0\1\57\1\0\1\60\4\0\1\61\1\0\1\62"+ + "\1\0\1\63\2\0\1\64\3\0\1\65\2\0\1\66"+ + "\4\0\1\67\3\0\1\70\17\0\1\71\2\0\1\72"+ + "\21\0\1\73\2\0\1\74\61\0\2\30\1\75\1\0"+ + "\1\76\1\0\1\76\1\77\1\0\1\30\2\0\1\201"+ + "\1\0\1\41\1\30\1\202\1\u0141\2\43\1\u0141\1\u015b"+ + "\1\u015c\2\u0141\1\43\1\u015d\2\u0141\2\43\2\u0141\1\43"+ + "\1\u0141\3\43\1\u015e\1\u0141\2\43\1\u0141\1\203\12\204"+ + "\1\76\1\154\1\205\1\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\2\0\1\55\1\0\1\56"+ + "\2\0\1\57\1\0\1\60\4\0\1\61\1\0\1\62"+ + "\1\0\1\63\2\0\1\64\3\0\1\65\2\0\1\66"+ + "\4\0\1\67\3\0\1\70\17\0\1\71\2\0\1\72"+ + "\21\0\1\73\2\0\1\74\61\0\2\30\1\75\1\0"+ + "\1\76\1\0\1\76\1\77\1\0\1\30\2\0\1\201"+ + "\1\0\1\41\1\30\1\202\3\u0141\1\u015f\2\u0141\1\43"+ + "\1\u0141\1\u0160\3\u0141\3\43\2\u0141\1\43\10\u0141\1\203"+ + "\12\204\1\76\1\154\1\205\1\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\2\0\1\55\1\0"+ + "\1\56\2\0\1\57\1\0\1\60\4\0\1\61\1\0"+ + "\1\62\1\0\1\63\2\0\1\64\3\0\1\65\2\0"+ + "\1\66\4\0\1\67\3\0\1\70\17\0\1\71\2\0"+ + "\1\72\21\0\1\73\2\0\1\74\61\0\2\30\1\75"+ + "\1\0\1\76\1\0\1\76\1\77\1\0\1\30\2\0"+ + "\1\201\1\0\1\41\1\30\1\202\1\u0161\2\u0141\1\u0162"+ + "\1\u0163\1\u0164\2\u0141\1\u0165\3\u0141\1\43\1\u0141\1\43"+ + "\1\u0141\1\43\1\u0141\1\43\1\u0141\1\43\4\u0141\1\43"+ + "\1\203\12\204\1\76\1\154\1\205\1\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\2\0\1\55"+ + "\1\0\1\56\2\0\1\57\1\0\1\60\4\0\1\61"+ + "\1\0\1\62\1\0\1\63\2\0\1\64\3\0\1\65"+ + "\2\0\1\66\4\0\1\67\3\0\1\70\17\0\1\71"+ + "\2\0\1\72\21\0\1\73\2\0\1\74\61\0\2\30"+ + "\1\75\1\0\1\76\1\0\1\76\1\77\1\0\1\30"+ + "\2\0\1\201\1\0\1\41\1\30\1\202\1\u0141\6\43"+ + "\1\u0141\3\43\1\u0166\2\43\1\u0141\4\43\1\u0141\2\43"+ + "\1\u0141\2\43\1\u0141\1\203\12\204\1\76\1\154\1\205"+ + "\1\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\2\0\1\55\1\0\1\56\2\0\1\57\1\0"+ + "\1\60\4\0\1\61\1\0\1\62\1\0\1\63\2\0"+ + "\1\64\3\0\1\65\2\0\1\66\4\0\1\67\3\0"+ + "\1\70\17\0\1\71\2\0\1\72\21\0\1\73\2\0"+ + "\1\74\61\0\2\30\1\75\1\0\1\76\1\0\1\76"+ + "\1\77\1\0\1\30\2\0\1\201\1\0\1\41\1\30"+ + "\1\202\6\43\1\u0141\7\43\1\u0141\13\43\1\203\12\204"+ + "\1\76\1\154\1\205\1\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\2\0\1\55\1\0\1\56"+ + "\2\0\1\57\1\0\1\60\4\0\1\61\1\0\1\62"+ + "\1\0\1\63\2\0\1\64\3\0\1\65\2\0\1\66"+ + "\4\0\1\67\3\0\1\70\17\0\1\71\2\0\1\72"+ + "\21\0\1\73\2\0\1\74\61\0\2\30\1\75\1\0"+ + "\1\76\1\0\1\76\1\77\1\0\1\30\2\0\1\201"+ + "\1\0\1\41\1\30\1\202\13\43\1\u0167\6\43\1\u0168"+ + "\7\43\1\203\12\204\1\76\1\154\1\205\1\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\2\0"+ + "\1\55\1\0\1\56\2\0\1\57\1\0\1\60\4\0"+ + "\1\61\1\0\1\62\1\0\1\63\2\0\1\64\3\0"+ + "\1\65\2\0\1\66\4\0\1\67\3\0\1\70\17\0"+ + "\1\71\2\0\1\72\21\0\1\73\2\0\1\74\61\0"+ + "\2\30\1\75\1\0\1\76\1\0\1\76\1\77\1\0"+ + "\1\30\2\0\1\201\1\0\1\41\1\30\1\202\1\u0141"+ + "\11\43\1\u0141\6\43\1\u0141\10\43\1\203\12\204\1\76"+ + "\1\154\1\205\1\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\2\0\1\55\1\0\1\56\2\0"+ + "\1\57\1\0\1\60\4\0\1\61\1\0\1\62\1\0"+ + "\1\63\2\0\1\64\3\0\1\65\2\0\1\66\4\0"+ + "\1\67\3\0\1\70\17\0\1\71\2\0\1\72\21\0"+ + "\1\73\2\0\1\74\61\0\2\30\1\75\1\0\1\76"+ + "\1\0\1\76\1\77\1\0\1\30\2\0\1\201\1\0"+ + "\1\41\1\30\1\202\1\u0141\1\43\6\u0141\1\u0169\1\43"+ + "\2\u0141\2\43\2\u0141\1\43\1\u0141\1\43\3\u0141\1\43"+ + "\3\u0141\1\203\12\204\1\76\1\154\1\205\1\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\2\0"+ + "\1\55\1\0\1\56\2\0\1\57\1\0\1\60\4\0"+ + "\1\61\1\0\1\62\1\0\1\63\2\0\1\64\3\0"+ + "\1\65\2\0\1\66\4\0\1\67\3\0\1\70\17\0"+ + "\1\71\2\0\1\72\21\0\1\73\2\0\1\74\61\0"+ + "\2\30\1\75\1\0\1\76\1\0\1\76\1\77\1\0"+ + "\1\30\2\0\1\201\1\0\1\41\1\30\1\202\4\43"+ + "\1\u0141\1\u016a\4\43\2\u0141\3\43\2\u0141\5\43\1\u0141"+ + "\3\43\1\203\12\204\1\76\1\154\1\205\1\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\2\0"+ + "\1\55\1\0\1\56\2\0\1\57\1\0\1\60\4\0"+ + "\1\61\1\0\1\62\1\0\1\63\2\0\1\64\3\0"+ + "\1\65\2\0\1\66\4\0\1\67\3\0\1\70\17\0"+ + "\1\71\2\0\1\72\21\0\1\73\2\0\1\74\61\0"+ + "\2\30\1\75\1\0\1\76\1\0\1\76\1\77\1\0"+ + "\1\30\2\0\1\201\1\0\1\41\1\30\1\202\3\43"+ + "\2\u0141\2\43\1\u0141\1\u016b\1\43\2\u0141\1\43\1\u0141"+ + "\3\43\1\u0141\1\43\1\u0141\1\43\1\u0141\3\43\1\u0141"+ + "\1\203\12\204\1\76\1\154\1\205\1\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\2\0\1\55"+ + "\1\0\1\56\2\0\1\57\1\0\1\60\4\0\1\61"+ + "\1\0\1\62\1\0\1\63\2\0\1\64\3\0\1\65"+ + "\2\0\1\66\4\0\1\67\3\0\1\70\17\0\1\71"+ + "\2\0\1\72\21\0\1\73\2\0\1\74\61\0\2\30"+ + "\1\75\1\0\1\76\1\0\1\76\1\77\1\0\1\30"+ + "\2\0\1\201\1\0\1\41\1\30\1\202\3\43\1\u0141"+ + "\1\43\1\u016c\4\43\1\u0141\2\43\1\u0141\14\43\1\203"+ + "\12\204\1\76\1\154\1\205\1\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\2\0\1\55\1\0"+ + "\1\56\2\0\1\57\1\0\1\60\4\0\1\61\1\0"+ + "\1\62\1\0\1\63\2\0\1\64\3\0\1\65\2\0"+ + "\1\66\4\0\1\67\3\0\1\70\17\0\1\71\2\0"+ + "\1\72\21\0\1\73\2\0\1\74\61\0\2\30\1\75"+ + "\1\0\1\76\1\0\1\76\1\77\1\0\1\30\2\0"+ + "\1\201\1\0\1\41\1\30\1\202\2\u0141\1\43\1\u016d"+ + "\1\43\1\u016e\1\43\2\u0141\2\43\1\u0141\4\43\1\u0141"+ + "\11\43\1\203\12\204\1\76\1\154\1\205\1\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\2\0"+ + "\1\55\1\0\1\56\2\0\1\57\1\0\1\60\4\0"+ + "\1\61\1\0\1\62\1\0\1\63\2\0\1\64\3\0"+ + "\1\65\2\0\1\66\4\0\1\67\3\0\1\70\17\0"+ + "\1\71\2\0\1\72\21\0\1\73\2\0\1\74\61\0"+ + "\2\30\1\75\1\0\1\76\1\0\1\76\1\77\1\0"+ + "\1\30\2\0\1\201\1\0\1\41\1\30\1\202\3\43"+ + "\1\u0141\13\43\1\u0141\12\43\1\203\12\204\1\76\1\154"+ + "\1\205\1\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\32\371\1\203"+ + "\12\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\7\0\1\u0126\1\0\1\u0127\17\0"+ + "\1\u0128\2\0\1\u0129\4\0\1\u012a\3\0\1\u012b\22\0"+ + "\1\u012c\21\0\1\u012d\2\0\1\u012e\62\0\1\243\1\75"+ + "\2\0\3\243\1\0\1\243\2\0\1\372\3\0\1\u0102"+ + "\33\154\12\375\1\0\1\154\1\372\1\154\1\0\1\372"+ + "\1\156\3\154\2\0\1\243\1\154\3\0\2\154\7\0"+ + "\1\u0126\1\0\1\u0127\17\0\1\u0128\2\0\1\u0129\4\0"+ + "\1\u012a\3\0\1\u012b\22\0\1\u012c\21\0\1\u012d\2\0"+ + "\1\u012e\62\0\1\243\1\75\2\0\3\243\1\0\1\243"+ + "\2\0\1\372\1\157\2\0\1\u0102\1\u0103\1\u0104\1\u0105"+ + "\1\u0106\1\u0107\1\u0108\1\u0109\1\u010a\1\u010b\1\u010c\1\u010d"+ + "\1\u010e\1\u010f\1\u0110\1\u0111\1\u0112\1\u0113\1\u0114\1\u0115"+ + "\1\u0116\1\u0117\1\u0118\1\u0119\1\u011a\1\u011b\1\u011c\1\154"+ + "\12\204\1\0\1\154\1\372\1\154\1\0\1\372\1\156"+ + "\3\154\2\0\1\243\1\154\3\0\2\154\2\0\1\55"+ + "\1\0\1\56\2\0\1\u012f\1\0\1\60\4\0\1\61"+ + "\1\0\1\62\1\0\1\63\2\0\1\64\3\0\1\u0130"+ + "\2\0\1\u0131\4\0\1\67\3\0\1\u0132\17\0\1\71"+ + "\2\0\1\u0133\21\0\1\u0134\2\0\1\u0135\41\0\1\133"+ + "\17\0\1\30\1\244\1\75\1\135\1\0\2\243\1\244"+ + "\1\0\1\244\2\0\1\372\1\0\1\41\1\30\1\u0102"+ + "\32\217\1\154\12\375\1\0\1\154\1\374\1\154\1\0"+ + "\1\372\1\156\3\154\2\0\1\243\1\154\3\0\2\154"+ + "\2\0\1\55\1\0\1\56\2\0\1\234\1\0\1\60"+ + "\4\0\1\61\1\0\1\62\1\0\1\63\2\0\1\64"+ + "\3\0\1\235\2\0\1\236\4\0\1\67\3\0\1\237"+ + "\17\0\1\71\2\0\1\240\21\0\1\241\2\0\1\242"+ + "\61\0\1\30\2\75\2\0\2\243\1\244\1\0\1\75"+ + "\2\0\1\372\1\0\1\41\1\30\1\u0102\32\217\1\154"+ + "\12\375\1\0\1\154\1\374\1\154\1\0\1\372\1\156"+ + "\3\154\2\0\1\243\1\154\3\0\2\154\2\0\1\55"+ + "\1\0\1\56\2\0\1\57\1\0\1\60\4\0\1\61"+ + "\1\0\1\62\1\0\1\63\2\0\1\64\3\0\1\65"+ + "\2\0\1\66\4\0\1\67\3\0\1\70\17\0\1\71"+ + "\2\0\1\72\21\0\1\73\2\0\1\74\61\0\2\30"+ + "\1\75\1\0\1\76\1\0\1\76\1\77\1\0\1\30"+ + "\2\0\1\201\1\0\1\41\1\30\1\202\3\43\1\u0170"+ + "\26\43\1\203\12\204\1\76\1\154\1\205\1\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\2\0"+ + "\1\55\1\0\1\56\2\0\1\57\1\0\1\60\4\0"+ + "\1\61\1\0\1\62\1\0\1\63\2\0\1\64\3\0"+ + "\1\65\2\0\1\66\4\0\1\67\3\0\1\70\17\0"+ + "\1\71\2\0\1\72\21\0\1\73\2\0\1\74\61\0"+ + "\2\30\1\75\1\0\1\76\1\0\1\76\1\77\1\0"+ + "\1\30\2\0\1\201\1\0\1\41\1\30\1\202\32\43"+ + "\1\203\12\204\1\u0171\1\154\1\205\1\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\2\0\1\55"+ + "\1\0\1\56\2\0\1\57\1\0\1\60\4\0\1\61"+ + "\1\0\1\62\1\0\1\63\2\0\1\64\3\0\1\65"+ + "\2\0\1\66\4\0\1\67\3\0\1\70\17\0\1\71"+ + "\2\0\1\72\21\0\1\73\2\0\1\74\61\0\2\30"+ + "\1\75\1\0\1\76\1\0\1\76\1\77\1\0\1\30"+ + "\2\0\1\201\1\0\1\41\1\30\1\202\11\43\1\u0172"+ + "\20\43\1\203\12\204\1\76\1\154\1\205\1\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\2\0"+ + "\1\55\1\0\1\56\2\0\1\57\1\0\1\60\4\0"+ + "\1\61\1\0\1\62\1\0\1\63\2\0\1\64\3\0"+ + "\1\65\2\0\1\66\4\0\1\67\3\0\1\70\17\0"+ + "\1\71\2\0\1\72\21\0\1\73\2\0\1\74\61\0"+ + "\2\30\1\75\1\0\1\76\1\0\1\76\1\77\1\0"+ + "\1\30\2\0\1\201\1\0\1\41\1\30\1\202\15\43"+ + "\1\u0173\14\43\1\203\12\204\1\76\1\154\1\205\1\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\7\0\1\u0126\1\0\1\u0127\17\0\1\u0128\2\0\1\u0129"+ + "\4\0\1\u012a\3\0\1\u012b\22\0\1\u012c\21\0\1\u012d"+ + "\2\0\1\u012e\62\0\1\243\1\75\2\0\3\243\1\0"+ + "\1\243\2\0\1\372\1\157\2\0\1\u0102\33\154\12\375"+ + "\1\0\1\154\1\372\1\154\1\0\1\372\1\156\3\154"+ + "\2\0\1\243\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\1\371\2\u0174\1\u0175\1\u0176\10\u0174\1\371\1\u0177"+ + "\5\u0174\6\371\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\1\u0178\2\u0174\1\371\1\u0174\1\u0179\3\u0174"+ + "\1\u017a\2\u0174\4\371\4\u0174\1\371\2\u0174\1\371\2\u0174"+ + "\1\203\12\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\3\371\1\u0174\1\371\1\u0174\2\371\1\u017b\1\371\1\u0174"+ + "\10\371\1\u0174\2\371\2\u0174\2\371\1\203\12\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\1\371\1\u0174\1\u017c"+ + "\2\u0174\2\371\1\u0174\3\371\1\u017d\1\u017e\1\371\1\u017f"+ + "\2\u0174\11\371\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\3\371\1\u0174\1\371\1\u0174\10\371\1\u0174"+ + "\1\371\2\u0174\10\371\1\203\12\371\1\0\3\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\213\0"+ + "\1\154\3\0\1\u016f\4\371\1\u0180\5\371\1\u0174\17\371"+ + "\1\203\12\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\4\371\2\u0174\2\371\1\u0174\1\371\1\u0174\13\371\2\u0174"+ + "\2\371\1\203\12\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\1\u0181\1\371\2\u0174\1\u0182\1\u0183\12\u0174\1\u0184"+ + "\1\u0174\2\371\2\u0174\3\371\1\u0174\1\203\12\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\2\371\4\u0174\3\371"+ + "\2\u0174\1\u0185\1\u0174\1\371\2\u0174\12\371\1\203\12\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\1\u0186\1\u0174"+ + "\2\371\1\u0174\3\371\1\u0187\5\371\3\u0174\3\371\1\u0174"+ + "\1\371\1\u0174\1\371\2\u0174\1\203\12\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\3\u0174\1\u0188\1\u0174\1\u0189"+ + "\1\371\1\u0174\1\u018a\7\u0174\1\u018b\3\u0174\1\371\2\u0174"+ + "\1\371\2\u0174\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\1\u018c\1\u0174\1\371\1\u018d\6\u0174\3\371"+ + "\1\u0174\2\371\1\u0174\2\371\1\u0174\6\371\1\203\12\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\1\u0174\31\371"+ + "\1\203\12\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\1\u0174\2\371\1\u0174\1\u018e\1\u018f\2\u0174\1\371\1\u0190"+ + "\2\u0174\2\371\2\u0174\1\371\1\u0174\3\371\1\u0191\1\u0174"+ + "\2\371\1\u0174\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\3\u0174\1\u0192\2\u0174\1\371\1\u0174\1\u0193"+ + "\3\u0174\3\371\2\u0174\1\371\10\u0174\1\203\12\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\1\u0194\2\u0174\1\u0195"+ + "\1\u0196\1\u0197\2\u0174\1\u0198\3\u0174\1\371\1\u0174\1\371"+ + "\1\u0174\1\371\1\u0174\1\371\1\u0174\1\371\4\u0174\1\371"+ + "\1\203\12\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\1\u0174\6\371\1\u0174\3\371\1\u0199\2\371\1\u0174\4\371"+ + "\1\u0174\2\371\1\u0174\2\371\1\u0174\1\203\12\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\6\371\1\u0174\7\371"+ + "\1\u0174\13\371\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\13\371\1\u019a\6\371\1\u019b\7\371\1\203"+ + "\12\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\1\u0174"+ + "\11\371\1\u0174\6\371\1\u0174\10\371\1\203\12\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\1\u0174\1\371\6\u0174"+ + "\1\u019c\1\371\2\u0174\2\371\2\u0174\1\371\1\u0174\1\371"+ + "\3\u0174\1\371\3\u0174\1\203\12\371\1\0\3\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\213\0"+ + "\1\154\3\0\1\u016f\4\371\1\u0174\1\u019d\4\371\2\u0174"+ + "\3\371\2\u0174\5\371\1\u0174\3\371\1\203\12\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\3\371\2\u0174\2\371"+ + "\1\u0174\1\u019e\1\371\2\u0174\1\371\1\u0174\3\371\1\u0174"+ + "\1\371\1\u0174\1\371\1\u0174\3\371\1\u0174\1\203\12\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\3\371\1\u0174"+ + "\1\371\1\u019f\4\371\1\u0174\2\371\1\u0174\14\371\1\203"+ + "\12\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\2\u0174"+ + "\1\371\1\u01a0\1\371\1\u01a1\1\371\2\u0174\2\371\1\u0174"+ + "\4\371\1\u0174\11\371\1\203\12\371\1\0\3\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\213\0"+ + "\1\154\3\0\1\u016f\3\371\1\u0174\13\371\1\u0174\12\371"+ + "\1\203\12\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\2\0\1\55\1\0\1\56"+ + "\2\0\1\100\1\0\1\101\4\0\1\61\1\0\1\62"+ + "\1\0\1\63\2\0\1\64\3\0\1\102\2\0\1\103"+ + "\4\0\1\104\3\0\1\105\17\0\1\71\2\0\1\106"+ + "\21\0\1\107\2\0\1\110\61\0\1\30\2\31\2\0"+ + "\2\111\1\112\1\0\1\31\2\0\1\212\1\0\1\41"+ + "\1\30\1\u01a2\32\43\1\203\12\u01a3\1\0\1\154\1\215"+ + "\1\154\1\0\1\212\1\156\3\154\2\0\1\111\1\154"+ + "\3\0\2\154\2\0\1\55\1\0\1\56\2\0\1\100"+ + "\1\0\1\101\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\102\2\0\1\103\4\0\1\104"+ + "\3\0\1\105\17\0\1\71\2\0\1\106\21\0\1\107"+ + "\2\0\1\110\61\0\1\30\2\31\2\0\2\111\1\112"+ + "\1\0\1\31\2\0\1\212\1\0\1\41\1\30\1\u01a2"+ + "\32\43\1\203\12\u011d\1\0\1\154\1\215\1\154\1\0"+ + "\1\212\1\156\3\154\2\0\1\111\1\154\3\0\2\154"+ + "\2\0\1\55\1\0\1\56\2\0\1\100\1\0\1\101"+ + "\4\0\1\61\1\0\1\62\1\0\1\63\2\0\1\64"+ + "\3\0\1\102\2\0\1\103\4\0\1\104\3\0\1\105"+ + "\17\0\1\71\2\0\1\106\21\0\1\107\2\0\1\110"+ + "\61\0\1\30\2\31\2\0\2\111\1\112\1\0\1\31"+ + "\2\0\1\212\1\0\1\41\1\30\1\u01a2\32\43\1\203"+ + "\2\u011d\1\u01a3\1\u011d\1\u01a4\2\u01a3\2\u011d\1\u01a3\1\0"+ + "\1\154\1\215\1\154\1\0\1\212\1\156\3\154\2\0"+ + "\1\111\1\154\3\0\2\154\2\0\1\55\1\0\1\56"+ + "\2\0\1\100\1\0\1\101\4\0\1\61\1\0\1\62"+ + "\1\0\1\63\2\0\1\64\3\0\1\102\2\0\1\103"+ + "\4\0\1\104\3\0\1\105\17\0\1\71\2\0\1\106"+ + "\21\0\1\107\2\0\1\110\61\0\1\30\2\31\2\0"+ + "\2\111\1\112\1\0\1\31\2\0\1\212\1\0\1\41"+ + "\1\30\1\u01a5\32\43\1\203\12\u0120\1\0\1\154\1\215"+ + "\1\154\1\0\1\212\1\156\3\154\2\0\1\111\1\154"+ + "\3\0\2\154\7\0\1\265\1\0\1\266\17\0\1\267"+ + "\2\0\1\270\4\0\1\271\3\0\1\272\22\0\1\273"+ + "\21\0\1\274\2\0\1\275\62\0\1\111\1\31\2\0"+ + "\3\243\1\0\1\111\2\0\1\372\1\157\2\0\1\u0102"+ + "\33\154\12\220\1\0\1\154\1\372\1\154\1\0\1\372"+ + "\1\156\3\154\2\0\1\243\1\154\3\0\2\154\220\0"+ + "\4\u01a6\2\0\1\u01a6\15\0\1\u01a6\6\0\12\u01a6\1\u0123"+ + "\242\0\4\u01a7\2\0\1\u01a7\15\0\1\u01a7\6\0\12\u01a7"+ + "\1\u01a8\242\0\4\u01a9\2\0\1\u01a9\15\0\1\u01a9\6\0"+ + "\1\u01aa\1\u01ab\5\u01aa\1\u01ac\1\u01ab\1\u01aa\13\0\1\u01ad"+ + "\16\0\1\u01ae\21\0\1\u01af\2\0\1\u01b0\10\0\1\u01b1"+ + "\22\0\1\u01b2\21\0\1\u01b3\2\0\1\u01b4\55\0\1\233"+ + "\4\0\1\u0125\7\0\1\u0125\171\0\1\243\2\0\1\243"+ + "\33\0\4\243\174\0\1\75\104\0\1\75\240\0\1\75"+ + "\41\0\1\75\13\0\1\243\157\0\1\75\11\0\1\243"+ + "\44\0\1\243\1\0\2\243\21\0\1\243\4\0\1\243"+ + "\3\0\4\75\10\0\4\243\3\0\1\243\12\0\1\243"+ + "\256\0\2\75\325\0\1\243\314\0\4\243\244\0\2\243"+ + "\25\0\4\243\147\0\1\243\15\0\2\243\10\0\2\243"+ + "\1\0\1\243\1\0\1\243\11\0\1\243\11\0\2\243"+ + "\6\0\1\243\2\0\4\243\3\0\1\243\2\0\2\243"+ + "\1\0\3\243\1\0\2\243\1\0\1\243\10\0\1\243"+ + "\1\0\2\243\2\0\2\243\1\0\4\243\23\0\1\243"+ + "\121\0\1\30\4\0\1\30\11\0\1\30\22\0\1\30"+ + "\3\0\1\30\13\0\1\244\2\0\1\244\10\0\1\30"+ + "\22\0\4\244\35\0\1\30\120\0\1\30\26\0\2\30"+ + "\23\0\1\75\1\30\40\0\1\75\13\0\1\244\157\0"+ + "\1\75\11\0\1\244\15\0\4\30\2\0\2\30\14\0"+ + "\3\30\1\244\1\0\2\244\11\0\3\30\3\0\1\30"+ + "\1\0\1\244\4\0\1\244\2\30\1\0\4\75\1\0"+ + "\2\30\5\0\4\244\2\0\1\30\1\244\12\0\1\244"+ + "\7\0\1\30\122\0\1\30\4\0\1\30\6\0\1\30"+ + "\3\0\1\30\6\0\1\30\5\0\1\30\2\0\2\30"+ + "\1\0\17\30\2\0\1\30\13\0\7\30\2\0\1\30"+ + "\1\0\1\30\1\0\2\30\2\0\1\30\1\0\3\30"+ + "\2\0\1\30\1\0\1\30\1\0\1\30\1\0\1\30"+ + "\4\0\1\244\1\0\2\30\6\0\1\30\7\0\1\30"+ + "\1\0\1\30\125\0\1\30\6\0\1\30\3\0\1\30"+ + "\3\0\1\30\7\0\1\30\31\0\20\30\5\0\3\30"+ + "\4\0\1\30\6\0\1\30\3\0\2\30\2\0\2\30"+ + "\4\0\1\30\4\244\1\0\1\30\2\0\1\30\4\0"+ + "\1\30\1\0\1\30\1\0\1\30\226\0\2\244\25\0"+ + "\4\244\147\0\1\244\15\0\2\244\10\0\2\244\1\0"+ + "\1\244\1\0\1\244\11\0\1\244\11\0\2\244\6\0"+ + "\1\244\2\0\4\244\3\0\1\244\2\0\2\244\1\0"+ + "\3\244\1\0\2\244\1\0\1\244\10\0\1\244\1\0"+ + "\2\244\2\0\2\244\1\0\4\244\23\0\1\244\331\0"+ + "\1\u01b5\1\u01b6\1\u01b7\1\u01b8\1\u01b9\1\u01ba\1\u01bb\1\u01bc"+ + "\1\u01bd\1\u01be\1\u01bf\1\u01c0\1\u01c1\1\u01c2\1\u01c3\1\u01c4"+ + "\1\u01c5\1\u01c6\1\u01c7\1\u01c8\1\u01c9\1\u01ca\1\u01cb\1\u01cc"+ + "\1\u01cd\1\u01ce\1\0\12\323\243\0\32\323\1\u0137\12\323"+ + "\236\0\2\324\2\0\72\324\7\0\1\30\4\0\1\30"+ + "\11\0\1\30\22\0\1\30\3\0\1\30\13\0\1\335"+ + "\2\0\1\335\10\0\1\30\22\0\4\335\35\0\1\30"+ + "\120\0\1\30\26\0\2\30\23\0\1\75\1\30\40\0"+ + "\1\75\13\0\1\335\157\0\1\75\11\0\1\335\15\0"+ + "\4\30\2\0\2\30\14\0\3\30\1\335\1\0\2\335"+ + "\11\0\3\30\3\0\1\30\1\0\1\335\4\0\1\335"+ + "\2\30\1\0\4\75\1\0\2\30\5\0\4\335\2\0"+ + "\1\30\1\335\12\0\1\335\7\0\1\30\122\0\1\30"+ + "\4\0\1\30\6\0\1\30\3\0\1\30\6\0\1\30"+ + "\5\0\1\30\2\0\2\30\1\0\17\30\2\0\1\30"+ + "\13\0\7\30\2\0\1\30\1\0\1\30\1\0\2\30"+ + "\2\0\1\30\1\0\3\30\2\0\1\30\1\0\1\30"+ + "\1\0\1\30\1\0\1\30\4\0\1\335\1\0\2\30"+ + "\6\0\1\30\7\0\1\30\1\0\1\30\125\0\1\30"+ + "\6\0\1\30\3\0\1\30\3\0\1\30\7\0\1\30"+ + "\31\0\20\30\5\0\3\30\4\0\1\30\6\0\1\30"+ + "\3\0\2\30\2\0\2\30\4\0\1\30\4\335\1\0"+ + "\1\30\2\0\1\30\4\0\1\30\1\0\1\30\1\0"+ + "\1\30\226\0\2\335\25\0\4\335\147\0\1\335\15\0"+ + "\2\335\10\0\2\335\1\0\1\335\1\0\1\335\11\0"+ + "\1\335\11\0\2\335\6\0\1\335\2\0\4\335\3\0"+ + "\1\335\2\0\2\335\1\0\3\335\1\0\2\335\1\0"+ + "\1\335\10\0\1\335\1\0\2\335\2\0\2\335\1\0"+ + "\4\335\23\0\1\335\113\0\1\55\1\0\1\56\2\0"+ + "\1\57\1\0\1\60\4\0\1\61\1\0\1\62\1\0"+ + "\1\63\2\0\1\64\3\0\1\65\2\0\1\66\4\0"+ + "\1\67\3\0\1\70\17\0\1\71\2\0\1\72\21\0"+ + "\1\73\2\0\1\74\61\0\2\30\1\75\1\0\1\76"+ + "\1\0\1\76\1\77\1\0\1\30\2\0\1\201\1\0"+ + "\1\41\1\30\1\u01cf\32\43\1\203\12\204\1\u01d0\1\154"+ + "\1\205\1\154\1\0\1\154\1\156\1\u01d1\1\u01d2\1\u01d3"+ + "\3\0\1\154\3\0\2\154\2\0\1\55\1\0\1\56"+ + "\2\0\1\57\1\0\1\60\4\0\1\61\1\0\1\62"+ + "\1\0\1\63\2\0\1\64\3\0\1\65\2\0\1\66"+ + "\4\0\1\67\3\0\1\70\17\0\1\71\2\0\1\72"+ + "\21\0\1\73\2\0\1\74\61\0\2\30\1\75\1\0"+ + "\1\76\1\0\1\76\1\77\1\0\1\30\2\0\1\201"+ + "\1\0\1\41\1\30\1\u01cf\4\43\1\u0166\25\43\1\203"+ + "\12\204\1\u01d0\1\154\1\205\1\154\1\0\1\154\1\156"+ + "\1\u01d1\1\u01d2\1\u01d3\3\0\1\154\3\0\2\154\2\0"+ + "\1\55\1\0\1\56\2\0\1\57\1\0\1\60\4\0"+ + "\1\61\1\0\1\62\1\0\1\63\2\0\1\64\3\0"+ + "\1\65\2\0\1\66\4\0\1\67\3\0\1\70\17\0"+ + "\1\71\2\0\1\72\21\0\1\73\2\0\1\74\61\0"+ + "\2\30\1\75\1\0\1\76\1\0\1\76\1\77\1\0"+ + "\1\30\2\0\1\201\1\0\1\41\1\30\1\u01cf\15\43"+ + "\1\353\14\43\1\203\12\204\1\u01d0\1\154\1\205\1\154"+ + "\1\0\1\154\1\156\1\u01d1\1\u01d2\1\u01d3\3\0\1\154"+ + "\3\0\2\154\2\0\1\55\1\0\1\56\2\0\1\57"+ + "\1\0\1\60\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\65\2\0\1\66\4\0\1\67"+ + "\3\0\1\70\17\0\1\71\2\0\1\72\21\0\1\73"+ + "\2\0\1\74\61\0\2\30\1\75\1\0\1\76\1\0"+ + "\1\76\1\77\1\0\1\30\2\0\1\201\1\0\1\41"+ + "\1\30\1\u01cf\10\43\1\353\21\43\1\203\12\204\1\u01d0"+ + "\1\154\1\205\1\154\1\0\1\154\1\156\1\u01d1\1\u01d2"+ + "\1\u01d3\3\0\1\154\3\0\2\154\2\0\1\55\1\0"+ + "\1\56\2\0\1\57\1\0\1\60\4\0\1\61\1\0"+ + "\1\62\1\0\1\63\2\0\1\64\3\0\1\65\2\0"+ + "\1\66\4\0\1\67\3\0\1\70\17\0\1\71\2\0"+ + "\1\72\21\0\1\73\2\0\1\74\61\0\2\30\1\75"+ + "\1\0\1\76\1\0\1\76\1\77\1\0\1\30\2\0"+ + "\1\201\1\0\1\41\1\30\1\u01cf\12\43\1\u01d4\4\43"+ + "\1\u0141\12\43\1\203\12\204\1\u01d0\1\154\1\205\1\154"+ + "\1\0\1\154\1\156\1\u01d1\1\u01d2\1\u01d3\3\0\1\154"+ + "\3\0\2\154\2\0\1\55\1\0\1\56\2\0\1\57"+ + "\1\0\1\60\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\65\2\0\1\66\4\0\1\67"+ + "\3\0\1\70\17\0\1\71\2\0\1\72\21\0\1\73"+ + "\2\0\1\74\61\0\2\30\1\75\1\0\1\76\1\0"+ + "\1\76\1\77\1\0\1\30\2\0\1\201\1\0\1\41"+ + "\1\30\1\u01cf\5\43\1\u01d5\4\43\1\u0141\1\u01d6\16\43"+ + "\1\203\12\204\1\u01d0\1\154\1\205\1\154\1\0\1\154"+ + "\1\156\1\u01d1\1\u01d2\1\u01d3\3\0\1\154\3\0\2\154"+ + "\2\0\1\55\1\0\1\56\2\0\1\57\1\0\1\60"+ + "\4\0\1\61\1\0\1\62\1\0\1\63\2\0\1\64"+ + "\3\0\1\65\2\0\1\66\4\0\1\67\3\0\1\70"+ + "\17\0\1\71\2\0\1\72\21\0\1\73\2\0\1\74"+ + "\61\0\2\30\1\75\1\0\1\76\1\0\1\76\1\77"+ + "\1\0\1\30\2\0\1\201\1\0\1\41\1\30\1\u01cf"+ + "\5\43\1\u01d7\24\43\1\203\12\204\1\u01d0\1\154\1\205"+ + "\1\154\1\0\1\154\1\156\1\u01d1\1\u01d2\1\u01d3\3\0"+ + "\1\154\3\0\2\154\2\0\1\55\1\0\1\56\2\0"+ + "\1\57\1\0\1\60\4\0\1\61\1\0\1\62\1\0"+ + "\1\63\2\0\1\64\3\0\1\65\2\0\1\66\4\0"+ + "\1\67\3\0\1\70\17\0\1\71\2\0\1\72\21\0"+ + "\1\73\2\0\1\74\61\0\2\30\1\75\1\0\1\76"+ + "\1\0\1\76\1\77\1\0\1\30\2\0\1\201\1\0"+ + "\1\41\1\30\1\202\1\u01d8\3\43\1\u01d9\25\43\1\203"+ + "\12\204\1\76\1\154\1\205\1\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\2\0\1\55\1\0"+ + "\1\56\2\0\1\57\1\0\1\60\4\0\1\61\1\0"+ + "\1\62\1\0\1\63\2\0\1\64\3\0\1\65\2\0"+ + "\1\66\4\0\1\67\3\0\1\70\17\0\1\71\2\0"+ + "\1\72\21\0\1\73\2\0\1\74\61\0\2\30\1\75"+ + "\1\0\1\76\1\0\1\76\1\77\1\0\1\30\2\0"+ + "\1\201\1\0\1\41\1\30\1\202\20\43\1\u0141\11\43"+ + "\1\203\12\204\1\76\1\154\1\205\1\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\2\0\1\55"+ + "\1\0\1\56\2\0\1\57\1\0\1\60\4\0\1\61"+ + "\1\0\1\62\1\0\1\63\2\0\1\64\3\0\1\65"+ + "\2\0\1\66\4\0\1\67\3\0\1\70\17\0\1\71"+ + "\2\0\1\72\21\0\1\73\2\0\1\74\61\0\2\30"+ + "\1\75\1\0\1\76\1\0\1\76\1\77\1\0\1\30"+ + "\2\0\1\201\1\0\1\41\1\30\1\202\17\43\1\u01da"+ + "\12\43\1\203\12\204\1\76\1\154\1\205\1\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\2\0"+ + "\1\55\1\0\1\56\2\0\1\57\1\0\1\60\4\0"+ + "\1\61\1\0\1\62\1\0\1\63\2\0\1\64\3\0"+ + "\1\65\2\0\1\66\4\0\1\67\3\0\1\70\17\0"+ + "\1\71\2\0\1\72\21\0\1\73\2\0\1\74\61\0"+ + "\2\30\1\75\1\0\1\76\1\0\1\76\1\77\1\0"+ + "\1\30\2\0\1\201\1\0\1\41\1\30\1\202\20\43"+ + "\1\u01db\11\43\1\203\12\204\1\76\1\154\1\205\1\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\2\0\1\55\1\0\1\56\2\0\1\57\1\0\1\60"+ + "\4\0\1\61\1\0\1\62\1\0\1\63\2\0\1\64"+ + "\3\0\1\65\2\0\1\66\4\0\1\67\3\0\1\70"+ + "\17\0\1\71\2\0\1\72\21\0\1\73\2\0\1\74"+ + "\61\0\2\30\1\75\1\0\1\76\1\0\1\76\1\77"+ + "\1\0\1\30\2\0\1\201\1\0\1\41\1\30\1\u01cf"+ + "\17\43\1\u01dc\12\43\1\203\12\204\1\u01d0\1\154\1\205"+ + "\1\154\1\0\1\154\1\156\1\u01d1\1\u01d2\1\u01d3\3\0"+ + "\1\154\3\0\2\154\2\0\1\55\1\0\1\56\2\0"+ + "\1\57\1\0\1\60\4\0\1\61\1\0\1\62\1\0"+ + "\1\63\2\0\1\64\3\0\1\65\2\0\1\66\4\0"+ + "\1\67\3\0\1\70\17\0\1\71\2\0\1\72\21\0"+ + "\1\73\2\0\1\74\61\0\2\30\1\75\1\0\1\76"+ + "\1\0\1\76\1\77\1\0\1\30\2\0\1\201\1\0"+ + "\1\41\1\30\1\202\7\43\1\u0141\22\43\1\203\12\204"+ + "\1\76\1\154\1\205\1\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\2\0\1\55\1\0\1\56"+ + "\2\0\1\57\1\0\1\60\4\0\1\61\1\0\1\62"+ + "\1\0\1\63\2\0\1\64\3\0\1\65\2\0\1\66"+ + "\4\0\1\67\3\0\1\70\17\0\1\71\2\0\1\72"+ + "\21\0\1\73\2\0\1\74\61\0\2\30\1\75\1\0"+ + "\1\76\1\0\1\76\1\77\1\0\1\30\2\0\1\201"+ + "\1\0\1\41\1\30\1\u01cf\11\43\1\u01dd\20\43\1\203"+ + "\12\204\1\u01d0\1\154\1\205\1\154\1\0\1\154\1\156"+ + "\1\u01d1\1\u01d2\1\u01d3\3\0\1\154\3\0\2\154\2\0"+ + "\1\55\1\0\1\56\2\0\1\57\1\0\1\60\4\0"+ + "\1\61\1\0\1\62\1\0\1\63\2\0\1\64\3\0"+ + "\1\65\2\0\1\66\4\0\1\67\3\0\1\70\17\0"+ + "\1\71\2\0\1\72\21\0\1\73\2\0\1\74\61\0"+ + "\2\30\1\75\1\0\1\76\1\0\1\76\1\77\1\0"+ + "\1\30\2\0\1\201\1\0\1\41\1\30\1\u01cf\1\u01de"+ + "\31\43\1\203\12\204\1\u01d0\1\154\1\205\1\154\1\0"+ + "\1\154\1\156\1\u01d1\1\u01d2\1\u01d3\3\0\1\154\3\0"+ + "\2\154\2\0\1\55\1\0\1\56\2\0\1\57\1\0"+ + "\1\60\4\0\1\61\1\0\1\62\1\0\1\63\2\0"+ + "\1\64\3\0\1\65\2\0\1\66\4\0\1\67\3\0"+ + "\1\70\17\0\1\71\2\0\1\72\21\0\1\73\2\0"+ + "\1\74\61\0\2\30\1\75\1\0\1\76\1\0\1\76"+ + "\1\77\1\0\1\30\2\0\1\201\1\0\1\41\1\30"+ + "\1\202\30\43\1\u0141\1\43\1\203\12\204\1\76\1\154"+ + "\1\205\1\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\2\0\1\55\1\0\1\56\2\0\1\57"+ + "\1\0\1\60\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\65\2\0\1\66\4\0\1\67"+ + "\3\0\1\70\17\0\1\71\2\0\1\72\21\0\1\73"+ + "\2\0\1\74\61\0\2\30\1\75\1\0\1\76\1\0"+ + "\1\76\1\77\1\0\1\30\2\0\1\201\1\0\1\41"+ + "\1\30\1\u01cf\4\43\1\u0149\25\43\1\203\12\204\1\u01d0"+ + "\1\154\1\205\1\154\1\0\1\154\1\156\1\u01d1\1\u01d2"+ + "\1\u01d3\3\0\1\154\3\0\2\154\2\0\1\55\1\0"+ + "\1\56\2\0\1\57\1\0\1\60\4\0\1\61\1\0"+ + "\1\62\1\0\1\63\2\0\1\64\3\0\1\65\2\0"+ + "\1\66\4\0\1\67\3\0\1\70\17\0\1\71\2\0"+ + "\1\72\21\0\1\73\2\0\1\74\61\0\2\30\1\75"+ + "\1\0\1\76\1\0\1\76\1\77\1\0\1\30\2\0"+ + "\1\201\1\0\1\41\1\30\1\u01cf\6\43\1\u0166\10\43"+ + "\1\u0141\12\43\1\203\12\204\1\u01d0\1\154\1\205\1\154"+ + "\1\0\1\154\1\156\1\u01d1\1\u01d2\1\u01d3\3\0\1\154"+ + "\3\0\2\154\2\0\1\55\1\0\1\56\2\0\1\57"+ + "\1\0\1\60\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\65\2\0\1\66\4\0\1\67"+ + "\3\0\1\70\17\0\1\71\2\0\1\72\21\0\1\73"+ + "\2\0\1\74\61\0\2\30\1\75\1\0\1\76\1\0"+ + "\1\76\1\77\1\0\1\30\2\0\1\201\1\0\1\41"+ + "\1\30\1\u01cf\13\43\1\u01df\16\43\1\203\12\204\1\u01d0"+ + "\1\154\1\205\1\154\1\0\1\154\1\156\1\u01d1\1\u01d2"+ + "\1\u01d3\3\0\1\154\3\0\2\154\2\0\1\55\1\0"+ + "\1\56\2\0\1\57\1\0\1\60\4\0\1\61\1\0"+ + "\1\62\1\0\1\63\2\0\1\64\3\0\1\65\2\0"+ + "\1\66\4\0\1\67\3\0\1\70\17\0\1\71\2\0"+ + "\1\72\21\0\1\73\2\0\1\74\61\0\2\30\1\75"+ + "\1\0\1\76\1\0\1\76\1\77\1\0\1\30\2\0"+ + "\1\201\1\0\1\41\1\30\1\u01cf\7\43\1\u01e0\22\43"+ + "\1\203\12\204\1\u01d0\1\154\1\205\1\154\1\0\1\154"+ + "\1\156\1\u01d1\1\u01d2\1\u01d3\3\0\1\154\3\0\2\154"+ + "\2\0\1\55\1\0\1\56\2\0\1\57\1\0\1\60"+ + "\4\0\1\61\1\0\1\62\1\0\1\63\2\0\1\64"+ + "\3\0\1\65\2\0\1\66\4\0\1\67\3\0\1\70"+ + "\17\0\1\71\2\0\1\72\21\0\1\73\2\0\1\74"+ + "\61\0\2\30\1\75\1\0\1\76\1\0\1\76\1\77"+ + "\1\0\1\30\2\0\1\201\1\0\1\41\1\30\1\u01cf"+ + "\13\43\1\u0149\16\43\1\203\12\204\1\u01d0\1\154\1\205"+ + "\1\154\1\0\1\154\1\156\1\u01d1\1\u01d2\1\u01d3\3\0"+ + "\1\154\3\0\2\154\2\0\1\55\1\0\1\56\2\0"+ + "\1\57\1\0\1\60\4\0\1\61\1\0\1\62\1\0"+ + "\1\63\2\0\1\64\3\0\1\65\2\0\1\66\4\0"+ + "\1\67\3\0\1\70\17\0\1\71\2\0\1\72\21\0"+ + "\1\73\2\0\1\74\61\0\2\30\1\75\1\0\1\76"+ + "\1\0\1\76\1\77\1\0\1\30\2\0\1\201\1\0"+ + "\1\41\1\30\1\u01cf\24\43\1\u01e1\5\43\1\203\12\204"+ + "\1\u01d0\1\154\1\205\1\154\1\0\1\154\1\156\1\u01d1"+ + "\1\u01d2\1\u01d3\3\0\1\154\3\0\2\154\2\0\1\55"+ + "\1\0\1\56\2\0\1\57\1\0\1\60\4\0\1\61"+ + "\1\0\1\62\1\0\1\63\2\0\1\64\3\0\1\65"+ + "\2\0\1\66\4\0\1\67\3\0\1\70\17\0\1\71"+ + "\2\0\1\72\21\0\1\73\2\0\1\74\61\0\2\30"+ + "\1\75\1\0\1\76\1\0\1\76\1\77\1\0\1\30"+ + "\2\0\1\201\1\0\1\41\1\30\1\202\11\43\1\u0141"+ + "\20\43\1\203\12\204\1\76\1\154\1\205\1\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\2\0"+ + "\1\55\1\0\1\56\2\0\1\57\1\0\1\60\4\0"+ + "\1\61\1\0\1\62\1\0\1\63\2\0\1\64\3\0"+ + "\1\65\2\0\1\66\4\0\1\67\3\0\1\70\17\0"+ + "\1\71\2\0\1\72\21\0\1\73\2\0\1\74\61\0"+ + "\2\30\1\75\1\0\1\76\1\0\1\76\1\77\1\0"+ + "\1\30\2\0\1\201\1\0\1\41\1\30\1\u01cf\16\43"+ + "\1\u01e2\13\43\1\203\12\204\1\u01d0\1\154\1\205\1\154"+ + "\1\0\1\154\1\156\1\u01d1\1\u01d2\1\u01d3\3\0\1\154"+ + "\3\0\2\154\2\0\1\55\1\0\1\56\2\0\1\57"+ + "\1\0\1\60\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\65\2\0\1\66\4\0\1\67"+ + "\3\0\1\70\17\0\1\71\2\0\1\72\21\0\1\73"+ + "\2\0\1\74\61\0\2\30\1\75\1\0\1\76\1\0"+ + "\1\76\1\77\1\0\1\30\2\0\1\201\1\0\1\41"+ + "\1\30\1\u01cf\12\43\1\u01e3\17\43\1\203\12\204\1\u01d0"+ + "\1\154\1\205\1\154\1\0\1\154\1\156\1\u01d1\1\u01d2"+ + "\1\u01d3\3\0\1\154\3\0\2\154\2\0\1\55\1\0"+ + "\1\56\2\0\1\57\1\0\1\60\4\0\1\61\1\0"+ + "\1\62\1\0\1\63\2\0\1\64\3\0\1\65\2\0"+ + "\1\66\4\0\1\67\3\0\1\70\17\0\1\71\2\0"+ + "\1\72\21\0\1\73\2\0\1\74\61\0\2\30\1\75"+ + "\1\0\1\76\1\0\1\76\1\77\1\0\1\30\2\0"+ + "\1\201\1\0\1\41\1\30\1\u01cf\17\43\1\u0141\12\43"+ + "\1\203\12\204\1\u01d0\1\154\1\205\1\154\1\0\1\154"+ + "\1\156\1\u01d1\1\u01d2\1\u01d3\3\0\1\154\3\0\2\154"+ + "\2\0\1\55\1\0\1\56\2\0\1\57\1\0\1\60"+ + "\4\0\1\61\1\0\1\62\1\0\1\63\2\0\1\64"+ + "\3\0\1\65\2\0\1\66\4\0\1\67\3\0\1\70"+ + "\17\0\1\71\2\0\1\72\21\0\1\73\2\0\1\74"+ + "\61\0\2\30\1\75\1\0\1\76\1\0\1\76\1\77"+ + "\1\0\1\30\2\0\1\201\1\0\1\41\1\30\1\u01cf"+ + "\5\43\1\u0141\24\43\1\203\12\204\1\u01d0\1\154\1\205"+ + "\1\154\1\0\1\154\1\156\1\u01d1\1\u01d2\1\u01d3\3\0"+ + "\1\154\3\0\2\154\2\0\1\55\1\0\1\56\2\0"+ + "\1\57\1\0\1\60\4\0\1\61\1\0\1\62\1\0"+ + "\1\63\2\0\1\64\3\0\1\65\2\0\1\66\4\0"+ + "\1\67\3\0\1\70\17\0\1\71\2\0\1\72\21\0"+ + "\1\73\2\0\1\74\61\0\2\30\1\75\1\0\1\76"+ + "\1\0\1\76\1\77\1\0\1\30\2\0\1\201\1\0"+ + "\1\41\1\30\1\202\16\43\1\u01e4\13\43\1\203\12\204"+ + "\1\76\1\154\1\205\1\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\2\0\1\55\1\0\1\56"+ + "\2\0\1\57\1\0\1\60\4\0\1\61\1\0\1\62"+ + "\1\0\1\63\2\0\1\64\3\0\1\65\2\0\1\66"+ + "\4\0\1\67\3\0\1\70\17\0\1\71\2\0\1\72"+ + "\21\0\1\73\2\0\1\74\61\0\2\30\1\75\1\0"+ + "\1\76\1\0\1\76\1\77\1\0\1\30\2\0\1\201"+ + "\1\0\1\41\1\30\1\u01cf\20\43\1\u01e5\11\43\1\203"+ + "\12\204\1\u01d0\1\154\1\205\1\154\1\0\1\154\1\156"+ + "\1\u01d1\1\u01d2\1\u01d3\3\0\1\154\3\0\2\154\2\0"+ + "\1\55\1\0\1\56\2\0\1\57\1\0\1\60\4\0"+ + "\1\61\1\0\1\62\1\0\1\63\2\0\1\64\3\0"+ + "\1\65\2\0\1\66\4\0\1\67\3\0\1\70\17\0"+ + "\1\71\2\0\1\72\21\0\1\73\2\0\1\74\61\0"+ + "\2\30\1\75\1\0\1\76\1\0\1\76\1\77\1\0"+ + "\1\30\2\0\1\201\1\0\1\41\1\30\1\u01cf\5\43"+ + "\1\u01e6\24\43\1\203\12\204\1\u01d0\1\154\1\205\1\154"+ + "\1\0\1\154\1\156\1\u01d1\1\u01d2\1\u01d3\3\0\1\154"+ + "\3\0\2\154\2\0\1\55\1\0\1\56\2\0\1\57"+ + "\1\0\1\60\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\65\2\0\1\66\4\0\1\67"+ + "\3\0\1\70\17\0\1\71\2\0\1\72\21\0\1\73"+ + "\2\0\1\74\61\0\2\30\1\75\1\0\1\76\1\0"+ + "\1\76\1\77\1\0\1\30\2\0\1\201\1\0\1\41"+ + "\1\30\1\u01cf\22\43\1\u01e7\7\43\1\203\12\204\1\u01d0"+ + "\1\154\1\205\1\154\1\0\1\154\1\156\1\u01d1\1\u01d2"+ + "\1\u01d3\3\0\1\154\3\0\2\154\2\0\1\55\1\0"+ + "\1\56\2\0\1\57\1\0\1\60\4\0\1\61\1\0"+ + "\1\62\1\0\1\63\2\0\1\64\3\0\1\65\2\0"+ + "\1\66\4\0\1\67\3\0\1\70\17\0\1\71\2\0"+ + "\1\72\21\0\1\73\2\0\1\74\61\0\2\30\1\75"+ + "\1\0\1\76\1\0\1\76\1\77\1\0\1\30\2\0"+ + "\1\201\1\0\1\41\1\30\1\u01cf\13\43\1\u01e8\16\43"+ + "\1\203\12\204\1\u01d0\1\154\1\205\1\154\1\0\1\154"+ + "\1\156\1\u01d1\1\u01d2\1\u01d3\3\0\1\154\3\0\2\154"+ + "\2\0\1\55\1\0\1\56\2\0\1\57\1\0\1\60"+ + "\4\0\1\61\1\0\1\62\1\0\1\63\2\0\1\64"+ + "\3\0\1\65\2\0\1\66\4\0\1\67\3\0\1\70"+ + "\17\0\1\71\2\0\1\72\21\0\1\73\2\0\1\74"+ + "\61\0\2\30\1\75\1\0\1\76\1\0\1\76\1\77"+ + "\1\0\1\30\2\0\1\201\1\0\1\41\1\30\1\202"+ + "\17\43\1\u01e9\12\43\1\203\12\204\1\76\1\154\1\205"+ + "\1\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\2\0\1\55\1\0\1\56\2\0\1\57\1\0"+ + "\1\60\4\0\1\61\1\0\1\62\1\0\1\63\2\0"+ + "\1\64\3\0\1\65\2\0\1\66\4\0\1\67\3\0"+ + "\1\70\17\0\1\71\2\0\1\72\21\0\1\73\2\0"+ + "\1\74\61\0\2\30\1\75\1\0\1\76\1\0\1\76"+ + "\1\77\1\0\1\30\2\0\1\201\1\0\1\41\1\30"+ + "\1\202\1\43\1\u01ea\7\43\1\u0141\20\43\1\203\12\204"+ + "\1\76\1\154\1\205\1\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\2\0\1\55\1\0\1\56"+ + "\2\0\1\57\1\0\1\60\4\0\1\61\1\0\1\62"+ + "\1\0\1\63\2\0\1\64\3\0\1\65\2\0\1\66"+ + "\4\0\1\67\3\0\1\70\17\0\1\71\2\0\1\72"+ + "\21\0\1\73\2\0\1\74\61\0\2\30\1\75\1\0"+ + "\1\76\1\0\1\76\1\77\1\0\1\30\2\0\1\201"+ + "\1\0\1\41\1\30\1\u01cf\1\u01eb\31\43\1\203\12\204"+ + "\1\u01d0\1\154\1\205\1\154\1\0\1\154\1\156\1\u01d1"+ + "\1\u01d2\1\u01d3\3\0\1\154\3\0\2\154\2\0\1\55"+ + "\1\0\1\56\2\0\1\57\1\0\1\60\4\0\1\61"+ + "\1\0\1\62\1\0\1\63\2\0\1\64\3\0\1\65"+ + "\2\0\1\66\4\0\1\67\3\0\1\70\17\0\1\71"+ + "\2\0\1\72\21\0\1\73\2\0\1\74\61\0\2\30"+ + "\1\75\1\0\1\76\1\0\1\76\1\77\1\0\1\30"+ + "\2\0\1\201\1\0\1\41\1\30\1\u01cf\2\43\1\u01ec"+ + "\27\43\1\203\12\204\1\u01d0\1\154\1\205\1\154\1\0"+ + "\1\154\1\156\1\u01d1\1\u01d2\1\u01d3\3\0\1\154\3\0"+ + "\2\154\2\0\1\55\1\0\1\56\2\0\1\57\1\0"+ + "\1\60\4\0\1\61\1\0\1\62\1\0\1\63\2\0"+ + "\1\64\3\0\1\65\2\0\1\66\4\0\1\67\3\0"+ + "\1\70\17\0\1\71\2\0\1\72\21\0\1\73\2\0"+ + "\1\74\61\0\2\30\1\75\1\0\1\76\1\0\1\76"+ + "\1\77\1\0\1\30\2\0\1\201\1\0\1\41\1\30"+ + "\1\202\15\43\1\u01ed\14\43\1\203\12\204\1\76\1\154"+ + "\1\205\1\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\2\0\1\55\1\0\1\56\2\0\1\57"+ + "\1\0\1\60\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\65\2\0\1\66\4\0\1\67"+ + "\3\0\1\70\17\0\1\71\2\0\1\72\21\0\1\73"+ + "\2\0\1\74\61\0\2\30\1\75\1\0\1\76\1\0"+ + "\1\76\1\77\1\0\1\30\2\0\1\201\1\0\1\41"+ + "\1\30\1\202\5\43\1\u0141\24\43\1\203\12\204\1\76"+ + "\1\154\1\205\1\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\2\0\1\55\1\0\1\56\2\0"+ + "\1\57\1\0\1\60\4\0\1\61\1\0\1\62\1\0"+ + "\1\63\2\0\1\64\3\0\1\65\2\0\1\66\4\0"+ + "\1\67\3\0\1\70\17\0\1\71\2\0\1\72\21\0"+ + "\1\73\2\0\1\74\61\0\2\30\1\75\1\0\1\76"+ + "\1\0\1\76\1\77\1\0\1\30\2\0\1\201\1\0"+ + "\1\41\1\30\1\202\32\43\1\u01ee\12\204\1\76\1\154"+ + "\1\205\1\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\2\0\1\55\1\0\1\56\2\0\1\57"+ + "\1\0\1\60\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\65\2\0\1\66\4\0\1\67"+ + "\3\0\1\70\17\0\1\71\2\0\1\72\21\0\1\73"+ + "\2\0\1\74\61\0\2\30\1\75\1\0\1\76\1\0"+ + "\1\76\1\77\1\0\1\30\2\0\1\201\1\0\1\41"+ + "\1\30\1\202\22\43\1\u0141\7\43\1\203\12\204\1\76"+ + "\1\154\1\205\1\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\2\0\1\55\1\0\1\56\2\0"+ + "\1\57\1\0\1\60\4\0\1\61\1\0\1\62\1\0"+ + "\1\63\2\0\1\64\3\0\1\65\2\0\1\66\4\0"+ + "\1\67\3\0\1\70\17\0\1\71\2\0\1\72\21\0"+ + "\1\73\2\0\1\74\61\0\2\30\1\75\1\0\1\76"+ + "\1\0\1\76\1\77\1\0\1\30\2\0\1\201\1\0"+ + "\1\41\1\30\1\u01cf\23\43\1\u0141\2\43\1\u01e3\3\43"+ + "\1\203\12\204\1\u01d0\1\154\1\205\1\154\1\0\1\154"+ + "\1\156\1\u01d1\1\u01d2\1\u01d3\3\0\1\154\3\0\2\154"+ + "\2\0\1\55\1\0\1\56\2\0\1\57\1\0\1\60"+ + "\4\0\1\61\1\0\1\62\1\0\1\63\2\0\1\64"+ + "\3\0\1\65\2\0\1\66\4\0\1\67\3\0\1\70"+ + "\17\0\1\71\2\0\1\72\21\0\1\73\2\0\1\74"+ + "\61\0\2\30\1\75\1\0\1\76\1\0\1\76\1\77"+ + "\1\0\1\30\2\0\1\201\1\0\1\41\1\30\1\202"+ + "\11\43\1\u01ef\20\43\1\203\12\204\1\76\1\154\1\205"+ + "\1\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\2\0\1\55\1\0\1\56\2\0\1\57\1\0"+ + "\1\60\4\0\1\61\1\0\1\62\1\0\1\63\2\0"+ + "\1\64\3\0\1\65\2\0\1\66\4\0\1\67\3\0"+ + "\1\70\17\0\1\71\2\0\1\72\21\0\1\73\2\0"+ + "\1\74\61\0\2\30\1\75\1\0\1\76\1\0\1\76"+ + "\1\77\1\0\1\30\2\0\1\201\1\0\1\41\1\30"+ + "\1\u01cf\17\43\1\u01f0\12\43\1\203\12\204\1\u01d0\1\154"+ + "\1\205\1\154\1\0\1\154\1\156\1\u01d1\1\u01d2\1\u01d3"+ + "\3\0\1\154\3\0\2\154\2\0\1\55\1\0\1\56"+ + "\2\0\1\57\1\0\1\60\4\0\1\61\1\0\1\62"+ + "\1\0\1\63\2\0\1\64\3\0\1\65\2\0\1\66"+ + "\4\0\1\67\3\0\1\70\17\0\1\71\2\0\1\72"+ + "\21\0\1\73\2\0\1\74\61\0\2\30\1\75\1\0"+ + "\1\76\1\0\1\76\1\77\1\0\1\30\2\0\1\201"+ + "\1\0\1\41\1\30\1\u01cf\24\43\1\u01ed\5\43\1\203"+ + "\12\204\1\u01d0\1\154\1\205\1\154\1\0\1\154\1\156"+ + "\1\u01d1\1\u01d2\1\u01d3\3\0\1\154\3\0\2\154\2\0"+ + "\1\55\1\0\1\56\2\0\1\57\1\0\1\60\4\0"+ + "\1\61\1\0\1\62\1\0\1\63\2\0\1\64\3\0"+ + "\1\65\2\0\1\66\4\0\1\67\3\0\1\70\17\0"+ + "\1\71\2\0\1\72\21\0\1\73\2\0\1\74\61\0"+ + "\2\30\1\75\1\0\1\76\1\0\1\76\1\77\1\0"+ + "\1\30\2\0\1\201\1\0\1\41\1\30\1\u01cf\13\43"+ + "\1\u01f1\16\43\1\203\12\204\1\u01d0\1\154\1\205\1\154"+ + "\1\0\1\154\1\156\1\u01d1\1\u01d2\1\u01d3\3\0\1\154"+ + "\3\0\2\154\2\0\1\55\1\0\1\56\2\0\1\57"+ + "\1\0\1\60\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\65\2\0\1\66\4\0\1\67"+ + "\3\0\1\70\17\0\1\71\2\0\1\72\21\0\1\73"+ + "\2\0\1\74\61\0\2\30\1\75\1\0\1\76\1\0"+ + "\1\76\1\77\1\0\1\30\2\0\1\201\1\0\1\41"+ + "\1\30\1\202\31\43\1\u01f2\1\203\12\204\1\76\1\154"+ + "\1\205\1\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\1\157\2\0\1\155\1\u0103"+ + "\1\u0104\1\u0105\1\u0106\1\u0107\1\u0108\1\u0109\1\u010a\1\u010b"+ + "\1\u010c\1\u010d\1\u010e\1\u010f\1\u0110\1\u0111\1\u0112\1\u0113"+ + "\1\u0114\1\u0115\1\u0116\1\u0117\1\u0118\1\u0119\1\u011a\1\u011b"+ + "\1\u011c\1\154\12\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\2\0\1\55\1\0"+ + "\1\56\2\0\1\57\1\0\1\60\4\0\1\61\1\0"+ + "\1\62\1\0\1\63\2\0\1\64\3\0\1\65\2\0"+ + "\1\66\4\0\1\67\3\0\1\70\17\0\1\71\2\0"+ + "\1\72\21\0\1\73\2\0\1\74\61\0\2\30\1\75"+ + "\1\0\1\76\1\0\1\76\1\77\1\0\1\30\2\0"+ + "\1\201\1\0\1\41\1\30\1\202\32\43\1\203\12\204"+ + "\1\u01f3\1\154\1\205\1\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\2\0\1\55\1\0\1\56"+ + "\2\0\1\245\1\0\1\246\4\0\1\61\1\0\1\62"+ + "\1\0\1\63\2\0\1\64\3\0\1\247\2\0\1\250"+ + "\4\0\1\251\3\0\1\252\17\0\1\71\2\0\1\253"+ + "\21\0\1\254\2\0\1\255\61\0\1\30\1\76\2\0"+ + "\1\76\1\0\2\76\1\0\1\76\2\0\1\76\1\0"+ + "\2\30\1\76\32\30\13\0\1\76\1\0\1\76\5\0"+ + "\1\u01f4\14\0\1\55\1\0\1\56\2\0\1\57\1\0"+ + "\1\60\4\0\1\61\1\0\1\62\1\0\1\63\2\0"+ + "\1\64\3\0\1\65\2\0\1\66\4\0\1\67\3\0"+ + "\1\70\17\0\1\71\2\0\1\72\21\0\1\73\2\0"+ + "\1\74\61\0\2\30\1\75\1\0\1\76\1\0\1\76"+ + "\1\77\1\0\1\30\2\0\1\201\1\0\1\41\1\30"+ + "\1\202\17\43\1\u01f5\12\43\1\203\12\204\1\76\1\154"+ + "\1\205\1\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\2\0\1\55\1\0\1\56\2\0\1\57"+ + "\1\0\1\60\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\65\2\0\1\66\4\0\1\67"+ + "\3\0\1\70\17\0\1\71\2\0\1\72\21\0\1\73"+ + "\2\0\1\74\61\0\2\30\1\75\1\0\1\76\1\0"+ + "\1\76\1\77\1\0\1\30\2\0\1\201\1\0\1\41"+ + "\1\30\1\202\16\43\1\u01f6\13\43\1\203\12\204\1\u01f7"+ + "\1\154\1\205\1\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u01f8\32\371"+ + "\1\203\12\371\1\u01f9\3\154\1\0\1\154\1\156\1\u01d1"+ + "\1\u01d2\1\u01d3\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u01f8\4\371\1\u0199\25\371\1\203\12\371\1\u01f9"+ + "\3\154\1\0\1\154\1\156\1\u01d1\1\u01d2\1\u01d3\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u01f8\15\371"+ + "\1\u010f\14\371\1\203\12\371\1\u01f9\3\154\1\0\1\154"+ + "\1\156\1\u01d1\1\u01d2\1\u01d3\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u01f8\10\371\1\u010f\21\371\1\203"+ + "\12\371\1\u01f9\3\154\1\0\1\154\1\156\1\u01d1\1\u01d2"+ + "\1\u01d3\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u01f8\12\371\1\u01fa\4\371\1\u0174\12\371\1\203\12\371"+ + "\1\u01f9\3\154\1\0\1\154\1\156\1\u01d1\1\u01d2\1\u01d3"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u01f8"+ + "\5\371\1\u01fb\4\371\1\u0174\1\u01fc\16\371\1\203\12\371"+ + "\1\u01f9\3\154\1\0\1\154\1\156\1\u01d1\1\u01d2\1\u01d3"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u01f8"+ + "\5\371\1\u01fd\24\371\1\203\12\371\1\u01f9\3\154\1\0"+ + "\1\154\1\156\1\u01d1\1\u01d2\1\u01d3\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\1\u01fe\3\371\1\u01ff"+ + "\25\371\1\203\12\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\20\371\1\u0174\11\371\1\203\12\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\17\371\1\u0200\12\371\1\203"+ + "\12\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\20\371"+ + "\1\u0201\11\371\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u01f8\17\371\1\u0202\12\371\1\203\12\371\1\u01f9"+ + "\3\154\1\0\1\154\1\156\1\u01d1\1\u01d2\1\u01d3\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\7\371"+ + "\1\u0174\22\371\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u01f8\11\371\1\u0203\20\371\1\203\12\371\1\u01f9"+ + "\3\154\1\0\1\154\1\156\1\u01d1\1\u01d2\1\u01d3\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u01f8\1\u0204"+ + "\31\371\1\203\12\371\1\u01f9\3\154\1\0\1\154\1\156"+ + "\1\u01d1\1\u01d2\1\u01d3\3\0\1\154\3\0\2\154\213\0"+ + "\1\154\3\0\1\u016f\30\371\1\u0174\1\371\1\203\12\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u01f8\4\371\1\u017c"+ + "\25\371\1\203\12\371\1\u01f9\3\154\1\0\1\154\1\156"+ + "\1\u01d1\1\u01d2\1\u01d3\3\0\1\154\3\0\2\154\213\0"+ + "\1\154\3\0\1\u01f8\6\371\1\u0199\10\371\1\u0174\12\371"+ + "\1\203\12\371\1\u01f9\3\154\1\0\1\154\1\156\1\u01d1"+ + "\1\u01d2\1\u01d3\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u01f8\13\371\1\u0205\16\371\1\203\12\371\1\u01f9"+ + "\3\154\1\0\1\154\1\156\1\u01d1\1\u01d2\1\u01d3\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u01f8\7\371"+ + "\1\u0206\22\371\1\203\12\371\1\u01f9\3\154\1\0\1\154"+ + "\1\156\1\u01d1\1\u01d2\1\u01d3\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u01f8\13\371\1\u017c\16\371\1\203"+ + "\12\371\1\u01f9\3\154\1\0\1\154\1\156\1\u01d1\1\u01d2"+ + "\1\u01d3\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u01f8\24\371\1\u0207\5\371\1\203\12\371\1\u01f9\3\154"+ + "\1\0\1\154\1\156\1\u01d1\1\u01d2\1\u01d3\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\11\371\1\u0174"+ + "\20\371\1\203\12\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u01f8\16\371\1\u0208\13\371\1\203\12\371\1\u01f9\3\154"+ + "\1\0\1\154\1\156\1\u01d1\1\u01d2\1\u01d3\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u01f8\12\371\1\u0209"+ + "\17\371\1\203\12\371\1\u01f9\3\154\1\0\1\154\1\156"+ + "\1\u01d1\1\u01d2\1\u01d3\3\0\1\154\3\0\2\154\213\0"+ + "\1\154\3\0\1\u01f8\17\371\1\u0174\12\371\1\203\12\371"+ + "\1\u01f9\3\154\1\0\1\154\1\156\1\u01d1\1\u01d2\1\u01d3"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u01f8"+ + "\5\371\1\u0174\24\371\1\203\12\371\1\u01f9\3\154\1\0"+ + "\1\154\1\156\1\u01d1\1\u01d2\1\u01d3\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\16\371\1\u020a\13\371"+ + "\1\203\12\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u01f8"+ + "\20\371\1\u020b\11\371\1\203\12\371\1\u01f9\3\154\1\0"+ + "\1\154\1\156\1\u01d1\1\u01d2\1\u01d3\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u01f8\5\371\1\u020c\24\371"+ + "\1\203\12\371\1\u01f9\3\154\1\0\1\154\1\156\1\u01d1"+ + "\1\u01d2\1\u01d3\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u01f8\22\371\1\u020d\7\371\1\203\12\371\1\u01f9"+ + "\3\154\1\0\1\154\1\156\1\u01d1\1\u01d2\1\u01d3\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u01f8\13\371"+ + "\1\u020e\16\371\1\203\12\371\1\u01f9\3\154\1\0\1\154"+ + "\1\156\1\u01d1\1\u01d2\1\u01d3\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\17\371\1\u020f\12\371\1\203"+ + "\12\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\1\371"+ + "\1\u0210\7\371\1\u0174\20\371\1\203\12\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u01f8\1\u0211\31\371\1\203\12\371"+ + "\1\u01f9\3\154\1\0\1\154\1\156\1\u01d1\1\u01d2\1\u01d3"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u01f8"+ + "\2\371\1\u0212\27\371\1\203\12\371\1\u01f9\3\154\1\0"+ + "\1\154\1\156\1\u01d1\1\u01d2\1\u01d3\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\15\371\1\u0213\14\371"+ + "\1\203\12\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\5\371\1\u0174\24\371\1\203\12\371\1\0\3\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\213\0"+ + "\1\154\3\0\1\u016f\32\371\1\u01ee\12\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\22\371\1\u0174\7\371\1\203"+ + "\12\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u01f8\23\371"+ + "\1\u0174\2\371\1\u0209\3\371\1\203\12\371\1\u01f9\3\154"+ + "\1\0\1\154\1\156\1\u01d1\1\u01d2\1\u01d3\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\11\371\1\u0214"+ + "\20\371\1\203\12\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u01f8\17\371\1\u0215\12\371\1\203\12\371\1\u01f9\3\154"+ + "\1\0\1\154\1\156\1\u01d1\1\u01d2\1\u01d3\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u01f8\24\371\1\u0213"+ + "\5\371\1\203\12\371\1\u01f9\3\154\1\0\1\154\1\156"+ + "\1\u01d1\1\u01d2\1\u01d3\3\0\1\154\3\0\2\154\213\0"+ + "\1\154\3\0\1\u01f8\13\371\1\u0216\16\371\1\203\12\371"+ + "\1\u01f9\3\154\1\0\1\154\1\156\1\u01d1\1\u01d2\1\u01d3"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\31\371\1\u0217\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\7\0\1\265"+ + "\1\0\1\266\17\0\1\267\2\0\1\270\4\0\1\271"+ + "\3\0\1\272\22\0\1\273\21\0\1\274\2\0\1\275"+ + "\62\0\1\111\1\31\2\0\3\243\1\0\1\111\2\0"+ + "\1\372\1\157\2\0\1\u0102\1\u0103\1\u0104\1\u0105\1\u0106"+ + "\1\u0107\1\u0108\1\u0109\1\u010a\1\u010b\1\u010c\1\u010d\1\u010e"+ + "\1\u010f\1\u0110\1\u0111\1\u0112\1\u0113\1\u0114\1\u0115\1\u0116"+ + "\1\u0117\1\u0118\1\u0119\1\u011a\1\u011b\1\u011c\1\154\1\u0218"+ + "\1\u0219\5\u0218\1\u021a\1\u0219\1\u0218\1\0\1\154\1\372"+ + "\1\154\1\0\1\372\1\156\3\154\2\0\1\243\1\154"+ + "\3\0\2\154\2\0\1\55\1\0\1\56\2\0\1\100"+ + "\1\0\1\101\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\102\2\0\1\103\4\0\1\104"+ + "\3\0\1\105\17\0\1\71\2\0\1\106\21\0\1\107"+ + "\2\0\1\110\61\0\1\30\2\31\2\0\2\111\1\112"+ + "\1\0\1\31\2\0\1\212\1\0\1\41\1\30\1\u01a2"+ + "\32\43\1\203\12\u0120\1\0\1\154\1\215\1\154\1\0"+ + "\1\212\1\156\3\154\2\0\1\111\1\154\3\0\2\154"+ + "\2\0\1\55\1\0\1\56\2\0\1\100\1\0\1\101"+ + "\4\0\1\61\1\0\1\62\1\0\1\63\2\0\1\64"+ + "\3\0\1\102\2\0\1\103\4\0\1\104\3\0\1\105"+ + "\17\0\1\71\2\0\1\106\21\0\1\107\2\0\1\110"+ + "\61\0\1\30\2\31\2\0\2\111\1\112\1\0\1\31"+ + "\2\0\1\212\1\0\1\41\1\30\1\u01a2\32\43\1\203"+ + "\2\u01a3\1\u0120\2\u01a3\2\u0120\2\u01a3\1\u0120\1\0\1\154"+ + "\1\215\1\154\1\0\1\212\1\156\3\154\2\0\1\111"+ + "\1\154\3\0\2\154\7\0\1\265\1\0\1\266\17\0"+ + "\1\267\2\0\1\270\4\0\1\271\3\0\1\272\22\0"+ + "\1\273\21\0\1\274\2\0\1\275\62\0\1\111\1\31"+ + "\2\0\3\243\1\0\1\111\2\0\1\372\1\157\2\0"+ + "\1\u0102\1\u0103\1\u0104\1\u0105\1\u0106\1\u0107\1\u0108\1\u0109"+ + "\1\u010a\1\u010b\1\u010c\1\u010d\1\u010e\1\u010f\1\u0110\1\u0111"+ + "\1\u0112\1\u0113\1\u0114\1\u0115\1\u0116\1\u0117\1\u0118\1\u0119"+ + "\1\u011a\1\u011b\1\u011c\1\154\12\u0120\1\0\1\154\1\372"+ + "\1\154\1\0\1\372\1\156\3\154\2\0\1\243\1\154"+ + "\3\0\2\154\220\0\4\u021b\2\0\1\u021b\15\0\1\u021b"+ + "\6\0\12\u021b\1\u0123\242\0\4\u021c\2\0\1\u021c\15\0"+ + "\1\u021c\6\0\12\u021c\1\u021d\242\0\4\u021e\2\0\1\u021e"+ + "\15\0\1\u021e\6\0\1\u021f\1\u0220\5\u021f\1\u0221\1\u0220"+ + "\1\u021f\13\0\1\u01ad\227\0\4\u0222\2\0\1\u0222\15\0"+ + "\1\u0222\6\0\12\u0222\1\u0223\12\0\1\u01ad\226\0\1\u0224"+ + "\4\u0222\2\0\1\u0222\15\0\1\u0222\6\0\12\u0225\1\u0223"+ + "\12\0\1\u01ad\226\0\1\u0224\4\u0222\2\0\1\u0222\15\0"+ + "\1\u0222\6\0\12\u0226\1\u0223\12\0\1\u01ad\226\0\1\u0224"+ + "\4\u0222\2\0\1\u0222\15\0\1\u0222\6\0\2\u0226\1\u0225"+ + "\1\u0226\1\u0227\2\u0225\2\u0226\1\u0225\1\u0223\12\0\1\u01ad"+ + "\274\0\1\u01f9\6\0\1\u0228\1\u0229\1\u022a\103\0\1\u0125"+ + "\2\0\1\u0125\33\0\4\u0125\310\0\1\u0125\171\0\1\u0125"+ + "\44\0\1\u0125\1\0\2\u0125\21\0\1\u0125\4\0\1\u0125"+ + "\17\0\4\u0125\3\0\1\u0125\12\0\1\u0125\275\0\1\u0125"+ + "\314\0\4\u0125\244\0\2\u0125\25\0\4\u0125\147\0\1\u0125"+ + "\15\0\2\u0125\10\0\2\u0125\1\0\1\u0125\1\0\1\u0125"+ + "\11\0\1\u0125\11\0\2\u0125\6\0\1\u0125\2\0\4\u0125"+ + "\3\0\1\u0125\2\0\2\u0125\1\0\3\u0125\1\0\2\u0125"+ + "\1\0\1\u0125\10\0\1\u0125\1\0\2\u0125\2\0\2\u0125"+ + "\1\0\4\u0125\23\0\1\u0125\330\0\1\u0136\1\323\2\u022b"+ + "\1\u022c\1\u022d\10\u022b\1\323\1\u022e\5\u022b\6\323\1\u0137"+ + "\12\323\242\0\1\u0136\1\u022f\2\u022b\1\323\1\u022b\1\u0230"+ + "\3\u022b\1\u0231\2\u022b\4\323\4\u022b\1\323\2\u022b\1\323"+ + "\2\u022b\1\u0137\12\323\242\0\1\u0136\3\323\1\u022b\1\323"+ + "\1\u022b\2\323\1\u0232\1\323\1\u022b\10\323\1\u022b\2\323"+ + "\2\u022b\2\323\1\u0137\12\323\242\0\1\u0136\1\323\1\u022b"+ + "\1\u0233\2\u022b\2\323\1\u022b\3\323\1\u0234\1\u0235\1\323"+ + "\1\u0236\2\u022b\11\323\1\u0137\12\323\242\0\1\u0136\3\323"+ + "\1\u022b\1\323\1\u022b\10\323\1\u022b\1\323\2\u022b\10\323"+ + "\1\u0137\12\323\242\0\1\u0136\4\323\1\u0237\5\323\1\u022b"+ + "\17\323\1\u0137\12\323\242\0\1\u0136\4\323\2\u022b\2\323"+ + "\1\u022b\1\323\1\u022b\13\323\2\u022b\2\323\1\u0137\12\323"+ + "\242\0\1\u0136\1\u0238\1\323\2\u022b\1\u0239\1\u023a\12\u022b"+ + "\1\u023b\1\u022b\2\323\2\u022b\3\323\1\u022b\1\u0137\12\323"+ + "\242\0\1\u0136\2\323\4\u022b\3\323\2\u022b\1\u023c\1\u022b"+ + "\1\323\2\u022b\12\323\1\u0137\12\323\242\0\1\u0136\1\u023d"+ + "\1\u022b\2\323\1\u022b\3\323\1\u023e\5\323\3\u022b\3\323"+ + "\1\u022b\1\323\1\u022b\1\323\2\u022b\1\u0137\12\323\242\0"+ + "\1\u0136\3\u022b\1\u023f\1\u022b\1\u0240\1\323\1\u022b\1\u0241"+ + "\7\u022b\1\u0242\3\u022b\1\323\2\u022b\1\323\2\u022b\1\u0137"+ + "\12\323\242\0\1\u0136\1\u0243\1\u022b\1\323\1\u0244\6\u022b"+ + "\3\323\1\u022b\2\323\1\u022b\2\323\1\u022b\6\323\1\u0137"+ + "\12\323\242\0\1\u0136\1\u022b\31\323\1\u0137\12\323\242\0"+ + "\1\u0136\1\u022b\2\323\1\u022b\1\u0245\1\u0246\2\u022b\1\323"+ + "\1\u0247\2\u022b\2\323\2\u022b\1\323\1\u022b\3\323\1\u0248"+ + "\1\u022b\2\323\1\u022b\1\u0137\12\323\242\0\1\u0136\3\u022b"+ + "\1\u0249\2\u022b\1\323\1\u022b\1\u024a\3\u022b\3\323\2\u022b"+ + "\1\323\10\u022b\1\u0137\12\323\242\0\1\u0136\1\u024b\2\u022b"+ + "\1\u024c\1\u024d\1\u024e\2\u022b\1\u024f\3\u022b\1\323\1\u022b"+ + "\1\323\1\u022b\1\323\1\u022b\1\323\1\u022b\1\323\4\u022b"+ + "\1\323\1\u0137\12\323\242\0\1\u0136\1\u022b\6\323\1\u022b"+ + "\3\323\1\u0250\2\323\1\u022b\4\323\1\u022b\2\323\1\u022b"+ + "\2\323\1\u022b\1\u0137\12\323\242\0\1\u0136\6\323\1\u022b"+ + "\7\323\1\u022b\13\323\1\u0137\12\323\242\0\1\u0136\13\323"+ + "\1\u0251\6\323\1\u0252\7\323\1\u0137\12\323\242\0\1\u0136"+ + "\1\u022b\11\323\1\u022b\6\323\1\u022b\10\323\1\u0137\12\323"+ + "\242\0\1\u0136\1\u022b\1\323\6\u022b\1\u0253\1\323\2\u022b"+ + "\2\323\2\u022b\1\323\1\u022b\1\323\3\u022b\1\323\3\u022b"+ + "\1\u0137\12\323\242\0\1\u0136\4\323\1\u022b\1\u0254\4\323"+ + "\2\u022b\3\323\2\u022b\5\323\1\u022b\3\323\1\u0137\12\323"+ + "\242\0\1\u0136\3\323\2\u022b\2\323\1\u022b\1\u0255\1\323"+ + "\2\u022b\1\323\1\u022b\3\323\1\u022b\1\323\1\u022b\1\323"+ + "\1\u022b\3\323\1\u022b\1\u0137\12\323\242\0\1\u0136\3\323"+ + "\1\u022b\1\323\1\u0256\4\323\1\u022b\2\323\1\u022b\14\323"+ + "\1\u0137\12\323\242\0\1\u0136\2\u022b\1\323\1\u0257\1\323"+ + "\1\u0258\1\323\2\u022b\2\323\1\u022b\4\323\1\u022b\11\323"+ + "\1\u0137\12\323\242\0\1\u0136\3\323\1\u022b\13\323\1\u022b"+ + "\12\323\1\u0137\12\323\25\0\1\55\1\0\1\56\2\0"+ + "\1\245\1\0\1\246\4\0\1\61\1\0\1\62\1\0"+ + "\1\63\2\0\1\64\3\0\1\247\2\0\1\250\4\0"+ + "\1\251\3\0\1\252\17\0\1\71\2\0\1\253\21\0"+ + "\1\254\2\0\1\255\61\0\1\30\1\76\2\0\1\76"+ + "\1\0\2\76\1\0\1\76\2\0\1\201\1\157\2\30"+ "\1\336\1\337\1\340\1\341\1\342\1\343\1\344\1\345"+ "\1\346\1\347\1\350\1\351\1\352\1\353\1\354\1\355"+ "\1\356\1\357\1\360\1\361\1\362\1\363\1\364\1\365"+ - "\1\161\1\366\2\367\1\366\5\367\1\370\1\0\3\161"+ - "\1\0\2\161\1\162\3\161\3\0\1\161\1\206\3\0"+ - "\2\161\2\0\1\53\1\0\1\54\2\0\1\252\1\0"+ - "\1\77\4\0\1\57\1\0\1\60\1\0\1\61\2\0"+ - "\1\62\3\0\1\253\2\0\1\254\4\0\1\102\3\0"+ - "\1\255\17\0\1\67\2\0\1\256\21\0\1\257\2\0"+ - "\1\260\41\0\1\130\15\0\1\30\1\110\1\31\1\132"+ - "\3\0\1\110\1\0\1\110\2\0\1\30\1\160\32\201"+ - "\1\161\12\202\1\0\1\161\1\175\1\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\7\0\1\241"+ - "\1\0\1\242\17\0\1\243\2\0\1\244\4\0\1\245"+ - "\3\0\1\246\22\0\1\247\21\0\1\250\2\0\1\251"+ - "\60\0\1\107\1\31\6\0\1\107\3\0\1\160\33\161"+ - "\12\202\1\0\3\161\1\0\2\161\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\2\0\1\53\1\0\1\54\2\0"+ - "\1\76\1\0\1\77\4\0\1\57\1\0\1\60\1\0"+ - "\1\61\2\0\1\62\3\0\1\100\2\0\1\101\4\0"+ - "\1\102\3\0\1\103\17\0\1\67\2\0\1\104\21\0"+ - "\1\105\2\0\1\106\57\0\1\30\2\31\2\0\2\107"+ - "\1\110\1\0\1\31\2\0\1\30\1\174\32\41\1\164"+ - "\12\371\1\0\1\161\1\175\1\161\1\0\2\176\1\162"+ - "\3\161\2\0\1\107\1\161\4\0\2\161\2\0\1\53"+ - "\1\0\1\54\2\0\1\76\1\0\1\77\4\0\1\57"+ - "\1\0\1\60\1\0\1\61\2\0\1\62\3\0\1\100"+ - "\2\0\1\101\4\0\1\102\3\0\1\103\17\0\1\67"+ - "\2\0\1\104\21\0\1\105\2\0\1\106\57\0\1\30"+ - "\2\31\2\0\2\107\1\110\1\0\1\31\2\0\1\30"+ - "\1\174\32\41\1\164\2\177\1\371\2\177\2\371\1\177"+ - "\1\371\1\177\1\0\1\161\1\175\1\161\1\0\2\176"+ - "\1\162\3\161\2\0\1\107\1\161\4\0\2\161\2\0"+ - "\1\53\1\0\1\54\2\0\1\55\1\0\1\56\4\0"+ - "\1\57\1\0\1\60\1\0\1\61\2\0\1\62\3\0"+ - "\1\63\2\0\1\64\4\0\1\65\3\0\1\66\17\0"+ - "\1\67\2\0\1\70\21\0\1\71\2\0\1\72\57\0"+ - "\2\30\1\73\1\0\1\74\1\0\1\74\1\75\1\0"+ - "\1\30\2\0\1\30\1\372\32\201\1\161\12\327\1\74"+ - "\1\161\1\166\1\161\1\0\1\161\1\167\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\2\0\1\53\1\0\1\54"+ - "\2\0\1\76\1\0\1\77\4\0\1\57\1\0\1\60"+ - "\1\0\1\61\2\0\1\62\3\0\1\100\2\0\1\101"+ - "\4\0\1\102\3\0\1\103\17\0\1\67\2\0\1\104"+ - "\21\0\1\105\2\0\1\106\57\0\1\30\2\31\2\0"+ - "\2\107\1\110\1\0\1\31\2\0\1\30\1\373\32\201"+ - "\1\161\12\202\1\0\1\161\1\175\1\161\1\0\2\176"+ - "\1\162\3\161\2\0\1\107\1\161\4\0\2\161\213\0"+ - "\4\374\2\0\1\374\15\0\1\374\6\0\12\374\1\375"+ - "\304\0\1\376\236\0\1\377\54\0\1\162\227\0\74\206"+ - "\7\0\1\30\4\0\1\30\11\0\1\30\22\0\1\30"+ - "\3\0\1\30\13\0\1\73\2\0\1\73\10\0\1\30"+ - "\12\0\4\73\45\0\1\30\115\0\1\30\26\0\2\30"+ - "\23\0\1\73\1\30\44\0\1\73\21\0\1\73\142\0"+ - "\1\73\11\0\1\73\15\0\4\30\2\0\2\30\14\0"+ - "\3\30\1\73\1\0\2\73\11\0\3\30\3\0\1\30"+ - "\1\0\1\73\4\0\1\73\2\30\5\0\4\73\2\0"+ - "\1\30\1\73\12\0\4\73\1\0\2\30\1\0\1\73"+ - "\7\0\1\30\117\0\1\30\4\0\1\30\6\0\1\30"+ - "\3\0\1\30\6\0\1\30\5\0\1\30\2\0\2\30"+ - "\1\0\17\30\2\0\1\30\13\0\7\30\2\0\1\30"+ - "\1\0\1\30\1\0\1\30\2\0\1\30\1\0\1\30"+ - "\1\0\1\30\1\0\1\30\4\0\1\73\1\0\2\30"+ - "\5\0\1\30\1\0\1\30\2\0\3\30\1\0\1\30"+ - "\7\0\1\30\1\0\1\30\122\0\1\30\6\0\1\30"+ - "\3\0\1\30\3\0\1\30\7\0\1\30\31\0\20\30"+ - "\5\0\3\30\3\0\1\30\3\0\2\30\2\0\2\30"+ - "\4\0\1\30\4\73\4\0\1\30\4\0\1\30\2\0"+ - "\1\30\4\0\1\30\1\0\1\30\1\0\1\30\223\0"+ - "\2\73\15\0\4\73\154\0\1\73\15\0\2\73\10\0"+ - "\2\73\1\0\1\73\1\0\1\73\11\0\1\73\11\0"+ - "\2\73\6\0\1\73\2\0\4\73\3\0\1\73\2\0"+ - "\2\73\1\0\3\73\5\0\1\73\1\0\2\73\2\0"+ - "\2\73\1\0\4\73\5\0\1\73\1\0\2\73\140\0"+ - "\1\u0100\1\0\1\u0101\17\0\1\u0102\2\0\1\u0103\4\0"+ - "\1\u0104\3\0\1\u0105\22\0\1\u0106\21\0\1\u0107\2\0"+ - "\1\u0108\60\0\1\220\1\73\6\0\1\220\37\0\12\73"+ - "\35\0\1\30\4\0\1\30\11\0\1\30\22\0\1\30"+ - "\3\0\1\30\13\0\1\74\2\0\1\74\10\0\1\30"+ - "\12\0\4\74\45\0\1\30\120\0\1\30\3\0\4\30"+ - "\1\0\1\30\4\0\1\30\1\0\2\30\2\0\2\30"+ - "\2\0\3\30\1\0\1\30\1\0\1\30\2\0\4\30"+ - "\1\0\3\30\1\0\1\30\1\0\3\30\1\0\2\30"+ - "\1\0\4\30\1\0\2\30\2\0\10\30\1\0\2\30"+ - "\1\0\11\30\1\0\10\30\1\0\13\30\2\0\1\30"+ - "\1\0\1\30\1\0\2\30\2\0\1\30\1\0\1\30"+ - "\3\0\1\30\113\0\1\30\26\0\2\30\24\0\1\30"+ - "\44\0\1\74\176\0\1\74\15\0\4\30\2\0\2\30"+ - "\14\0\3\30\1\74\1\0\2\74\11\0\3\30\3\0"+ - "\1\30\1\0\1\74\4\0\1\74\2\30\5\0\4\74"+ - "\2\0\1\30\1\74\17\0\2\30\1\0\1\74\7\0"+ - "\1\30\133\0\1\30\3\0\2\30\12\0\2\30\1\0"+ - "\3\30\7\0\1\30\6\0\2\30\1\0\2\30\6\0"+ - "\1\30\4\0\2\30\2\0\2\30\5\0\3\30\10\0"+ - "\1\30\16\0\1\30\7\0\1\30\7\0\1\30\117\0"+ - "\1\30\4\0\1\30\6\0\1\30\3\0\1\30\6\0"+ - "\1\30\5\0\1\30\2\0\2\30\1\0\17\30\2\0"+ - "\1\30\13\0\7\30\2\0\1\30\1\0\1\30\1\0"+ - "\1\30\2\0\1\30\1\0\1\30\1\0\1\30\1\0"+ - "\1\30\4\0\1\74\1\0\2\30\5\0\1\30\1\0"+ - "\1\30\2\0\3\30\1\0\1\30\7\0\1\30\1\0"+ - "\1\30\122\0\1\30\6\0\1\30\3\0\1\30\3\0"+ - "\1\30\7\0\1\30\31\0\20\30\5\0\3\30\3\0"+ - "\1\30\3\0\2\30\2\0\2\30\4\0\1\30\4\74"+ - "\4\0\1\30\4\0\1\30\2\0\1\30\4\0\1\30"+ - "\1\0\1\30\1\0\1\30\223\0\2\74\15\0\4\74"+ - "\154\0\1\74\15\0\2\74\10\0\2\74\1\0\1\74"+ - "\1\0\1\74\11\0\1\74\11\0\2\74\6\0\1\74"+ - "\2\0\4\74\3\0\1\74\2\0\2\74\1\0\3\74"+ - "\5\0\1\74\1\0\2\74\2\0\2\74\1\0\4\74"+ - "\5\0\1\74\1\0\2\74\141\0\1\30\4\0\1\30"+ - "\11\0\1\30\22\0\1\30\3\0\1\30\13\0\1\75"+ - "\2\0\1\75\10\0\1\30\12\0\4\75\45\0\1\30"+ - "\115\0\1\30\26\0\2\30\23\0\1\73\1\30\44\0"+ - "\1\75\21\0\1\73\142\0\1\73\11\0\1\75\15\0"+ - "\4\30\2\0\2\30\14\0\3\30\1\75\1\0\2\75"+ - "\11\0\3\30\3\0\1\30\1\0\1\75\4\0\1\75"+ - "\2\30\5\0\4\75\2\0\1\30\1\75\12\0\4\73"+ - "\1\0\2\30\1\0\1\75\7\0\1\30\117\0\1\30"+ - "\4\0\1\30\6\0\1\30\3\0\1\30\6\0\1\30"+ - "\5\0\1\30\2\0\2\30\1\0\17\30\2\0\1\30"+ - "\13\0\7\30\2\0\1\30\1\0\1\30\1\0\1\30"+ - "\2\0\1\30\1\0\1\30\1\0\1\30\1\0\1\30"+ - "\4\0\1\75\1\0\2\30\5\0\1\30\1\0\1\30"+ - "\2\0\3\30\1\0\1\30\7\0\1\30\1\0\1\30"+ - "\122\0\1\30\6\0\1\30\3\0\1\30\3\0\1\30"+ - "\7\0\1\30\31\0\20\30\5\0\3\30\3\0\1\30"+ - "\3\0\2\30\2\0\2\30\4\0\1\30\4\75\4\0"+ - "\1\30\4\0\1\30\2\0\1\30\4\0\1\30\1\0"+ - "\1\30\1\0\1\30\223\0\2\75\15\0\4\75\154\0"+ - "\1\75\15\0\2\75\10\0\2\75\1\0\1\75\1\0"+ - "\1\75\11\0\1\75\11\0\2\75\6\0\1\75\2\0"+ - "\4\75\3\0\1\75\2\0\2\75\1\0\3\75\5\0"+ - "\1\75\1\0\2\75\2\0\2\75\1\0\4\75\5\0"+ - "\1\75\1\0\2\75\223\0\1\107\2\0\1\107\23\0"+ - "\4\107\201\0\1\31\132\0\1\31\207\0\1\31\45\0"+ - "\1\107\21\0\1\31\142\0\1\31\11\0\1\107\44\0"+ - "\1\107\1\0\2\107\21\0\1\107\4\0\1\107\7\0"+ - "\4\107\3\0\1\107\12\0\4\31\4\0\1\107\301\0"+ - "\2\31\264\0\1\107\311\0\4\107\251\0\2\107\15\0"+ - "\4\107\154\0\1\107\15\0\2\107\10\0\2\107\1\0"+ - "\1\107\1\0\1\107\11\0\1\107\11\0\2\107\6\0"+ - "\1\107\2\0\4\107\3\0\1\107\2\0\2\107\1\0"+ - "\3\107\5\0\1\107\1\0\2\107\2\0\2\107\1\0"+ - "\4\107\5\0\1\107\1\0\2\107\141\0\1\30\4\0"+ - "\1\30\11\0\1\30\22\0\1\30\3\0\1\30\13\0"+ - "\1\110\2\0\1\110\10\0\1\30\12\0\4\110\45\0"+ - "\1\30\115\0\1\30\26\0\2\30\23\0\1\31\1\30"+ - "\44\0\1\110\21\0\1\31\142\0\1\31\11\0\1\110"+ - "\15\0\4\30\2\0\2\30\14\0\3\30\1\110\1\0"+ - "\2\110\11\0\3\30\3\0\1\30\1\0\1\110\4\0"+ - "\1\110\2\30\5\0\4\110\2\0\1\30\1\110\12\0"+ - "\4\31\1\0\2\30\1\0\1\110\7\0\1\30\117\0"+ - "\1\30\4\0\1\30\6\0\1\30\3\0\1\30\6\0"+ - "\1\30\5\0\1\30\2\0\2\30\1\0\17\30\2\0"+ - "\1\30\13\0\7\30\2\0\1\30\1\0\1\30\1\0"+ - "\1\30\2\0\1\30\1\0\1\30\1\0\1\30\1\0"+ - "\1\30\4\0\1\110\1\0\2\30\5\0\1\30\1\0"+ - "\1\30\2\0\3\30\1\0\1\30\7\0\1\30\1\0"+ - "\1\30\122\0\1\30\6\0\1\30\3\0\1\30\3\0"+ - "\1\30\7\0\1\30\31\0\20\30\5\0\3\30\3\0"+ - "\1\30\3\0\2\30\2\0\2\30\4\0\1\30\4\110"+ - "\4\0\1\30\4\0\1\30\2\0\1\30\4\0\1\30"+ - "\1\0\1\30\1\0\1\30\223\0\2\110\15\0\4\110"+ - "\154\0\1\110\15\0\2\110\10\0\2\110\1\0\1\110"+ - "\1\0\1\110\11\0\1\110\11\0\2\110\6\0\1\110"+ - "\2\0\4\110\3\0\1\110\2\0\2\110\1\0\3\110"+ - "\5\0\1\110\1\0\2\110\2\0\2\110\1\0\4\110"+ - "\5\0\1\110\1\0\2\110\223\0\1\132\2\0\1\132"+ - "\23\0\4\132\305\0\1\132\176\0\1\132\44\0\1\132"+ - "\1\0\2\132\21\0\1\132\4\0\1\132\7\0\4\132"+ - "\3\0\1\132\22\0\1\132\262\0\1\132\311\0\4\132"+ - "\251\0\2\132\15\0\4\132\154\0\1\132\15\0\2\132"+ - "\10\0\2\132\1\0\1\132\1\0\1\132\11\0\1\132"+ - "\11\0\2\132\6\0\1\132\2\0\4\132\3\0\1\132"+ - "\2\0\2\132\1\0\3\132\5\0\1\132\1\0\2\132"+ - "\2\0\2\132\1\0\4\132\5\0\1\132\1\0\2\132"+ - "\343\0\1\u0109\32\270\1\u010a\12\270\237\0\61\271\1\0"+ - "\1\u010b\4\271\1\u010c\1\0\3\271\1\0\1\53\1\0"+ - "\1\54\2\0\1\55\1\0\1\56\4\0\1\57\1\0"+ - "\1\60\1\0\1\61\2\0\1\62\3\0\1\63\2\0"+ - "\1\64\4\0\1\65\3\0\1\66\17\0\1\67\2\0"+ - "\1\70\21\0\1\71\2\0\1\72\57\0\2\30\1\73"+ - "\1\0\1\74\1\0\1\74\1\75\1\0\1\30\2\0"+ - "\1\30\1\163\1\41\2\u010d\1\u010e\1\u010f\10\u010d\1\41"+ - "\1\u0110\5\u010d\6\41\1\164\12\165\1\74\1\161\1\166"+ - "\1\161\1\0\1\161\1\167\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\2\0\1\53\1\0\1\54\2\0\1\55"+ - "\1\0\1\56\4\0\1\57\1\0\1\60\1\0\1\61"+ - "\2\0\1\62\3\0\1\63\2\0\1\64\4\0\1\65"+ - "\3\0\1\66\17\0\1\67\2\0\1\70\21\0\1\71"+ - "\2\0\1\72\57\0\2\30\1\73\1\0\1\74\1\0"+ - "\1\74\1\75\1\0\1\30\2\0\1\30\1\163\1\u0111"+ - "\2\u010d\1\41\1\u010d\1\u0112\6\u010d\4\41\4\u010d\1\41"+ - "\1\u010d\1\41\3\u010d\1\164\12\165\1\74\1\161\1\166"+ - "\1\161\1\0\1\161\1\167\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\2\0\1\53\1\0\1\54\2\0\1\55"+ - "\1\0\1\56\4\0\1\57\1\0\1\60\1\0\1\61"+ - "\2\0\1\62\3\0\1\63\2\0\1\64\4\0\1\65"+ - "\3\0\1\66\17\0\1\67\2\0\1\70\21\0\1\71"+ - "\2\0\1\72\57\0\2\30\1\73\1\0\1\74\1\0"+ - "\1\74\1\75\1\0\1\30\2\0\1\30\1\163\3\41"+ - "\1\u010d\1\41\1\u010d\4\41\1\u010d\10\41\1\u010d\2\41"+ - "\1\u010d\2\41\1\u010d\1\164\12\165\1\74\1\161\1\166"+ - "\1\161\1\0\1\161\1\167\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\2\0\1\53\1\0\1\54\2\0\1\55"+ - "\1\0\1\56\4\0\1\57\1\0\1\60\1\0\1\61"+ - "\2\0\1\62\3\0\1\63\2\0\1\64\4\0\1\65"+ - "\3\0\1\66\17\0\1\67\2\0\1\70\21\0\1\71"+ - "\2\0\1\72\57\0\2\30\1\73\1\0\1\74\1\0"+ - "\1\74\1\75\1\0\1\30\2\0\1\30\1\163\1\41"+ - "\1\u010d\1\u0113\2\u010d\2\41\1\u010d\6\41\3\u010d\11\41"+ - "\1\164\12\165\1\74\1\161\1\166\1\161\1\0\1\161"+ - "\1\167\1\162\3\161\3\0\1\161\4\0\2\161\2\0"+ - "\1\53\1\0\1\54\2\0\1\55\1\0\1\56\4\0"+ - "\1\57\1\0\1\60\1\0\1\61\2\0\1\62\3\0"+ - "\1\63\2\0\1\64\4\0\1\65\3\0\1\66\17\0"+ - "\1\67\2\0\1\70\21\0\1\71\2\0\1\72\57\0"+ - "\2\30\1\73\1\0\1\74\1\0\1\74\1\75\1\0"+ - "\1\30\2\0\1\30\1\163\3\41\1\u010d\1\41\1\u010d"+ - "\10\41\1\u010d\1\41\2\u010d\10\41\1\164\12\165\1\74"+ - "\1\161\1\166\1\161\1\0\1\161\1\167\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\2\0\1\53\1\0\1\54"+ - "\2\0\1\55\1\0\1\56\4\0\1\57\1\0\1\60"+ - "\1\0\1\61\2\0\1\62\3\0\1\63\2\0\1\64"+ - "\4\0\1\65\3\0\1\66\17\0\1\67\2\0\1\70"+ - "\21\0\1\71\2\0\1\72\57\0\2\30\1\73\1\0"+ - "\1\74\1\0\1\74\1\75\1\0\1\30\2\0\1\30"+ - "\1\163\4\41\1\u0114\5\41\1\u010d\17\41\1\164\12\165"+ - "\1\74\1\161\1\166\1\161\1\0\1\161\1\167\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\2\0\1\53\1\0"+ - "\1\54\2\0\1\55\1\0\1\56\4\0\1\57\1\0"+ - "\1\60\1\0\1\61\2\0\1\62\3\0\1\63\2\0"+ - "\1\64\4\0\1\65\3\0\1\66\17\0\1\67\2\0"+ - "\1\70\21\0\1\71\2\0\1\72\57\0\2\30\1\73"+ - "\1\0\1\74\1\0\1\74\1\75\1\0\1\30\2\0"+ - "\1\30\1\163\4\41\2\u010d\2\41\1\u010d\1\41\1\u010d"+ - "\13\41\1\u010d\2\41\1\u010d\1\164\12\165\1\74\1\161"+ - "\1\166\1\161\1\0\1\161\1\167\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\2\0\1\53\1\0\1\54\2\0"+ - "\1\55\1\0\1\56\4\0\1\57\1\0\1\60\1\0"+ - "\1\61\2\0\1\62\3\0\1\63\2\0\1\64\4\0"+ - "\1\65\3\0\1\66\17\0\1\67\2\0\1\70\21\0"+ - "\1\71\2\0\1\72\57\0\2\30\1\73\1\0\1\74"+ - "\1\0\1\74\1\75\1\0\1\30\2\0\1\30\1\163"+ - "\1\u010d\1\41\3\u010d\1\u0115\14\u010d\2\41\2\u010d\2\41"+ - "\1\u010d\1\41\1\164\12\165\1\74\1\161\1\166\1\161"+ - "\1\0\1\161\1\167\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\2\0\1\53\1\0\1\54\2\0\1\55\1\0"+ - "\1\56\4\0\1\57\1\0\1\60\1\0\1\61\2\0"+ - "\1\62\3\0\1\63\2\0\1\64\4\0\1\65\3\0"+ - "\1\66\17\0\1\67\2\0\1\70\21\0\1\71\2\0"+ - "\1\72\57\0\2\30\1\73\1\0\1\74\1\0\1\74"+ - "\1\75\1\0\1\30\2\0\1\30\1\163\2\41\4\u010d"+ - "\3\41\2\u010d\1\u0116\1\u010d\1\41\2\u010d\12\41\1\164"+ - "\12\165\1\74\1\161\1\166\1\161\1\0\1\161\1\167"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\2\0\1\53"+ - "\1\0\1\54\2\0\1\55\1\0\1\56\4\0\1\57"+ - "\1\0\1\60\1\0\1\61\2\0\1\62\3\0\1\63"+ - "\2\0\1\64\4\0\1\65\3\0\1\66\17\0\1\67"+ - "\2\0\1\70\21\0\1\71\2\0\1\72\57\0\2\30"+ - "\1\73\1\0\1\74\1\0\1\74\1\75\1\0\1\30"+ - "\2\0\1\30\1\163\2\u010d\2\41\1\u010d\3\41\1\u010d"+ - "\5\41\3\u010d\3\41\1\u010d\2\41\3\u010d\1\164\12\165"+ - "\1\74\1\161\1\166\1\161\1\0\1\161\1\167\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\2\0\1\53\1\0"+ - "\1\54\2\0\1\55\1\0\1\56\4\0\1\57\1\0"+ - "\1\60\1\0\1\61\2\0\1\62\3\0\1\63\2\0"+ - "\1\64\4\0\1\65\3\0\1\66\17\0\1\67\2\0"+ - "\1\70\21\0\1\71\2\0\1\72\57\0\2\30\1\73"+ - "\1\0\1\74\1\0\1\74\1\75\1\0\1\30\2\0"+ - "\1\30\1\163\5\u010d\1\u0117\1\41\1\u010d\1\u0118\7\u010d"+ - "\1\u0119\3\u010d\1\41\1\u010d\1\41\3\u010d\1\164\12\165"+ - "\1\74\1\161\1\166\1\161\1\0\1\161\1\167\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\2\0\1\53\1\0"+ - "\1\54\2\0\1\55\1\0\1\56\4\0\1\57\1\0"+ - "\1\60\1\0\1\61\2\0\1\62\3\0\1\63\2\0"+ - "\1\64\4\0\1\65\3\0\1\66\17\0\1\67\2\0"+ - "\1\70\21\0\1\71\2\0\1\72\57\0\2\30\1\73"+ - "\1\0\1\74\1\0\1\74\1\75\1\0\1\30\2\0"+ - "\1\30\1\163\1\u011a\1\u010d\1\41\1\u0111\6\u010d\3\41"+ - "\1\u010d\2\41\1\u010d\2\41\1\u010d\6\41\1\164\12\165"+ - "\1\74\1\161\1\166\1\161\1\0\1\161\1\167\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\2\0\1\53\1\0"+ - "\1\54\2\0\1\55\1\0\1\56\4\0\1\57\1\0"+ - "\1\60\1\0\1\61\2\0\1\62\3\0\1\63\2\0"+ - "\1\64\4\0\1\65\3\0\1\66\17\0\1\67\2\0"+ - "\1\70\21\0\1\71\2\0\1\72\57\0\2\30\1\73"+ - "\1\0\1\74\1\0\1\74\1\75\1\0\1\30\2\0"+ - "\1\30\1\163\1\u010d\31\41\1\164\12\165\1\74\1\161"+ - "\1\166\1\161\1\0\1\161\1\167\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\2\0\1\53\1\0\1\54\2\0"+ - "\1\55\1\0\1\56\4\0\1\57\1\0\1\60\1\0"+ - "\1\61\2\0\1\62\3\0\1\63\2\0\1\64\4\0"+ - "\1\65\3\0\1\66\17\0\1\67\2\0\1\70\21\0"+ - "\1\71\2\0\1\72\57\0\2\30\1\73\1\0\1\74"+ - "\1\0\1\74\1\75\1\0\1\30\2\0\1\30\1\163"+ - "\1\u010d\2\41\1\u010d\1\u011b\1\41\2\u010d\1\41\3\u010d"+ - "\2\41\2\u010d\1\41\1\u010d\3\41\1\u010d\2\41\2\u010d"+ - "\1\164\12\165\1\74\1\161\1\166\1\161\1\0\1\161"+ - "\1\167\1\162\3\161\3\0\1\161\4\0\2\161\2\0"+ - "\1\53\1\0\1\54\2\0\1\55\1\0\1\56\4\0"+ - "\1\57\1\0\1\60\1\0\1\61\2\0\1\62\3\0"+ - "\1\63\2\0\1\64\4\0\1\65\3\0\1\66\17\0"+ - "\1\67\2\0\1\70\21\0\1\71\2\0\1\72\57\0"+ - "\2\30\1\73\1\0\1\74\1\0\1\74\1\75\1\0"+ - "\1\30\2\0\1\30\1\163\6\u010d\1\41\5\u010d\3\41"+ - "\2\u010d\1\41\10\u010d\1\164\12\165\1\74\1\161\1\166"+ - "\1\161\1\0\1\161\1\167\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\2\0\1\53\1\0\1\54\2\0\1\55"+ - "\1\0\1\56\4\0\1\57\1\0\1\60\1\0\1\61"+ - "\2\0\1\62\3\0\1\63\2\0\1\64\4\0\1\65"+ - "\3\0\1\66\17\0\1\67\2\0\1\70\21\0\1\71"+ - "\2\0\1\72\57\0\2\30\1\73\1\0\1\74\1\0"+ - "\1\74\1\75\1\0\1\30\2\0\1\30\1\163\1\41"+ - "\2\u010d\1\u0118\1\u011c\3\u010d\1\41\3\u010d\1\41\1\u010d"+ - "\1\41\1\u010d\1\41\1\u010d\1\41\1\u010d\1\41\3\u010d"+ - "\1\41\1\u010d\1\164\12\165\1\74\1\161\1\166\1\161"+ - "\1\0\1\161\1\167\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\2\0\1\53\1\0\1\54\2\0\1\55\1\0"+ - "\1\56\4\0\1\57\1\0\1\60\1\0\1\61\2\0"+ - "\1\62\3\0\1\63\2\0\1\64\4\0\1\65\3\0"+ - "\1\66\17\0\1\67\2\0\1\70\21\0\1\71\2\0"+ - "\1\72\57\0\2\30\1\73\1\0\1\74\1\0\1\74"+ - "\1\75\1\0\1\30\2\0\1\30\1\163\1\u010d\6\41"+ - "\1\u010d\6\41\1\u010d\4\41\1\u010d\4\41\2\u010d\1\164"+ - "\12\165\1\74\1\161\1\166\1\161\1\0\1\161\1\167"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\2\0\1\53"+ - "\1\0\1\54\2\0\1\55\1\0\1\56\4\0\1\57"+ - "\1\0\1\60\1\0\1\61\2\0\1\62\3\0\1\63"+ - "\2\0\1\64\4\0\1\65\3\0\1\66\17\0\1\67"+ - "\2\0\1\70\21\0\1\71\2\0\1\72\57\0\2\30"+ - "\1\73\1\0\1\74\1\0\1\74\1\75\1\0\1\30"+ - "\2\0\1\30\1\163\6\41\1\u010d\7\41\1\u010d\13\41"+ - "\1\164\12\165\1\74\1\161\1\166\1\161\1\0\1\161"+ - "\1\167\1\162\3\161\3\0\1\161\4\0\2\161\2\0"+ - "\1\53\1\0\1\54\2\0\1\55\1\0\1\56\4\0"+ - "\1\57\1\0\1\60\1\0\1\61\2\0\1\62\3\0"+ - "\1\63\2\0\1\64\4\0\1\65\3\0\1\66\17\0"+ - "\1\67\2\0\1\70\21\0\1\71\2\0\1\72\57\0"+ - "\2\30\1\73\1\0\1\74\1\0\1\74\1\75\1\0"+ - "\1\30\2\0\1\30\1\163\13\41\1\u011d\6\41\1\u011e"+ - "\7\41\1\164\12\165\1\74\1\161\1\166\1\161\1\0"+ - "\1\161\1\167\1\162\3\161\3\0\1\161\4\0\2\161"+ - "\2\0\1\53\1\0\1\54\2\0\1\55\1\0\1\56"+ - "\4\0\1\57\1\0\1\60\1\0\1\61\2\0\1\62"+ - "\3\0\1\63\2\0\1\64\4\0\1\65\3\0\1\66"+ - "\17\0\1\67\2\0\1\70\21\0\1\71\2\0\1\72"+ - "\57\0\2\30\1\73\1\0\1\74\1\0\1\74\1\75"+ - "\1\0\1\30\2\0\1\30\1\163\1\u010d\11\41\1\u010d"+ - "\6\41\1\u010d\10\41\1\164\12\165\1\74\1\161\1\166"+ - "\1\161\1\0\1\161\1\167\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\2\0\1\53\1\0\1\54\2\0\1\55"+ - "\1\0\1\56\4\0\1\57\1\0\1\60\1\0\1\61"+ - "\2\0\1\62\3\0\1\63\2\0\1\64\4\0\1\65"+ - "\3\0\1\66\17\0\1\67\2\0\1\70\21\0\1\71"+ - "\2\0\1\72\57\0\2\30\1\73\1\0\1\74\1\0"+ - "\1\74\1\75\1\0\1\30\2\0\1\30\1\163\1\u010d"+ - "\1\41\6\u010d\1\u011f\1\41\2\u010d\2\41\2\u010d\1\41"+ - "\1\u010d\1\41\6\u010d\1\41\1\164\12\165\1\74\1\161"+ - "\1\166\1\161\1\0\1\161\1\167\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\2\0\1\53\1\0\1\54\2\0"+ - "\1\55\1\0\1\56\4\0\1\57\1\0\1\60\1\0"+ - "\1\61\2\0\1\62\3\0\1\63\2\0\1\64\4\0"+ - "\1\65\3\0\1\66\17\0\1\67\2\0\1\70\21\0"+ - "\1\71\2\0\1\72\57\0\2\30\1\73\1\0\1\74"+ - "\1\0\1\74\1\75\1\0\1\30\2\0\1\30\1\163"+ - "\4\41\1\u010d\5\41\2\u010d\3\41\2\u010d\10\41\1\u010d"+ - "\1\164\12\165\1\74\1\161\1\166\1\161\1\0\1\161"+ - "\1\167\1\162\3\161\3\0\1\161\4\0\2\161\2\0"+ - "\1\53\1\0\1\54\2\0\1\55\1\0\1\56\4\0"+ - "\1\57\1\0\1\60\1\0\1\61\2\0\1\62\3\0"+ - "\1\63\2\0\1\64\4\0\1\65\3\0\1\66\17\0"+ - "\1\67\2\0\1\70\21\0\1\71\2\0\1\72\57\0"+ - "\2\30\1\73\1\0\1\74\1\0\1\74\1\75\1\0"+ - "\1\30\2\0\1\30\1\163\3\41\1\u010d\1\41\1\u0120"+ - "\4\41\1\u010d\2\41\1\u010d\14\41\1\164\12\165\1\74"+ - "\1\161\1\166\1\161\1\0\1\161\1\167\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\2\0\1\53\1\0\1\54"+ - "\2\0\1\55\1\0\1\56\4\0\1\57\1\0\1\60"+ - "\1\0\1\61\2\0\1\62\3\0\1\63\2\0\1\64"+ - "\4\0\1\65\3\0\1\66\17\0\1\67\2\0\1\70"+ - "\21\0\1\71\2\0\1\72\57\0\2\30\1\73\1\0"+ - "\1\74\1\0\1\74\1\75\1\0\1\30\2\0\1\30"+ - "\1\163\2\u010d\1\41\1\u010d\3\41\2\u010d\2\41\1\u010d"+ - "\4\41\1\u010d\11\41\1\164\12\165\1\74\1\161\1\166"+ - "\1\161\1\0\1\161\1\167\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\2\0\1\53\1\0\1\54\2\0\1\55"+ - "\1\0\1\56\4\0\1\57\1\0\1\60\1\0\1\61"+ - "\2\0\1\62\3\0\1\63\2\0\1\64\4\0\1\65"+ - "\3\0\1\66\17\0\1\67\2\0\1\70\21\0\1\71"+ - "\2\0\1\72\57\0\2\30\1\73\1\0\1\74\1\0"+ - "\1\74\1\75\1\0\1\30\2\0\1\30\1\163\3\41"+ - "\1\u010d\13\41\1\u010d\12\41\1\164\12\165\1\74\1\161"+ - "\1\166\1\161\1\0\1\161\1\167\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\2\0\1\53\1\0\1\54\2\0"+ - "\1\55\1\0\1\56\4\0\1\57\1\0\1\60\1\0"+ - "\1\61\2\0\1\62\3\0\1\63\2\0\1\64\4\0"+ - "\1\65\3\0\1\66\17\0\1\67\2\0\1\70\21\0"+ - "\1\71\2\0\1\72\57\0\2\30\1\73\1\0\1\74"+ - "\1\0\1\74\1\75\1\0\1\30\2\0\1\30\1\163"+ - "\3\41\2\u010d\2\41\2\u010d\1\41\2\u010d\1\41\1\u010d"+ - "\3\41\1\u010d\1\41\1\u010d\1\41\1\u010d\2\41\1\u010d"+ - "\1\41\1\164\12\165\1\74\1\161\1\166\1\161\1\0"+ - "\1\161\1\167\1\162\3\161\3\0\1\161\4\0\2\161"+ - "\212\0\1\u0121\32\324\1\164\12\324\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\4\0\2\161\7\0"+ - "\1\u0100\1\0\1\u0101\17\0\1\u0102\2\0\1\u0103\4\0"+ - "\1\u0104\3\0\1\u0105\22\0\1\u0106\21\0\1\u0107\2\0"+ - "\1\u0108\60\0\1\220\1\73\6\0\1\220\3\0\1\160"+ - "\1\334\1\335\1\336\1\337\1\340\1\341\1\342\1\343"+ - "\1\344\1\345\1\346\1\347\1\350\1\351\1\352\1\353"+ - "\1\354\1\355\1\356\1\357\1\360\1\361\1\362\1\363"+ - "\1\364\1\365\1\161\12\165\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\1\206\3\0\2\161\7\0"+ - "\1\u0100\1\0\1\u0101\17\0\1\u0102\2\0\1\u0103\4\0"+ - "\1\u0104\3\0\1\u0105\22\0\1\u0106\21\0\1\u0107\2\0"+ - "\1\u0108\60\0\1\220\1\73\6\0\1\220\3\0\1\160"+ - "\33\161\12\327\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\2\0\1\53\1\0\1\54"+ - "\2\0\1\211\1\0\1\56\4\0\1\57\1\0\1\60"+ - "\1\0\1\61\2\0\1\62\3\0\1\212\2\0\1\213"+ - "\4\0\1\65\3\0\1\214\17\0\1\67\2\0\1\215"+ - "\21\0\1\216\2\0\1\217\57\0\1\30\2\73\2\0"+ - "\2\220\1\75\1\0\1\73\2\0\1\30\1\u0122\32\201"+ - "\1\161\12\327\1\0\1\161\1\166\1\161\1\0\2\326"+ - "\1\162\3\161\2\0\1\220\1\161\4\0\2\161\2\0"+ - "\1\53\1\0\1\54\2\0\1\55\1\0\1\56\4\0"+ - "\1\57\1\0\1\60\1\0\1\61\2\0\1\62\3\0"+ - "\1\63\2\0\1\64\4\0\1\65\3\0\1\66\17\0"+ - "\1\67\2\0\1\70\21\0\1\71\2\0\1\72\57\0"+ - "\2\30\1\73\1\0\1\74\1\0\1\74\1\75\1\0"+ - "\1\30\2\0\1\30\1\163\3\41\1\u0123\26\41\1\164"+ - "\12\165\1\74\1\161\1\166\1\161\1\0\1\161\1\167"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\2\0\1\53"+ - "\1\0\1\54\2\0\1\55\1\0\1\56\4\0\1\57"+ - "\1\0\1\60\1\0\1\61\2\0\1\62\3\0\1\63"+ - "\2\0\1\64\4\0\1\65\3\0\1\66\17\0\1\67"+ - "\2\0\1\70\21\0\1\71\2\0\1\72\57\0\2\30"+ - "\1\73\1\0\1\74\1\0\1\74\1\75\1\0\1\30"+ - "\2\0\1\30\1\163\32\41\1\164\12\165\1\u0124\1\161"+ - "\1\166\1\161\1\0\1\161\1\167\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\2\0\1\53\1\0\1\54\2\0"+ - "\1\55\1\0\1\56\4\0\1\57\1\0\1\60\1\0"+ - "\1\61\2\0\1\62\3\0\1\63\2\0\1\64\4\0"+ - "\1\65\3\0\1\66\17\0\1\67\2\0\1\70\21\0"+ - "\1\71\2\0\1\72\57\0\2\30\1\73\1\0\1\74"+ - "\1\0\1\74\1\75\1\0\1\30\2\0\1\30\1\163"+ - "\11\41\1\u0125\20\41\1\164\12\165\1\74\1\161\1\166"+ - "\1\161\1\0\1\161\1\167\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\2\0\1\53\1\0\1\54\2\0\1\55"+ - "\1\0\1\56\4\0\1\57\1\0\1\60\1\0\1\61"+ - "\2\0\1\62\3\0\1\63\2\0\1\64\4\0\1\65"+ - "\3\0\1\66\17\0\1\67\2\0\1\70\21\0\1\71"+ - "\2\0\1\72\57\0\2\30\1\73\1\0\1\74\1\0"+ - "\1\74\1\75\1\0\1\30\2\0\1\30\1\163\15\41"+ - "\1\u0126\14\41\1\164\12\165\1\74\1\161\1\166\1\161"+ - "\1\0\1\161\1\167\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0121\1\324\2\u0127\1\u0128\1\u0129\10\u0127"+ - "\1\324\1\u012a\5\u0127\6\324\1\164\12\324\1\0\3\161"+ - "\1\0\2\161\1\162\3\161\3\0\1\161\4\0\2\161"+ - "\212\0\1\u0121\1\u012b\2\u0127\1\324\1\u0127\1\u012c\6\u0127"+ - "\4\324\4\u0127\1\324\1\u0127\1\324\3\u0127\1\164\12\324"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\212\0\1\u0121\3\324\1\u0127\1\324\1\u0127"+ - "\4\324\1\u0127\10\324\1\u0127\2\324\1\u0127\2\324\1\u0127"+ - "\1\164\12\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\1\324\1\u0127"+ - "\1\u012d\2\u0127\2\324\1\u0127\6\324\3\u0127\11\324\1\164"+ - "\12\324\1\0\3\161\1\0\2\161\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\212\0\1\u0121\3\324\1\u0127\1\324"+ - "\1\u0127\10\324\1\u0127\1\324\2\u0127\10\324\1\164\12\324"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\212\0\1\u0121\4\324\1\u012e\5\324\1\u0127"+ - "\17\324\1\164\12\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121\4\324"+ - "\2\u0127\2\324\1\u0127\1\324\1\u0127\13\324\1\u0127\2\324"+ - "\1\u0127\1\164\12\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121\1\u0127"+ - "\1\324\3\u0127\1\u012f\14\u0127\2\324\2\u0127\2\324\1\u0127"+ - "\1\324\1\164\12\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121\2\324"+ - "\4\u0127\3\324\2\u0127\1\u0130\1\u0127\1\324\2\u0127\12\324"+ - "\1\164\12\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\2\u0127\2\324"+ - "\1\u0127\3\324\1\u0127\5\324\3\u0127\3\324\1\u0127\2\324"+ - "\3\u0127\1\164\12\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121\5\u0127"+ - "\1\u0131\1\324\1\u0127\1\u0132\7\u0127\1\u0133\3\u0127\1\324"+ - "\1\u0127\1\324\3\u0127\1\164\12\324\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\4\0\2\161\212\0"+ - "\1\u0121\1\u0134\1\u0127\1\324\1\u012b\6\u0127\3\324\1\u0127"+ - "\2\324\1\u0127\2\324\1\u0127\6\324\1\164\12\324\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0121\1\u0127\31\324\1\164\12\324\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0121\1\u0127\2\324\1\u0127\1\u0135\1\324"+ - "\2\u0127\1\324\3\u0127\2\324\2\u0127\1\324\1\u0127\3\324"+ - "\1\u0127\2\324\2\u0127\1\164\12\324\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\4\0\2\161\212\0"+ - "\1\u0121\6\u0127\1\324\5\u0127\3\324\2\u0127\1\324\10\u0127"+ - "\1\164\12\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\1\324\2\u0127"+ - "\1\u0132\1\u0136\3\u0127\1\324\3\u0127\1\324\1\u0127\1\324"+ - "\1\u0127\1\324\1\u0127\1\324\1\u0127\1\324\3\u0127\1\324"+ - "\1\u0127\1\164\12\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121\1\u0127"+ - "\6\324\1\u0127\6\324\1\u0127\4\324\1\u0127\4\324\2\u0127"+ - "\1\164\12\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\6\324\1\u0127"+ - "\7\324\1\u0127\13\324\1\164\12\324\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\4\0\2\161\212\0"+ - "\1\u0121\13\324\1\u0137\6\324\1\u0138\7\324\1\164\12\324"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\212\0\1\u0121\1\u0127\11\324\1\u0127\6\324"+ - "\1\u0127\10\324\1\164\12\324\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121"+ - "\1\u0127\1\324\6\u0127\1\u0139\1\324\2\u0127\2\324\2\u0127"+ - "\1\324\1\u0127\1\324\6\u0127\1\324\1\164\12\324\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0121\4\324\1\u0127\5\324\2\u0127\3\324"+ - "\2\u0127\10\324\1\u0127\1\164\12\324\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\4\0\2\161\212\0"+ - "\1\u0121\3\324\1\u0127\1\324\1\u013a\4\324\1\u0127\2\324"+ - "\1\u0127\14\324\1\164\12\324\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121"+ - "\2\u0127\1\324\1\u0127\3\324\2\u0127\2\324\1\u0127\4\324"+ - "\1\u0127\11\324\1\164\12\324\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121"+ - "\3\324\1\u0127\13\324\1\u0127\12\324\1\164\12\324\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0121\3\324\2\u0127\2\324\2\u0127\1\324"+ - "\2\u0127\1\324\1\u0127\3\324\1\u0127\1\324\1\u0127\1\324"+ - "\1\u0127\2\324\1\u0127\1\324\1\164\12\324\1\0\3\161"+ - "\1\0\2\161\1\162\3\161\3\0\1\161\4\0\2\161"+ - "\2\0\1\53\1\0\1\54\2\0\1\76\1\0\1\77"+ - "\4\0\1\57\1\0\1\60\1\0\1\61\2\0\1\62"+ - "\3\0\1\100\2\0\1\101\4\0\1\102\3\0\1\103"+ - "\17\0\1\67\2\0\1\104\21\0\1\105\2\0\1\106"+ - "\57\0\1\30\2\31\2\0\2\107\1\110\1\0\1\31"+ - "\2\0\1\30\1\u013b\32\41\1\164\12\367\1\0\1\161"+ - "\1\175\1\161\1\0\2\176\1\162\3\161\2\0\1\107"+ - "\1\161\4\0\2\161\2\0\1\53\1\0\1\54\2\0"+ - "\1\76\1\0\1\77\4\0\1\57\1\0\1\60\1\0"+ - "\1\61\2\0\1\62\3\0\1\100\2\0\1\101\4\0"+ - "\1\102\3\0\1\103\17\0\1\67\2\0\1\104\21\0"+ - "\1\105\2\0\1\106\57\0\1\30\2\31\2\0\2\107"+ - "\1\110\1\0\1\31\2\0\1\30\1\u013b\32\41\1\164"+ - "\12\u013c\1\0\1\161\1\175\1\161\1\0\2\176\1\162"+ - "\3\161\2\0\1\107\1\161\4\0\2\161\2\0\1\53"+ - "\1\0\1\54\2\0\1\76\1\0\1\77\4\0\1\57"+ - "\1\0\1\60\1\0\1\61\2\0\1\62\3\0\1\100"+ - "\2\0\1\101\4\0\1\102\3\0\1\103\17\0\1\67"+ - "\2\0\1\104\21\0\1\105\2\0\1\106\57\0\1\30"+ - "\2\31\2\0\2\107\1\110\1\0\1\31\2\0\1\30"+ - "\1\u013b\32\41\1\164\1\367\1\u013d\1\u013c\2\367\2\u013c"+ - "\1\367\1\u013c\1\367\1\0\1\161\1\175\1\161\1\0"+ - "\2\176\1\162\3\161\2\0\1\107\1\161\4\0\2\161"+ - "\2\0\1\53\1\0\1\54\2\0\1\76\1\0\1\77"+ - "\4\0\1\57\1\0\1\60\1\0\1\61\2\0\1\62"+ - "\3\0\1\100\2\0\1\101\4\0\1\102\3\0\1\103"+ - "\17\0\1\67\2\0\1\104\21\0\1\105\2\0\1\106"+ - "\57\0\1\30\2\31\2\0\2\107\1\110\1\0\1\31"+ - "\2\0\1\30\1\u013e\32\41\1\164\12\371\1\0\1\161"+ - "\1\175\1\161\1\0\2\176\1\162\3\161\2\0\1\107"+ - "\1\161\4\0\2\161\2\0\1\53\1\0\1\54\2\0"+ - "\1\221\1\0\1\222\4\0\1\57\1\0\1\60\1\0"+ - "\1\61\2\0\1\62\3\0\1\223\2\0\1\224\4\0"+ - "\1\225\3\0\1\226\17\0\1\67\2\0\1\227\21\0"+ - "\1\230\2\0\1\231\57\0\1\30\1\74\7\0\1\74"+ - "\2\0\1\30\1\160\32\201\13\161\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\1\206\3\0\2\161"+ - "\7\0\1\241\1\0\1\242\17\0\1\243\2\0\1\244"+ - "\4\0\1\245\3\0\1\246\22\0\1\247\21\0\1\250"+ - "\2\0\1\251\60\0\1\107\1\31\6\0\1\107\3\0"+ - "\1\160\33\161\12\202\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\1\206\3\0\2\161\213\0\4\u013f"+ - "\2\0\1\u013f\15\0\1\u013f\6\0\12\u013f\1\375\237\0"+ - "\4\u0140\2\0\1\u0140\15\0\1\u0140\6\0\12\u0140\1\u0141"+ - "\237\0\4\u0142\2\0\1\u0142\15\0\1\u0142\6\0\1\u0143"+ - "\2\u0144\1\u0143\5\u0144\1\u0145\14\0\1\u0146\222\0\46\161"+ - "\1\0\3\161\1\0\2\161\1\0\3\161\3\0\1\161"+ - "\1\206\3\0\2\161\72\0\1\220\2\0\1\220\23\0"+ - "\4\220\201\0\1\73\132\0\1\73\207\0\1\73\45\0"+ - "\1\220\21\0\1\73\142\0\1\73\11\0\1\220\44\0"+ - "\1\220\1\0\2\220\21\0\1\220\4\0\1\220\7\0"+ - "\4\220\3\0\1\220\12\0\4\73\4\0\1\220\301\0"+ - "\2\73\264\0\1\220\311\0\4\220\251\0\2\220\15\0"+ - "\4\220\154\0\1\220\15\0\2\220\10\0\2\220\1\0"+ - "\1\220\1\0\1\220\11\0\1\220\11\0\2\220\6\0"+ - "\1\220\2\0\4\220\3\0\1\220\2\0\2\220\1\0"+ - "\3\220\5\0\1\220\1\0\2\220\2\0\2\220\1\0"+ - "\4\220\5\0\1\220\1\0\2\220\344\0\1\u0147\1\u0148"+ - "\1\u0149\1\u014a\1\u014b\1\u014c\1\u014d\1\u014e\1\u014f\1\u0150"+ - "\1\u0151\1\u0152\1\u0153\1\u0154\1\u0155\1\u0156\1\u0157\1\u0158"+ - "\1\u0159\1\u015a\1\u015b\1\u015c\1\u015d\1\u015e\1\u015f\1\u0160"+ - "\1\0\12\270\240\0\32\270\1\u010a\12\270\237\0\74\271"+ - "\1\0\1\53\1\0\1\54\2\0\1\55\1\0\1\56"+ - "\4\0\1\57\1\0\1\60\1\0\1\61\2\0\1\62"+ - "\3\0\1\63\2\0\1\64\4\0\1\65\3\0\1\66"+ - "\17\0\1\67\2\0\1\70\21\0\1\71\2\0\1\72"+ - "\57\0\2\30\1\73\1\0\1\74\1\0\1\74\1\75"+ - "\1\0\1\30\2\0\1\30\1\u0161\32\41\1\164\12\165"+ - "\1\u0162\1\161\1\166\1\161\1\0\1\161\1\167\1\162"+ - "\1\u0163\1\u0164\1\u0165\3\0\1\161\4\0\2\161\2\0"+ - "\1\53\1\0\1\54\2\0\1\55\1\0\1\56\4\0"+ - "\1\57\1\0\1\60\1\0\1\61\2\0\1\62\3\0"+ - "\1\63\2\0\1\64\4\0\1\65\3\0\1\66\17\0"+ - "\1\67\2\0\1\70\21\0\1\71\2\0\1\72\57\0"+ - "\2\30\1\73\1\0\1\74\1\0\1\74\1\75\1\0"+ - "\1\30\2\0\1\30\1\u0161\4\41\1\u0166\25\41\1\164"+ - "\12\165\1\u0162\1\161\1\166\1\161\1\0\1\161\1\167"+ - "\1\162\1\u0163\1\u0164\1\u0165\3\0\1\161\4\0\2\161"+ - "\2\0\1\53\1\0\1\54\2\0\1\55\1\0\1\56"+ - "\4\0\1\57\1\0\1\60\1\0\1\61\2\0\1\62"+ - "\3\0\1\63\2\0\1\64\4\0\1\65\3\0\1\66"+ - "\17\0\1\67\2\0\1\70\21\0\1\71\2\0\1\72"+ - "\57\0\2\30\1\73\1\0\1\74\1\0\1\74\1\75"+ - "\1\0\1\30\2\0\1\30\1\u0161\15\41\1\306\14\41"+ - "\1\164\12\165\1\u0162\1\161\1\166\1\161\1\0\1\161"+ - "\1\167\1\162\1\u0163\1\u0164\1\u0165\3\0\1\161\4\0"+ - "\2\161\2\0\1\53\1\0\1\54\2\0\1\55\1\0"+ - "\1\56\4\0\1\57\1\0\1\60\1\0\1\61\2\0"+ - "\1\62\3\0\1\63\2\0\1\64\4\0\1\65\3\0"+ - "\1\66\17\0\1\67\2\0\1\70\21\0\1\71\2\0"+ - "\1\72\57\0\2\30\1\73\1\0\1\74\1\0\1\74"+ - "\1\75\1\0\1\30\2\0\1\30\1\u0161\10\41\1\306"+ - "\21\41\1\164\12\165\1\u0162\1\161\1\166\1\161\1\0"+ - "\1\161\1\167\1\162\1\u0163\1\u0164\1\u0165\3\0\1\161"+ - "\4\0\2\161\2\0\1\53\1\0\1\54\2\0\1\55"+ - "\1\0\1\56\4\0\1\57\1\0\1\60\1\0\1\61"+ - "\2\0\1\62\3\0\1\63\2\0\1\64\4\0\1\65"+ - "\3\0\1\66\17\0\1\67\2\0\1\70\21\0\1\71"+ - "\2\0\1\72\57\0\2\30\1\73\1\0\1\74\1\0"+ - "\1\74\1\75\1\0\1\30\2\0\1\30\1\u0161\17\41"+ - "\1\u010d\12\41\1\164\12\165\1\u0162\1\161\1\166\1\161"+ - "\1\0\1\161\1\167\1\162\1\u0163\1\u0164\1\u0165\3\0"+ - "\1\161\4\0\2\161\2\0\1\53\1\0\1\54\2\0"+ - "\1\55\1\0\1\56\4\0\1\57\1\0\1\60\1\0"+ - "\1\61\2\0\1\62\3\0\1\63\2\0\1\64\4\0"+ - "\1\65\3\0\1\66\17\0\1\67\2\0\1\70\21\0"+ - "\1\71\2\0\1\72\57\0\2\30\1\73\1\0\1\74"+ - "\1\0\1\74\1\75\1\0\1\30\2\0\1\30\1\u0161"+ - "\5\41\1\u0167\4\41\1\u010d\17\41\1\164\12\165\1\u0162"+ - "\1\161\1\166\1\161\1\0\1\161\1\167\1\162\1\u0163"+ - "\1\u0164\1\u0165\3\0\1\161\4\0\2\161\2\0\1\53"+ - "\1\0\1\54\2\0\1\55\1\0\1\56\4\0\1\57"+ - "\1\0\1\60\1\0\1\61\2\0\1\62\3\0\1\63"+ - "\2\0\1\64\4\0\1\65\3\0\1\66\17\0\1\67"+ - "\2\0\1\70\21\0\1\71\2\0\1\72\57\0\2\30"+ - "\1\73\1\0\1\74\1\0\1\74\1\75\1\0\1\30"+ - "\2\0\1\30\1\163\20\41\1\u010d\11\41\1\164\12\165"+ - "\1\74\1\161\1\166\1\161\1\0\1\161\1\167\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\2\0\1\53\1\0"+ - "\1\54\2\0\1\55\1\0\1\56\4\0\1\57\1\0"+ - "\1\60\1\0\1\61\2\0\1\62\3\0\1\63\2\0"+ - "\1\64\4\0\1\65\3\0\1\66\17\0\1\67\2\0"+ - "\1\70\21\0\1\71\2\0\1\72\57\0\2\30\1\73"+ - "\1\0\1\74\1\0\1\74\1\75\1\0\1\30\2\0"+ - "\1\30\1\163\7\41\1\u010d\22\41\1\164\12\165\1\74"+ - "\1\161\1\166\1\161\1\0\1\161\1\167\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\2\0\1\53\1\0\1\54"+ - "\2\0\1\55\1\0\1\56\4\0\1\57\1\0\1\60"+ - "\1\0\1\61\2\0\1\62\3\0\1\63\2\0\1\64"+ - "\4\0\1\65\3\0\1\66\17\0\1\67\2\0\1\70"+ - "\21\0\1\71\2\0\1\72\57\0\2\30\1\73\1\0"+ - "\1\74\1\0\1\74\1\75\1\0\1\30\2\0\1\30"+ - "\1\163\27\41\1\u010d\2\41\1\164\12\165\1\74\1\161"+ - "\1\166\1\161\1\0\1\161\1\167\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\2\0\1\53\1\0\1\54\2\0"+ - "\1\55\1\0\1\56\4\0\1\57\1\0\1\60\1\0"+ - "\1\61\2\0\1\62\3\0\1\63\2\0\1\64\4\0"+ - "\1\65\3\0\1\66\17\0\1\67\2\0\1\70\21\0"+ - "\1\71\2\0\1\72\57\0\2\30\1\73\1\0\1\74"+ - "\1\0\1\74\1\75\1\0\1\30\2\0\1\30\1\u0161"+ - "\6\41\1\u0166\10\41\1\u010d\12\41\1\164\12\165\1\u0162"+ - "\1\161\1\166\1\161\1\0\1\161\1\167\1\162\1\u0163"+ - "\1\u0164\1\u0165\3\0\1\161\4\0\2\161\2\0\1\53"+ - "\1\0\1\54\2\0\1\55\1\0\1\56\4\0\1\57"+ - "\1\0\1\60\1\0\1\61\2\0\1\62\3\0\1\63"+ - "\2\0\1\64\4\0\1\65\3\0\1\66\17\0\1\67"+ - "\2\0\1\70\21\0\1\71\2\0\1\72\57\0\2\30"+ - "\1\73\1\0\1\74\1\0\1\74\1\75\1\0\1\30"+ - "\2\0\1\30\1\u0161\24\41\1\u0168\5\41\1\164\12\165"+ - "\1\u0162\1\161\1\166\1\161\1\0\1\161\1\167\1\162"+ - "\1\u0163\1\u0164\1\u0165\3\0\1\161\4\0\2\161\2\0"+ - "\1\53\1\0\1\54\2\0\1\55\1\0\1\56\4\0"+ - "\1\57\1\0\1\60\1\0\1\61\2\0\1\62\3\0"+ - "\1\63\2\0\1\64\4\0\1\65\3\0\1\66\17\0"+ - "\1\67\2\0\1\70\21\0\1\71\2\0\1\72\57\0"+ - "\2\30\1\73\1\0\1\74\1\0\1\74\1\75\1\0"+ - "\1\30\2\0\1\30\1\163\11\41\1\u010d\20\41\1\164"+ - "\12\165\1\74\1\161\1\166\1\161\1\0\1\161\1\167"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\2\0\1\53"+ - "\1\0\1\54\2\0\1\55\1\0\1\56\4\0\1\57"+ - "\1\0\1\60\1\0\1\61\2\0\1\62\3\0\1\63"+ - "\2\0\1\64\4\0\1\65\3\0\1\66\17\0\1\67"+ - "\2\0\1\70\21\0\1\71\2\0\1\72\57\0\2\30"+ - "\1\73\1\0\1\74\1\0\1\74\1\75\1\0\1\30"+ - "\2\0\1\30\1\u0161\16\41\1\u0169\13\41\1\164\12\165"+ - "\1\u0162\1\161\1\166\1\161\1\0\1\161\1\167\1\162"+ - "\1\u0163\1\u0164\1\u0165\3\0\1\161\4\0\2\161\2\0"+ - "\1\53\1\0\1\54\2\0\1\55\1\0\1\56\4\0"+ - "\1\57\1\0\1\60\1\0\1\61\2\0\1\62\3\0"+ - "\1\63\2\0\1\64\4\0\1\65\3\0\1\66\17\0"+ - "\1\67\2\0\1\70\21\0\1\71\2\0\1\72\57\0"+ - "\2\30\1\73\1\0\1\74\1\0\1\74\1\75\1\0"+ - "\1\30\2\0\1\30\1\u0161\12\41\1\u016a\17\41\1\164"+ - "\12\165\1\u0162\1\161\1\166\1\161\1\0\1\161\1\167"+ - "\1\162\1\u0163\1\u0164\1\u0165\3\0\1\161\4\0\2\161"+ - "\2\0\1\53\1\0\1\54\2\0\1\55\1\0\1\56"+ - "\4\0\1\57\1\0\1\60\1\0\1\61\2\0\1\62"+ - "\3\0\1\63\2\0\1\64\4\0\1\65\3\0\1\66"+ - "\17\0\1\67\2\0\1\70\21\0\1\71\2\0\1\72"+ - "\57\0\2\30\1\73\1\0\1\74\1\0\1\74\1\75"+ - "\1\0\1\30\2\0\1\30\1\u0161\5\41\1\u010d\24\41"+ - "\1\164\12\165\1\u0162\1\161\1\166\1\161\1\0\1\161"+ - "\1\167\1\162\1\u0163\1\u0164\1\u0165\3\0\1\161\4\0"+ - "\2\161\2\0\1\53\1\0\1\54\2\0\1\55\1\0"+ - "\1\56\4\0\1\57\1\0\1\60\1\0\1\61\2\0"+ - "\1\62\3\0\1\63\2\0\1\64\4\0\1\65\3\0"+ - "\1\66\17\0\1\67\2\0\1\70\21\0\1\71\2\0"+ - "\1\72\57\0\2\30\1\73\1\0\1\74\1\0\1\74"+ - "\1\75\1\0\1\30\2\0\1\30\1\u0161\1\u016b\31\41"+ - "\1\164\12\165\1\u0162\1\161\1\166\1\161\1\0\1\161"+ - "\1\167\1\162\1\u0163\1\u0164\1\u0165\3\0\1\161\4\0"+ - "\2\161\2\0\1\53\1\0\1\54\2\0\1\55\1\0"+ - "\1\56\4\0\1\57\1\0\1\60\1\0\1\61\2\0"+ - "\1\62\3\0\1\63\2\0\1\64\4\0\1\65\3\0"+ - "\1\66\17\0\1\67\2\0\1\70\21\0\1\71\2\0"+ - "\1\72\57\0\2\30\1\73\1\0\1\74\1\0\1\74"+ - "\1\75\1\0\1\30\2\0\1\30\1\163\32\41\1\u016c"+ - "\12\165\1\74\1\161\1\166\1\161\1\0\1\161\1\167"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\2\0\1\53"+ - "\1\0\1\54\2\0\1\55\1\0\1\56\4\0\1\57"+ - "\1\0\1\60\1\0\1\61\2\0\1\62\3\0\1\63"+ - "\2\0\1\64\4\0\1\65\3\0\1\66\17\0\1\67"+ - "\2\0\1\70\21\0\1\71\2\0\1\72\57\0\2\30"+ - "\1\73\1\0\1\74\1\0\1\74\1\75\1\0\1\30"+ - "\2\0\1\30\1\163\22\41\1\u010d\7\41\1\164\12\165"+ - "\1\74\1\161\1\166\1\161\1\0\1\161\1\167\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\2\0\1\53\1\0"+ - "\1\54\2\0\1\55\1\0\1\56\4\0\1\57\1\0"+ - "\1\60\1\0\1\61\2\0\1\62\3\0\1\63\2\0"+ - "\1\64\4\0\1\65\3\0\1\66\17\0\1\67\2\0"+ - "\1\70\21\0\1\71\2\0\1\72\57\0\2\30\1\73"+ - "\1\0\1\74\1\0\1\74\1\75\1\0\1\30\2\0"+ - "\1\30\1\u0161\23\41\1\u010d\6\41\1\164\12\165\1\u0162"+ - "\1\161\1\166\1\161\1\0\1\161\1\167\1\162\1\u0163"+ - "\1\u0164\1\u0165\3\0\1\161\4\0\2\161\2\0\1\53"+ - "\1\0\1\54\2\0\1\55\1\0\1\56\4\0\1\57"+ - "\1\0\1\60\1\0\1\61\2\0\1\62\3\0\1\63"+ - "\2\0\1\64\4\0\1\65\3\0\1\66\17\0\1\67"+ - "\2\0\1\70\21\0\1\71\2\0\1\72\57\0\2\30"+ - "\1\73\1\0\1\74\1\0\1\74\1\75\1\0\1\30"+ - "\2\0\1\30\1\u0161\24\41\1\u016d\5\41\1\164\12\165"+ - "\1\u0162\1\161\1\166\1\161\1\0\1\161\1\167\1\162"+ - "\1\u0163\1\u0164\1\u0165\3\0\1\161\4\0\2\161\212\0"+ - "\1\160\1\334\1\335\1\336\1\337\1\340\1\341\1\342"+ - "\1\343\1\344\1\345\1\346\1\347\1\350\1\351\1\352"+ - "\1\353\1\354\1\355\1\356\1\357\1\360\1\361\1\362"+ - "\1\363\1\364\1\365\1\161\12\324\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\1\206\3\0\2\161"+ - "\7\0\1\u0100\1\0\1\u0101\17\0\1\u0102\2\0\1\u0103"+ - "\4\0\1\u0104\3\0\1\u0105\22\0\1\u0106\21\0\1\u0107"+ - "\2\0\1\u0108\60\0\1\220\1\73\6\0\1\220\3\0"+ - "\1\160\33\161\12\327\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\1\206\3\0\2\161\2\0\1\53"+ - "\1\0\1\54\2\0\1\55\1\0\1\56\4\0\1\57"+ - "\1\0\1\60\1\0\1\61\2\0\1\62\3\0\1\63"+ - "\2\0\1\64\4\0\1\65\3\0\1\66\17\0\1\67"+ - "\2\0\1\70\21\0\1\71\2\0\1\72\57\0\2\30"+ - "\1\73\1\0\1\74\1\0\1\74\1\75\1\0\1\30"+ - "\2\0\1\30\1\163\32\41\1\164\12\165\1\u016e\1\161"+ - "\1\166\1\161\1\0\1\161\1\167\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\2\0\1\53\1\0\1\54\2\0"+ - "\1\221\1\0\1\222\4\0\1\57\1\0\1\60\1\0"+ - "\1\61\2\0\1\62\3\0\1\223\2\0\1\224\4\0"+ - "\1\225\3\0\1\226\17\0\1\67\2\0\1\227\21\0"+ - "\1\230\2\0\1\231\57\0\1\30\1\74\7\0\1\74"+ - "\2\0\1\30\1\0\32\30\24\0\1\u016f\15\0\1\53"+ - "\1\0\1\54\2\0\1\55\1\0\1\56\4\0\1\57"+ - "\1\0\1\60\1\0\1\61\2\0\1\62\3\0\1\63"+ - "\2\0\1\64\4\0\1\65\3\0\1\66\17\0\1\67"+ - "\2\0\1\70\21\0\1\71\2\0\1\72\57\0\2\30"+ - "\1\73\1\0\1\74\1\0\1\74\1\75\1\0\1\30"+ - "\2\0\1\30\1\163\17\41\1\u0170\12\41\1\164\12\165"+ - "\1\74\1\161\1\166\1\161\1\0\1\161\1\167\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\2\0\1\53\1\0"+ - "\1\54\2\0\1\55\1\0\1\56\4\0\1\57\1\0"+ - "\1\60\1\0\1\61\2\0\1\62\3\0\1\63\2\0"+ - "\1\64\4\0\1\65\3\0\1\66\17\0\1\67\2\0"+ - "\1\70\21\0\1\71\2\0\1\72\57\0\2\30\1\73"+ - "\1\0\1\74\1\0\1\74\1\75\1\0\1\30\2\0"+ - "\1\30\1\163\16\41\1\u0171\13\41\1\164\12\165\1\u0172"+ - "\1\161\1\166\1\161\1\0\1\161\1\167\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0173\32\324\1\164"+ - "\12\324\1\u0174\3\161\1\0\2\161\1\162\1\u0163\1\u0164"+ - "\1\u0165\3\0\1\161\4\0\2\161\212\0\1\u0173\4\324"+ - "\1\u0175\25\324\1\164\12\324\1\u0174\3\161\1\0\2\161"+ - "\1\162\1\u0163\1\u0164\1\u0165\3\0\1\161\4\0\2\161"+ - "\212\0\1\u0173\15\324\1\350\14\324\1\164\12\324\1\u0174"+ - "\3\161\1\0\2\161\1\162\1\u0163\1\u0164\1\u0165\3\0"+ - "\1\161\4\0\2\161\212\0\1\u0173\10\324\1\350\21\324"+ - "\1\164\12\324\1\u0174\3\161\1\0\2\161\1\162\1\u0163"+ - "\1\u0164\1\u0165\3\0\1\161\4\0\2\161\212\0\1\u0173"+ - "\17\324\1\u0127\12\324\1\164\12\324\1\u0174\3\161\1\0"+ - "\2\161\1\162\1\u0163\1\u0164\1\u0165\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0173\5\324\1\u0176\4\324\1\u0127\17\324"+ - "\1\164\12\324\1\u0174\3\161\1\0\2\161\1\162\1\u0163"+ - "\1\u0164\1\u0165\3\0\1\161\4\0\2\161\212\0\1\u0121"+ - "\20\324\1\u0127\11\324\1\164\12\324\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\4\0\2\161\212\0"+ - "\1\u0121\7\324\1\u0127\22\324\1\164\12\324\1\0\3\161"+ - "\1\0\2\161\1\162\3\161\3\0\1\161\4\0\2\161"+ - "\212\0\1\u0121\27\324\1\u0127\2\324\1\164\12\324\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0173\6\324\1\u0175\10\324\1\u0127\12\324"+ - "\1\164\12\324\1\u0174\3\161\1\0\2\161\1\162\1\u0163"+ - "\1\u0164\1\u0165\3\0\1\161\4\0\2\161\212\0\1\u0173"+ - "\24\324\1\u0177\5\324\1\164\12\324\1\u0174\3\161\1\0"+ - "\2\161\1\162\1\u0163\1\u0164\1\u0165\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0121\11\324\1\u0127\20\324\1\164\12\324"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\212\0\1\u0173\16\324\1\u0178\13\324\1\164"+ - "\12\324\1\u0174\3\161\1\0\2\161\1\162\1\u0163\1\u0164"+ - "\1\u0165\3\0\1\161\4\0\2\161\212\0\1\u0173\12\324"+ - "\1\u0179\17\324\1\164\12\324\1\u0174\3\161\1\0\2\161"+ - "\1\162\1\u0163\1\u0164\1\u0165\3\0\1\161\4\0\2\161"+ - "\212\0\1\u0173\5\324\1\u0127\24\324\1\164\12\324\1\u0174"+ - "\3\161\1\0\2\161\1\162\1\u0163\1\u0164\1\u0165\3\0"+ - "\1\161\4\0\2\161\212\0\1\u0173\1\u017a\31\324\1\164"+ - "\12\324\1\u0174\3\161\1\0\2\161\1\162\1\u0163\1\u0164"+ - "\1\u0165\3\0\1\161\4\0\2\161\212\0\1\u0121\32\324"+ - "\1\u016c\12\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\22\324\1\u0127"+ - "\7\324\1\164\12\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\212\0\1\u0173\23\324"+ - "\1\u0127\6\324\1\164\12\324\1\u0174\3\161\1\0\2\161"+ - "\1\162\1\u0163\1\u0164\1\u0165\3\0\1\161\4\0\2\161"+ - "\212\0\1\u0173\24\324\1\u017b\5\324\1\164\12\324\1\u0174"+ - "\3\161\1\0\2\161\1\162\1\u0163\1\u0164\1\u0165\3\0"+ - "\1\161\4\0\2\161\7\0\1\241\1\0\1\242\17\0"+ - "\1\243\2\0\1\244\4\0\1\245\3\0\1\246\22\0"+ - "\1\247\21\0\1\250\2\0\1\251\60\0\1\107\1\31"+ - "\6\0\1\107\3\0\1\160\1\334\1\335\1\336\1\337"+ - "\1\340\1\341\1\342\1\343\1\344\1\345\1\346\1\347"+ - "\1\350\1\351\1\352\1\353\1\354\1\355\1\356\1\357"+ - "\1\360\1\361\1\362\1\363\1\364\1\365\1\161\1\u017c"+ - "\2\u017d\1\u017c\5\u017d\1\u017e\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\1\206\3\0\2\161\2\0"+ - "\1\53\1\0\1\54\2\0\1\76\1\0\1\77\4\0"+ - "\1\57\1\0\1\60\1\0\1\61\2\0\1\62\3\0"+ - "\1\100\2\0\1\101\4\0\1\102\3\0\1\103\17\0"+ - "\1\67\2\0\1\104\21\0\1\105\2\0\1\106\57\0"+ - "\1\30\2\31\2\0\2\107\1\110\1\0\1\31\2\0"+ - "\1\30\1\u013b\32\41\1\164\12\371\1\0\1\161\1\175"+ - "\1\161\1\0\2\176\1\162\3\161\2\0\1\107\1\161"+ - "\4\0\2\161\2\0\1\53\1\0\1\54\2\0\1\76"+ - "\1\0\1\77\4\0\1\57\1\0\1\60\1\0\1\61"+ - "\2\0\1\62\3\0\1\100\2\0\1\101\4\0\1\102"+ - "\3\0\1\103\17\0\1\67\2\0\1\104\21\0\1\105"+ - "\2\0\1\106\57\0\1\30\2\31\2\0\2\107\1\110"+ - "\1\0\1\31\2\0\1\30\1\u013b\32\41\1\164\2\u013c"+ - "\1\371\2\u013c\2\371\1\u013c\1\371\1\u013c\1\0\1\161"+ - "\1\175\1\161\1\0\2\176\1\162\3\161\2\0\1\107"+ - "\1\161\4\0\2\161\7\0\1\241\1\0\1\242\17\0"+ - "\1\243\2\0\1\244\4\0\1\245\3\0\1\246\22\0"+ - "\1\247\21\0\1\250\2\0\1\251\60\0\1\107\1\31"+ - "\6\0\1\107\3\0\1\160\1\334\1\335\1\336\1\337"+ - "\1\340\1\341\1\342\1\343\1\344\1\345\1\346\1\347"+ - "\1\350\1\351\1\352\1\353\1\354\1\355\1\356\1\357"+ - "\1\360\1\361\1\362\1\363\1\364\1\365\1\161\12\371"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\1\206\3\0\2\161\213\0\4\u017f\2\0\1\u017f\15\0"+ - "\1\u017f\6\0\12\u017f\1\375\237\0\4\u0180\2\0\1\u0180"+ - "\15\0\1\u0180\6\0\12\u0180\1\u0181\237\0\4\u0182\2\0"+ - "\1\u0182\15\0\1\u0182\6\0\1\u0183\2\u0184\1\u0183\5\u0184"+ - "\1\u0185\14\0\1\u0146\223\0\4\u0186\2\0\1\u0186\15\0"+ - "\1\u0186\6\0\12\u0186\1\u0187\13\0\1\u0146\222\0\1\u0188"+ - "\4\u0186\2\0\1\u0186\15\0\1\u0186\6\0\12\u0189\1\u0187"+ - "\13\0\1\u0146\222\0\1\u0188\4\u0186\2\0\1\u0186\15\0"+ - "\1\u0186\6\0\12\u018a\1\u0187\13\0\1\u0146\222\0\1\u0188"+ - "\4\u0186\2\0\1\u0186\15\0\1\u0186\6\0\1\u0189\1\u018b"+ - "\1\u018a\2\u0189\2\u018a\1\u0189\1\u018a\1\u0189\1\u0187\13\0"+ - "\1\u0146\270\0\1\u0174\7\0\1\u018c\1\u018d\1\u018e\224\0"+ - "\1\u0109\1\270\2\u018f\1\u0190\1\u0191\10\u018f\1\270\1\u0192"+ - "\5\u018f\6\270\1\u010a\12\270\237\0\1\u0109\1\u0193\2\u018f"+ - "\1\270\1\u018f\1\u0194\6\u018f\4\270\4\u018f\1\270\1\u018f"+ - "\1\270\3\u018f\1\u010a\12\270\237\0\1\u0109\3\270\1\u018f"+ - "\1\270\1\u018f\4\270\1\u018f\10\270\1\u018f\2\270\1\u018f"+ - "\2\270\1\u018f\1\u010a\12\270\237\0\1\u0109\1\270\1\u018f"+ - "\1\u0195\2\u018f\2\270\1\u018f\6\270\3\u018f\11\270\1\u010a"+ - "\12\270\237\0\1\u0109\3\270\1\u018f\1\270\1\u018f\10\270"+ - "\1\u018f\1\270\2\u018f\10\270\1\u010a\12\270\237\0\1\u0109"+ - "\4\270\1\u0196\5\270\1\u018f\17\270\1\u010a\12\270\237\0"+ - "\1\u0109\4\270\2\u018f\2\270\1\u018f\1\270\1\u018f\13\270"+ - "\1\u018f\2\270\1\u018f\1\u010a\12\270\237\0\1\u0109\1\u018f"+ - "\1\270\3\u018f\1\u0197\14\u018f\2\270\2\u018f\2\270\1\u018f"+ - "\1\270\1\u010a\12\270\237\0\1\u0109\2\270\4\u018f\3\270"+ - "\2\u018f\1\u0198\1\u018f\1\270\2\u018f\12\270\1\u010a\12\270"+ - "\237\0\1\u0109\2\u018f\2\270\1\u018f\3\270\1\u018f\5\270"+ - "\3\u018f\3\270\1\u018f\2\270\3\u018f\1\u010a\12\270\237\0"+ - "\1\u0109\5\u018f\1\u0199\1\270\1\u018f\1\u019a\7\u018f\1\u019b"+ - "\3\u018f\1\270\1\u018f\1\270\3\u018f\1\u010a\12\270\237\0"+ - "\1\u0109\1\u019c\1\u018f\1\270\1\u0193\6\u018f\3\270\1\u018f"+ - "\2\270\1\u018f\2\270\1\u018f\6\270\1\u010a\12\270\237\0"+ - "\1\u0109\1\u018f\31\270\1\u010a\12\270\237\0\1\u0109\1\u018f"+ - "\2\270\1\u018f\1\u019d\1\270\2\u018f\1\270\3\u018f\2\270"+ - "\2\u018f\1\270\1\u018f\3\270\1\u018f\2\270\2\u018f\1\u010a"+ - "\12\270\237\0\1\u0109\6\u018f\1\270\5\u018f\3\270\2\u018f"+ - "\1\270\10\u018f\1\u010a\12\270\237\0\1\u0109\1\270\2\u018f"+ - "\1\u019a\1\u019e\3\u018f\1\270\3\u018f\1\270\1\u018f\1\270"+ - "\1\u018f\1\270\1\u018f\1\270\1\u018f\1\270\3\u018f\1\270"+ - "\1\u018f\1\u010a\12\270\237\0\1\u0109\1\u018f\6\270\1\u018f"+ - "\6\270\1\u018f\4\270\1\u018f\4\270\2\u018f\1\u010a\12\270"+ - "\237\0\1\u0109\6\270\1\u018f\7\270\1\u018f\13\270\1\u010a"+ - "\12\270\237\0\1\u0109\13\270\1\u019f\6\270\1\u01a0\7\270"+ - "\1\u010a\12\270\237\0\1\u0109\1\u018f\11\270\1\u018f\6\270"+ - "\1\u018f\10\270\1\u010a\12\270\237\0\1\u0109\1\u018f\1\270"+ - "\6\u018f\1\u01a1\1\270\2\u018f\2\270\2\u018f\1\270\1\u018f"+ - "\1\270\6\u018f\1\270\1\u010a\12\270\237\0\1\u0109\4\270"+ - "\1\u018f\5\270\2\u018f\3\270\2\u018f\10\270\1\u018f\1\u010a"+ - "\12\270\237\0\1\u0109\3\270\1\u018f\1\270\1\u01a2\4\270"+ - "\1\u018f\2\270\1\u018f\14\270\1\u010a\12\270\237\0\1\u0109"+ - "\2\u018f\1\270\1\u018f\3\270\2\u018f\2\270\1\u018f\4\270"+ - "\1\u018f\11\270\1\u010a\12\270\237\0\1\u0109\3\270\1\u018f"+ - "\13\270\1\u018f\12\270\1\u010a\12\270\237\0\1\u0109\3\270"+ - "\2\u018f\2\270\2\u018f\1\270\2\u018f\1\270\1\u018f\3\270"+ - "\1\u018f\1\270\1\u018f\1\270\1\u018f\2\270\1\u018f\1\270"+ - "\1\u010a\12\270\27\0\1\53\1\0\1\54\2\0\1\221"+ - "\1\0\1\222\4\0\1\57\1\0\1\60\1\0\1\61"+ - "\2\0\1\62\3\0\1\223\2\0\1\224\4\0\1\225"+ - "\3\0\1\226\17\0\1\67\2\0\1\227\21\0\1\230"+ - "\2\0\1\231\57\0\1\30\1\74\7\0\1\74\2\0"+ - "\1\30\1\160\1\272\1\273\1\274\1\275\1\276\1\277"+ - "\1\300\1\301\1\302\1\303\1\304\1\305\1\306\1\307"+ - "\1\310\1\311\1\312\1\313\1\314\1\315\1\316\1\317"+ - "\1\320\1\321\1\322\1\323\1\161\12\324\1\u0174\3\161"+ - "\1\0\2\161\1\162\1\u0163\1\u0164\1\u0165\3\0\1\161"+ - "\1\206\3\0\2\161\2\0\1\53\1\0\1\54\2\0"+ - "\1\221\1\0\1\222\4\0\1\57\1\0\1\60\1\0"+ - "\1\61\2\0\1\62\3\0\1\223\2\0\1\224\4\0"+ - "\1\225\3\0\1\226\17\0\1\67\2\0\1\227\21\0"+ - "\1\230\2\0\1\231\57\0\1\30\1\74\7\0\1\74"+ - "\2\0\1\30\1\0\32\30\1\0\12\u01a3\237\0\1\u01a4"+ - "\45\u0163\1\u018c\2\u0163\1\u01a5\1\u018c\2\u0163\1\u01a6\2\u0163"+ - "\1\u0165\2\0\1\u018c\1\u0163\4\0\1\u0163\1\161\212\0"+ - "\1\u01a7\45\u0164\1\u018d\2\u0164\1\u01a8\1\0\2\161\1\u01a9"+ - "\1\u0163\1\u0164\1\u0165\2\0\1\u018d\1\u0164\4\0\2\161"+ - "\212\0\1\u01aa\45\u0165\1\u018e\2\u0165\1\u01ab\1\u018e\2\u0165"+ - "\1\u01ac\2\u0165\1\161\2\0\1\u018e\1\u0165\4\0\1\u0165"+ - "\1\161\2\0\1\53\1\0\1\54\2\0\1\55\1\0"+ - "\1\56\4\0\1\57\1\0\1\60\1\0\1\61\2\0"+ - "\1\62\3\0\1\63\2\0\1\64\4\0\1\65\3\0"+ - "\1\66\17\0\1\67\2\0\1\70\21\0\1\71\2\0"+ - "\1\72\57\0\2\30\1\73\1\0\1\74\1\0\1\74"+ - "\1\75\1\0\1\30\2\0\1\30\1\163\5\41\1\u010d"+ - "\24\41\1\164\12\165\1\74\1\161\1\166\1\161\1\0"+ - "\1\161\1\167\1\162\3\161\3\0\1\161\4\0\2\161"+ - "\2\0\1\53\1\0\1\54\2\0\1\55\1\0\1\56"+ - "\4\0\1\57\1\0\1\60\1\0\1\61\2\0\1\62"+ - "\3\0\1\63\2\0\1\64\4\0\1\65\3\0\1\66"+ - "\17\0\1\67\2\0\1\70\21\0\1\71\2\0\1\72"+ - "\57\0\2\30\1\73\1\0\1\74\1\0\1\74\1\75"+ - "\1\0\1\30\2\0\1\30\1\163\15\41\1\u010d\14\41"+ - "\1\164\12\165\1\74\1\161\1\166\1\161\1\0\1\161"+ - "\1\167\1\162\3\161\3\0\1\161\4\0\2\161\2\0"+ - "\1\53\1\0\1\54\2\0\1\55\1\0\1\56\4\0"+ - "\1\57\1\0\1\60\1\0\1\61\2\0\1\62\3\0"+ - "\1\63\2\0\1\64\4\0\1\65\3\0\1\66\17\0"+ - "\1\67\2\0\1\70\21\0\1\71\2\0\1\72\57\0"+ - "\2\30\1\73\1\0\1\74\1\0\1\74\1\75\1\0"+ - "\1\30\2\0\1\30\1\163\10\41\1\u010d\21\41\1\164"+ - "\12\165\1\74\1\161\1\166\1\161\1\0\1\161\1\167"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\2\0\1\53"+ - "\1\0\1\54\2\0\1\55\1\0\1\56\4\0\1\57"+ - "\1\0\1\60\1\0\1\61\2\0\1\62\3\0\1\63"+ - "\2\0\1\64\4\0\1\65\3\0\1\66\17\0\1\67"+ - "\2\0\1\70\21\0\1\71\2\0\1\72\57\0\2\30"+ - "\1\73\1\0\1\74\1\0\1\74\1\75\1\0\1\30"+ - "\2\0\1\30\1\163\3\41\1\u01ad\26\41\1\164\12\165"+ - "\1\74\1\161\1\166\1\161\1\0\1\161\1\167\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\2\0\1\53\1\0"+ - "\1\54\2\0\1\55\1\0\1\56\4\0\1\57\1\0"+ - "\1\60\1\0\1\61\2\0\1\62\3\0\1\63\2\0"+ - "\1\64\4\0\1\65\3\0\1\66\17\0\1\67\2\0"+ - "\1\70\21\0\1\71\2\0\1\72\57\0\2\30\1\73"+ - "\1\0\1\74\1\0\1\74\1\75\1\0\1\30\2\0"+ - "\1\30\1\163\3\41\1\u010d\26\41\1\164\12\165\1\74"+ - "\1\161\1\166\1\161\1\0\1\161\1\167\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\2\0\1\53\1\0\1\54"+ - "\2\0\1\55\1\0\1\56\4\0\1\57\1\0\1\60"+ - "\1\0\1\61\2\0\1\62\3\0\1\63\2\0\1\64"+ - "\4\0\1\65\3\0\1\66\17\0\1\67\2\0\1\70"+ - "\21\0\1\71\2\0\1\72\57\0\2\30\1\73\1\0"+ - "\1\74\1\0\1\74\1\75\1\0\1\30\2\0\1\30"+ - "\1\163\27\41\1\u01ae\2\41\1\164\12\165\1\74\1\161"+ - "\1\166\1\161\1\0\1\161\1\167\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\212\0\1\160\32\324\1\u01af\12\324"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\2\0\1\53\1\0\1\54\2\0\1\55"+ - "\1\0\1\56\4\0\1\57\1\0\1\60\1\0\1\61"+ - "\2\0\1\62\3\0\1\63\2\0\1\64\4\0\1\65"+ - "\3\0\1\66\17\0\1\67\2\0\1\70\21\0\1\71"+ - "\2\0\1\72\57\0\2\30\1\73\1\0\1\74\1\0"+ - "\1\74\1\75\1\0\1\30\2\0\1\30\1\163\16\41"+ - "\1\u010d\13\41\1\164\12\165\1\74\1\161\1\166\1\161"+ - "\1\0\1\161\1\167\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\2\0\1\53\1\0\1\54\2\0\1\221\1\0"+ - "\1\222\4\0\1\57\1\0\1\60\1\0\1\61\2\0"+ - "\1\62\3\0\1\223\2\0\1\224\4\0\1\225\3\0"+ - "\1\226\17\0\1\67\2\0\1\227\21\0\1\230\2\0"+ - "\1\231\57\0\1\30\1\74\7\0\1\74\2\0\1\30"+ - "\1\0\32\30\24\0\1\u01b0\304\0\1\u01b1\15\0\1\53"+ - "\1\0\1\54\2\0\1\55\1\0\1\56\4\0\1\57"+ - "\1\0\1\60\1\0\1\61\2\0\1\62\3\0\1\63"+ - "\2\0\1\64\4\0\1\65\3\0\1\66\17\0\1\67"+ - "\2\0\1\70\21\0\1\71\2\0\1\72\57\0\2\30"+ - "\1\73\1\0\1\74\1\0\1\74\1\75\1\0\1\30"+ - "\2\0\1\30\1\163\5\41\1\u01b2\24\41\1\164\12\165"+ - "\1\74\1\161\1\166\1\161\1\0\1\161\1\167\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\2\0\1\53\1\0"+ - "\1\54\2\0\1\55\1\0\1\56\4\0\1\57\1\0"+ - "\1\60\1\0\1\61\2\0\1\62\3\0\1\63\2\0"+ - "\1\64\4\0\1\65\3\0\1\66\17\0\1\67\2\0"+ - "\1\70\21\0\1\71\2\0\1\72\57\0\2\30\1\73"+ - "\1\0\1\74\1\0\1\74\1\75\1\0\1\30\2\0"+ - "\1\30\1\163\32\41\1\164\12\165\1\u0172\1\161\1\166"+ - "\1\161\1\0\1\161\1\167\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\2\0\1\53\1\0\1\54\2\0\1\221"+ - "\1\0\1\222\4\0\1\57\1\0\1\60\1\0\1\61"+ - "\2\0\1\62\3\0\1\223\2\0\1\224\4\0\1\225"+ - "\3\0\1\226\17\0\1\67\2\0\1\227\21\0\1\230"+ - "\2\0\1\231\57\0\1\30\1\74\7\0\1\74\2\0"+ - "\1\30\1\0\32\30\24\0\1\u01b3\225\0\1\160\1\334"+ - "\1\335\1\336\1\337\1\340\1\341\1\342\1\343\1\344"+ - "\1\345\1\346\1\347\1\350\1\351\1\352\1\353\1\354"+ - "\1\355\1\356\1\357\1\360\1\361\1\362\1\363\1\364"+ - "\1\365\1\161\12\324\1\u0174\3\161\1\0\2\161\1\162"+ - "\1\u0163\1\u0164\1\u0165\3\0\1\161\1\206\3\0\2\161"+ - "\246\0\12\u01a3\237\0\1\u0121\5\324\1\u0127\24\324\1\164"+ - "\12\324\1\0\3\161\1\0\2\161\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\212\0\1\u0121\15\324\1\u0127\14\324"+ - "\1\164\12\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\10\324\1\u0127"+ - "\21\324\1\164\12\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121\3\324"+ - "\1\u01b4\26\324\1\164\12\324\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121"+ - "\3\324\1\u0127\26\324\1\164\12\324\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\4\0\2\161\212\0"+ - "\1\u0121\27\324\1\u01b5\2\324\1\164\12\324\1\0\3\161"+ - "\1\0\2\161\1\162\3\161\3\0\1\161\4\0\2\161"+ - "\212\0\1\u0121\16\324\1\u0127\13\324\1\164\12\324\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\2\0\1\53\1\0\1\54\2\0\1\76\1\0"+ - "\1\77\4\0\1\57\1\0\1\60\1\0\1\61\2\0"+ - "\1\62\3\0\1\100\2\0\1\101\4\0\1\102\3\0"+ - "\1\103\17\0\1\67\2\0\1\104\21\0\1\105\2\0"+ - "\1\106\57\0\1\30\2\31\2\0\2\107\1\110\1\0"+ - "\1\31\2\0\1\30\1\u01b6\32\41\1\164\12\u017d\1\0"+ - "\1\161\1\175\1\161\1\0\2\176\1\162\3\161\2\0"+ - "\1\107\1\161\4\0\2\161\2\0\1\53\1\0\1\54"+ - "\2\0\1\76\1\0\1\77\4\0\1\57\1\0\1\60"+ - "\1\0\1\61\2\0\1\62\3\0\1\100\2\0\1\101"+ - "\4\0\1\102\3\0\1\103\17\0\1\67\2\0\1\104"+ - "\21\0\1\105\2\0\1\106\57\0\1\30\2\31\2\0"+ - "\2\107\1\110\1\0\1\31\2\0\1\30\1\u01b6\32\41"+ - "\1\164\12\u01b7\1\0\1\161\1\175\1\161\1\0\2\176"+ - "\1\162\3\161\2\0\1\107\1\161\4\0\2\161\2\0"+ - "\1\53\1\0\1\54\2\0\1\76\1\0\1\77\4\0"+ - "\1\57\1\0\1\60\1\0\1\61\2\0\1\62\3\0"+ - "\1\100\2\0\1\101\4\0\1\102\3\0\1\103\17\0"+ - "\1\67\2\0\1\104\21\0\1\105\2\0\1\106\57\0"+ - "\1\30\2\31\2\0\2\107\1\110\1\0\1\31\2\0"+ - "\1\30\1\u01b6\32\41\1\164\1\u017d\1\u01b8\1\u01b7\2\u017d"+ - "\2\u01b7\1\u017d\1\u01b7\1\u017d\1\0\1\161\1\175\1\161"+ - "\1\0\2\176\1\162\3\161\2\0\1\107\1\161\4\0"+ - "\2\161\260\0\1\375\237\0\4\u01b9\2\0\1\u01b9\15\0"+ - "\1\u01b9\6\0\12\u01b9\1\u0181\237\0\4\u01ba\2\0\1\u01ba"+ - "\15\0\1\u01ba\6\0\12\u01ba\1\u01bb\237\0\4\u01bc\2\0"+ - "\1\u01bc\15\0\1\u01bc\6\0\12\u01bc\1\u01bd\13\0\1\u0146"+ - "\222\0\1\u0188\4\u01bc\2\0\1\u01bc\15\0\1\u01bc\6\0"+ - "\12\u01be\1\u01bd\13\0\1\u0146\222\0\1\u0188\4\u01bc\2\0"+ - "\1\u01bc\15\0\1\u01bc\6\0\12\u01bf\1\u01bd\13\0\1\u0146"+ - "\222\0\1\u0188\4\u01bc\2\0\1\u01bc\15\0\1\u01bc\6\0"+ - "\1\u01be\1\u01c0\1\u01bf\2\u01be\2\u01bf\1\u01be\1\u01bf\1\u01be"+ - "\1\u01bd\13\0\1\u0146\223\0\4\u01c1\2\0\1\u01c1\15\0"+ - "\1\u01c1\6\0\12\u01c1\1\u0187\13\0\1\u0146\223\0\4\u0182"+ - "\2\0\1\u0182\15\0\1\u0182\6\0\1\u0183\2\u0184\1\u0183"+ - "\5\u0184\1\u0185\273\0\1\u01c2\2\u01c3\1\u01c2\5\u01c3\1\u01c4"+ - "\237\0\1\u0188\4\u01c1\2\0\1\u01c1\15\0\1\u01c1\6\0"+ - "\12\u01c5\1\u0187\13\0\1\u0146\222\0\1\u0188\4\u01c1\2\0"+ - "\1\u01c1\15\0\1\u01c1\6\0\12\u01c1\1\u0187\13\0\1\u0146"+ - "\222\0\1\u0188\4\u01c1\2\0\1\u01c1\15\0\1\u01c1\6\0"+ - "\2\u01c5\1\u01c1\2\u01c5\2\u01c1\1\u01c5\1\u01c1\1\u01c5\1\u0187"+ - "\13\0\1\u0146\222\0\51\u018c\1\u01c6\6\u018c\1\u018e\2\0"+ - "\2\u018c\4\0\1\u018c\213\0\51\u018d\1\u01c7\3\0\1\u018d"+ - "\1\u018c\1\u018d\1\u018e\2\0\2\u018d\220\0\51\u018e\1\u01c8"+ - "\6\u018e\3\0\2\u018e\4\0\1\u018e\213\0\1\u01c9\32\270"+ - "\1\u010a\12\270\237\0\1\u01c9\4\270\1\u01ca\25\270\1\u010a"+ - "\12\270\237\0\1\u01c9\15\270\1\u0153\14\270\1\u010a\12\270"+ - "\237\0\1\u01c9\10\270\1\u0153\21\270\1\u010a\12\270\237\0"+ - "\1\u01c9\17\270\1\u018f\12\270\1\u010a\12\270\237\0\1\u01c9"+ - "\5\270\1\u01cb\4\270\1\u018f\17\270\1\u010a\12\270\237\0"+ - "\1\u0109\20\270\1\u018f\11\270\1\u010a\12\270\237\0\1\u0109"+ - "\7\270\1\u018f\22\270\1\u010a\12\270\237\0\1\u0109\27\270"+ - "\1\u018f\2\270\1\u010a\12\270\237\0\1\u01c9\6\270\1\u01ca"+ - "\10\270\1\u018f\12\270\1\u010a\12\270\237\0\1\u01c9\24\270"+ - "\1\u01cc\5\270\1\u010a\12\270\237\0\1\u0109\11\270\1\u018f"+ - "\20\270\1\u010a\12\270\237\0\1\u01c9\16\270\1\u01cd\13\270"+ - "\1\u010a\12\270\237\0\1\u01c9\12\270\1\u01ce\17\270\1\u010a"+ - "\12\270\237\0\1\u01c9\5\270\1\u018f\24\270\1\u010a\12\270"+ - "\237\0\1\u01c9\1\u01cf\31\270\1\u010a\12\270\237\0\1\u0109"+ - "\32\270\1\u01d0\12\270\237\0\1\u0109\22\270\1\u018f\7\270"+ - "\1\u010a\12\270\237\0\1\u01c9\23\270\1\u018f\6\270\1\u010a"+ - "\12\270\237\0\1\u01c9\24\270\1\u01d1\5\270\1\u010a\12\270"+ - "\273\0\12\u01d2\10\0\1\u018c\1\u018d\1\u018e\224\0\1\u01a4"+ - "\45\u0163\1\u018c\2\u0163\1\u01a5\1\u018c\2\u0163\1\u01a6\2\u0163"+ - "\1\u0165\2\0\1\u018c\1\u0163\1\206\3\0\1\u0163\1\161"+ - "\212\0\1\160\4\u01d3\2\161\1\u01d3\15\161\1\u01d3\6\161"+ - "\12\u01d3\1\0\3\161\1\0\2\161\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\212\0\51\u018c\1\u01c6\6\u018c\1\u018e"+ - "\1\271\1\0\2\u018c\4\0\1\u018c\213\0\1\u01a7\45\u0164"+ - "\1\u018d\2\u0164\1\u01a8\1\0\2\161\1\u01a9\1\u0163\1\u0164"+ - "\1\u0165\2\0\1\u018d\1\u0164\1\206\3\0\2\161\212\0"+ - "\1\160\4\u01d4\2\161\1\u01d4\15\161\1\u01d4\6\161\12\u01d4"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\212\0\51\u018d\1\u01c7\3\0\1\u018d\1\u018c"+ - "\1\u018d\1\u018e\1\271\1\0\2\u018d\220\0\1\u01aa\45\u0165"+ - "\1\u018e\2\u0165\1\u01ab\1\u018e\2\u0165\1\u01ac\2\u0165\1\161"+ - "\2\0\1\u018e\1\u0165\1\206\3\0\1\u0165\1\161\212\0"+ - "\1\160\4\u01d5\2\161\1\u01d5\15\161\1\u01d5\6\161\12\u01d5"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\212\0\51\u018e\1\u01c8\6\u018e\1\0\1\271"+ - "\1\0\2\u018e\4\0\1\u018e\3\0\1\53\1\0\1\54"+ - "\2\0\1\55\1\0\1\56\4\0\1\57\1\0\1\60"+ - "\1\0\1\61\2\0\1\62\3\0\1\63\2\0\1\64"+ - "\4\0\1\65\3\0\1\66\17\0\1\67\2\0\1\70"+ - "\21\0\1\71\2\0\1\72\57\0\2\30\1\73\1\0"+ - "\1\74\1\0\1\74\1\75\1\0\1\30\2\0\1\30"+ - "\1\163\20\41\1\u01d6\11\41\1\164\12\165\1\74\1\161"+ - "\1\166\1\161\1\0\1\161\1\167\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\2\0\1\53\1\0\1\54\2\0"+ - "\1\55\1\0\1\56\4\0\1\57\1\0\1\60\1\0"+ - "\1\61\2\0\1\62\3\0\1\63\2\0\1\64\4\0"+ - "\1\65\3\0\1\66\17\0\1\67\2\0\1\70\21\0"+ - "\1\71\2\0\1\72\57\0\2\30\1\73\1\0\1\74"+ - "\1\0\1\74\1\75\1\0\1\30\2\0\1\30\1\163"+ - "\3\41\1\u0118\26\41\1\164\12\165\1\74\1\161\1\166"+ - "\1\161\1\0\1\161\1\167\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\212\0\1\160\1\324\1\u01d7\1\u01d8\2\324"+ - "\1\u01d9\1\u01da\1\u01db\1\324\1\u01dc\1\u01dd\2\324\1\u01de"+ - "\1\u01df\2\324\1\u01e0\1\u01e1\1\u01e2\1\324\1\u01e3\1\u01e4"+ - "\1\324\1\u01e5\1\u01e6\1\164\1\u01e7\2\324\1\u01e8\1\u01e9"+ - "\1\u01ea\1\324\1\u01eb\1\u01ec\1\324\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\4\0\2\161\271\0"+ - "\1\u01ed\225\0\1\u01ee\32\u01ef\1\u01ee\12\u01ef\1\u01f0\2\u01ee"+ - "\1\u01f1\3\u01ee\1\u01f2\3\0\1\u01f3\1\0\2\u01ee\4\0"+ - "\1\u01ee\3\0\1\53\1\0\1\54\2\0\1\55\1\0"+ - "\1\56\4\0\1\57\1\0\1\60\1\0\1\61\2\0"+ - "\1\62\3\0\1\63\2\0\1\64\4\0\1\65\3\0"+ - "\1\66\17\0\1\67\2\0\1\70\21\0\1\71\2\0"+ - "\1\72\57\0\2\30\1\73\1\0\1\74\1\0\1\74"+ - "\1\75\1\0\1\30\2\0\1\30\1\163\32\41\1\164"+ - "\12\165\1\u01f4\1\161\1\166\1\161\1\0\1\161\1\167"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\271\0\1\u01f5"+ - "\225\0\1\u0121\20\324\1\u01f6\11\324\1\164\12\324\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0121\3\324\1\u0132\26\324\1\164\12\324"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\7\0\1\241\1\0\1\242\17\0\1\243"+ - "\2\0\1\244\4\0\1\245\3\0\1\246\22\0\1\247"+ - "\21\0\1\250\2\0\1\251\60\0\1\107\1\31\6\0"+ - "\1\107\3\0\1\160\1\334\1\335\1\336\1\337\1\340"+ - "\1\341\1\342\1\343\1\344\1\345\1\346\1\347\1\350"+ - "\1\351\1\352\1\353\1\354\1\355\1\356\1\357\1\360"+ - "\1\361\1\362\1\363\1\364\1\365\1\161\1\u01f7\2\u01f8"+ - "\1\u01f7\5\u01f8\1\u01f9\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\1\206\3\0\2\161\2\0\1\53"+ - "\1\0\1\54\2\0\1\76\1\0\1\77\4\0\1\57"+ - "\1\0\1\60\1\0\1\61\2\0\1\62\3\0\1\100"+ - "\2\0\1\101\4\0\1\102\3\0\1\103\17\0\1\67"+ - "\2\0\1\104\21\0\1\105\2\0\1\106\57\0\1\30"+ - "\2\31\2\0\2\107\1\110\1\0\1\31\2\0\1\30"+ - "\1\u01b6\32\41\1\164\12\371\1\0\1\161\1\175\1\161"+ - "\1\0\2\176\1\162\3\161\2\0\1\107\1\161\4\0"+ - "\2\161\2\0\1\53\1\0\1\54\2\0\1\76\1\0"+ - "\1\77\4\0\1\57\1\0\1\60\1\0\1\61\2\0"+ - "\1\62\3\0\1\100\2\0\1\101\4\0\1\102\3\0"+ - "\1\103\17\0\1\67\2\0\1\104\21\0\1\105\2\0"+ - "\1\106\57\0\1\30\2\31\2\0\2\107\1\110\1\0"+ - "\1\31\2\0\1\30\1\u01b6\32\41\1\164\2\u01b7\1\371"+ - "\2\u01b7\2\371\1\u01b7\1\371\1\u01b7\1\0\1\161\1\175"+ - "\1\161\1\0\2\176\1\162\3\161\2\0\1\107\1\161"+ - "\4\0\2\161\213\0\4\u01fa\2\0\1\u01fa\15\0\1\u01fa"+ - "\6\0\12\u01fa\1\u0181\237\0\4\u01fb\2\0\1\u01fb\15\0"+ - "\1\u01fb\6\0\12\u01fb\1\u01fc\237\0\4\u01fd\2\0\1\u01fd"+ - "\15\0\1\u01fd\6\0\1\u01fe\2\u01ff\1\u01fe\5\u01ff\1\u0200"+ - "\14\0\1\u0146\223\0\4\u0201\2\0\1\u0201\15\0\1\u0201"+ - "\6\0\12\u0201\1\u01bd\13\0\1\u0146\223\0\4\u01fd\2\0"+ - "\1\u01fd\15\0\1\u01fd\6\0\1\u01fe\2\u01ff\1\u01fe\5\u01ff"+ - "\1\u0200\237\0\1\u0188\4\u0201\2\0\1\u0201\15\0\1\u0201"+ - "\6\0\12\u0202\1\u01bd\13\0\1\u0146\222\0\1\u0188\4\u0201"+ - "\2\0\1\u0201\15\0\1\u0201\6\0\12\u0201\1\u01bd\13\0"+ - "\1\u0146\222\0\1\u0188\4\u0201\2\0\1\u0201\15\0\1\u0201"+ - "\6\0\2\u0202\1\u0201\2\u0202\2\u0201\1\u0202\1\u0201\1\u0202"+ - "\1\u01bd\13\0\1\u0146\223\0\4\u0203\2\0\1\u0203\15\0"+ - "\1\u0203\6\0\12\u0203\1\u0187\13\0\1\u0146\222\0\1\u0204"+ - "\33\0\12\u01c3\237\0\1\u0204\33\0\12\u0205\237\0\1\u0204"+ - "\33\0\1\u01c3\1\u0206\1\u0205\2\u01c3\2\u0205\1\u01c3\1\u0205"+ - "\1\u01c3\237\0\1\u0188\4\u0203\2\0\1\u0203\15\0\1\u0203"+ - "\6\0\12\u0203\1\u0187\13\0\1\u0146\223\0\4\u0207\2\0"+ - "\1\u0207\15\0\1\u0207\6\0\12\u0207\240\0\4\u0208\2\0"+ - "\1\u0208\15\0\1\u0208\6\0\12\u0208\240\0\4\u0209\2\0"+ - "\1\u0209\15\0\1\u0209\6\0\12\u0209\237\0\1\u0109\5\270"+ - "\1\u018f\24\270\1\u010a\12\270\237\0\1\u0109\15\270\1\u018f"+ - "\14\270\1\u010a\12\270\237\0\1\u0109\10\270\1\u018f\21\270"+ - "\1\u010a\12\270\237\0\1\u0109\3\270\1\u020a\26\270\1\u010a"+ - "\12\270\237\0\1\u0109\3\270\1\u018f\26\270\1\u010a\12\270"+ - "\237\0\1\u0109\27\270\1\u020b\2\270\1\u010a\12\270\240\0"+ - "\32\270\1\u020c\12\270\237\0\1\u0109\16\270\1\u018f\13\270"+ - "\1\u010a\12\270\273\0\12\u020d\10\0\1\u018c\1\u018d\1\u018e"+ - "\224\0\1\160\4\u0163\2\161\1\u0163\15\161\1\u0163\6\161"+ - "\12\u0163\1\0\3\161\1\0\2\161\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\212\0\1\160\4\u0164\2\161\1\u0164"+ - "\15\161\1\u0164\6\161\12\u0164\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\212\0\1\160"+ - "\4\u0165\2\161\1\u0165\15\161\1\u0165\6\161\12\u0165\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\2\0\1\53\1\0\1\54\2\0\1\55\1\0"+ - "\1\56\4\0\1\57\1\0\1\60\1\0\1\61\2\0"+ - "\1\62\3\0\1\63\2\0\1\64\4\0\1\65\3\0"+ - "\1\66\17\0\1\67\2\0\1\70\21\0\1\71\2\0"+ - "\1\72\57\0\2\30\1\73\1\0\1\74\1\0\1\74"+ - "\1\75\1\0\1\30\2\0\1\30\1\163\12\41\1\u010d"+ - "\17\41\1\164\12\165\1\74\1\161\1\166\1\161\1\0"+ - "\1\161\1\167\1\162\3\161\3\0\1\161\4\0\2\161"+ - "\212\0\1\u0121\11\324\1\u020e\20\324\1\164\12\324\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0121\3\324\1\u020f\26\324\1\164\12\324"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\212\0\1\u0121\7\324\1\u0210\22\324\1\164"+ - "\4\324\1\u0211\5\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121\10\324"+ - "\1\u0212\4\324\1\u0213\5\324\1\u0214\6\324\1\164\12\324"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\212\0\1\u0121\3\324\1\u0215\26\324\1\164"+ - "\2\324\1\u0216\7\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121\7\324"+ - "\1\u0217\22\324\1\164\12\324\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121"+ - "\7\324\1\u0218\22\324\1\164\12\324\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\4\0\2\161\212\0"+ - "\1\u0121\7\324\1\u0219\22\324\1\164\3\324\1\u021a\6\324"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\212\0\1\u0121\32\324\1\164\5\324\1\u021b"+ - "\4\324\1\0\3\161\1\0\2\161\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\212\0\1\u0121\7\324\1\u021c\22\324"+ - "\1\164\12\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\31\324\1\u021d"+ - "\1\164\12\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\1\324\1\u021e"+ - "\30\324\1\164\12\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121\7\324"+ - "\1\u021f\1\324\1\u0220\20\324\1\164\11\324\1\u021b\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0121\22\324\1\u0221\7\324\1\164\2\324"+ - "\1\u0222\7\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\6\324\1\u0223"+ - "\1\u0224\22\324\1\164\12\324\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121"+ - "\7\324\1\u0225\5\324\1\u0226\14\324\1\164\12\324\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0121\23\324\1\u0227\6\324\1\164\12\324"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\212\0\1\u0121\32\324\1\164\3\324\1\u0228"+ - "\6\324\1\0\3\161\1\0\2\161\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\212\0\1\u0121\3\324\1\u0229\26\324"+ - "\1\164\12\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\17\324\1\u022a"+ - "\12\324\1\164\1\u022b\11\324\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121"+ - "\32\324\1\164\1\324\1\u021b\10\324\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\4\0\2\161\212\0"+ - "\1\u0121\32\324\1\164\1\u022c\11\324\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\4\0\2\161\213\0"+ - "\32\u022d\1\0\12\u022d\11\0\1\u022e\1\0\1\u022f\223\0"+ - "\46\u01ee\1\u01f0\2\u01ee\1\u01f1\3\u01ee\1\u01f2\5\0\2\u01ee"+ - "\4\0\1\u01ee\213\0\1\u0230\32\u01ef\1\u0231\12\u01ef\1\u0232"+ - "\2\u01ee\1\u01f1\3\u01ee\1\u01f2\1\0\1\u0233\3\0\2\u01ee"+ - "\4\0\1\u01ee\213\0\46\u01f0\1\0\2\u01f0\1\u0234\3\u01f0"+ - "\1\u01f2\5\0\2\u01f0\4\0\1\u01f0\214\0\4\u0235\2\0"+ - "\1\u0235\15\0\1\u0235\6\0\12\u0235\240\0\32\u0236\1\0"+ - "\12\u0236\13\0\1\u01f3\224\0\4\u0237\2\0\1\u0237\15\0"+ - "\1\u0237\6\0\12\u0237\1\u0238\26\0\1\53\1\0\1\54"+ - "\2\0\1\221\1\0\1\222\4\0\1\57\1\0\1\60"+ - "\1\0\1\61\2\0\1\62\3\0\1\223\2\0\1\224"+ - "\4\0\1\225\3\0\1\226\17\0\1\67\2\0\1\227"+ - "\21\0\1\230\2\0\1\231\57\0\1\30\1\74\7\0"+ - "\1\74\2\0\1\30\1\u0239\32\u023a\13\u0239\1\0\3\u0239"+ - "\1\0\2\u0239\1\0\3\u0239\3\0\1\u0239\1\u023b\3\0"+ - "\2\u0239\212\0\1\u023c\32\u023d\1\u023c\12\u023d\1\u023e\2\u023c"+ - "\1\u023f\3\u023c\1\u0240\3\0\1\u0241\1\0\2\u023c\4\0"+ - "\1\u023c\213\0\1\u0121\12\324\1\u0127\17\324\1\164\12\324"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\2\0\1\53\1\0\1\54\2\0\1\76"+ - "\1\0\1\77\4\0\1\57\1\0\1\60\1\0\1\61"+ - "\2\0\1\62\3\0\1\100\2\0\1\101\4\0\1\102"+ - "\3\0\1\103\17\0\1\67\2\0\1\104\21\0\1\105"+ - "\2\0\1\106\57\0\1\30\2\31\2\0\2\107\1\110"+ - "\1\0\1\31\2\0\1\30\1\u013e\32\41\1\164\12\u01f8"+ - "\1\u0174\1\161\1\175\1\161\1\0\2\176\1\162\1\u0163"+ - "\1\u0164\1\u0165\2\0\1\107\1\161\4\0\2\161\2\0"+ - "\1\53\1\0\1\54\2\0\1\76\1\0\1\77\4\0"+ - "\1\57\1\0\1\60\1\0\1\61\2\0\1\62\3\0"+ - "\1\100\2\0\1\101\4\0\1\102\3\0\1\103\17\0"+ - "\1\67\2\0\1\104\21\0\1\105\2\0\1\106\57\0"+ - "\1\30\2\31\2\0\2\107\1\110\1\0\1\31\2\0"+ - "\1\30\1\u013e\32\41\1\164\12\u0242\1\u0174\1\161\1\175"+ - "\1\161\1\0\2\176\1\162\1\u0163\1\u0164\1\u0165\2\0"+ - "\1\107\1\161\4\0\2\161\2\0\1\53\1\0\1\54"+ - "\2\0\1\76\1\0\1\77\4\0\1\57\1\0\1\60"+ - "\1\0\1\61\2\0\1\62\3\0\1\100\2\0\1\101"+ - "\4\0\1\102\3\0\1\103\17\0\1\67\2\0\1\104"+ - "\21\0\1\105\2\0\1\106\57\0\1\30\2\31\2\0"+ - "\2\107\1\110\1\0\1\31\2\0\1\30\1\u013e\32\41"+ - "\1\164\1\u01f8\1\u0243\1\u0242\2\u01f8\2\u0242\1\u01f8\1\u0242"+ - "\1\u01f8\1\u0174\1\161\1\175\1\161\1\0\2\176\1\162"+ - "\1\u0163\1\u0164\1\u0165\2\0\1\107\1\161\4\0\2\161"+ - "\260\0\1\u0181\237\0\4\u0244\2\0\1\u0244\15\0\1\u0244"+ - "\6\0\12\u0244\1\u01fc\237\0\4\u0245\2\0\1\u0245\15\0"+ - "\1\u0245\6\0\12\u0245\1\u0246\237\0\4\u0247\2\0\1\u0247"+ - "\15\0\1\u0247\6\0\12\u0247\1\u0248\13\0\1\u0146\222\0"+ - "\1\u0188\4\u0247\2\0\1\u0247\15\0\1\u0247\6\0\12\u0249"+ - "\1\u0248\13\0\1\u0146\222\0\1\u0188\4\u0247\2\0\1\u0247"+ - "\15\0\1\u0247\6\0\12\u024a\1\u0248\13\0\1\u0146\222\0"+ - "\1\u0188\4\u0247\2\0\1\u0247\15\0\1\u0247\6\0\1\u0249"+ - "\1\u024b\1\u024a\2\u0249\2\u024a\1\u0249\1\u024a\1\u0249\1\u0248"+ - "\13\0\1\u0146\223\0\4\u024c\2\0\1\u024c\15\0\1\u024c"+ - "\6\0\12\u024c\1\u01bd\13\0\1\u0146\222\0\1\u0188\4\u024c"+ - "\2\0\1\u024c\15\0\1\u024c\6\0\12\u024c\1\u01bd\13\0"+ - "\1\u0146\270\0\1\u0187\13\0\1\u0146\256\0\1\u024d\2\u024e"+ - "\1\u024d\5\u024e\1\u024f\237\0\1\u0204\304\0\1\u0204\33\0"+ - "\2\u0205\1\0\2\u0205\2\0\1\u0205\1\0\1\u0205\240\0"+ - "\4\u018c\2\0\1\u018c\15\0\1\u018c\6\0\12\u018c\240\0"+ - "\4\u018d\2\0\1\u018d\15\0\1\u018d\6\0\12\u018d\240\0"+ - "\4\u018e\2\0\1\u018e\15\0\1\u018e\6\0\12\u018e\237\0"+ - "\1\u0109\20\270\1\u0250\11\270\1\u010a\12\270\237\0\1\u0109"+ - "\3\270\1\u019a\26\270\1\u010a\12\270\240\0\1\270\1\u0251"+ - "\1\u0252\2\270\1\u0253\1\u0254\1\u0255\1\270\1\u0256\1\u0257"+ - "\2\270\1\u0258\1\u0259\2\270\1\u025a\1\u025b\1\u025c\1\270"+ - "\1\u025d\1\u025e\1\270\1\u025f\1\u0260\1\u010a\1\u0261\2\270"+ - "\1\u0262\1\u0263\1\u0264\1\270\1\u0265\1\u0266\1\270\273\0"+ - "\12\u0267\10\0\1\u018c\1\u018d\1\u018e\224\0\1\u0121\1\324"+ - "\1\u0268\30\324\1\164\12\324\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121"+ - "\24\324\1\u0269\5\324\1\164\12\324\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\4\0\2\161\212\0"+ - "\1\u0121\24\324\1\u026a\5\324\1\164\12\324\1\0\3\161"+ - "\1\0\2\161\1\162\3\161\3\0\1\161\4\0\2\161"+ - "\212\0\1\u0121\1\324\1\u026b\30\324\1\164\12\324\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0121\14\324\1\u026c\15\324\1\164\12\324"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\212\0\1\u0121\1\324\1\u026d\30\324\1\164"+ - "\12\324\1\0\3\161\1\0\2\161\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\212\0\1\u0121\1\324\1\u026e\30\324"+ - "\1\164\12\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\1\324\1\u026f"+ - "\30\324\1\164\12\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121\21\324"+ - "\1\u0270\10\324\1\164\12\324\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121"+ - "\24\324\1\u0271\5\324\1\164\12\324\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\4\0\2\161\212\0"+ - "\1\u0121\24\324\1\u0272\5\324\1\164\12\324\1\0\3\161"+ - "\1\0\2\161\1\162\3\161\3\0\1\161\4\0\2\161"+ - "\212\0\1\u0121\24\324\1\u0273\5\324\1\164\12\324\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0121\1\u0177\31\324\1\164\12\324\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0121\24\324\1\u026f\5\324\1\164\12\324"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\212\0\1\u0121\24\324\1\u0274\5\324\1\164"+ - "\12\324\1\0\3\161\1\0\2\161\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\212\0\1\u0121\1\324\1\u0275\30\324"+ - "\1\164\12\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\31\324\1\u0276"+ - "\1\164\12\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\24\324\1\u0277"+ - "\5\324\1\164\12\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121\1\324"+ - "\1\u0278\30\324\1\164\12\324\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121"+ - "\1\u0279\31\324\1\164\12\324\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121"+ - "\21\324\1\u027a\10\324\1\164\12\324\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\4\0\2\161\212\0"+ - "\1\u0121\4\324\1\u027b\25\324\1\164\12\324\1\0\3\161"+ - "\1\0\2\161\1\162\3\161\3\0\1\161\4\0\2\161"+ - "\212\0\1\u0121\24\324\1\u027c\5\324\1\164\12\324\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0121\24\324\1\u027d\5\324\1\164\12\324"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\212\0\1\u0121\4\324\1\u027e\25\324\1\164"+ - "\12\324\1\0\3\161\1\0\2\161\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\212\0\1\u0121\21\324\1\u027f\10\324"+ - "\1\164\12\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\24\324\1\u0280"+ - "\5\324\1\164\12\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121\32\324"+ - "\1\164\1\u0281\11\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121\32\324"+ - "\1\164\7\324\1\u0282\2\324\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121"+ - "\1\u0283\31\324\1\164\12\324\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121"+ - "\1\u0284\31\324\1\164\12\324\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\212\0\1\u0285"+ - "\32\u022d\1\u0286\12\u022d\11\0\1\u022e\225\0\51\u022e\1\u0287"+ - "\3\0\3\u022e\1\u018e\3\0\1\u022e\221\0\4\u0288\2\0"+ - "\1\u0288\15\0\1\u0288\6\0\12\u0288\1\u0289\236\0\1\u01ee"+ - "\32\u01ef\1\u01ee\12\u01ef\1\u01f0\2\u01ee\1\u01f1\3\u01ee\1\u01f2"+ - "\5\0\2\u01ee\4\0\1\u01ee\213\0\1\u01ee\32\u01ef\1\u0231"+ - "\12\u01ef\1\u01f0\2\u01ee\1\u01f1\3\u01ee\1\u01f2\5\0\2\u01ee"+ - "\4\0\1\u01ee\213\0\34\u01f0\12\u028a\1\0\2\u01f0\1\u0234"+ - "\3\u01f0\1\u01f2\5\0\2\u01f0\4\0\1\u01f0\213\0\51\u0233"+ - "\1\u028b\3\0\3\u0233\1\u018e\2\0\1\u028c\1\u0233\221\0"+ - "\4\u028d\2\0\1\u028d\15\0\1\u028d\6\0\12\u028d\240\0"+ - "\4\u01ee\2\0\1\u01ee\15\0\1\u01ee\6\0\12\u01ee\237\0"+ - "\1\u028e\32\u0236\1\u028f\12\u0236\1\u0290\10\0\1\u0233\226\0"+ - "\4\u0291\2\0\1\u0291\15\0\1\u0291\6\0\12\u0291\1\u0292"+ - "\304\0\1\u0293\236\0\1\u0294\45\u0239\1\0\3\u0239\1\0"+ - "\2\u0239\1\u0295\3\u0239\3\0\1\u0239\4\0\2\u0239\2\0"+ - "\1\53\1\0\1\54\2\0\1\55\1\0\1\56\4\0"+ - "\1\57\1\0\1\60\1\0\1\61\2\0\1\62\3\0"+ - "\1\63\2\0\1\64\4\0\1\65\3\0\1\66\17\0"+ - "\1\67\2\0\1\70\21\0\1\71\2\0\1\72\57\0"+ - "\2\30\1\73\1\0\1\74\1\0\1\74\1\75\1\0"+ - "\1\30\2\0\1\30\1\u0296\32\u023a\1\u0239\12\u0297\1\74"+ - "\1\u0239\1\u0298\1\u0239\1\0\1\u0239\1\u0299\1\u0295\3\u0239"+ - "\3\0\1\u0239\4\0\2\u0239\212\0\65\u023b\1\u029a\1\u023b"+ - "\1\u029b\1\0\2\u023b\212\0\46\u023c\1\u023e\2\u023c\1\u023f"+ - "\3\u023c\1\u0240\5\0\2\u023c\4\0\1\u023c\213\0\1\u029c"+ - "\32\u023d\1\u029d\12\u023d\1\u029e\2\u023c\1\u023f\3\u023c\1\u0240"+ - "\1\u018c\1\u018d\1\u018e\2\0\2\u023c\4\0\1\u023c\213\0"+ - "\46\u023e\1\0\2\u023e\1\u029f\3\u023e\1\u0240\5\0\2\u023e"+ - "\4\0\1\u023e\214\0\4\u02a0\2\0\1\u02a0\15\0\1\u02a0"+ - "\6\0\12\u02a0\240\0\32\u02a1\1\0\12\u02a1\13\0\1\u0241"+ - "\13\0\1\53\1\0\1\54\2\0\1\76\1\0\1\77"+ - "\4\0\1\57\1\0\1\60\1\0\1\61\2\0\1\62"+ - "\3\0\1\100\2\0\1\101\4\0\1\102\3\0\1\103"+ - "\17\0\1\67\2\0\1\104\21\0\1\105\2\0\1\106"+ - "\57\0\1\30\2\31\2\0\2\107\1\110\1\0\1\31"+ - "\2\0\1\30\1\u013e\32\41\1\164\12\371\1\u0174\1\161"+ - "\1\175\1\161\1\0\2\176\1\162\1\u0163\1\u0164\1\u0165"+ - "\2\0\1\107\1\161\4\0\2\161\2\0\1\53\1\0"+ - "\1\54\2\0\1\76\1\0\1\77\4\0\1\57\1\0"+ - "\1\60\1\0\1\61\2\0\1\62\3\0\1\100\2\0"+ - "\1\101\4\0\1\102\3\0\1\103\17\0\1\67\2\0"+ - "\1\104\21\0\1\105\2\0\1\106\57\0\1\30\2\31"+ - "\2\0\2\107\1\110\1\0\1\31\2\0\1\30\1\u013e"+ - "\32\41\1\164\2\u0242\1\371\2\u0242\2\371\1\u0242\1\371"+ - "\1\u0242\1\u0174\1\161\1\175\1\161\1\0\2\176\1\162"+ - "\1\u0163\1\u0164\1\u0165\2\0\1\107\1\161\4\0\2\161"+ - "\213\0\4\u02a2\2\0\1\u02a2\15\0\1\u02a2\6\0\12\u02a2"+ - "\1\u01fc\237\0\4\u02a3\2\0\1\u02a3\15\0\1\u02a3\6\0"+ - "\12\u02a3\1\u02a4\237\0\4\u02a5\2\0\1\u02a5\15\0\1\u02a5"+ - "\6\0\1\u02a6\2\u02a7\1\u02a6\5\u02a7\1\u02a8\14\0\1\u0146"+ - "\223\0\4\u02a9\2\0\1\u02a9\15\0\1\u02a9\6\0\12\u02a9"+ - "\1\u0248\13\0\1\u0146\223\0\4\u02a5\2\0\1\u02a5\15\0"+ - "\1\u02a5\6\0\1\u02a6\2\u02a7\1\u02a6\5\u02a7\1\u02a8\237\0"+ - "\1\u0188\4\u02a9\2\0\1\u02a9\15\0\1\u02a9\6\0\12\u02aa"+ - "\1\u0248\13\0\1\u0146\222\0\1\u0188\4\u02a9\2\0\1\u02a9"+ - "\15\0\1\u02a9\6\0\12\u02a9\1\u0248\13\0\1\u0146\222\0"+ - "\1\u0188\4\u02a9\2\0\1\u02a9\15\0\1\u02a9\6\0\2\u02aa"+ - "\1\u02a9\2\u02aa\2\u02a9\1\u02aa\1\u02a9\1\u02aa\1\u0248\13\0"+ - "\1\u0146\270\0\1\u01bd\13\0\1\u0146\222\0\1\u02ab\33\0"+ - "\12\u024e\237\0\1\u02ab\33\0\12\u02ac\237\0\1\u02ab\33\0"+ - "\1\u024e\1\u02ad\1\u02ac\2\u024e\2\u02ac\1\u024e\1\u02ac\1\u024e"+ - "\237\0\1\u0109\12\270\1\u018f\17\270\1\u010a\12\270\237\0"+ - "\1\u0109\11\270\1\u02ae\20\270\1\u010a\12\270\237\0\1\u0109"+ - "\3\270\1\u02af\26\270\1\u010a\12\270\237\0\1\u0109\7\270"+ - "\1\u02b0\22\270\1\u010a\4\270\1\u02b1\5\270\237\0\1\u0109"+ - "\10\270\1\u02b2\4\270\1\u02b3\5\270\1\u02b4\6\270\1\u010a"+ - "\12\270\237\0\1\u0109\3\270\1\u02b5\26\270\1\u010a\2\270"+ - "\1\u02b6\7\270\237\0\1\u0109\7\270\1\u02b7\22\270\1\u010a"+ - "\12\270\237\0\1\u0109\7\270\1\u02b8\22\270\1\u010a\12\270"+ - "\237\0\1\u0109\7\270\1\u02b9\22\270\1\u010a\3\270\1\u02ba"+ - "\6\270\237\0\1\u0109\32\270\1\u010a\5\270\1\u02bb\4\270"+ - "\237\0\1\u0109\7\270\1\u02bc\22\270\1\u010a\12\270\237\0"+ - "\1\u0109\31\270\1\u02bd\1\u010a\12\270\237\0\1\u0109\1\270"+ - "\1\u02be\30\270\1\u010a\12\270\237\0\1\u0109\7\270\1\u02bf"+ - "\1\270\1\u02c0\20\270\1\u010a\11\270\1\u02bb\237\0\1\u0109"+ - "\22\270\1\u02c1\7\270\1\u010a\2\270\1\u02c2\7\270\237\0"+ - "\1\u0109\6\270\1\u02c3\1\u02c4\22\270\1\u010a\12\270\237\0"+ - "\1\u0109\7\270\1\u02c5\5\270\1\u02c6\14\270\1\u010a\12\270"+ - "\237\0\1\u0109\23\270\1\u02c7\6\270\1\u010a\12\270\237\0"+ - "\1\u0109\32\270\1\u010a\3\270\1\u02c8\6\270\237\0\1\u0109"+ - "\3\270\1\u02c9\26\270\1\u010a\12\270\237\0\1\u0109\17\270"+ - "\1\u02ca\12\270\1\u010a\1\u02cb\11\270\237\0\1\u0109\32\270"+ - "\1\u010a\1\270\1\u02bb\10\270\237\0\1\u0109\32\270\1\u010a"+ - "\1\u02cc\11\270\273\0\12\u02cd\10\0\1\u018c\1\u018d\1\u018e"+ - "\224\0\1\u0121\25\324\1\u02ce\4\324\1\164\12\324\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0121\1\u02cf\31\324\1\164\12\324\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0121\15\324\1\u02d0\14\324\1\164\12\324"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\212\0\1\u0121\21\324\1\u02d1\10\324\1\164"+ - "\12\324\1\0\3\161\1\0\2\161\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\212\0\1\u0121\16\324\1\u02d2\4\324"+ - "\1\u02d3\6\324\1\164\12\324\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121"+ - "\4\324\1\u02d4\25\324\1\164\12\324\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\4\0\2\161\212\0"+ - "\1\u0121\32\324\1\164\11\324\1\u02d5\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\4\0\2\161\212\0"+ - "\1\u0121\4\324\1\u02d6\25\324\1\164\12\324\1\0\3\161"+ - "\1\0\2\161\1\162\3\161\3\0\1\161\4\0\2\161"+ - "\212\0\1\u0121\32\324\1\164\11\324\1\u02d7\1\0\3\161"+ - "\1\0\2\161\1\162\3\161\3\0\1\161\4\0\2\161"+ - "\212\0\1\u0121\24\324\1\u02d8\5\324\1\164\12\324\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0121\1\u02d9\1\u02da\1\324\1\u02db\20\324"+ - "\1\u02dc\5\324\1\164\5\324\1\u02dd\4\324\1\0\3\161"+ - "\1\0\2\161\1\162\3\161\3\0\1\161\4\0\2\161"+ - "\212\0\1\u0121\16\324\1\u02de\13\324\1\164\12\324\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0121\11\324\1\u02df\13\324\1\u02e0\4\324"+ - "\1\164\12\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\32\324\1\164"+ - "\11\324\1\u02e1\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\23\324\1\u02e2"+ - "\6\324\1\164\12\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121\31\324"+ - "\1\u02e3\1\164\12\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121\26\324"+ - "\1\u02e4\3\324\1\164\12\324\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121"+ - "\11\324\1\u02e5\20\324\1\164\12\324\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\4\0\2\161\212\0"+ - "\1\u0121\32\324\1\164\3\324\1\u02e6\6\324\1\0\3\161"+ - "\1\0\2\161\1\162\3\161\3\0\1\161\4\0\2\161"+ - "\212\0\1\u0121\5\324\1\u02e7\24\324\1\164\12\324\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0121\10\324\1\u02e8\21\324\1\164\12\324"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\212\0\1\u0121\3\324\1\u02e9\26\324\1\164"+ - "\12\324\1\0\3\161\1\0\2\161\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\212\0\1\u0121\21\324\1\u02ea\6\324"+ - "\1\u02eb\1\324\1\164\12\324\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121"+ - "\12\324\1\u02ec\17\324\1\164\12\324\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\4\0\2\161\212\0"+ - "\1\u0121\32\324\1\164\1\324\1\u02ed\10\324\1\0\3\161"+ - "\1\0\2\161\1\162\3\161\3\0\1\161\4\0\2\161"+ - "\212\0\1\u0121\24\324\1\u02ee\5\324\1\164\12\324\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0121\24\324\1\u02ef\5\324\1\164\12\324"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\212\0\1\u0121\32\324\1\164\4\324\1\u02f0"+ - "\5\324\1\0\3\161\1\0\2\161\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\212\0\1\u0121\5\324\1\u02f1\23\324"+ - "\1\u02f2\1\164\12\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\213\0\32\u022d\1\0"+ - "\12\u022d\240\0\32\u022d\1\u0286\12\u022d\240\0\4\u02f3\2\0"+ - "\1\u02f3\15\0\1\u02f3\6\0\12\u02f3\240\0\4\u02f4\2\0"+ - "\1\u02f4\15\0\1\u02f4\6\0\12\u02f4\1\u02f5\304\0\1\u02f6"+ - "\236\0\34\u01f0\12\u02f7\1\0\2\u01f0\1\u0234\3\u01f0\1\u01f2"+ - "\1\0\1\u0233\3\0\2\u01f0\4\0\1\u01f0\214\0\4\u02f8"+ - "\2\0\1\u02f8\15\0\1\u02f8\6\0\12\u02f8\257\0\1\u02f9"+ - "\265\0\4\u01f0\2\0\1\u01f0\15\0\1\u01f0\6\0\12\u01f0"+ - "\240\0\32\u0236\1\0\12\u0236\240\0\32\u0236\1\u028f\12\u0236"+ - "\273\0\12\u02fa\240\0\4\u02fb\2\0\1\u02fb\15\0\1\u02fb"+ - "\6\0\12\u02fb\1\u0292\237\0\4\u02fc\2\0\1\u02fc\15\0"+ - "\1\u02fc\6\0\12\u02fc\1\u02fd\237\0\4\u02fe\2\0\1\u02fe"+ - "\15\0\1\u02fe\6\0\1\u02ff\2\u0300\1\u02ff\5\u0300\1\u0301"+ - "\14\0\1\u0302\222\0\1\u0294\45\u0239\1\0\3\u0239\1\0"+ - "\2\u0239\1\u0295\3\u0239\3\0\1\u0239\1\u023b\3\0\2\u0239"+ - "\213\0\32\u0303\1\0\12\u0303\13\0\1\u0304\13\0\1\53"+ - "\1\0\1\54\2\0\1\221\1\0\1\222\4\0\1\57"+ - "\1\0\1\60\1\0\1\61\2\0\1\62\3\0\1\223"+ - "\2\0\1\224\4\0\1\225\3\0\1\226\17\0\1\67"+ - "\2\0\1\227\21\0\1\230\2\0\1\231\57\0\1\30"+ - "\1\74\7\0\1\74\2\0\1\30\1\u0294\32\u023a\13\u0239"+ - "\1\0\3\u0239\1\0\2\u0239\1\u0295\3\u0239\3\0\1\u0239"+ - "\1\u023b\3\0\2\u0239\2\0\1\53\1\0\1\54\2\0"+ - "\1\211\1\0\1\56\4\0\1\57\1\0\1\60\1\0"+ - "\1\61\2\0\1\62\3\0\1\212\2\0\1\213\4\0"+ - "\1\65\3\0\1\214\17\0\1\67\2\0\1\215\21\0"+ - "\1\216\2\0\1\217\57\0\1\30\2\73\2\0\2\220"+ - "\1\75\1\0\1\73\2\0\1\30\1\u0305\32\u023a\1\u0239"+ - "\12\u0297\1\0\1\u0239\1\u0298\1\u0239\1\0\2\u0306\1\u0295"+ - "\3\u0239\2\0\1\220\1\u0239\4\0\2\u0239\2\0\1\53"+ - "\1\0\1\54\2\0\1\232\1\0\1\56\4\0\1\57"+ - "\1\0\1\60\1\0\1\61\2\0\1\62\3\0\1\233"+ - "\2\0\1\234\4\0\1\65\3\0\1\235\17\0\1\67"+ - "\2\0\1\236\21\0\1\237\2\0\1\240\41\0\1\130"+ - "\15\0\1\30\1\75\1\73\1\132\3\0\1\75\1\0"+ - "\1\75\2\0\1\30\1\u0294\32\u023a\1\u0239\12\u0297\1\0"+ - "\1\u0239\1\u0298\1\u0239\1\0\2\u0239\1\u0295\3\u0239\3\0"+ - "\1\u0239\4\0\2\u0239\2\0\1\53\1\0\1\54\2\0"+ - "\1\221\1\0\1\222\4\0\1\57\1\0\1\60\1\0"+ - "\1\61\2\0\1\62\3\0\1\223\2\0\1\224\4\0"+ - "\1\225\3\0\1\226\17\0\1\67\2\0\1\227\21\0"+ - "\1\230\2\0\1\231\57\0\1\30\1\74\7\0\1\74"+ - "\2\0\1\30\1\u0294\32\u023a\13\u0239\1\0\3\u0239\1\0"+ - "\2\u0239\1\u0295\3\u0239\3\0\1\u0239\4\0\2\u0239\212\0"+ - "\1\u0307\54\0\1\u0295\227\0\74\u023b\211\0\1\u023c\32\u023d"+ - "\1\u023c\12\u023d\1\u023e\2\u023c\1\u023f\3\u023c\1\u0240\5\0"+ - "\2\u023c\4\0\1\u023c\213\0\1\u023c\32\u023d\1\u029d\12\u023d"+ - "\1\u023e\2\u023c\1\u023f\3\u023c\1\u0240\5\0\2\u023c\4\0"+ - "\1\u023c\213\0\34\u023e\12\u0308\1\0\2\u023e\1\u029f\3\u023e"+ - "\1\u0240\5\0\2\u023e\4\0\1\u023e\214\0\4\u0309\2\0"+ - "\1\u0309\15\0\1\u0309\6\0\12\u0309\240\0\4\u023c\2\0"+ - "\1\u023c\15\0\1\u023c\6\0\12\u023c\237\0\1\u030a\32\u02a1"+ - "\1\u030b\12\u02a1\1\u0174\7\0\1\u018c\1\u018d\1\u018e\272\0"+ - "\1\u01fc\237\0\4\u030c\2\0\1\u030c\15\0\1\u030c\6\0"+ - "\12\u030c\1\u02a4\237\0\4\u030d\2\0\1\u030d\15\0\1\u030d"+ - "\6\0\12\u030d\1\u030e\237\0\4\u030f\2\0\1\u030f\15\0"+ - "\1\u030f\6\0\12\u030f\1\u0310\13\0\1\u0146\222\0\1\u0188"+ - "\4\u030f\2\0\1\u030f\15\0\1\u030f\6\0\12\u0311\1\u0310"+ - "\13\0\1\u0146\222\0\1\u0188\4\u030f\2\0\1\u030f\15\0"+ - "\1\u030f\6\0\12\u0312\1\u0310\13\0\1\u0146\222\0\1\u0188"+ - "\4\u030f\2\0\1\u030f\15\0\1\u030f\6\0\1\u0311\1\u0313"+ - "\1\u0312\2\u0311\2\u0312\1\u0311\1\u0312\1\u0311\1\u0310\13\0"+ - "\1\u0146\223\0\4\u0314\2\0\1\u0314\15\0\1\u0314\6\0"+ - "\12\u0314\1\u0248\13\0\1\u0146\222\0\1\u0188\4\u0314\2\0"+ - "\1\u0314\15\0\1\u0314\6\0\12\u0314\1\u0248\13\0\1\u0146"+ - "\256\0\1\u0315\2\u0316\1\u0315\5\u0316\1\u0317\237\0\1\u02ab"+ - "\304\0\1\u02ab\33\0\2\u02ac\1\0\2\u02ac\2\0\1\u02ac"+ - "\1\0\1\u02ac\237\0\1\u0109\1\270\1\u0318\30\270\1\u010a"+ - "\12\270\237\0\1\u0109\24\270\1\u0319\5\270\1\u010a\12\270"+ - "\237\0\1\u0109\24\270\1\u031a\5\270\1\u010a\12\270\237\0"+ - "\1\u0109\1\270\1\u031b\30\270\1\u010a\12\270\237\0\1\u0109"+ - "\14\270\1\u031c\15\270\1\u010a\12\270\237\0\1\u0109\1\270"+ - "\1\u031d\30\270\1\u010a\12\270\237\0\1\u0109\1\270\1\u031e"+ - "\30\270\1\u010a\12\270\237\0\1\u0109\1\270\1\u031f\30\270"+ - "\1\u010a\12\270\237\0\1\u0109\21\270\1\u0320\10\270\1\u010a"+ - "\12\270\237\0\1\u0109\24\270\1\u0321\5\270\1\u010a\12\270"+ - "\237\0\1\u0109\24\270\1\u0322\5\270\1\u010a\12\270\237\0"+ - "\1\u0109\24\270\1\u0323\5\270\1\u010a\12\270\237\0\1\u0109"+ - "\1\u01cc\31\270\1\u010a\12\270\237\0\1\u0109\24\270\1\u031f"+ - "\5\270\1\u010a\12\270\237\0\1\u0109\24\270\1\u0324\5\270"+ - "\1\u010a\12\270\237\0\1\u0109\1\270\1\u0325\30\270\1\u010a"+ - "\12\270\237\0\1\u0109\31\270\1\u0326\1\u010a\12\270\237\0"+ - "\1\u0109\24\270\1\u0327\5\270\1\u010a\12\270\237\0\1\u0109"+ - "\1\270\1\u0328\30\270\1\u010a\12\270\237\0\1\u0109\1\u0329"+ - "\31\270\1\u010a\12\270\237\0\1\u0109\21\270\1\u032a\10\270"+ - "\1\u010a\12\270\237\0\1\u0109\4\270\1\u032b\25\270\1\u010a"+ - "\12\270\237\0\1\u0109\24\270\1\u032c\5\270\1\u010a\12\270"+ - "\237\0\1\u0109\24\270\1\u032d\5\270\1\u010a\12\270\237\0"+ - "\1\u0109\4\270\1\u032e\25\270\1\u010a\12\270\237\0\1\u0109"+ - "\21\270\1\u032f\10\270\1\u010a\12\270\237\0\1\u0109\24\270"+ - "\1\u0330\5\270\1\u010a\12\270\237\0\1\u0109\32\270\1\u010a"+ - "\1\u0331\11\270\237\0\1\u0109\32\270\1\u010a\7\270\1\u0332"+ - "\2\270\237\0\1\u0109\1\u0333\31\270\1\u010a\12\270\237\0"+ - "\1\u0109\1\u0334\31\270\1\u010a\12\270\315\0\1\u018c\1\u018d"+ - "\1\u018e\224\0\1\u0121\1\324\1\u0335\30\324\1\164\12\324"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\212\0\1\u0121\32\324\1\164\1\u0336\11\324"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\212\0\1\u0121\6\324\1\u0337\23\324\1\164"+ - "\12\324\1\0\3\161\1\0\2\161\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\212\0\1\u0121\32\324\1\164\7\324"+ - "\1\u0338\2\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\32\324\1\164"+ - "\10\324\1\u017b\1\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121\32\324"+ - "\1\164\5\324\1\u017b\4\324\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121"+ - "\26\324\1\u0339\3\324\1\164\12\324\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\4\0\2\161\212\0"+ - "\1\u0121\1\324\1\u033a\30\324\1\164\12\324\1\0\3\161"+ - "\1\0\2\161\1\162\3\161\3\0\1\161\4\0\2\161"+ - "\212\0\1\u0121\26\324\1\u033b\3\324\1\164\12\324\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0121\32\324\1\164\1\324\1\u033c\10\324"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\212\0\1\u0121\1\u033d\31\324\1\164\12\324"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\212\0\1\u0121\1\u033e\27\324\1\u033f\1\324"+ - "\1\164\12\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\32\324\1\164"+ - "\1\u0340\11\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\4\324\1\u0341"+ - "\25\324\1\164\12\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121\25\324"+ - "\1\u0342\4\324\1\164\12\324\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121"+ - "\1\u0343\31\324\1\164\12\324\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121"+ - "\32\324\1\164\1\u0344\11\324\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121"+ - "\32\324\1\164\2\324\1\350\7\324\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\4\0\2\161\212\0"+ - "\1\u0121\32\324\1\164\3\324\1\u0345\6\324\1\0\3\161"+ - "\1\0\2\161\1\162\3\161\3\0\1\161\4\0\2\161"+ - "\212\0\1\u0121\1\u0346\1\324\1\u0347\27\324\1\164\12\324"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\212\0\1\u0121\1\u0338\31\324\1\164\12\324"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\212\0\1\u0121\32\324\1\164\2\324\1\u0348"+ - "\7\324\1\0\3\161\1\0\2\161\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\212\0\1\u0121\32\324\1\164\2\324"+ - "\1\u0349\7\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\15\324\1\u034a"+ - "\14\324\1\164\12\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121\32\324"+ - "\1\164\5\324\1\u034b\4\324\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121"+ - "\32\324\1\164\7\324\1\u034c\2\324\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\4\0\2\161\212\0"+ - "\1\u0121\32\324\1\164\11\324\1\u034d\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\4\0\2\161\212\0"+ - "\1\u0121\1\324\1\u034e\30\324\1\164\12\324\1\0\3\161"+ - "\1\0\2\161\1\162\3\161\3\0\1\161\4\0\2\161"+ - "\212\0\1\u0121\32\324\1\164\3\324\1\u034f\6\324\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0121\32\324\1\164\1\324\1\u0350\10\324"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\212\0\1\u0121\32\324\1\164\1\324\1\u0351"+ - "\10\324\1\0\3\161\1\0\2\161\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\212\0\1\u0121\24\324\1\u0352\5\324"+ - "\1\164\12\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\32\324\1\164"+ - "\6\324\1\u0353\3\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121\32\324"+ - "\1\164\3\324\1\u0354\6\324\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121"+ - "\1\u0345\31\324\1\164\12\324\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121"+ - "\32\324\1\164\11\324\1\u0355\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121"+ - "\25\324\1\u0356\4\324\1\164\12\324\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\4\0\2\161\213\0"+ - "\4\u022e\2\0\1\u022e\15\0\1\u022e\6\0\12\u022e\240\0"+ - "\4\u0357\2\0\1\u0357\15\0\1\u0357\6\0\12\u0357\1\u02f5"+ - "\237\0\4\u0358\2\0\1\u0358\15\0\1\u0358\6\0\12\u0358"+ - "\1\u0359\237\0\4\u035a\2\0\1\u035a\15\0\1\u035a\6\0"+ - "\1\u035b\2\u035c\1\u035b\5\u035c\1\u035d\14\0\1\u035e\222\0"+ - "\34\u01f0\12\u035f\1\0\2\u01f0\1\u0234\3\u01f0\1\u01f2\1\0"+ - "\1\u0233\3\0\2\u01f0\4\0\1\u01f0\214\0\4\u0233\2\0"+ - "\1\u0233\15\0\1\u0233\6\0\12\u0233\270\0\1\u0360\307\0"+ - "\12\u0361\11\0\1\u0233\226\0\4\u0362\2\0\1\u0362\15\0"+ - "\1\u0362\6\0\12\u0362\1\u0292\237\0\4\u0363\2\0\1\u0363"+ - "\15\0\1\u0363\6\0\12\u0363\1\u0364\237\0\4\u0365\2\0"+ - "\1\u0365\15\0\1\u0365\6\0\1\u0366\2\u0367\1\u0366\5\u0367"+ - "\1\u0368\14\0\1\u0302\223\0\4\u0369\2\0\1\u0369\15\0"+ - "\1\u0369\6\0\12\u0369\1\u036a\13\0\1\u0302\222\0\1\u036b"+ - "\4\u0369\2\0\1\u0369\15\0\1\u0369\6\0\12\u036c\1\u036a"+ - "\13\0\1\u0302\222\0\1\u036b\4\u0369\2\0\1\u0369\15\0"+ - "\1\u0369\6\0\12\u036d\1\u036a\13\0\1\u0302\222\0\1\u036b"+ - "\4\u0369\2\0\1\u0369\15\0\1\u0369\6\0\1\u036c\1\u036e"+ - "\1\u036d\2\u036c\2\u036d\1\u036c\1\u036d\1\u036c\1\u036a\13\0"+ - "\1\u0302\270\0\1\u0290\10\0\1\u0233\225\0\1\u036f\32\u0303"+ - "\1\u0370\12\u0303\237\0\61\u0304\1\0\1\u0371\4\u0304\1\u0372"+ - "\1\0\3\u0304\6\0\1\u0100\1\0\1\u0101\17\0\1\u0102"+ - "\2\0\1\u0103\4\0\1\u0104\3\0\1\u0105\22\0\1\u0106"+ - "\21\0\1\u0107\2\0\1\u0108\60\0\1\220\1\73\6\0"+ - "\1\220\3\0\1\u0294\33\u0239\12\u0297\1\0\3\u0239\1\0"+ - "\2\u0239\1\u0295\3\u0239\3\0\1\u0239\1\u023b\3\0\2\u0239"+ - "\7\0\1\u0100\1\0\1\u0101\17\0\1\u0102\2\0\1\u0103"+ - "\4\0\1\u0104\3\0\1\u0105\22\0\1\u0106\21\0\1\u0107"+ - "\2\0\1\u0108\60\0\1\220\1\73\6\0\1\220\3\0"+ - "\1\u0294\33\u0239\12\u0297\1\0\3\u0239\1\0\2\u0239\1\u0295"+ - "\3\u0239\3\0\1\u0239\4\0\2\u0239\212\0\46\u0239\1\0"+ - "\3\u0239\1\0\2\u0239\1\0\3\u0239\3\0\1\u0239\1\u023b"+ - "\3\0\2\u0239\212\0\34\u023e\12\u0373\1\0\2\u023e\1\u029f"+ - "\3\u023e\1\u0240\1\u018c\1\u018d\1\u018e\2\0\2\u023e\4\0"+ - "\1\u023e\214\0\4\u023e\2\0\1\u023e\15\0\1\u023e\6\0"+ - "\12\u023e\240\0\32\u02a1\1\0\12\u02a1\240\0\32\u02a1\1\u030b"+ - "\12\u02a1\240\0\4\u0374\2\0\1\u0374\15\0\1\u0374\6\0"+ - "\12\u0374\1\u02a4\237\0\4\u0375\2\0\1\u0375\15\0\1\u0375"+ - "\6\0\12\u0375\1\u0376\237\0\4\u0377\2\0\1\u0377\15\0"+ - "\1\u0377\6\0\1\u0378\2\u0379\1\u0378\5\u0379\1\u037a\14\0"+ - "\1\u0146\223\0\4\u037b\2\0\1\u037b\15\0\1\u037b\6\0"+ - "\12\u037b\1\u0310\13\0\1\u0146\223\0\4\u0377\2\0\1\u0377"+ - "\15\0\1\u0377\6\0\1\u0378\2\u0379\1\u0378\5\u0379\1\u037a"+ - "\237\0\1\u0188\4\u037b\2\0\1\u037b\15\0\1\u037b\6\0"+ - "\12\u037c\1\u0310\13\0\1\u0146\222\0\1\u0188\4\u037b\2\0"+ - "\1\u037b\15\0\1\u037b\6\0\12\u037b\1\u0310\13\0\1\u0146"+ - "\222\0\1\u0188\4\u037b\2\0\1\u037b\15\0\1\u037b\6\0"+ - "\2\u037c\1\u037b\2\u037c\2\u037b\1\u037c\1\u037b\1\u037c\1\u0310"+ - "\13\0\1\u0146\270\0\1\u0248\13\0\1\u0146\256\0\12\u0316"+ - "\14\0\1\u0146\256\0\12\u037d\14\0\1\u0146\256\0\1\u0316"+ - "\1\u037e\1\u037d\2\u0316\2\u037d\1\u0316\1\u037d\1\u0316\14\0"+ - "\1\u0146\222\0\1\u0109\25\270\1\u037f\4\270\1\u010a\12\270"+ - "\237\0\1\u0109\1\u0380\31\270\1\u010a\12\270\237\0\1\u0109"+ - "\15\270\1\u0381\14\270\1\u010a\12\270\237\0\1\u0109\21\270"+ - "\1\u0382\10\270\1\u010a\12\270\237\0\1\u0109\16\270\1\u0383"+ - "\4\270\1\u0384\6\270\1\u010a\12\270\237\0\1\u0109\4\270"+ - "\1\u0385\25\270\1\u010a\12\270\237\0\1\u0109\32\270\1\u010a"+ - "\11\270\1\u0386\237\0\1\u0109\4\270\1\u0387\25\270\1\u010a"+ - "\12\270\237\0\1\u0109\32\270\1\u010a\11\270\1\u0388\237\0"+ - "\1\u0109\24\270\1\u0389\5\270\1\u010a\12\270\237\0\1\u0109"+ - "\1\u038a\1\u038b\1\270\1\u038c\20\270\1\u038d\5\270\1\u010a"+ - "\5\270\1\u038e\4\270\237\0\1\u0109\16\270\1\u038f\13\270"+ - "\1\u010a\12\270\237\0\1\u0109\11\270\1\u0390\13\270\1\u0391"+ - "\4\270\1\u010a\12\270\237\0\1\u0109\32\270\1\u010a\11\270"+ - "\1\u0392\237\0\1\u0109\23\270\1\u0393\6\270\1\u010a\12\270"+ - "\237\0\1\u0109\31\270\1\u0394\1\u010a\12\270\237\0\1\u0109"+ - "\26\270\1\u0395\3\270\1\u010a\12\270\237\0\1\u0109\11\270"+ - "\1\u0396\20\270\1\u010a\12\270\237\0\1\u0109\32\270\1\u010a"+ - "\3\270\1\u0397\6\270\237\0\1\u0109\5\270\1\u0398\24\270"+ - "\1\u010a\12\270\237\0\1\u0109\10\270\1\u0399\21\270\1\u010a"+ - "\12\270\237\0\1\u0109\3\270\1\u039a\26\270\1\u010a\12\270"+ - "\237\0\1\u0109\21\270\1\u039b\6\270\1\u039c\1\270\1\u010a"+ - "\12\270\237\0\1\u0109\12\270\1\u039d\17\270\1\u010a\12\270"+ - "\237\0\1\u0109\32\270\1\u010a\1\270\1\u039e\10\270\237\0"+ - "\1\u0109\24\270\1\u039f\5\270\1\u010a\12\270\237\0\1\u0109"+ - "\24\270\1\u03a0\5\270\1\u010a\12\270\237\0\1\u0109\32\270"+ - "\1\u010a\4\270\1\u03a1\5\270\237\0\1\u0109\5\270\1\u03a2"+ - "\23\270\1\u03a3\1\u010a\12\270\237\0\1\u0121\32\324\1\164"+ - "\1\u03a4\11\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\1\u03a5\31\324"+ - "\1\164\12\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\32\324\1\164"+ - "\10\324\1\u03a6\1\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121\25\324"+ - "\1\u0127\4\324\1\164\12\324\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121"+ - "\32\324\1\164\5\324\1\u03a7\4\324\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\4\0\2\161\212\0"+ - "\1\u0121\32\324\1\164\5\324\1\u03a8\4\324\1\0\3\161"+ - "\1\0\2\161\1\162\3\161\3\0\1\161\4\0\2\161"+ - "\212\0\1\u0121\32\324\1\164\5\324\1\u0345\4\324\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0121\32\324\1\164\3\324\1\u03a5\6\324"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\212\0\1\u0121\17\324\1\u03a9\12\324\1\164"+ - "\12\324\1\0\3\161\1\0\2\161\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\212\0\1\u0121\12\324\1\u03aa\17\324"+ - "\1\164\12\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\25\324\1\u03ab"+ - "\4\324\1\164\12\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121\1\u03ac"+ - "\31\324\1\164\12\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121\15\324"+ - "\1\u03ad\14\324\1\164\12\324\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121"+ - "\32\324\1\164\3\324\1\u03ae\6\324\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\4\0\2\161\212\0"+ - "\1\u0121\21\324\1\u03af\10\324\1\164\12\324\1\0\3\161"+ - "\1\0\2\161\1\162\3\161\3\0\1\161\4\0\2\161"+ - "\212\0\1\u0121\2\324\1\u0338\27\324\1\164\12\324\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0121\1\324\1\u0127\30\324\1\164\12\324"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\212\0\1\u0121\11\324\1\u03b0\20\324\1\164"+ - "\12\324\1\0\3\161\1\0\2\161\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\212\0\1\u0121\11\324\1\u03b1\20\324"+ - "\1\164\12\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\1\u03b2\31\324"+ - "\1\164\12\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\1\u03b3\31\324"+ - "\1\164\12\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\2\324\1\u03b4"+ - "\27\324\1\164\12\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121\32\324"+ - "\1\164\4\324\1\u012e\5\324\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121"+ - "\10\324\1\u03b5\21\324\1\164\12\324\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\4\0\2\161\212\0"+ - "\1\u0121\1\u03b6\31\324\1\164\12\324\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\4\0\2\161\212\0"+ - "\1\u0121\25\324\1\u03b7\4\324\1\164\12\324\1\0\3\161"+ - "\1\0\2\161\1\162\3\161\3\0\1\161\4\0\2\161"+ - "\212\0\1\u0121\32\324\1\164\4\324\1\u03a5\5\324\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0121\32\324\1\164\6\324\1\u03a5\3\324"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\212\0\1\u0121\32\324\1\164\2\324\1\u03a5"+ - "\7\324\1\0\3\161\1\0\2\161\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\212\0\1\u0121\16\324\1\u03b8\13\324"+ - "\1\164\12\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\32\324\1\164"+ - "\1\u03b9\11\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\32\324\1\164"+ - "\3\324\1\u03ba\6\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121\32\324"+ - "\1\164\3\324\1\350\6\324\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121"+ - "\24\324\1\u03bb\5\324\1\164\12\324\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\4\0\2\161\213\0"+ - "\4\u03bc\2\0\1\u03bc\15\0\1\u03bc\6\0\12\u03bc\1\u02f5"+ - "\237\0\4\u03bd\2\0\1\u03bd\15\0\1\u03bd\6\0\12\u03bd"+ - "\1\u03be\237\0\4\u03bf\2\0\1\u03bf\15\0\1\u03bf\6\0"+ - "\1\u03c0\2\u03c1\1\u03c0\5\u03c1\1\u03c2\14\0\1\u035e\223\0"+ - "\4\u03c3\2\0\1\u03c3\15\0\1\u03c3\6\0\12\u03c3\1\u03c4"+ - "\13\0\1\u035e\222\0\1\u03c5\4\u03c3\2\0\1\u03c3\15\0"+ - "\1\u03c3\6\0\12\u03c6\1\u03c4\13\0\1\u035e\222\0\1\u03c5"+ - "\4\u03c3\2\0\1\u03c3\15\0\1\u03c3\6\0\12\u03c7\1\u03c4"+ - "\13\0\1\u035e\222\0\1\u03c5\4\u03c3\2\0\1\u03c3\15\0"+ - "\1\u03c3\6\0\1\u03c6\1\u03c8\1\u03c7\2\u03c6\2\u03c7\1\u03c6"+ - "\1\u03c7\1\u03c6\1\u03c4\13\0\1\u035e\301\0\1\u022e\225\0"+ - "\34\u01f0\12\u03c9\1\0\2\u01f0\1\u0234\3\u01f0\1\u01f2\1\0"+ - "\1\u0233\3\0\2\u01f0\4\0\1\u01f0\231\0\1\u03ca\322\0"+ - "\12\u03cb\11\0\1\u0233\273\0\1\u0292\237\0\4\u03cc\2\0"+ - "\1\u03cc\15\0\1\u03cc\6\0\12\u03cc\1\u0364\237\0\4\u03cd"+ - "\2\0\1\u03cd\15\0\1\u03cd\6\0\12\u03cd\1\u03ce\237\0"+ - "\4\u03cf\2\0\1\u03cf\15\0\1\u03cf\6\0\12\u03cf\1\u03d0"+ - "\13\0\1\u0302\222\0\1\u036b\4\u03cf\2\0\1\u03cf\15\0"+ - "\1\u03cf\6\0\12\u03d1\1\u03d0\13\0\1\u0302\222\0\1\u036b"+ - "\4\u03cf\2\0\1\u03cf\15\0\1\u03cf\6\0\12\u03d2\1\u03d0"+ - "\13\0\1\u0302\222\0\1\u036b\4\u03cf\2\0\1\u03cf\15\0"+ - "\1\u03cf\6\0\1\u03d1\1\u03d3\1\u03d2\2\u03d1\2\u03d2\1\u03d1"+ - "\1\u03d2\1\u03d1\1\u03d0\13\0\1\u0302\223\0\4\u03d4\2\0"+ - "\1\u03d4\15\0\1\u03d4\6\0\12\u03d4\1\u036a\13\0\1\u0302"+ - "\223\0\4\u0365\2\0\1\u0365\15\0\1\u0365\6\0\1\u0366"+ - "\2\u0367\1\u0366\5\u0367\1\u0368\273\0\1\u03d5\2\u03d6\1\u03d5"+ - "\5\u03d6\1\u03d7\237\0\1\u036b\4\u03d4\2\0\1\u03d4\15\0"+ - "\1\u03d4\6\0\12\u03d8\1\u036a\13\0\1\u0302\222\0\1\u036b"+ - "\4\u03d4\2\0\1\u03d4\15\0\1\u03d4\6\0\12\u03d4\1\u036a"+ - "\13\0\1\u0302\222\0\1\u036b\4\u03d4\2\0\1\u03d4\15\0"+ - "\1\u03d4\6\0\2\u03d8\1\u03d4\2\u03d8\2\u03d4\1\u03d8\1\u03d4"+ - "\1\u03d8\1\u036a\13\0\1\u0302\223\0\1\u03d9\1\u03da\1\u03db"+ - "\1\u03dc\1\u03dd\1\u03de\1\u03df\1\u03e0\1\u03e1\1\u03e2\1\u03e3"+ - "\1\u03e4\1\u03e5\1\u03e6\1\u03e7\1\u03e8\1\u03e9\1\u03ea\1\u03eb"+ - "\1\u03ec\1\u03ed\1\u03ee\1\u03ef\1\u03f0\1\u03f1\1\u03f2\1\0"+ - "\12\u0303\240\0\32\u0303\1\u0370\12\u0303\237\0\74\u0304\211\0"+ - "\34\u023e\12\u03f3\1\0\2\u023e\1\u029f\3\u023e\1\u0240\1\u018c"+ - "\1\u018d\1\u018e\2\0\2\u023e\4\0\1\u023e\261\0\1\u02a4"+ - "\237\0\4\u03f4\2\0\1\u03f4\15\0\1\u03f4\6\0\12\u03f4"+ - "\1\u0376\237\0\4\u03f5\2\0\1\u03f5\15\0\1\u03f5\6\0"+ - "\12\u03f5\1\u03f6\237\0\4\u03f7\2\0\1\u03f7\15\0\1\u03f7"+ - "\6\0\12\u03f7\1\u03f8\13\0\1\u0146\222\0\1\u0188\4\u03f7"+ - "\2\0\1\u03f7\15\0\1\u03f7\6\0\12\u03f9\1\u03f8\13\0"+ - "\1\u0146\222\0\1\u0188\4\u03f7\2\0\1\u03f7\15\0\1\u03f7"+ - "\6\0\12\u03fa\1\u03f8\13\0\1\u0146\222\0\1\u0188\4\u03f7"+ - "\2\0\1\u03f7\15\0\1\u03f7\6\0\1\u03f9\1\u03fb\1\u03fa"+ - "\2\u03f9\2\u03fa\1\u03f9\1\u03fa\1\u03f9\1\u03f8\13\0\1\u0146"+ - "\223\0\4\u03fc\2\0\1\u03fc\15\0\1\u03fc\6\0\12\u03fc"+ - "\1\u0310\13\0\1\u0146\222\0\1\u0188\4\u03fc\2\0\1\u03fc"+ - "\15\0\1\u03fc\6\0\12\u03fc\1\u0310\13\0\1\u0146\304\0"+ - "\1\u0146\256\0\2\u037d\1\0\2\u037d\2\0\1\u037d\1\0"+ - "\1\u037d\14\0\1\u0146\222\0\1\u0109\1\270\1\u03fd\30\270"+ - "\1\u010a\12\270\237\0\1\u0109\32\270\1\u010a\1\u03fe\11\270"+ - "\237\0\1\u0109\6\270\1\u03ff\23\270\1\u010a\12\270\237\0"+ - "\1\u0109\32\270\1\u010a\7\270\1\u0400\2\270\237\0\1\u0109"+ - "\32\270\1\u010a\10\270\1\u01d1\1\270\237\0\1\u0109\32\270"+ - "\1\u010a\5\270\1\u01d1\4\270\237\0\1\u0109\26\270\1\u0401"+ - "\3\270\1\u010a\12\270\237\0\1\u0109\1\270\1\u0402\30\270"+ - "\1\u010a\12\270\237\0\1\u0109\26\270\1\u0403\3\270\1\u010a"+ - "\12\270\237\0\1\u0109\32\270\1\u010a\1\270\1\u0404\10\270"+ - "\237\0\1\u0109\1\u0405\31\270\1\u010a\12\270\237\0\1\u0109"+ - "\1\u0406\27\270\1\u0407\1\270\1\u010a\12\270\237\0\1\u0109"+ - "\32\270\1\u010a\1\u0408\11\270\237\0\1\u0109\4\270\1\u0409"+ - "\25\270\1\u010a\12\270\237\0\1\u0109\25\270\1\u040a\4\270"+ - "\1\u010a\12\270\237\0\1\u0109\1\u040b\31\270\1\u010a\12\270"+ - "\237\0\1\u0109\32\270\1\u010a\1\u040c\11\270\237\0\1\u0109"+ - "\32\270\1\u010a\2\270\1\u0153\7\270\237\0\1\u0109\32\270"+ - "\1\u010a\3\270\1\u040d\6\270\237\0\1\u0109\1\u040e\1\270"+ - "\1\u040f\27\270\1\u010a\12\270\237\0\1\u0109\1\u0400\31\270"+ - "\1\u010a\12\270\237\0\1\u0109\32\270\1\u010a\2\270\1\u0410"+ - "\7\270\237\0\1\u0109\32\270\1\u010a\2\270\1\u0411\7\270"+ - "\237\0\1\u0109\15\270\1\u0412\14\270\1\u010a\12\270\237\0"+ - "\1\u0109\32\270\1\u010a\5\270\1\u0413\4\270\237\0\1\u0109"+ - "\32\270\1\u010a\7\270\1\u0414\2\270\237\0\1\u0109\32\270"+ - "\1\u010a\11\270\1\u0415\237\0\1\u0109\1\270\1\u0416\30\270"+ - "\1\u010a\12\270\237\0\1\u0109\32\270\1\u010a\3\270\1\u0417"+ - "\6\270\237\0\1\u0109\32\270\1\u010a\1\270\1\u0418\10\270"+ - "\237\0\1\u0109\32\270\1\u010a\1\270\1\u0419\10\270\237\0"+ - "\1\u0109\24\270\1\u041a\5\270\1\u010a\12\270\237\0\1\u0109"+ - "\32\270\1\u010a\6\270\1\u041b\3\270\237\0\1\u0109\32\270"+ - "\1\u010a\3\270\1\u041c\6\270\237\0\1\u0109\1\u040d\31\270"+ - "\1\u010a\12\270\237\0\1\u0109\32\270\1\u010a\11\270\1\u041d"+ - "\237\0\1\u0109\25\270\1\u041e\4\270\1\u010a\12\270\237\0"+ - "\1\u0121\3\324\1\u041f\26\324\1\164\12\324\1\0\3\161"+ - "\1\0\2\161\1\162\3\161\3\0\1\161\4\0\2\161"+ - "\212\0\1\u0121\2\324\1\u0127\27\324\1\164\12\324\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0121\6\324\1\u0132\23\324\1\164\12\324"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\212\0\1\u0121\1\324\1\u034f\30\324\1\164"+ - "\12\324\1\0\3\161\1\0\2\161\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\212\0\1\u0121\3\324\1\u0420\26\324"+ - "\1\164\12\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\32\324\1\164"+ - "\3\324\1\u0421\6\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121\32\324"+ - "\1\164\6\324\1\u0422\3\324\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121"+ - "\32\324\1\164\6\324\1\u0423\3\324\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\4\0\2\161\212\0"+ - "\1\u0121\32\324\1\164\5\324\1\u0424\4\324\1\0\3\161"+ - "\1\0\2\161\1\162\3\161\3\0\1\161\4\0\2\161"+ - "\212\0\1\u0121\32\324\1\164\7\324\1\u0425\2\324\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0121\1\u0426\31\324\1\164\12\324\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0121\24\324\1\u0427\5\324\1\164\12\324"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\212\0\1\u0121\32\324\1\164\4\324\1\u0428"+ - "\5\324\1\0\3\161\1\0\2\161\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\212\0\1\u0121\32\324\1\164\4\324"+ - "\1\u0429\5\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\26\324\1\u042a"+ - "\3\324\1\164\12\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121\30\324"+ - "\1\u042b\1\324\1\164\12\324\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121"+ - "\11\324\1\u0176\20\324\1\164\12\324\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\4\0\2\161\212\0"+ - "\1\u0121\32\324\1\164\2\324\1\u042c\7\324\1\0\3\161"+ - "\1\0\2\161\1\162\3\161\3\0\1\161\4\0\2\161"+ - "\212\0\1\u0121\12\324\1\u042d\17\324\1\164\12\324\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0121\17\324\1\u012f\12\324\1\164\12\324"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\212\0\1\u0121\32\324\1\164\4\324\1\u042e"+ - "\5\324\1\0\3\161\1\0\2\161\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\212\0\1\u0121\32\324\1\164\6\324"+ - "\1\u0179\3\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\30\324\1\u042f"+ - "\1\324\1\164\12\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121\30\324"+ - "\1\u0430\1\324\1\164\12\324\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\260\0\1\u02f5"+ - "\237\0\4\u0431\2\0\1\u0431\15\0\1\u0431\6\0\12\u0431"+ - "\1\u03be\237\0\4\u0432\2\0\1\u0432\15\0\1\u0432\6\0"+ - "\12\u0432\1\u0433\237\0\4\u0434\2\0\1\u0434\15\0\1\u0434"+ - "\6\0\12\u0434\1\u0435\13\0\1\u035e\222\0\1\u03c5\4\u0434"+ - "\2\0\1\u0434\15\0\1\u0434\6\0\12\u0436\1\u0435\13\0"+ - "\1\u035e\222\0\1\u03c5\4\u0434\2\0\1\u0434\15\0\1\u0434"+ - "\6\0\12\u0437\1\u0435\13\0\1\u035e\222\0\1\u03c5\4\u0434"+ - "\2\0\1\u0434\15\0\1\u0434\6\0\1\u0436\1\u0438\1\u0437"+ - "\2\u0436\2\u0437\1\u0436\1\u0437\1\u0436\1\u0435\13\0\1\u035e"+ - "\223\0\4\u0439\2\0\1\u0439\15\0\1\u0439\6\0\12\u0439"+ - "\1\u03c4\13\0\1\u035e\223\0\4\u03bf\2\0\1\u03bf\15\0"+ - "\1\u03bf\6\0\1\u03c0\2\u03c1\1\u03c0\5\u03c1\1\u03c2\273\0"+ - "\1\u043a\2\u043b\1\u043a\5\u043b\1\u043c\237\0\1\u03c5\4\u0439"+ - "\2\0\1\u0439\15\0\1\u0439\6\0\12\u043d\1\u03c4\13\0"+ - "\1\u035e\222\0\1\u03c5\4\u0439\2\0\1\u0439\15\0\1\u0439"+ - "\6\0\12\u0439\1\u03c4\13\0\1\u035e\222\0\1\u03c5\4\u0439"+ - "\2\0\1\u0439\15\0\1\u0439\6\0\2\u043d\1\u0439\2\u043d"+ - "\2\u0439\1\u043d\1\u0439\1\u043d\1\u03c4\13\0\1\u035e\222\0"+ - "\34\u01f0\12\u043e\1\0\2\u01f0\1\u0234\3\u01f0\1\u01f2\1\0"+ - "\1\u0233\3\0\2\u01f0\4\0\1\u01f0\217\0\1\u043f\334\0"+ - "\12\u0440\11\0\1\u0233\226\0\4\u0441\2\0\1\u0441\15\0"+ - "\1\u0441\6\0\12\u0441\1\u0364\237\0\4\u0442\2\0\1\u0442"+ - "\15\0\1\u0442\6\0\12\u0442\1\u0443\237\0\4\u0444\2\0"+ - "\1\u0444\15\0\1\u0444\6\0\1\u0445\2\u0446\1\u0445\5\u0446"+ - "\1\u0447\14\0\1\u0302\223\0\4\u0448\2\0\1\u0448\15\0"+ - "\1\u0448\6\0\12\u0448\1\u03d0\13\0\1\u0302\223\0\4\u0444"+ - "\2\0\1\u0444\15\0\1\u0444\6\0\1\u0445\2\u0446\1\u0445"+ - "\5\u0446\1\u0447\237\0\1\u036b\4\u0448\2\0\1\u0448\15\0"+ - "\1\u0448\6\0\12\u0449\1\u03d0\13\0\1\u0302\222\0\1\u036b"+ - "\4\u0448\2\0\1\u0448\15\0\1\u0448\6\0\12\u0448\1\u03d0"+ - "\13\0\1\u0302\222\0\1\u036b\4\u0448\2\0\1\u0448\15\0"+ - "\1\u0448\6\0\2\u0449\1\u0448\2\u0449\2\u0448\1\u0449\1\u0448"+ - "\1\u0449\1\u03d0\13\0\1\u0302\223\0\4\u044a\2\0\1\u044a"+ - "\15\0\1\u044a\6\0\12\u044a\1\u036a\13\0\1\u0302\222\0"+ - "\1\u044b\33\0\12\u03d6\237\0\1\u044b\33\0\12\u044c\237\0"+ - "\1\u044b\33\0\1\u03d6\1\u044d\1\u044c\2\u03d6\2\u044c\1\u03d6"+ - "\1\u044c\1\u03d6\237\0\1\u036b\4\u044a\2\0\1\u044a\15\0"+ - "\1\u044a\6\0\12\u044a\1\u036a\13\0\1\u0302\222\0\1\u036f"+ - "\1\u0303\2\u044e\1\u044f\1\u0450\10\u044e\1\u0303\1\u0451\5\u044e"+ - "\6\u0303\1\u0370\12\u0303\237\0\1\u036f\1\u0452\2\u044e\1\u0303"+ - "\1\u044e\1\u0453\6\u044e\4\u0303\4\u044e\1\u0303\1\u044e\1\u0303"+ - "\3\u044e\1\u0370\12\u0303\237\0\1\u036f\3\u0303\1\u044e\1\u0303"+ - "\1\u044e\4\u0303\1\u044e\10\u0303\1\u044e\2\u0303\1\u044e\2\u0303"+ - "\1\u044e\1\u0370\12\u0303\237\0\1\u036f\1\u0303\1\u044e\1\u0454"+ - "\2\u044e\2\u0303\1\u044e\6\u0303\3\u044e\11\u0303\1\u0370\12\u0303"+ - "\237\0\1\u036f\3\u0303\1\u044e\1\u0303\1\u044e\10\u0303\1\u044e"+ - "\1\u0303\2\u044e\10\u0303\1\u0370\12\u0303\237\0\1\u036f\4\u0303"+ - "\1\u0455\5\u0303\1\u044e\17\u0303\1\u0370\12\u0303\237\0\1\u036f"+ - "\4\u0303\2\u044e\2\u0303\1\u044e\1\u0303\1\u044e\13\u0303\1\u044e"+ - "\2\u0303\1\u044e\1\u0370\12\u0303\237\0\1\u036f\1\u044e\1\u0303"+ - "\3\u044e\1\u0456\14\u044e\2\u0303\2\u044e\2\u0303\1\u044e\1\u0303"+ - "\1\u0370\12\u0303\237\0\1\u036f\2\u0303\4\u044e\3\u0303\2\u044e"+ - "\1\u0457\1\u044e\1\u0303\2\u044e\12\u0303\1\u0370\12\u0303\237\0"+ - "\1\u036f\2\u044e\2\u0303\1\u044e\3\u0303\1\u044e\5\u0303\3\u044e"+ - "\3\u0303\1\u044e\2\u0303\3\u044e\1\u0370\12\u0303\237\0\1\u036f"+ - "\5\u044e\1\u0458\1\u0303\1\u044e\1\u0459\7\u044e\1\u045a\3\u044e"+ - "\1\u0303\1\u044e\1\u0303\3\u044e\1\u0370\12\u0303\237\0\1\u036f"+ - "\1\u045b\1\u044e\1\u0303\1\u0452\6\u044e\3\u0303\1\u044e\2\u0303"+ - "\1\u044e\2\u0303\1\u044e\6\u0303\1\u0370\12\u0303\237\0\1\u036f"+ - "\1\u044e\31\u0303\1\u0370\12\u0303\237\0\1\u036f\1\u044e\2\u0303"+ - "\1\u044e\1\u045c\1\u0303\2\u044e\1\u0303\3\u044e\2\u0303\2\u044e"+ - "\1\u0303\1\u044e\3\u0303\1\u044e\2\u0303\2\u044e\1\u0370\12\u0303"+ - "\237\0\1\u036f\6\u044e\1\u0303\5\u044e\3\u0303\2\u044e\1\u0303"+ - "\10\u044e\1\u0370\12\u0303\237\0\1\u036f\1\u0303\2\u044e\1\u0459"+ - "\1\u045d\3\u044e\1\u0303\3\u044e\1\u0303\1\u044e\1\u0303\1\u044e"+ - "\1\u0303\1\u044e\1\u0303\1\u044e\1\u0303\3\u044e\1\u0303\1\u044e"+ - "\1\u0370\12\u0303\237\0\1\u036f\1\u044e\6\u0303\1\u044e\6\u0303"+ - "\1\u044e\4\u0303\1\u044e\4\u0303\2\u044e\1\u0370\12\u0303\237\0"+ - "\1\u036f\6\u0303\1\u044e\7\u0303\1\u044e\13\u0303\1\u0370\12\u0303"+ - "\237\0\1\u036f\13\u0303\1\u045e\6\u0303\1\u045f\7\u0303\1\u0370"+ - "\12\u0303\237\0\1\u036f\1\u044e\11\u0303\1\u044e\6\u0303\1\u044e"+ - "\10\u0303\1\u0370\12\u0303\237\0\1\u036f\1\u044e\1\u0303\6\u044e"+ - "\1\u0460\1\u0303\2\u044e\2\u0303\2\u044e\1\u0303\1\u044e\1\u0303"+ - "\6\u044e\1\u0303\1\u0370\12\u0303\237\0\1\u036f\4\u0303\1\u044e"+ - "\5\u0303\2\u044e\3\u0303\2\u044e\10\u0303\1\u044e\1\u0370\12\u0303"+ - "\237\0\1\u036f\3\u0303\1\u044e\1\u0303\1\u0461\4\u0303\1\u044e"+ - "\2\u0303\1\u044e\14\u0303\1\u0370\12\u0303\237\0\1\u036f\2\u044e"+ - "\1\u0303\1\u044e\3\u0303\2\u044e\2\u0303\1\u044e\4\u0303\1\u044e"+ - "\11\u0303\1\u0370\12\u0303\237\0\1\u036f\3\u0303\1\u044e\13\u0303"+ - "\1\u044e\12\u0303\1\u0370\12\u0303\237\0\1\u036f\3\u0303\2\u044e"+ - "\2\u0303\2\u044e\1\u0303\2\u044e\1\u0303\1\u044e\3\u0303\1\u044e"+ - "\1\u0303\1\u044e\1\u0303\1\u044e\2\u0303\1\u044e\1\u0303\1\u0370"+ - "\12\u0303\237\0\34\u023e\12\u0462\1\0\2\u023e\1\u029f\3\u023e"+ - "\1\u0240\1\u018c\1\u018d\1\u018e\2\0\2\u023e\4\0\1\u023e"+ - "\214\0\4\u0463\2\0\1\u0463\15\0\1\u0463\6\0\12\u0463"+ - "\1\u0376\237\0\4\u0464\2\0\1\u0464\15\0\1\u0464\6\0"+ - "\12\u0464\1\u0465\237\0\4\u0466\2\0\1\u0466\15\0\1\u0466"+ - "\6\0\1\u0467\2\u0468\1\u0467\5\u0468\1\u0469\14\0\1\u0146"+ - "\223\0\4\u046a\2\0\1\u046a\15\0\1\u046a\6\0\12\u046a"+ - "\1\u03f8\13\0\1\u0146\223\0\4\u0466\2\0\1\u0466\15\0"+ - "\1\u0466\6\0\1\u0467\2\u0468\1\u0467\5\u0468\1\u0469\237\0"+ - "\1\u0188\4\u046a\2\0\1\u046a\15\0\1\u046a\6\0\12\u046b"+ - "\1\u03f8\13\0\1\u0146\222\0\1\u0188\4\u046a\2\0\1\u046a"+ - "\15\0\1\u046a\6\0\12\u046a\1\u03f8\13\0\1\u0146\222\0"+ - "\1\u0188\4\u046a\2\0\1\u046a\15\0\1\u046a\6\0\2\u046b"+ - "\1\u046a\2\u046b\2\u046a\1\u046b\1\u046a\1\u046b\1\u03f8\13\0"+ - "\1\u0146\270\0\1\u0310\13\0\1\u0146\222\0\1\u0109\32\270"+ - "\1\u010a\1\u046c\11\270\237\0\1\u0109\1\u046d\31\270\1\u010a"+ - "\12\270\237\0\1\u0109\32\270\1\u010a\10\270\1\u046e\1\270"+ - "\237\0\1\u0109\25\270\1\u018f\4\270\1\u010a\12\270\237\0"+ - "\1\u0109\32\270\1\u010a\5\270\1\u046f\4\270\237\0\1\u0109"+ - "\32\270\1\u010a\5\270\1\u0470\4\270\237\0\1\u0109\32\270"+ - "\1\u010a\5\270\1\u040d\4\270\237\0\1\u0109\32\270\1\u010a"+ - "\3\270\1\u046d\6\270\237\0\1\u0109\17\270\1\u0471\12\270"+ - "\1\u010a\12\270\237\0\1\u0109\12\270\1\u0472\17\270\1\u010a"+ - "\12\270\237\0\1\u0109\25\270\1\u0473\4\270\1\u010a\12\270"+ - "\237\0\1\u0109\1\u0474\31\270\1\u010a\12\270\237\0\1\u0109"+ - "\15\270\1\u0475\14\270\1\u010a\12\270\237\0\1\u0109\32\270"+ - "\1\u010a\3\270\1\u0476\6\270\237\0\1\u0109\21\270\1\u0477"+ - "\10\270\1\u010a\12\270\237\0\1\u0109\2\270\1\u0400\27\270"+ - "\1\u010a\12\270\237\0\1\u0109\1\270\1\u018f\30\270\1\u010a"+ - "\12\270\237\0\1\u0109\11\270\1\u0478\20\270\1\u010a\12\270"+ - "\237\0\1\u0109\11\270\1\u0479\20\270\1\u010a\12\270\237\0"+ - "\1\u0109\1\u047a\31\270\1\u010a\12\270\237\0\1\u0109\1\u047b"+ - "\31\270\1\u010a\12\270\237\0\1\u0109\2\270\1\u047c\27\270"+ - "\1\u010a\12\270\237\0\1\u0109\32\270\1\u010a\4\270\1\u0196"+ - "\5\270\237\0\1\u0109\10\270\1\u047d\21\270\1\u010a\12\270"+ - "\237\0\1\u0109\1\u047e\31\270\1\u010a\12\270\237\0\1\u0109"+ - "\25\270\1\u047f\4\270\1\u010a\12\270\237\0\1\u0109\32\270"+ - "\1\u010a\4\270\1\u046d\5\270\237\0\1\u0109\32\270\1\u010a"+ - "\6\270\1\u046d\3\270\237\0\1\u0109\32\270\1\u010a\2\270"+ - "\1\u046d\7\270\237\0\1\u0109\16\270\1\u0480\13\270\1\u010a"+ - "\12\270\237\0\1\u0109\32\270\1\u010a\1\u0481\11\270\237\0"+ - "\1\u0109\32\270\1\u010a\3\270\1\u0482\6\270\237\0\1\u0109"+ - "\32\270\1\u010a\3\270\1\u0153\6\270\237\0\1\u0109\24\270"+ - "\1\u0483\5\270\1\u010a\12\270\237\0\1\u0121\1\u0484\31\324"+ - "\1\164\12\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\32\324\1\164"+ - "\11\324\1\u0345\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\1\u0485\31\324"+ - "\1\164\12\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\1\u0486\31\324"+ - "\1\164\12\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\7\324\1\u0487"+ - "\22\324\1\164\12\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121\1\u0488"+ - "\31\324\1\164\12\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121\1\u0489"+ - "\31\324\1\164\12\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121\32\324"+ - "\1\164\6\324\1\u048a\3\324\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121"+ - "\6\324\1\u0127\23\324\1\164\12\324\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\4\0\2\161\212\0"+ - "\1\u0121\25\324\1\u048b\4\324\1\164\12\324\1\0\3\161"+ - "\1\0\2\161\1\162\3\161\3\0\1\161\4\0\2\161"+ - "\212\0\1\u0121\1\u048c\31\324\1\164\12\324\1\0\3\161"+ - "\1\0\2\161\1\162\3\161\3\0\1\161\4\0\2\161"+ - "\212\0\1\u0121\32\324\1\164\6\324\1\u048d\3\324\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0121\1\u048e\31\324\1\164\12\324\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0121\32\324\1\164\6\324\1\u0175\3\324"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\212\0\1\u0121\12\324\1\u0138\17\324\1\164"+ - "\12\324\1\0\3\161\1\0\2\161\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\212\0\1\u0121\1\u048f\31\324\1\164"+ - "\12\324\1\0\3\161\1\0\2\161\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\212\0\1\u0121\10\324\1\u0490\21\324"+ - "\1\164\12\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\31\324\1\u0491"+ - "\1\164\12\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\213\0\4\u0492\2\0\1\u0492"+ - "\15\0\1\u0492\6\0\12\u0492\1\u03be\237\0\4\u0493\2\0"+ - "\1\u0493\15\0\1\u0493\6\0\12\u0493\1\u0494\237\0\4\u0495"+ - "\2\0\1\u0495\15\0\1\u0495\6\0\1\u0496\2\u0497\1\u0496"+ - "\5\u0497\1\u0498\14\0\1\u035e\223\0\4\u0499\2\0\1\u0499"+ - "\15\0\1\u0499\6\0\12\u0499\1\u0435\13\0\1\u035e\223\0"+ - "\4\u0495\2\0\1\u0495\15\0\1\u0495\6\0\1\u0496\2\u0497"+ - "\1\u0496\5\u0497\1\u0498\237\0\1\u03c5\4\u0499\2\0\1\u0499"+ - "\15\0\1\u0499\6\0\12\u049a\1\u0435\13\0\1\u035e\222\0"+ - "\1\u03c5\4\u0499\2\0\1\u0499\15\0\1\u0499\6\0\12\u0499"+ - "\1\u0435\13\0\1\u035e\222\0\1\u03c5\4\u0499\2\0\1\u0499"+ - "\15\0\1\u0499\6\0\2\u049a\1\u0499\2\u049a\2\u0499\1\u049a"+ - "\1\u0499\1\u049a\1\u0435\13\0\1\u035e\223\0\4\u049b\2\0"+ - "\1\u049b\15\0\1\u049b\6\0\12\u049b\1\u03c4\13\0\1\u035e"+ - "\222\0\1\u049c\33\0\12\u043b\237\0\1\u049c\33\0\12\u049d"+ - "\237\0\1\u049c\33\0\1\u043b\1\u049e\1\u049d\2\u043b\2\u049d"+ - "\1\u043b\1\u049d\1\u043b\237\0\1\u03c5\4\u049b\2\0\1\u049b"+ - "\15\0\1\u049b\6\0\12\u049b\1\u03c4\13\0\1\u035e\222\0"+ - "\46\u01f0\1\0\2\u01f0\1\u0234\3\u01f0\1\u01f2\1\0\1\u0233"+ - "\3\0\2\u01f0\4\0\1\u01f0\277\0\1\u049f\254\0\12\u04a0"+ - "\11\0\1\u0233\273\0\1\u0364\237\0\4\u04a1\2\0\1\u04a1"+ - "\15\0\1\u04a1\6\0\12\u04a1\1\u0443\237\0\4\u04a2\2\0"+ - "\1\u04a2\15\0\1\u04a2\6\0\12\u04a2\1\u04a3\237\0\4\u04a4"+ - "\2\0\1\u04a4\15\0\1\u04a4\6\0\12\u04a4\1\u04a5\13\0"+ - "\1\u0302\222\0\1\u036b\4\u04a4\2\0\1\u04a4\15\0\1\u04a4"+ - "\6\0\12\u04a6\1\u04a5\13\0\1\u0302\222\0\1\u036b\4\u04a4"+ - "\2\0\1\u04a4\15\0\1\u04a4\6\0\12\u04a7\1\u04a5\13\0"+ - "\1\u0302\222\0\1\u036b\4\u04a4\2\0\1\u04a4\15\0\1\u04a4"+ - "\6\0\1\u04a6\1\u04a8\1\u04a7\2\u04a6\2\u04a7\1\u04a6\1\u04a7"+ - "\1\u04a6\1\u04a5\13\0\1\u0302\223\0\4\u04a9\2\0\1\u04a9"+ - "\15\0\1\u04a9\6\0\12\u04a9\1\u03d0\13\0\1\u0302\222\0"+ - "\1\u036b\4\u04a9\2\0\1\u04a9\15\0\1\u04a9\6\0\12\u04a9"+ - "\1\u03d0\13\0\1\u0302\270\0\1\u036a\13\0\1\u0302\256\0"+ - "\1\u04aa\2\u04ab\1\u04aa\5\u04ab\1\u04ac\237\0\1\u044b\304\0"+ - "\1\u044b\33\0\2\u044c\1\0\2\u044c\2\0\1\u044c\1\0"+ - "\1\u044c\237\0\1\u04ad\32\u0303\1\u0370\12\u0303\237\0\1\u04ad"+ - "\4\u0303\1\u04ae\25\u0303\1\u0370\12\u0303\237\0\1\u04ad\15\u0303"+ - "\1\u03e5\14\u0303\1\u0370\12\u0303\237\0\1\u04ad\10\u0303\1\u03e5"+ - "\21\u0303\1\u0370\12\u0303\237\0\1\u04ad\17\u0303\1\u044e\12\u0303"+ - "\1\u0370\12\u0303\237\0\1\u04ad\5\u0303\1\u04af\4\u0303\1\u044e"+ - "\17\u0303\1\u0370\12\u0303\237\0\1\u036f\20\u0303\1\u044e\11\u0303"+ - "\1\u0370\12\u0303\237\0\1\u036f\7\u0303\1\u044e\22\u0303\1\u0370"+ - "\12\u0303\237\0\1\u036f\27\u0303\1\u044e\2\u0303\1\u0370\12\u0303"+ - "\237\0\1\u04ad\6\u0303\1\u04ae\10\u0303\1\u044e\12\u0303\1\u0370"+ - "\12\u0303\237\0\1\u04ad\24\u0303\1\u04b0\5\u0303\1\u0370\12\u0303"+ - "\237\0\1\u036f\11\u0303\1\u044e\20\u0303\1\u0370\12\u0303\237\0"+ - "\1\u04ad\16\u0303\1\u04b1\13\u0303\1\u0370\12\u0303\237\0\1\u04ad"+ - "\12\u0303\1\u04b2\17\u0303\1\u0370\12\u0303\237\0\1\u04ad\5\u0303"+ - "\1\u044e\24\u0303\1\u0370\12\u0303\237\0\1\u04ad\1\u04b3\31\u0303"+ - "\1\u0370\12\u0303\237\0\1\u036f\32\u0303\1\u04b4\12\u0303\237\0"+ - "\1\u036f\22\u0303\1\u044e\7\u0303\1\u0370\12\u0303\237\0\1\u04ad"+ - "\23\u0303\1\u044e\6\u0303\1\u0370\12\u0303\237\0\1\u04ad\24\u0303"+ - "\1\u04b5\5\u0303\1\u0370\12\u0303\237\0\34\u023e\12\u04b6\1\0"+ - "\2\u023e\1\u029f\3\u023e\1\u0240\1\u018c\1\u018d\1\u018e\2\0"+ - "\2\u023e\4\0\1\u023e\261\0\1\u0376\237\0\4\u04b7\2\0"+ - "\1\u04b7\15\0\1\u04b7\6\0\12\u04b7\1\u0465\237\0\4\u04b8"+ - "\2\0\1\u04b8\15\0\1\u04b8\6\0\1\u04b9\2\u04ba\1\u04b9"+ - "\5\u04ba\1\u04bb\1\u04bc\237\0\4\u04bd\2\0\1\u04bd\15\0"+ - "\1\u04bd\6\0\12\u04bd\1\u04be\13\0\1\u0146\222\0\1\u0188"+ - "\4\u04bd\2\0\1\u04bd\15\0\1\u04bd\6\0\12\u04bf\1\u04be"+ - "\13\0\1\u0146\222\0\1\u0188\4\u04bd\2\0\1\u04bd\15\0"+ - "\1\u04bd\6\0\12\u04c0\1\u04be\13\0\1\u0146\222\0\1\u0188"+ - "\4\u04bd\2\0\1\u04bd\15\0\1\u04bd\6\0\1\u04bf\1\u04c1"+ - "\1\u04c0\2\u04bf\2\u04c0\1\u04bf\1\u04c0\1\u04bf\1\u04be\13\0"+ - "\1\u0146\223\0\4\u04c2\2\0\1\u04c2\15\0\1\u04c2\6\0"+ - "\12\u04c2\1\u03f8\13\0\1\u0146\222\0\1\u0188\4\u04c2\2\0"+ - "\1\u04c2\15\0\1\u04c2\6\0\12\u04c2\1\u03f8\13\0\1\u0146"+ - "\222\0\1\u0109\3\270\1\u04c3\26\270\1\u010a\12\270\237\0"+ - "\1\u0109\2\270\1\u018f\27\270\1\u010a\12\270\237\0\1\u0109"+ - "\6\270\1\u019a\23\270\1\u010a\12\270\237\0\1\u0109\1\270"+ - "\1\u0417\30\270\1\u010a\12\270\237\0\1\u0109\3\270\1\u04c4"+ - "\26\270\1\u010a\12\270\237\0\1\u0109\32\270\1\u010a\3\270"+ - "\1\u04c5\6\270\237\0\1\u0109\32\270\1\u010a\6\270\1\u04c6"+ - "\3\270\237\0\1\u0109\32\270\1\u010a\6\270\1\u04c7\3\270"+ - "\237\0\1\u0109\32\270\1\u010a\5\270\1\u04c8\4\270\237\0"+ - "\1\u0109\32\270\1\u010a\7\270\1\u04c9\2\270\237\0\1\u0109"+ - "\1\u04ca\31\270\1\u010a\12\270\237\0\1\u0109\24\270\1\u04cb"+ - "\5\270\1\u010a\12\270\237\0\1\u0109\32\270\1\u010a\4\270"+ - "\1\u04cc\5\270\237\0\1\u0109\32\270\1\u010a\4\270\1\u04cd"+ - "\5\270\237\0\1\u0109\26\270\1\u04ce\3\270\1\u010a\12\270"+ - "\237\0\1\u0109\30\270\1\u04cf\1\270\1\u010a\12\270\237\0"+ - "\1\u0109\11\270\1\u01cb\20\270\1\u010a\12\270\237\0\1\u0109"+ - "\32\270\1\u010a\2\270\1\u04d0\7\270\237\0\1\u0109\12\270"+ - "\1\u04d1\17\270\1\u010a\12\270\237\0\1\u0109\17\270\1\u0197"+ - "\12\270\1\u010a\12\270\237\0\1\u0109\32\270\1\u010a\4\270"+ - "\1\u04d2\5\270\237\0\1\u0109\32\270\1\u010a\6\270\1\u01ce"+ - "\3\270\237\0\1\u0109\30\270\1\u04d3\1\270\1\u010a\12\270"+ - "\237\0\1\u0109\30\270\1\u04d4\1\270\1\u010a\12\270\237\0"+ - "\1\u0121\32\324\1\164\1\u04d5\11\324\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\4\0\2\161\212\0"+ - "\1\u0121\2\324\1\u04d6\27\324\1\164\12\324\1\0\3\161"+ - "\1\0\2\161\1\162\3\161\3\0\1\161\4\0\2\161"+ - "\212\0\1\u0121\32\324\1\164\10\324\1\u0338\1\324\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0121\15\324\1\350\14\324\1\164\12\324"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\212\0\1\u0121\23\324\1\u04d7\6\324\1\164"+ - "\12\324\1\0\3\161\1\0\2\161\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\212\0\1\u0121\32\324\1\164\1\324"+ - "\1\u04d8\10\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\32\324\1\164"+ - "\3\324\1\u0179\6\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121\30\324"+ - "\1\u04d9\1\324\1\164\12\324\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121"+ - "\32\324\1\164\1\324\1\u04da\10\324\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\4\0\2\161\212\0"+ - "\1\u0121\6\324\1\u04db\23\324\1\164\12\324\1\0\3\161"+ - "\1\0\2\161\1\162\3\161\3\0\1\161\4\0\2\161"+ - "\212\0\1\u0121\32\324\1\164\5\324\1\u04dc\4\324\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0121\32\324\1\164\5\324\1\u04dd\4\324"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\212\0\1\u0121\32\324\1\164\1\324\1\350"+ - "\10\324\1\0\3\161\1\0\2\161\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\212\0\1\u0121\13\324\1\u04de\16\324"+ - "\1\164\12\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\260\0\1\u03be\237\0\4\u04df"+ - "\2\0\1\u04df\15\0\1\u04df\6\0\12\u04df\1\u0494\237\0"+ - "\4\u04e0\2\0\1\u04e0\15\0\1\u04e0\6\0\12\u04e0\1\u04e1"+ - "\237\0\4\u04e2\2\0\1\u04e2\15\0\1\u04e2\6\0\12\u04e2"+ - "\1\u04e3\13\0\1\u035e\222\0\1\u03c5\4\u04e2\2\0\1\u04e2"+ - "\15\0\1\u04e2\6\0\12\u04e4\1\u04e3\13\0\1\u035e\222\0"+ - "\1\u03c5\4\u04e2\2\0\1\u04e2\15\0\1\u04e2\6\0\12\u04e5"+ - "\1\u04e3\13\0\1\u035e\222\0\1\u03c5\4\u04e2\2\0\1\u04e2"+ - "\15\0\1\u04e2\6\0\1\u04e4\1\u04e6\1\u04e5\2\u04e4\2\u04e5"+ - "\1\u04e4\1\u04e5\1\u04e4\1\u04e3\13\0\1\u035e\223\0\4\u04e7"+ - "\2\0\1\u04e7\15\0\1\u04e7\6\0\12\u04e7\1\u0435\13\0"+ - "\1\u035e\222\0\1\u03c5\4\u04e7\2\0\1\u04e7\15\0\1\u04e7"+ - "\6\0\12\u04e7\1\u0435\13\0\1\u035e\270\0\1\u03c4\13\0"+ - "\1\u035e\256\0\1\u04e8\2\u04e9\1\u04e8\5\u04e9\1\u04ea\237\0"+ - "\1\u049c\304\0\1\u049c\33\0\2\u049d\1\0\2\u049d\2\0"+ - "\1\u049d\1\0\1\u049d\240\0\1\u04eb\1\0\1\u04eb\5\0"+ - "\1\u04eb\352\0\1\u0233\226\0\4\u04ec\2\0\1\u04ec\15\0"+ - "\1\u04ec\6\0\12\u04ec\1\u0443\237\0\4\u04ed\2\0\1\u04ed"+ - "\15\0\1\u04ed\6\0\12\u04ed\1\u04ee\237\0\4\u04ef\2\0"+ - "\1\u04ef\15\0\1\u04ef\6\0\1\u04f0\2\u04f1\1\u04f0\5\u04f1"+ - "\1\u04f2\14\0\1\u0302\223\0\4\u04f3\2\0\1\u04f3\15\0"+ - "\1\u04f3\6\0\12\u04f3\1\u04a5\13\0\1\u0302\223\0\4\u04ef"+ - "\2\0\1\u04ef\15\0\1\u04ef\6\0\1\u04f0\2\u04f1\1\u04f0"+ - "\5\u04f1\1\u04f2\237\0\1\u036b\4\u04f3\2\0\1\u04f3\15\0"+ - "\1\u04f3\6\0\12\u04f4\1\u04a5\13\0\1\u0302\222\0\1\u036b"+ - "\4\u04f3\2\0\1\u04f3\15\0\1\u04f3\6\0\12\u04f3\1\u04a5"+ - "\13\0\1\u0302\222\0\1\u036b\4\u04f3\2\0\1\u04f3\15\0"+ - "\1\u04f3\6\0\2\u04f4\1\u04f3\2\u04f4\2\u04f3\1\u04f4\1\u04f3"+ - "\1\u04f4\1\u04a5\13\0\1\u0302\270\0\1\u03d0\13\0\1\u0302"+ - "\222\0\1\u04f5\33\0\12\u04ab\237\0\1\u04f5\33\0\12\u04f6"+ - "\237\0\1\u04f5\33\0\1\u04ab\1\u04f7\1\u04f6\2\u04ab\2\u04f6"+ - "\1\u04ab\1\u04f6\1\u04ab\237\0\1\u036f\5\u0303\1\u044e\24\u0303"+ - "\1\u0370\12\u0303\237\0\1\u036f\15\u0303\1\u044e\14\u0303\1\u0370"+ - "\12\u0303\237\0\1\u036f\10\u0303\1\u044e\21\u0303\1\u0370\12\u0303"+ - "\237\0\1\u036f\3\u0303\1\u04f8\26\u0303\1\u0370\12\u0303\237\0"+ - "\1\u036f\3\u0303\1\u044e\26\u0303\1\u0370\12\u0303\237\0\1\u036f"+ - "\27\u0303\1\u04f9\2\u0303\1\u0370\12\u0303\240\0\32\u0303\1\u04fa"+ - "\12\u0303\237\0\1\u036f\16\u0303\1\u044e\13\u0303\1\u0370\12\u0303"+ - "\237\0\46\u023e\1\0\2\u023e\1\u029f\3\u023e\1\u0240\1\u018c"+ - "\1\u018d\1\u018e\2\0\2\u023e\4\0\1\u023e\214\0\4\u04fb"+ - "\2\0\1\u04fb\15\0\1\u04fb\6\0\12\u04fb\1\u0465\237\0"+ - "\4\u04fc\2\0\1\u04fc\15\0\1\u04fc\6\0\12\u04fc\1\u04fd"+ - "\236\0\1\u0188\4\u04fc\2\0\1\u04fc\15\0\1\u04fc\6\0"+ - "\12\u04fe\1\u04fd\236\0\1\u0188\4\u04fc\2\0\1\u04fc\15\0"+ - "\1\u04fc\6\0\12\u04ff\1\u04fd\236\0\1\u0188\4\u04fc\2\0"+ - "\1\u04fc\15\0\1\u04fc\6\0\1\u04fe\1\u0500\1\u04ff\2\u04fe"+ - "\2\u04ff\1\u04fe\1\u04ff\1\u04fe\1\u04fd\237\0\4\u0501\2\0"+ - "\1\u0501\15\0\1\u0501\6\0\12\u0501\14\0\1\u0146\223\0"+ - "\4\u0502\2\0\1\u0502\15\0\1\u0502\6\0\12\u0502\1\u04be"+ - "\13\0\1\u0146\223\0\4\u0501\2\0\1\u0501\15\0\1\u0501"+ - "\6\0\12\u0501\237\0\1\u0188\4\u0502\2\0\1\u0502\15\0"+ - "\1\u0502\6\0\12\u0503\1\u04be\13\0\1\u0146\222\0\1\u0188"+ - "\4\u0502\2\0\1\u0502\15\0\1\u0502\6\0\12\u0502\1\u04be"+ - "\13\0\1\u0146\222\0\1\u0188\4\u0502\2\0\1\u0502\15\0"+ - "\1\u0502\6\0\2\u0503\1\u0502\2\u0503\2\u0502\1\u0503\1\u0502"+ - "\1\u0503\1\u04be\13\0\1\u0146\270\0\1\u03f8\13\0\1\u0146"+ - "\222\0\1\u0109\1\u0504\31\270\1\u010a\12\270\237\0\1\u0109"+ - "\32\270\1\u010a\11\270\1\u040d\237\0\1\u0109\1\u0505\31\270"+ - "\1\u010a\12\270\237\0\1\u0109\1\u0506\31\270\1\u010a\12\270"+ - "\237\0\1\u0109\7\270\1\u0507\22\270\1\u010a\12\270\237\0"+ - "\1\u0109\1\u0508\31\270\1\u010a\12\270\237\0\1\u0109\1\u0509"+ - "\31\270\1\u010a\12\270\237\0\1\u0109\32\270\1\u010a\6\270"+ - "\1\u050a\3\270\237\0\1\u0109\6\270\1\u018f\23\270\1\u010a"+ - "\12\270\237\0\1\u0109\25\270\1\u050b\4\270\1\u010a\12\270"+ - "\237\0\1\u0109\1\u050c\31\270\1\u010a\12\270\237\0\1\u0109"+ - "\32\270\1\u010a\6\270\1\u050d\3\270\237\0\1\u0109\1\u050e"+ - "\31\270\1\u010a\12\270\237\0\1\u0109\32\270\1\u010a\6\270"+ - "\1\u01ca\3\270\237\0\1\u0109\12\270\1\u01a0\17\270\1\u010a"+ - "\12\270\237\0\1\u0109\1\u050f\31\270\1\u010a\12\270\237\0"+ - "\1\u0109\10\270\1\u0510\21\270\1\u010a\12\270\237\0\1\u0109"+ - "\31\270\1\u0511\1\u010a\12\270\237\0\1\u0121\24\324\1\u0512"+ - "\5\324\1\164\12\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121\32\324"+ - "\1\164\10\324\1\u0513\1\324\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121"+ - "\1\324\1\u012e\30\324\1\164\12\324\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\4\0\2\161\212\0"+ - "\1\u0121\2\324\1\u0514\27\324\1\164\12\324\1\0\3\161"+ - "\1\0\2\161\1\162\3\161\3\0\1\161\4\0\2\161"+ - "\212\0\1\u0121\3\324\1\u0515\26\324\1\164\12\324\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0121\3\324\1\u0516\26\324\1\164\12\324"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\212\0\1\u0121\32\324\1\164\1\324\1\u0517"+ - "\10\324\1\0\3\161\1\0\2\161\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\212\0\1\u0121\3\324\1\u0518\26\324"+ - "\1\164\12\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\1\u0519\31\324"+ - "\1\164\12\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\26\324\1\u051a"+ - "\3\324\1\164\12\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\213\0\4\u051b\2\0"+ - "\1\u051b\15\0\1\u051b\6\0\12\u051b\1\u0494\237\0\4\u051c"+ - "\2\0\1\u051c\15\0\1\u051c\6\0\12\u051c\1\u051d\237\0"+ - "\4\u051e\2\0\1\u051e\15\0\1\u051e\6\0\1\u051f\2\u0520"+ - "\1\u051f\5\u0520\1\u0521\14\0\1\u035e\223\0\4\u0522\2\0"+ - "\1\u0522\15\0\1\u0522\6\0\12\u0522\1\u04e3\13\0\1\u035e"+ - "\223\0\4\u051e\2\0\1\u051e\15\0\1\u051e\6\0\1\u051f"+ - "\2\u0520\1\u051f\5\u0520\1\u0521\237\0\1\u03c5\4\u0522\2\0"+ - "\1\u0522\15\0\1\u0522\6\0\12\u0523\1\u04e3\13\0\1\u035e"+ - "\222\0\1\u03c5\4\u0522\2\0\1\u0522\15\0\1\u0522\6\0"+ - "\12\u0522\1\u04e3\13\0\1\u035e\222\0\1\u03c5\4\u0522\2\0"+ - "\1\u0522\15\0\1\u0522\6\0\2\u0523\1\u0522\2\u0523\2\u0522"+ - "\1\u0523\1\u0522\1\u0523\1\u04e3\13\0\1\u035e\270\0\1\u0435"+ - "\13\0\1\u035e\222\0\1\u0524\33\0\12\u04e9\237\0\1\u0524"+ - "\33\0\12\u0525\237\0\1\u0524\33\0\1\u04e9\1\u0526\1\u0525"+ - "\2\u04e9\2\u0525\1\u04e9\1\u0525\1\u04e9\317\0\1\u018e\272\0"+ - "\1\u0443\237\0\4\u0527\2\0\1\u0527\15\0\1\u0527\6\0"+ - "\12\u0527\1\u04ee\237\0\4\u0528\2\0\1\u0528\15\0\1\u0528"+ - "\6\0\12\u0528\1\u0529\237\0\4\u052a\2\0\1\u052a\15\0"+ - "\1\u052a\6\0\12\u052a\1\u052b\13\0\1\u0302\222\0\1\u036b"+ - "\4\u052a\2\0\1\u052a\15\0\1\u052a\6\0\12\u052c\1\u052b"+ - "\13\0\1\u0302\222\0\1\u036b\4\u052a\2\0\1\u052a\15\0"+ - "\1\u052a\6\0\12\u052d\1\u052b\13\0\1\u0302\222\0\1\u036b"+ - "\4\u052a\2\0\1\u052a\15\0\1\u052a\6\0\1\u052c\1\u052e"+ - "\1\u052d\2\u052c\2\u052d\1\u052c\1\u052d\1\u052c\1\u052b\13\0"+ - "\1\u0302\223\0\4\u052f\2\0\1\u052f\15\0\1\u052f\6\0"+ - "\12\u052f\1\u04a5\13\0\1\u0302\222\0\1\u036b\4\u052f\2\0"+ - "\1\u052f\15\0\1\u052f\6\0\12\u052f\1\u04a5\13\0\1\u0302"+ - "\256\0\1\u0530\2\u0531\1\u0530\5\u0531\1\u0532\237\0\1\u04f5"+ - "\304\0\1\u04f5\33\0\2\u04f6\1\0\2\u04f6\2\0\1\u04f6"+ - "\1\0\1\u04f6\237\0\1\u036f\20\u0303\1\u0533\11\u0303\1\u0370"+ - "\12\u0303\237\0\1\u036f\3\u0303\1\u0459\26\u0303\1\u0370\12\u0303"+ - "\240\0\1\u0303\1\u0534\1\u0535\2\u0303\1\u0536\1\u0537\1\u0538"+ - "\1\u0303\1\u0539\1\u053a\2\u0303\1\u053b\1\u053c\2\u0303\1\u053d"+ - "\1\u053e\1\u053f\1\u0303\1\u0540\1\u0541\1\u0303\1\u0542\1\u0543"+ - "\1\u0370\1\u0544\2\u0303\1\u0545\1\u0546\1\u0547\1\u0303\1\u0548"+ - "\1\u0549\1\u0303\305\0\1\u0465\237\0\4\u054a\2\0\1\u054a"+ - "\15\0\1\u054a\6\0\12\u054a\1\u04fd\237\0\4\u0501\2\0"+ - "\1\u0501\15\0\1\u0501\6\0\12\u0501\1\u037d\236\0\1\u0188"+ - "\4\u054a\2\0\1\u054a\15\0\1\u054a\6\0\12\u054b\1\u04fd"+ - "\236\0\1\u0188\4\u054a\2\0\1\u054a\15\0\1\u054a\6\0"+ - "\12\u054a\1\u04fd\236\0\1\u0188\4\u054a\2\0\1\u054a\15\0"+ - "\1\u054a\6\0\2\u054b\1\u054a\2\u054b\2\u054a\1\u054b\1\u054a"+ - "\1\u054b\1\u04fd\237\0\4\u054c\2\0\1\u054c\15\0\1\u054c"+ - "\6\0\12\u054c\14\0\1\u0146\223\0\4\u054d\2\0\1\u054d"+ - "\15\0\1\u054d\6\0\12\u054d\1\u04be\13\0\1\u0146\222\0"+ - "\1\u0188\4\u054d\2\0\1\u054d\15\0\1\u054d\6\0\12\u054d"+ - "\1\u04be\13\0\1\u0146\222\0\1\u0109\32\270\1\u010a\1\u054e"+ - "\11\270\237\0\1\u0109\2\270\1\u054f\27\270\1\u010a\12\270"+ - "\237\0\1\u0109\32\270\1\u010a\10\270\1\u0400\1\270\237\0"+ - "\1\u0109\15\270\1\u0153\14\270\1\u010a\12\270\237\0\1\u0109"+ - "\23\270\1\u0550\6\270\1\u010a\12\270\237\0\1\u0109\32\270"+ - "\1\u010a\1\270\1\u0551\10\270\237\0\1\u0109\32\270\1\u010a"+ - "\3\270\1\u01ce\6\270\237\0\1\u0109\30\270\1\u0552\1\270"+ - "\1\u010a\12\270\237\0\1\u0109\32\270\1\u010a\1\270\1\u0553"+ - "\10\270\237\0\1\u0109\6\270\1\u0554\23\270\1\u010a\12\270"+ - "\237\0\1\u0109\32\270\1\u010a\5\270\1\u0555\4\270\237\0"+ - "\1\u0109\32\270\1\u010a\5\270\1\u0556\4\270\237\0\1\u0109"+ - "\32\270\1\u010a\1\270\1\u0153\10\270\237\0\1\u0109\13\270"+ - "\1\u0557\16\270\1\u010a\12\270\237\0\1\u0121\32\324\1\164"+ - "\11\324\1\u0558\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\26\324\1\u0127"+ - "\3\324\1\164\12\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121\32\324"+ - "\1\164\7\324\1\u0559\2\324\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121"+ - "\32\324\1\164\11\324\1\350\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121"+ - "\3\324\1\u055a\26\324\1\164\12\324\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\4\0\2\161\212\0"+ - "\1\u0121\32\324\1\164\4\324\1\u055b\5\324\1\0\3\161"+ - "\1\0\2\161\1\162\3\161\3\0\1\161\4\0\2\161"+ - "\212\0\1\u0121\16\324\1\u055c\13\324\1\164\12\324\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0121\26\324\1\u055d\3\324\1\164\12\324"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\212\0\1\u0121\32\324\1\164\7\324\1\u0427"+ - "\2\324\1\0\3\161\1\0\2\161\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\260\0\1\u0494\237\0\4\u055e\2\0"+ - "\1\u055e\15\0\1\u055e\6\0\12\u055e\1\u051d\237\0\4\u055f"+ - "\2\0\1\u055f\15\0\1\u055f\6\0\12\u055f\1\u0560\237\0"+ - "\4\u0561\2\0\1\u0561\15\0\1\u0561\6\0\12\u0561\1\u0562"+ - "\13\0\1\u035e\222\0\1\u03c5\4\u0561\2\0\1\u0561\15\0"+ - "\1\u0561\6\0\12\u0563\1\u0562\13\0\1\u035e\222\0\1\u03c5"+ - "\4\u0561\2\0\1\u0561\15\0\1\u0561\6\0\12\u0564\1\u0562"+ - "\13\0\1\u035e\222\0\1\u03c5\4\u0561\2\0\1\u0561\15\0"+ - "\1\u0561\6\0\1\u0563\1\u0565\1\u0564\2\u0563\2\u0564\1\u0563"+ - "\1\u0564\1\u0563\1\u0562\13\0\1\u035e\223\0\4\u0566\2\0"+ - "\1\u0566\15\0\1\u0566\6\0\12\u0566\1\u04e3\13\0\1\u035e"+ - "\222\0\1\u03c5\4\u0566\2\0\1\u0566\15\0\1\u0566\6\0"+ - "\12\u0566\1\u04e3\13\0\1\u035e\256\0\1\u0567\2\u0568\1\u0567"+ - "\5\u0568\1\u0569\237\0\1\u0524\304\0\1\u0524\33\0\2\u0525"+ - "\1\0\2\u0525\2\0\1\u0525\1\0\1\u0525\240\0\4\u056a"+ - "\2\0\1\u056a\15\0\1\u056a\6\0\12\u056a\1\u04ee\237\0"+ - "\4\u056b\2\0\1\u056b\15\0\1\u056b\6\0\12\u056b\1\u056c"+ - "\237\0\4\u056d\2\0\1\u056d\15\0\1\u056d\6\0\1\u056e"+ - "\2\u056f\1\u056e\5\u056f\1\u0570\14\0\1\u0302\223\0\4\u0571"+ - "\2\0\1\u0571\15\0\1\u0571\6\0\12\u0571\1\u052b\13\0"+ - "\1\u0302\223\0\4\u056d\2\0\1\u056d\15\0\1\u056d\6\0"+ - "\1\u056e\2\u056f\1\u056e\5\u056f\1\u0570\237\0\1\u036b\4\u0571"+ - "\2\0\1\u0571\15\0\1\u0571\6\0\12\u0572\1\u052b\13\0"+ - "\1\u0302\222\0\1\u036b\4\u0571\2\0\1\u0571\15\0\1\u0571"+ - "\6\0\12\u0571\1\u052b\13\0\1\u0302\222\0\1\u036b\4\u0571"+ - "\2\0\1\u0571\15\0\1\u0571\6\0\2\u0572\1\u0571\2\u0572"+ - "\2\u0571\1\u0572\1\u0571\1\u0572\1\u052b\13\0\1\u0302\270\0"+ - "\1\u04a5\13\0\1\u0302\256\0\12\u0531\14\0\1\u0302\256\0"+ - "\12\u0573\14\0\1\u0302\256\0\1\u0531\1\u0574\1\u0573\2\u0531"+ - "\2\u0573\1\u0531\1\u0573\1\u0531\14\0\1\u0302\222\0\1\u036f"+ - "\12\u0303\1\u044e\17\u0303\1\u0370\12\u0303\237\0\1\u036f\11\u0303"+ - "\1\u0575\20\u0303\1\u0370\12\u0303\237\0\1\u036f\3\u0303\1\u0576"+ - "\26\u0303\1\u0370\12\u0303\237\0\1\u036f\7\u0303\1\u0577\22\u0303"+ - "\1\u0370\4\u0303\1\u0578\5\u0303\237\0\1\u036f\10\u0303\1\u0579"+ - "\4\u0303\1\u057a\5\u0303\1\u057b\6\u0303\1\u0370\12\u0303\237\0"+ - "\1\u036f\3\u0303\1\u057c\26\u0303\1\u0370\2\u0303\1\u057d\7\u0303"+ - "\237\0\1\u036f\7\u0303\1\u057e\22\u0303\1\u0370\12\u0303\237\0"+ - "\1\u036f\7\u0303\1\u057f\22\u0303\1\u0370\12\u0303\237\0\1\u036f"+ - "\7\u0303\1\u0580\22\u0303\1\u0370\3\u0303\1\u0581\6\u0303\237\0"+ - "\1\u036f\32\u0303\1\u0370\5\u0303\1\u0582\4\u0303\237\0\1\u036f"+ - "\7\u0303\1\u0583\22\u0303\1\u0370\12\u0303\237\0\1\u036f\31\u0303"+ - "\1\u0584\1\u0370\12\u0303\237\0\1\u036f\1\u0303\1\u0585\30\u0303"+ - "\1\u0370\12\u0303\237\0\1\u036f\7\u0303\1\u0586\1\u0303\1\u0587"+ - "\20\u0303\1\u0370\11\u0303\1\u0582\237\0\1\u036f\22\u0303\1\u0588"+ - "\7\u0303\1\u0370\2\u0303\1\u0589\7\u0303\237\0\1\u036f\6\u0303"+ - "\1\u058a\1\u058b\22\u0303\1\u0370\12\u0303\237\0\1\u036f\7\u0303"+ - "\1\u058c\5\u0303\1\u058d\14\u0303\1\u0370\12\u0303\237\0\1\u036f"+ - "\23\u0303\1\u058e\6\u0303\1\u0370\12\u0303\237\0\1\u036f\32\u0303"+ - "\1\u0370\3\u0303\1\u058f\6\u0303\237\0\1\u036f\3\u0303\1\u0590"+ - "\26\u0303\1\u0370\12\u0303\237\0\1\u036f\17\u0303\1\u0591\12\u0303"+ - "\1\u0370\1\u0592\11\u0303\237\0\1\u036f\32\u0303\1\u0370\1\u0303"+ - "\1\u0582\10\u0303\237\0\1\u036f\32\u0303\1\u0370\1\u0593\11\u0303"+ - "\240\0\4\u0594\2\0\1\u0594\15\0\1\u0594\6\0\12\u0594"+ - "\1\u04fd\236\0\1\u0188\4\u0594\2\0\1\u0594\15\0\1\u0594"+ - "\6\0\12\u0594\1\u04fd\237\0\4\u0595\2\0\1\u0595\15\0"+ - "\1\u0595\6\0\12\u0595\14\0\1\u0146\270\0\1\u04be\13\0"+ - "\1\u0146\222\0\1\u0109\24\270\1\u0596\5\270\1\u010a\12\270"+ - "\237\0\1\u0109\32\270\1\u010a\10\270\1\u0597\1\270\237\0"+ - "\1\u0109\1\270\1\u0196\30\270\1\u010a\12\270\237\0\1\u0109"+ - "\2\270\1\u0598\27\270\1\u010a\12\270\237\0\1\u0109\3\270"+ - "\1\u0599\26\270\1\u010a\12\270\237\0\1\u0109\3\270\1\u059a"+ - "\26\270\1\u010a\12\270\237\0\1\u0109\32\270\1\u010a\1\270"+ - "\1\u059b\10\270\237\0\1\u0109"; + "\1\366\1\367\1\370\1\154\12\371\1\u01d0\1\154\1\201"+ + "\1\154\1\0\1\154\1\156\1\u01d1\1\u01d2\1\u01d3\3\0"+ + "\1\154\3\0\2\154\2\0\1\55\1\0\1\56\2\0"+ + "\1\245\1\0\1\246\4\0\1\61\1\0\1\62\1\0"+ + "\1\63\2\0\1\64\3\0\1\247\2\0\1\250\4\0"+ + "\1\251\3\0\1\252\17\0\1\71\2\0\1\253\21\0"+ + "\1\254\2\0\1\255\61\0\1\30\1\76\2\0\1\76"+ + "\1\0\2\76\1\0\1\76\2\0\1\76\1\0\2\30"+ + "\1\76\32\30\1\0\12\u0259\1\76\1\0\1\76\233\0"+ + "\1\u01d1\3\0\1\u025a\45\u01d1\1\u0228\2\u01d1\1\u025b\1\u0228"+ + "\1\u01d1\1\u025c\2\u01d1\1\u01d3\2\0\1\u0228\1\u01d1\3\0"+ + "\1\u01d1\1\154\213\0\1\154\3\0\1\u025d\45\u01d2\1\u0229"+ + "\2\u01d2\1\u025e\1\0\1\154\1\u025f\1\u01d1\1\u01d2\1\u01d3"+ + "\2\0\1\u0229\1\u01d2\3\0\2\154\213\0\1\u01d3\3\0"+ + "\1\u0260\45\u01d3\1\u022a\2\u01d3\1\u0261\1\u022a\1\u01d3\1\u0262"+ + "\2\u01d3\1\154\2\0\1\u022a\1\u01d3\3\0\1\u01d3\1\154"+ + "\2\0\1\55\1\0\1\56\2\0\1\57\1\0\1\60"+ + "\4\0\1\61\1\0\1\62\1\0\1\63\2\0\1\64"+ + "\3\0\1\65\2\0\1\66\4\0\1\67\3\0\1\70"+ + "\17\0\1\71\2\0\1\72\21\0\1\73\2\0\1\74"+ + "\61\0\2\30\1\75\1\0\1\76\1\0\1\76\1\77"+ + "\1\0\1\30\2\0\1\201\1\0\1\41\1\30\1\202"+ + "\3\43\1\u0263\26\43\1\203\12\204\1\76\1\154\1\205"+ + "\1\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\2\0\1\55\1\0\1\56\2\0\1\57\1\0"+ + "\1\60\4\0\1\61\1\0\1\62\1\0\1\63\2\0"+ + "\1\64\3\0\1\65\2\0\1\66\4\0\1\67\3\0"+ + "\1\70\17\0\1\71\2\0\1\72\21\0\1\73\2\0"+ + "\1\74\61\0\2\30\1\75\1\0\1\76\1\0\1\76"+ + "\1\77\1\0\1\30\2\0\1\201\1\0\1\41\1\30"+ + "\1\202\15\43\1\u0141\14\43\1\203\12\204\1\76\1\154"+ + "\1\205\1\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\2\0\1\55\1\0\1\56\2\0\1\57"+ + "\1\0\1\60\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\65\2\0\1\66\4\0\1\67"+ + "\3\0\1\70\17\0\1\71\2\0\1\72\21\0\1\73"+ + "\2\0\1\74\61\0\2\30\1\75\1\0\1\76\1\0"+ + "\1\76\1\77\1\0\1\30\2\0\1\201\1\0\1\41"+ + "\1\30\1\202\16\43\1\u0264\1\u0265\12\43\1\203\12\204"+ + "\1\76\1\154\1\205\1\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\2\0\1\55\1\0\1\56"+ + "\2\0\1\57\1\0\1\60\4\0\1\61\1\0\1\62"+ + "\1\0\1\63\2\0\1\64\3\0\1\65\2\0\1\66"+ + "\4\0\1\67\3\0\1\70\17\0\1\71\2\0\1\72"+ + "\21\0\1\73\2\0\1\74\61\0\2\30\1\75\1\0"+ + "\1\76\1\0\1\76\1\77\1\0\1\30\2\0\1\201"+ + "\1\0\1\41\1\30\1\202\17\43\1\u0266\12\43\1\203"+ + "\12\204\1\76\1\154\1\205\1\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\2\0\1\55\1\0"+ + "\1\56\2\0\1\57\1\0\1\60\4\0\1\61\1\0"+ + "\1\62\1\0\1\63\2\0\1\64\3\0\1\65\2\0"+ + "\1\66\4\0\1\67\3\0\1\70\17\0\1\71\2\0"+ + "\1\72\21\0\1\73\2\0\1\74\61\0\2\30\1\75"+ + "\1\0\1\76\1\0\1\76\1\77\1\0\1\30\2\0"+ + "\1\201\1\0\1\41\1\30\1\202\12\43\1\u0267\17\43"+ + "\1\203\12\204\1\76\1\154\1\205\1\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\2\0\1\55"+ + "\1\0\1\56\2\0\1\57\1\0\1\60\4\0\1\61"+ + "\1\0\1\62\1\0\1\63\2\0\1\64\3\0\1\65"+ + "\2\0\1\66\4\0\1\67\3\0\1\70\17\0\1\71"+ + "\2\0\1\72\21\0\1\73\2\0\1\74\61\0\2\30"+ + "\1\75\1\0\1\76\1\0\1\76\1\77\1\0\1\30"+ + "\2\0\1\201\1\0\1\41\1\30\1\202\3\43\1\u0268"+ + "\26\43\1\203\12\204\1\76\1\154\1\205\1\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\2\0"+ + "\1\55\1\0\1\56\2\0\1\57\1\0\1\60\4\0"+ + "\1\61\1\0\1\62\1\0\1\63\2\0\1\64\3\0"+ + "\1\65\2\0\1\66\4\0\1\67\3\0\1\70\17\0"+ + "\1\71\2\0\1\72\21\0\1\73\2\0\1\74\61\0"+ + "\2\30\1\75\1\0\1\76\1\0\1\76\1\77\1\0"+ + "\1\30\2\0\1\201\1\0\1\41\1\30\1\202\3\43"+ + "\1\u0269\26\43\1\203\12\204\1\76\1\154\1\205\1\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\2\0\1\55\1\0\1\56\2\0\1\57\1\0\1\60"+ + "\4\0\1\61\1\0\1\62\1\0\1\63\2\0\1\64"+ + "\3\0\1\65\2\0\1\66\4\0\1\67\3\0\1\70"+ + "\17\0\1\71\2\0\1\72\21\0\1\73\2\0\1\74"+ + "\61\0\2\30\1\75\1\0\1\76\1\0\1\76\1\77"+ + "\1\0\1\30\2\0\1\201\1\0\1\41\1\30\1\202"+ + "\10\43\1\u026a\21\43\1\203\12\204\1\76\1\154\1\205"+ + "\1\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\2\0\1\55\1\0\1\56\2\0\1\57\1\0"+ + "\1\60\4\0\1\61\1\0\1\62\1\0\1\63\2\0"+ + "\1\64\3\0\1\65\2\0\1\66\4\0\1\67\3\0"+ + "\1\70\17\0\1\71\2\0\1\72\21\0\1\73\2\0"+ + "\1\74\61\0\2\30\1\75\1\0\1\76\1\0\1\76"+ + "\1\77\1\0\1\30\2\0\1\201\1\0\1\41\1\30"+ + "\1\202\1\u026b\31\43\1\203\12\204\1\76\1\154\1\205"+ + "\1\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\2\0\1\55\1\0\1\56\2\0\1\57\1\0"+ + "\1\60\4\0\1\61\1\0\1\62\1\0\1\63\2\0"+ + "\1\64\3\0\1\65\2\0\1\66\4\0\1\67\3\0"+ + "\1\70\17\0\1\71\2\0\1\72\21\0\1\73\2\0"+ + "\1\74\61\0\2\30\1\75\1\0\1\76\1\0\1\76"+ + "\1\77\1\0\1\30\2\0\1\201\1\0\1\41\1\30"+ + "\1\202\11\43\1\u026c\20\43\1\203\12\204\1\76\1\154"+ + "\1\205\1\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\2\0\1\55\1\0\1\56\2\0\1\57"+ + "\1\0\1\60\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\65\2\0\1\66\4\0\1\67"+ + "\3\0\1\70\17\0\1\71\2\0\1\72\21\0\1\73"+ + "\2\0\1\74\61\0\2\30\1\75\1\0\1\76\1\0"+ + "\1\76\1\77\1\0\1\30\2\0\1\201\1\0\1\41"+ + "\1\30\1\202\15\43\1\u026d\14\43\1\203\12\204\1\76"+ + "\1\154\1\205\1\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\2\0\1\55\1\0\1\56\2\0"+ + "\1\57\1\0\1\60\4\0\1\61\1\0\1\62\1\0"+ + "\1\63\2\0\1\64\3\0\1\65\2\0\1\66\4\0"+ + "\1\67\3\0\1\70\17\0\1\71\2\0\1\72\21\0"+ + "\1\73\2\0\1\74\61\0\2\30\1\75\1\0\1\76"+ + "\1\0\1\76\1\77\1\0\1\30\2\0\1\201\1\0"+ + "\1\41\1\30\1\202\2\43\1\u0141\27\43\1\203\12\204"+ + "\1\76\1\154\1\205\1\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\2\0\1\55\1\0\1\56"+ + "\2\0\1\57\1\0\1\60\4\0\1\61\1\0\1\62"+ + "\1\0\1\63\2\0\1\64\3\0\1\65\2\0\1\66"+ + "\4\0\1\67\3\0\1\70\17\0\1\71\2\0\1\72"+ + "\21\0\1\73\2\0\1\74\61\0\2\30\1\75\1\0"+ + "\1\76\1\0\1\76\1\77\1\0\1\30\2\0\1\201"+ + "\1\0\1\41\1\30\1\202\25\43\1\u026e\4\43\1\203"+ + "\12\204\1\76\1\154\1\205\1\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\2\0\1\55\1\0"+ + "\1\56\2\0\1\57\1\0\1\60\4\0\1\61\1\0"+ + "\1\62\1\0\1\63\2\0\1\64\3\0\1\65\2\0"+ + "\1\66\4\0\1\67\3\0\1\70\17\0\1\71\2\0"+ + "\1\72\21\0\1\73\2\0\1\74\61\0\2\30\1\75"+ + "\1\0\1\76\1\0\1\76\1\77\1\0\1\30\2\0"+ + "\1\201\1\0\1\41\1\30\1\202\10\43\1\u0141\21\43"+ + "\1\203\12\204\1\76\1\154\1\205\1\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\2\0\1\55"+ + "\1\0\1\56\2\0\1\57\1\0\1\60\4\0\1\61"+ + "\1\0\1\62\1\0\1\63\2\0\1\64\3\0\1\65"+ + "\2\0\1\66\4\0\1\67\3\0\1\70\17\0\1\71"+ + "\2\0\1\72\21\0\1\73\2\0\1\74\61\0\2\30"+ + "\1\75\1\0\1\76\1\0\1\76\1\77\1\0\1\30"+ + "\2\0\1\201\1\0\1\41\1\30\1\202\3\43\1\u026f"+ + "\26\43\1\203\12\204\1\76\1\154\1\205\1\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\2\0"+ + "\1\55\1\0\1\56\2\0\1\57\1\0\1\60\4\0"+ + "\1\61\1\0\1\62\1\0\1\63\2\0\1\64\3\0"+ + "\1\65\2\0\1\66\4\0\1\67\3\0\1\70\17\0"+ + "\1\71\2\0\1\72\21\0\1\73\2\0\1\74\61\0"+ + "\2\30\1\75\1\0\1\76\1\0\1\76\1\77\1\0"+ + "\1\30\2\0\1\201\1\0\1\41\1\30\1\202\3\43"+ + "\1\u0141\26\43\1\203\12\204\1\76\1\154\1\205\1\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\2\0\1\55\1\0\1\56\2\0\1\57\1\0\1\60"+ + "\4\0\1\61\1\0\1\62\1\0\1\63\2\0\1\64"+ + "\3\0\1\65\2\0\1\66\4\0\1\67\3\0\1\70"+ + "\17\0\1\71\2\0\1\72\21\0\1\73\2\0\1\74"+ + "\61\0\2\30\1\75\1\0\1\76\1\0\1\76\1\77"+ + "\1\0\1\30\2\0\1\201\1\0\1\41\1\30\1\202"+ + "\17\43\1\u0141\12\43\1\203\12\204\1\76\1\154\1\205"+ + "\1\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\2\0\1\55\1\0\1\56\2\0\1\57\1\0"+ + "\1\60\4\0\1\61\1\0\1\62\1\0\1\63\2\0"+ + "\1\64\3\0\1\65\2\0\1\66\4\0\1\67\3\0"+ + "\1\70\17\0\1\71\2\0\1\72\21\0\1\73\2\0"+ + "\1\74\61\0\2\30\1\75\1\0\1\76\1\0\1\76"+ + "\1\77\1\0\1\30\2\0\1\201\1\0\1\41\1\30"+ + "\1\202\12\43\1\u0270\17\43\1\203\12\204\1\76\1\154"+ + "\1\205\1\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\2\0\1\55\1\0\1\56\2\0\1\57"+ + "\1\0\1\60\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\65\2\0\1\66\4\0\1\67"+ + "\3\0\1\70\17\0\1\71\2\0\1\72\21\0\1\73"+ + "\2\0\1\74\61\0\2\30\1\75\1\0\1\76\1\0"+ + "\1\76\1\77\1\0\1\30\2\0\1\201\1\0\1\41"+ + "\1\30\1\202\17\43\1\u0271\12\43\1\203\12\204\1\76"+ + "\1\154\1\205\1\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\2\0\1\55\1\0\1\56\2\0"+ + "\1\57\1\0\1\60\4\0\1\61\1\0\1\62\1\0"+ + "\1\63\2\0\1\64\3\0\1\65\2\0\1\66\4\0"+ + "\1\67\3\0\1\70\17\0\1\71\2\0\1\72\21\0"+ + "\1\73\2\0\1\74\61\0\2\30\1\75\1\0\1\76"+ + "\1\0\1\76\1\77\1\0\1\30\2\0\1\201\1\0"+ + "\1\41\1\30\1\202\31\43\1\u0141\1\203\12\204\1\76"+ + "\1\154\1\205\1\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\2\0\1\55\1\0\1\56\2\0"+ + "\1\57\1\0\1\60\4\0\1\61\1\0\1\62\1\0"+ + "\1\63\2\0\1\64\3\0\1\65\2\0\1\66\4\0"+ + "\1\67\3\0\1\70\17\0\1\71\2\0\1\72\21\0"+ + "\1\73\2\0\1\74\61\0\2\30\1\75\1\0\1\76"+ + "\1\0\1\76\1\77\1\0\1\30\2\0\1\201\1\0"+ + "\1\41\1\30\1\202\7\43\1\u0272\22\43\1\203\12\204"+ + "\1\76\1\154\1\205\1\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\2\0\1\55\1\0\1\56"+ + "\2\0\1\57\1\0\1\60\4\0\1\61\1\0\1\62"+ + "\1\0\1\63\2\0\1\64\3\0\1\65\2\0\1\66"+ + "\4\0\1\67\3\0\1\70\17\0\1\71\2\0\1\72"+ + "\21\0\1\73\2\0\1\74\61\0\2\30\1\75\1\0"+ + "\1\76\1\0\1\76\1\77\1\0\1\30\2\0\1\201"+ + "\1\0\1\41\1\30\1\202\17\43\1\u0273\12\43\1\203"+ + "\12\204\1\76\1\154\1\205\1\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\2\0\1\55\1\0"+ + "\1\56\2\0\1\57\1\0\1\60\4\0\1\61\1\0"+ + "\1\62\1\0\1\63\2\0\1\64\3\0\1\65\2\0"+ + "\1\66\4\0\1\67\3\0\1\70\17\0\1\71\2\0"+ + "\1\72\21\0\1\73\2\0\1\74\61\0\2\30\1\75"+ + "\1\0\1\76\1\0\1\76\1\77\1\0\1\30\2\0"+ + "\1\201\1\0\1\41\1\30\1\202\25\43\1\u0274\4\43"+ + "\1\203\12\204\1\76\1\154\1\205\1\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\2\0\1\55"+ + "\1\0\1\56\2\0\1\57\1\0\1\60\4\0\1\61"+ + "\1\0\1\62\1\0\1\63\2\0\1\64\3\0\1\65"+ + "\2\0\1\66\4\0\1\67\3\0\1\70\17\0\1\71"+ + "\2\0\1\72\21\0\1\73\2\0\1\74\61\0\2\30"+ + "\1\75\1\0\1\76\1\0\1\76\1\77\1\0\1\30"+ + "\2\0\1\201\1\0\1\41\1\30\1\202\30\43\1\u0275"+ + "\1\43\1\203\12\204\1\76\1\154\1\205\1\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\2\0"+ + "\1\55\1\0\1\56\2\0\1\57\1\0\1\60\4\0"+ + "\1\61\1\0\1\62\1\0\1\63\2\0\1\64\3\0"+ + "\1\65\2\0\1\66\4\0\1\67\3\0\1\70\17\0"+ + "\1\71\2\0\1\72\21\0\1\73\2\0\1\74\61\0"+ + "\2\30\1\75\1\0\1\76\1\0\1\76\1\77\1\0"+ + "\1\30\2\0\1\201\1\0\1\41\1\30\1\202\1\u01e7"+ + "\31\43\1\203\12\204\1\76\1\154\1\205\1\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\2\0"+ + "\1\55\1\0\1\56\2\0\1\57\1\0\1\60\4\0"+ + "\1\61\1\0\1\62\1\0\1\63\2\0\1\64\3\0"+ + "\1\65\2\0\1\66\4\0\1\67\3\0\1\70\17\0"+ + "\1\71\2\0\1\72\21\0\1\73\2\0\1\74\61\0"+ + "\2\30\1\75\1\0\1\76\1\0\1\76\1\77\1\0"+ + "\1\30\2\0\1\201\1\0\1\41\1\30\1\202\16\43"+ + "\1\u0141\13\43\1\203\12\204\1\76\1\154\1\205\1\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\155\32\371\1\u0276\12\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\2\0\1\55\1\0\1\56\2\0\1\57\1\0"+ + "\1\60\4\0\1\61\1\0\1\62\1\0\1\63\2\0"+ + "\1\64\3\0\1\65\2\0\1\66\4\0\1\67\3\0"+ + "\1\70\17\0\1\71\2\0\1\72\21\0\1\73\2\0"+ + "\1\74\61\0\2\30\1\75\1\0\1\76\1\0\1\76"+ + "\1\77\1\0\1\30\2\0\1\201\1\0\1\41\1\30"+ + "\1\202\2\43\1\u0277\27\43\1\203\12\204\1\76\1\154"+ + "\1\205\1\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\2\0\1\55\1\0\1\56\2\0\1\57"+ + "\1\0\1\60\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\65\2\0\1\66\4\0\1\67"+ + "\3\0\1\70\17\0\1\71\2\0\1\72\21\0\1\73"+ + "\2\0\1\74\61\0\2\30\1\75\1\0\1\76\1\0"+ + "\1\76\1\77\1\0\1\30\2\0\1\201\1\0\1\41"+ + "\1\30\1\202\1\43\1\u0278\30\43\1\203\12\204\1\76"+ + "\1\154\1\205\1\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\2\0\1\55\1\0\1\56\2\0"+ + "\1\57\1\0\1\60\4\0\1\61\1\0\1\62\1\0"+ + "\1\63\2\0\1\64\3\0\1\65\2\0\1\66\4\0"+ + "\1\67\3\0\1\70\17\0\1\71\2\0\1\72\21\0"+ + "\1\73\2\0\1\74\61\0\2\30\1\75\1\0\1\76"+ + "\1\0\1\76\1\77\1\0\1\30\2\0\1\201\1\0"+ + "\1\41\1\30\1\202\17\43\1\u0279\12\43\1\203\12\204"+ + "\1\76\1\154\1\205\1\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\2\0\1\55\1\0\1\56"+ + "\2\0\1\57\1\0\1\60\4\0\1\61\1\0\1\62"+ + "\1\0\1\63\2\0\1\64\3\0\1\65\2\0\1\66"+ + "\4\0\1\67\3\0\1\70\17\0\1\71\2\0\1\72"+ + "\21\0\1\73\2\0\1\74\61\0\2\30\1\75\1\0"+ + "\1\76\1\0\1\76\1\77\1\0\1\30\2\0\1\201"+ + "\1\0\1\41\1\30\1\202\1\u027a\31\43\1\203\12\204"+ + "\1\76\1\154\1\205\1\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\2\0\1\55\1\0\1\56"+ + "\2\0\1\245\1\0\1\246\4\0\1\61\1\0\1\62"+ + "\1\0\1\63\2\0\1\64\3\0\1\247\2\0\1\250"+ + "\4\0\1\251\3\0\1\252\17\0\1\71\2\0\1\253"+ + "\21\0\1\254\2\0\1\255\61\0\1\30\1\76\2\0"+ + "\1\76\1\0\2\76\1\0\1\76\2\0\1\76\1\0"+ + "\2\30\1\76\32\30\13\0\1\76\1\0\1\76\5\0"+ + "\1\u027b\307\0\1\u027c\14\0\1\55\1\0\1\56\2\0"+ + "\1\57\1\0\1\60\4\0\1\61\1\0\1\62\1\0"+ + "\1\63\2\0\1\64\3\0\1\65\2\0\1\66\4\0"+ + "\1\67\3\0\1\70\17\0\1\71\2\0\1\72\21\0"+ + "\1\73\2\0\1\74\61\0\2\30\1\75\1\0\1\76"+ + "\1\0\1\76\1\77\1\0\1\30\2\0\1\201\1\0"+ + "\1\41\1\30\1\202\5\43\1\u027d\24\43\1\203\12\204"+ + "\1\76\1\154\1\205\1\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\2\0\1\55\1\0\1\56"+ + "\2\0\1\57\1\0\1\60\4\0\1\61\1\0\1\62"+ + "\1\0\1\63\2\0\1\64\3\0\1\65\2\0\1\66"+ + "\4\0\1\67\3\0\1\70\17\0\1\71\2\0\1\72"+ + "\21\0\1\73\2\0\1\74\61\0\2\30\1\75\1\0"+ + "\1\76\1\0\1\76\1\77\1\0\1\30\2\0\1\201"+ + "\1\0\1\41\1\30\1\202\32\43\1\203\12\204\1\u01f7"+ + "\1\154\1\205\1\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\2\0\1\55\1\0\1\56\2\0"+ + "\1\245\1\0\1\246\4\0\1\61\1\0\1\62\1\0"+ + "\1\63\2\0\1\64\3\0\1\247\2\0\1\250\4\0"+ + "\1\251\3\0\1\252\17\0\1\71\2\0\1\253\21\0"+ + "\1\254\2\0\1\255\61\0\1\30\1\76\2\0\1\76"+ + "\1\0\2\76\1\0\1\76\2\0\1\76\1\0\2\30"+ + "\1\76\32\30\13\0\1\76\1\0\1\76\5\0\1\u027e"+ + "\225\0\1\154\1\157\2\0\1\155\1\u0103\1\u0104\1\u0105"+ + "\1\u0106\1\u0107\1\u0108\1\u0109\1\u010a\1\u010b\1\u010c\1\u010d"+ + "\1\u010e\1\u010f\1\u0110\1\u0111\1\u0112\1\u0113\1\u0114\1\u0115"+ + "\1\u0116\1\u0117\1\u0118\1\u0119\1\u011a\1\u011b\1\u011c\1\154"+ + "\12\371\1\u01f9\3\154\1\0\1\154\1\156\1\u01d1\1\u01d2"+ + "\1\u01d3\3\0\1\154\3\0\2\154\253\0\12\u0259\236\0"+ + "\1\154\3\0\1\u016f\3\371\1\u027f\26\371\1\203\12\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\15\371\1\u0174"+ + "\14\371\1\203\12\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\16\371\1\u0280\1\u0281\12\371\1\203\12\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\17\371\1\u0282\12\371"+ + "\1\203\12\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\12\371\1\u0283\17\371\1\203\12\371\1\0\3\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\213\0"+ + "\1\154\3\0\1\u016f\3\371\1\u0284\26\371\1\203\12\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\3\371\1\u0285"+ + "\26\371\1\203\12\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\10\371\1\u0286\21\371\1\203\12\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\1\u0287\31\371\1\203\12\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\11\371\1\u0288"+ + "\20\371\1\203\12\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\15\371\1\u0289\14\371\1\203\12\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\2\371\1\u0174\27\371\1\203"+ + "\12\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\25\371"+ + "\1\u028a\4\371\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\10\371\1\u0174\21\371\1\203\12\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\3\371\1\u028b\26\371"+ + "\1\203\12\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\3\371\1\u0174\26\371\1\203\12\371\1\0\3\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\213\0"+ + "\1\154\3\0\1\u016f\17\371\1\u0174\12\371\1\203\12\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\12\371\1\u028c"+ + "\17\371\1\203\12\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\17\371\1\u028d\12\371\1\203\12\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\31\371\1\u0174\1\203\12\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\7\371\1\u028e"+ + "\22\371\1\203\12\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\17\371\1\u028f\12\371\1\203\12\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\25\371\1\u0290\4\371\1\203"+ + "\12\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\30\371"+ + "\1\u0291\1\371\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\1\u020d\31\371\1\203\12\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\16\371\1\u0174\13\371\1\203"+ + "\12\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\2\371"+ + "\1\u0292\27\371\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\1\371\1\u0293\30\371\1\203\12\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\17\371\1\u0294\12\371"+ + "\1\203\12\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\1\u0295\31\371\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\2\0\1\55"+ + "\1\0\1\56\2\0\1\100\1\0\1\101\4\0\1\61"+ + "\1\0\1\62\1\0\1\63\2\0\1\64\3\0\1\102"+ + "\2\0\1\103\4\0\1\104\3\0\1\105\17\0\1\71"+ + "\2\0\1\106\21\0\1\107\2\0\1\110\61\0\1\30"+ + "\2\31\2\0\2\111\1\112\1\0\1\31\2\0\1\212"+ + "\1\0\1\41\1\30\1\u0296\32\43\1\203\12\u0297\1\0"+ + "\1\154\1\215\1\154\1\0\1\212\1\156\3\154\2\0"+ + "\1\111\1\154\3\0\2\154\2\0\1\55\1\0\1\56"+ + "\2\0\1\100\1\0\1\101\4\0\1\61\1\0\1\62"+ + "\1\0\1\63\2\0\1\64\3\0\1\102\2\0\1\103"+ + "\4\0\1\104\3\0\1\105\17\0\1\71\2\0\1\106"+ + "\21\0\1\107\2\0\1\110\61\0\1\30\2\31\2\0"+ + "\2\111\1\112\1\0\1\31\2\0\1\212\1\0\1\41"+ + "\1\30\1\u0296\32\43\1\203\12\u0218\1\0\1\154\1\215"+ + "\1\154\1\0\1\212\1\156\3\154\2\0\1\111\1\154"+ + "\3\0\2\154\2\0\1\55\1\0\1\56\2\0\1\100"+ + "\1\0\1\101\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\102\2\0\1\103\4\0\1\104"+ + "\3\0\1\105\17\0\1\71\2\0\1\106\21\0\1\107"+ + "\2\0\1\110\61\0\1\30\2\31\2\0\2\111\1\112"+ + "\1\0\1\31\2\0\1\212\1\0\1\41\1\30\1\u0296"+ + "\32\43\1\203\2\u0218\1\u0297\1\u0218\1\u0298\2\u0297\2\u0218"+ + "\1\u0297\1\0\1\154\1\215\1\154\1\0\1\212\1\156"+ + "\3\154\2\0\1\111\1\154\3\0\2\154\265\0\1\u0123"+ + "\242\0\4\u0299\2\0\1\u0299\15\0\1\u0299\6\0\12\u0299"+ + "\1\u021d\242\0\4\u029a\2\0\1\u029a\15\0\1\u029a\6\0"+ + "\12\u029a\1\u029b\242\0\4\u029c\2\0\1\u029c\15\0\1\u029c"+ + "\6\0\12\u029c\1\u029d\12\0\1\u01ad\226\0\1\u0224\4\u029c"+ + "\2\0\1\u029c\15\0\1\u029c\6\0\12\u029e\1\u029d\12\0"+ + "\1\u01ad\226\0\1\u0224\4\u029c\2\0\1\u029c\15\0\1\u029c"+ + "\6\0\12\u029f\1\u029d\12\0\1\u01ad\226\0\1\u0224\4\u029c"+ + "\2\0\1\u029c\15\0\1\u029c\6\0\2\u029f\1\u029e\1\u029f"+ + "\1\u02a0\2\u029e\2\u029f\1\u029e\1\u029d\12\0\1\u01ad\227\0"+ + "\4\u02a1\2\0\1\u02a1\15\0\1\u02a1\6\0\12\u02a1\1\u0223"+ + "\12\0\1\u01ad\227\0\4\u021e\2\0\1\u021e\15\0\1\u021e"+ + "\6\0\1\u021f\1\u0220\5\u021f\1\u0221\1\u0220\1\u021f\276\0"+ + "\1\u02a2\1\u02a3\5\u02a2\1\u02a4\1\u02a3\1\u02a2\242\0\1\u0224"+ + "\4\u02a1\2\0\1\u02a1\15\0\1\u02a1\6\0\12\u02a1\1\u0223"+ + "\12\0\1\u01ad\226\0\1\u0224\4\u02a1\2\0\1\u02a1\15\0"+ + "\1\u02a1\6\0\12\u02a5\1\u0223\12\0\1\u01ad\226\0\1\u0224"+ + "\4\u02a1\2\0\1\u02a1\15\0\1\u02a1\6\0\2\u02a5\1\u02a1"+ + "\2\u02a5\2\u02a1\2\u02a5\1\u02a1\1\u0223\12\0\1\u01ad\222\0"+ + "\1\u0228\3\0\51\u0228\1\u02a6\5\u0228\1\u022a\2\0\2\u0228"+ + "\3\0\1\u0228\220\0\51\u0229\1\u02a7\2\0\1\u0229\1\u0228"+ + "\1\u0229\1\u022a\2\0\2\u0229\220\0\1\u022a\3\0\51\u022a"+ + "\1\u02a8\5\u022a\3\0\2\u022a\3\0\1\u022a\220\0\1\u02a9"+ + "\32\323\1\u0137\12\323\242\0\1\u02a9\4\323\1\u0250\25\323"+ + "\1\u0137\12\323\242\0\1\u02a9\15\323\1\u01c1\14\323\1\u0137"+ + "\12\323\242\0\1\u02a9\10\323\1\u01c1\21\323\1\u0137\12\323"+ + "\242\0\1\u02a9\12\323\1\u02aa\4\323\1\u022b\12\323\1\u0137"+ + "\12\323\242\0\1\u02a9\5\323\1\u02ab\4\323\1\u022b\1\u02ac"+ + "\16\323\1\u0137\12\323\242\0\1\u02a9\5\323\1\u02ad\24\323"+ + "\1\u0137\12\323\242\0\1\u0136\1\u02ae\3\323\1\u02af\25\323"+ + "\1\u0137\12\323\242\0\1\u0136\20\323\1\u022b\11\323\1\u0137"+ + "\12\323\242\0\1\u0136\17\323\1\u02b0\12\323\1\u0137\12\323"+ + "\242\0\1\u0136\20\323\1\u02b1\11\323\1\u0137\12\323\242\0"+ + "\1\u02a9\17\323\1\u02b2\12\323\1\u0137\12\323\242\0\1\u0136"+ + "\7\323\1\u022b\22\323\1\u0137\12\323\242\0\1\u02a9\11\323"+ + "\1\u02b3\20\323\1\u0137\12\323\242\0\1\u02a9\1\u02b4\31\323"+ + "\1\u0137\12\323\242\0\1\u0136\30\323\1\u022b\1\323\1\u0137"+ + "\12\323\242\0\1\u02a9\4\323\1\u0233\25\323\1\u0137\12\323"+ + "\242\0\1\u02a9\6\323\1\u0250\10\323\1\u022b\12\323\1\u0137"+ + "\12\323\242\0\1\u02a9\13\323\1\u02b5\16\323\1\u0137\12\323"+ + "\242\0\1\u02a9\7\323\1\u02b6\22\323\1\u0137\12\323\242\0"+ + "\1\u02a9\13\323\1\u0233\16\323\1\u0137\12\323\242\0\1\u02a9"+ + "\24\323\1\u02b7\5\323\1\u0137\12\323\242\0\1\u0136\11\323"+ + "\1\u022b\20\323\1\u0137\12\323\242\0\1\u02a9\16\323\1\u02b8"+ + "\13\323\1\u0137\12\323\242\0\1\u02a9\12\323\1\u02b9\17\323"+ + "\1\u0137\12\323\242\0\1\u02a9\17\323\1\u022b\12\323\1\u0137"+ + "\12\323\242\0\1\u02a9\5\323\1\u022b\24\323\1\u0137\12\323"+ + "\242\0\1\u0136\16\323\1\u02ba\13\323\1\u0137\12\323\242\0"+ + "\1\u02a9\20\323\1\u02bb\11\323\1\u0137\12\323\242\0\1\u02a9"+ + "\5\323\1\u02bc\24\323\1\u0137\12\323\242\0\1\u02a9\22\323"+ + "\1\u02bd\7\323\1\u0137\12\323\242\0\1\u02a9\13\323\1\u02be"+ + "\16\323\1\u0137\12\323\242\0\1\u0136\17\323\1\u02bf\12\323"+ + "\1\u0137\12\323\242\0\1\u0136\1\323\1\u02c0\7\323\1\u022b"+ + "\20\323\1\u0137\12\323\242\0\1\u02a9\1\u02c1\31\323\1\u0137"+ + "\12\323\242\0\1\u02a9\2\323\1\u02c2\27\323\1\u0137\12\323"+ + "\242\0\1\u0136\15\323\1\u02c3\14\323\1\u0137\12\323\242\0"+ + "\1\u0136\5\323\1\u022b\24\323\1\u0137\12\323\242\0\1\u0136"+ + "\32\323\1\u02c4\12\323\242\0\1\u0136\22\323\1\u022b\7\323"+ + "\1\u0137\12\323\242\0\1\u02a9\23\323\1\u022b\2\323\1\u02b9"+ + "\3\323\1\u0137\12\323\242\0\1\u0136\11\323\1\u02c5\20\323"+ + "\1\u0137\12\323\242\0\1\u02a9\17\323\1\u02c6\12\323\1\u0137"+ + "\12\323\242\0\1\u02a9\24\323\1\u02c3\5\323\1\u0137\12\323"+ + "\242\0\1\u02a9\13\323\1\u02c7\16\323\1\u0137\12\323\242\0"+ + "\1\u0136\31\323\1\u02c8\1\u0137\12\323\276\0\12\u02c9\7\0"+ + "\1\u0228\1\u0229\1\u022a\224\0\1\u01d1\1\157\2\0\1\u025a"+ + "\45\u01d1\1\u0228\2\u01d1\1\u025b\1\u0228\1\u01d1\1\u025c\2\u01d1"+ + "\1\u01d3\2\0\1\u0228\1\u01d1\3\0\1\u01d1\1\154\213\0"+ + "\1\154\3\0\1\155\4\u02ca\2\154\1\u02ca\15\154\1\u02ca"+ + "\6\154\12\u02ca\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\u0228\3\0\51\u0228"+ + "\1\u02a6\5\u0228\1\u022a\1\324\1\0\2\u0228\3\0\1\u0228"+ + "\214\0\1\154\1\157\2\0\1\u025d\45\u01d2\1\u0229\2\u01d2"+ + "\1\u025e\1\0\1\154\1\u025f\1\u01d1\1\u01d2\1\u01d3\2\0"+ + "\1\u0229\1\u01d2\3\0\2\154\213\0\1\154\3\0\1\155"+ + "\4\u02cb\2\154\1\u02cb\15\154\1\u02cb\6\154\12\u02cb\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\217\0\51\u0229\1\u02a7\2\0\1\u0229\1\u0228\1\u0229"+ + "\1\u022a\1\324\1\0\2\u0229\220\0\1\u01d3\1\157\2\0"+ + "\1\u0260\45\u01d3\1\u022a\2\u01d3\1\u0261\1\u022a\1\u01d3\1\u0262"+ + "\2\u01d3\1\154\2\0\1\u022a\1\u01d3\3\0\1\u01d3\1\154"+ + "\213\0\1\154\3\0\1\155\4\u02cc\2\154\1\u02cc\15\154"+ + "\1\u02cc\6\154\12\u02cc\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\u022a\3\0"+ + "\51\u022a\1\u02a8\5\u022a\1\0\1\324\1\0\2\u022a\3\0"+ + "\1\u022a\3\0\1\55\1\0\1\56\2\0\1\57\1\0"+ + "\1\60\4\0\1\61\1\0\1\62\1\0\1\63\2\0"+ + "\1\64\3\0\1\65\2\0\1\66\4\0\1\67\3\0"+ + "\1\70\17\0\1\71\2\0\1\72\21\0\1\73\2\0"+ + "\1\74\61\0\2\30\1\75\1\0\1\76\1\0\1\76"+ + "\1\77\1\0\1\30\2\0\1\201\1\0\1\41\1\30"+ + "\1\202\4\43\1\353\25\43\1\203\12\204\1\76\1\154"+ + "\1\205\1\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\2\0\1\55\1\0\1\56\2\0\1\57"+ + "\1\0\1\60\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\65\2\0\1\66\4\0\1\67"+ + "\3\0\1\70\17\0\1\71\2\0\1\72\21\0\1\73"+ + "\2\0\1\74\61\0\2\30\1\75\1\0\1\76\1\0"+ + "\1\76\1\77\1\0\1\30\2\0\1\201\1\0\1\41"+ + "\1\30\1\202\17\43\1\u02cd\12\43\1\203\12\204\1\76"+ + "\1\154\1\205\1\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\2\0\1\55\1\0\1\56\2\0"+ + "\1\57\1\0\1\60\4\0\1\61\1\0\1\62\1\0"+ + "\1\63\2\0\1\64\3\0\1\65\2\0\1\66\4\0"+ + "\1\67\3\0\1\70\17\0\1\71\2\0\1\72\21\0"+ + "\1\73\2\0\1\74\61\0\2\30\1\75\1\0\1\76"+ + "\1\0\1\76\1\77\1\0\1\30\2\0\1\201\1\0"+ + "\1\41\1\30\1\202\4\43\1\u02ce\25\43\1\203\12\204"+ + "\1\76\1\154\1\205\1\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\2\0\1\55\1\0\1\56"+ + "\2\0\1\57\1\0\1\60\4\0\1\61\1\0\1\62"+ + "\1\0\1\63\2\0\1\64\3\0\1\65\2\0\1\66"+ + "\4\0\1\67\3\0\1\70\17\0\1\71\2\0\1\72"+ + "\21\0\1\73\2\0\1\74\61\0\2\30\1\75\1\0"+ + "\1\76\1\0\1\76\1\77\1\0\1\30\2\0\1\201"+ + "\1\0\1\41\1\30\1\202\25\43\1\u02cf\4\43\1\203"+ + "\12\204\1\76\1\154\1\205\1\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\2\0\1\55\1\0"+ + "\1\56\2\0\1\57\1\0\1\60\4\0\1\61\1\0"+ + "\1\62\1\0\1\63\2\0\1\64\3\0\1\65\2\0"+ + "\1\66\4\0\1\67\3\0\1\70\17\0\1\71\2\0"+ + "\1\72\21\0\1\73\2\0\1\74\61\0\2\30\1\75"+ + "\1\0\1\76\1\0\1\76\1\77\1\0\1\30\2\0"+ + "\1\201\1\0\1\41\1\30\1\202\5\43\1\u02d0\24\43"+ + "\1\203\12\204\1\76\1\154\1\205\1\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\2\0\1\55"+ + "\1\0\1\56\2\0\1\57\1\0\1\60\4\0\1\61"+ + "\1\0\1\62\1\0\1\63\2\0\1\64\3\0\1\65"+ + "\2\0\1\66\4\0\1\67\3\0\1\70\17\0\1\71"+ + "\2\0\1\72\21\0\1\73\2\0\1\74\61\0\2\30"+ + "\1\75\1\0\1\76\1\0\1\76\1\77\1\0\1\30"+ + "\2\0\1\201\1\0\1\41\1\30\1\202\1\43\1\u02d1"+ + "\30\43\1\203\12\204\1\76\1\154\1\205\1\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\2\0"+ + "\1\55\1\0\1\56\2\0\1\57\1\0\1\60\4\0"+ + "\1\61\1\0\1\62\1\0\1\63\2\0\1\64\3\0"+ + "\1\65\2\0\1\66\4\0\1\67\3\0\1\70\17\0"+ + "\1\71\2\0\1\72\21\0\1\73\2\0\1\74\61\0"+ + "\2\30\1\75\1\0\1\76\1\0\1\76\1\77\1\0"+ + "\1\30\2\0\1\201\1\0\1\41\1\30\1\202\4\43"+ + "\1\u02d2\25\43\1\203\12\204\1\76\1\154\1\205\1\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\2\0\1\55\1\0\1\56\2\0\1\57\1\0\1\60"+ + "\4\0\1\61\1\0\1\62\1\0\1\63\2\0\1\64"+ + "\3\0\1\65\2\0\1\66\4\0\1\67\3\0\1\70"+ + "\17\0\1\71\2\0\1\72\21\0\1\73\2\0\1\74"+ + "\61\0\2\30\1\75\1\0\1\76\1\0\1\76\1\77"+ + "\1\0\1\30\2\0\1\201\1\0\1\41\1\30\1\202"+ + "\15\43\1\u02d3\14\43\1\203\12\204\1\76\1\154\1\205"+ + "\1\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\2\0\1\55\1\0\1\56\2\0\1\57\1\0"+ + "\1\60\4\0\1\61\1\0\1\62\1\0\1\63\2\0"+ + "\1\64\3\0\1\65\2\0\1\66\4\0\1\67\3\0"+ + "\1\70\17\0\1\71\2\0\1\72\21\0\1\73\2\0"+ + "\1\74\61\0\2\30\1\75\1\0\1\76\1\0\1\76"+ + "\1\77\1\0\1\30\2\0\1\201\1\0\1\41\1\30"+ + "\1\202\17\43\1\u01e3\12\43\1\203\12\204\1\76\1\154"+ + "\1\205\1\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\2\0\1\55\1\0\1\56\2\0\1\57"+ + "\1\0\1\60\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\65\2\0\1\66\4\0\1\67"+ + "\3\0\1\70\17\0\1\71\2\0\1\72\21\0\1\73"+ + "\2\0\1\74\61\0\2\30\1\75\1\0\1\76\1\0"+ + "\1\76\1\77\1\0\1\30\2\0\1\201\1\0\1\41"+ + "\1\30\1\202\3\43\1\u02d4\26\43\1\203\12\204\1\76"+ + "\1\154\1\205\1\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\2\0\1\55\1\0\1\56\2\0"+ + "\1\57\1\0\1\60\4\0\1\61\1\0\1\62\1\0"+ + "\1\63\2\0\1\64\3\0\1\65\2\0\1\66\4\0"+ + "\1\67\3\0\1\70\17\0\1\71\2\0\1\72\21\0"+ + "\1\73\2\0\1\74\61\0\2\30\1\75\1\0\1\76"+ + "\1\0\1\76\1\77\1\0\1\30\2\0\1\201\1\0"+ + "\1\41\1\30\1\202\25\43\1\u02d5\4\43\1\203\12\204"+ + "\1\76\1\154\1\205\1\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\2\0\1\55\1\0\1\56"+ + "\2\0\1\57\1\0\1\60\4\0\1\61\1\0\1\62"+ + "\1\0\1\63\2\0\1\64\3\0\1\65\2\0\1\66"+ + "\4\0\1\67\3\0\1\70\17\0\1\71\2\0\1\72"+ + "\21\0\1\73\2\0\1\74\61\0\2\30\1\75\1\0"+ + "\1\76\1\0\1\76\1\77\1\0\1\30\2\0\1\201"+ + "\1\0\1\41\1\30\1\202\17\43\1\u02cf\12\43\1\203"+ + "\12\204\1\76\1\154\1\205\1\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\2\0\1\55\1\0"+ + "\1\56\2\0\1\57\1\0\1\60\4\0\1\61\1\0"+ + "\1\62\1\0\1\63\2\0\1\64\3\0\1\65\2\0"+ + "\1\66\4\0\1\67\3\0\1\70\17\0\1\71\2\0"+ + "\1\72\21\0\1\73\2\0\1\74\61\0\2\30\1\75"+ + "\1\0\1\76\1\0\1\76\1\77\1\0\1\30\2\0"+ + "\1\201\1\0\1\41\1\30\1\202\20\43\1\u02d6\11\43"+ + "\1\203\12\204\1\76\1\154\1\205\1\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\2\0\1\55"+ + "\1\0\1\56\2\0\1\57\1\0\1\60\4\0\1\61"+ + "\1\0\1\62\1\0\1\63\2\0\1\64\3\0\1\65"+ + "\2\0\1\66\4\0\1\67\3\0\1\70\17\0\1\71"+ + "\2\0\1\72\21\0\1\73\2\0\1\74\61\0\2\30"+ + "\1\75\1\0\1\76\1\0\1\76\1\77\1\0\1\30"+ + "\2\0\1\201\1\0\1\41\1\30\1\202\24\43\1\u02cf"+ + "\5\43\1\203\12\204\1\76\1\154\1\205\1\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\2\0"+ + "\1\55\1\0\1\56\2\0\1\57\1\0\1\60\4\0"+ + "\1\61\1\0\1\62\1\0\1\63\2\0\1\64\3\0"+ + "\1\65\2\0\1\66\4\0\1\67\3\0\1\70\17\0"+ + "\1\71\2\0\1\72\21\0\1\73\2\0\1\74\61\0"+ + "\2\30\1\75\1\0\1\76\1\0\1\76\1\77\1\0"+ + "\1\30\2\0\1\201\1\0\1\41\1\30\1\202\5\43"+ + "\1\u02d7\24\43\1\203\12\204\1\76\1\154\1\205\1\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\2\0\1\55\1\0\1\56\2\0\1\57\1\0\1\60"+ + "\4\0\1\61\1\0\1\62\1\0\1\63\2\0\1\64"+ + "\3\0\1\65\2\0\1\66\4\0\1\67\3\0\1\70"+ + "\17\0\1\71\2\0\1\72\21\0\1\73\2\0\1\74"+ + "\61\0\2\30\1\75\1\0\1\76\1\0\1\76\1\77"+ + "\1\0\1\30\2\0\1\201\1\0\1\41\1\30\1\202"+ + "\11\43\1\u02d8\20\43\1\203\12\204\1\76\1\154\1\205"+ + "\1\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\2\0\1\55\1\0\1\56\2\0\1\57\1\0"+ + "\1\60\4\0\1\61\1\0\1\62\1\0\1\63\2\0"+ + "\1\64\3\0\1\65\2\0\1\66\4\0\1\67\3\0"+ + "\1\70\17\0\1\71\2\0\1\72\21\0\1\73\2\0"+ + "\1\74\61\0\2\30\1\75\1\0\1\76\1\0\1\76"+ + "\1\77\1\0\1\30\2\0\1\201\1\0\1\41\1\30"+ + "\1\202\5\43\1\u0166\24\43\1\203\12\204\1\76\1\154"+ + "\1\205\1\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\2\0\1\55\1\0\1\56\2\0\1\57"+ + "\1\0\1\60\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\65\2\0\1\66\4\0\1\67"+ + "\3\0\1\70\17\0\1\71\2\0\1\72\21\0\1\73"+ + "\2\0\1\74\61\0\2\30\1\75\1\0\1\76\1\0"+ + "\1\76\1\77\1\0\1\30\2\0\1\201\1\0\1\41"+ + "\1\30\1\202\13\43\1\u02d9\16\43\1\203\12\204\1\76"+ + "\1\154\1\205\1\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\2\0\1\55\1\0\1\56\2\0"+ + "\1\57\1\0\1\60\4\0\1\61\1\0\1\62\1\0"+ + "\1\63\2\0\1\64\3\0\1\65\2\0\1\66\4\0"+ + "\1\67\3\0\1\70\17\0\1\71\2\0\1\72\21\0"+ + "\1\73\2\0\1\74\61\0\2\30\1\75\1\0\1\76"+ + "\1\0\1\76\1\77\1\0\1\30\2\0\1\201\1\0"+ + "\1\41\1\30\1\202\3\43\1\u0157\26\43\1\203\12\204"+ + "\1\76\1\154\1\205\1\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\155"+ + "\1\371\1\u02da\3\371\1\u02db\1\u02dc\1\u02dd\1\371\1\u02de"+ + "\1\u02df\1\u02e0\1\u02e1\1\u02e2\1\u02e3\1\371\1\u02e4\1\u02e5"+ + "\1\u02e6\2\371\1\u02e7\1\u02e8\1\u02e9\1\371\1\u02ea\1\203"+ + "\1\u02eb\2\371\1\u02ec\1\371\1\u02ed\1\u02ee\3\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\2\0\1\55\1\0\1\56\2\0\1\57\1\0"+ + "\1\60\4\0\1\61\1\0\1\62\1\0\1\63\2\0"+ + "\1\64\3\0\1\65\2\0\1\66\4\0\1\67\3\0"+ + "\1\70\17\0\1\71\2\0\1\72\21\0\1\73\2\0"+ + "\1\74\61\0\2\30\1\75\1\0\1\76\1\0\1\76"+ + "\1\77\1\0\1\30\2\0\1\201\1\0\1\41\1\30"+ + "\1\202\10\43\1\u02ef\21\43\1\203\12\204\1\76\1\154"+ + "\1\205\1\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\2\0\1\55\1\0\1\56\2\0\1\57"+ + "\1\0\1\60\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\65\2\0\1\66\4\0\1\67"+ + "\3\0\1\70\17\0\1\71\2\0\1\72\21\0\1\73"+ + "\2\0\1\74\61\0\2\30\1\75\1\0\1\76\1\0"+ + "\1\76\1\77\1\0\1\30\2\0\1\201\1\0\1\41"+ + "\1\30\1\202\25\43\1\u02f0\4\43\1\203\12\204\1\76"+ + "\1\154\1\205\1\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\2\0\1\55\1\0\1\56\2\0"+ + "\1\57\1\0\1\60\4\0\1\61\1\0\1\62\1\0"+ + "\1\63\2\0\1\64\3\0\1\65\2\0\1\66\4\0"+ + "\1\67\3\0\1\70\17\0\1\71\2\0\1\72\21\0"+ + "\1\73\2\0\1\74\61\0\2\30\1\75\1\0\1\76"+ + "\1\0\1\76\1\77\1\0\1\30\2\0\1\201\1\0"+ + "\1\41\1\30\1\202\20\43\1\u02f1\11\43\1\203\12\204"+ + "\1\76\1\154\1\205\1\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\2\0\1\55\1\0\1\56"+ + "\2\0\1\57\1\0\1\60\4\0\1\61\1\0\1\62"+ + "\1\0\1\63\2\0\1\64\3\0\1\65\2\0\1\66"+ + "\4\0\1\67\3\0\1\70\17\0\1\71\2\0\1\72"+ + "\21\0\1\73\2\0\1\74\61\0\2\30\1\75\1\0"+ + "\1\76\1\0\1\76\1\77\1\0\1\30\2\0\1\201"+ + "\1\0\1\41\1\30\1\202\7\43\1\u01e3\22\43\1\203"+ + "\12\204\1\76\1\154\1\205\1\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\275\0\1\u02f2\225\0"+ + "\1\u02f3\3\0\1\u02f3\32\u02f4\1\u02f3\12\u02f4\1\u02f5\2\u02f3"+ + "\1\u02f6\2\u02f3\1\u02f7\3\0\1\u02f8\1\0\2\u02f3\3\0"+ + "\1\u02f3\3\0\1\55\1\0\1\56\2\0\1\57\1\0"+ + "\1\60\4\0\1\61\1\0\1\62\1\0\1\63\2\0"+ + "\1\64\3\0\1\65\2\0\1\66\4\0\1\67\3\0"+ + "\1\70\17\0\1\71\2\0\1\72\21\0\1\73\2\0"+ + "\1\74\61\0\2\30\1\75\1\0\1\76\1\0\1\76"+ + "\1\77\1\0\1\30\2\0\1\201\1\0\1\41\1\30"+ + "\1\202\32\43\1\203\12\204\1\u02f9\1\154\1\205\1\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\275\0\1\u02fa\225\0\1\154\3\0\1\u016f\4\371\1\u010f"+ + "\25\371\1\203\12\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\17\371\1\u02fb\12\371\1\203\12\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\4\371\1\u02fc\25\371\1\203"+ + "\12\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\25\371"+ + "\1\u02fd\4\371\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\5\371\1\u02fe\24\371\1\203\12\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\1\371\1\u02ff\30\371"+ + "\1\203\12\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\4\371\1\u0300\25\371\1\203\12\371\1\0\3\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\213\0"+ + "\1\154\3\0\1\u016f\15\371\1\u0301\14\371\1\203\12\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\17\371\1\u0209"+ + "\12\371\1\203\12\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\3\371\1\u0302\26\371\1\203\12\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\25\371\1\u0303\4\371\1\203"+ + "\12\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\17\371"+ + "\1\u02fd\12\371\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\20\371\1\u0304\11\371\1\203\12\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\24\371\1\u02fd\5\371"+ + "\1\203\12\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\5\371\1\u0305\24\371\1\203\12\371\1\0\3\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\213\0"+ + "\1\154\3\0\1\u016f\11\371\1\u0306\20\371\1\203\12\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\5\371\1\u0199"+ + "\24\371\1\203\12\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\13\371\1\u0307\16\371\1\203\12\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\3\371\1\u018a\26\371\1\203"+ + "\12\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\10\371"+ + "\1\u0308\21\371\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\25\371\1\u0309\4\371\1\203\12\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\20\371\1\u030a\11\371"+ + "\1\203\12\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\7\371\1\u0209\22\371\1\203\12\371\1\0\3\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\7\0"+ + "\1\265\1\0\1\266\17\0\1\267\2\0\1\270\4\0"+ + "\1\271\3\0\1\272\22\0\1\273\21\0\1\274\2\0"+ + "\1\275\62\0\1\111\1\31\2\0\3\243\1\0\1\111"+ + "\2\0\1\372\1\157\2\0\1\u0102\1\u0103\1\u0104\1\u0105"+ + "\1\u0106\1\u0107\1\u0108\1\u0109\1\u010a\1\u010b\1\u010c\1\u010d"+ + "\1\u010e\1\u010f\1\u0110\1\u0111\1\u0112\1\u0113\1\u0114\1\u0115"+ + "\1\u0116\1\u0117\1\u0118\1\u0119\1\u011a\1\u011b\1\u011c\1\154"+ + "\1\u030b\1\u030c\5\u030b\1\u030d\1\u030c\1\u030b\1\0\1\154"+ + "\1\372\1\154\1\0\1\372\1\156\3\154\2\0\1\243"+ + "\1\154\3\0\2\154\2\0\1\55\1\0\1\56\2\0"+ + "\1\100\1\0\1\101\4\0\1\61\1\0\1\62\1\0"+ + "\1\63\2\0\1\64\3\0\1\102\2\0\1\103\4\0"+ + "\1\104\3\0\1\105\17\0\1\71\2\0\1\106\21\0"+ + "\1\107\2\0\1\110\61\0\1\30\2\31\2\0\2\111"+ + "\1\112\1\0\1\31\2\0\1\212\1\0\1\41\1\30"+ + "\1\u0296\32\43\1\203\12\u0120\1\0\1\154\1\215\1\154"+ + "\1\0\1\212\1\156\3\154\2\0\1\111\1\154\3\0"+ + "\2\154\2\0\1\55\1\0\1\56\2\0\1\100\1\0"+ + "\1\101\4\0\1\61\1\0\1\62\1\0\1\63\2\0"+ + "\1\64\3\0\1\102\2\0\1\103\4\0\1\104\3\0"+ + "\1\105\17\0\1\71\2\0\1\106\21\0\1\107\2\0"+ + "\1\110\61\0\1\30\2\31\2\0\2\111\1\112\1\0"+ + "\1\31\2\0\1\212\1\0\1\41\1\30\1\u0296\32\43"+ + "\1\203\2\u0297\1\u0120\2\u0297\2\u0120\2\u0297\1\u0120\1\0"+ + "\1\154\1\215\1\154\1\0\1\212\1\156\3\154\2\0"+ + "\1\111\1\154\3\0\2\154\220\0\4\u030e\2\0\1\u030e"+ + "\15\0\1\u030e\6\0\12\u030e\1\u021d\242\0\4\u030f\2\0"+ + "\1\u030f\15\0\1\u030f\6\0\12\u030f\1\u0310\242\0\4\u0311"+ + "\2\0\1\u0311\15\0\1\u0311\6\0\1\u0312\1\u0313\5\u0312"+ + "\1\u0314\1\u0313\1\u0312\13\0\1\u01ad\227\0\4\u0315\2\0"+ + "\1\u0315\15\0\1\u0315\6\0\12\u0315\1\u029d\12\0\1\u01ad"+ + "\227\0\4\u0311\2\0\1\u0311\15\0\1\u0311\6\0\1\u0312"+ + "\1\u0313\5\u0312\1\u0314\1\u0313\1\u0312\242\0\1\u0224\4\u0315"+ + "\2\0\1\u0315\15\0\1\u0315\6\0\12\u0315\1\u029d\12\0"+ + "\1\u01ad\226\0\1\u0224\4\u0315\2\0\1\u0315\15\0\1\u0315"+ + "\6\0\12\u0316\1\u029d\12\0\1\u01ad\226\0\1\u0224\4\u0315"+ + "\2\0\1\u0315\15\0\1\u0315\6\0\2\u0316\1\u0315\2\u0316"+ + "\2\u0315\2\u0316\1\u0315\1\u029d\12\0\1\u01ad\227\0\4\u0317"+ + "\2\0\1\u0317\15\0\1\u0317\6\0\12\u0317\1\u0223\12\0"+ + "\1\u01ad\226\0\1\u0318\33\0\12\u0319\242\0\1\u0318\33\0"+ + "\12\u02a2\242\0\1\u0318\33\0\2\u02a2\1\u0319\1\u02a2\1\u031a"+ + "\2\u0319\2\u02a2\1\u0319\242\0\1\u0224\4\u0317\2\0\1\u0317"+ + "\15\0\1\u0317\6\0\12\u0317\1\u0223\12\0\1\u01ad\227\0"+ + "\4\u031b\2\0\1\u031b\15\0\1\u031b\6\0\12\u031b\243\0"+ + "\4\u031c\2\0\1\u031c\15\0\1\u031c\6\0\12\u031c\243\0"+ + "\4\u031d\2\0\1\u031d\15\0\1\u031d\6\0\12\u031d\242\0"+ + "\1\u0136\3\323\1\u031e\26\323\1\u0137\12\323\242\0\1\u0136"+ + "\15\323\1\u022b\14\323\1\u0137\12\323\242\0\1\u0136\16\323"+ + "\1\u031f\1\u0320\12\323\1\u0137\12\323\242\0\1\u0136\17\323"+ + "\1\u0321\12\323\1\u0137\12\323\242\0\1\u0136\12\323\1\u0322"+ + "\17\323\1\u0137\12\323\242\0\1\u0136\3\323\1\u0323\26\323"+ + "\1\u0137\12\323\242\0\1\u0136\3\323\1\u0324\26\323\1\u0137"+ + "\12\323\242\0\1\u0136\10\323\1\u0325\21\323\1\u0137\12\323"+ + "\242\0\1\u0136\1\u0326\31\323\1\u0137\12\323\242\0\1\u0136"+ + "\11\323\1\u0327\20\323\1\u0137\12\323\242\0\1\u0136\15\323"+ + "\1\u0328\14\323\1\u0137\12\323\242\0\1\u0136\2\323\1\u022b"+ + "\27\323\1\u0137\12\323\242\0\1\u0136\25\323\1\u0329\4\323"+ + "\1\u0137\12\323\242\0\1\u0136\10\323\1\u022b\21\323\1\u0137"+ + "\12\323\242\0\1\u0136\3\323\1\u032a\26\323\1\u0137\12\323"+ + "\242\0\1\u0136\3\323\1\u022b\26\323\1\u0137\12\323\242\0"+ + "\1\u0136\17\323\1\u022b\12\323\1\u0137\12\323\242\0\1\u0136"+ + "\12\323\1\u032b\17\323\1\u0137\12\323\242\0\1\u0136\17\323"+ + "\1\u032c\12\323\1\u0137\12\323\242\0\1\u0136\31\323\1\u022b"+ + "\1\u0137\12\323\242\0\1\u0136\7\323\1\u032d\22\323\1\u0137"+ + "\12\323\242\0\1\u0136\17\323\1\u032e\12\323\1\u0137\12\323"+ + "\242\0\1\u0136\25\323\1\u032f\4\323\1\u0137\12\323\242\0"+ + "\1\u0136\30\323\1\u0330\1\323\1\u0137\12\323\242\0\1\u0136"+ + "\1\u02bd\31\323\1\u0137\12\323\242\0\1\u0136\16\323\1\u022b"+ + "\13\323\1\u0137\12\323\243\0\32\323\1\u0331\12\323\242\0"+ + "\1\u0136\2\323\1\u0332\27\323\1\u0137\12\323\242\0\1\u0136"+ + "\1\323\1\u0333\30\323\1\u0137\12\323\242\0\1\u0136\17\323"+ + "\1\u0334\12\323\1\u0137\12\323\242\0\1\u0136\1\u0335\31\323"+ + "\1\u0137\12\323\276\0\12\u0336\7\0\1\u0228\1\u0229\1\u022a"+ + "\224\0\1\154\3\0\1\155\4\u01d1\2\154\1\u01d1\15\154"+ + "\1\u01d1\6\154\12\u01d1\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\155\4\u01d2\2\154\1\u01d2\15\154\1\u01d2\6\154\12\u01d2"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\155\4\u01d3\2\154"+ + "\1\u01d3\15\154\1\u01d3\6\154\12\u01d3\1\0\3\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\2\0"+ + "\1\55\1\0\1\56\2\0\1\57\1\0\1\60\4\0"+ + "\1\61\1\0\1\62\1\0\1\63\2\0\1\64\3\0"+ + "\1\65\2\0\1\66\4\0\1\67\3\0\1\70\17\0"+ + "\1\71\2\0\1\72\21\0\1\73\2\0\1\74\61\0"+ + "\2\30\1\75\1\0\1\76\1\0\1\76\1\77\1\0"+ + "\1\30\2\0\1\201\1\0\1\41\1\30\1\202\4\43"+ + "\1\u0337\25\43\1\203\12\204\1\76\1\154\1\205\1\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\2\0\1\55\1\0\1\56\2\0\1\57\1\0\1\60"+ + "\4\0\1\61\1\0\1\62\1\0\1\63\2\0\1\64"+ + "\3\0\1\65\2\0\1\66\4\0\1\67\3\0\1\70"+ + "\17\0\1\71\2\0\1\72\21\0\1\73\2\0\1\74"+ + "\61\0\2\30\1\75\1\0\1\76\1\0\1\76\1\77"+ + "\1\0\1\30\2\0\1\201\1\0\1\41\1\30\1\202"+ + "\1\u0338\31\43\1\203\12\204\1\76\1\154\1\205\1\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\2\0\1\55\1\0\1\56\2\0\1\57\1\0\1\60"+ + "\4\0\1\61\1\0\1\62\1\0\1\63\2\0\1\64"+ + "\3\0\1\65\2\0\1\66\4\0\1\67\3\0\1\70"+ + "\17\0\1\71\2\0\1\72\21\0\1\73\2\0\1\74"+ + "\61\0\2\30\1\75\1\0\1\76\1\0\1\76\1\77"+ + "\1\0\1\30\2\0\1\201\1\0\1\41\1\30\1\202"+ + "\10\43\1\u0339\21\43\1\203\12\204\1\76\1\154\1\205"+ + "\1\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\2\0\1\55\1\0\1\56\2\0\1\57\1\0"+ + "\1\60\4\0\1\61\1\0\1\62\1\0\1\63\2\0"+ + "\1\64\3\0\1\65\2\0\1\66\4\0\1\67\3\0"+ + "\1\70\17\0\1\71\2\0\1\72\21\0\1\73\2\0"+ + "\1\74\61\0\2\30\1\75\1\0\1\76\1\0\1\76"+ + "\1\77\1\0\1\30\2\0\1\201\1\0\1\41\1\30"+ + "\1\202\13\43\1\u033a\16\43\1\203\12\204\1\76\1\154"+ + "\1\205\1\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\2\0\1\55\1\0\1\56\2\0\1\57"+ + "\1\0\1\60\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\65\2\0\1\66\4\0\1\67"+ + "\3\0\1\70\17\0\1\71\2\0\1\72\21\0\1\73"+ + "\2\0\1\74\61\0\2\30\1\75\1\0\1\76\1\0"+ + "\1\76\1\77\1\0\1\30\2\0\1\201\1\0\1\41"+ + "\1\30\1\202\17\43\1\u033b\12\43\1\203\12\204\1\76"+ + "\1\154\1\205\1\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\2\0\1\55\1\0\1\56\2\0"+ + "\1\57\1\0\1\60\4\0\1\61\1\0\1\62\1\0"+ + "\1\63\2\0\1\64\3\0\1\65\2\0\1\66\4\0"+ + "\1\67\3\0\1\70\17\0\1\71\2\0\1\72\21\0"+ + "\1\73\2\0\1\74\61\0\2\30\1\75\1\0\1\76"+ + "\1\0\1\76\1\77\1\0\1\30\2\0\1\201\1\0"+ + "\1\41\1\30\1\202\15\43\1\u033c\14\43\1\203\12\204"+ + "\1\76\1\154\1\205\1\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\2\0\1\55\1\0\1\56"+ + "\2\0\1\57\1\0\1\60\4\0\1\61\1\0\1\62"+ + "\1\0\1\63\2\0\1\64\3\0\1\65\2\0\1\66"+ + "\4\0\1\67\3\0\1\70\17\0\1\71\2\0\1\72"+ + "\21\0\1\73\2\0\1\74\61\0\2\30\1\75\1\0"+ + "\1\76\1\0\1\76\1\77\1\0\1\30\2\0\1\201"+ + "\1\0\1\41\1\30\1\202\12\43\1\u033d\17\43\1\203"+ + "\12\204\1\76\1\154\1\205\1\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\2\0\1\55\1\0"+ + "\1\56\2\0\1\57\1\0\1\60\4\0\1\61\1\0"+ + "\1\62\1\0\1\63\2\0\1\64\3\0\1\65\2\0"+ + "\1\66\4\0\1\67\3\0\1\70\17\0\1\71\2\0"+ + "\1\72\21\0\1\73\2\0\1\74\61\0\2\30\1\75"+ + "\1\0\1\76\1\0\1\76\1\77\1\0\1\30\2\0"+ + "\1\201\1\0\1\41\1\30\1\202\4\43\1\u01e7\25\43"+ + "\1\203\12\204\1\76\1\154\1\205\1\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\2\0\1\55"+ + "\1\0\1\56\2\0\1\57\1\0\1\60\4\0\1\61"+ + "\1\0\1\62\1\0\1\63\2\0\1\64\3\0\1\65"+ + "\2\0\1\66\4\0\1\67\3\0\1\70\17\0\1\71"+ + "\2\0\1\72\21\0\1\73\2\0\1\74\61\0\2\30"+ + "\1\75\1\0\1\76\1\0\1\76\1\77\1\0\1\30"+ + "\2\0\1\201\1\0\1\41\1\30\1\202\10\43\1\u033e"+ + "\21\43\1\203\12\204\1\76\1\154\1\205\1\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\2\0"+ + "\1\55\1\0\1\56\2\0\1\57\1\0\1\60\4\0"+ + "\1\61\1\0\1\62\1\0\1\63\2\0\1\64\3\0"+ + "\1\65\2\0\1\66\4\0\1\67\3\0\1\70\17\0"+ + "\1\71\2\0\1\72\21\0\1\73\2\0\1\74\61\0"+ + "\2\30\1\75\1\0\1\76\1\0\1\76\1\77\1\0"+ + "\1\30\2\0\1\201\1\0\1\41\1\30\1\202\12\43"+ + "\1\u0141\17\43\1\203\12\204\1\76\1\154\1\205\1\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\2\0\1\55\1\0\1\56\2\0\1\57\1\0\1\60"+ + "\4\0\1\61\1\0\1\62\1\0\1\63\2\0\1\64"+ + "\3\0\1\65\2\0\1\66\4\0\1\67\3\0\1\70"+ + "\17\0\1\71\2\0\1\72\21\0\1\73\2\0\1\74"+ + "\61\0\2\30\1\75\1\0\1\76\1\0\1\76\1\77"+ + "\1\0\1\30\2\0\1\201\1\0\1\41\1\30\1\202"+ + "\7\43\1\u033f\22\43\1\203\12\204\1\76\1\154\1\205"+ + "\1\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\2\0\1\55\1\0\1\56\2\0\1\57\1\0"+ + "\1\60\4\0\1\61\1\0\1\62\1\0\1\63\2\0"+ + "\1\64\3\0\1\65\2\0\1\66\4\0\1\67\3\0"+ + "\1\70\17\0\1\71\2\0\1\72\21\0\1\73\2\0"+ + "\1\74\61\0\2\30\1\75\1\0\1\76\1\0\1\76"+ + "\1\77\1\0\1\30\2\0\1\201\1\0\1\41\1\30"+ + "\1\202\3\43\1\u01ed\26\43\1\203\12\204\1\76\1\154"+ + "\1\205\1\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\2\0\1\55\1\0\1\56\2\0\1\57"+ + "\1\0\1\60\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\65\2\0\1\66\4\0\1\67"+ + "\3\0\1\70\17\0\1\71\2\0\1\72\21\0\1\73"+ + "\2\0\1\74\61\0\2\30\1\75\1\0\1\76\1\0"+ + "\1\76\1\77\1\0\1\30\2\0\1\201\1\0\1\41"+ + "\1\30\1\202\5\43\1\u0340\24\43\1\203\12\204\1\76"+ + "\1\154\1\205\1\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\11\371"+ + "\1\u0341\20\371\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\7\371\1\u0342\22\371\1\203\1\u0343\11\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\10\371\1\u0344"+ + "\4\371\1\u0345\5\371\1\u0346\6\371\1\203\12\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\3\371\1\u0347\26\371"+ + "\1\203\12\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\7\371\1\u0348\22\371\1\203\10\371\1\u0349\1\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\7\371\1\u034a\22\371"+ + "\1\203\12\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\7\371\1\u034b\22\371\1\203\12\371\1\0\3\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\213\0"+ + "\1\154\3\0\1\u016f\32\371\1\203\5\371\1\u034c\4\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\7\371\1\u034d"+ + "\22\371\1\203\10\371\1\u034e\1\371\1\0\3\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\213\0"+ + "\1\154\3\0\1\u016f\32\371\1\203\5\371\1\u034f\4\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\13\371\1\u0350"+ + "\16\371\1\203\12\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\7\371\1\u0351\22\371\1\203\12\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\26\371\1\u0352\3\371\1\203"+ + "\12\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\32\371"+ + "\1\203\7\371\1\u034f\2\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\15\371\1\u0353\14\371\1\203\12\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\32\371\1\203\10\371"+ + "\1\u0354\1\u0355\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\6\371\1\u0356\1\u0357\22\371\1\203\12\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\3\371\1\u0358\26\371\1\203"+ + "\12\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\32\371"+ + "\1\203\4\371\1\u034f\5\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\32\371\1\203\1\371\1\u0359\10\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\32\371\1\203\1\371"+ + "\1\u035a\10\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\2\0\1\55\1\0\1\56"+ + "\2\0\1\57\1\0\1\60\4\0\1\61\1\0\1\62"+ + "\1\0\1\63\2\0\1\64\3\0\1\65\2\0\1\66"+ + "\4\0\1\67\3\0\1\70\17\0\1\71\2\0\1\72"+ + "\21\0\1\73\2\0\1\74\61\0\2\30\1\75\1\0"+ + "\1\76\1\0\1\76\1\77\1\0\1\30\2\0\1\201"+ + "\1\0\1\41\1\30\1\202\13\43\1\u035b\16\43\1\203"+ + "\12\204\1\76\1\154\1\205\1\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\2\0\1\55\1\0"+ + "\1\56\2\0\1\57\1\0\1\60\4\0\1\61\1\0"+ + "\1\62\1\0\1\63\2\0\1\64\3\0\1\65\2\0"+ + "\1\66\4\0\1\67\3\0\1\70\17\0\1\71\2\0"+ + "\1\72\21\0\1\73\2\0\1\74\61\0\2\30\1\75"+ + "\1\0\1\76\1\0\1\76\1\77\1\0\1\30\2\0"+ + "\1\201\1\0\1\41\1\30\1\202\3\43\1\u035c\26\43"+ + "\1\203\12\204\1\76\1\154\1\205\1\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\2\0\1\55"+ + "\1\0\1\56\2\0\1\57\1\0\1\60\4\0\1\61"+ + "\1\0\1\62\1\0\1\63\2\0\1\64\3\0\1\65"+ + "\2\0\1\66\4\0\1\67\3\0\1\70\17\0\1\71"+ + "\2\0\1\72\21\0\1\73\2\0\1\74\61\0\2\30"+ + "\1\75\1\0\1\76\1\0\1\76\1\77\1\0\1\30"+ + "\2\0\1\201\1\0\1\41\1\30\1\202\4\43\1\u02d8"+ + "\25\43\1\203\12\204\1\76\1\154\1\205\1\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\220\0"+ + "\32\u035d\1\0\12\u035d\10\0\1\u035e\1\0\1\u035f\223\0"+ + "\1\u02f3\3\0\46\u02f3\1\u02f5\2\u02f3\1\u02f6\2\u02f3\1\u02f7"+ + "\5\0\2\u02f3\3\0\1\u02f3\214\0\1\u02f3\3\0\1\u0360"+ + "\32\u02f4\1\u0361\12\u02f4\1\u0362\2\u02f3\1\u02f6\2\u02f3\1\u02f7"+ + "\1\0\1\u0363\3\0\2\u02f3\3\0\1\u02f3\214\0\1\u02f5"+ + "\3\0\46\u02f5\1\0\2\u02f5\1\u0364\2\u02f5\1\u02f7\5\0"+ + "\2\u02f5\3\0\1\u02f5\221\0\4\u0365\2\0\1\u0365\15\0"+ + "\1\u0365\6\0\12\u0365\243\0\32\u0366\1\0\12\u0366\12\0"+ + "\1\u02f8\230\0\4\u0367\2\0\1\u0367\15\0\1\u0367\6\0"+ + "\12\u0367\1\u0368\24\0\1\55\1\0\1\56\2\0\1\245"+ + "\1\0\1\246\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\247\2\0\1\250\4\0\1\251"+ + "\3\0\1\252\17\0\1\71\2\0\1\253\21\0\1\254"+ + "\2\0\1\255\61\0\1\30\1\76\2\0\1\76\1\0"+ + "\2\76\1\0\1\76\2\0\1\u0369\1\u036a\2\30\1\u0369"+ + "\32\u036b\13\u036c\1\76\1\u036c\1\u0369\1\u036c\1\0\1\u036c"+ + "\1\0\3\u036c\3\0\1\u036c\3\0\2\u036c\213\0\1\u036d"+ + "\3\0\1\u036d\32\u036e\1\u036d\12\u036e\1\u036f\2\u036d\1\u0370"+ + "\2\u036d\1\u0371\3\0\1\u0372\1\0\2\u036d\3\0\1\u036d"+ + "\214\0\1\154\3\0\1\u016f\4\371\1\u0373\25\371\1\203"+ + "\12\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\1\u0374"+ + "\31\371\1\203\12\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\10\371\1\u0375\21\371\1\203\12\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\13\371\1\u0376\16\371\1\203"+ + "\12\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\17\371"+ + "\1\u0377\12\371\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\15\371\1\u0378\14\371\1\203\12\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\12\371\1\u0379\17\371"+ + "\1\203\12\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\4\371\1\u020d\25\371\1\203\12\371\1\0\3\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\213\0"+ + "\1\154\3\0\1\u016f\10\371\1\u037a\21\371\1\203\12\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\12\371\1\u0174"+ + "\17\371\1\203\12\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\7\371\1\u037b\22\371\1\203\12\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\3\371\1\u0213\26\371\1\203"+ + "\12\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\5\371"+ + "\1\u037c\24\371\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\13\371\1\u037d\16\371\1\203\12\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\3\371\1\u037e\26\371"+ + "\1\203\12\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\4\371\1\u0306\25\371\1\203\12\371\1\0\3\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\2\0"+ + "\1\55\1\0\1\56\2\0\1\100\1\0\1\101\4\0"+ + "\1\61\1\0\1\62\1\0\1\63\2\0\1\64\3\0"+ + "\1\102\2\0\1\103\4\0\1\104\3\0\1\105\17\0"+ + "\1\71\2\0\1\106\21\0\1\107\2\0\1\110\61\0"+ + "\1\30\2\31\2\0\2\111\1\112\1\0\1\31\2\0"+ + "\1\212\1\0\1\41\1\30\1\u01a5\32\43\1\203\12\u037f"+ + "\1\u01f9\1\154\1\215\1\154\1\0\1\212\1\156\1\u01d1"+ + "\1\u01d2\1\u01d3\2\0\1\111\1\154\3\0\2\154\2\0"+ + "\1\55\1\0\1\56\2\0\1\100\1\0\1\101\4\0"+ + "\1\61\1\0\1\62\1\0\1\63\2\0\1\64\3\0"+ + "\1\102\2\0\1\103\4\0\1\104\3\0\1\105\17\0"+ + "\1\71\2\0\1\106\21\0\1\107\2\0\1\110\61\0"+ + "\1\30\2\31\2\0\2\111\1\112\1\0\1\31\2\0"+ + "\1\212\1\0\1\41\1\30\1\u01a5\32\43\1\203\12\u030b"+ + "\1\u01f9\1\154\1\215\1\154\1\0\1\212\1\156\1\u01d1"+ + "\1\u01d2\1\u01d3\2\0\1\111\1\154\3\0\2\154\2\0"+ + "\1\55\1\0\1\56\2\0\1\100\1\0\1\101\4\0"+ + "\1\61\1\0\1\62\1\0\1\63\2\0\1\64\3\0"+ + "\1\102\2\0\1\103\4\0\1\104\3\0\1\105\17\0"+ + "\1\71\2\0\1\106\21\0\1\107\2\0\1\110\61\0"+ + "\1\30\2\31\2\0\2\111\1\112\1\0\1\31\2\0"+ + "\1\212\1\0\1\41\1\30\1\u01a5\32\43\1\203\2\u030b"+ + "\1\u037f\1\u030b\1\u0380\2\u037f\2\u030b\1\u037f\1\u01f9\1\154"+ + "\1\215\1\154\1\0\1\212\1\156\1\u01d1\1\u01d2\1\u01d3"+ + "\2\0\1\111\1\154\3\0\2\154\265\0\1\u021d\242\0"+ + "\4\u0381\2\0\1\u0381\15\0\1\u0381\6\0\12\u0381\1\u0310"+ + "\242\0\4\u0382\2\0\1\u0382\15\0\1\u0382\6\0\12\u0382"+ + "\1\u0383\242\0\4\u0384\2\0\1\u0384\15\0\1\u0384\6\0"+ + "\12\u0384\1\u0385\12\0\1\u01ad\226\0\1\u0224\4\u0384\2\0"+ + "\1\u0384\15\0\1\u0384\6\0\12\u0386\1\u0385\12\0\1\u01ad"+ + "\226\0\1\u0224\4\u0384\2\0\1\u0384\15\0\1\u0384\6\0"+ + "\12\u0387\1\u0385\12\0\1\u01ad\226\0\1\u0224\4\u0384\2\0"+ + "\1\u0384\15\0\1\u0384\6\0\2\u0387\1\u0386\1\u0387\1\u0388"+ + "\2\u0386\2\u0387\1\u0386\1\u0385\12\0\1\u01ad\227\0\4\u0389"+ + "\2\0\1\u0389\15\0\1\u0389\6\0\12\u0389\1\u029d\12\0"+ + "\1\u01ad\226\0\1\u0224\4\u0389\2\0\1\u0389\15\0\1\u0389"+ + "\6\0\12\u0389\1\u029d\12\0\1\u01ad\274\0\1\u0223\12\0"+ + "\1\u01ad\262\0\1\u038a\1\u038b\5\u038a\1\u038c\1\u038b\1\u038a"+ + "\242\0\1\u0318\307\0\1\u0318\33\0\2\u0319\1\0\2\u0319"+ + "\2\0\2\u0319\244\0\4\u0228\2\0\1\u0228\15\0\1\u0228"+ + "\6\0\12\u0228\243\0\4\u0229\2\0\1\u0229\15\0\1\u0229"+ + "\6\0\12\u0229\243\0\4\u022a\2\0\1\u022a\15\0\1\u022a"+ + "\6\0\12\u022a\242\0\1\u0136\4\323\1\u01c1\25\323\1\u0137"+ + "\12\323\242\0\1\u0136\17\323\1\u038d\12\323\1\u0137\12\323"+ + "\242\0\1\u0136\4\323\1\u038e\25\323\1\u0137\12\323\242\0"+ + "\1\u0136\25\323\1\u038f\4\323\1\u0137\12\323\242\0\1\u0136"+ + "\5\323\1\u0390\24\323\1\u0137\12\323\242\0\1\u0136\1\323"+ + "\1\u0391\30\323\1\u0137\12\323\242\0\1\u0136\4\323\1\u0392"+ + "\25\323\1\u0137\12\323\242\0\1\u0136\15\323\1\u0393\14\323"+ + "\1\u0137\12\323\242\0\1\u0136\17\323\1\u02b9\12\323\1\u0137"+ + "\12\323\242\0\1\u0136\3\323\1\u0394\26\323\1\u0137\12\323"+ + "\242\0\1\u0136\25\323\1\u0395\4\323\1\u0137\12\323\242\0"+ + "\1\u0136\17\323\1\u038f\12\323\1\u0137\12\323\242\0\1\u0136"+ + "\20\323\1\u0396\11\323\1\u0137\12\323\242\0\1\u0136\24\323"+ + "\1\u038f\5\323\1\u0137\12\323\242\0\1\u0136\5\323\1\u0397"+ + "\24\323\1\u0137\12\323\242\0\1\u0136\11\323\1\u0398\20\323"+ + "\1\u0137\12\323\242\0\1\u0136\5\323\1\u0250\24\323\1\u0137"+ + "\12\323\242\0\1\u0136\13\323\1\u0399\16\323\1\u0137\12\323"+ + "\242\0\1\u0136\3\323\1\u0241\26\323\1\u0137\12\323\243\0"+ + "\1\323\1\u039a\3\323\1\u039b\1\u039c\1\u039d\1\323\1\u039e"+ + "\1\u039f\1\u03a0\1\u03a1\1\u03a2\1\u03a3\1\323\1\u03a4\1\u03a5"+ + "\1\u03a6\2\323\1\u03a7\1\u03a8\1\u03a9\1\323\1\u03aa\1\u0137"+ + "\1\u03ab\2\323\1\u03ac\1\323\1\u03ad\1\u03ae\3\323\242\0"+ + "\1\u0136\10\323\1\u03af\21\323\1\u0137\12\323\242\0\1\u0136"+ + "\25\323\1\u03b0\4\323\1\u0137\12\323\242\0\1\u0136\20\323"+ + "\1\u03b1\11\323\1\u0137\12\323\242\0\1\u0136\7\323\1\u02b9"+ + "\22\323\1\u0137\12\323\276\0\12\u03b2\7\0\1\u0228\1\u0229"+ + "\1\u022a\13\0\1\55\1\0\1\56\2\0\1\57\1\0"+ + "\1\60\4\0\1\61\1\0\1\62\1\0\1\63\2\0"+ + "\1\64\3\0\1\65\2\0\1\66\4\0\1\67\3\0"+ + "\1\70\17\0\1\71\2\0\1\72\21\0\1\73\2\0"+ + "\1\74\61\0\2\30\1\75\1\0\1\76\1\0\1\76"+ + "\1\77\1\0\1\30\2\0\1\201\1\0\1\41\1\30"+ + "\1\202\20\43\1\u03b3\11\43\1\203\12\204\1\76\1\154"+ + "\1\205\1\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\2\0\1\55\1\0\1\56\2\0\1\57"+ + "\1\0\1\60\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\65\2\0\1\66\4\0\1\67"+ + "\3\0\1\70\17\0\1\71\2\0\1\72\21\0\1\73"+ + "\2\0\1\74\61\0\2\30\1\75\1\0\1\76\1\0"+ + "\1\76\1\77\1\0\1\30\2\0\1\201\1\0\1\41"+ + "\1\30\1\202\1\43\1\u03b4\30\43\1\203\12\204\1\76"+ + "\1\154\1\205\1\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\2\0\1\55\1\0\1\56\2\0"+ + "\1\57\1\0\1\60\4\0\1\61\1\0\1\62\1\0"+ + "\1\63\2\0\1\64\3\0\1\65\2\0\1\66\4\0"+ + "\1\67\3\0\1\70\17\0\1\71\2\0\1\72\21\0"+ + "\1\73\2\0\1\74\61\0\2\30\1\75\1\0\1\76"+ + "\1\0\1\76\1\77\1\0\1\30\2\0\1\201\1\0"+ + "\1\41\1\30\1\202\13\43\1\u014d\16\43\1\203\12\204"+ + "\1\76\1\154\1\205\1\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\2\0\1\55\1\0\1\56"+ + "\2\0\1\57\1\0\1\60\4\0\1\61\1\0\1\62"+ + "\1\0\1\63\2\0\1\64\3\0\1\65\2\0\1\66"+ + "\4\0\1\67\3\0\1\70\17\0\1\71\2\0\1\72"+ + "\21\0\1\73\2\0\1\74\61\0\2\30\1\75\1\0"+ + "\1\76\1\0\1\76\1\77\1\0\1\30\2\0\1\201"+ + "\1\0\1\41\1\30\1\202\2\43\1\u01ed\27\43\1\203"+ + "\12\204\1\76\1\154\1\205\1\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\2\0\1\55\1\0"+ + "\1\56\2\0\1\57\1\0\1\60\4\0\1\61\1\0"+ + "\1\62\1\0\1\63\2\0\1\64\3\0\1\65\2\0"+ + "\1\66\4\0\1\67\3\0\1\70\17\0\1\71\2\0"+ + "\1\72\21\0\1\73\2\0\1\74\61\0\2\30\1\75"+ + "\1\0\1\76\1\0\1\76\1\77\1\0\1\30\2\0"+ + "\1\201\1\0\1\41\1\30\1\202\5\43\1\u02d4\24\43"+ + "\1\203\12\204\1\76\1\154\1\205\1\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\2\0\1\55"+ + "\1\0\1\56\2\0\1\57\1\0\1\60\4\0\1\61"+ + "\1\0\1\62\1\0\1\63\2\0\1\64\3\0\1\65"+ + "\2\0\1\66\4\0\1\67\3\0\1\70\17\0\1\71"+ + "\2\0\1\72\21\0\1\73\2\0\1\74\61\0\2\30"+ + "\1\75\1\0\1\76\1\0\1\76\1\77\1\0\1\30"+ + "\2\0\1\201\1\0\1\41\1\30\1\202\4\43\1\u03b5"+ + "\25\43\1\203\12\204\1\76\1\154\1\205\1\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\2\0"+ + "\1\55\1\0\1\56\2\0\1\57\1\0\1\60\4\0"+ + "\1\61\1\0\1\62\1\0\1\63\2\0\1\64\3\0"+ + "\1\65\2\0\1\66\4\0\1\67\3\0\1\70\17\0"+ + "\1\71\2\0\1\72\21\0\1\73\2\0\1\74\61\0"+ + "\2\30\1\75\1\0\1\76\1\0\1\76\1\77\1\0"+ + "\1\30\2\0\1\201\1\0\1\41\1\30\1\202\3\43"+ + "\1\u03b6\26\43\1\203\12\204\1\76\1\154\1\205\1\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\2\0\1\55\1\0\1\56\2\0\1\57\1\0\1\60"+ + "\4\0\1\61\1\0\1\62\1\0\1\63\2\0\1\64"+ + "\3\0\1\65\2\0\1\66\4\0\1\67\3\0\1\70"+ + "\17\0\1\71\2\0\1\72\21\0\1\73\2\0\1\74"+ + "\61\0\2\30\1\75\1\0\1\76\1\0\1\76\1\77"+ + "\1\0\1\30\2\0\1\201\1\0\1\41\1\30\1\202"+ + "\1\43\1\u01ed\30\43\1\203\12\204\1\76\1\154\1\205"+ + "\1\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\2\0\1\55\1\0\1\56\2\0\1\57\1\0"+ + "\1\60\4\0\1\61\1\0\1\62\1\0\1\63\2\0"+ + "\1\64\3\0\1\65\2\0\1\66\4\0\1\67\3\0"+ + "\1\70\17\0\1\71\2\0\1\72\21\0\1\73\2\0"+ + "\1\74\61\0\2\30\1\75\1\0\1\76\1\0\1\76"+ + "\1\77\1\0\1\30\2\0\1\201\1\0\1\41\1\30"+ + "\1\202\4\43\1\u03b7\25\43\1\203\12\204\1\76\1\154"+ + "\1\205\1\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\2\0\1\55\1\0\1\56\2\0\1\57"+ + "\1\0\1\60\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\65\2\0\1\66\4\0\1\67"+ + "\3\0\1\70\17\0\1\71\2\0\1\72\21\0\1\73"+ + "\2\0\1\74\61\0\2\30\1\75\1\0\1\76\1\0"+ + "\1\76\1\77\1\0\1\30\2\0\1\201\1\0\1\41"+ + "\1\30\1\202\11\43\1\u03b8\20\43\1\203\12\204\1\76"+ + "\1\154\1\205\1\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\1\371"+ + "\1\u03b9\30\371\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\24\371\1\u03ba\5\371\1\203\12\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\1\371\1\u03bb\30\371"+ + "\1\203\12\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\14\371\1\u03bc\15\371\1\203\12\371\1\0\3\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\213\0"+ + "\1\154\3\0\1\u016f\1\371\1\u03bd\30\371\1\203\12\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\1\371\1\u03be"+ + "\30\371\1\203\12\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\1\371\1\u03bf\30\371\1\203\12\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\24\371\1\u03c0\5\371\1\203"+ + "\12\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\1\u03c1"+ + "\31\371\1\203\12\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\24\371\1\u03c2\5\371\1\203\12\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\24\371\1\u03c3\5\371\1\203"+ + "\12\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\27\371"+ + "\1\u03c4\2\371\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\24\371\1\u03c5\5\371\1\203\12\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\1\u0207\31\371\1\203"+ + "\12\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\24\371"+ + "\1\u03bf\5\371\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\20\371\1\u03c6\11\371\1\203\12\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\24\371\1\u03c7\5\371"+ + "\1\203\12\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\1\371\1\u03c8\30\371\1\203\12\371\1\0\3\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\213\0"+ + "\1\154\3\0\1\u016f\4\371\1\u03c9\25\371\1\203\12\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\1\u03ca\31\371"+ + "\1\203\12\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\21\371\1\u03cb\10\371\1\203\12\371\1\0\3\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\213\0"+ + "\1\154\3\0\1\u016f\4\371\1\u03cc\25\371\1\203\12\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\24\371\1\u03cd"+ + "\5\371\1\203\12\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\32\371\1\203\1\371\1\u03ce\10\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\1\u03cf\31\371\1\203\12\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\1\u03d0\31\371"+ + "\1\203\12\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\2\0\1\55\1\0\1\56"+ + "\2\0\1\57\1\0\1\60\4\0\1\61\1\0\1\62"+ + "\1\0\1\63\2\0\1\64\3\0\1\65\2\0\1\66"+ + "\4\0\1\67\3\0\1\70\17\0\1\71\2\0\1\72"+ + "\21\0\1\73\2\0\1\74\61\0\2\30\1\75\1\0"+ + "\1\76\1\0\1\76\1\77\1\0\1\30\2\0\1\201"+ + "\1\0\1\41\1\30\1\202\7\43\1\u01ed\22\43\1\203"+ + "\12\204\1\76\1\154\1\205\1\154\1\0\1\154\1\156"; private static final String ZZ_TRANS_PACKED_1 = - "\3\270\1\u059c\26\270\1\u010a\12\270\237\0\1\u0109\1\u059d"+ - "\31\270\1\u010a\12\270\237\0\1\u0109\26\270\1\u059e\3\270"+ - "\1\u010a\12\270\237\0\1\u0121\7\324\1\u059f\22\324\1\164"+ - "\12\324\1\0\3\161\1\0\2\161\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\212\0\1\u0121\1\u05a0\31\324\1\164"+ - "\12\324\1\0\3\161\1\0\2\161\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\212\0\1\u0121\32\324\1\164\1\u0338"+ - "\11\324\1\0\3\161\1\0\2\161\1\162\3\161\3\0"+ - "\1\161\4\0\2\161\212\0\1\u0121\24\324\1\u05a1\5\324"+ - "\1\164\12\324\1\0\3\161\1\0\2\161\1\162\3\161"+ - "\3\0\1\161\4\0\2\161\212\0\1\u0121\1\324\1\u05a2"+ - "\30\324\1\164\12\324\1\0\3\161\1\0\2\161\1\162"+ - "\3\161\3\0\1\161\4\0\2\161\212\0\1\u0121\32\324"+ - "\1\164\2\324\1\u012e\7\324\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\213\0\4\u05a3"+ - "\2\0\1\u05a3\15\0\1\u05a3\6\0\12\u05a3\1\u051d\237\0"+ - "\4\u05a4\2\0\1\u05a4\15\0\1\u05a4\6\0\12\u05a4\1\u05a5"+ - "\237\0\4\u05a6\2\0\1\u05a6\15\0\1\u05a6\6\0\1\u05a7"+ - "\2\u05a8\1\u05a7\5\u05a8\1\u05a9\14\0\1\u035e\223\0\4\u05aa"+ - "\2\0\1\u05aa\15\0\1\u05aa\6\0\12\u05aa\1\u0562\13\0"+ - "\1\u035e\223\0\4\u05a6\2\0\1\u05a6\15\0\1\u05a6\6\0"+ - "\1\u05a7\2\u05a8\1\u05a7\5\u05a8\1\u05a9\237\0\1\u03c5\4\u05aa"+ - "\2\0\1\u05aa\15\0\1\u05aa\6\0\12\u05ab\1\u0562\13\0"+ - "\1\u035e\222\0\1\u03c5\4\u05aa\2\0\1\u05aa\15\0\1\u05aa"+ - "\6\0\12\u05aa\1\u0562\13\0\1\u035e\222\0\1\u03c5\4\u05aa"+ - "\2\0\1\u05aa\15\0\1\u05aa\6\0\2\u05ab\1\u05aa\2\u05ab"+ - "\2\u05aa\1\u05ab\1\u05aa\1\u05ab\1\u0562\13\0\1\u035e\270\0"+ - "\1\u04e3\13\0\1\u035e\256\0\12\u0568\14\0\1\u035e\256\0"+ - "\12\u05ac\14\0\1\u035e\256\0\1\u0568\1\u05ad\1\u05ac\2\u0568"+ - "\2\u05ac\1\u0568\1\u05ac\1\u0568\14\0\1\u035e\270\0\1\u04ee"+ - "\237\0\4\u05ae\2\0\1\u05ae\15\0\1\u05ae\6\0\12\u05ae"+ - "\1\u056c\237\0\4\u05af\2\0\1\u05af\15\0\1\u05af\6\0"+ - "\12\u05af\1\u05b0\237\0\4\u05b1\2\0\1\u05b1\15\0\1\u05b1"+ - "\6\0\12\u05b1\1\u05b2\13\0\1\u0302\222\0\1\u036b\4\u05b1"+ - "\2\0\1\u05b1\15\0\1\u05b1\6\0\12\u05b3\1\u05b2\13\0"+ - "\1\u0302\222\0\1\u036b\4\u05b1\2\0\1\u05b1\15\0\1\u05b1"+ - "\6\0\12\u05b4\1\u05b2\13\0\1\u0302\222\0\1\u036b\4\u05b1"+ - "\2\0\1\u05b1\15\0\1\u05b1\6\0\1\u05b3\1\u05b5\1\u05b4"+ - "\2\u05b3\2\u05b4\1\u05b3\1\u05b4\1\u05b3\1\u05b2\13\0\1\u0302"+ - "\223\0\4\u05b6\2\0\1\u05b6\15\0\1\u05b6\6\0\12\u05b6"+ - "\1\u052b\13\0\1\u0302\222\0\1\u036b\4\u05b6\2\0\1\u05b6"+ - "\15\0\1\u05b6\6\0\12\u05b6\1\u052b\13\0\1\u0302\304\0"+ - "\1\u0302\256\0\2\u0573\1\0\2\u0573\2\0\1\u0573\1\0"+ - "\1\u0573\14\0\1\u0302\222\0\1\u036f\1\u0303\1\u05b7\30\u0303"+ - "\1\u0370\12\u0303\237\0\1\u036f\24\u0303\1\u05b8\5\u0303\1\u0370"+ - "\12\u0303\237\0\1\u036f\24\u0303\1\u05b9\5\u0303\1\u0370\12\u0303"+ - "\237\0\1\u036f\1\u0303\1\u05ba\30\u0303\1\u0370\12\u0303\237\0"+ - "\1\u036f\14\u0303\1\u05bb\15\u0303\1\u0370\12\u0303\237\0\1\u036f"+ - "\1\u0303\1\u05bc\30\u0303\1\u0370\12\u0303\237\0\1\u036f\1\u0303"+ - "\1\u05bd\30\u0303\1\u0370\12\u0303\237\0\1\u036f\1\u0303\1\u05be"+ - "\30\u0303\1\u0370\12\u0303\237\0\1\u036f\21\u0303\1\u05bf\10\u0303"+ - "\1\u0370\12\u0303\237\0\1\u036f\24\u0303\1\u05c0\5\u0303\1\u0370"+ - "\12\u0303\237\0\1\u036f\24\u0303\1\u05c1\5\u0303\1\u0370\12\u0303"+ - "\237\0\1\u036f\24\u0303\1\u05c2\5\u0303\1\u0370\12\u0303\237\0"+ - "\1\u036f\1\u04b0\31\u0303\1\u0370\12\u0303\237\0\1\u036f\24\u0303"+ - "\1\u05be\5\u0303\1\u0370\12\u0303\237\0\1\u036f\24\u0303\1\u05c3"+ - "\5\u0303\1\u0370\12\u0303\237\0\1\u036f\1\u0303\1\u05c4\30\u0303"+ - "\1\u0370\12\u0303\237\0\1\u036f\31\u0303\1\u05c5\1\u0370\12\u0303"+ - "\237\0\1\u036f\24\u0303\1\u05c6\5\u0303\1\u0370\12\u0303\237\0"+ - "\1\u036f\1\u0303\1\u05c7\30\u0303\1\u0370\12\u0303\237\0\1\u036f"+ - "\1\u05c8\31\u0303\1\u0370\12\u0303\237\0\1\u036f\21\u0303\1\u05c9"+ - "\10\u0303\1\u0370\12\u0303\237\0\1\u036f\4\u0303\1\u05ca\25\u0303"+ - "\1\u0370\12\u0303\237\0\1\u036f\24\u0303\1\u05cb\5\u0303\1\u0370"+ - "\12\u0303\237\0\1\u036f\24\u0303\1\u05cc\5\u0303\1\u0370\12\u0303"+ - "\237\0\1\u036f\4\u0303\1\u05cd\25\u0303\1\u0370\12\u0303\237\0"+ - "\1\u036f\21\u0303\1\u05ce\10\u0303\1\u0370\12\u0303\237\0\1\u036f"+ - "\24\u0303\1\u05cf\5\u0303\1\u0370\12\u0303\237\0\1\u036f\32\u0303"+ - "\1\u0370\1\u05d0\11\u0303\237\0\1\u036f\32\u0303\1\u0370\7\u0303"+ - "\1\u05d1\2\u0303\237\0\1\u036f\1\u05d2\31\u0303\1\u0370\12\u0303"+ - "\237\0\1\u036f\1\u05d3\31\u0303\1\u0370\12\u0303\305\0\1\u04fd"+ - "\237\0\4\u037d\2\0\1\u037d\15\0\1\u037d\6\0\12\u037d"+ - "\14\0\1\u0146\222\0\1\u0109\32\270\1\u010a\11\270\1\u05d4"+ - "\237\0\1\u0109\26\270\1\u018f\3\270\1\u010a\12\270\237\0"+ - "\1\u0109\32\270\1\u010a\7\270\1\u05d5\2\270\237\0\1\u0109"+ - "\32\270\1\u010a\11\270\1\u0153\237\0\1\u0109\3\270\1\u05d6"+ - "\26\270\1\u010a\12\270\237\0\1\u0109\32\270\1\u010a\4\270"+ - "\1\u05d7\5\270\237\0\1\u0109\16\270\1\u05d8\13\270\1\u010a"+ - "\12\270\237\0\1\u0109\26\270\1\u05d9\3\270\1\u010a\12\270"+ - "\237\0\1\u0109\32\270\1\u010a\7\270\1\u04cb\2\270\237\0"+ - "\1\u0121\32\324\1\164\11\324\1\u05da\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\4\0\2\161\212\0"+ - "\1\u0121\4\324\1\u0127\25\324\1\164\12\324\1\0\3\161"+ - "\1\0\2\161\1\162\3\161\3\0\1\161\4\0\2\161"+ - "\212\0\1\u0121\24\324\1\350\5\324\1\164\12\324\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\212\0\1\u0121\32\324\1\164\6\324\1\350\3\324"+ - "\1\0\3\161\1\0\2\161\1\162\3\161\3\0\1\161"+ - "\4\0\2\161\260\0\1\u051d\237\0\4\u05db\2\0\1\u05db"+ - "\15\0\1\u05db\6\0\12\u05db\1\u05a5\237\0\4\u05dc\2\0"+ - "\1\u05dc\15\0\1\u05dc\6\0\12\u05dc\1\u05dd\237\0\4\u05de"+ - "\2\0\1\u05de\15\0\1\u05de\6\0\12\u05de\1\u05df\13\0"+ - "\1\u035e\222\0\1\u03c5\4\u05de\2\0\1\u05de\15\0\1\u05de"+ - "\6\0\12\u05e0\1\u05df\13\0\1\u035e\222\0\1\u03c5\4\u05de"+ - "\2\0\1\u05de\15\0\1\u05de\6\0\12\u05e1\1\u05df\13\0"+ - "\1\u035e\222\0\1\u03c5\4\u05de\2\0\1\u05de\15\0\1\u05de"+ - "\6\0\1\u05e0\1\u05e2\1\u05e1\2\u05e0\2\u05e1\1\u05e0\1\u05e1"+ - "\1\u05e0\1\u05df\13\0\1\u035e\223\0\4\u05e3\2\0\1\u05e3"+ - "\15\0\1\u05e3\6\0\12\u05e3\1\u0562\13\0\1\u035e\222\0"+ - "\1\u03c5\4\u05e3\2\0\1\u05e3\15\0\1\u05e3\6\0\12\u05e3"+ - "\1\u0562\13\0\1\u035e\304\0\1\u035e\256\0\2\u05ac\1\0"+ - "\2\u05ac\2\0\1\u05ac\1\0\1\u05ac\14\0\1\u035e\223\0"+ - "\4\u05e4\2\0\1\u05e4\15\0\1\u05e4\6\0\12\u05e4\1\u056c"+ - "\237\0\4\u05e5\2\0\1\u05e5\15\0\1\u05e5\6\0\12\u05e5"+ - "\1\u05e6\237\0\4\u05e7\2\0\1\u05e7\15\0\1\u05e7\6\0"+ - "\1\u05e8\2\u05e9\1\u05e8\5\u05e9\1\u05ea\14\0\1\u0302\223\0"+ - "\4\u05eb\2\0\1\u05eb\15\0\1\u05eb\6\0\12\u05eb\1\u05b2"+ - "\13\0\1\u0302\223\0\4\u05e7\2\0\1\u05e7\15\0\1\u05e7"+ - "\6\0\1\u05e8\2\u05e9\1\u05e8\5\u05e9\1\u05ea\237\0\1\u036b"+ - "\4\u05eb\2\0\1\u05eb\15\0\1\u05eb\6\0\12\u05ec\1\u05b2"+ - "\13\0\1\u0302\222\0\1\u036b\4\u05eb\2\0\1\u05eb\15\0"+ - "\1\u05eb\6\0\12\u05eb\1\u05b2\13\0\1\u0302\222\0\1\u036b"+ - "\4\u05eb\2\0\1\u05eb\15\0\1\u05eb\6\0\2\u05ec\1\u05eb"+ - "\2\u05ec\2\u05eb\1\u05ec\1\u05eb\1\u05ec\1\u05b2\13\0\1\u0302"+ - "\270\0\1\u052b\13\0\1\u0302\222\0\1\u036f\25\u0303\1\u05ed"+ - "\4\u0303\1\u0370\12\u0303\237\0\1\u036f\1\u05ee\31\u0303\1\u0370"+ - "\12\u0303\237\0\1\u036f\15\u0303\1\u05ef\14\u0303\1\u0370\12\u0303"+ - "\237\0\1\u036f\21\u0303\1\u05f0\10\u0303\1\u0370\12\u0303\237\0"+ - "\1\u036f\16\u0303\1\u05f1\4\u0303\1\u05f2\6\u0303\1\u0370\12\u0303"+ - "\237\0\1\u036f\4\u0303\1\u05f3\25\u0303\1\u0370\12\u0303\237\0"+ - "\1\u036f\32\u0303\1\u0370\11\u0303\1\u05f4\237\0\1\u036f\4\u0303"+ - "\1\u05f5\25\u0303\1\u0370\12\u0303\237\0\1\u036f\32\u0303\1\u0370"+ - "\11\u0303\1\u05f6\237\0\1\u036f\24\u0303\1\u05f7\5\u0303\1\u0370"+ - "\12\u0303\237\0\1\u036f\1\u05f8\1\u05f9\1\u0303\1\u05fa\20\u0303"+ - "\1\u05fb\5\u0303\1\u0370\5\u0303\1\u05fc\4\u0303\237\0\1\u036f"+ - "\16\u0303\1\u05fd\13\u0303\1\u0370\12\u0303\237\0\1\u036f\11\u0303"+ - "\1\u05fe\13\u0303\1\u05ff\4\u0303\1\u0370\12\u0303\237\0\1\u036f"+ - "\32\u0303\1\u0370\11\u0303\1\u0600\237\0\1\u036f\23\u0303\1\u0601"+ - "\6\u0303\1\u0370\12\u0303\237\0\1\u036f\31\u0303\1\u0602\1\u0370"+ - "\12\u0303\237\0\1\u036f\26\u0303\1\u0603\3\u0303\1\u0370\12\u0303"+ - "\237\0\1\u036f\11\u0303\1\u0604\20\u0303\1\u0370\12\u0303\237\0"+ - "\1\u036f\32\u0303\1\u0370\3\u0303\1\u0605\6\u0303\237\0\1\u036f"+ - "\5\u0303\1\u0606\24\u0303\1\u0370\12\u0303\237\0\1\u036f\10\u0303"+ - "\1\u0607\21\u0303\1\u0370\12\u0303\237\0\1\u036f\3\u0303\1\u0608"+ - "\26\u0303\1\u0370\12\u0303\237\0\1\u036f\21\u0303\1\u0609\6\u0303"+ - "\1\u060a\1\u0303\1\u0370\12\u0303\237\0\1\u036f\12\u0303\1\u060b"+ - "\17\u0303\1\u0370\12\u0303\237\0\1\u036f\32\u0303\1\u0370\1\u0303"+ - "\1\u060c\10\u0303\237\0\1\u036f\24\u0303\1\u060d\5\u0303\1\u0370"+ - "\12\u0303\237\0\1\u036f\24\u0303\1\u060e\5\u0303\1\u0370\12\u0303"+ - "\237\0\1\u036f\32\u0303\1\u0370\4\u0303\1\u060f\5\u0303\237\0"+ - "\1\u036f\5\u0303\1\u0610\23\u0303\1\u0611\1\u0370\12\u0303\237\0"+ - "\1\u0109\7\270\1\u0612\22\270\1\u010a\12\270\237\0\1\u0109"+ - "\1\u0613\31\270\1\u010a\12\270\237\0\1\u0109\32\270\1\u010a"+ - "\1\u0400\11\270\237\0\1\u0109\24\270\1\u0614\5\270\1\u010a"+ - "\12\270\237\0\1\u0109\1\270\1\u0615\30\270\1\u010a\12\270"+ - "\237\0\1\u0109\32\270\1\u010a\2\270\1\u0196\7\270\237\0"+ - "\1\u0121\1\u0616\31\324\1\164\12\324\1\0\3\161\1\0"+ - "\2\161\1\162\3\161\3\0\1\161\4\0\2\161\213\0"+ - "\4\u0617\2\0\1\u0617\15\0\1\u0617\6\0\12\u0617\1\u05a5"+ - "\237\0\4\u0618\2\0\1\u0618\15\0\1\u0618\6\0\12\u0618"+ - "\1\u0619\237\0\4\u061a\2\0\1\u061a\15\0\1\u061a\6\0"+ - "\1\u061b\2\u061c\1\u061b\5\u061c\1\u061d\14\0\1\u035e\223\0"+ - "\4\u061e\2\0\1\u061e\15\0\1\u061e\6\0\12\u061e\1\u05df"+ - "\13\0\1\u035e\223\0\4\u061a\2\0\1\u061a\15\0\1\u061a"+ - "\6\0\1\u061b\2\u061c\1\u061b\5\u061c\1\u061d\237\0\1\u03c5"+ - "\4\u061e\2\0\1\u061e\15\0\1\u061e\6\0\12\u061f\1\u05df"+ - "\13\0\1\u035e\222\0\1\u03c5\4\u061e\2\0\1\u061e\15\0"+ - "\1\u061e\6\0\12\u061e\1\u05df\13\0\1\u035e\222\0\1\u03c5"+ - "\4\u061e\2\0\1\u061e\15\0\1\u061e\6\0\2\u061f\1\u061e"+ - "\2\u061f\2\u061e\1\u061f\1\u061e\1\u061f\1\u05df\13\0\1\u035e"+ - "\270\0\1\u0562\13\0\1\u035e\270\0\1\u056c\237\0\4\u0620"+ - "\2\0\1\u0620\15\0\1\u0620\6\0\12\u0620\1\u05e6\237\0"+ - "\4\u0621\2\0\1\u0621\15\0\1\u0621\6\0\1\u0622\2\u0623"+ - "\1\u0622\5\u0623\1\u0624\1\u0625\237\0\4\u0626\2\0\1\u0626"+ - "\15\0\1\u0626\6\0\12\u0626\1\u0627\13\0\1\u0302\222\0"+ - "\1\u036b\4\u0626\2\0\1\u0626\15\0\1\u0626\6\0\12\u0628"+ - "\1\u0627\13\0\1\u0302\222\0\1\u036b\4\u0626\2\0\1\u0626"+ - "\15\0\1\u0626\6\0\12\u0629\1\u0627\13\0\1\u0302\222\0"+ - "\1\u036b\4\u0626\2\0\1\u0626\15\0\1\u0626\6\0\1\u0628"+ - "\1\u062a\1\u0629\2\u0628\2\u0629\1\u0628\1\u0629\1\u0628\1\u0627"+ - "\13\0\1\u0302\223\0\4\u062b\2\0\1\u062b\15\0\1\u062b"+ - "\6\0\12\u062b\1\u05b2\13\0\1\u0302\222\0\1\u036b\4\u062b"+ - "\2\0\1\u062b\15\0\1\u062b\6\0\12\u062b\1\u05b2\13\0"+ - "\1\u0302\222\0\1\u036f\1\u0303\1\u062c\30\u0303\1\u0370\12\u0303"+ - "\237\0\1\u036f\32\u0303\1\u0370\1\u062d\11\u0303\237\0\1\u036f"+ - "\6\u0303\1\u062e\23\u0303\1\u0370\12\u0303\237\0\1\u036f\32\u0303"+ - "\1\u0370\7\u0303\1\u062f\2\u0303\237\0\1\u036f\32\u0303\1\u0370"+ - "\10\u0303\1\u04b5\1\u0303\237\0\1\u036f\32\u0303\1\u0370\5\u0303"+ - "\1\u04b5\4\u0303\237\0\1\u036f\26\u0303\1\u0630\3\u0303\1\u0370"+ - "\12\u0303\237\0\1\u036f\1\u0303\1\u0631\30\u0303\1\u0370\12\u0303"+ - "\237\0\1\u036f\26\u0303\1\u0632\3\u0303\1\u0370\12\u0303\237\0"+ - "\1\u036f\32\u0303\1\u0370\1\u0303\1\u0633\10\u0303\237\0\1\u036f"+ - "\1\u0634\31\u0303\1\u0370\12\u0303\237\0\1\u036f\1\u0635\27\u0303"+ - "\1\u0636\1\u0303\1\u0370\12\u0303\237\0\1\u036f\32\u0303\1\u0370"+ - "\1\u0637\11\u0303\237\0\1\u036f\4\u0303\1\u0638\25\u0303\1\u0370"+ - "\12\u0303\237\0\1\u036f\25\u0303\1\u0639\4\u0303\1\u0370\12\u0303"+ - "\237\0\1\u036f\1\u063a\31\u0303\1\u0370\12\u0303\237\0\1\u036f"+ - "\32\u0303\1\u0370\1\u063b\11\u0303\237\0\1\u036f\32\u0303\1\u0370"+ - "\2\u0303\1\u03e5\7\u0303\237\0\1\u036f\32\u0303\1\u0370\3\u0303"+ - "\1\u063c\6\u0303\237\0\1\u036f\1\u063d\1\u0303\1\u063e\27\u0303"+ - "\1\u0370\12\u0303\237\0\1\u036f\1\u062f\31\u0303\1\u0370\12\u0303"+ - "\237\0\1\u036f\32\u0303\1\u0370\2\u0303\1\u063f\7\u0303\237\0"+ - "\1\u036f\32\u0303\1\u0370\2\u0303\1\u0640\7\u0303\237\0\1\u036f"+ - "\15\u0303\1\u0641\14\u0303\1\u0370\12\u0303\237\0\1\u036f\32\u0303"+ - "\1\u0370\5\u0303\1\u0642\4\u0303\237\0\1\u036f\32\u0303\1\u0370"+ - "\7\u0303\1\u0643\2\u0303\237\0\1\u036f\32\u0303\1\u0370\11\u0303"+ - "\1\u0644\237\0\1\u036f\1\u0303\1\u0645\30\u0303\1\u0370\12\u0303"+ - "\237\0\1\u036f\32\u0303\1\u0370\3\u0303\1\u0646\6\u0303\237\0"+ - "\1\u036f\32\u0303\1\u0370\1\u0303\1\u0647\10\u0303\237\0\1\u036f"+ - "\32\u0303\1\u0370\1\u0303\1\u0648\10\u0303\237\0\1\u036f\24\u0303"+ - "\1\u0649\5\u0303\1\u0370\12\u0303\237\0\1\u036f\32\u0303\1\u0370"+ - "\6\u0303\1\u064a\3\u0303\237\0\1\u036f\32\u0303\1\u0370\3\u0303"+ - "\1\u064b\6\u0303\237\0\1\u036f\1\u063c\31\u0303\1\u0370\12\u0303"+ - "\237\0\1\u036f\32\u0303\1\u0370\11\u0303\1\u064c\237\0\1\u036f"+ - "\25\u0303\1\u064d\4\u0303\1\u0370\12\u0303\237\0\1\u0109\32\270"+ - "\1\u010a\11\270\1\u064e\237\0\1\u0109\4\270\1\u018f\25\270"+ - "\1\u010a\12\270\237\0\1\u0109\24\270\1\u0153\5\270\1\u010a"+ - "\12\270\237\0\1\u0109\32\270\1\u010a\6\270\1\u0153\3\270"+ - "\237\0\1\u0121\32\324\1\164\5\324\1\u064f\4\324\1\0"+ - "\3\161\1\0\2\161\1\162\3\161\3\0\1\161\4\0"+ - "\2\161\260\0\1\u05a5\237\0\4\u0650\2\0\1\u0650\15\0"+ - "\1\u0650\6\0\12\u0650\1\u0619\237\0\4\u0651\2\0\1\u0651"+ - "\15\0\1\u0651\6\0\1\u0652\2\u0653\1\u0652\5\u0653\1\u0654"+ - "\1\u0655\237\0\4\u0656\2\0\1\u0656\15\0\1\u0656\6\0"+ - "\12\u0656\1\u0657\13\0\1\u035e\222\0\1\u03c5\4\u0656\2\0"+ - "\1\u0656\15\0\1\u0656\6\0\12\u0658\1\u0657\13\0\1\u035e"+ - "\222\0\1\u03c5\4\u0656\2\0\1\u0656\15\0\1\u0656\6\0"+ - "\12\u0659\1\u0657\13\0\1\u035e\222\0\1\u03c5\4\u0656\2\0"+ - "\1\u0656\15\0\1\u0656\6\0\1\u0658\1\u065a\1\u0659\2\u0658"+ - "\2\u0659\1\u0658\1\u0659\1\u0658\1\u0657\13\0\1\u035e\223\0"+ - "\4\u065b\2\0\1\u065b\15\0\1\u065b\6\0\12\u065b\1\u05df"+ - "\13\0\1\u035e\222\0\1\u03c5\4\u065b\2\0\1\u065b\15\0"+ - "\1\u065b\6\0\12\u065b\1\u05df\13\0\1\u035e\223\0\4\u065c"+ - "\2\0\1\u065c\15\0\1\u065c\6\0\12\u065c\1\u05e6\237\0"+ - "\4\u065d\2\0\1\u065d\15\0\1\u065d\6\0\12\u065d\1\u065e"+ - "\236\0\1\u036b\4\u065d\2\0\1\u065d\15\0\1\u065d\6\0"+ - "\12\u065f\1\u065e\236\0\1\u036b\4\u065d\2\0\1\u065d\15\0"+ - "\1\u065d\6\0\12\u0660\1\u065e\236\0\1\u036b\4\u065d\2\0"+ - "\1\u065d\15\0\1\u065d\6\0\1\u065f\1\u0661\1\u0660\2\u065f"+ - "\2\u0660\1\u065f\1\u0660\1\u065f\1\u065e\237\0\4\u0662\2\0"+ - "\1\u0662\15\0\1\u0662\6\0\12\u0662\14\0\1\u0302\223\0"+ - "\4\u0663\2\0\1\u0663\15\0\1\u0663\6\0\12\u0663\1\u0627"+ - "\13\0\1\u0302\223\0\4\u0662\2\0\1\u0662\15\0\1\u0662"+ - "\6\0\12\u0662\237\0\1\u036b\4\u0663\2\0\1\u0663\15\0"+ - "\1\u0663\6\0\12\u0664\1\u0627\13\0\1\u0302\222\0\1\u036b"+ - "\4\u0663\2\0\1\u0663\15\0\1\u0663\6\0\12\u0663\1\u0627"+ - "\13\0\1\u0302\222\0\1\u036b\4\u0663\2\0\1\u0663\15\0"+ - "\1\u0663\6\0\2\u0664\1\u0663\2\u0664\2\u0663\1\u0664\1\u0663"+ - "\1\u0664\1\u0627\13\0\1\u0302\270\0\1\u05b2\13\0\1\u0302"+ - "\222\0\1\u036f\32\u0303\1\u0370\1\u0665\11\u0303\237\0\1\u036f"+ - "\1\u0666\31\u0303\1\u0370\12\u0303\237\0\1\u036f\32\u0303\1\u0370"+ - "\10\u0303\1\u0667\1\u0303\237\0\1\u036f\25\u0303\1\u044e\4\u0303"+ - "\1\u0370\12\u0303\237\0\1\u036f\32\u0303\1\u0370\5\u0303\1\u0668"+ - "\4\u0303\237\0\1\u036f\32\u0303\1\u0370\5\u0303\1\u0669\4\u0303"+ - "\237\0\1\u036f\32\u0303\1\u0370\5\u0303\1\u063c\4\u0303\237\0"+ - "\1\u036f\32\u0303\1\u0370\3\u0303\1\u0666\6\u0303\237\0\1\u036f"+ - "\17\u0303\1\u066a\12\u0303\1\u0370\12\u0303\237\0\1\u036f\12\u0303"+ - "\1\u066b\17\u0303\1\u0370\12\u0303\237\0\1\u036f\25\u0303\1\u066c"+ - "\4\u0303\1\u0370\12\u0303\237\0\1\u036f\1\u066d\31\u0303\1\u0370"+ - "\12\u0303\237\0\1\u036f\15\u0303\1\u066e\14\u0303\1\u0370\12\u0303"+ - "\237\0\1\u036f\32\u0303\1\u0370\3\u0303\1\u066f\6\u0303\237\0"+ - "\1\u036f\21\u0303\1\u0670\10\u0303\1\u0370\12\u0303\237\0\1\u036f"+ - "\2\u0303\1\u062f\27\u0303\1\u0370\12\u0303\237\0\1\u036f\1\u0303"+ - "\1\u044e\30\u0303\1\u0370\12\u0303\237\0\1\u036f\11\u0303\1\u0671"+ - "\20\u0303\1\u0370\12\u0303\237\0\1\u036f\11\u0303\1\u0672\20\u0303"+ - "\1\u0370\12\u0303\237\0\1\u036f\1\u0673\31\u0303\1\u0370\12\u0303"+ - "\237\0\1\u036f\1\u0674\31\u0303\1\u0370\12\u0303\237\0\1\u036f"+ - "\2\u0303\1\u0675\27\u0303\1\u0370\12\u0303\237\0\1\u036f\32\u0303"+ - "\1\u0370\4\u0303\1\u0455\5\u0303\237\0\1\u036f\10\u0303\1\u0676"+ - "\21\u0303\1\u0370\12\u0303\237\0\1\u036f\1\u0677\31\u0303\1\u0370"+ - "\12\u0303\237\0\1\u036f\25\u0303\1\u0678\4\u0303\1\u0370\12\u0303"+ - "\237\0\1\u036f\32\u0303\1\u0370\4\u0303\1\u0666\5\u0303\237\0"+ - "\1\u036f\32\u0303\1\u0370\6\u0303\1\u0666\3\u0303\237\0\1\u036f"+ - "\32\u0303\1\u0370\2\u0303\1\u0666\7\u0303\237\0\1\u036f\16\u0303"+ - "\1\u0679\13\u0303\1\u0370\12\u0303\237\0\1\u036f\32\u0303\1\u0370"+ - "\1\u067a\11\u0303\237\0\1\u036f\32\u0303\1\u0370\3\u0303\1\u067b"+ - "\6\u0303\237\0\1\u036f\32\u0303\1\u0370\3\u0303\1\u03e5\6\u0303"+ - "\237\0\1\u036f\24\u0303\1\u067c\5\u0303\1\u0370\12\u0303\237\0"+ - "\1\u0109\1\u067d\31\270\1\u010a\12\270\237\0\1\u0121\7\324"+ - "\1\u067e\22\324\1\164\12\324\1\0\3\161\1\0\2\161"+ - "\1\162\3\161\3\0\1\161\4\0\2\161\213\0\4\u067f"+ - "\2\0\1\u067f\15\0\1\u067f\6\0\12\u067f\1\u0619\237\0"+ - "\4\u0680\2\0\1\u0680\15\0\1\u0680\6\0\12\u0680\1\u0681"+ - "\236\0\1\u03c5\4\u0680\2\0\1\u0680\15\0\1\u0680\6\0"+ - "\12\u0682\1\u0681\236\0\1\u03c5\4\u0680\2\0\1\u0680\15\0"+ - "\1\u0680\6\0\12\u0683\1\u0681\236\0\1\u03c5\4\u0680\2\0"+ - "\1\u0680\15\0\1\u0680\6\0\1\u0682\1\u0684\1\u0683\2\u0682"+ - "\2\u0683\1\u0682\1\u0683\1\u0682\1\u0681\237\0\4\u0685\2\0"+ - "\1\u0685\15\0\1\u0685\6\0\12\u0685\14\0\1\u035e\223\0"+ - "\4\u0686\2\0\1\u0686\15\0\1\u0686\6\0\12\u0686\1\u0657"+ - "\13\0\1\u035e\223\0\4\u0685\2\0\1\u0685\15\0\1\u0685"+ - "\6\0\12\u0685\237\0\1\u03c5\4\u0686\2\0\1\u0686\15\0"+ - "\1\u0686\6\0\12\u0687\1\u0657\13\0\1\u035e\222\0\1\u03c5"+ - "\4\u0686\2\0\1\u0686\15\0\1\u0686\6\0\12\u0686\1\u0657"+ - "\13\0\1\u035e\222\0\1\u03c5\4\u0686\2\0\1\u0686\15\0"+ - "\1\u0686\6\0\2\u0687\1\u0686\2\u0687\2\u0686\1\u0687\1\u0686"+ - "\1\u0687\1\u0657\13\0\1\u035e\270\0\1\u05df\13\0\1\u035e"+ - "\270\0\1\u05e6\237\0\4\u0688\2\0\1\u0688\15\0\1\u0688"+ - "\6\0\12\u0688\1\u065e\237\0\4\u0662\2\0\1\u0662\15\0"+ - "\1\u0662\6\0\12\u0662\1\u0573\236\0\1\u036b\4\u0688\2\0"+ - "\1\u0688\15\0\1\u0688\6\0\12\u0689\1\u065e\236\0\1\u036b"+ - "\4\u0688\2\0\1\u0688\15\0\1\u0688\6\0\12\u0688\1\u065e"+ - "\236\0\1\u036b\4\u0688\2\0\1\u0688\15\0\1\u0688\6\0"+ - "\2\u0689\1\u0688\2\u0689\2\u0688\1\u0689\1\u0688\1\u0689\1\u065e"+ - "\237\0\4\u068a\2\0\1\u068a\15\0\1\u068a\6\0\12\u068a"+ - "\14\0\1\u0302\223\0\4\u068b\2\0\1\u068b\15\0\1\u068b"+ - "\6\0\12\u068b\1\u0627\13\0\1\u0302\222\0\1\u036b\4\u068b"+ - "\2\0\1\u068b\15\0\1\u068b\6\0\12\u068b\1\u0627\13\0"+ - "\1\u0302\222\0\1\u036f\3\u0303\1\u068c\26\u0303\1\u0370\12\u0303"+ - "\237\0\1\u036f\2\u0303\1\u044e\27\u0303\1\u0370\12\u0303\237\0"+ - "\1\u036f\6\u0303\1\u0459\23\u0303\1\u0370\12\u0303\237\0\1\u036f"+ - "\1\u0303\1\u0646\30\u0303\1\u0370\12\u0303\237\0\1\u036f\3\u0303"+ - "\1\u068d\26\u0303\1\u0370\12\u0303\237\0\1\u036f\32\u0303\1\u0370"+ - "\3\u0303\1\u068e\6\u0303\237\0\1\u036f\32\u0303\1\u0370\6\u0303"+ - "\1\u068f\3\u0303\237\0\1\u036f\32\u0303\1\u0370\6\u0303\1\u0690"+ - "\3\u0303\237\0\1\u036f\32\u0303\1\u0370\5\u0303\1\u0691\4\u0303"+ - "\237\0\1\u036f\32\u0303\1\u0370\7\u0303\1\u0692\2\u0303\237\0"+ - "\1\u036f\1\u0693\31\u0303\1\u0370\12\u0303\237\0\1\u036f\24\u0303"+ - "\1\u0694\5\u0303\1\u0370\12\u0303\237\0\1\u036f\32\u0303\1\u0370"+ - "\4\u0303\1\u0695\5\u0303\237\0\1\u036f\32\u0303\1\u0370\4\u0303"+ - "\1\u0696\5\u0303\237\0\1\u036f\26\u0303\1\u0697\3\u0303\1\u0370"+ - "\12\u0303\237\0\1\u036f\30\u0303\1\u0698\1\u0303\1\u0370\12\u0303"+ - "\237\0\1\u036f\11\u0303\1\u04af\20\u0303\1\u0370\12\u0303\237\0"+ - "\1\u036f\32\u0303\1\u0370\2\u0303\1\u0699\7\u0303\237\0\1\u036f"+ - "\12\u0303\1\u069a\17\u0303\1\u0370\12\u0303\237\0\1\u036f\17\u0303"+ - "\1\u0456\12\u0303\1\u0370\12\u0303\237\0\1\u036f\32\u0303\1\u0370"+ - "\4\u0303\1\u069b\5\u0303\237\0\1\u036f\32\u0303\1\u0370\6\u0303"+ - "\1\u04b2\3\u0303\237\0\1\u036f\30\u0303\1\u069c\1\u0303\1\u0370"+ - "\12\u0303\237\0\1\u036f\30\u0303\1\u069d\1\u0303\1\u0370\12\u0303"+ - "\237\0\1\u0109\32\270\1\u010a\5\270\1\u069e\4\270\237\0"+ - "\1\u0121\1\324\1\u03a5\30\324\1\164\12\324\1\0\3\161"+ - "\1\0\2\161\1\162\3\161\3\0\1\161\4\0\2\161"+ - "\260\0\1\u0619\237\0\4\u069f\2\0\1\u069f\15\0\1\u069f"+ - "\6\0\12\u069f\1\u0681\237\0\4\u0685\2\0\1\u0685\15\0"+ - "\1\u0685\6\0\12\u0685\1\u05ac\236\0\1\u03c5\4\u069f\2\0"+ - "\1\u069f\15\0\1\u069f\6\0\12\u06a0\1\u0681\236\0\1\u03c5"+ - "\4\u069f\2\0\1\u069f\15\0\1\u069f\6\0\12\u069f\1\u0681"+ - "\236\0\1\u03c5\4\u069f\2\0\1\u069f\15\0\1\u069f\6\0"+ - "\2\u06a0\1\u069f\2\u06a0\2\u069f\1\u06a0\1\u069f\1\u06a0\1\u0681"+ - "\237\0\4\u06a1\2\0\1\u06a1\15\0\1\u06a1\6\0\12\u06a1"+ - "\14\0\1\u035e\223\0\4\u06a2\2\0\1\u06a2\15\0\1\u06a2"+ - "\6\0\12\u06a2\1\u0657\13\0\1\u035e\222\0\1\u03c5\4\u06a2"+ - "\2\0\1\u06a2\15\0\1\u06a2\6\0\12\u06a2\1\u0657\13\0"+ - "\1\u035e\223\0\4\u06a3\2\0\1\u06a3\15\0\1\u06a3\6\0"+ - "\12\u06a3\1\u065e\236\0\1\u036b\4\u06a3\2\0\1\u06a3\15\0"+ - "\1\u06a3\6\0\12\u06a3\1\u065e\237\0\4\u06a4\2\0\1\u06a4"+ - "\15\0\1\u06a4\6\0\12\u06a4\14\0\1\u0302\270\0\1\u0627"+ - "\13\0\1\u0302\222\0\1\u036f\1\u06a5\31\u0303\1\u0370\12\u0303"+ - "\237\0\1\u036f\32\u0303\1\u0370\11\u0303\1\u063c\237\0\1\u036f"+ - "\1\u06a6\31\u0303\1\u0370\12\u0303\237\0\1\u036f\1\u06a7\31\u0303"+ - "\1\u0370\12\u0303\237\0\1\u036f\7\u0303\1\u06a8\22\u0303\1\u0370"+ - "\12\u0303\237\0\1\u036f\1\u06a9\31\u0303\1\u0370\12\u0303\237\0"+ - "\1\u036f\1\u06aa\31\u0303\1\u0370\12\u0303\237\0\1\u036f\32\u0303"+ - "\1\u0370\6\u0303\1\u06ab\3\u0303\237\0\1\u036f\6\u0303\1\u044e"+ - "\23\u0303\1\u0370\12\u0303\237\0\1\u036f\25\u0303\1\u06ac\4\u0303"+ - "\1\u0370\12\u0303\237\0\1\u036f\1\u06ad\31\u0303\1\u0370\12\u0303"+ - "\237\0\1\u036f\32\u0303\1\u0370\6\u0303\1\u06ae\3\u0303\237\0"+ - "\1\u036f\1\u06af\31\u0303\1\u0370\12\u0303\237\0\1\u036f\32\u0303"+ - "\1\u0370\6\u0303\1\u04ae\3\u0303\237\0\1\u036f\12\u0303\1\u045f"+ - "\17\u0303\1\u0370\12\u0303\237\0\1\u036f\1\u06b0\31\u0303\1\u0370"+ - "\12\u0303\237\0\1\u036f\10\u0303\1\u06b1\21\u0303\1\u0370\12\u0303"+ - "\237\0\1\u036f\31\u0303\1\u06b2\1\u0370\12\u0303\237\0\1\u0109"+ - "\7\270\1\u06b3\22\270\1\u010a\12\270\240\0\4\u06b4\2\0"+ - "\1\u06b4\15\0\1\u06b4\6\0\12\u06b4\1\u0681\236\0\1\u03c5"+ - "\4\u06b4\2\0\1\u06b4\15\0\1\u06b4\6\0\12\u06b4\1\u0681"+ - "\237\0\4\u06b5\2\0\1\u06b5\15\0\1\u06b5\6\0\12\u06b5"+ - "\14\0\1\u035e\270\0\1\u0657\13\0\1\u035e\270\0\1\u065e"+ - "\237\0\4\u0573\2\0\1\u0573\15\0\1\u0573\6\0\12\u0573"+ - "\14\0\1\u0302\222\0\1\u036f\32\u0303\1\u0370\1\u06b6\11\u0303"+ - "\237\0\1\u036f\2\u0303\1\u06b7\27\u0303\1\u0370\12\u0303\237\0"+ - "\1\u036f\32\u0303\1\u0370\10\u0303\1\u062f\1\u0303\237\0\1\u036f"+ - "\15\u0303\1\u03e5\14\u0303\1\u0370\12\u0303\237\0\1\u036f\23\u0303"+ - "\1\u06b8\6\u0303\1\u0370\12\u0303\237\0\1\u036f\32\u0303\1\u0370"+ - "\1\u0303\1\u06b9\10\u0303\237\0\1\u036f\32\u0303\1\u0370\3\u0303"+ - "\1\u04b2\6\u0303\237\0\1\u036f\30\u0303\1\u06ba\1\u0303\1\u0370"+ - "\12\u0303\237\0\1\u036f\32\u0303\1\u0370\1\u0303\1\u06bb\10\u0303"+ - "\237\0\1\u036f\6\u0303\1\u06bc\23\u0303\1\u0370\12\u0303\237\0"+ - "\1\u036f\32\u0303\1\u0370\5\u0303\1\u06bd\4\u0303\237\0\1\u036f"+ - "\32\u0303\1\u0370\5\u0303\1\u06be\4\u0303\237\0\1\u036f\32\u0303"+ - "\1\u0370\1\u0303\1\u03e5\10\u0303\237\0\1\u036f\13\u0303\1\u06bf"+ - "\16\u0303\1\u0370\12\u0303\237\0\1\u0109\1\270\1\u046d\30\270"+ - "\1\u010a\12\270\305\0\1\u0681\237\0\4\u05ac\2\0\1\u05ac"+ - "\15\0\1\u05ac\6\0\12\u05ac\14\0\1\u035e\222\0\1\u036f"+ - "\24\u0303\1\u06c0\5\u0303\1\u0370\12\u0303\237\0\1\u036f\32\u0303"+ - "\1\u0370\10\u0303\1\u06c1\1\u0303\237\0\1\u036f\1\u0303\1\u0455"+ - "\30\u0303\1\u0370\12\u0303\237\0\1\u036f\2\u0303\1\u06c2\27\u0303"+ - "\1\u0370\12\u0303\237\0\1\u036f\3\u0303\1\u06c3\26\u0303\1\u0370"+ - "\12\u0303\237\0\1\u036f\3\u0303\1\u06c4\26\u0303\1\u0370\12\u0303"+ - "\237\0\1\u036f\32\u0303\1\u0370\1\u0303\1\u06c5\10\u0303\237\0"+ - "\1\u036f\3\u0303\1\u06c6\26\u0303\1\u0370\12\u0303\237\0\1\u036f"+ - "\1\u06c7\31\u0303\1\u0370\12\u0303\237\0\1\u036f\26\u0303\1\u06c8"+ - "\3\u0303\1\u0370\12\u0303\237\0\1\u036f\32\u0303\1\u0370\11\u0303"+ - "\1\u06c9\237\0\1\u036f\26\u0303\1\u044e\3\u0303\1\u0370\12\u0303"+ - "\237\0\1\u036f\32\u0303\1\u0370\7\u0303\1\u06ca\2\u0303\237\0"+ - "\1\u036f\32\u0303\1\u0370\11\u0303\1\u03e5\237\0\1\u036f\3\u0303"+ - "\1\u06cb\26\u0303\1\u0370\12\u0303\237\0\1\u036f\32\u0303\1\u0370"+ - "\4\u0303\1\u06cc\5\u0303\237\0\1\u036f\16\u0303\1\u06cd\13\u0303"+ - "\1\u0370\12\u0303\237\0\1\u036f\26\u0303\1\u06ce\3\u0303\1\u0370"+ - "\12\u0303\237\0\1\u036f\32\u0303\1\u0370\7\u0303\1\u0694\2\u0303"+ - "\237\0\1\u036f\7\u0303\1\u06cf\22\u0303\1\u0370\12\u0303\237\0"+ - "\1\u036f\1\u06d0\31\u0303\1\u0370\12\u0303\237\0\1\u036f\32\u0303"+ - "\1\u0370\1\u062f\11\u0303\237\0\1\u036f\24\u0303\1\u06d1\5\u0303"+ - "\1\u0370\12\u0303\237\0\1\u036f\1\u0303\1\u06d2\30\u0303\1\u0370"+ - "\12\u0303\237\0\1\u036f\32\u0303\1\u0370\2\u0303\1\u0455\7\u0303"+ - "\237\0\1\u036f\32\u0303\1\u0370\11\u0303\1\u06d3\237\0\1\u036f"+ - "\4\u0303\1\u044e\25\u0303\1\u0370\12\u0303\237\0\1\u036f\24\u0303"+ - "\1\u03e5\5\u0303\1\u0370\12\u0303\237\0\1\u036f\32\u0303\1\u0370"+ - "\6\u0303\1\u03e5\3\u0303\237\0\1\u036f\1\u06d4\31\u0303\1\u0370"+ - "\12\u0303\237\0\1\u036f\32\u0303\1\u0370\5\u0303\1\u06d5\4\u0303"+ - "\237\0\1\u036f\7\u0303\1\u06d6\22\u0303\1\u0370\12\u0303\237\0"+ - "\1\u036f\1\u0303\1\u0666\30\u0303\1\u0370\12\u0303\26\0"; + "\3\154\3\0\1\154\3\0\2\154\2\0\1\55\1\0"+ + "\1\56\2\0\1\57\1\0\1\60\4\0\1\61\1\0"+ + "\1\62\1\0\1\63\2\0\1\64\3\0\1\65\2\0"+ + "\1\66\4\0\1\67\3\0\1\70\17\0\1\71\2\0"+ + "\1\72\21\0\1\73\2\0\1\74\61\0\2\30\1\75"+ + "\1\0\1\76\1\0\1\76\1\77\1\0\1\30\2\0"+ + "\1\201\1\0\1\41\1\30\1\202\13\43\1\u0141\16\43"+ + "\1\203\12\204\1\76\1\154\1\205\1\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\217\0\1\u03d1"+ + "\32\u035d\1\u03d2\12\u035d\10\0\1\u035e\231\0\51\u035e\1\u03d3"+ + "\2\0\3\u035e\1\u022a\3\0\1\u035e\225\0\4\u03d4\2\0"+ + "\1\u03d4\15\0\1\u03d4\6\0\12\u03d4\1\u03d5\235\0\1\u02f3"+ + "\3\0\1\u02f3\32\u02f4\1\u02f3\12\u02f4\1\u02f5\2\u02f3\1\u02f6"+ + "\2\u02f3\1\u02f7\5\0\2\u02f3\3\0\1\u02f3\214\0\1\u02f3"+ + "\3\0\1\u02f3\32\u02f4\1\u0361\12\u02f4\1\u02f5\2\u02f3\1\u02f6"+ + "\2\u02f3\1\u02f7\5\0\2\u02f3\3\0\1\u02f3\214\0\1\u02f5"+ + "\3\0\34\u02f5\12\u03d6\1\0\2\u02f5\1\u0364\2\u02f5\1\u02f7"+ + "\5\0\2\u02f5\3\0\1\u02f5\220\0\51\u0363\1\u03d7\2\0"+ + "\3\u0363\1\u022a\2\0\1\u03d8\1\u0363\225\0\4\u03d9\2\0"+ + "\1\u03d9\15\0\1\u03d9\6\0\12\u03d9\243\0\4\u02f3\2\0"+ + "\1\u02f3\15\0\1\u02f3\6\0\12\u02f3\242\0\1\u03da\32\u0366"+ + "\1\u03db\12\u0366\1\u03dc\7\0\1\u0363\232\0\4\u03dd\2\0"+ + "\1\u03dd\15\0\1\u03dd\6\0\12\u03dd\1\u03de\307\0\1\u03df"+ + "\24\0\1\55\1\0\1\56\2\0\1\245\1\0\1\246"+ + "\4\0\1\61\1\0\1\62\1\0\1\63\2\0\1\64"+ + "\3\0\1\247\2\0\1\250\4\0\1\251\3\0\1\252"+ + "\17\0\1\71\2\0\1\253\21\0\1\254\2\0\1\255"+ + "\61\0\1\30\1\76\2\0\1\76\1\0\2\76\1\0"+ + "\1\76\2\0\1\u0369\1\0\2\30\1\u03e0\32\u036b\13\u036c"+ + "\1\76\1\u036c\1\u0369\1\u036c\1\0\1\u036c\1\u03e1\3\u036c"+ + "\3\0\1\u036c\3\0\2\u036c\213\0\1\u036a\1\u03e2\2\0"+ + "\65\u036a\1\u03e3\1\0\2\u036a\2\0\1\55\1\0\1\56"+ + "\2\0\1\57\1\0\1\60\4\0\1\61\1\0\1\62"+ + "\1\0\1\63\2\0\1\64\3\0\1\65\2\0\1\66"+ + "\4\0\1\67\3\0\1\70\17\0\1\71\2\0\1\72"+ + "\21\0\1\73\2\0\1\74\61\0\2\30\1\75\1\0"+ + "\1\76\1\0\1\76\1\77\1\0\1\30\2\0\1\u0369"+ + "\1\0\1\41\1\30\1\u03e0\32\u036b\1\u036c\12\u03e4\1\76"+ + "\1\u036c\1\u03e5\1\u036c\1\0\1\u036c\1\u03e1\3\u036c\3\0"+ + "\1\u036c\3\0\2\u036c\213\0\1\u036c\3\0\1\u03e6\45\u036c"+ + "\1\0\3\u036c\1\0\1\u036c\1\u03e1\3\u036c\3\0\1\u036c"+ + "\3\0\2\u036c\213\0\1\u036d\3\0\46\u036d\1\u036f\2\u036d"+ + "\1\u0370\2\u036d\1\u0371\5\0\2\u036d\3\0\1\u036d\214\0"+ + "\1\u036d\3\0\1\u03e7\32\u036e\1\u03e8\12\u036e\1\u03e9\2\u036d"+ + "\1\u0370\2\u036d\1\u0371\1\u0228\1\u0229\1\u022a\2\0\2\u036d"+ + "\3\0\1\u036d\214\0\1\u036f\3\0\46\u036f\1\0\2\u036f"+ + "\1\u03ea\2\u036f\1\u0371\5\0\2\u036f\3\0\1\u036f\221\0"+ + "\4\u03eb\2\0\1\u03eb\15\0\1\u03eb\6\0\12\u03eb\243\0"+ + "\32\u03ec\1\0\12\u03ec\12\0\1\u0372\223\0\1\154\3\0"+ + "\1\u016f\20\371\1\u03ed\11\371\1\203\12\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\1\371\1\u03ee\30\371\1\203"+ + "\12\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\13\371"+ + "\1\u0180\16\371\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\2\371\1\u0213\27\371\1\203\12\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\5\371\1\u0302\24\371"+ + "\1\203\12\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\4\371\1\u03ef\25\371\1\203\12\371\1\0\3\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\213\0"+ + "\1\154\3\0\1\u016f\3\371\1\u03f0\26\371\1\203\12\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\1\371\1\u0213"+ + "\30\371\1\203\12\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\4\371\1\u03f1\25\371\1\203\12\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\11\371\1\u03f2\20\371\1\203"+ + "\12\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\7\371"+ + "\1\u0213\22\371\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\13\371\1\u0174\16\371\1\203\12\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\2\0\1\55\1\0\1\56\2\0\1\100\1\0"+ + "\1\101\4\0\1\61\1\0\1\62\1\0\1\63\2\0"+ + "\1\64\3\0\1\102\2\0\1\103\4\0\1\104\3\0"+ + "\1\105\17\0\1\71\2\0\1\106\21\0\1\107\2\0"+ + "\1\110\61\0\1\30\2\31\2\0\2\111\1\112\1\0"+ + "\1\31\2\0\1\212\1\0\1\41\1\30\1\u01a5\32\43"+ + "\1\203\12\u0120\1\u01f9\1\154\1\215\1\154\1\0\1\212"+ + "\1\156\1\u01d1\1\u01d2\1\u01d3\2\0\1\111\1\154\3\0"+ + "\2\154\2\0\1\55\1\0\1\56\2\0\1\100\1\0"+ + "\1\101\4\0\1\61\1\0\1\62\1\0\1\63\2\0"+ + "\1\64\3\0\1\102\2\0\1\103\4\0\1\104\3\0"+ + "\1\105\17\0\1\71\2\0\1\106\21\0\1\107\2\0"+ + "\1\110\61\0\1\30\2\31\2\0\2\111\1\112\1\0"+ + "\1\31\2\0\1\212\1\0\1\41\1\30\1\u01a5\32\43"+ + "\1\203\2\u037f\1\u0120\2\u037f\2\u0120\2\u037f\1\u0120\1\u01f9"+ + "\1\154\1\215\1\154\1\0\1\212\1\156\1\u01d1\1\u01d2"+ + "\1\u01d3\2\0\1\111\1\154\3\0\2\154\220\0\4\u03f3"+ + "\2\0\1\u03f3\15\0\1\u03f3\6\0\12\u03f3\1\u0310\242\0"+ + "\4\u03f4\2\0\1\u03f4\15\0\1\u03f4\6\0\12\u03f4\1\u03f5"+ + "\242\0\4\u03f6\2\0\1\u03f6\15\0\1\u03f6\6\0\1\u03f7"+ + "\1\u03f8\5\u03f7\1\u03f9\1\u03f8\1\u03f7\13\0\1\u01ad\227\0"+ + "\4\u03fa\2\0\1\u03fa\15\0\1\u03fa\6\0\12\u03fa\1\u0385"+ + "\12\0\1\u01ad\227\0\4\u03f6\2\0\1\u03f6\15\0\1\u03f6"+ + "\6\0\1\u03f7\1\u03f8\5\u03f7\1\u03f9\1\u03f8\1\u03f7\242\0"+ + "\1\u0224\4\u03fa\2\0\1\u03fa\15\0\1\u03fa\6\0\12\u03fa"+ + "\1\u0385\12\0\1\u01ad\226\0\1\u0224\4\u03fa\2\0\1\u03fa"+ + "\15\0\1\u03fa\6\0\12\u03fb\1\u0385\12\0\1\u01ad\226\0"+ + "\1\u0224\4\u03fa\2\0\1\u03fa\15\0\1\u03fa\6\0\2\u03fb"+ + "\1\u03fa\2\u03fb\2\u03fa\2\u03fb\1\u03fa\1\u0385\12\0\1\u01ad"+ + "\274\0\1\u029d\12\0\1\u01ad\226\0\1\u03fc\33\0\12\u03fd"+ + "\242\0\1\u03fc\33\0\12\u038a\242\0\1\u03fc\33\0\2\u038a"+ + "\1\u03fd\1\u038a\1\u03fe\2\u03fd\2\u038a\1\u03fd\242\0\1\u0136"+ + "\4\323\1\u03ff\25\323\1\u0137\12\323\242\0\1\u0136\1\u0400"+ + "\31\323\1\u0137\12\323\242\0\1\u0136\10\323\1\u0401\21\323"+ + "\1\u0137\12\323\242\0\1\u0136\13\323\1\u0402\16\323\1\u0137"+ + "\12\323\242\0\1\u0136\17\323\1\u0403\12\323\1\u0137\12\323"+ + "\242\0\1\u0136\15\323\1\u0404\14\323\1\u0137\12\323\242\0"+ + "\1\u0136\12\323\1\u0405\17\323\1\u0137\12\323\242\0\1\u0136"+ + "\4\323\1\u02bd\25\323\1\u0137\12\323\242\0\1\u0136\10\323"+ + "\1\u0406\21\323\1\u0137\12\323\242\0\1\u0136\12\323\1\u022b"+ + "\17\323\1\u0137\12\323\242\0\1\u0136\7\323\1\u0407\22\323"+ + "\1\u0137\12\323\242\0\1\u0136\3\323\1\u02c3\26\323\1\u0137"+ + "\12\323\242\0\1\u0136\5\323\1\u0408\24\323\1\u0137\12\323"+ + "\242\0\1\u0136\11\323\1\u0409\20\323\1\u0137\12\323\242\0"+ + "\1\u0136\7\323\1\u040a\22\323\1\u0137\1\u040b\11\323\242\0"+ + "\1\u0136\10\323\1\u040c\4\323\1\u040d\5\323\1\u040e\6\323"+ + "\1\u0137\12\323\242\0\1\u0136\3\323\1\u040f\26\323\1\u0137"+ + "\12\323\242\0\1\u0136\7\323\1\u0410\22\323\1\u0137\10\323"+ + "\1\u0411\1\323\242\0\1\u0136\7\323\1\u0412\22\323\1\u0137"+ + "\12\323\242\0\1\u0136\7\323\1\u0413\22\323\1\u0137\12\323"+ + "\242\0\1\u0136\32\323\1\u0137\5\323\1\u0414\4\323\242\0"+ + "\1\u0136\7\323\1\u0415\22\323\1\u0137\10\323\1\u0416\1\323"+ + "\242\0\1\u0136\32\323\1\u0137\5\323\1\u0417\4\323\242\0"+ + "\1\u0136\13\323\1\u0418\16\323\1\u0137\12\323\242\0\1\u0136"+ + "\7\323\1\u0419\22\323\1\u0137\12\323\242\0\1\u0136\26\323"+ + "\1\u041a\3\323\1\u0137\12\323\242\0\1\u0136\32\323\1\u0137"+ + "\7\323\1\u0417\2\323\242\0\1\u0136\15\323\1\u041b\14\323"+ + "\1\u0137\12\323\242\0\1\u0136\32\323\1\u0137\10\323\1\u041c"+ + "\1\u041d\242\0\1\u0136\6\323\1\u041e\1\u041f\22\323\1\u0137"+ + "\12\323\242\0\1\u0136\3\323\1\u0420\26\323\1\u0137\12\323"+ + "\242\0\1\u0136\32\323\1\u0137\4\323\1\u0417\5\323\242\0"+ + "\1\u0136\32\323\1\u0137\1\323\1\u0421\10\323\242\0\1\u0136"+ + "\32\323\1\u0137\1\323\1\u0422\10\323\242\0\1\u0136\13\323"+ + "\1\u0423\16\323\1\u0137\12\323\242\0\1\u0136\3\323\1\u0424"+ + "\26\323\1\u0137\12\323\242\0\1\u0136\4\323\1\u0398\25\323"+ + "\1\u0137\12\323\276\0\12\u0425\7\0\1\u0228\1\u0229\1\u022a"+ + "\13\0\1\55\1\0\1\56\2\0\1\57\1\0\1\60"+ + "\4\0\1\61\1\0\1\62\1\0\1\63\2\0\1\64"+ + "\3\0\1\65\2\0\1\66\4\0\1\67\3\0\1\70"+ + "\17\0\1\71\2\0\1\72\21\0\1\73\2\0\1\74"+ + "\61\0\2\30\1\75\1\0\1\76\1\0\1\76\1\77"+ + "\1\0\1\30\2\0\1\201\1\0\1\41\1\30\1\202"+ + "\1\43\1\u0426\30\43\1\203\12\204\1\76\1\154\1\205"+ + "\1\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\2\0\1\55\1\0\1\56\2\0\1\57\1\0"+ + "\1\60\4\0\1\61\1\0\1\62\1\0\1\63\2\0"+ + "\1\64\3\0\1\65\2\0\1\66\4\0\1\67\3\0"+ + "\1\70\17\0\1\71\2\0\1\72\21\0\1\73\2\0"+ + "\1\74\61\0\2\30\1\75\1\0\1\76\1\0\1\76"+ + "\1\77\1\0\1\30\2\0\1\201\1\0\1\41\1\30"+ + "\1\202\17\43\1\u0427\12\43\1\203\12\204\1\76\1\154"+ + "\1\205\1\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\2\0\1\55\1\0\1\56\2\0\1\57"+ + "\1\0\1\60\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\65\2\0\1\66\4\0\1\67"+ + "\3\0\1\70\17\0\1\71\2\0\1\72\21\0\1\73"+ + "\2\0\1\74\61\0\2\30\1\75\1\0\1\76\1\0"+ + "\1\76\1\77\1\0\1\30\2\0\1\201\1\0\1\41"+ + "\1\30\1\202\10\43\1\u0428\21\43\1\203\12\204\1\76"+ + "\1\154\1\205\1\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\2\0\1\55\1\0\1\56\2\0"+ + "\1\57\1\0\1\60\4\0\1\61\1\0\1\62\1\0"+ + "\1\63\2\0\1\64\3\0\1\65\2\0\1\66\4\0"+ + "\1\67\3\0\1\70\17\0\1\71\2\0\1\72\21\0"+ + "\1\73\2\0\1\74\61\0\2\30\1\75\1\0\1\76"+ + "\1\0\1\76\1\77\1\0\1\30\2\0\1\201\1\0"+ + "\1\41\1\30\1\202\13\43\1\u01e4\16\43\1\203\12\204"+ + "\1\76\1\154\1\205\1\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\2\0\1\55\1\0\1\56"+ + "\2\0\1\57\1\0\1\60\4\0\1\61\1\0\1\62"+ + "\1\0\1\63\2\0\1\64\3\0\1\65\2\0\1\66"+ + "\4\0\1\67\3\0\1\70\17\0\1\71\2\0\1\72"+ + "\21\0\1\73\2\0\1\74\61\0\2\30\1\75\1\0"+ + "\1\76\1\0\1\76\1\77\1\0\1\30\2\0\1\201"+ + "\1\0\1\41\1\30\1\202\1\u0429\31\43\1\203\12\204"+ + "\1\76\1\154\1\205\1\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\2\0\1\55\1\0\1\56"+ + "\2\0\1\57\1\0\1\60\4\0\1\61\1\0\1\62"+ + "\1\0\1\63\2\0\1\64\3\0\1\65\2\0\1\66"+ + "\4\0\1\67\3\0\1\70\17\0\1\71\2\0\1\72"+ + "\21\0\1\73\2\0\1\74\61\0\2\30\1\75\1\0"+ + "\1\76\1\0\1\76\1\77\1\0\1\30\2\0\1\201"+ + "\1\0\1\41\1\30\1\202\5\43\1\u042a\24\43\1\203"+ + "\12\204\1\76\1\154\1\205\1\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\25\371\1\u042b\4\371\1\203\12\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\15\371\1\u042c\14\371\1\203"+ + "\12\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\21\371"+ + "\1\u042d\10\371\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\16\371\1\u042e\4\371\1\u042f\6\371\1\203"+ + "\12\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\4\371"+ + "\1\u0430\25\371\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\32\371\1\203\7\371\1\u0431\2\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\4\371\1\u0432\25\371"+ + "\1\203\12\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\24\371\1\u0433\5\371\1\203\12\371\1\0\3\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\213\0"+ + "\1\154\3\0\1\u016f\1\371\1\u0434\30\371\1\203\12\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\1\u0435\1\u0436"+ + "\1\371\1\u0437\16\371\1\u0438\1\371\1\u0439\5\371\1\203"+ + "\5\371\1\u043a\4\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\1\371\1\u043b\30\371\1\203\12\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\31\371\1\u043c\1\203\12\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\16\371\1\u043d"+ + "\13\371\1\203\12\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\15\371\1\u043e\14\371\1\203\12\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\11\371\1\u043f\13\371\1\u0440"+ + "\4\371\1\203\12\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\32\371\1\203\7\371\1\u0441\2\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\21\371\1\u0442\7\371\1\u0443"+ + "\1\203\12\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\12\371\1\u0444\17\371\1\203\12\371\1\0\3\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\213\0"+ + "\1\154\3\0\1\u016f\32\371\1\203\10\371\1\u0445\1\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\5\371\1\u0446"+ + "\24\371\1\203\12\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\10\371\1\u0447\21\371\1\203\12\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\24\371\1\u0448\5\371\1\203"+ + "\12\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\32\371"+ + "\1\203\1\u0449\11\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\5\371\1\u044a\10\371\1\u044b\13\371\1\203\12\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\220\0\32\u035d\1\0\12\u035d\243\0\32\u035d"+ + "\1\u03d2\12\u035d\243\0\4\u044c\2\0\1\u044c\15\0\1\u044c"+ + "\6\0\12\u044c\243\0\4\u044d\2\0\1\u044d\15\0\1\u044d"+ + "\6\0\12\u044d\1\u044e\307\0\1\u044f\235\0\1\u02f5\3\0"+ + "\34\u02f5\12\u0450\1\0\2\u02f5\1\u0364\2\u02f5\1\u02f7\1\0"+ + "\1\u0363\3\0\2\u02f5\3\0\1\u02f5\221\0\4\u0451\2\0"+ + "\1\u0451\15\0\1\u0451\6\0\12\u0451\262\0\1\u0452\270\0"+ + "\4\u02f5\2\0\1\u02f5\15\0\1\u02f5\6\0\12\u02f5\243\0"+ + "\32\u0366\1\0\12\u0366\243\0\32\u0366\1\u03db\12\u0366\276\0"+ + "\12\u0453\243\0\4\u0454\2\0\1\u0454\15\0\1\u0454\6\0"+ + "\12\u0454\1\u03de\242\0\4\u0455\2\0\1\u0455\15\0\1\u0455"+ + "\6\0\12\u0455\1\u0456\242\0\4\u0457\2\0\1\u0457\15\0"+ + "\1\u0457\6\0\1\u0458\1\u0459\5\u0458\1\u045a\1\u0459\1\u0458"+ + "\13\0\1\u045b\11\0\1\55\1\0\1\56\2\0\1\245"+ + "\1\0\1\246\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\247\2\0\1\250\4\0\1\251"+ + "\3\0\1\252\17\0\1\71\2\0\1\253\21\0\1\254"+ + "\2\0\1\255\61\0\1\30\1\76\2\0\1\76\1\0"+ + "\2\76\1\0\1\76\2\0\1\u0369\1\u036a\2\30\1\u03e0"+ + "\32\u036b\13\u036c\1\76\1\u036c\1\u0369\1\u036c\1\0\1\u036c"+ + "\1\u03e1\3\u036c\3\0\1\u036c\3\0\2\u036c\220\0\32\u045c"+ + "\1\0\12\u045c\12\0\1\u045d\227\0\1\u045e\53\0\1\u03e1"+ + "\227\0\2\u036a\2\0\72\u036a\1\0\1\55\1\0\1\56"+ + "\2\0\1\234\1\0\1\60\4\0\1\61\1\0\1\62"+ + "\1\0\1\63\2\0\1\64\3\0\1\235\2\0\1\236"+ + "\4\0\1\67\3\0\1\237\17\0\1\71\2\0\1\240"+ + "\21\0\1\241\2\0\1\242\61\0\1\30\2\75\2\0"+ + "\2\243\1\244\1\0\1\75\2\0\1\u045f\1\0\1\41"+ + "\1\30\1\u0460\32\u036b\1\u036c\12\u03e4\1\0\1\u036c\1\u0461"+ + "\1\u036c\1\0\1\u045f\1\u03e1\3\u036c\2\0\1\243\1\u036c"+ + "\3\0\2\u036c\2\0\1\55\1\0\1\56\2\0\1\256"+ + "\1\0\1\60\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\257\2\0\1\260\4\0\1\67"+ + "\3\0\1\261\17\0\1\71\2\0\1\262\21\0\1\263"+ + "\2\0\1\264\41\0\1\133\17\0\1\30\1\77\1\75"+ + "\1\135\1\76\1\0\1\76\1\77\1\0\1\77\2\0"+ + "\1\u0369\1\0\1\41\1\30\1\u03e0\32\u036b\1\u036c\12\u03e4"+ + "\1\76\1\u036c\1\u03e5\1\u036c\1\0\1\u036c\1\u03e1\3\u036c"+ + "\3\0\1\u036c\3\0\2\u036c\213\0\1\u036c\1\u036a\2\0"+ + "\1\u03e6\45\u036c\1\0\3\u036c\1\0\1\u036c\1\u03e1\3\u036c"+ + "\3\0\1\u036c\3\0\2\u036c\213\0\1\u036d\3\0\1\u036d"+ + "\32\u036e\1\u036d\12\u036e\1\u036f\2\u036d\1\u0370\2\u036d\1\u0371"+ + "\5\0\2\u036d\3\0\1\u036d\214\0\1\u036d\3\0\1\u036d"+ + "\32\u036e\1\u03e8\12\u036e\1\u036f\2\u036d\1\u0370\2\u036d\1\u0371"+ + "\5\0\2\u036d\3\0\1\u036d\214\0\1\u036f\3\0\34\u036f"+ + "\12\u0462\1\0\2\u036f\1\u03ea\2\u036f\1\u0371\5\0\2\u036f"+ + "\3\0\1\u036f\221\0\4\u0463\2\0\1\u0463\15\0\1\u0463"+ + "\6\0\12\u0463\243\0\4\u036d\2\0\1\u036d\15\0\1\u036d"+ + "\6\0\12\u036d\242\0\1\u0464\32\u03ec\1\u0465\12\u03ec\1\u01f9"+ + "\6\0\1\u0228\1\u0229\1\u022a\224\0\1\154\3\0\1\u016f"+ + "\1\371\1\u0466\30\371\1\203\12\371\1\0\3\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\213\0"+ + "\1\154\3\0\1\u016f\17\371\1\u0467\12\371\1\203\12\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\10\371\1\u0468"+ + "\21\371\1\203\12\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\13\371\1\u020a\16\371\1\203\12\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\1\u0469\31\371\1\203\12\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\5\371\1\u046a"+ + "\24\371\1\203\12\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\265\0\1\u0310\242\0"+ + "\4\u046b\2\0\1\u046b\15\0\1\u046b\6\0\12\u046b\1\u03f5"+ + "\242\0\4\u046c\2\0\1\u046c\15\0\1\u046c\6\0\12\u046c"+ + "\1\u046d\242\0\4\u046e\2\0\1\u046e\15\0\1\u046e\6\0"+ + "\12\u046e\1\u046f\12\0\1\u01ad\226\0\1\u0224\4\u046e\2\0"+ + "\1\u046e\15\0\1\u046e\6\0\12\u0470\1\u046f\12\0\1\u01ad"+ + "\226\0\1\u0224\4\u046e\2\0\1\u046e\15\0\1\u046e\6\0"+ + "\12\u0471\1\u046f\12\0\1\u01ad\226\0\1\u0224\4\u046e\2\0"+ + "\1\u046e\15\0\1\u046e\6\0\2\u0471\1\u0470\1\u0471\1\u0472"+ + "\2\u0470\2\u0471\1\u0470\1\u046f\12\0\1\u01ad\227\0\4\u0473"+ + "\2\0\1\u0473\15\0\1\u0473\6\0\12\u0473\1\u0385\12\0"+ + "\1\u01ad\226\0\1\u0224\4\u0473\2\0\1\u0473\15\0\1\u0473"+ + "\6\0\12\u0473\1\u0385\12\0\1\u01ad\262\0\1\u0474\1\u0475"+ + "\5\u0474\1\u0476\1\u0475\1\u0474\242\0\1\u03fc\307\0\1\u03fc"+ + "\33\0\2\u03fd\1\0\2\u03fd\2\0\2\u03fd\243\0\1\u0136"+ + "\20\323\1\u0477\11\323\1\u0137\12\323\242\0\1\u0136\1\323"+ + "\1\u0478\30\323\1\u0137\12\323\242\0\1\u0136\13\323\1\u0237"+ + "\16\323\1\u0137\12\323\242\0\1\u0136\2\323\1\u02c3\27\323"+ + "\1\u0137\12\323\242\0\1\u0136\5\323\1\u0394\24\323\1\u0137"+ + "\12\323\242\0\1\u0136\4\323\1\u0479\25\323\1\u0137\12\323"+ + "\242\0\1\u0136\3\323\1\u047a\26\323\1\u0137\12\323\242\0"+ + "\1\u0136\1\323\1\u02c3\30\323\1\u0137\12\323\242\0\1\u0136"+ + "\4\323\1\u047b\25\323\1\u0137\12\323\242\0\1\u0136\11\323"+ + "\1\u047c\20\323\1\u0137\12\323\242\0\1\u0136\1\323\1\u047d"+ + "\30\323\1\u0137\12\323\242\0\1\u0136\24\323\1\u047e\5\323"+ + "\1\u0137\12\323\242\0\1\u0136\1\323\1\u047f\30\323\1\u0137"+ + "\12\323\242\0\1\u0136\14\323\1\u0480\15\323\1\u0137\12\323"+ + "\242\0\1\u0136\1\323\1\u0481\30\323\1\u0137\12\323\242\0"+ + "\1\u0136\1\323\1\u0482\30\323\1\u0137\12\323\242\0\1\u0136"+ + "\1\323\1\u0483\30\323\1\u0137\12\323\242\0\1\u0136\24\323"+ + "\1\u0484\5\323\1\u0137\12\323\242\0\1\u0136\1\u0485\31\323"+ + "\1\u0137\12\323\242\0\1\u0136\24\323\1\u0486\5\323\1\u0137"+ + "\12\323\242\0\1\u0136\24\323\1\u0487\5\323\1\u0137\12\323"+ + "\242\0\1\u0136\27\323\1\u0488\2\323\1\u0137\12\323\242\0"+ + "\1\u0136\24\323\1\u0489\5\323\1\u0137\12\323\242\0\1\u0136"+ + "\1\u02b7\31\323\1\u0137\12\323\242\0\1\u0136\24\323\1\u0483"+ + "\5\323\1\u0137\12\323\242\0\1\u0136\20\323\1\u048a\11\323"+ + "\1\u0137\12\323\242\0\1\u0136\24\323\1\u048b\5\323\1\u0137"+ + "\12\323\242\0\1\u0136\1\323\1\u048c\30\323\1\u0137\12\323"+ + "\242\0\1\u0136\4\323\1\u048d\25\323\1\u0137\12\323\242\0"+ + "\1\u0136\1\u048e\31\323\1\u0137\12\323\242\0\1\u0136\21\323"+ + "\1\u048f\10\323\1\u0137\12\323\242\0\1\u0136\4\323\1\u0490"+ + "\25\323\1\u0137\12\323\242\0\1\u0136\24\323\1\u0491\5\323"+ + "\1\u0137\12\323\242\0\1\u0136\32\323\1\u0137\1\323\1\u0492"+ + "\10\323\242\0\1\u0136\1\u0493\31\323\1\u0137\12\323\242\0"+ + "\1\u0136\1\u0494\31\323\1\u0137\12\323\242\0\1\u0136\7\323"+ + "\1\u02c3\22\323\1\u0137\12\323\242\0\1\u0136\13\323\1\u022b"+ + "\16\323\1\u0137\12\323\317\0\1\u0228\1\u0229\1\u022a\13\0"+ + "\1\55\1\0\1\56\2\0\1\57\1\0\1\60\4\0"+ + "\1\61\1\0\1\62\1\0\1\63\2\0\1\64\3\0"+ + "\1\65\2\0\1\66\4\0\1\67\3\0\1\70\17\0"+ + "\1\71\2\0\1\72\21\0\1\73\2\0\1\74\61\0"+ + "\2\30\1\75\1\0\1\76\1\0\1\76\1\77\1\0"+ + "\1\30\2\0\1\201\1\0\1\41\1\30\1\202\17\43"+ + "\1\u0495\12\43\1\203\12\204\1\76\1\154\1\205\1\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\2\0\1\55\1\0\1\56\2\0\1\57\1\0\1\60"+ + "\4\0\1\61\1\0\1\62\1\0\1\63\2\0\1\64"+ + "\3\0\1\65\2\0\1\66\4\0\1\67\3\0\1\70"+ + "\17\0\1\71\2\0\1\72\21\0\1\73\2\0\1\74"+ + "\61\0\2\30\1\75\1\0\1\76\1\0\1\76\1\77"+ + "\1\0\1\30\2\0\1\201\1\0\1\41\1\30\1\202"+ + "\5\43\1\u0496\24\43\1\203\12\204\1\76\1\154\1\205"+ + "\1\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\2\0\1\55\1\0\1\56\2\0\1\57\1\0"+ + "\1\60\4\0\1\61\1\0\1\62\1\0\1\63\2\0"+ + "\1\64\3\0\1\65\2\0\1\66\4\0\1\67\3\0"+ + "\1\70\17\0\1\71\2\0\1\72\21\0\1\73\2\0"+ + "\1\74\61\0\2\30\1\75\1\0\1\76\1\0\1\76"+ + "\1\77\1\0\1\30\2\0\1\201\1\0\1\41\1\30"+ + "\1\202\16\43\1\u02d8\13\43\1\203\12\204\1\76\1\154"+ + "\1\205\1\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\2\0\1\55\1\0\1\56\2\0\1\57"+ + "\1\0\1\60\4\0\1\61\1\0\1\62\1\0\1\63"+ + "\2\0\1\64\3\0\1\65\2\0\1\66\4\0\1\67"+ + "\3\0\1\70\17\0\1\71\2\0\1\72\21\0\1\73"+ + "\2\0\1\74\61\0\2\30\1\75\1\0\1\76\1\0"+ + "\1\76\1\77\1\0\1\30\2\0\1\201\1\0\1\41"+ + "\1\30\1\202\15\43\1\u0497\14\43\1\203\12\204\1\76"+ + "\1\154\1\205\1\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\2\0\1\55\1\0\1\56\2\0"+ + "\1\57\1\0\1\60\4\0\1\61\1\0\1\62\1\0"+ + "\1\63\2\0\1\64\3\0\1\65\2\0\1\66\4\0"+ + "\1\67\3\0\1\70\17\0\1\71\2\0\1\72\21\0"+ + "\1\73\2\0\1\74\61\0\2\30\1\75\1\0\1\76"+ + "\1\0\1\76\1\77\1\0\1\30\2\0\1\201\1\0"+ + "\1\41\1\30\1\202\7\43\1\u01e7\22\43\1\203\12\204"+ + "\1\76\1\154\1\205\1\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\1\371\1\u0498\30\371\1\203\12\371\1\0\3\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\213\0"+ + "\1\154\3\0\1\u016f\6\371\1\u0499\23\371\1\203\12\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\32\371\1\203"+ + "\3\371\1\u0444\6\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\32\371\1\203\6\371\1\u0213\3\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\32\371\1\203\5\371\1\u0213"+ + "\4\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\27\371"+ + "\1\u049a\2\371\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\1\371\1\u049b\30\371\1\203\12\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\27\371\1\u049c\2\371"+ + "\1\203\12\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\1\u049d\31\371\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\1\371\1\u0174\30\371\1\203\12\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\1\u049e\30\371\1\u049f"+ + "\1\203\1\u04a0\11\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\32\371\1\203\1\371\1\u04a1\10\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\4\371\1\u04a2\25\371\1\203"+ + "\12\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\32\371"+ + "\1\203\3\371\1\u04a3\6\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\25\371\1\u04a4\4\371\1\203\12\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\1\u04a5\31\371\1\203"+ + "\12\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\32\371"+ + "\1\203\4\371\1\u04a6\5\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\24\371\1\u04a7\5\371\1\203\12\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\32\371\1\203\1\371"+ + "\1\u04a8\10\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\32\371\1\203\3\371\1\u020d\6\371\1\0\3\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\213\0"+ + "\1\154\3\0\1\u016f\32\371\1\203\11\371\1\u010f\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\32\371\1\203\10\371"+ + "\1\u0434\1\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\1\u04a9\1\371\1\u04aa\27\371\1\203\12\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\32\371\1\203\10\371\1\u04ab"+ + "\1\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\32\371"+ + "\1\203\4\371\1\u04ac\5\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\25\371\1\u0174\4\371\1\203\12\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\32\371\1\203\5\371"+ + "\1\u04ad\4\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\32\371\1\203\3\371\1\u04ae\6\371\1\0\3\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\213\0"+ + "\1\154\3\0\1\u016f\32\371\1\203\7\371\1\u04af\2\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\32\371\1\203"+ + "\2\371\1\u04b0\7\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\1\u0434\31\371\1\203\12\371\1\0\3\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\213\0"+ + "\1\154\3\0\1\u016f\32\371\1\203\7\371\1\u04b1\2\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\3\371\1\u04b2"+ + "\15\371\1\u0180\10\371\1\203\12\371\1\0\3\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\220\0"+ + "\4\u035e\2\0\1\u035e\15\0\1\u035e\6\0\12\u035e\243\0"+ + "\4\u04b3\2\0\1\u04b3\15\0\1\u04b3\6\0\12\u04b3\1\u044e"+ + "\242\0\4\u04b4\2\0\1\u04b4\15\0\1\u04b4\6\0\12\u04b4"+ + "\1\u04b5\242\0\4\u04b6\2\0\1\u04b6\15\0\1\u04b6\6\0"+ + "\1\u04b7\1\u04b8\5\u04b7\1\u04b9\1\u04b8\1\u04b7\13\0\1\u04ba"+ + "\222\0\1\u02f5\3\0\34\u02f5\12\u04bb\1\0\2\u02f5\1\u0364"+ + "\2\u02f5\1\u02f7\1\0\1\u0363\3\0\2\u02f5\3\0\1\u02f5"+ + "\221\0\4\u0363\2\0\1\u0363\15\0\1\u0363\6\0\12\u0363"+ + "\274\0\1\u04bc\311\0\12\u04bd\10\0\1\u0363\232\0\4\u04be"+ + "\2\0\1\u04be\15\0\1\u04be\6\0\12\u04be\1\u03de\242\0"+ + "\4\u04bf\2\0\1\u04bf\15\0\1\u04bf\6\0\12\u04bf\1\u04c0"+ + "\242\0\4\u04c1\2\0\1\u04c1\15\0\1\u04c1\6\0\1\u04c2"+ + "\1\u04c3\5\u04c2\1\u04c4\1\u04c3\1\u04c2\13\0\1\u045b\227\0"+ + "\4\u04c5\2\0\1\u04c5\15\0\1\u04c5\6\0\12\u04c5\1\u04c6"+ + "\12\0\1\u045b\226\0\1\u04c7\4\u04c5\2\0\1\u04c5\15\0"+ + "\1\u04c5\6\0\12\u04c8\1\u04c6\12\0\1\u045b\226\0\1\u04c7"+ + "\4\u04c5\2\0\1\u04c5\15\0\1\u04c5\6\0\12\u04c9\1\u04c6"+ + "\12\0\1\u045b\226\0\1\u04c7\4\u04c5\2\0\1\u04c5\15\0"+ + "\1\u04c5\6\0\2\u04c9\1\u04c8\1\u04c9\1\u04ca\2\u04c8\2\u04c9"+ + "\1\u04c8\1\u04c6\12\0\1\u045b\274\0\1\u03dc\7\0\1\u0363"+ + "\231\0\1\u04cb\32\u045c\1\u04cc\12\u045c\236\0\2\u045d\2\0"+ + "\60\u045d\1\0\1\u04cd\3\u045d\1\u04ce\1\0\3\u045d\212\0"+ + "\1\u036c\1\u036a\2\0\46\u036c\1\0\3\u036c\1\0\1\u036c"+ + "\1\0\3\u036c\3\0\1\u036c\3\0\2\u036c\7\0\1\u0126"+ + "\1\0\1\u0127\17\0\1\u0128\2\0\1\u0129\4\0\1\u012a"+ + "\3\0\1\u012b\22\0\1\u012c\21\0\1\u012d\2\0\1\u012e"+ + "\62\0\1\243\1\75\2\0\3\243\1\0\1\243\2\0"+ + "\1\u045f\3\0\1\u0460\33\u036c\12\u03e4\1\0\1\u036c\1\u045f"+ + "\1\u036c\1\0\1\u045f\1\u03e1\3\u036c\2\0\1\243\1\u036c"+ + "\3\0\2\u036c\7\0\1\u0126\1\0\1\u0127\17\0\1\u0128"+ + "\2\0\1\u0129\4\0\1\u012a\3\0\1\u012b\22\0\1\u012c"+ + "\21\0\1\u012d\2\0\1\u012e\62\0\1\243\1\75\2\0"+ + "\3\243\1\0\1\243\2\0\1\u045f\1\u036a\2\0\1\u0460"+ + "\33\u036c\12\u03e4\1\0\1\u036c\1\u045f\1\u036c\1\0\1\u045f"+ + "\1\u03e1\3\u036c\2\0\1\243\1\u036c\3\0\2\u036c\2\0"+ + "\1\55\1\0\1\56\2\0\1\u012f\1\0\1\60\4\0"+ + "\1\61\1\0\1\62\1\0\1\63\2\0\1\64\3\0"+ + "\1\u0130\2\0\1\u0131\4\0\1\67\3\0\1\u0132\17\0"+ + "\1\71\2\0\1\u0133\21\0\1\u0134\2\0\1\u0135\41\0"+ + "\1\133\17\0\1\30\1\244\1\75\1\135\1\0\2\243"+ + "\1\244\1\0\1\244\2\0\1\u045f\1\0\1\41\1\30"+ + "\1\u0460\32\u036b\1\u036c\12\u03e4\1\0\1\u036c\1\u0461\1\u036c"+ + "\1\0\1\u045f\1\u03e1\3\u036c\2\0\1\243\1\u036c\3\0"+ + "\2\u036c\213\0\1\u036f\3\0\34\u036f\12\u04cf\1\0\2\u036f"+ + "\1\u03ea\2\u036f\1\u0371\1\u0228\1\u0229\1\u022a\2\0\2\u036f"+ + "\3\0\1\u036f\221\0\4\u036f\2\0\1\u036f\15\0\1\u036f"+ + "\6\0\12\u036f\243\0\32\u03ec\1\0\12\u03ec\243\0\32\u03ec"+ + "\1\u0465\12\u03ec\236\0\1\154\3\0\1\u016f\17\371\1\u04d0"+ + "\12\371\1\203\12\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\5\371\1\u04d1\24\371\1\203\12\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\16\371\1\u0306\13\371\1\203"+ + "\12\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\15\371"+ + "\1\u04d2\14\371\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\7\371\1\u020d\22\371\1\203\12\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\220\0\4\u04d3\2\0\1\u04d3\15\0\1\u04d3\6\0"+ + "\12\u04d3\1\u03f5\242\0\4\u04d4\2\0\1\u04d4\15\0\1\u04d4"+ + "\6\0\12\u04d4\1\u04d5\242\0\4\u04d6\2\0\1\u04d6\15\0"+ + "\1\u04d6\6\0\1\u04d7\1\u04d8\5\u04d7\1\u04d9\1\u04d8\1\u04d7"+ + "\13\0\1\u01ad\227\0\4\u04da\2\0\1\u04da\15\0\1\u04da"+ + "\6\0\12\u04da\1\u046f\12\0\1\u01ad\227\0\4\u04d6\2\0"+ + "\1\u04d6\15\0\1\u04d6\6\0\1\u04d7\1\u04d8\5\u04d7\1\u04d9"+ + "\1\u04d8\1\u04d7\242\0\1\u0224\4\u04da\2\0\1\u04da\15\0"+ + "\1\u04da\6\0\12\u04da\1\u046f\12\0\1\u01ad\226\0\1\u0224"+ + "\4\u04da\2\0\1\u04da\15\0\1\u04da\6\0\12\u04db\1\u046f"+ + "\12\0\1\u01ad\226\0\1\u0224\4\u04da\2\0\1\u04da\15\0"+ + "\1\u04da\6\0\2\u04db\1\u04da\2\u04db\2\u04da\2\u04db\1\u04da"+ + "\1\u046f\12\0\1\u01ad\274\0\1\u0385\12\0\1\u01ad\262\0"+ + "\12\u04dc\13\0\1\u01ad\262\0\12\u0474\13\0\1\u01ad\262\0"+ + "\2\u0474\1\u04dc\1\u0474\1\u04dd\2\u04dc\2\u0474\1\u04dc\13\0"+ + "\1\u01ad\226\0\1\u0136\1\323\1\u04de\30\323\1\u0137\12\323"+ + "\242\0\1\u0136\17\323\1\u04df\12\323\1\u0137\12\323\242\0"+ + "\1\u0136\10\323\1\u04e0\21\323\1\u0137\12\323\242\0\1\u0136"+ + "\13\323\1\u02ba\16\323\1\u0137\12\323\242\0\1\u0136\1\u04e1"+ + "\31\323\1\u0137\12\323\242\0\1\u0136\5\323\1\u04e2\24\323"+ + "\1\u0137\12\323\242\0\1\u0136\25\323\1\u04e3\4\323\1\u0137"+ + "\12\323\242\0\1\u0136\15\323\1\u04e4\14\323\1\u0137\12\323"+ + "\242\0\1\u0136\21\323\1\u04e5\10\323\1\u0137\12\323\242\0"+ + "\1\u0136\16\323\1\u04e6\4\323\1\u04e7\6\323\1\u0137\12\323"+ + "\242\0\1\u0136\4\323\1\u04e8\25\323\1\u0137\12\323\242\0"+ + "\1\u0136\32\323\1\u0137\7\323\1\u04e9\2\323\242\0\1\u0136"+ + "\4\323\1\u04ea\25\323\1\u0137\12\323\242\0\1\u0136\24\323"+ + "\1\u04eb\5\323\1\u0137\12\323\242\0\1\u0136\1\323\1\u04ec"+ + "\30\323\1\u0137\12\323\242\0\1\u0136\1\u04ed\1\u04ee\1\323"+ + "\1\u04ef\16\323\1\u04f0\1\323\1\u04f1\5\323\1\u0137\5\323"+ + "\1\u04f2\4\323\242\0\1\u0136\1\323\1\u04f3\30\323\1\u0137"+ + "\12\323\242\0\1\u0136\31\323\1\u04f4\1\u0137\12\323\242\0"+ + "\1\u0136\16\323\1\u04f5\13\323\1\u0137\12\323\242\0\1\u0136"+ + "\15\323\1\u04f6\14\323\1\u0137\12\323\242\0\1\u0136\11\323"+ + "\1\u04f7\13\323\1\u04f8\4\323\1\u0137\12\323\242\0\1\u0136"+ + "\32\323\1\u0137\7\323\1\u04f9\2\323\242\0\1\u0136\21\323"+ + "\1\u04fa\7\323\1\u04fb\1\u0137\12\323\242\0\1\u0136\12\323"+ + "\1\u04fc\17\323\1\u0137\12\323\242\0\1\u0136\32\323\1\u0137"+ + "\10\323\1\u04fd\1\323\242\0\1\u0136\5\323\1\u04fe\24\323"+ + "\1\u0137\12\323\242\0\1\u0136\10\323\1\u04ff\21\323\1\u0137"+ + "\12\323\242\0\1\u0136\24\323\1\u0500\5\323\1\u0137\12\323"+ + "\242\0\1\u0136\32\323\1\u0137\1\u0501\11\323\242\0\1\u0136"+ + "\5\323\1\u0502\10\323\1\u0503\13\323\1\u0137\12\323\25\0"+ + "\1\55\1\0\1\56\2\0\1\57\1\0\1\60\4\0"+ + "\1\61\1\0\1\62\1\0\1\63\2\0\1\64\3\0"+ + "\1\65\2\0\1\66\4\0\1\67\3\0\1\70\17\0"+ + "\1\71\2\0\1\72\21\0\1\73\2\0\1\74\61\0"+ + "\2\30\1\75\1\0\1\76\1\0\1\76\1\77\1\0"+ + "\1\30\2\0\1\201\1\0\1\41\1\30\1\202\10\43"+ + "\1\u0504\21\43\1\203\12\204\1\76\1\154\1\205\1\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\2\0\1\55\1\0\1\56\2\0\1\57\1\0\1\60"+ + "\4\0\1\61\1\0\1\62\1\0\1\63\2\0\1\64"+ + "\3\0\1\65\2\0\1\66\4\0\1\67\3\0\1\70"+ + "\17\0\1\71\2\0\1\72\21\0\1\73\2\0\1\74"+ + "\61\0\2\30\1\75\1\0\1\76\1\0\1\76\1\77"+ + "\1\0\1\30\2\0\1\201\1\0\1\41\1\30\1\202"+ + "\4\43\1\u01ed\25\43\1\203\12\204\1\76\1\154\1\205"+ + "\1\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\2\0\1\55\1\0\1\56\2\0\1\57\1\0"+ + "\1\60\4\0\1\61\1\0\1\62\1\0\1\63\2\0"+ + "\1\64\3\0\1\65\2\0\1\66\4\0\1\67\3\0"+ + "\1\70\17\0\1\71\2\0\1\72\21\0\1\73\2\0"+ + "\1\74\61\0\2\30\1\75\1\0\1\76\1\0\1\76"+ + "\1\77\1\0\1\30\2\0\1\201\1\0\1\41\1\30"+ + "\1\202\25\43\1\u01e7\4\43\1\203\12\204\1\76\1\154"+ + "\1\205\1\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\32\371\1\203"+ + "\1\371\1\u0505\10\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\32\371\1\203\6\371\1\u0506\3\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\32\371\1\203\5\371\1\u0507"+ + "\4\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\32\371"+ + "\1\203\5\371\1\u0508\4\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\32\371\1\203\5\371\1\u0434\4\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\17\371\1\u0509\12\371"+ + "\1\203\12\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\12\371\1\u050a\17\371\1\203\12\371\1\0\3\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\213\0"+ + "\1\154\3\0\1\u016f\25\371\1\u050b\4\371\1\203\12\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\1\u050c\31\371"+ + "\1\203\12\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\1\u050d\31\371\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\15\371\1\u050e\14\371\1\203\12\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\1\371\1\u050f\30\371"+ + "\1\203\12\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\32\371\1\203\10\371\1\u0510\1\371\1\0\3\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\213\0"+ + "\1\154\3\0\1\u016f\21\371\1\u0511\10\371\1\203\12\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\1\u0512\31\371"+ + "\1\203\12\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\32\371\1\203\3\371\1\u0434\6\371\1\0\3\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\213\0"+ + "\1\154\3\0\1\u016f\2\371\1\u0444\27\371\1\203\12\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\11\371\1\u0513"+ + "\20\371\1\203\12\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\11\371\1\u0514\20\371\1\203\12\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\32\371\1\203\1\u0205\11\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\32\371\1\203"+ + "\2\371\1\u0205\7\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\32\371\1\203\1\u0180\11\371\1\0\3\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\213\0"+ + "\1\154\3\0\1\u016f\10\371\1\u0515\21\371\1\203\12\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\1\u0516\31\371"+ + "\1\203\12\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\32\371\1\203\1\371\1\u0517\10\371\1\0\3\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\213\0"+ + "\1\154\3\0\1\u016f\32\371\1\203\10\371\1\u010f\1\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\25\371\1\u0518"+ + "\4\371\1\203\12\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\220\0\4\u0519\2\0"+ + "\1\u0519\15\0\1\u0519\6\0\12\u0519\1\u044e\242\0\4\u051a"+ + "\2\0\1\u051a\15\0\1\u051a\6\0\12\u051a\1\u051b\242\0"+ + "\4\u051c\2\0\1\u051c\15\0\1\u051c\6\0\1\u051d\1\u051e"+ + "\5\u051d\1\u051f\1\u051e\1\u051d\13\0\1\u04ba\227\0\4\u0520"+ + "\2\0\1\u0520\15\0\1\u0520\6\0\12\u0520\1\u0521\12\0"+ + "\1\u04ba\226\0\1\u0522\4\u0520\2\0\1\u0520\15\0\1\u0520"+ + "\6\0\12\u0523\1\u0521\12\0\1\u04ba\226\0\1\u0522\4\u0520"+ + "\2\0\1\u0520\15\0\1\u0520\6\0\12\u0524\1\u0521\12\0"+ + "\1\u04ba\226\0\1\u0522\4\u0520\2\0\1\u0520\15\0\1\u0520"+ + "\6\0\2\u0524\1\u0523\1\u0524\1\u0525\2\u0523\2\u0524\1\u0523"+ + "\1\u0521\12\0\1\u04ba\304\0\1\u035e\225\0\1\u02f5\3\0"+ + "\34\u02f5\12\u0526\1\0\2\u02f5\1\u0364\2\u02f5\1\u02f7\1\0"+ + "\1\u0363\3\0\2\u02f5\3\0\1\u02f5\236\0\1\u0527\325\0"+ + "\12\u0528\10\0\1\u0363\277\0\1\u03de\242\0\4\u0529\2\0"+ + "\1\u0529\15\0\1\u0529\6\0\12\u0529\1\u04c0\242\0\4\u052a"+ + "\2\0\1\u052a\15\0\1\u052a\6\0\12\u052a\1\u052b\242\0"+ + "\4\u052c\2\0\1\u052c\15\0\1\u052c\6\0\12\u052c\1\u052d"+ + "\12\0\1\u045b\226\0\1\u04c7\4\u052c\2\0\1\u052c\15\0"+ + "\1\u052c\6\0\12\u052e\1\u052d\12\0\1\u045b\226\0\1\u04c7"+ + "\4\u052c\2\0\1\u052c\15\0\1\u052c\6\0\12\u052f\1\u052d"+ + "\12\0\1\u045b\226\0\1\u04c7\4\u052c\2\0\1\u052c\15\0"+ + "\1\u052c\6\0\2\u052f\1\u052e\1\u052f\1\u0530\2\u052e\2\u052f"+ + "\1\u052e\1\u052d\12\0\1\u045b\227\0\4\u0531\2\0\1\u0531"+ + "\15\0\1\u0531\6\0\12\u0531\1\u04c6\12\0\1\u045b\227\0"+ + "\4\u04c1\2\0\1\u04c1\15\0\1\u04c1\6\0\1\u04c2\1\u04c3"+ + "\5\u04c2\1\u04c4\1\u04c3\1\u04c2\276\0\1\u0532\1\u0533\5\u0532"+ + "\1\u0534\1\u0533\1\u0532\242\0\1\u04c7\4\u0531\2\0\1\u0531"+ + "\15\0\1\u0531\6\0\12\u0531\1\u04c6\12\0\1\u045b\226\0"+ + "\1\u04c7\4\u0531\2\0\1\u0531\15\0\1\u0531\6\0\12\u0535"+ + "\1\u04c6\12\0\1\u045b\226\0\1\u04c7\4\u0531\2\0\1\u0531"+ + "\15\0\1\u0531\6\0\2\u0535\1\u0531\2\u0535\2\u0531\2\u0535"+ + "\1\u0531\1\u04c6\12\0\1\u045b\227\0\1\u0536\1\u0537\1\u0538"+ + "\1\u0539\1\u053a\1\u053b\1\u053c\1\u053d\1\u053e\1\u053f\1\u0540"+ + "\1\u0541\1\u0542\1\u0543\1\u0544\1\u0545\1\u0546\1\u0547\1\u0548"+ + "\1\u0549\1\u054a\1\u054b\1\u054c\1\u054d\1\u054e\1\u054f\1\0"+ + "\12\u045c\243\0\32\u045c\1\u04cc\12\u045c\236\0\2\u045d\2\0"+ + "\72\u045d\212\0\1\u036f\3\0\34\u036f\12\u0550\1\0\2\u036f"+ + "\1\u03ea\2\u036f\1\u0371\1\u0228\1\u0229\1\u022a\2\0\2\u036f"+ + "\3\0\1\u036f\214\0\1\154\3\0\1\u016f\10\371\1\u0551"+ + "\21\371\1\203\12\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\4\371\1\u0213\25\371\1\203\12\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\25\371\1\u020d\4\371\1\203"+ + "\12\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\265\0\1\u03f5\242\0\4\u0552\2\0"+ + "\1\u0552\15\0\1\u0552\6\0\12\u0552\1\u04d5\242\0\4\u0553"+ + "\2\0\1\u0553\15\0\1\u0553\6\0\12\u0553\1\u0554\242\0"+ + "\4\u0555\2\0\1\u0555\15\0\1\u0555\6\0\12\u0555\1\u0556"+ + "\12\0\1\u01ad\226\0\1\u0224\4\u0555\2\0\1\u0555\15\0"+ + "\1\u0555\6\0\12\u0557\1\u0556\12\0\1\u01ad\226\0\1\u0224"+ + "\4\u0555\2\0\1\u0555\15\0\1\u0555\6\0\12\u0558\1\u0556"+ + "\12\0\1\u01ad\226\0\1\u0224\4\u0555\2\0\1\u0555\15\0"+ + "\1\u0555\6\0\2\u0558\1\u0557\1\u0558\1\u0559\2\u0557\2\u0558"+ + "\1\u0557\1\u0556\12\0\1\u01ad\227\0\4\u055a\2\0\1\u055a"+ + "\15\0\1\u055a\6\0\12\u055a\1\u046f\12\0\1\u01ad\226\0"+ + "\1\u0224\4\u055a\2\0\1\u055a\15\0\1\u055a\6\0\12\u055a"+ + "\1\u046f\12\0\1\u01ad\307\0\1\u01ad\262\0\2\u04dc\1\0"+ + "\2\u04dc\2\0\2\u04dc\14\0\1\u01ad\226\0\1\u0136\17\323"+ + "\1\u055b\12\323\1\u0137\12\323\242\0\1\u0136\5\323\1\u055c"+ + "\24\323\1\u0137\12\323\242\0\1\u0136\16\323\1\u0398\13\323"+ + "\1\u0137\12\323\242\0\1\u0136\15\323\1\u055d\14\323\1\u0137"+ + "\12\323\242\0\1\u0136\7\323\1\u02bd\22\323\1\u0137\12\323"+ + "\242\0\1\u0136\1\323\1\u055e\30\323\1\u0137\12\323\242\0"+ + "\1\u0136\6\323\1\u055f\23\323\1\u0137\12\323\242\0\1\u0136"+ + "\32\323\1\u0137\3\323\1\u04fc\6\323\242\0\1\u0136\32\323"+ + "\1\u0137\6\323\1\u02c3\3\323\242\0\1\u0136\32\323\1\u0137"+ + "\5\323\1\u02c3\4\323\242\0\1\u0136\27\323\1\u0560\2\323"+ + "\1\u0137\12\323\242\0\1\u0136\1\323\1\u0561\30\323\1\u0137"+ + "\12\323\242\0\1\u0136\27\323\1\u0562\2\323\1\u0137\12\323"+ + "\242\0\1\u0136\1\u0563\31\323\1\u0137\12\323\242\0\1\u0136"+ + "\1\323\1\u022b\30\323\1\u0137\12\323\242\0\1\u0136\1\u0564"+ + "\30\323\1\u0565\1\u0137\1\u0566\11\323\242\0\1\u0136\32\323"+ + "\1\u0137\1\323\1\u0567\10\323\242\0\1\u0136\4\323\1\u0568"+ + "\25\323\1\u0137\12\323\242\0\1\u0136\32\323\1\u0137\3\323"+ + "\1\u0569\6\323\242\0\1\u0136\25\323\1\u056a\4\323\1\u0137"+ + "\12\323\242\0\1\u0136\1\u056b\31\323\1\u0137\12\323\242\0"+ + "\1\u0136\32\323\1\u0137\4\323\1\u056c\5\323\242\0\1\u0136"+ + "\24\323\1\u056d\5\323\1\u0137\12\323\242\0\1\u0136\32\323"+ + "\1\u0137\1\323\1\u056e\10\323\242\0\1\u0136\32\323\1\u0137"+ + "\3\323\1\u02bd\6\323\242\0\1\u0136\32\323\1\u0137\11\323"+ + "\1\u01c1\242\0\1\u0136\32\323\1\u0137\10\323\1\u04ec\1\323"+ + "\242\0\1\u0136\1\u056f\1\323\1\u0570\27\323\1\u0137\12\323"+ + "\242\0\1\u0136\32\323\1\u0137\10\323\1\u0571\1\323\242\0"+ + "\1\u0136\32\323\1\u0137\4\323\1\u0572\5\323\242\0\1\u0136"+ + "\25\323\1\u022b\4\323\1\u0137\12\323\242\0\1\u0136\32\323"+ + "\1\u0137\5\323\1\u0573\4\323\242\0\1\u0136\32\323\1\u0137"+ + "\3\323\1\u0574\6\323\242\0\1\u0136\32\323\1\u0137\7\323"+ + "\1\u0575\2\323\242\0\1\u0136\32\323\1\u0137\2\323\1\u0576"+ + "\7\323\242\0\1\u0136\1\u04ec\31\323\1\u0137\12\323\242\0"+ + "\1\u0136\32\323\1\u0137\7\323\1\u0577\2\323\242\0\1\u0136"+ + "\3\323\1\u0578\15\323\1\u0237\10\323\1\u0137\12\323\25\0"+ + "\1\55\1\0\1\56\2\0\1\57\1\0\1\60\4\0"+ + "\1\61\1\0\1\62\1\0\1\63\2\0\1\64\3\0"+ + "\1\65\2\0\1\66\4\0\1\67\3\0\1\70\17\0"+ + "\1\71\2\0\1\72\21\0\1\73\2\0\1\74\61\0"+ + "\2\30\1\75\1\0\1\76\1\0\1\76\1\77\1\0"+ + "\1\30\2\0\1\201\1\0\1\41\1\30\1\202\5\43"+ + "\1\u035c\24\43\1\203\12\204\1\76\1\154\1\205\1\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\3\371\1\u0579\26\371\1\203"+ + "\12\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\6\371"+ + "\1\u018a\23\371\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\1\371\1\u04ab\30\371\1\203\12\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\3\371\1\u057a\26\371"+ + "\1\203\12\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\32\371\1\203\10\371\1\u057b\1\371\1\0\3\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\213\0"+ + "\1\154\3\0\1\u016f\32\371\1\203\2\371\1\u057c\7\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\32\371\1\203"+ + "\2\371\1\u057d\7\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\32\371\1\203\3\371\1\u057e\6\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\32\371\1\203\5\371\1\u057f"+ + "\4\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\32\371"+ + "\1\203\3\371\1\u0580\6\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\2\371\1\u0581\27\371\1\203\12\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\1\u0582\31\371\1\203"+ + "\12\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\24\371"+ + "\1\u0583\5\371\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\23\371\1\u0205\6\371\1\203\12\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\32\371\1\203\1\u0584"+ + "\11\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\32\371"+ + "\1\203\1\u0585\11\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\32\371\1\203\11\371\1\u0586\1\0\3\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\213\0"+ + "\1\154\3\0\1\u016f\12\371\1\u0587\17\371\1\203\12\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\32\371\1\203"+ + "\2\371\1\u0209\7\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\2\371\1\u0588\27\371\1\203\12\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\265\0\1\u044e\242\0\4\u0589\2\0\1\u0589\15\0\1\u0589"+ + "\6\0\12\u0589\1\u051b\242\0\4\u058a\2\0\1\u058a\15\0"+ + "\1\u058a\6\0\12\u058a\1\u058b\242\0\4\u058c\2\0\1\u058c"+ + "\15\0\1\u058c\6\0\12\u058c\1\u058d\12\0\1\u04ba\226\0"+ + "\1\u0522\4\u058c\2\0\1\u058c\15\0\1\u058c\6\0\12\u058e"+ + "\1\u058d\12\0\1\u04ba\226\0\1\u0522\4\u058c\2\0\1\u058c"+ + "\15\0\1\u058c\6\0\12\u058f\1\u058d\12\0\1\u04ba\226\0"+ + "\1\u0522\4\u058c\2\0\1\u058c\15\0\1\u058c\6\0\2\u058f"+ + "\1\u058e\1\u058f\1\u0590\2\u058e\2\u058f\1\u058e\1\u058d\12\0"+ + "\1\u04ba\227\0\4\u0591\2\0\1\u0591\15\0\1\u0591\6\0"+ + "\12\u0591\1\u0521\12\0\1\u04ba\227\0\4\u051c\2\0\1\u051c"+ + "\15\0\1\u051c\6\0\1\u051d\1\u051e\5\u051d\1\u051f\1\u051e"+ + "\1\u051d\276\0\1\u0592\1\u0593\5\u0592\1\u0594\1\u0593\1\u0592"+ + "\242\0\1\u0522\4\u0591\2\0\1\u0591\15\0\1\u0591\6\0"+ + "\12\u0591\1\u0521\12\0\1\u04ba\226\0\1\u0522\4\u0591\2\0"+ + "\1\u0591\15\0\1\u0591\6\0\12\u0595\1\u0521\12\0\1\u04ba"+ + "\226\0\1\u0522\4\u0591\2\0\1\u0591\15\0\1\u0591\6\0"+ + "\2\u0595\1\u0591\2\u0595\2\u0591\2\u0595\1\u0591\1\u0521\12\0"+ + "\1\u04ba\222\0\1\u02f5\3\0\34\u02f5\12\u0596\1\0\2\u02f5"+ + "\1\u0364\2\u02f5\1\u02f7\1\0\1\u0363\3\0\2\u02f5\3\0"+ + "\1\u02f5\224\0\1\u0597\337\0\12\u0598\10\0\1\u0363\232\0"+ + "\4\u0599\2\0\1\u0599\15\0\1\u0599\6\0\12\u0599\1\u04c0"+ + "\242\0\4\u059a\2\0\1\u059a\15\0\1\u059a\6\0\12\u059a"+ + "\1\u059b\242\0\4\u059c\2\0\1\u059c\15\0\1\u059c\6\0"+ + "\1\u059d\1\u059e\5\u059d\1\u059f\1\u059e\1\u059d\13\0\1\u045b"+ + "\227\0\4\u05a0\2\0\1\u05a0\15\0\1\u05a0\6\0\12\u05a0"+ + "\1\u052d\12\0\1\u045b\227\0\4\u059c\2\0\1\u059c\15\0"+ + "\1\u059c\6\0\1\u059d\1\u059e\5\u059d\1\u059f\1\u059e\1\u059d"+ + "\242\0\1\u04c7\4\u05a0\2\0\1\u05a0\15\0\1\u05a0\6\0"+ + "\12\u05a0\1\u052d\12\0\1\u045b\226\0\1\u04c7\4\u05a0\2\0"+ + "\1\u05a0\15\0\1\u05a0\6\0\12\u05a1\1\u052d\12\0\1\u045b"+ + "\226\0\1\u04c7\4\u05a0\2\0\1\u05a0\15\0\1\u05a0\6\0"+ + "\2\u05a1\1\u05a0\2\u05a1\2\u05a0\2\u05a1\1\u05a0\1\u052d\12\0"+ + "\1\u045b\227\0\4\u05a2\2\0\1\u05a2\15\0\1\u05a2\6\0"+ + "\12\u05a2\1\u04c6\12\0\1\u045b\226\0\1\u05a3\33\0\12\u05a4"+ + "\242\0\1\u05a3\33\0\12\u0532\242\0\1\u05a3\33\0\2\u0532"+ + "\1\u05a4\1\u0532\1\u05a5\2\u05a4\2\u0532\1\u05a4\242\0\1\u04c7"+ + "\4\u05a2\2\0\1\u05a2\15\0\1\u05a2\6\0\12\u05a2\1\u04c6"+ + "\12\0\1\u045b\226\0\1\u04cb\1\u045c\2\u05a6\1\u05a7\1\u05a8"+ + "\10\u05a6\1\u045c\1\u05a9\5\u05a6\6\u045c\1\u04cc\12\u045c\242\0"+ + "\1\u04cb\1\u05aa\2\u05a6\1\u045c\1\u05a6\1\u05ab\3\u05a6\1\u05ac"+ + "\2\u05a6\4\u045c\4\u05a6\1\u045c\2\u05a6\1\u045c\2\u05a6\1\u04cc"+ + "\12\u045c\242\0\1\u04cb\3\u045c\1\u05a6\1\u045c\1\u05a6\2\u045c"+ + "\1\u05ad\1\u045c\1\u05a6\10\u045c\1\u05a6\2\u045c\2\u05a6\2\u045c"+ + "\1\u04cc\12\u045c\242\0\1\u04cb\1\u045c\1\u05a6\1\u05ae\2\u05a6"+ + "\2\u045c\1\u05a6\3\u045c\1\u05af\1\u05b0\1\u045c\1\u05b1\2\u05a6"+ + "\11\u045c\1\u04cc\12\u045c\242\0\1\u04cb\3\u045c\1\u05a6\1\u045c"+ + "\1\u05a6\10\u045c\1\u05a6\1\u045c\2\u05a6\10\u045c\1\u04cc\12\u045c"+ + "\242\0\1\u04cb\4\u045c\1\u05b2\5\u045c\1\u05a6\17\u045c\1\u04cc"+ + "\12\u045c\242\0\1\u04cb\4\u045c\2\u05a6\2\u045c\1\u05a6\1\u045c"+ + "\1\u05a6\13\u045c\2\u05a6\2\u045c\1\u04cc\12\u045c\242\0\1\u04cb"+ + "\1\u05b3\1\u045c\2\u05a6\1\u05b4\1\u05b5\12\u05a6\1\u05b6\1\u05a6"+ + "\2\u045c\2\u05a6\3\u045c\1\u05a6\1\u04cc\12\u045c\242\0\1\u04cb"+ + "\2\u045c\4\u05a6\3\u045c\2\u05a6\1\u05b7\1\u05a6\1\u045c\2\u05a6"+ + "\12\u045c\1\u04cc\12\u045c\242\0\1\u04cb\1\u05b8\1\u05a6\2\u045c"+ + "\1\u05a6\3\u045c\1\u05b9\5\u045c\3\u05a6\3\u045c\1\u05a6\1\u045c"+ + "\1\u05a6\1\u045c\2\u05a6\1\u04cc\12\u045c\242\0\1\u04cb\3\u05a6"+ + "\1\u05ba\1\u05a6\1\u05bb\1\u045c\1\u05a6\1\u05bc\7\u05a6\1\u05bd"+ + "\3\u05a6\1\u045c\2\u05a6\1\u045c\2\u05a6\1\u04cc\12\u045c\242\0"+ + "\1\u04cb\1\u05be\1\u05a6\1\u045c\1\u05bf\6\u05a6\3\u045c\1\u05a6"+ + "\2\u045c\1\u05a6\2\u045c\1\u05a6\6\u045c\1\u04cc\12\u045c\242\0"+ + "\1\u04cb\1\u05a6\31\u045c\1\u04cc\12\u045c\242\0\1\u04cb\1\u05a6"+ + "\2\u045c\1\u05a6\1\u05c0\1\u05c1\2\u05a6\1\u045c\1\u05c2\2\u05a6"+ + "\2\u045c\2\u05a6\1\u045c\1\u05a6\3\u045c\1\u05c3\1\u05a6\2\u045c"+ + "\1\u05a6\1\u04cc\12\u045c\242\0\1\u04cb\3\u05a6\1\u05c4\2\u05a6"+ + "\1\u045c\1\u05a6\1\u05c5\3\u05a6\3\u045c\2\u05a6\1\u045c\10\u05a6"+ + "\1\u04cc\12\u045c\242\0\1\u04cb\1\u05c6\2\u05a6\1\u05c7\1\u05c8"+ + "\1\u05c9\2\u05a6\1\u05ca\3\u05a6\1\u045c\1\u05a6\1\u045c\1\u05a6"+ + "\1\u045c\1\u05a6\1\u045c\1\u05a6\1\u045c\4\u05a6\1\u045c\1\u04cc"+ + "\12\u045c\242\0\1\u04cb\1\u05a6\6\u045c\1\u05a6\3\u045c\1\u05cb"+ + "\2\u045c\1\u05a6\4\u045c\1\u05a6\2\u045c\1\u05a6\2\u045c\1\u05a6"+ + "\1\u04cc\12\u045c\242\0\1\u04cb\6\u045c\1\u05a6\7\u045c\1\u05a6"+ + "\13\u045c\1\u04cc\12\u045c\242\0\1\u04cb\13\u045c\1\u05cc\6\u045c"+ + "\1\u05cd\7\u045c\1\u04cc\12\u045c\242\0\1\u04cb\1\u05a6\11\u045c"+ + "\1\u05a6\6\u045c\1\u05a6\10\u045c\1\u04cc\12\u045c\242\0\1\u04cb"+ + "\1\u05a6\1\u045c\6\u05a6\1\u05ce\1\u045c\2\u05a6\2\u045c\2\u05a6"+ + "\1\u045c\1\u05a6\1\u045c\3\u05a6\1\u045c\3\u05a6\1\u04cc\12\u045c"+ + "\242\0\1\u04cb\4\u045c\1\u05a6\1\u05cf\4\u045c\2\u05a6\3\u045c"+ + "\2\u05a6\5\u045c\1\u05a6\3\u045c\1\u04cc\12\u045c\242\0\1\u04cb"+ + "\3\u045c\2\u05a6\2\u045c\1\u05a6\1\u05d0\1\u045c\2\u05a6\1\u045c"+ + "\1\u05a6\3\u045c\1\u05a6\1\u045c\1\u05a6\1\u045c\1\u05a6\3\u045c"+ + "\1\u05a6\1\u04cc\12\u045c\242\0\1\u04cb\3\u045c\1\u05a6\1\u045c"+ + "\1\u05d1\4\u045c\1\u05a6\2\u045c\1\u05a6\14\u045c\1\u04cc\12\u045c"+ + "\242\0\1\u04cb\2\u05a6\1\u045c\1\u05d2\1\u045c\1\u05d3\1\u045c"+ + "\2\u05a6\2\u045c\1\u05a6\4\u045c\1\u05a6\11\u045c\1\u04cc\12\u045c"+ + "\242\0\1\u04cb\3\u045c\1\u05a6\13\u045c\1\u05a6\12\u045c\1\u04cc"+ + "\12\u045c\236\0\1\u036f\3\0\34\u036f\12\u05d4\1\0\2\u036f"+ + "\1\u03ea\2\u036f\1\u0371\1\u0228\1\u0229\1\u022a\2\0\2\u036f"+ + "\3\0\1\u036f\214\0\1\154\3\0\1\u016f\5\371\1\u037e"+ + "\24\371\1\203\12\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\220\0\4\u05d5\2\0"+ + "\1\u05d5\15\0\1\u05d5\6\0\12\u05d5\1\u04d5\242\0\4\u05d6"+ + "\2\0\1\u05d6\15\0\1\u05d6\6\0\12\u05d6\1\u05d7\242\0"+ + "\4\u05d8\2\0\1\u05d8\15\0\1\u05d8\6\0\1\u05d9\1\u05da"+ + "\5\u05d9\1\u05db\1\u05da\1\u05d9\13\0\1\u01ad\227\0\4\u05dc"+ + "\2\0\1\u05dc\15\0\1\u05dc\6\0\12\u05dc\1\u0556\12\0"+ + "\1\u01ad\227\0\4\u05d8\2\0\1\u05d8\15\0\1\u05d8\6\0"+ + "\1\u05d9\1\u05da\5\u05d9\1\u05db\1\u05da\1\u05d9\242\0\1\u0224"+ + "\4\u05dc\2\0\1\u05dc\15\0\1\u05dc\6\0\12\u05dc\1\u0556"+ + "\12\0\1\u01ad\226\0\1\u0224\4\u05dc\2\0\1\u05dc\15\0"+ + "\1\u05dc\6\0\12\u05dd\1\u0556\12\0\1\u01ad\226\0\1\u0224"+ + "\4\u05dc\2\0\1\u05dc\15\0\1\u05dc\6\0\2\u05dd\1\u05dc"+ + "\2\u05dd\2\u05dc\2\u05dd\1\u05dc\1\u0556\12\0\1\u01ad\274\0"+ + "\1\u046f\12\0\1\u01ad\226\0\1\u0136\10\323\1\u05de\21\323"+ + "\1\u0137\12\323\242\0\1\u0136\4\323\1\u02c3\25\323\1\u0137"+ + "\12\323\242\0\1\u0136\25\323\1\u02bd\4\323\1\u0137\12\323"+ + "\242\0\1\u0136\32\323\1\u0137\1\323\1\u05df\10\323\242\0"+ + "\1\u0136\32\323\1\u0137\6\323\1\u05e0\3\323\242\0\1\u0136"+ + "\32\323\1\u0137\5\323\1\u05e1\4\323\242\0\1\u0136\32\323"+ + "\1\u0137\5\323\1\u05e2\4\323\242\0\1\u0136\32\323\1\u0137"+ + "\5\323\1\u04ec\4\323\242\0\1\u0136\17\323\1\u05e3\12\323"+ + "\1\u0137\12\323\242\0\1\u0136\12\323\1\u05e4\17\323\1\u0137"+ + "\12\323\242\0\1\u0136\25\323\1\u05e5\4\323\1\u0137\12\323"+ + "\242\0\1\u0136\1\u05e6\31\323\1\u0137\12\323\242\0\1\u0136"+ + "\1\u05e7\31\323\1\u0137\12\323\242\0\1\u0136\15\323\1\u05e8"+ + "\14\323\1\u0137\12\323\242\0\1\u0136\1\323\1\u05e9\30\323"+ + "\1\u0137\12\323\242\0\1\u0136\32\323\1\u0137\10\323\1\u05ea"+ + "\1\323\242\0\1\u0136\21\323\1\u05eb\10\323\1\u0137\12\323"+ + "\242\0\1\u0136\1\u05ec\31\323\1\u0137\12\323\242\0\1\u0136"+ + "\32\323\1\u0137\3\323\1\u04ec\6\323\242\0\1\u0136\2\323"+ + "\1\u04fc\27\323\1\u0137\12\323\242\0\1\u0136\11\323\1\u05ed"+ + "\20\323\1\u0137\12\323\242\0\1\u0136\11\323\1\u05ee\20\323"+ + "\1\u0137\12\323\242\0\1\u0136\32\323\1\u0137\1\u02b5\11\323"+ + "\242\0\1\u0136\32\323\1\u0137\2\323\1\u02b5\7\323\242\0"+ + "\1\u0136\32\323\1\u0137\1\u0237\11\323\242\0\1\u0136\10\323"+ + "\1\u05ef\21\323\1\u0137\12\323\242\0\1\u0136\1\u05f0\31\323"+ + "\1\u0137\12\323\242\0\1\u0136\32\323\1\u0137\1\323\1\u05f1"+ + "\10\323\242\0\1\u0136\32\323\1\u0137\10\323\1\u01c1\1\323"+ + "\242\0\1\u0136\25\323\1\u05f2\4\323\1\u0137\12\323\236\0"+ + "\1\154\3\0\1\u016f\1\u05f3\31\371\1\203\12\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\32\371\1\203\7\371"+ + "\1\u0434\2\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\1\u05f4\31\371\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\1\u05f5\31\371\1\203\12\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\7\371\1\u05f6\22\371\1\203"+ + "\12\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\6\371"+ + "\1\u05f7\23\371\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\1\u05f8\31\371\1\203\12\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\1\u05f9\31\371\1\203\12\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\32\371\1\203"+ + "\1\371\1\u05fa\10\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\32\371\1\203\2\371\1\u05fb\7\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\6\371\1\u0174\23\371\1\203"+ + "\12\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\25\371"+ + "\1\u05fc\4\371\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\1\u05fd\31\371\1\203\12\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\32\371\1\203\2\371\1\u0199"+ + "\7\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\12\371"+ + "\1\u019b\17\371\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\24\371\1\u0174\5\371\1\203\12\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\220\0\4\u05fe\2\0\1\u05fe\15\0\1\u05fe\6\0"+ + "\12\u05fe\1\u051b\242\0\4\u05ff\2\0\1\u05ff\15\0\1\u05ff"+ + "\6\0\12\u05ff\1\u0600\242\0\4\u0601\2\0\1\u0601\15\0"+ + "\1\u0601\6\0\1\u0602\1\u0603\5\u0602\1\u0604\1\u0603\1\u0602"+ + "\13\0\1\u04ba\227\0\4\u0605\2\0\1\u0605\15\0\1\u0605"+ + "\6\0\12\u0605\1\u058d\12\0\1\u04ba\227\0\4\u0601\2\0"+ + "\1\u0601\15\0\1\u0601\6\0\1\u0602\1\u0603\5\u0602\1\u0604"+ + "\1\u0603\1\u0602\242\0\1\u0522\4\u0605\2\0\1\u0605\15\0"+ + "\1\u0605\6\0\12\u0605\1\u058d\12\0\1\u04ba\226\0\1\u0522"+ + "\4\u0605\2\0\1\u0605\15\0\1\u0605\6\0\12\u0606\1\u058d"+ + "\12\0\1\u04ba\226\0\1\u0522\4\u0605\2\0\1\u0605\15\0"+ + "\1\u0605\6\0\2\u0606\1\u0605\2\u0606\2\u0605\2\u0606\1\u0605"+ + "\1\u058d\12\0\1\u04ba\227\0\4\u0607\2\0\1\u0607\15\0"+ + "\1\u0607\6\0\12\u0607\1\u0521\12\0\1\u04ba\226\0\1\u0608"+ + "\33\0\12\u0609\242\0\1\u0608\33\0\12\u0592\242\0\1\u0608"+ + "\33\0\2\u0592\1\u0609\1\u0592\1\u060a\2\u0609\2\u0592\1\u0609"+ + "\242\0\1\u0522\4\u0607\2\0\1\u0607\15\0\1\u0607\6\0"+ + "\12\u0607\1\u0521\12\0\1\u04ba\222\0\1\u02f5\3\0\46\u02f5"+ + "\1\0\2\u02f5\1\u0364\2\u02f5\1\u02f7\1\0\1\u0363\3\0"+ + "\2\u02f5\3\0\1\u02f5\303\0\1\u060b\260\0\12\u060c\10\0"+ + "\1\u0363\277\0\1\u04c0\242\0\4\u060d\2\0\1\u060d\15\0"+ + "\1\u060d\6\0\12\u060d\1\u059b\242\0\4\u060e\2\0\1\u060e"+ + "\15\0\1\u060e\6\0\12\u060e\1\u060f\242\0\4\u0610\2\0"+ + "\1\u0610\15\0\1\u0610\6\0\12\u0610\1\u0611\12\0\1\u045b"+ + "\226\0\1\u04c7\4\u0610\2\0\1\u0610\15\0\1\u0610\6\0"+ + "\12\u0612\1\u0611\12\0\1\u045b\226\0\1\u04c7\4\u0610\2\0"+ + "\1\u0610\15\0\1\u0610\6\0\12\u0613\1\u0611\12\0\1\u045b"+ + "\226\0\1\u04c7\4\u0610\2\0\1\u0610\15\0\1\u0610\6\0"+ + "\2\u0613\1\u0612\1\u0613\1\u0614\2\u0612\2\u0613\1\u0612\1\u0611"+ + "\12\0\1\u045b\227\0\4\u0615\2\0\1\u0615\15\0\1\u0615"+ + "\6\0\12\u0615\1\u052d\12\0\1\u045b\226\0\1\u04c7\4\u0615"+ + "\2\0\1\u0615\15\0\1\u0615\6\0\12\u0615\1\u052d\12\0"+ + "\1\u045b\274\0\1\u04c6\12\0\1\u045b\262\0\1\u0616\1\u0617"+ + "\5\u0616\1\u0618\1\u0617\1\u0616\242\0\1\u05a3\307\0\1\u05a3"+ + "\33\0\2\u05a4\1\0\2\u05a4\2\0\2\u05a4\243\0\1\u0619"+ + "\32\u045c\1\u04cc\12\u045c\242\0\1\u0619\4\u045c\1\u05cb\25\u045c"+ + "\1\u04cc\12\u045c\242\0\1\u0619\15\u045c\1\u0542\14\u045c\1\u04cc"+ + "\12\u045c\242\0\1\u0619\10\u045c\1\u0542\21\u045c\1\u04cc\12\u045c"+ + "\242\0\1\u0619\12\u045c\1\u061a\4\u045c\1\u05a6\12\u045c\1\u04cc"+ + "\12\u045c\242\0\1\u0619\5\u045c\1\u061b\4\u045c\1\u05a6\1\u061c"+ + "\16\u045c\1\u04cc\12\u045c\242\0\1\u0619\5\u045c\1\u061d\24\u045c"+ + "\1\u04cc\12\u045c\242\0\1\u04cb\1\u061e\3\u045c\1\u061f\25\u045c"+ + "\1\u04cc\12\u045c\242\0\1\u04cb\20\u045c\1\u05a6\11\u045c\1\u04cc"+ + "\12\u045c\242\0\1\u04cb\17\u045c\1\u0620\12\u045c\1\u04cc\12\u045c"+ + "\242\0\1\u04cb\20\u045c\1\u0621\11\u045c\1\u04cc\12\u045c\242\0"+ + "\1\u0619\17\u045c\1\u0622\12\u045c\1\u04cc\12\u045c\242\0\1\u04cb"+ + "\7\u045c\1\u05a6\22\u045c\1\u04cc\12\u045c\242\0\1\u0619\11\u045c"+ + "\1\u0623\20\u045c\1\u04cc\12\u045c\242\0\1\u0619\1\u0624\31\u045c"+ + "\1\u04cc\12\u045c\242\0\1\u04cb\30\u045c\1\u05a6\1\u045c\1\u04cc"+ + "\12\u045c\242\0\1\u0619\4\u045c\1\u05ae\25\u045c\1\u04cc\12\u045c"+ + "\242\0\1\u0619\6\u045c\1\u05cb\10\u045c\1\u05a6\12\u045c\1\u04cc"+ + "\12\u045c\242\0\1\u0619\13\u045c\1\u0625\16\u045c\1\u04cc\12\u045c"+ + "\242\0\1\u0619\7\u045c\1\u0626\22\u045c\1\u04cc\12\u045c\242\0"+ + "\1\u0619\13\u045c\1\u05ae\16\u045c\1\u04cc\12\u045c\242\0\1\u0619"+ + "\24\u045c\1\u0627\5\u045c\1\u04cc\12\u045c\242\0\1\u04cb\11\u045c"+ + "\1\u05a6\20\u045c\1\u04cc\12\u045c\242\0\1\u0619\16\u045c\1\u0628"+ + "\13\u045c\1\u04cc\12\u045c\242\0\1\u0619\12\u045c\1\u0629\17\u045c"+ + "\1\u04cc\12\u045c\242\0\1\u0619\17\u045c\1\u05a6\12\u045c\1\u04cc"+ + "\12\u045c\242\0\1\u0619\5\u045c\1\u05a6\24\u045c\1\u04cc\12\u045c"+ + "\242\0\1\u04cb\16\u045c\1\u062a\13\u045c\1\u04cc\12\u045c\242\0"+ + "\1\u0619\20\u045c\1\u062b\11\u045c\1\u04cc\12\u045c\242\0\1\u0619"+ + "\5\u045c\1\u062c\24\u045c\1\u04cc\12\u045c\242\0\1\u0619\22\u045c"+ + "\1\u062d\7\u045c\1\u04cc\12\u045c\242\0\1\u0619\13\u045c\1\u062e"+ + "\16\u045c\1\u04cc\12\u045c\242\0\1\u04cb\17\u045c\1\u062f\12\u045c"+ + "\1\u04cc\12\u045c\242\0\1\u04cb\1\u045c\1\u0630\7\u045c\1\u05a6"+ + "\20\u045c\1\u04cc\12\u045c\242\0\1\u0619\1\u0631\31\u045c\1\u04cc"+ + "\12\u045c\242\0\1\u0619\2\u045c\1\u0632\27\u045c\1\u04cc\12\u045c"+ + "\242\0\1\u04cb\15\u045c\1\u0633\14\u045c\1\u04cc\12\u045c\242\0"+ + "\1\u04cb\5\u045c\1\u05a6\24\u045c\1\u04cc\12\u045c\242\0\1\u04cb"+ + "\32\u045c\1\u0634\12\u045c\242\0\1\u04cb\22\u045c\1\u05a6\7\u045c"+ + "\1\u04cc\12\u045c\242\0\1\u0619\23\u045c\1\u05a6\2\u045c\1\u0629"+ + "\3\u045c\1\u04cc\12\u045c\242\0\1\u04cb\11\u045c\1\u0635\20\u045c"+ + "\1\u04cc\12\u045c\242\0\1\u0619\17\u045c\1\u0636\12\u045c\1\u04cc"+ + "\12\u045c\242\0\1\u0619\24\u045c\1\u0633\5\u045c\1\u04cc\12\u045c"+ + "\242\0\1\u0619\13\u045c\1\u0637\16\u045c\1\u04cc\12\u045c\242\0"+ + "\1\u04cb\31\u045c\1\u0638\1\u04cc\12\u045c\236\0\1\u036f\3\0"+ + "\34\u036f\12\u0639\1\0\2\u036f\1\u03ea\2\u036f\1\u0371\1\u0228"+ + "\1\u0229\1\u022a\2\0\2\u036f\3\0\1\u036f\266\0\1\u04d5"+ + "\242\0\4\u063a\2\0\1\u063a\15\0\1\u063a\6\0\12\u063a"+ + "\1\u05d7\242\0\4\u063b\2\0\1\u063b\15\0\1\u063b\6\0"+ + "\1\u063c\1\u063d\5\u063c\1\u063e\1\u063d\1\u063c\1\u063f\242\0"+ + "\4\u0640\2\0\1\u0640\15\0\1\u0640\6\0\12\u0640\1\u0641"+ + "\12\0\1\u01ad\226\0\1\u0224\4\u0640\2\0\1\u0640\15\0"+ + "\1\u0640\6\0\12\u0642\1\u0641\12\0\1\u01ad\226\0\1\u0224"+ + "\4\u0640\2\0\1\u0640\15\0\1\u0640\6\0\12\u0643\1\u0641"+ + "\12\0\1\u01ad\226\0\1\u0224\4\u0640\2\0\1\u0640\15\0"+ + "\1\u0640\6\0\2\u0643\1\u0642\1\u0643\1\u0644\2\u0642\2\u0643"+ + "\1\u0642\1\u0641\12\0\1\u01ad\227\0\4\u0645\2\0\1\u0645"+ + "\15\0\1\u0645\6\0\12\u0645\1\u0556\12\0\1\u01ad\226\0"+ + "\1\u0224\4\u0645\2\0\1\u0645\15\0\1\u0645\6\0\12\u0645"+ + "\1\u0556\12\0\1\u01ad\226\0\1\u0136\5\323\1\u0424\24\323"+ + "\1\u0137\12\323\242\0\1\u0136\3\323\1\u0646\26\323\1\u0137"+ + "\12\323\242\0\1\u0136\6\323\1\u0241\23\323\1\u0137\12\323"+ + "\242\0\1\u0136\1\323\1\u0571\30\323\1\u0137\12\323\242\0"+ + "\1\u0136\3\323\1\u0647\26\323\1\u0137\12\323\242\0\1\u0136"+ + "\32\323\1\u0137\10\323\1\u0648\1\323\242\0\1\u0136\32\323"+ + "\1\u0137\2\323\1\u0649\7\323\242\0\1\u0136\32\323\1\u0137"+ + "\2\323\1\u064a\7\323\242\0\1\u0136\32\323\1\u0137\3\323"+ + "\1\u064b\6\323\242\0\1\u0136\32\323\1\u0137\5\323\1\u064c"+ + "\4\323\242\0\1\u0136\32\323\1\u0137\3\323\1\u064d\6\323"+ + "\242\0\1\u0136\2\323\1\u064e\27\323\1\u0137\12\323\242\0"+ + "\1\u0136\1\u064f\31\323\1\u0137\12\323\242\0\1\u0136\24\323"+ + "\1\u0650\5\323\1\u0137\12\323\242\0\1\u0136\23\323\1\u02b5"+ + "\6\323\1\u0137\12\323\242\0\1\u0136\32\323\1\u0137\1\u0651"+ + "\11\323\242\0\1\u0136\32\323\1\u0137\1\u0652\11\323\242\0"+ + "\1\u0136\32\323\1\u0137\11\323\1\u0653\242\0\1\u0136\12\323"+ + "\1\u0654\17\323\1\u0137\12\323\242\0\1\u0136\32\323\1\u0137"+ + "\2\323\1\u02b9\7\323\242\0\1\u0136\2\323\1\u0655\27\323"+ + "\1\u0137\12\323\236\0\1\154\3\0\1\u016f\32\371\1\203"+ + "\1\371\1\u0656\10\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\2\371\1\u0657\27\371\1\203\12\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\32\371\1\203\6\371\1\u0444"+ + "\3\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f\15\371"+ + "\1\u010f\14\371\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\32\371\1\203\10\371\1\u043f\1\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\23\371\1\u0658\6\371"+ + "\1\203\12\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\32\371\1\203\4\371\1\u0659\5\371\1\0\3\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\213\0"+ + "\1\154\3\0\1\u016f\1\u0588\31\371\1\203\12\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\32\371\1\203\10\371"+ + "\1\u0209\1\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\31\371\1\u065a\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\32\371\1\203\4\371\1\u065b\5\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\265\0\1\u051b\242\0\4\u065c\2\0\1\u065c\15\0"+ + "\1\u065c\6\0\12\u065c\1\u0600\242\0\4\u065d\2\0\1\u065d"+ + "\15\0\1\u065d\6\0\12\u065d\1\u065e\242\0\4\u065f\2\0"+ + "\1\u065f\15\0\1\u065f\6\0\12\u065f\1\u0660\12\0\1\u04ba"+ + "\226\0\1\u0522\4\u065f\2\0\1\u065f\15\0\1\u065f\6\0"+ + "\12\u0661\1\u0660\12\0\1\u04ba\226\0\1\u0522\4\u065f\2\0"+ + "\1\u065f\15\0\1\u065f\6\0\12\u0662\1\u0660\12\0\1\u04ba"+ + "\226\0\1\u0522\4\u065f\2\0\1\u065f\15\0\1\u065f\6\0"+ + "\2\u0662\1\u0661\1\u0662\1\u0663\2\u0661\2\u0662\1\u0661\1\u0660"+ + "\12\0\1\u04ba\227\0\4\u0664\2\0\1\u0664\15\0\1\u0664"+ + "\6\0\12\u0664\1\u058d\12\0\1\u04ba\226\0\1\u0522\4\u0664"+ + "\2\0\1\u0664\15\0\1\u0664\6\0\12\u0664\1\u058d\12\0"+ + "\1\u04ba\274\0\1\u0521\12\0\1\u04ba\262\0\1\u0665\1\u0666"+ + "\5\u0665\1\u0667\1\u0666\1\u0665\242\0\1\u0608\307\0\1\u0608"+ + "\33\0\2\u0609\1\0\2\u0609\2\0\2\u0609\244\0\1\u0668"+ + "\1\0\1\u0668\5\0\1\u0668\354\0\1\u0363\232\0\4\u0669"+ + "\2\0\1\u0669\15\0\1\u0669\6\0\12\u0669\1\u059b\242\0"+ + "\4\u066a\2\0\1\u066a\15\0\1\u066a\6\0\12\u066a\1\u066b"+ + "\242\0\4\u066c\2\0\1\u066c\15\0\1\u066c\6\0\1\u066d"+ + "\1\u066e\5\u066d\1\u066f\1\u066e\1\u066d\13\0\1\u045b\227\0"+ + "\4\u0670\2\0\1\u0670\15\0\1\u0670\6\0\12\u0670\1\u0611"+ + "\12\0\1\u045b\227\0\4\u066c\2\0\1\u066c\15\0\1\u066c"+ + "\6\0\1\u066d\1\u066e\5\u066d\1\u066f\1\u066e\1\u066d\242\0"+ + "\1\u04c7\4\u0670\2\0\1\u0670\15\0\1\u0670\6\0\12\u0670"+ + "\1\u0611\12\0\1\u045b\226\0\1\u04c7\4\u0670\2\0\1\u0670"+ + "\15\0\1\u0670\6\0\12\u0671\1\u0611\12\0\1\u045b\226\0"+ + "\1\u04c7\4\u0670\2\0\1\u0670\15\0\1\u0670\6\0\2\u0671"+ + "\1\u0670\2\u0671\2\u0670\2\u0671\1\u0670\1\u0611\12\0\1\u045b"+ + "\274\0\1\u052d\12\0\1\u045b\226\0\1\u0672\33\0\12\u0673"+ + "\242\0\1\u0672\33\0\12\u0616\242\0\1\u0672\33\0\2\u0616"+ + "\1\u0673\1\u0616\1\u0674\2\u0673\2\u0616\1\u0673\242\0\1\u04cb"+ + "\3\u045c\1\u0675\26\u045c\1\u04cc\12\u045c\242\0\1\u04cb\15\u045c"+ + "\1\u05a6\14\u045c\1\u04cc\12\u045c\242\0\1\u04cb\16\u045c\1\u0676"+ + "\1\u0677\12\u045c\1\u04cc\12\u045c\242\0\1\u04cb\17\u045c\1\u0678"+ + "\12\u045c\1\u04cc\12\u045c\242\0\1\u04cb\12\u045c\1\u0679\17\u045c"+ + "\1\u04cc\12\u045c\242\0\1\u04cb\3\u045c\1\u067a\26\u045c\1\u04cc"+ + "\12\u045c\242\0\1\u04cb\3\u045c\1\u067b\26\u045c\1\u04cc\12\u045c"+ + "\242\0\1\u04cb\10\u045c\1\u067c\21\u045c\1\u04cc\12\u045c\242\0"+ + "\1\u04cb\1\u067d\31\u045c\1\u04cc\12\u045c\242\0\1\u04cb\11\u045c"+ + "\1\u067e\20\u045c\1\u04cc\12\u045c\242\0\1\u04cb\15\u045c\1\u067f"+ + "\14\u045c\1\u04cc\12\u045c\242\0\1\u04cb\2\u045c\1\u05a6\27\u045c"+ + "\1\u04cc\12\u045c\242\0\1\u04cb\25\u045c\1\u0680\4\u045c\1\u04cc"+ + "\12\u045c\242\0\1\u04cb\10\u045c\1\u05a6\21\u045c\1\u04cc\12\u045c"+ + "\242\0\1\u04cb\3\u045c\1\u0681\26\u045c\1\u04cc\12\u045c\242\0"+ + "\1\u04cb\3\u045c\1\u05a6\26\u045c\1\u04cc\12\u045c\242\0\1\u04cb"+ + "\17\u045c\1\u05a6\12\u045c\1\u04cc\12\u045c\242\0\1\u04cb\12\u045c"+ + "\1\u0682\17\u045c\1\u04cc\12\u045c\242\0\1\u04cb\17\u045c\1\u0683"+ + "\12\u045c\1\u04cc\12\u045c\242\0\1\u04cb\31\u045c\1\u05a6\1\u04cc"+ + "\12\u045c\242\0\1\u04cb\7\u045c\1\u0684\22\u045c\1\u04cc\12\u045c"+ + "\242\0\1\u04cb\17\u045c\1\u0685\12\u045c\1\u04cc\12\u045c\242\0"+ + "\1\u04cb\25\u045c\1\u0686\4\u045c\1\u04cc\12\u045c\242\0\1\u04cb"+ + "\30\u045c\1\u0687\1\u045c\1\u04cc\12\u045c\242\0\1\u04cb\1\u062d"+ + "\31\u045c\1\u04cc\12\u045c\242\0\1\u04cb\16\u045c\1\u05a6\13\u045c"+ + "\1\u04cc\12\u045c\243\0\32\u045c\1\u0688\12\u045c\242\0\1\u04cb"+ + "\2\u045c\1\u0689\27\u045c\1\u04cc\12\u045c\242\0\1\u04cb\1\u045c"+ + "\1\u068a\30\u045c\1\u04cc\12\u045c\242\0\1\u04cb\17\u045c\1\u068b"+ + "\12\u045c\1\u04cc\12\u045c\242\0\1\u04cb\1\u068c\31\u045c\1\u04cc"+ + "\12\u045c\236\0\1\u036f\3\0\46\u036f\1\0\2\u036f\1\u03ea"+ + "\2\u036f\1\u0371\1\u0228\1\u0229\1\u022a\2\0\2\u036f\3\0"+ + "\1\u036f\221\0\4\u068d\2\0\1\u068d\15\0\1\u068d\6\0"+ + "\12\u068d\1\u05d7\242\0\4\u068e\2\0\1\u068e\15\0\1\u068e"+ + "\6\0\12\u068e\1\u068f\241\0\1\u0224\4\u068e\2\0\1\u068e"+ + "\15\0\1\u068e\6\0\12\u0690\1\u068f\241\0\1\u0224\4\u068e"+ + "\2\0\1\u068e\15\0\1\u068e\6\0\12\u0691\1\u068f\241\0"+ + "\1\u0224\4\u068e\2\0\1\u068e\15\0\1\u068e\6\0\2\u0691"+ + "\1\u0690\1\u0691\1\u0692\2\u0690\2\u0691\1\u0690\1\u068f\242\0"+ + "\4\u0693\2\0\1\u0693\15\0\1\u0693\6\0\12\u0693\13\0"+ + "\1\u01ad\227\0\4\u0694\2\0\1\u0694\15\0\1\u0694\6\0"+ + "\12\u0694\1\u0641\12\0\1\u01ad\227\0\4\u0693\2\0\1\u0693"+ + "\15\0\1\u0693\6\0\12\u0693\242\0\1\u0224\4\u0694\2\0"+ + "\1\u0694\15\0\1\u0694\6\0\12\u0694\1\u0641\12\0\1\u01ad"+ + "\226\0\1\u0224\4\u0694\2\0\1\u0694\15\0\1\u0694\6\0"+ + "\12\u0695\1\u0641\12\0\1\u01ad\226\0\1\u0224\4\u0694\2\0"+ + "\1\u0694\15\0\1\u0694\6\0\2\u0695\1\u0694\2\u0695\2\u0694"+ + "\2\u0695\1\u0694\1\u0641\12\0\1\u01ad\274\0\1\u0556\12\0"+ + "\1\u01ad\226\0\1\u0136\1\u0696\31\323\1\u0137\12\323\242\0"+ + "\1\u0136\32\323\1\u0137\7\323\1\u04ec\2\323\242\0\1\u0136"+ + "\1\u0697\31\323\1\u0137\12\323\242\0\1\u0136\1\u0698\31\323"+ + "\1\u0137\12\323\242\0\1\u0136\7\323\1\u0699\22\323\1\u0137"+ + "\12\323\242\0\1\u0136\6\323\1\u069a\23\323\1\u0137\12\323"+ + "\242\0\1\u0136\1\u069b\31\323\1\u0137\12\323\242\0\1\u0136"+ + "\1\u069c\31\323\1\u0137\12\323\242\0\1\u0136\32\323\1\u0137"+ + "\1\323\1\u069d\10\323\242\0\1\u0136\32\323\1\u0137\2\323"+ + "\1\u069e\7\323\242\0\1\u0136\6\323\1\u022b\23\323\1\u0137"+ + "\12\323\242\0\1\u0136\25\323\1\u069f\4\323\1\u0137\12\323"+ + "\242\0\1\u0136\1\u06a0\31\323\1\u0137\12\323\242\0\1\u0136"+ + "\32\323\1\u0137\2\323\1\u0250\7\323\242\0\1\u0136\12\323"+ + "\1\u0252\17\323\1\u0137\12\323\242\0\1\u0136\24\323\1\u022b"+ + "\5\323\1\u0137\12\323\236\0\1\154\3\0\1\u016f\24\371"+ + "\1\u06a1\5\371\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\32\371\1\203\6\371\1\u06a2\3\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\213\0\1\154\3\0\1\u016f\1\371\1\u0180\30\371"+ + "\1\203\12\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\2\371\1\u06a3\27\371\1\203\12\371\1\0\3\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\213\0"+ + "\1\154\3\0\1\u016f\3\371\1\u06a4\26\371\1\203\12\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\3\371\1\u06a5"+ + "\26\371\1\203\12\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\220\0\4\u06a6\2\0"+ + "\1\u06a6\15\0\1\u06a6\6\0\12\u06a6\1\u0600\242\0\4\u06a7"+ + "\2\0\1\u06a7\15\0\1\u06a7\6\0\12\u06a7\1\u06a8\242\0"+ + "\4\u06a9\2\0\1\u06a9\15\0\1\u06a9\6\0\1\u06aa\1\u06ab"+ + "\5\u06aa\1\u06ac\1\u06ab\1\u06aa\13\0\1\u04ba\227\0\4\u06ad"+ + "\2\0\1\u06ad\15\0\1\u06ad\6\0\12\u06ad\1\u0660\12\0"+ + "\1\u04ba\227\0\4\u06a9\2\0\1\u06a9\15\0\1\u06a9\6\0"+ + "\1\u06aa\1\u06ab\5\u06aa\1\u06ac\1\u06ab\1\u06aa\242\0\1\u0522"+ + "\4\u06ad\2\0\1\u06ad\15\0\1\u06ad\6\0\12\u06ad\1\u0660"+ + "\12\0\1\u04ba\226\0\1\u0522\4\u06ad\2\0\1\u06ad\15\0"+ + "\1\u06ad\6\0\12\u06ae\1\u0660\12\0\1\u04ba\226\0\1\u0522"+ + "\4\u06ad\2\0\1\u06ad\15\0\1\u06ad\6\0\2\u06ae\1\u06ad"+ + "\2\u06ae\2\u06ad\2\u06ae\1\u06ad\1\u0660\12\0\1\u04ba\274\0"+ + "\1\u058d\12\0\1\u04ba\226\0\1\u06af\33\0\12\u06b0\242\0"+ + "\1\u06af\33\0\12\u0665\242\0\1\u06af\33\0\2\u0665\1\u06b0"+ + "\1\u0665\1\u06b1\2\u06b0\2\u0665\1\u06b0\321\0\1\u022a\276\0"+ + "\1\u059b\242\0\4\u06b2\2\0\1\u06b2\15\0\1\u06b2\6\0"+ + "\12\u06b2\1\u066b\242\0\4\u06b3\2\0\1\u06b3\15\0\1\u06b3"+ + "\6\0\12\u06b3\1\u06b4\242\0\4\u06b5\2\0\1\u06b5\15\0"+ + "\1\u06b5\6\0\12\u06b5\1\u06b6\12\0\1\u045b\226\0\1\u04c7"+ + "\4\u06b5\2\0\1\u06b5\15\0\1\u06b5\6\0\12\u06b7\1\u06b6"+ + "\12\0\1\u045b\226\0\1\u04c7\4\u06b5\2\0\1\u06b5\15\0"+ + "\1\u06b5\6\0\12\u06b8\1\u06b6\12\0\1\u045b\226\0\1\u04c7"+ + "\4\u06b5\2\0\1\u06b5\15\0\1\u06b5\6\0\2\u06b8\1\u06b7"+ + "\1\u06b8\1\u06b9\2\u06b7\2\u06b8\1\u06b7\1\u06b6\12\0\1\u045b"+ + "\227\0\4\u06ba\2\0\1\u06ba\15\0\1\u06ba\6\0\12\u06ba"+ + "\1\u0611\12\0\1\u045b\226\0\1\u04c7\4\u06ba\2\0\1\u06ba"+ + "\15\0\1\u06ba\6\0\12\u06ba\1\u0611\12\0\1\u045b\262\0"+ + "\1\u06bb\1\u06bc\5\u06bb\1\u06bd\1\u06bc\1\u06bb\242\0\1\u0672"+ + "\307\0\1\u0672\33\0\2\u0673\1\0\2\u0673\2\0\2\u0673"+ + "\243\0\1\u04cb\4\u045c\1\u0542\25\u045c\1\u04cc\12\u045c\242\0"+ + "\1\u04cb\17\u045c\1\u06be\12\u045c\1\u04cc\12\u045c\242\0\1\u04cb"+ + "\4\u045c\1\u06bf\25\u045c\1\u04cc\12\u045c\242\0\1\u04cb\25\u045c"+ + "\1\u06c0\4\u045c\1\u04cc\12\u045c\242\0\1\u04cb\5\u045c\1\u06c1"+ + "\24\u045c\1\u04cc\12\u045c\242\0\1\u04cb\1\u045c\1\u06c2\30\u045c"+ + "\1\u04cc\12\u045c\242\0\1\u04cb\4\u045c\1\u06c3\25\u045c\1\u04cc"+ + "\12\u045c\242\0\1\u04cb\15\u045c\1\u06c4\14\u045c\1\u04cc\12\u045c"+ + "\242\0\1\u04cb\17\u045c\1\u0629\12\u045c\1\u04cc\12\u045c\242\0"+ + "\1\u04cb\3\u045c\1\u06c5\26\u045c\1\u04cc\12\u045c\242\0\1\u04cb"+ + "\25\u045c\1\u06c6\4\u045c\1\u04cc\12\u045c\242\0\1\u04cb\17\u045c"+ + "\1\u06c0\12\u045c\1\u04cc\12\u045c\242\0\1\u04cb\20\u045c\1\u06c7"+ + "\11\u045c\1\u04cc\12\u045c\242\0\1\u04cb\24\u045c\1\u06c0\5\u045c"+ + "\1\u04cc\12\u045c\242\0\1\u04cb\5\u045c\1\u06c8\24\u045c\1\u04cc"+ + "\12\u045c\242\0\1\u04cb\11\u045c\1\u06c9\20\u045c\1\u04cc\12\u045c"+ + "\242\0\1\u04cb\5\u045c\1\u05cb\24\u045c\1\u04cc\12\u045c\242\0"+ + "\1\u04cb\13\u045c\1\u06ca\16\u045c\1\u04cc\12\u045c\242\0\1\u04cb"+ + "\3\u045c\1\u05bc\26\u045c\1\u04cc\12\u045c\243\0\1\u045c\1\u06cb"+ + "\3\u045c\1\u06cc\1\u06cd\1\u06ce\1\u045c\1\u06cf\1\u06d0\1\u06d1"+ + "\1\u06d2\1\u06d3\1\u06d4\1\u045c\1\u06d5\1\u06d6\1\u06d7\2\u045c"+ + "\1\u06d8\1\u06d9\1\u06da\1\u045c\1\u06db\1\u04cc\1\u06dc\2\u045c"+ + "\1\u06dd\1\u045c\1\u06de\1\u06df\3\u045c\242\0\1\u04cb\10\u045c"+ + "\1\u06e0\21\u045c\1\u04cc\12\u045c\242\0\1\u04cb\25\u045c\1\u06e1"+ + "\4\u045c\1\u04cc\12\u045c\242\0\1\u04cb\20\u045c\1\u06e2\11\u045c"+ + "\1\u04cc\12\u045c\242\0\1\u04cb\7\u045c\1\u0629\22\u045c\1\u04cc"+ + "\12\u045c\310\0\1\u05d7\242\0\4\u06e3\2\0\1\u06e3\15\0"+ + "\1\u06e3\6\0\12\u06e3\1\u068f\242\0\4\u0693\2\0\1\u0693"+ + "\15\0\1\u0693\6\0\12\u0693\1\u04dc\241\0\1\u0224\4\u06e3"+ + "\2\0\1\u06e3\15\0\1\u06e3\6\0\12\u06e3\1\u068f\241\0"+ + "\1\u0224\4\u06e3\2\0\1\u06e3\15\0\1\u06e3\6\0\12\u06e4"+ + "\1\u068f\241\0\1\u0224\4\u06e3\2\0\1\u06e3\15\0\1\u06e3"+ + "\6\0\2\u06e4\1\u06e3\2\u06e4\2\u06e3\2\u06e4\1\u06e3\1\u068f"+ + "\242\0\4\u06e5\2\0\1\u06e5\15\0\1\u06e5\6\0\12\u06e5"+ + "\13\0\1\u01ad\227\0\4\u06e6\2\0\1\u06e6\15\0\1\u06e6"+ + "\6\0\12\u06e6\1\u0641\12\0\1\u01ad\226\0\1\u0224\4\u06e6"+ + "\2\0\1\u06e6\15\0\1\u06e6\6\0\12\u06e6\1\u0641\12\0"+ + "\1\u01ad\226\0\1\u0136\32\323\1\u0137\1\323\1\u06e7\10\323"+ + "\242\0\1\u0136\2\323\1\u06e8\27\323\1\u0137\12\323\242\0"+ + "\1\u0136\32\323\1\u0137\6\323\1\u04fc\3\323\242\0\1\u0136"+ + "\15\323\1\u01c1\14\323\1\u0137\12\323\242\0\1\u0136\32\323"+ + "\1\u0137\10\323\1\u04f7\1\323\242\0\1\u0136\23\323\1\u06e9"+ + "\6\323\1\u0137\12\323\242\0\1\u0136\32\323\1\u0137\4\323"+ + "\1\u06ea\5\323\242\0\1\u0136\1\u0655\31\323\1\u0137\12\323"+ + "\242\0\1\u0136\32\323\1\u0137\10\323\1\u02b9\1\323\242\0"+ + "\1\u0136\31\323\1\u06eb\1\u0137\12\323\242\0\1\u0136\32\323"+ + "\1\u0137\4\323\1\u06ec\5\323\236\0\1\154\3\0\1\u016f"+ + "\32\371\1\203\7\371\1\u06ed\2\371\1\0\3\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\213\0"+ + "\1\154\3\0\1\u016f\27\371\1\u0174\2\371\1\203\12\371"+ + "\1\0\3\154\1\0\1\154\1\156\3\154\3\0\1\154"+ + "\3\0\2\154\213\0\1\154\3\0\1\u016f\32\371\1\203"+ + "\3\371\1\u06ee\6\371\1\0\3\154\1\0\1\154\1\156"+ + "\3\154\3\0\1\154\3\0\2\154\213\0\1\154\3\0"+ + "\1\u016f\32\371\1\203\7\371\1\u010f\2\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\3\371\1\u06ef\26\371\1\203"+ + "\12\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\265\0\1\u0600\242\0\4\u06f0\2\0"+ + "\1\u06f0\15\0\1\u06f0\6\0\12\u06f0\1\u06a8\242\0\4\u06f1"+ + "\2\0\1\u06f1\15\0\1\u06f1\6\0\12\u06f1\1\u06f2\242\0"+ + "\4\u06f3\2\0\1\u06f3\15\0\1\u06f3\6\0\12\u06f3\1\u06f4"+ + "\12\0\1\u04ba\226\0\1\u0522\4\u06f3\2\0\1\u06f3\15\0"+ + "\1\u06f3\6\0\12\u06f5\1\u06f4\12\0\1\u04ba\226\0\1\u0522"+ + "\4\u06f3\2\0\1\u06f3\15\0\1\u06f3\6\0\12\u06f6\1\u06f4"+ + "\12\0\1\u04ba\226\0\1\u0522\4\u06f3\2\0\1\u06f3\15\0"+ + "\1\u06f3\6\0\2\u06f6\1\u06f5\1\u06f6\1\u06f7\2\u06f5\2\u06f6"+ + "\1\u06f5\1\u06f4\12\0\1\u04ba\227\0\4\u06f8\2\0\1\u06f8"+ + "\15\0\1\u06f8\6\0\12\u06f8\1\u0660\12\0\1\u04ba\226\0"+ + "\1\u0522\4\u06f8\2\0\1\u06f8\15\0\1\u06f8\6\0\12\u06f8"+ + "\1\u0660\12\0\1\u04ba\262\0\1\u06f9\1\u06fa\5\u06f9\1\u06fb"+ + "\1\u06fa\1\u06f9\242\0\1\u06af\307\0\1\u06af\33\0\2\u06b0"+ + "\1\0\2\u06b0\2\0\2\u06b0\244\0\4\u06fc\2\0\1\u06fc"+ + "\15\0\1\u06fc\6\0\12\u06fc\1\u066b\242\0\4\u06fd\2\0"+ + "\1\u06fd\15\0\1\u06fd\6\0\12\u06fd\1\u06fe\242\0\4\u06ff"+ + "\2\0\1\u06ff\15\0\1\u06ff\6\0\1\u0700\1\u0701\5\u0700"+ + "\1\u0702\1\u0701\1\u0700\13\0\1\u045b\227\0\4\u0703\2\0"+ + "\1\u0703\15\0\1\u0703\6\0\12\u0703\1\u06b6\12\0\1\u045b"+ + "\227\0\4\u06ff\2\0\1\u06ff\15\0\1\u06ff\6\0\1\u0700"+ + "\1\u0701\5\u0700\1\u0702\1\u0701\1\u0700\242\0\1\u04c7\4\u0703"+ + "\2\0\1\u0703\15\0\1\u0703\6\0\12\u0703\1\u06b6\12\0"+ + "\1\u045b\226\0\1\u04c7\4\u0703\2\0\1\u0703\15\0\1\u0703"+ + "\6\0\12\u0704\1\u06b6\12\0\1\u045b\226\0\1\u04c7\4\u0703"+ + "\2\0\1\u0703\15\0\1\u0703\6\0\2\u0704\1\u0703\2\u0704"+ + "\2\u0703\2\u0704\1\u0703\1\u06b6\12\0\1\u045b\274\0\1\u0611"+ + "\12\0\1\u045b\262\0\12\u0705\13\0\1\u045b\262\0\12\u06bb"+ + "\13\0\1\u045b\262\0\2\u06bb\1\u0705\1\u06bb\1\u0706\2\u0705"+ + "\2\u06bb\1\u0705\13\0\1\u045b\226\0\1\u04cb\4\u045c\1\u0707"+ + "\25\u045c\1\u04cc\12\u045c\242\0\1\u04cb\1\u0708\31\u045c\1\u04cc"+ + "\12\u045c\242\0\1\u04cb\10\u045c\1\u0709\21\u045c\1\u04cc\12\u045c"+ + "\242\0\1\u04cb\13\u045c\1\u070a\16\u045c\1\u04cc\12\u045c\242\0"+ + "\1\u04cb\17\u045c\1\u070b\12\u045c\1\u04cc\12\u045c\242\0\1\u04cb"+ + "\15\u045c\1\u070c\14\u045c\1\u04cc\12\u045c\242\0\1\u04cb\12\u045c"+ + "\1\u070d\17\u045c\1\u04cc\12\u045c\242\0\1\u04cb\4\u045c\1\u062d"+ + "\25\u045c\1\u04cc\12\u045c\242\0\1\u04cb\10\u045c\1\u070e\21\u045c"+ + "\1\u04cc\12\u045c\242\0\1\u04cb\12\u045c\1\u05a6\17\u045c\1\u04cc"+ + "\12\u045c\242\0\1\u04cb\7\u045c\1\u070f\22\u045c\1\u04cc\12\u045c"+ + "\242\0\1\u04cb\3\u045c\1\u0633\26\u045c\1\u04cc\12\u045c\242\0"+ + "\1\u04cb\5\u045c\1\u0710\24\u045c\1\u04cc\12\u045c\242\0\1\u04cb"+ + "\11\u045c\1\u0711\20\u045c\1\u04cc\12\u045c\242\0\1\u04cb\7\u045c"+ + "\1\u0712\22\u045c\1\u04cc\1\u0713\11\u045c\242\0\1\u04cb\10\u045c"+ + "\1\u0714\4\u045c\1\u0715\5\u045c\1\u0716\6\u045c\1\u04cc\12\u045c"+ + "\242\0\1\u04cb\3\u045c\1\u0717\26\u045c\1\u04cc\12\u045c\242\0"+ + "\1\u04cb\7\u045c\1\u0718\22\u045c\1\u04cc\10\u045c\1\u0719\1\u045c"+ + "\242\0\1\u04cb\7\u045c\1\u071a\22\u045c\1\u04cc\12\u045c\242\0"+ + "\1\u04cb\7\u045c\1\u071b\22\u045c\1\u04cc\12\u045c\242\0\1\u04cb"+ + "\32\u045c\1\u04cc\5\u045c\1\u071c\4\u045c\242\0\1\u04cb\7\u045c"+ + "\1\u071d\22\u045c\1\u04cc\10\u045c\1\u071e\1\u045c\242\0\1\u04cb"+ + "\32\u045c\1\u04cc\5\u045c\1\u071f\4\u045c\242\0\1\u04cb\13\u045c"+ + "\1\u0720\16\u045c\1\u04cc\12\u045c\242\0\1\u04cb\7\u045c\1\u0721"+ + "\22\u045c\1\u04cc\12\u045c\242\0\1\u04cb\26\u045c\1\u0722\3\u045c"+ + "\1\u04cc\12\u045c\242\0\1\u04cb\32\u045c\1\u04cc\7\u045c\1\u071f"+ + "\2\u045c\242\0\1\u04cb\15\u045c\1\u0723\14\u045c\1\u04cc\12\u045c"+ + "\242\0\1\u04cb\32\u045c\1\u04cc\10\u045c\1\u0724\1\u0725\242\0"+ + "\1\u04cb\6\u045c\1\u0726\1\u0727\22\u045c\1\u04cc\12\u045c\242\0"+ + "\1\u04cb\3\u045c\1\u0728\26\u045c\1\u04cc\12\u045c\242\0\1\u04cb"+ + "\32\u045c\1\u04cc\4\u045c\1\u071f\5\u045c\242\0\1\u04cb\32\u045c"+ + "\1\u04cc\1\u045c\1\u0729\10\u045c\242\0\1\u04cb\32\u045c\1\u04cc"+ + "\1\u045c\1\u072a\10\u045c\242\0\1\u04cb\13\u045c\1\u072b\16\u045c"+ + "\1\u04cc\12\u045c\242\0\1\u04cb\3\u045c\1\u072c\26\u045c\1\u04cc"+ + "\12\u045c\242\0\1\u04cb\4\u045c\1\u06c9\25\u045c\1\u04cc\12\u045c"+ + "\243\0\4\u072d\2\0\1\u072d\15\0\1\u072d\6\0\12\u072d"+ + "\1\u068f\241\0\1\u0224\4\u072d\2\0\1\u072d\15\0\1\u072d"+ + "\6\0\12\u072d\1\u068f\242\0\4\u072e\2\0\1\u072e\15\0"+ + "\1\u072e\6\0\12\u072e\13\0\1\u01ad\274\0\1\u0641\12\0"+ + "\1\u01ad\226\0\1\u0136\24\323\1\u072f\5\323\1\u0137\12\323"+ + "\242\0\1\u0136\32\323\1\u0137\6\323\1\u0730\3\323\242\0"+ + "\1\u0136\1\323\1\u0237\30\323\1\u0137\12\323\242\0\1\u0136"+ + "\2\323\1\u0731\27\323\1\u0137\12\323\242\0\1\u0136\3\323"+ + "\1\u0732\26\323\1\u0137\12\323\242\0\1\u0136\3\323\1\u0733"+ + "\26\323\1\u0137\12\323\236\0\1\154\3\0\1\u016f\7\371"+ + "\1\u0734\22\371\1\203\12\371\1\0\3\154\1\0\1\154"+ + "\1\156\3\154\3\0\1\154\3\0\2\154\213\0\1\154"+ + "\3\0\1\u016f\1\u0735\31\371\1\203\12\371\1\0\3\154"+ + "\1\0\1\154\1\156\3\154\3\0\1\154\3\0\2\154"+ + "\213\0\1\154\3\0\1\u016f\32\371\1\203\1\371\1\u0444"+ + "\10\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\220\0\4\u0736\2\0\1\u0736\15\0"+ + "\1\u0736\6\0\12\u0736\1\u06a8\242\0\4\u0737\2\0\1\u0737"+ + "\15\0\1\u0737\6\0\12\u0737\1\u0738\242\0\4\u0739\2\0"+ + "\1\u0739\15\0\1\u0739\6\0\1\u073a\1\u073b\5\u073a\1\u073c"+ + "\1\u073b\1\u073a\13\0\1\u04ba\227\0\4\u073d\2\0\1\u073d"+ + "\15\0\1\u073d\6\0\12\u073d\1\u06f4\12\0\1\u04ba\227\0"+ + "\4\u0739\2\0\1\u0739\15\0\1\u0739\6\0\1\u073a\1\u073b"+ + "\5\u073a\1\u073c\1\u073b\1\u073a\242\0\1\u0522\4\u073d\2\0"+ + "\1\u073d\15\0\1\u073d\6\0\12\u073d\1\u06f4\12\0\1\u04ba"+ + "\226\0\1\u0522\4\u073d\2\0\1\u073d\15\0\1\u073d\6\0"+ + "\12\u073e\1\u06f4\12\0\1\u04ba\226\0\1\u0522\4\u073d\2\0"+ + "\1\u073d\15\0\1\u073d\6\0\2\u073e\1\u073d\2\u073e\2\u073d"+ + "\2\u073e\1\u073d\1\u06f4\12\0\1\u04ba\274\0\1\u0660\12\0"+ + "\1\u04ba\262\0\12\u073f\13\0\1\u04ba\262\0\12\u06f9\13\0"+ + "\1\u04ba\262\0\2\u06f9\1\u073f\1\u06f9\1\u0740\2\u073f\2\u06f9"+ + "\1\u073f\13\0\1\u04ba\274\0\1\u066b\242\0\4\u0741\2\0"+ + "\1\u0741\15\0\1\u0741\6\0\12\u0741\1\u06fe\242\0\4\u0742"+ + "\2\0\1\u0742\15\0\1\u0742\6\0\12\u0742\1\u0743\242\0"+ + "\4\u0744\2\0\1\u0744\15\0\1\u0744\6\0\12\u0744\1\u0745"+ + "\12\0\1\u045b\226\0\1\u04c7\4\u0744\2\0\1\u0744\15\0"+ + "\1\u0744\6\0\12\u0746\1\u0745\12\0\1\u045b\226\0\1\u04c7"+ + "\4\u0744\2\0\1\u0744\15\0\1\u0744\6\0\12\u0747\1\u0745"+ + "\12\0\1\u045b\226\0\1\u04c7\4\u0744\2\0\1\u0744\15\0"+ + "\1\u0744\6\0\2\u0747\1\u0746\1\u0747\1\u0748\2\u0746\2\u0747"+ + "\1\u0746\1\u0745\12\0\1\u045b\227\0\4\u0749\2\0\1\u0749"+ + "\15\0\1\u0749\6\0\12\u0749\1\u06b6\12\0\1\u045b\226\0"+ + "\1\u04c7\4\u0749\2\0\1\u0749\15\0\1\u0749\6\0\12\u0749"+ + "\1\u06b6\12\0\1\u045b\307\0\1\u045b\262\0\2\u0705\1\0"+ + "\2\u0705\2\0\2\u0705\14\0\1\u045b\226\0\1\u04cb\20\u045c"+ + "\1\u074a\11\u045c\1\u04cc\12\u045c\242\0\1\u04cb\1\u045c\1\u074b"+ + "\30\u045c\1\u04cc\12\u045c\242\0\1\u04cb\13\u045c\1\u05b2\16\u045c"+ + "\1\u04cc\12\u045c\242\0\1\u04cb\2\u045c\1\u0633\27\u045c\1\u04cc"+ + "\12\u045c\242\0\1\u04cb\5\u045c\1\u06c5\24\u045c\1\u04cc\12\u045c"+ + "\242\0\1\u04cb\4\u045c\1\u074c\25\u045c\1\u04cc\12\u045c\242\0"+ + "\1\u04cb\3\u045c\1\u074d\26\u045c\1\u04cc\12\u045c\242\0\1\u04cb"+ + "\1\u045c\1\u0633\30\u045c\1\u04cc\12\u045c\242\0\1\u04cb\4\u045c"+ + "\1\u074e\25\u045c\1\u04cc\12\u045c\242\0\1\u04cb\11\u045c\1\u074f"+ + "\20\u045c\1\u04cc\12\u045c\242\0\1\u04cb\1\u045c\1\u0750\30\u045c"+ + "\1\u04cc\12\u045c\242\0\1\u04cb\24\u045c\1\u0751\5\u045c\1\u04cc"+ + "\12\u045c\242\0\1\u04cb\1\u045c\1\u0752\30\u045c\1\u04cc\12\u045c"+ + "\242\0\1\u04cb\14\u045c\1\u0753\15\u045c\1\u04cc\12\u045c\242\0"+ + "\1\u04cb\1\u045c\1\u0754\30\u045c\1\u04cc\12\u045c\242\0\1\u04cb"+ + "\1\u045c\1\u0755\30\u045c\1\u04cc\12\u045c\242\0\1\u04cb\1\u045c"+ + "\1\u0756\30\u045c\1\u04cc\12\u045c\242\0\1\u04cb\24\u045c\1\u0757"+ + "\5\u045c\1\u04cc\12\u045c\242\0\1\u04cb\1\u0758\31\u045c\1\u04cc"+ + "\12\u045c\242\0\1\u04cb\24\u045c\1\u0759\5\u045c\1\u04cc\12\u045c"+ + "\242\0\1\u04cb\24\u045c\1\u075a\5\u045c\1\u04cc\12\u045c\242\0"+ + "\1\u04cb\27\u045c\1\u075b\2\u045c\1\u04cc\12\u045c\242\0\1\u04cb"+ + "\24\u045c\1\u075c\5\u045c\1\u04cc\12\u045c\242\0\1\u04cb\1\u0627"+ + "\31\u045c\1\u04cc\12\u045c\242\0\1\u04cb\24\u045c\1\u0756\5\u045c"+ + "\1\u04cc\12\u045c\242\0\1\u04cb\20\u045c\1\u075d\11\u045c\1\u04cc"+ + "\12\u045c\242\0\1\u04cb\24\u045c\1\u075e\5\u045c\1\u04cc\12\u045c"+ + "\242\0\1\u04cb\1\u045c\1\u075f\30\u045c\1\u04cc\12\u045c\242\0"+ + "\1\u04cb\4\u045c\1\u0760\25\u045c\1\u04cc\12\u045c\242\0\1\u04cb"+ + "\1\u0761\31\u045c\1\u04cc\12\u045c\242\0\1\u04cb\21\u045c\1\u0762"+ + "\10\u045c\1\u04cc\12\u045c\242\0\1\u04cb\4\u045c\1\u0763\25\u045c"+ + "\1\u04cc\12\u045c\242\0\1\u04cb\24\u045c\1\u0764\5\u045c\1\u04cc"+ + "\12\u045c\242\0\1\u04cb\32\u045c\1\u04cc\1\u045c\1\u0765\10\u045c"+ + "\242\0\1\u04cb\1\u0766\31\u045c\1\u04cc\12\u045c\242\0\1\u04cb"+ + "\1\u0767\31\u045c\1\u04cc\12\u045c\242\0\1\u04cb\7\u045c\1\u0633"+ + "\22\u045c\1\u04cc\12\u045c\242\0\1\u04cb\13\u045c\1\u05a6\16\u045c"+ + "\1\u04cc\12\u045c\310\0\1\u068f\242\0\4\u04dc\2\0\1\u04dc"+ + "\15\0\1\u04dc\6\0\12\u04dc\13\0\1\u01ad\226\0\1\u0136"+ + "\32\323\1\u0137\7\323\1\u0768\2\323\242\0\1\u0136\27\323"+ + "\1\u022b\2\323\1\u0137\12\323\242\0\1\u0136\32\323\1\u0137"+ + "\3\323\1\u0769\6\323\242\0\1\u0136\32\323\1\u0137\7\323"+ + "\1\u01c1\2\323\242\0\1\u0136\3\323\1\u076a\26\323\1\u0137"+ + "\12\323\236\0\1\154\3\0\1\u016f\32\371\1\203\7\371"+ + "\1\u076b\2\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\213\0\1\154\3\0\1\u016f"+ + "\4\371\1\u0174\25\371\1\203\12\371\1\0\3\154\1\0"+ + "\1\154\1\156\3\154\3\0\1\154\3\0\2\154\265\0"+ + "\1\u06a8\242\0\4\u076c\2\0\1\u076c\15\0\1\u076c\6\0"+ + "\12\u076c\1\u0738\242\0\4\u076d\2\0\1\u076d\15\0\1\u076d"+ + "\6\0\12\u076d\1\u076e\242\0\4\u076f\2\0\1\u076f\15\0"+ + "\1\u076f\6\0\12\u076f\1\u0770\12\0\1\u04ba\226\0\1\u0522"+ + "\4\u076f\2\0\1\u076f\15\0\1\u076f\6\0\12\u0771\1\u0770"+ + "\12\0\1\u04ba\226\0\1\u0522\4\u076f\2\0\1\u076f\15\0"+ + "\1\u076f\6\0\12\u0772\1\u0770\12\0\1\u04ba\226\0\1\u0522"+ + "\4\u076f\2\0\1\u076f\15\0\1\u076f\6\0\2\u0772\1\u0771"+ + "\1\u0772\1\u0773\2\u0771\2\u0772\1\u0771\1\u0770\12\0\1\u04ba"+ + "\227\0\4\u0774\2\0\1\u0774\15\0\1\u0774\6\0\12\u0774"+ + "\1\u06f4\12\0\1\u04ba\226\0\1\u0522\4\u0774\2\0\1\u0774"+ + "\15\0\1\u0774\6\0\12\u0774\1\u06f4\12\0\1\u04ba\307\0"+ + "\1\u04ba\262\0\2\u073f\1\0\2\u073f\2\0\2\u073f\14\0"+ + "\1\u04ba\227\0\4\u0775\2\0\1\u0775\15\0\1\u0775\6\0"+ + "\12\u0775\1\u06fe\242\0\4\u0776\2\0\1\u0776\15\0\1\u0776"+ + "\6\0\12\u0776\1\u0777\242\0\4\u0778\2\0\1\u0778\15\0"+ + "\1\u0778\6\0\1\u0779\1\u077a\5\u0779\1\u077b\1\u077a\1\u0779"+ + "\13\0\1\u045b\227\0\4\u077c\2\0\1\u077c\15\0\1\u077c"+ + "\6\0\12\u077c\1\u0745\12\0\1\u045b\227\0\4\u0778\2\0"+ + "\1\u0778\15\0\1\u0778\6\0\1\u0779\1\u077a\5\u0779\1\u077b"+ + "\1\u077a\1\u0779\242\0\1\u04c7\4\u077c\2\0\1\u077c\15\0"+ + "\1\u077c\6\0\12\u077c\1\u0745\12\0\1\u045b\226\0\1\u04c7"+ + "\4\u077c\2\0\1\u077c\15\0\1\u077c\6\0\12\u077d\1\u0745"+ + "\12\0\1\u045b\226\0\1\u04c7\4\u077c\2\0\1\u077c\15\0"+ + "\1\u077c\6\0\2\u077d\1\u077c\2\u077d\2\u077c\2\u077d\1\u077c"+ + "\1\u0745\12\0\1\u045b\274\0\1\u06b6\12\0\1\u045b\226\0"+ + "\1\u04cb\1\u045c\1\u077e\30\u045c\1\u04cc\12\u045c\242\0\1\u04cb"+ + "\17\u045c\1\u077f\12\u045c\1\u04cc\12\u045c\242\0\1\u04cb\10\u045c"+ + "\1\u0780\21\u045c\1\u04cc\12\u045c\242\0\1\u04cb\13\u045c\1\u062a"+ + "\16\u045c\1\u04cc\12\u045c\242\0\1\u04cb\1\u0781\31\u045c\1\u04cc"+ + "\12\u045c\242\0\1\u04cb\5\u045c\1\u0782\24\u045c\1\u04cc\12\u045c"+ + "\242\0\1\u04cb\25\u045c\1\u0783\4\u045c\1\u04cc\12\u045c\242\0"+ + "\1\u04cb\15\u045c\1\u0784\14\u045c\1\u04cc\12\u045c\242\0\1\u04cb"+ + "\21\u045c\1\u0785\10\u045c\1\u04cc\12\u045c\242\0\1\u04cb\16\u045c"+ + "\1\u0786\4\u045c\1\u0787\6\u045c\1\u04cc\12\u045c\242\0\1\u04cb"+ + "\4\u045c\1\u0788\25\u045c\1\u04cc\12\u045c\242\0\1\u04cb\32\u045c"+ + "\1\u04cc\7\u045c\1\u0789\2\u045c\242\0\1\u04cb\4\u045c\1\u078a"+ + "\25\u045c\1\u04cc\12\u045c\242\0\1\u04cb\24\u045c\1\u078b\5\u045c"+ + "\1\u04cc\12\u045c\242\0\1\u04cb\1\u045c\1\u078c\30\u045c\1\u04cc"+ + "\12\u045c\242\0\1\u04cb\1\u078d\1\u078e\1\u045c\1\u078f\16\u045c"+ + "\1\u0790\1\u045c\1\u0791\5\u045c\1\u04cc\5\u045c\1\u0792\4\u045c"+ + "\242\0\1\u04cb\1\u045c\1\u0793\30\u045c\1\u04cc\12\u045c\242\0"+ + "\1\u04cb\31\u045c\1\u0794\1\u04cc\12\u045c\242\0\1\u04cb\16\u045c"+ + "\1\u0795\13\u045c\1\u04cc\12\u045c\242\0\1\u04cb\15\u045c\1\u0796"+ + "\14\u045c\1\u04cc\12\u045c\242\0\1\u04cb\11\u045c\1\u0797\13\u045c"+ + "\1\u0798\4\u045c\1\u04cc\12\u045c\242\0\1\u04cb\32\u045c\1\u04cc"+ + "\7\u045c\1\u0799\2\u045c\242\0\1\u04cb\21\u045c\1\u079a\7\u045c"+ + "\1\u079b\1\u04cc\12\u045c\242\0\1\u04cb\12\u045c\1\u079c\17\u045c"+ + "\1\u04cc\12\u045c\242\0\1\u04cb\32\u045c\1\u04cc\10\u045c\1\u079d"+ + "\1\u045c\242\0\1\u04cb\5\u045c\1\u079e\24\u045c\1\u04cc\12\u045c"+ + "\242\0\1\u04cb\10\u045c\1\u079f\21\u045c\1\u04cc\12\u045c\242\0"+ + "\1\u04cb\24\u045c\1\u07a0\5\u045c\1\u04cc\12\u045c\242\0\1\u04cb"+ + "\32\u045c\1\u04cc\1\u07a1\11\u045c\242\0\1\u04cb\5\u045c\1\u07a2"+ + "\10\u045c\1\u07a3\13\u045c\1\u04cc\12\u045c\242\0\1\u0136\7\323"+ + "\1\u07a4\22\323\1\u0137\12\323\242\0\1\u0136\1\u07a5\31\323"+ + "\1\u0137\12\323\242\0\1\u0136\32\323\1\u0137\1\323\1\u04fc"+ + "\10\323\236\0\1\154\3\0\1\u016f\1\u07a6\31\371\1\203"+ + "\12\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\220\0\4\u07a7\2\0\1\u07a7\15\0"+ + "\1\u07a7\6\0\12\u07a7\1\u0738\242\0\4\u07a8\2\0\1\u07a8"+ + "\15\0\1\u07a8\6\0\12\u07a8\1\u07a9\242\0\4\u07aa\2\0"+ + "\1\u07aa\15\0\1\u07aa\6\0\1\u07ab\1\u07ac\5\u07ab\1\u07ad"+ + "\1\u07ac\1\u07ab\13\0\1\u04ba\227\0\4\u07ae\2\0\1\u07ae"+ + "\15\0\1\u07ae\6\0\12\u07ae\1\u0770\12\0\1\u04ba\227\0"+ + "\4\u07aa\2\0\1\u07aa\15\0\1\u07aa\6\0\1\u07ab\1\u07ac"+ + "\5\u07ab\1\u07ad\1\u07ac\1\u07ab\242\0\1\u0522\4\u07ae\2\0"+ + "\1\u07ae\15\0\1\u07ae\6\0\12\u07ae\1\u0770\12\0\1\u04ba"+ + "\226\0\1\u0522\4\u07ae\2\0\1\u07ae\15\0\1\u07ae\6\0"+ + "\12\u07af\1\u0770\12\0\1\u04ba\226\0\1\u0522\4\u07ae\2\0"+ + "\1\u07ae\15\0\1\u07ae\6\0\2\u07af\1\u07ae\2\u07af\2\u07ae"+ + "\2\u07af\1\u07ae\1\u0770\12\0\1\u04ba\274\0\1\u06f4\12\0"+ + "\1\u04ba\274\0\1\u06fe\242\0\4\u07b0\2\0\1\u07b0\15\0"+ + "\1\u07b0\6\0\12\u07b0\1\u0777\242\0\4\u07b1\2\0\1\u07b1"+ + "\15\0\1\u07b1\6\0\1\u07b2\1\u07b3\5\u07b2\1\u07b4\1\u07b3"+ + "\1\u07b2\1\u07b5\242\0\4\u07b6\2\0\1\u07b6\15\0\1\u07b6"+ + "\6\0\12\u07b6\1\u07b7\12\0\1\u045b\226\0\1\u04c7\4\u07b6"+ + "\2\0\1\u07b6\15\0\1\u07b6\6\0\12\u07b8\1\u07b7\12\0"+ + "\1\u045b\226\0\1\u04c7\4\u07b6\2\0\1\u07b6\15\0\1\u07b6"+ + "\6\0\12\u07b9\1\u07b7\12\0\1\u045b\226\0\1\u04c7\4\u07b6"+ + "\2\0\1\u07b6\15\0\1\u07b6\6\0\2\u07b9\1\u07b8\1\u07b9"+ + "\1\u07ba\2\u07b8\2\u07b9\1\u07b8\1\u07b7\12\0\1\u045b\227\0"+ + "\4\u07bb\2\0\1\u07bb\15\0\1\u07bb\6\0\12\u07bb\1\u0745"+ + "\12\0\1\u045b\226\0\1\u04c7\4\u07bb\2\0\1\u07bb\15\0"+ + "\1\u07bb\6\0\12\u07bb\1\u0745\12\0\1\u045b\226\0\1\u04cb"+ + "\17\u045c\1\u07bc\12\u045c\1\u04cc\12\u045c\242\0\1\u04cb\5\u045c"+ + "\1\u07bd\24\u045c\1\u04cc\12\u045c\242\0\1\u04cb\16\u045c\1\u06c9"+ + "\13\u045c\1\u04cc\12\u045c\242\0\1\u04cb\15\u045c\1\u07be\14\u045c"+ + "\1\u04cc\12\u045c\242\0\1\u04cb\7\u045c\1\u062d\22\u045c\1\u04cc"+ + "\12\u045c\242\0\1\u04cb\1\u045c\1\u07bf\30\u045c\1\u04cc\12\u045c"+ + "\242\0\1\u04cb\6\u045c\1\u07c0\23\u045c\1\u04cc\12\u045c\242\0"+ + "\1\u04cb\32\u045c\1\u04cc\3\u045c\1\u079c\6\u045c\242\0\1\u04cb"+ + "\32\u045c\1\u04cc\6\u045c\1\u0633\3\u045c\242\0\1\u04cb\32\u045c"+ + "\1\u04cc\5\u045c\1\u0633\4\u045c\242\0\1\u04cb\27\u045c\1\u07c1"+ + "\2\u045c\1\u04cc\12\u045c\242\0\1\u04cb\1\u045c\1\u07c2\30\u045c"+ + "\1\u04cc\12\u045c\242\0\1\u04cb\27\u045c\1\u07c3\2\u045c\1\u04cc"+ + "\12\u045c\242\0\1\u04cb\1\u07c4\31\u045c\1\u04cc\12\u045c\242\0"+ + "\1\u04cb\1\u045c\1\u05a6\30\u045c\1\u04cc\12\u045c\242\0\1\u04cb"+ + "\1\u07c5\30\u045c\1\u07c6\1\u04cc\1\u07c7\11\u045c\242\0\1\u04cb"+ + "\32\u045c\1\u04cc\1\u045c\1\u07c8\10\u045c\242\0\1\u04cb\4\u045c"+ + "\1\u07c9\25\u045c\1\u04cc\12\u045c\242\0\1\u04cb\32\u045c\1\u04cc"+ + "\3\u045c\1\u07ca\6\u045c\242\0\1\u04cb\25\u045c\1\u07cb\4\u045c"+ + "\1\u04cc\12\u045c\242\0\1\u04cb\1\u07cc\31\u045c\1\u04cc\12\u045c"+ + "\242\0\1\u04cb\32\u045c\1\u04cc\4\u045c\1\u07cd\5\u045c\242\0"+ + "\1\u04cb\24\u045c\1\u07ce\5\u045c\1\u04cc\12\u045c\242\0\1\u04cb"+ + "\32\u045c\1\u04cc\1\u045c\1\u07cf\10\u045c\242\0\1\u04cb\32\u045c"+ + "\1\u04cc\3\u045c\1\u062d\6\u045c\242\0\1\u04cb\32\u045c\1\u04cc"+ + "\11\u045c\1\u0542\242\0\1\u04cb\32\u045c\1\u04cc\10\u045c\1\u078c"+ + "\1\u045c\242\0\1\u04cb\1\u07d0\1\u045c\1\u07d1\27\u045c\1\u04cc"+ + "\12\u045c\242\0\1\u04cb\32\u045c\1\u04cc\10\u045c\1\u07d2\1\u045c"+ + "\242\0\1\u04cb\32\u045c\1\u04cc\4\u045c\1\u07d3\5\u045c\242\0"+ + "\1\u04cb\25\u045c\1\u05a6\4\u045c\1\u04cc\12\u045c\242\0\1\u04cb"+ + "\32\u045c\1\u04cc\5\u045c\1\u07d4\4\u045c\242\0\1\u04cb\32\u045c"+ + "\1\u04cc\3\u045c\1\u07d5\6\u045c\242\0\1\u04cb\32\u045c\1\u04cc"+ + "\7\u045c\1\u07d6\2\u045c\242\0\1\u04cb\32\u045c\1\u04cc\2\u045c"+ + "\1\u07d7\7\u045c\242\0\1\u04cb\1\u078c\31\u045c\1\u04cc\12\u045c"+ + "\242\0\1\u04cb\32\u045c\1\u04cc\7\u045c\1\u07d8\2\u045c\242\0"+ + "\1\u04cb\3\u045c\1\u07d9\15\u045c\1\u05b2\10\u045c\1\u04cc\12\u045c"+ + "\242\0\1\u0136\32\323\1\u0137\7\323\1\u07da\2\323\242\0"+ + "\1\u0136\4\323\1\u022b\25\323\1\u0137\12\323\236\0\1\154"+ + "\3\0\1\u016f\32\371\1\203\5\371\1\u07db\4\371\1\0"+ + "\3\154\1\0\1\154\1\156\3\154\3\0\1\154\3\0"+ + "\2\154\265\0\1\u0738\242\0\4\u07dc\2\0\1\u07dc\15\0"+ + "\1\u07dc\6\0\12\u07dc\1\u07a9\242\0\4\u07dd\2\0\1\u07dd"+ + "\15\0\1\u07dd\6\0\1\u07de\1\u07df\5\u07de\1\u07e0\1\u07df"+ + "\1\u07de\1\u07e1\242\0\4\u07e2\2\0\1\u07e2\15\0\1\u07e2"+ + "\6\0\12\u07e2\1\u07e3\12\0\1\u04ba\226\0\1\u0522\4\u07e2"+ + "\2\0\1\u07e2\15\0\1\u07e2\6\0\12\u07e4\1\u07e3\12\0"+ + "\1\u04ba\226\0\1\u0522\4\u07e2\2\0\1\u07e2\15\0\1\u07e2"+ + "\6\0\12\u07e5\1\u07e3\12\0\1\u04ba\226\0\1\u0522\4\u07e2"+ + "\2\0\1\u07e2\15\0\1\u07e2\6\0\2\u07e5\1\u07e4\1\u07e5"+ + "\1\u07e6\2\u07e4\2\u07e5\1\u07e4\1\u07e3\12\0\1\u04ba\227\0"+ + "\4\u07e7\2\0\1\u07e7\15\0\1\u07e7\6\0\12\u07e7\1\u0770"+ + "\12\0\1\u04ba\226\0\1\u0522\4\u07e7\2\0\1\u07e7\15\0"+ + "\1\u07e7\6\0\12\u07e7\1\u0770\12\0\1\u04ba\227\0\4\u07e8"+ + "\2\0\1\u07e8\15\0\1\u07e8\6\0\12\u07e8\1\u0777\242\0"+ + "\4\u07e9\2\0\1\u07e9\15\0\1\u07e9\6\0\12\u07e9\1\u07ea"+ + "\241\0\1\u04c7\4\u07e9\2\0\1\u07e9\15\0\1\u07e9\6\0"+ + "\12\u07eb\1\u07ea\241\0\1\u04c7\4\u07e9\2\0\1\u07e9\15\0"+ + "\1\u07e9\6\0\12\u07ec\1\u07ea\241\0\1\u04c7\4\u07e9\2\0"+ + "\1\u07e9\15\0\1\u07e9\6\0\2\u07ec\1\u07eb\1\u07ec\1\u07ed"+ + "\2\u07eb\2\u07ec\1\u07eb\1\u07ea\242\0\4\u07ee\2\0\1\u07ee"+ + "\15\0\1\u07ee\6\0\12\u07ee\13\0\1\u045b\227\0\4\u07ef"+ + "\2\0\1\u07ef\15\0\1\u07ef\6\0\12\u07ef\1\u07b7\12\0"+ + "\1\u045b\227\0\4\u07ee\2\0\1\u07ee\15\0\1\u07ee\6\0"+ + "\12\u07ee\242\0\1\u04c7\4\u07ef\2\0\1\u07ef\15\0\1\u07ef"+ + "\6\0\12\u07ef\1\u07b7\12\0\1\u045b\226\0\1\u04c7\4\u07ef"+ + "\2\0\1\u07ef\15\0\1\u07ef\6\0\12\u07f0\1\u07b7\12\0"+ + "\1\u045b\226\0\1\u04c7\4\u07ef\2\0\1\u07ef\15\0\1\u07ef"+ + "\6\0\2\u07f0\1\u07ef\2\u07f0\2\u07ef\2\u07f0\1\u07ef\1\u07b7"+ + "\12\0\1\u045b\274\0\1\u0745\12\0\1\u045b\226\0\1\u04cb"+ + "\10\u045c\1\u07f1\21\u045c\1\u04cc\12\u045c\242\0\1\u04cb\4\u045c"+ + "\1\u0633\25\u045c\1\u04cc\12\u045c\242\0\1\u04cb\25\u045c\1\u062d"+ + "\4\u045c\1\u04cc\12\u045c\242\0\1\u04cb\32\u045c\1\u04cc\1\u045c"+ + "\1\u07f2\10\u045c\242\0\1\u04cb\32\u045c\1\u04cc\6\u045c\1\u07f3"+ + "\3\u045c\242\0\1\u04cb\32\u045c\1\u04cc\5\u045c\1\u07f4\4\u045c"+ + "\242\0\1\u04cb\32\u045c\1\u04cc\5\u045c\1\u07f5\4\u045c\242\0"+ + "\1\u04cb\32\u045c\1\u04cc\5\u045c\1\u078c\4\u045c\242\0\1\u04cb"+ + "\17\u045c\1\u07f6\12\u045c\1\u04cc\12\u045c\242\0\1\u04cb\12\u045c"+ + "\1\u07f7\17\u045c\1\u04cc\12\u045c\242\0\1\u04cb\25\u045c\1\u07f8"+ + "\4\u045c\1\u04cc\12\u045c\242\0\1\u04cb\1\u07f9\31\u045c\1\u04cc"+ + "\12\u045c\242\0\1\u04cb\1\u07fa\31\u045c\1\u04cc\12\u045c\242\0"+ + "\1\u04cb\15\u045c\1\u07fb\14\u045c\1\u04cc\12\u045c\242\0\1\u04cb"+ + "\1\u045c\1\u07fc\30\u045c\1\u04cc\12\u045c\242\0\1\u04cb\32\u045c"+ + "\1\u04cc\10\u045c\1\u07fd\1\u045c\242\0\1\u04cb\21\u045c\1\u07fe"+ + "\10\u045c\1\u04cc\12\u045c\242\0\1\u04cb\1\u07ff\31\u045c\1\u04cc"+ + "\12\u045c\242\0\1\u04cb\32\u045c\1\u04cc\3\u045c\1\u078c\6\u045c"+ + "\242\0\1\u04cb\2\u045c\1\u079c\27\u045c\1\u04cc\12\u045c\242\0"+ + "\1\u04cb\11\u045c\1\u0800\20\u045c\1\u04cc\12\u045c\242\0\1\u04cb"+ + "\11\u045c\1\u0801\20\u045c\1\u04cc\12\u045c\242\0\1\u04cb\32\u045c"+ + "\1\u04cc\1\u0625\11\u045c\242\0\1\u04cb\32\u045c\1\u04cc\2\u045c"+ + "\1\u0625\7\u045c\242\0\1\u04cb\32\u045c\1\u04cc\1\u05b2\11\u045c"+ + "\242\0\1\u04cb\10\u045c\1\u0802\21\u045c\1\u04cc\12\u045c\242\0"+ + "\1\u04cb\1\u0803\31\u045c\1\u04cc\12\u045c\242\0\1\u04cb\32\u045c"+ + "\1\u04cc\1\u045c\1\u0804\10\u045c\242\0\1\u04cb\32\u045c\1\u04cc"+ + "\10\u045c\1\u0542\1\u045c\242\0\1\u04cb\25\u045c\1\u0805\4\u045c"+ + "\1\u04cc\12\u045c\242\0\1\u0136\1\u0806\31\323\1\u0137\12\323"+ + "\236\0\1\154\3\0\1\u016f\7\371\1\u0807\22\371\1\203"+ + "\12\371\1\0\3\154\1\0\1\154\1\156\3\154\3\0"+ + "\1\154\3\0\2\154\220\0\4\u0808\2\0\1\u0808\15\0"+ + "\1\u0808\6\0\12\u0808\1\u07a9\242\0\4\u0809\2\0\1\u0809"+ + "\15\0\1\u0809\6\0\12\u0809\1\u080a\241\0\1\u0522\4\u0809"+ + "\2\0\1\u0809\15\0\1\u0809\6\0\12\u080b\1\u080a\241\0"+ + "\1\u0522\4\u0809\2\0\1\u0809\15\0\1\u0809\6\0\12\u080c"+ + "\1\u080a\241\0\1\u0522\4\u0809\2\0\1\u0809\15\0\1\u0809"+ + "\6\0\2\u080c\1\u080b\1\u080c\1\u080d\2\u080b\2\u080c\1\u080b"+ + "\1\u080a\242\0\4\u080e\2\0\1\u080e\15\0\1\u080e\6\0"+ + "\12\u080e\13\0\1\u04ba\227\0\4\u080f\2\0\1\u080f\15\0"+ + "\1\u080f\6\0\12\u080f\1\u07e3\12\0\1\u04ba\227\0\4\u080e"+ + "\2\0\1\u080e\15\0\1\u080e\6\0\12\u080e\242\0\1\u0522"+ + "\4\u080f\2\0\1\u080f\15\0\1\u080f\6\0\12\u080f\1\u07e3"+ + "\12\0\1\u04ba\226\0\1\u0522\4\u080f\2\0\1\u080f\15\0"+ + "\1\u080f\6\0\12\u0810\1\u07e3\12\0\1\u04ba\226\0\1\u0522"+ + "\4\u080f\2\0\1\u080f\15\0\1\u080f\6\0\2\u0810\1\u080f"+ + "\2\u0810\2\u080f\2\u0810\1\u080f\1\u07e3\12\0\1\u04ba\274\0"+ + "\1\u0770\12\0\1\u04ba\274\0\1\u0777\242\0\4\u0811\2\0"+ + "\1\u0811\15\0\1\u0811\6\0\12\u0811\1\u07ea\242\0\4\u07ee"+ + "\2\0\1\u07ee\15\0\1\u07ee\6\0\12\u07ee\1\u0705\241\0"+ + "\1\u04c7\4\u0811\2\0\1\u0811\15\0\1\u0811\6\0\12\u0811"+ + "\1\u07ea\241\0\1\u04c7\4\u0811\2\0\1\u0811\15\0\1\u0811"+ + "\6\0\12\u0812\1\u07ea\241\0\1\u04c7\4\u0811\2\0\1\u0811"+ + "\15\0\1\u0811\6\0\2\u0812\1\u0811\2\u0812\2\u0811\2\u0812"+ + "\1\u0811\1\u07ea\242\0\4\u0813\2\0\1\u0813\15\0\1\u0813"+ + "\6\0\12\u0813\13\0\1\u045b\227\0\4\u0814\2\0\1\u0814"+ + "\15\0\1\u0814\6\0\12\u0814\1\u07b7\12\0\1\u045b\226\0"+ + "\1\u04c7\4\u0814\2\0\1\u0814\15\0\1\u0814\6\0\12\u0814"+ + "\1\u07b7\12\0\1\u045b\226\0\1\u04cb\5\u045c\1\u072c\24\u045c"+ + "\1\u04cc\12\u045c\242\0\1\u04cb\3\u045c\1\u0815\26\u045c\1\u04cc"+ + "\12\u045c\242\0\1\u04cb\6\u045c\1\u05bc\23\u045c\1\u04cc\12\u045c"+ + "\242\0\1\u04cb\1\u045c\1\u07d2\30\u045c\1\u04cc\12\u045c\242\0"+ + "\1\u04cb\3\u045c\1\u0816\26\u045c\1\u04cc\12\u045c\242\0\1\u04cb"+ + "\32\u045c\1\u04cc\10\u045c\1\u0817\1\u045c\242\0\1\u04cb\32\u045c"+ + "\1\u04cc\2\u045c\1\u0818\7\u045c\242\0\1\u04cb\32\u045c\1\u04cc"+ + "\2\u045c\1\u0819\7\u045c\242\0\1\u04cb\32\u045c\1\u04cc\3\u045c"+ + "\1\u081a\6\u045c\242\0\1\u04cb\32\u045c\1\u04cc\5\u045c\1\u081b"+ + "\4\u045c\242\0\1\u04cb\32\u045c\1\u04cc\3\u045c\1\u081c\6\u045c"+ + "\242\0\1\u04cb\2\u045c\1\u081d\27\u045c\1\u04cc\12\u045c\242\0"+ + "\1\u04cb\1\u081e\31\u045c\1\u04cc\12\u045c\242\0\1\u04cb\24\u045c"+ + "\1\u081f\5\u045c\1\u04cc\12\u045c\242\0\1\u04cb\23\u045c\1\u0625"+ + "\6\u045c\1\u04cc\12\u045c\242\0\1\u04cb\32\u045c\1\u04cc\1\u0820"+ + "\11\u045c\242\0\1\u04cb\32\u045c\1\u04cc\1\u0821\11\u045c\242\0"+ + "\1\u04cb\32\u045c\1\u04cc\11\u045c\1\u0822\242\0\1\u04cb\12\u045c"+ + "\1\u0823\17\u045c\1\u04cc\12\u045c\242\0\1\u04cb\32\u045c\1\u04cc"+ + "\2\u045c\1\u0629\7\u045c\242\0\1\u04cb\2\u045c\1\u0824\27\u045c"+ + "\1\u04cc\12\u045c\242\0\1\u0136\32\323\1\u0137\5\323\1\u0825"+ + "\4\323\236\0\1\154\3\0\1\u016f\1\371\1\u0205\30\371"+ + "\1\203\12\371\1\0\3\154\1\0\1\154\1\156\3\154"+ + "\3\0\1\154\3\0\2\154\265\0\1\u07a9\242\0\4\u0826"+ + "\2\0\1\u0826\15\0\1\u0826\6\0\12\u0826\1\u080a\242\0"+ + "\4\u080e\2\0\1\u080e\15\0\1\u080e\6\0\12\u080e\1\u073f"+ + "\241\0\1\u0522\4\u0826\2\0\1\u0826\15\0\1\u0826\6\0"+ + "\12\u0826\1\u080a\241\0\1\u0522\4\u0826\2\0\1\u0826\15\0"+ + "\1\u0826\6\0\12\u0827\1\u080a\241\0\1\u0522\4\u0826\2\0"+ + "\1\u0826\15\0\1\u0826\6\0\2\u0827\1\u0826\2\u0827\2\u0826"+ + "\2\u0827\1\u0826\1\u080a\242\0\4\u0828\2\0\1\u0828\15\0"+ + "\1\u0828\6\0\12\u0828\13\0\1\u04ba\227\0\4\u0829\2\0"+ + "\1\u0829\15\0\1\u0829\6\0\12\u0829\1\u07e3\12\0\1\u04ba"+ + "\226\0\1\u0522\4\u0829\2\0\1\u0829\15\0\1\u0829\6\0"+ + "\12\u0829\1\u07e3\12\0\1\u04ba\227\0\4\u082a\2\0\1\u082a"+ + "\15\0\1\u082a\6\0\12\u082a\1\u07ea\241\0\1\u04c7\4\u082a"+ + "\2\0\1\u082a\15\0\1\u082a\6\0\12\u082a\1\u07ea\242\0"+ + "\4\u082b\2\0\1\u082b\15\0\1\u082b\6\0\12\u082b\13\0"+ + "\1\u045b\274\0\1\u07b7\12\0\1\u045b\226\0\1\u04cb\1\u082c"+ + "\31\u045c\1\u04cc\12\u045c\242\0\1\u04cb\32\u045c\1\u04cc\7\u045c"+ + "\1\u078c\2\u045c\242\0\1\u04cb\1\u082d\31\u045c\1\u04cc\12\u045c"+ + "\242\0\1\u04cb\1\u082e\31\u045c\1\u04cc\12\u045c\242\0\1\u04cb"+ + "\7\u045c\1\u082f\22\u045c\1\u04cc\12\u045c\242\0\1\u04cb\6\u045c"+ + "\1\u0830\23\u045c\1\u04cc\12\u045c\242\0\1\u04cb\1\u0831\31\u045c"+ + "\1\u04cc\12\u045c\242\0\1\u04cb\1\u0832\31\u045c\1\u04cc\12\u045c"+ + "\242\0\1\u04cb\32\u045c\1\u04cc\1\u045c\1\u0833\10\u045c\242\0"+ + "\1\u04cb\32\u045c\1\u04cc\2\u045c\1\u0834\7\u045c\242\0\1\u04cb"+ + "\6\u045c\1\u05a6\23\u045c\1\u04cc\12\u045c\242\0\1\u04cb\25\u045c"+ + "\1\u0835\4\u045c\1\u04cc\12\u045c\242\0\1\u04cb\1\u0836\31\u045c"+ + "\1\u04cc\12\u045c\242\0\1\u04cb\32\u045c\1\u04cc\2\u045c\1\u05cb"+ + "\7\u045c\242\0\1\u04cb\12\u045c\1\u05cd\17\u045c\1\u04cc\12\u045c"+ + "\242\0\1\u04cb\24\u045c\1\u05a6\5\u045c\1\u04cc\12\u045c\242\0"+ + "\1\u0136\7\323\1\u0837\22\323\1\u0137\12\323\243\0\4\u0838"+ + "\2\0\1\u0838\15\0\1\u0838\6\0\12\u0838\1\u080a\241\0"+ + "\1\u0522\4\u0838\2\0\1\u0838\15\0\1\u0838\6\0\12\u0838"+ + "\1\u080a\242\0\4\u0839\2\0\1\u0839\15\0\1\u0839\6\0"+ + "\12\u0839\13\0\1\u04ba\274\0\1\u07e3\12\0\1\u04ba\274\0"+ + "\1\u07ea\242\0\4\u0705\2\0\1\u0705\15\0\1\u0705\6\0"+ + "\12\u0705\13\0\1\u045b\226\0\1\u04cb\32\u045c\1\u04cc\1\u045c"+ + "\1\u083a\10\u045c\242\0\1\u04cb\2\u045c\1\u083b\27\u045c\1\u04cc"+ + "\12\u045c\242\0\1\u04cb\32\u045c\1\u04cc\6\u045c\1\u079c\3\u045c"+ + "\242\0\1\u04cb\15\u045c\1\u0542\14\u045c\1\u04cc\12\u045c\242\0"+ + "\1\u04cb\32\u045c\1\u04cc\10\u045c\1\u0797\1\u045c\242\0\1\u04cb"+ + "\23\u045c\1\u083c\6\u045c\1\u04cc\12\u045c\242\0\1\u04cb\32\u045c"+ + "\1\u04cc\4\u045c\1\u083d\5\u045c\242\0\1\u04cb\1\u0824\31\u045c"+ + "\1\u04cc\12\u045c\242\0\1\u04cb\32\u045c\1\u04cc\10\u045c\1\u0629"+ + "\1\u045c\242\0\1\u04cb\31\u045c\1\u083e\1\u04cc\12\u045c\242\0"+ + "\1\u04cb\32\u045c\1\u04cc\4\u045c\1\u083f\5\u045c\242\0\1\u0136"+ + "\1\323\1\u02b5\30\323\1\u0137\12\323\310\0\1\u080a\242\0"+ + "\4\u073f\2\0\1\u073f\15\0\1\u073f\6\0\12\u073f\13\0"+ + "\1\u04ba\226\0\1\u04cb\24\u045c\1\u0840\5\u045c\1\u04cc\12\u045c"+ + "\242\0\1\u04cb\32\u045c\1\u04cc\6\u045c\1\u0841\3\u045c\242\0"+ + "\1\u04cb\1\u045c\1\u05b2\30\u045c\1\u04cc\12\u045c\242\0\1\u04cb"+ + "\2\u045c\1\u0842\27\u045c\1\u04cc\12\u045c\242\0\1\u04cb\3\u045c"+ + "\1\u0843\26\u045c\1\u04cc\12\u045c\242\0\1\u04cb\3\u045c\1\u0844"+ + "\26\u045c\1\u04cc\12\u045c\242\0\1\u04cb\32\u045c\1\u04cc\7\u045c"+ + "\1\u0845\2\u045c\242\0\1\u04cb\27\u045c\1\u05a6\2\u045c\1\u04cc"+ + "\12\u045c\242\0\1\u04cb\32\u045c\1\u04cc\3\u045c\1\u0846\6\u045c"+ + "\242\0\1\u04cb\32\u045c\1\u04cc\7\u045c\1\u0542\2\u045c\242\0"+ + "\1\u04cb\3\u045c\1\u0847\26\u045c\1\u04cc\12\u045c\242\0\1\u04cb"+ + "\7\u045c\1\u0848\22\u045c\1\u04cc\12\u045c\242\0\1\u04cb\1\u0849"+ + "\31\u045c\1\u04cc\12\u045c\242\0\1\u04cb\32\u045c\1\u04cc\1\u045c"+ + "\1\u079c\10\u045c\242\0\1\u04cb\32\u045c\1\u04cc\7\u045c\1\u084a"+ + "\2\u045c\242\0\1\u04cb\4\u045c\1\u05a6\25\u045c\1\u04cc\12\u045c"+ + "\242\0\1\u04cb\1\u084b\31\u045c\1\u04cc\12\u045c\242\0\1\u04cb"+ + "\32\u045c\1\u04cc\5\u045c\1\u084c\4\u045c\242\0\1\u04cb\7\u045c"+ + "\1\u084d\22\u045c\1\u04cc\12\u045c\242\0\1\u04cb\1\u045c\1\u0625"+ + "\30\u045c\1\u04cc\12\u045c\24\0"; private static int [] zzUnpackTrans() { - int [] result = new int[341204]; + int [] result = new int[421400]; int offset = 0; offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); offset = zzUnpackTrans(ZZ_TRANS_PACKED_1, offset, result); @@ -3919,25 +5512,31 @@ public final class UAX29URLEmailTokenizerImpl implements StandardTokenizerInterf private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); private static final String ZZ_ATTRIBUTE_PACKED_0 = - "\1\0\1\11\50\1\20\0\1\1\1\0\1\1\12\0"+ - "\1\1\21\0\1\1\32\0\2\1\1\0\4\1\1\0"+ - "\1\1\1\0\4\1\67\0\32\1\3\0\5\1\32\0"+ - "\4\1\21\0\1\11\1\0\24\1\2\0\1\1\1\0"+ - "\10\1\3\0\2\1\1\0\4\1\2\0\2\1\1\0"+ - "\2\1\10\0\1\1\32\0\1\1\1\0\11\1\1\0"+ - "\1\1\2\0\2\1\1\0\1\1\10\0\3\1\15\0"+ - "\11\1\3\0\2\1\1\0\4\1\2\0\4\1\1\0"+ - "\2\1\1\0\2\1\1\0\3\1\3\0\1\1\4\0"+ - "\2\1\20\0\1\1\10\0\1\1\3\0\1\1\40\0"+ - "\3\1\23\0\1\1\40\0\1\1\4\0\1\1\6\0"+ - "\1\1\2\0\1\1\4\0\2\1\43\0\1\1\57\0"+ - "\2\1\10\0\1\1\53\0\1\1\72\0\1\1\150\0"+ - "\1\11\1\0\1\1\177\0\1\1\132\0\6\1\3\0"+ - "\2\1\1\0\4\1\2\0\3\1\112\0\1\1\10\0"+ - "\1\1\64\0\1\1\u01eb\0"; + "\1\0\1\11\51\1\21\0\1\1\1\0\1\1\12\0"+ + "\1\1\10\0\1\1\11\0\1\1\46\0\6\1\2\0"+ + "\5\1\23\0\1\1\70\0\1\1\1\0\32\1\3\0"+ + "\6\1\33\0\4\1\4\0\1\1\22\0\1\11\10\0"+ + "\56\1\1\0\1\1\1\0\11\1\4\0\1\1\1\0"+ + "\2\1\1\0\6\1\1\0\4\1\1\0\4\1\2\0"+ + "\2\1\4\0\1\1\1\0\3\1\2\0\2\1\10\0"+ + "\1\1\41\0\1\1\1\0\35\1\1\0\4\1\2\0"+ + "\2\1\1\0\1\1\37\0\3\1\15\0\12\1\4\0"+ + "\1\1\1\0\2\1\1\0\6\1\1\0\4\1\1\0"+ + "\4\1\2\0\2\1\4\0\1\1\1\0\3\1\1\0"+ + "\2\1\1\0\2\1\1\0\2\1\1\0\24\1\1\0"+ + "\4\1\2\0\1\1\31\0\2\1\20\0\1\1\37\0"+ + "\1\1\3\0\15\1\25\0\3\1\31\0\3\1\50\0"+ + "\13\1\32\0\2\1\1\0\1\1\4\0\1\1\7\0"+ + "\1\1\2\0\1\1\20\0\2\1\61\0\7\1\53\0"+ + "\2\1\6\0\1\1\70\0\6\1\66\0\2\1\62\0"+ + "\3\1\65\0\1\11\1\0\1\1\64\0\1\1\113\0"+ + "\1\1\125\0\7\1\4\0\1\1\1\0\2\1\1\0"+ + "\6\1\1\0\4\1\1\0\4\1\2\0\2\1\4\0"+ + "\1\1\1\0\3\1\1\0\1\1\104\0\1\1\37\0"+ + "\1\1\56\0\1\1\u01e5\0"; private static int [] zzUnpackAttribute() { - int [] result = new int[1750]; + int [] result = new int[2125]; int offset = 0; offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); return result; @@ -4048,7 +5647,6 @@ public final class UAX29URLEmailTokenizerImpl implements StandardTokenizerInterf /** * Creates a new scanner - * There is also a java.io.InputStream version of this constructor. * * @param in the java.io.Reader to read input from. */ @@ -4056,7 +5654,6 @@ public final class UAX29URLEmailTokenizerImpl implements StandardTokenizerInterf this.zzReader = in; } - /** * Unpacks the compressed character translation table. @@ -4068,7 +5665,7 @@ public final class UAX29URLEmailTokenizerImpl implements StandardTokenizerInterf char [] map = new char[0x10000]; int i = 0; /* index in packed string */ int j = 0; /* index in unpacked array */ - while (i < 3010) { + while (i < 3018) { int count = packed.charAt(i++); char value = packed.charAt(i++); do map[j++] = value; while (--count > 0); @@ -4348,7 +5945,7 @@ public final class UAX29URLEmailTokenizerImpl implements StandardTokenizerInterf switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) { case 1: - { /* Break so we don't hit fall-through warning: */ break;/* Not numeric, word, ideographic, hiragana, or SE Asian -- ignore it. */ + { /* Break so we don't hit fall-through warning: */ break; /* Not numeric, word, ideographic, hiragana, or SE Asian -- ignore it. */ } case 12: break; case 2: diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/UAX29URLEmailTokenizerImpl.jflex b/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/UAX29URLEmailTokenizerImpl.jflex index 91bbe2e232d..08ade389faa 100644 --- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/UAX29URLEmailTokenizerImpl.jflex +++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/UAX29URLEmailTokenizerImpl.jflex @@ -35,11 +35,13 @@ import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; * Asian languages, including Thai, Lao, Myanmar, and Khmer *
  • <IDEOGRAPHIC>: A single CJKV ideographic character
  • *
  • <HIRAGANA>: A single hiragana character
  • + *
  • <KATAKANA>: A sequence of katakana characters
  • + *
  • <HANGUL>: A sequence of Hangul characters
  • * */ %% -%unicode 6.1 +%unicode 6.3 %integer %final %public @@ -50,33 +52,39 @@ import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; %buffer 4096 %include SUPPLEMENTARY.jflex-macro -ALetter = ([\p{WB:ALetter}] | {ALetterSupp}) -Format = ([\p{WB:Format}] | {FormatSupp}) -Numeric = ([\p{WB:Numeric}] | {NumericSupp}) -Extend = ([\p{WB:Extend}] | {ExtendSupp}) -Katakana = ([\p{WB:Katakana}] | {KatakanaSupp}) -MidLetter = ([\p{WB:MidLetter}] | {MidLetterSupp}) -MidNum = ([\p{WB:MidNum}] | {MidNumSupp}) -MidNumLet = ([\p{WB:MidNumLet}] | {MidNumLetSupp}) -ExtendNumLet = ([\p{WB:ExtendNumLet}] | {ExtendNumLetSupp}) -ComplexContext = ([\p{LB:Complex_Context}] | {ComplexContextSupp}) -Han = ([\p{Script:Han}] | {HanSupp}) -Hiragana = ([\p{Script:Hiragana}] | {HiraganaSupp}) +ALetter = (\p{WB:ALetter} | {ALetterSupp}) +Format = (\p{WB:Format} | {FormatSupp}) +Numeric = ([\p{WB:Numeric}[\p{Blk:HalfAndFullForms}&&\p{Nd}]] | {NumericSupp}) +Extend = (\p{WB:Extend} | {ExtendSupp}) +Katakana = (\p{WB:Katakana} | {KatakanaSupp}) +MidLetter = (\p{WB:MidLetter} | {MidLetterSupp}) +MidNum = (\p{WB:MidNum} | {MidNumSupp}) +MidNumLet = (\p{WB:MidNumLet} | {MidNumLetSupp}) +ExtendNumLet = (\p{WB:ExtendNumLet} | {ExtendNumLetSupp}) +ComplexContext = (\p{LB:Complex_Context} | {ComplexContextSupp}) +Han = (\p{Script:Han} | {HanSupp}) +Hiragana = (\p{Script:Hiragana} | {HiraganaSupp}) +SingleQuote = (\p{WB:Single_Quote} | {SingleQuoteSupp}) +DoubleQuote = (\p{WB:Double_Quote} | {DoubleQuoteSupp}) +HebrewLetter = (\p{WB:Hebrew_Letter} | {HebrewLetterSupp}) +RegionalIndicator = (\p{WB:Regional_Indicator} | {RegionalIndicatorSupp}) +HebrewOrALetter = ({HebrewLetter} | {ALetter}) -// Script=Hangul & Aletter -HangulEx = (!(!\p{Script:Hangul}|!\p{WB:ALetter})) ({Format} | {Extend})* // UAX#29 WB4. X (Extend | Format)* --> X // -ALetterEx = {ALetter} ({Format} | {Extend})* -// TODO: Convert hard-coded full-width numeric range to property intersection (something like [\p{Full-Width}&&\p{Numeric}]) once JFlex supports it -NumericEx = ({Numeric} | [\uFF10-\uFF19]) ({Format} | {Extend})* -KatakanaEx = {Katakana} ({Format} | {Extend})* -MidLetterEx = ({MidLetter} | {MidNumLet}) ({Format} | {Extend})* -MidNumericEx = ({MidNum} | {MidNumLet}) ({Format} | {Extend})* -ExtendNumLetEx = {ExtendNumLet} ({Format} | {Extend})* - -HanEx = {Han} ({Format} | {Extend})* -HiraganaEx = {Hiragana} ({Format} | {Extend})* +HangulEx = [\p{Script:Hangul}&&[\p{WB:ALetter}\p{WB:Hebrew_Letter}]] ({Format} | {Extend})* +HebrewOrALetterEx = {HebrewOrALetter} ({Format} | {Extend})* +NumericEx = {Numeric} ({Format} | {Extend})* +KatakanaEx = {Katakana} ({Format} | {Extend})* +MidLetterEx = ({MidLetter} | {MidNumLet} | {SingleQuote}) ({Format} | {Extend})* +MidNumericEx = ({MidNum} | {MidNumLet} | {SingleQuote}) ({Format} | {Extend})* +ExtendNumLetEx = {ExtendNumLet} ({Format} | {Extend})* +HanEx = {Han} ({Format} | {Extend})* +HiraganaEx = {Hiragana} ({Format} | {Extend})* +SingleQuoteEx = {SingleQuote} ({Format} | {Extend})* +DoubleQuoteEx = {DoubleQuote} ({Format} | {Extend})* +HebrewLetterEx = {HebrewLetter} ({Format} | {Extend})* +RegionalIndicatorEx = {RegionalIndicator} ({Format} | {Extend})* // URL and E-mail syntax specifications: // @@ -213,40 +221,47 @@ EMAIL = {EMAILlocalPart} "@" ({DomainNameStrict} | {EMAILbracketedHost}) {EMAIL} { return EMAIL_TYPE; } // UAX#29 WB8. Numeric × Numeric -// WB11. Numeric (MidNum | MidNumLet) × Numeric -// WB12. Numeric × (MidNum | MidNumLet) Numeric -// WB13a. (ALetter | Numeric | Katakana | ExtendNumLet) × ExtendNumLet -// WB13b. ExtendNumLet × (ALetter | Numeric | Katakana) +// WB11. Numeric (MidNum | MidNumLet | Single_Quote) × Numeric +// WB12. Numeric × (MidNum | MidNumLet | Single_Quote) Numeric +// WB13a. (ALetter | Hebrew_Letter | Numeric | Katakana | ExtendNumLet) × ExtendNumLet +// WB13b. ExtendNumLet × (ALetter | Hebrew_Letter | Numeric | Katakana) // -{ExtendNumLetEx}* {NumericEx} ({ExtendNumLetEx}+ {NumericEx} - | {MidNumericEx} {NumericEx} - | {NumericEx})* -{ExtendNumLetEx}* +{ExtendNumLetEx}* {NumericEx} ( ( {ExtendNumLetEx}* | {MidNumericEx} ) {NumericEx} )* {ExtendNumLetEx}* { return NUMERIC_TYPE; } // subset of the below for typing purposes only! {HangulEx}+ { return HANGUL_TYPE; } - + {KatakanaEx}+ { return KATAKANA_TYPE; } -// UAX#29 WB5. ALetter × ALetter -// WB6. ALetter × (MidLetter | MidNumLet) ALetter -// WB7. ALetter (MidLetter | MidNumLet) × ALetter -// WB9. ALetter × Numeric -// WB10. Numeric × ALetter +// UAX#29 WB5. (ALetter | Hebrew_Letter) × (ALetter | Hebrew_Letter) +// WB6. (ALetter | Hebrew_Letter) × (MidLetter | MidNumLet | Single_Quote) (ALetter | Hebrew_Letter) +// WB7. (ALetter | Hebrew_Letter) (MidLetter | MidNumLet | Single_Quote) × (ALetter | Hebrew_Letter) +// WB7a. Hebrew_Letter × Single_Quote +// WB7b. Hebrew_Letter × Double_Quote Hebrew_Letter +// WB7c. Hebrew_Letter Double_Quote × Hebrew_Letter +// WB9. (ALetter | Hebrew_Letter) × Numeric +// WB10. Numeric × (ALetter | Hebrew_Letter) // WB13. Katakana × Katakana -// WB13a. (ALetter | Numeric | Katakana | ExtendNumLet) × ExtendNumLet -// WB13b. ExtendNumLet × (ALetter | Numeric | Katakana) +// WB13a. (ALetter | Hebrew_Letter | Numeric | Katakana | ExtendNumLet) × ExtendNumLet +// WB13b. ExtendNumLet × (ALetter | Hebrew_Letter | Numeric | Katakana) // -{ExtendNumLetEx}* ( {KatakanaEx} ({ExtendNumLetEx}* {KatakanaEx})* - | ( {NumericEx} ({ExtendNumLetEx}+ {NumericEx} | {MidNumericEx} {NumericEx} | {NumericEx})* - | {ALetterEx} ({ExtendNumLetEx}+ {ALetterEx} | {MidLetterEx} {ALetterEx} | {ALetterEx})* )+ ) -({ExtendNumLetEx}+ ( {KatakanaEx} ({ExtendNumLetEx}* {KatakanaEx})* - | ( {NumericEx} ({ExtendNumLetEx}+ {NumericEx} | {MidNumericEx} {NumericEx} | {NumericEx})* - | {ALetterEx} ({ExtendNumLetEx}+ {ALetterEx} | {MidLetterEx} {ALetterEx} | {ALetterEx})* )+ ) )* -{ExtendNumLetEx}* +{ExtendNumLetEx}* ( {KatakanaEx} ( {ExtendNumLetEx}* {KatakanaEx} )* + | ( {HebrewLetterEx} ( {SingleQuoteEx} | {DoubleQuoteEx} {HebrewLetterEx} ) + | {NumericEx} ( ( {ExtendNumLetEx}* | {MidNumericEx} )* {NumericEx} )* + | {HebrewOrALetterEx} ( ( {ExtendNumLetEx}* | {MidLetterEx} )* {HebrewOrALetterEx} )* + )+ + ) +({ExtendNumLetEx}+ ( {KatakanaEx} ( {ExtendNumLetEx}* {KatakanaEx} )* + | ( {HebrewLetterEx} ( {SingleQuoteEx} | {DoubleQuoteEx} {HebrewLetterEx} ) + | {NumericEx} ( ( {ExtendNumLetEx}* | {MidNumericEx} )* {NumericEx} )* + | {HebrewOrALetterEx} ( ( {ExtendNumLetEx}* | {MidLetterEx} )* {HebrewOrALetterEx} )* + )+ + ) +)* +{ExtendNumLetEx}* { return WORD_TYPE; } @@ -258,7 +273,7 @@ EMAIL = {EMAILlocalPart} "@" ({DomainNameStrict} | {EMAILbracketedHost}) // annex. That means that satisfactory treatment of languages like Chinese // or Thai requires special handling. // -// In Unicode 6.1, only one character has the \p{Line_Break = Contingent_Break} +// In Unicode 6.3, only one character has the \p{Line_Break = Contingent_Break} // property: U+FFFC (  ) OBJECT REPLACEMENT CHARACTER. // // In the ICU implementation of UAX#29, \p{Line_Break = Complex_Context} @@ -280,6 +295,8 @@ EMAIL = {EMAILlocalPart} "@" ({DomainNameStrict} | {EMAILbracketedHost}) // UAX#29 WB3. CR × LF // WB3a. (Newline | CR | LF) ÷ // WB3b. ÷ (Newline | CR | LF) +// WB13c. Regional_Indicator × Regional_Indicator // WB14. Any ÷ Any // -[^] { /* Break so we don't hit fall-through warning: */ break;/* Not numeric, word, ideographic, hiragana, or SE Asian -- ignore it. */ } +{RegionalIndicatorEx} {RegionalIndicatorEx}+ | [^] + { /* Break so we don't hit fall-through warning: */ break; /* Not numeric, word, ideographic, hiragana, or SE Asian -- ignore it. */ } diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/wikipedia/WikipediaTokenizerImpl.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/wikipedia/WikipediaTokenizerImpl.java index f5723182f53..bdacc563f9a 100644 --- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/wikipedia/WikipediaTokenizerImpl.java +++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/wikipedia/WikipediaTokenizerImpl.java @@ -1,4 +1,4 @@ -/* The following code was generated by JFlex. */ +/* The following code was generated by JFlex 1.5.0-SNAPSHOT */ package org.apache.lucene.analysis.wikipedia; @@ -84,21 +84,20 @@ class WikipediaTokenizerImpl { private static final int [] ZZ_ACTION = zzUnpackAction(); private static final String ZZ_ACTION_PACKED_0 = - "\12\0\4\1\4\2\1\3\1\1\1\4\1\1\2\5"+ - "\1\6\2\5\1\7\1\5\2\10\1\11\1\12\1\11"+ - "\1\13\1\14\1\10\1\15\1\16\1\15\1\17\1\20"+ - "\1\10\1\21\1\10\4\22\1\23\1\22\1\24\1\25"+ - "\1\26\3\0\1\27\14\0\1\30\1\31\1\32\1\33"+ - "\1\11\1\0\1\34\1\35\1\36\1\0\1\37\1\0"+ - "\1\40\3\0\1\41\1\42\2\43\1\42\2\44\2\0"+ - "\1\43\1\0\14\43\1\42\3\0\1\11\1\45\3\0"+ - "\1\46\1\47\5\0\1\50\4\0\1\50\2\0\2\50"+ - "\2\0\1\11\5\0\1\31\1\42\1\43\1\51\3\0"+ - "\1\11\2\0\1\52\30\0\1\53\2\0\1\54\1\55"+ - "\1\56"; + "\12\0\4\1\4\2\1\3\1\4\1\1\2\5\1\6"+ + "\1\5\1\7\1\5\2\10\1\11\1\5\1\12\1\11"+ + "\1\13\1\14\1\15\1\16\1\15\1\17\1\20\1\10"+ + "\1\21\1\10\4\22\1\23\1\24\1\25\1\26\3\0"+ + "\1\27\14\0\1\30\1\31\1\32\1\33\1\11\1\0"+ + "\1\34\1\35\1\36\1\0\1\37\1\0\1\40\3\0"+ + "\1\41\1\42\2\43\1\42\2\44\2\0\1\43\1\0"+ + "\14\43\1\42\3\0\1\11\1\45\3\0\1\46\1\47"+ + "\5\0\1\50\4\0\1\50\2\0\2\50\2\0\1\11"+ + "\5\0\1\31\1\42\1\43\1\51\3\0\1\11\2\0"+ + "\1\52\30\0\1\53\2\0\1\54\1\55\1\56"; private static int [] zzUnpackAction() { - int [] result = new int[184]; + int [] result = new int[181]; int offset = 0; offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); return result; @@ -125,30 +124,30 @@ class WikipediaTokenizerImpl { private static final String ZZ_ROWMAP_PACKED_0 = "\0\0\0\54\0\130\0\204\0\260\0\334\0\u0108\0\u0134"+ "\0\u0160\0\u018c\0\u01b8\0\u01e4\0\u0210\0\u023c\0\u0268\0\u0294"+ - "\0\u02c0\0\u02ec\0\u01b8\0\u0318\0\u0344\0\u0370\0\u01b8\0\u039c"+ - "\0\u03c8\0\u03f4\0\u0420\0\u044c\0\u0478\0\u01b8\0\u039c\0\u04a4"+ - "\0\u01b8\0\u04d0\0\u04fc\0\u0528\0\u0554\0\u0580\0\u05ac\0\u05d8"+ - "\0\u0604\0\u0630\0\u065c\0\u0688\0\u06b4\0\u01b8\0\u06e0\0\u039c"+ - "\0\u070c\0\u0738\0\u0764\0\u0790\0\u01b8\0\u01b8\0\u07bc\0\u07e8"+ - "\0\u0814\0\u01b8\0\u0840\0\u086c\0\u0898\0\u08c4\0\u08f0\0\u091c"+ - "\0\u0948\0\u0974\0\u09a0\0\u09cc\0\u09f8\0\u0a24\0\u0a50\0\u0a7c"+ - "\0\u01b8\0\u01b8\0\u0aa8\0\u0ad4\0\u0b00\0\u0b00\0\u01b8\0\u0b2c"+ + "\0\u02c0\0\u02ec\0\u01b8\0\u0318\0\u0344\0\u01b8\0\u0370\0\u039c"+ + "\0\u03c8\0\u03f4\0\u0420\0\u01b8\0\u0370\0\u044c\0\u0478\0\u01b8"+ + "\0\u04a4\0\u04d0\0\u04fc\0\u0528\0\u0554\0\u0580\0\u05ac\0\u05d8"+ + "\0\u0604\0\u0630\0\u065c\0\u01b8\0\u0688\0\u0370\0\u06b4\0\u06e0"+ + "\0\u070c\0\u01b8\0\u01b8\0\u0738\0\u0764\0\u0790\0\u01b8\0\u07bc"+ + "\0\u07e8\0\u0814\0\u0840\0\u086c\0\u0898\0\u08c4\0\u08f0\0\u091c"+ + "\0\u0948\0\u0974\0\u09a0\0\u09cc\0\u09f8\0\u01b8\0\u01b8\0\u0a24"+ + "\0\u0a50\0\u0a7c\0\u0a7c\0\u01b8\0\u0aa8\0\u0ad4\0\u0b00\0\u0b2c"+ "\0\u0b58\0\u0b84\0\u0bb0\0\u0bdc\0\u0c08\0\u0c34\0\u0c60\0\u0c8c"+ - "\0\u0cb8\0\u0ce4\0\u0d10\0\u0898\0\u0d3c\0\u0d68\0\u0d94\0\u0dc0"+ + "\0\u0814\0\u0cb8\0\u0ce4\0\u0d10\0\u0d3c\0\u0d68\0\u0d94\0\u0dc0"+ "\0\u0dec\0\u0e18\0\u0e44\0\u0e70\0\u0e9c\0\u0ec8\0\u0ef4\0\u0f20"+ - "\0\u0f4c\0\u0f78\0\u0fa4\0\u0fd0\0\u0ffc\0\u1028\0\u1054\0\u1080"+ - "\0\u10ac\0\u10d8\0\u01b8\0\u1104\0\u1130\0\u115c\0\u1188\0\u01b8"+ + "\0\u0f4c\0\u0f78\0\u0fa4\0\u0fd0\0\u0ffc\0\u1028\0\u1054\0\u01b8"+ + "\0\u1080\0\u10ac\0\u10d8\0\u1104\0\u01b8\0\u1130\0\u115c\0\u1188"+ "\0\u11b4\0\u11e0\0\u120c\0\u1238\0\u1264\0\u1290\0\u12bc\0\u12e8"+ - "\0\u1314\0\u1340\0\u136c\0\u1398\0\u13c4\0\u086c\0\u09f8\0\u13f0"+ - "\0\u141c\0\u1448\0\u1474\0\u14a0\0\u14cc\0\u14f8\0\u1524\0\u01b8"+ - "\0\u1550\0\u157c\0\u15a8\0\u15d4\0\u1600\0\u162c\0\u1658\0\u1684"+ - "\0\u16b0\0\u01b8\0\u16dc\0\u1708\0\u1734\0\u1760\0\u178c\0\u17b8"+ + "\0\u1314\0\u1340\0\u07e8\0\u0974\0\u136c\0\u1398\0\u13c4\0\u13f0"+ + "\0\u141c\0\u1448\0\u1474\0\u14a0\0\u01b8\0\u14cc\0\u14f8\0\u1524"+ + "\0\u1550\0\u157c\0\u15a8\0\u15d4\0\u1600\0\u162c\0\u01b8\0\u1658"+ + "\0\u1684\0\u16b0\0\u16dc\0\u1708\0\u1734\0\u1760\0\u178c\0\u17b8"+ "\0\u17e4\0\u1810\0\u183c\0\u1868\0\u1894\0\u18c0\0\u18ec\0\u1918"+ "\0\u1944\0\u1970\0\u199c\0\u19c8\0\u19f4\0\u1a20\0\u1a4c\0\u1a78"+ - "\0\u1aa4\0\u1ad0\0\u1afc\0\u1b28\0\u1b54\0\u01b8\0\u01b8\0\u01b8"; + "\0\u1aa4\0\u1ad0\0\u01b8\0\u01b8\0\u01b8"; private static int [] zzUnpackRowMap() { - int [] result = new int[184]; + int [] result = new int[181]; int offset = 0; offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); return result; @@ -172,152 +171,149 @@ class WikipediaTokenizerImpl { private static final String ZZ_TRANS_PACKED_0 = "\1\13\1\14\5\13\1\15\1\13\1\16\3\13\1\17"+ - "\1\20\1\21\1\22\1\23\1\24\2\13\1\25\2\13"+ - "\15\17\1\26\2\13\3\17\1\13\7\27\1\30\5\27"+ - "\4\31\1\27\1\32\3\27\1\33\1\27\15\31\3\27"+ - "\3\31\10\27\1\30\5\27\4\34\1\27\1\32\3\27"+ - "\1\35\1\27\15\34\3\27\3\34\1\27\7\36\1\37"+ - "\5\36\4\40\1\36\1\32\2\27\1\36\1\41\1\36"+ - "\15\40\3\36\1\42\2\40\2\36\1\43\5\36\1\37"+ - "\5\36\4\44\1\36\1\45\2\36\1\46\2\36\15\44"+ - "\3\36\3\44\10\36\1\37\5\36\4\47\1\36\1\45"+ - "\2\36\1\46\2\36\15\47\3\36\3\47\10\36\1\37"+ - "\5\36\4\47\1\36\1\45\2\36\1\50\2\36\15\47"+ - "\3\36\3\47\10\36\1\37\1\36\1\51\3\36\4\52"+ - "\1\36\1\45\5\36\15\52\3\36\3\52\10\36\1\53"+ - "\5\36\4\54\1\36\1\45\5\36\15\54\1\36\1\55"+ - "\1\36\3\54\1\36\1\56\1\57\5\56\1\60\1\56"+ - "\1\61\3\56\4\62\1\56\1\63\2\56\1\64\2\56"+ - "\15\62\2\56\1\65\3\62\1\56\55\0\1\66\62\0"+ - "\1\67\4\0\4\70\7\0\6\70\1\71\6\70\3\0"+ - "\3\70\12\0\1\72\43\0\1\73\1\74\1\75\1\76"+ - "\2\77\1\0\1\100\3\0\1\100\1\17\1\20\1\21"+ - "\1\22\7\0\15\17\3\0\3\17\3\0\1\101\1\0"+ - "\1\102\2\103\1\0\1\104\3\0\1\104\3\20\1\22"+ - "\7\0\15\20\3\0\3\20\2\0\1\73\1\105\1\75"+ - "\1\76\2\103\1\0\1\104\3\0\1\104\1\21\1\20"+ - "\1\21\1\22\7\0\15\21\3\0\3\21\3\0\1\106"+ - "\1\0\1\102\2\77\1\0\1\100\3\0\1\100\4\22"+ - "\7\0\15\22\3\0\3\22\24\0\1\13\55\0\1\107"+ - "\73\0\1\110\16\0\1\67\4\0\4\70\7\0\15\70"+ - "\3\0\3\70\16\0\4\31\7\0\15\31\3\0\3\31"+ - "\24\0\1\27\56\0\1\111\42\0\4\34\7\0\15\34"+ - "\3\0\3\34\27\0\1\112\42\0\4\40\7\0\15\40"+ - "\3\0\3\40\16\0\4\40\7\0\2\40\1\113\12\40"+ - "\3\0\3\40\2\0\1\114\67\0\4\44\7\0\15\44"+ - "\3\0\3\44\24\0\1\36\55\0\1\115\43\0\4\47"+ - "\7\0\15\47\3\0\3\47\26\0\1\116\37\0\1\117"+ - "\57\0\4\52\7\0\15\52\3\0\3\52\11\0\1\120"+ - "\4\0\4\70\7\0\15\70\3\0\3\70\16\0\4\54"+ - "\7\0\15\54\3\0\3\54\47\0\1\117\6\0\1\121"+ - "\63\0\1\122\57\0\4\62\7\0\15\62\3\0\3\62"+ - "\24\0\1\56\55\0\1\123\43\0\4\70\7\0\15\70"+ - "\3\0\3\70\14\0\1\36\1\0\4\124\1\0\3\125"+ - "\3\0\15\124\3\0\3\124\14\0\1\36\1\0\4\124"+ - "\1\0\3\125\3\0\3\124\1\126\11\124\3\0\3\124"+ - "\16\0\1\127\1\0\1\127\10\0\15\127\3\0\3\127"+ - "\16\0\1\130\1\131\1\132\1\133\7\0\15\130\3\0"+ - "\3\130\16\0\1\134\1\0\1\134\10\0\15\134\3\0"+ - "\3\134\16\0\1\135\1\136\1\135\1\136\7\0\15\135"+ - "\3\0\3\135\16\0\1\137\2\140\1\141\7\0\15\137"+ - "\3\0\3\137\16\0\1\100\2\142\10\0\15\100\3\0"+ - "\3\100\16\0\1\143\2\144\1\145\7\0\15\143\3\0"+ - "\3\143\16\0\4\136\7\0\15\136\3\0\3\136\16\0"+ - "\1\146\2\147\1\150\7\0\15\146\3\0\3\146\16\0"+ - "\1\151\2\152\1\153\7\0\15\151\3\0\3\151\16\0"+ - "\1\154\1\144\1\155\1\145\7\0\15\154\3\0\3\154"+ - "\16\0\1\156\2\131\1\133\7\0\15\156\3\0\3\156"+ - "\30\0\1\157\1\160\64\0\1\161\27\0\4\40\7\0"+ - "\2\40\1\162\12\40\3\0\3\40\2\0\1\163\101\0"+ - "\1\164\1\165\40\0\4\70\7\0\6\70\1\166\6\70"+ - "\3\0\3\70\2\0\1\167\63\0\1\170\71\0\1\171"+ - "\1\172\34\0\1\173\1\0\1\36\1\0\4\124\1\0"+ - "\3\125\3\0\15\124\3\0\3\124\16\0\4\174\1\0"+ - "\3\125\3\0\15\174\3\0\3\174\12\0\1\173\1\0"+ - "\1\36\1\0\4\124\1\0\3\125\3\0\10\124\1\175"+ - "\4\124\3\0\3\124\2\0\1\73\13\0\1\127\1\0"+ - "\1\127\10\0\15\127\3\0\3\127\3\0\1\176\1\0"+ - "\1\102\2\177\6\0\1\130\1\131\1\132\1\133\7\0"+ - "\15\130\3\0\3\130\3\0\1\200\1\0\1\102\2\201"+ - "\1\0\1\202\3\0\1\202\3\131\1\133\7\0\15\131"+ - "\3\0\3\131\3\0\1\203\1\0\1\102\2\201\1\0"+ - "\1\202\3\0\1\202\1\132\1\131\1\132\1\133\7\0"+ - "\15\132\3\0\3\132\3\0\1\204\1\0\1\102\2\177"+ - "\6\0\4\133\7\0\15\133\3\0\3\133\3\0\1\205"+ - "\2\0\1\205\7\0\1\135\1\136\1\135\1\136\7\0"+ - "\15\135\3\0\3\135\3\0\1\205\2\0\1\205\7\0"+ - "\4\136\7\0\15\136\3\0\3\136\3\0\1\177\1\0"+ - "\1\102\2\177\6\0\1\137\2\140\1\141\7\0\15\137"+ - "\3\0\3\137\3\0\1\201\1\0\1\102\2\201\1\0"+ - "\1\202\3\0\1\202\3\140\1\141\7\0\15\140\3\0"+ - "\3\140\3\0\1\177\1\0\1\102\2\177\6\0\4\141"+ - "\7\0\15\141\3\0\3\141\3\0\1\202\2\0\2\202"+ - "\1\0\1\202\3\0\1\202\3\142\10\0\15\142\3\0"+ - "\3\142\3\0\1\106\1\0\1\102\2\77\1\0\1\100"+ - "\3\0\1\100\1\143\2\144\1\145\7\0\15\143\3\0"+ - "\3\143\3\0\1\101\1\0\1\102\2\103\1\0\1\104"+ - "\3\0\1\104\3\144\1\145\7\0\15\144\3\0\3\144"+ - "\3\0\1\106\1\0\1\102\2\77\1\0\1\100\3\0"+ - "\1\100\4\145\7\0\15\145\3\0\3\145\3\0\1\77"+ - "\1\0\1\102\2\77\1\0\1\100\3\0\1\100\1\146"+ - "\2\147\1\150\7\0\15\146\3\0\3\146\3\0\1\103"+ - "\1\0\1\102\2\103\1\0\1\104\3\0\1\104\3\147"+ - "\1\150\7\0\15\147\3\0\3\147\3\0\1\77\1\0"+ - "\1\102\2\77\1\0\1\100\3\0\1\100\4\150\7\0"+ - "\15\150\3\0\3\150\3\0\1\100\2\0\2\100\1\0"+ - "\1\100\3\0\1\100\1\151\2\152\1\153\7\0\15\151"+ - "\3\0\3\151\3\0\1\104\2\0\2\104\1\0\1\104"+ - "\3\0\1\104\3\152\1\153\7\0\15\152\3\0\3\152"+ - "\3\0\1\100\2\0\2\100\1\0\1\100\3\0\1\100"+ - "\4\153\7\0\15\153\3\0\3\153\3\0\1\206\1\0"+ - "\1\102\2\77\1\0\1\100\3\0\1\100\1\154\1\144"+ - "\1\155\1\145\7\0\15\154\3\0\3\154\3\0\1\207"+ - "\1\0\1\102\2\103\1\0\1\104\3\0\1\104\1\155"+ - "\1\144\1\155\1\145\7\0\15\155\3\0\3\155\3\0"+ - "\1\204\1\0\1\102\2\177\6\0\1\156\2\131\1\133"+ - "\7\0\15\156\3\0\3\156\31\0\1\160\54\0\1\210"+ - "\64\0\1\211\26\0\4\40\7\0\15\40\3\0\1\40"+ - "\1\212\1\40\31\0\1\165\54\0\1\213\35\0\1\36"+ - "\1\0\4\124\1\0\3\125\3\0\3\124\1\214\11\124"+ - "\3\0\3\124\2\0\1\215\102\0\1\172\54\0\1\216"+ - "\34\0\1\217\52\0\1\173\3\0\4\174\7\0\15\174"+ - "\3\0\3\174\12\0\1\173\1\0\1\220\1\0\4\124"+ - "\1\0\3\125\3\0\15\124\3\0\3\124\16\0\1\221"+ - "\1\133\1\221\1\133\7\0\15\221\3\0\3\221\16\0"+ - "\4\141\7\0\15\141\3\0\3\141\16\0\4\145\7\0"+ - "\15\145\3\0\3\145\16\0\4\150\7\0\15\150\3\0"+ - "\3\150\16\0\4\153\7\0\15\153\3\0\3\153\16\0"+ - "\1\222\1\145\1\222\1\145\7\0\15\222\3\0\3\222"+ - "\16\0\4\133\7\0\15\133\3\0\3\133\16\0\4\223"+ - "\7\0\15\223\3\0\3\223\33\0\1\224\61\0\1\225"+ - "\30\0\4\40\6\0\1\226\15\40\3\0\2\40\1\227"+ - "\33\0\1\230\32\0\1\173\1\0\1\36\1\0\4\124"+ - "\1\0\3\125\3\0\10\124\1\231\4\124\3\0\3\124"+ - "\2\0\1\232\104\0\1\233\36\0\4\234\7\0\15\234"+ - "\3\0\3\234\3\0\1\176\1\0\1\102\2\177\6\0"+ - "\1\221\1\133\1\221\1\133\7\0\15\221\3\0\3\221"+ - "\3\0\1\206\1\0\1\102\2\77\1\0\1\100\3\0"+ - "\1\100\1\222\1\145\1\222\1\145\7\0\15\222\3\0"+ - "\3\222\3\0\1\205\2\0\1\205\7\0\4\223\7\0"+ - "\15\223\3\0\3\223\34\0\1\235\55\0\1\236\26\0"+ - "\1\237\60\0\4\40\6\0\1\226\15\40\3\0\3\40"+ - "\34\0\1\240\31\0\1\173\1\0\1\117\1\0\4\124"+ - "\1\0\3\125\3\0\15\124\3\0\3\124\34\0\1\241"+ - "\32\0\1\242\2\0\4\234\7\0\15\234\3\0\3\234"+ - "\35\0\1\243\62\0\1\244\20\0\1\245\77\0\1\246"+ - "\53\0\1\247\32\0\1\36\1\0\4\174\1\0\3\125"+ - "\3\0\15\174\3\0\3\174\36\0\1\250\53\0\1\251"+ - "\33\0\4\252\7\0\15\252\3\0\3\252\36\0\1\253"+ - "\53\0\1\254\54\0\1\255\61\0\1\256\11\0\1\257"+ - "\12\0\4\252\7\0\15\252\3\0\3\252\37\0\1\260"+ - "\53\0\1\261\54\0\1\262\22\0\1\13\62\0\4\263"+ - "\7\0\15\263\3\0\3\263\40\0\1\264\53\0\1\265"+ - "\43\0\1\266\26\0\2\263\1\0\2\263\1\0\2\263"+ - "\2\0\5\263\7\0\15\263\3\0\4\263\27\0\1\267"+ - "\53\0\1\270\24\0"; + "\1\20\1\21\1\22\1\23\3\13\1\24\2\13\15\17"+ + "\1\25\2\13\3\17\1\13\7\26\1\27\5\26\4\30"+ + "\5\26\1\31\1\26\15\30\3\26\3\30\10\26\1\27"+ + "\5\26\4\32\5\26\1\33\1\26\15\32\3\26\3\32"+ + "\1\26\7\34\1\35\5\34\4\36\1\34\1\37\2\26"+ + "\1\34\1\40\1\34\15\36\3\34\1\41\2\36\2\34"+ + "\1\42\5\34\1\35\5\34\4\43\4\34\1\44\2\34"+ + "\15\43\3\34\3\43\10\34\1\35\5\34\4\45\4\34"+ + "\1\44\2\34\15\45\3\34\3\45\10\34\1\35\5\34"+ + "\4\45\4\34\1\46\2\34\15\45\3\34\3\45\10\34"+ + "\1\35\1\34\1\47\3\34\4\50\7\34\15\50\3\34"+ + "\3\50\10\34\1\51\5\34\4\52\7\34\15\52\1\34"+ + "\1\53\1\34\3\52\1\34\1\54\1\55\5\54\1\56"+ + "\1\54\1\57\3\54\4\60\4\54\1\61\2\54\15\60"+ + "\2\54\1\62\3\60\1\54\55\0\1\63\62\0\1\64"+ + "\4\0\4\65\7\0\6\65\1\66\6\65\3\0\3\65"+ + "\12\0\1\67\43\0\1\70\1\71\1\72\1\73\2\74"+ + "\1\0\1\75\3\0\1\75\1\17\1\20\1\21\1\22"+ + "\7\0\15\17\3\0\3\17\3\0\1\76\1\0\1\77"+ + "\2\100\1\0\1\101\3\0\1\101\3\20\1\22\7\0"+ + "\15\20\3\0\3\20\2\0\1\70\1\102\1\72\1\73"+ + "\2\100\1\0\1\101\3\0\1\101\1\21\1\20\1\21"+ + "\1\22\7\0\15\21\3\0\3\21\3\0\1\103\1\0"+ + "\1\77\2\74\1\0\1\75\3\0\1\75\4\22\7\0"+ + "\15\22\3\0\3\22\26\0\1\104\73\0\1\105\16\0"+ + "\1\64\4\0\4\65\7\0\15\65\3\0\3\65\16\0"+ + "\4\30\7\0\15\30\3\0\3\30\27\0\1\106\42\0"+ + "\4\32\7\0\15\32\3\0\3\32\27\0\1\107\42\0"+ + "\4\36\7\0\15\36\3\0\3\36\24\0\1\26\45\0"+ + "\4\36\7\0\2\36\1\110\12\36\3\0\3\36\2\0"+ + "\1\111\67\0\4\43\7\0\15\43\3\0\3\43\26\0"+ + "\1\112\43\0\4\45\7\0\15\45\3\0\3\45\26\0"+ + "\1\113\37\0\1\114\57\0\4\50\7\0\15\50\3\0"+ + "\3\50\11\0\1\115\4\0\4\65\7\0\15\65\3\0"+ + "\3\65\16\0\4\52\7\0\15\52\3\0\3\52\47\0"+ + "\1\114\6\0\1\116\63\0\1\117\57\0\4\60\7\0"+ + "\15\60\3\0\3\60\26\0\1\120\43\0\4\65\7\0"+ + "\15\65\3\0\3\65\14\0\1\34\1\0\4\121\1\0"+ + "\3\122\3\0\15\121\3\0\3\121\14\0\1\34\1\0"+ + "\4\121\1\0\3\122\3\0\3\121\1\123\11\121\3\0"+ + "\3\121\16\0\1\124\1\0\1\124\10\0\15\124\3\0"+ + "\3\124\16\0\1\125\1\126\1\127\1\130\7\0\15\125"+ + "\3\0\3\125\16\0\1\131\1\0\1\131\10\0\15\131"+ + "\3\0\3\131\16\0\1\132\1\133\1\132\1\133\7\0"+ + "\15\132\3\0\3\132\16\0\1\134\2\135\1\136\7\0"+ + "\15\134\3\0\3\134\16\0\1\75\2\137\10\0\15\75"+ + "\3\0\3\75\16\0\1\140\2\141\1\142\7\0\15\140"+ + "\3\0\3\140\16\0\4\133\7\0\15\133\3\0\3\133"+ + "\16\0\1\143\2\144\1\145\7\0\15\143\3\0\3\143"+ + "\16\0\1\146\2\147\1\150\7\0\15\146\3\0\3\146"+ + "\16\0\1\151\1\141\1\152\1\142\7\0\15\151\3\0"+ + "\3\151\16\0\1\153\2\126\1\130\7\0\15\153\3\0"+ + "\3\153\30\0\1\154\1\155\64\0\1\156\27\0\4\36"+ + "\7\0\2\36\1\157\12\36\3\0\3\36\2\0\1\160"+ + "\101\0\1\161\1\162\40\0\4\65\7\0\6\65\1\163"+ + "\6\65\3\0\3\65\2\0\1\164\63\0\1\165\71\0"+ + "\1\166\1\167\34\0\1\170\1\0\1\34\1\0\4\121"+ + "\1\0\3\122\3\0\15\121\3\0\3\121\16\0\4\171"+ + "\1\0\3\122\3\0\15\171\3\0\3\171\12\0\1\170"+ + "\1\0\1\34\1\0\4\121\1\0\3\122\3\0\10\121"+ + "\1\172\4\121\3\0\3\121\2\0\1\70\13\0\1\124"+ + "\1\0\1\124\10\0\15\124\3\0\3\124\3\0\1\173"+ + "\1\0\1\77\2\174\6\0\1\125\1\126\1\127\1\130"+ + "\7\0\15\125\3\0\3\125\3\0\1\175\1\0\1\77"+ + "\2\176\1\0\1\177\3\0\1\177\3\126\1\130\7\0"+ + "\15\126\3\0\3\126\3\0\1\200\1\0\1\77\2\176"+ + "\1\0\1\177\3\0\1\177\1\127\1\126\1\127\1\130"+ + "\7\0\15\127\3\0\3\127\3\0\1\201\1\0\1\77"+ + "\2\174\6\0\4\130\7\0\15\130\3\0\3\130\3\0"+ + "\1\202\2\0\1\202\7\0\1\132\1\133\1\132\1\133"+ + "\7\0\15\132\3\0\3\132\3\0\1\202\2\0\1\202"+ + "\7\0\4\133\7\0\15\133\3\0\3\133\3\0\1\174"+ + "\1\0\1\77\2\174\6\0\1\134\2\135\1\136\7\0"+ + "\15\134\3\0\3\134\3\0\1\176\1\0\1\77\2\176"+ + "\1\0\1\177\3\0\1\177\3\135\1\136\7\0\15\135"+ + "\3\0\3\135\3\0\1\174\1\0\1\77\2\174\6\0"+ + "\4\136\7\0\15\136\3\0\3\136\3\0\1\177\2\0"+ + "\2\177\1\0\1\177\3\0\1\177\3\137\10\0\15\137"+ + "\3\0\3\137\3\0\1\103\1\0\1\77\2\74\1\0"+ + "\1\75\3\0\1\75\1\140\2\141\1\142\7\0\15\140"+ + "\3\0\3\140\3\0\1\76\1\0\1\77\2\100\1\0"+ + "\1\101\3\0\1\101\3\141\1\142\7\0\15\141\3\0"+ + "\3\141\3\0\1\103\1\0\1\77\2\74\1\0\1\75"+ + "\3\0\1\75\4\142\7\0\15\142\3\0\3\142\3\0"+ + "\1\74\1\0\1\77\2\74\1\0\1\75\3\0\1\75"+ + "\1\143\2\144\1\145\7\0\15\143\3\0\3\143\3\0"+ + "\1\100\1\0\1\77\2\100\1\0\1\101\3\0\1\101"+ + "\3\144\1\145\7\0\15\144\3\0\3\144\3\0\1\74"+ + "\1\0\1\77\2\74\1\0\1\75\3\0\1\75\4\145"+ + "\7\0\15\145\3\0\3\145\3\0\1\75\2\0\2\75"+ + "\1\0\1\75\3\0\1\75\1\146\2\147\1\150\7\0"+ + "\15\146\3\0\3\146\3\0\1\101\2\0\2\101\1\0"+ + "\1\101\3\0\1\101\3\147\1\150\7\0\15\147\3\0"+ + "\3\147\3\0\1\75\2\0\2\75\1\0\1\75\3\0"+ + "\1\75\4\150\7\0\15\150\3\0\3\150\3\0\1\203"+ + "\1\0\1\77\2\74\1\0\1\75\3\0\1\75\1\151"+ + "\1\141\1\152\1\142\7\0\15\151\3\0\3\151\3\0"+ + "\1\204\1\0\1\77\2\100\1\0\1\101\3\0\1\101"+ + "\1\152\1\141\1\152\1\142\7\0\15\152\3\0\3\152"+ + "\3\0\1\201\1\0\1\77\2\174\6\0\1\153\2\126"+ + "\1\130\7\0\15\153\3\0\3\153\31\0\1\155\54\0"+ + "\1\205\64\0\1\206\26\0\4\36\7\0\15\36\3\0"+ + "\1\36\1\207\1\36\31\0\1\162\54\0\1\210\35\0"+ + "\1\34\1\0\4\121\1\0\3\122\3\0\3\121\1\211"+ + "\11\121\3\0\3\121\2\0\1\212\102\0\1\167\54\0"+ + "\1\213\34\0\1\214\52\0\1\170\3\0\4\171\7\0"+ + "\15\171\3\0\3\171\12\0\1\170\1\0\1\215\1\0"+ + "\4\121\1\0\3\122\3\0\15\121\3\0\3\121\16\0"+ + "\1\216\1\130\1\216\1\130\7\0\15\216\3\0\3\216"+ + "\16\0\4\136\7\0\15\136\3\0\3\136\16\0\4\142"+ + "\7\0\15\142\3\0\3\142\16\0\4\145\7\0\15\145"+ + "\3\0\3\145\16\0\4\150\7\0\15\150\3\0\3\150"+ + "\16\0\1\217\1\142\1\217\1\142\7\0\15\217\3\0"+ + "\3\217\16\0\4\130\7\0\15\130\3\0\3\130\16\0"+ + "\4\220\7\0\15\220\3\0\3\220\33\0\1\221\61\0"+ + "\1\222\30\0\4\36\6\0\1\223\15\36\3\0\2\36"+ + "\1\224\33\0\1\225\32\0\1\170\1\0\1\34\1\0"+ + "\4\121\1\0\3\122\3\0\10\121\1\226\4\121\3\0"+ + "\3\121\2\0\1\227\104\0\1\230\36\0\4\231\7\0"+ + "\15\231\3\0\3\231\3\0\1\173\1\0\1\77\2\174"+ + "\6\0\1\216\1\130\1\216\1\130\7\0\15\216\3\0"+ + "\3\216\3\0\1\203\1\0\1\77\2\74\1\0\1\75"+ + "\3\0\1\75\1\217\1\142\1\217\1\142\7\0\15\217"+ + "\3\0\3\217\3\0\1\202\2\0\1\202\7\0\4\220"+ + "\7\0\15\220\3\0\3\220\34\0\1\232\55\0\1\233"+ + "\26\0\1\234\60\0\4\36\6\0\1\223\15\36\3\0"+ + "\3\36\34\0\1\235\31\0\1\170\1\0\1\114\1\0"+ + "\4\121\1\0\3\122\3\0\15\121\3\0\3\121\34\0"+ + "\1\236\32\0\1\237\2\0\4\231\7\0\15\231\3\0"+ + "\3\231\35\0\1\240\62\0\1\241\20\0\1\242\77\0"+ + "\1\243\53\0\1\244\32\0\1\34\1\0\4\171\1\0"+ + "\3\122\3\0\15\171\3\0\3\171\36\0\1\245\53\0"+ + "\1\246\33\0\4\247\7\0\15\247\3\0\3\247\36\0"+ + "\1\250\53\0\1\251\54\0\1\252\61\0\1\253\11\0"+ + "\1\254\12\0\4\247\7\0\15\247\3\0\3\247\37\0"+ + "\1\255\53\0\1\256\54\0\1\257\22\0\1\13\62\0"+ + "\4\260\7\0\15\260\3\0\3\260\40\0\1\261\53\0"+ + "\1\262\43\0\1\263\26\0\2\260\1\0\2\260\1\0"+ + "\2\260\2\0\5\260\7\0\15\260\3\0\4\260\27\0"+ + "\1\264\53\0\1\265\24\0"; private static int [] zzUnpackTrans() { - int [] result = new int[7040]; + int [] result = new int[6908]; int offset = 0; offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); return result; @@ -355,8 +351,8 @@ class WikipediaTokenizerImpl { private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); private static final String ZZ_ATTRIBUTE_PACKED_0 = - "\12\0\1\11\7\1\1\11\3\1\1\11\6\1\1\11"+ - "\2\1\1\11\14\1\1\11\6\1\2\11\3\0\1\11"+ + "\12\0\1\11\7\1\1\11\2\1\1\11\5\1\1\11"+ + "\3\1\1\11\13\1\1\11\5\1\2\11\3\0\1\11"+ "\14\0\2\1\2\11\1\1\1\0\2\1\1\11\1\0"+ "\1\1\1\0\1\1\3\0\7\1\2\0\1\1\1\0"+ "\15\1\3\0\1\1\1\11\3\0\1\1\1\11\5\0"+ @@ -365,7 +361,7 @@ class WikipediaTokenizerImpl { "\2\0\3\11"; private static int [] zzUnpackAttribute() { - int [] result = new int[184]; + int [] result = new int[181]; int offset = 0; offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); return result; @@ -508,7 +504,6 @@ final void reset() { /** * Creates a new scanner - * There is also a java.io.InputStream version of this constructor. * * @param in the java.io.Reader to read input from. */ @@ -516,7 +511,6 @@ final void reset() { this.zzReader = in; } - /** * Unpacks the compressed character translation table. diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/wikipedia/WikipediaTokenizerImpl.jflex b/lucene/analysis/common/src/java/org/apache/lucene/analysis/wikipedia/WikipediaTokenizerImpl.jflex index 3865ea08aba..7fde30afb3d 100644 --- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/wikipedia/WikipediaTokenizerImpl.jflex +++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/wikipedia/WikipediaTokenizerImpl.jflex @@ -212,7 +212,7 @@ DOUBLE_EQUALS = "="{2} {DOUBLE_BRACE} {numWikiTokensSeen = 0; positionInc = 1; currentTokType = CITATION; yybegin(DOUBLE_BRACE_STATE);/* Break so we don't hit fall-through warning: */ break;} {CITATION} {numWikiTokensSeen = 0; positionInc = 1; currentTokType = CITATION; yybegin(DOUBLE_BRACE_STATE);/* Break so we don't hit fall-through warning: */ break;} //ignore - . | {WHITESPACE} |{INFOBOX} {numWikiTokensSeen = 0; positionInc = 1; /* Break so we don't hit fall-through warning: */ break;} + [^] |{INFOBOX} {numWikiTokensSeen = 0; positionInc = 1; /* Break so we don't hit fall-through warning: */ break;} } { @@ -221,7 +221,7 @@ DOUBLE_EQUALS = "="{2} {ALPHANUM} {yybegin(INTERNAL_LINK_STATE); numWikiTokensSeen++; return currentTokType;} {DOUBLE_BRACKET_CLOSE} {numLinkToks = 0; yybegin(YYINITIAL); /* Break so we don't hit fall-through warning: */ break;} //ignore - . | {WHITESPACE} { positionInc = 1; /* Break so we don't hit fall-through warning: */ break;} + [^] { positionInc = 1; /* Break so we don't hit fall-through warning: */ break;} } { @@ -236,7 +236,7 @@ DOUBLE_EQUALS = "="{2} {ALPHANUM} {yybegin(CATEGORY_STATE); numWikiTokensSeen++; return currentTokType;} {DOUBLE_BRACKET_CLOSE} {yybegin(YYINITIAL);/* Break so we don't hit fall-through warning: */ break;} //ignore - . | {WHITESPACE} { positionInc = 1; /* Break so we don't hit fall-through warning: */ break;} + [^] { positionInc = 1; /* Break so we don't hit fall-through warning: */ break;} } //italics { @@ -249,7 +249,7 @@ DOUBLE_EQUALS = "="{2} {EXTERNAL_LINK} {currentTokType = EXTERNAL_LINK; numWikiTokensSeen = 0; yybegin(EXTERNAL_LINK_STATE); /* Break so we don't hit fall-through warning: */ break;} //ignore - . | {WHITESPACE} { /* Break so we don't hit fall-through warning: */ break;/* ignore */ } + [^] { /* Break so we don't hit fall-through warning: */ break;/* ignore */ } } //bold { @@ -260,7 +260,7 @@ DOUBLE_EQUALS = "="{2} {EXTERNAL_LINK} {currentTokType = EXTERNAL_LINK; numWikiTokensSeen = 0; yybegin(EXTERNAL_LINK_STATE); /* Break so we don't hit fall-through warning: */ break;} //ignore - . | {WHITESPACE} { /* Break so we don't hit fall-through warning: */ break;/* ignore */ } + [^] { /* Break so we don't hit fall-through warning: */ break;/* ignore */ } } //bold italics @@ -272,7 +272,7 @@ DOUBLE_EQUALS = "="{2} {EXTERNAL_LINK} {currentTokType = EXTERNAL_LINK; numWikiTokensSeen = 0; yybegin(EXTERNAL_LINK_STATE); /* Break so we don't hit fall-through warning: */ break;} //ignore - . | {WHITESPACE} { /* Break so we don't hit fall-through warning: */ break;/* ignore */ } + [^] { /* Break so we don't hit fall-through warning: */ break;/* ignore */ } } { @@ -280,15 +280,15 @@ DOUBLE_EQUALS = "="{2} {ALPHANUM} {currentTokType = HEADING; yybegin(DOUBLE_EQUALS_STATE); numWikiTokensSeen++; return currentTokType;} {DOUBLE_EQUALS} {yybegin(YYINITIAL); /* Break so we don't hit fall-through warning: */ break;} //ignore - . | {WHITESPACE} { /* Break so we don't hit fall-through warning: */ break;/* ignore */ } + [^] { /* Break so we don't hit fall-through warning: */ break;/* ignore */ } } { {ALPHANUM} {yybegin(DOUBLE_BRACE_STATE); numWikiTokensSeen = 0; return currentTokType;} {DOUBLE_BRACE_CLOSE} {yybegin(YYINITIAL); /* Break so we don't hit fall-through warning: */ break;} {CITATION_CLOSE} {yybegin(YYINITIAL); /* Break so we don't hit fall-through warning: */ break;} - //ignore - . | {WHITESPACE} { /* Break so we don't hit fall-through warning: */ break;/* ignore */ } + //ignore + [^] { /* Break so we don't hit fall-through warning: */ break;/* ignore */ } } { @@ -305,7 +305,7 @@ DOUBLE_EQUALS = "="{2} {PIPE} {yybegin(STRING); return currentTokType;/*pipe*/} - .|{WHITESPACE} { /* Break so we don't hit fall-through warning: */ break;/* ignore STRING */ } + [^] { /* Break so we don't hit fall-through warning: */ break;/* ignore STRING */ } } @@ -327,7 +327,7 @@ DOUBLE_EQUALS = "="{2} //end wikipedia /** Ignore the rest */ -. | {WHITESPACE}|{TAGS} { /* Break so we don't hit fall-through warning: */ break;/* ignore */ } +[^] | {TAGS} { /* Break so we don't hit fall-through warning: */ break;/* ignore */ } //INTERNAL_LINK = "["{2}({ALPHANUM}+{WHITESPACE}*)+"]"{2} diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestStandardAnalyzer.java b/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestStandardAnalyzer.java index 7c593a57041..570e3612a1b 100644 --- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestStandardAnalyzer.java +++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestStandardAnalyzer.java @@ -202,7 +202,7 @@ public class TestStandardAnalyzer extends BaseTokenStreamTestCase { } public void testUnicodeWordBreaks() throws Exception { - WordBreakTestUnicode_6_1_0 wordBreakTest = new WordBreakTestUnicode_6_1_0(); + WordBreakTestUnicode_6_3_0 wordBreakTest = new WordBreakTestUnicode_6_3_0(); wordBreakTest.test(a); } @@ -230,6 +230,8 @@ public class TestStandardAnalyzer extends BaseTokenStreamTestCase { checkOneTerm(a, "壹゙", "壹゙"); // ideographic checkOneTerm(a, "아゙", "아゙"); // hangul } + + /** blast some random strings through the analyzer */ public void testRandomStrings() throws Exception { diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestUAX29URLEmailTokenizer.java b/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestUAX29URLEmailTokenizer.java index 736b07f2c29..becc397f157 100644 --- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestUAX29URLEmailTokenizer.java +++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestUAX29URLEmailTokenizer.java @@ -424,7 +424,7 @@ public class TestUAX29URLEmailTokenizer extends BaseTokenStreamTestCase { } public void testUnicodeWordBreaks() throws Exception { - WordBreakTestUnicode_6_1_0 wordBreakTest = new WordBreakTestUnicode_6_1_0(); + WordBreakTestUnicode_6_3_0 wordBreakTest = new WordBreakTestUnicode_6_3_0(); wordBreakTest.test(a); } diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/WordBreakTestUnicode_6_1_0.java b/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/WordBreakTestUnicode_6_3_0.java similarity index 64% rename from lucene/analysis/common/src/test/org/apache/lucene/analysis/core/WordBreakTestUnicode_6_1_0.java rename to lucene/analysis/common/src/test/org/apache/lucene/analysis/core/WordBreakTestUnicode_6_3_0.java index a9a79a32818..9838530cf83 100644 --- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/WordBreakTestUnicode_6_1_0.java +++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/WordBreakTestUnicode_6_3_0.java @@ -23,7 +23,7 @@ import org.junit.Ignore; /** * This class was automatically generated by generateJavaUnicodeWordBreakTest.pl - * from: http://www.unicode.org/Public/6.1.0/ucd/auxiliary/WordBreakTest.txt + * from: http://www.unicode.org/Public/6.3.0/ucd/auxiliary/WordBreakTest.txt * * WordBreakTest.txt indicates the points in the provided character sequences * at which conforming implementations must and must not break words. This @@ -32,16 +32,17 @@ import org.junit.Ignore; * sequences bounded by word breaks and containing at least one character * from one of the following character sets: * - * \p{Script = Han} (From http://www.unicode.org/Public/6.1.0/ucd/Scripts.txt) + * \p{Script = Han} (From http://www.unicode.org/Public/6.3.0/ucd/Scripts.txt) * \p{Script = Hiragana} - * \p{LineBreak = Complex_Context} (From http://www.unicode.org/Public/6.1.0/ucd/LineBreak.txt) - * \p{WordBreak = ALetter} (From http://www.unicode.org/Public/6.1.0/ucd/auxiliary/WordBreakProperty.txt) + * \p{LineBreak = Complex_Context} (From http://www.unicode.org/Public/6.3.0/ucd/LineBreak.txt) + * \p{WordBreak = ALetter} (From http://www.unicode.org/Public/6.3.0/ucd/auxiliary/WordBreakProperty.txt) + * \p{WordBreak = Hebrew_Letter} * \p{WordBreak = Katakana} * \p{WordBreak = Numeric} (Excludes full-width Arabic digits) - * [\uFF10-\uFF19] (Full-width Arabic digits) + * [\uFF10-\uFF19] (Full-width Arabic digits) */ @Ignore -public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { +public class WordBreakTestUnicode_6_3_0 extends BaseTokenStreamTestCase { public void test(Analyzer analyzer) throws Exception { // ÷ 0001 ÷ 0001 ÷ # ÷ [0.2] (Other) ÷ [999.0] (Other) ÷ [0.3] @@ -108,12 +109,12 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0001\u0308\u002C", new String[] { }); - // ÷ 0001 ÷ 0027 ÷ # ÷ [0.2] (Other) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0001\u0027", + // ÷ 0001 ÷ 002E ÷ # ÷ [0.2] (Other) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0001\u002E", new String[] { }); - // ÷ 0001 × 0308 ÷ 0027 ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0001\u0308\u0027", + // ÷ 0001 × 0308 ÷ 002E ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0001\u0308\u002E", new String[] { }); // ÷ 0001 ÷ 0030 ÷ # ÷ [0.2] (Other) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] @@ -132,6 +133,38 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0001\u0308\u005F", new String[] { }); + // ÷ 0001 ÷ 1F1E6 ÷ # ÷ [0.2] (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0001\uD83C\uDDE6", + new String[] { }); + + // ÷ 0001 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0001\u0308\uD83C\uDDE6", + new String[] { }); + + // ÷ 0001 ÷ 05D0 ÷ # ÷ [0.2] (Other) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0001\u05D0", + new String[] { "\u05D0" }); + + // ÷ 0001 × 0308 ÷ 05D0 ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0001\u0308\u05D0", + new String[] { "\u05D0" }); + + // ÷ 0001 ÷ 0022 ÷ # ÷ [0.2] (Other) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0001\"", + new String[] { }); + + // ÷ 0001 × 0308 ÷ 0022 ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0001\u0308\"", + new String[] { }); + + // ÷ 0001 ÷ 0027 ÷ # ÷ [0.2] (Other) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0001\u0027", + new String[] { }); + + // ÷ 0001 × 0308 ÷ 0027 ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0001\u0308\u0027", + new String[] { }); + // ÷ 0001 × 00AD ÷ # ÷ [0.2] (Other) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0001\u00AD", new String[] { }); @@ -164,19 +197,19 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0001\u0308\u0061\u003A", new String[] { "\u0061" }); - // ÷ 0001 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] (Other) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0001 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] (Other) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0001\u0061\u0027", new String[] { "\u0061" }); - // ÷ 0001 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0001 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0001\u0308\u0061\u0027", new String[] { "\u0061" }); - // ÷ 0001 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] (Other) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0001 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] (Other) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0001\u0061\u0027\u2060", new String[] { "\u0061" }); - // ÷ 0001 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0001 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0001\u0308\u0061\u0027\u2060", new String[] { "\u0061" }); @@ -196,11 +229,11 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0001\u0308\u0031\u003A", new String[] { "\u0031" }); - // ÷ 0001 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] (Other) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0001 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] (Other) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0001\u0031\u0027", new String[] { "\u0031" }); - // ÷ 0001 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0001 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0001\u0308\u0031\u0027", new String[] { "\u0031" }); @@ -284,12 +317,12 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\r\u0308\u002C", new String[] { }); - // ÷ 000D ÷ 0027 ÷ # ÷ [0.2] (CR) ÷ [3.1] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\r\u0027", + // ÷ 000D ÷ 002E ÷ # ÷ [0.2] (CR) ÷ [3.1] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\r\u002E", new String[] { }); - // ÷ 000D ÷ 0308 ÷ 0027 ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\r\u0308\u0027", + // ÷ 000D ÷ 0308 ÷ 002E ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\r\u0308\u002E", new String[] { }); // ÷ 000D ÷ 0030 ÷ # ÷ [0.2] (CR) ÷ [3.1] DIGIT ZERO (Numeric) ÷ [0.3] @@ -308,6 +341,38 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\r\u0308\u005F", new String[] { }); + // ÷ 000D ÷ 1F1E6 ÷ # ÷ [0.2] (CR) ÷ [3.1] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\r\uD83C\uDDE6", + new String[] { }); + + // ÷ 000D ÷ 0308 ÷ 1F1E6 ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\r\u0308\uD83C\uDDE6", + new String[] { }); + + // ÷ 000D ÷ 05D0 ÷ # ÷ [0.2] (CR) ÷ [3.1] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\r\u05D0", + new String[] { "\u05D0" }); + + // ÷ 000D ÷ 0308 ÷ 05D0 ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\r\u0308\u05D0", + new String[] { "\u05D0" }); + + // ÷ 000D ÷ 0022 ÷ # ÷ [0.2] (CR) ÷ [3.1] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\r\"", + new String[] { }); + + // ÷ 000D ÷ 0308 ÷ 0022 ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\r\u0308\"", + new String[] { }); + + // ÷ 000D ÷ 0027 ÷ # ÷ [0.2] (CR) ÷ [3.1] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\r\u0027", + new String[] { }); + + // ÷ 000D ÷ 0308 ÷ 0027 ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\r\u0308\u0027", + new String[] { }); + // ÷ 000D ÷ 00AD ÷ # ÷ [0.2] (CR) ÷ [3.1] SOFT HYPHEN (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\r\u00AD", new String[] { }); @@ -340,19 +405,19 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\r\u0308\u0061\u003A", new String[] { "\u0061" }); - // ÷ 000D ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] (CR) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 000D ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] (CR) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\r\u0061\u0027", new String[] { "\u0061" }); - // ÷ 000D ÷ 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 000D ÷ 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\r\u0308\u0061\u0027", new String[] { "\u0061" }); - // ÷ 000D ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] (CR) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 000D ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] (CR) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\r\u0061\u0027\u2060", new String[] { "\u0061" }); - // ÷ 000D ÷ 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 000D ÷ 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\r\u0308\u0061\u0027\u2060", new String[] { "\u0061" }); @@ -372,11 +437,11 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\r\u0308\u0031\u003A", new String[] { "\u0031" }); - // ÷ 000D ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] (CR) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 000D ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] (CR) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\r\u0031\u0027", new String[] { "\u0031" }); - // ÷ 000D ÷ 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 000D ÷ 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\r\u0308\u0031\u0027", new String[] { "\u0031" }); @@ -460,12 +525,12 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\n\u0308\u002C", new String[] { }); - // ÷ 000A ÷ 0027 ÷ # ÷ [0.2] (LF) ÷ [3.1] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\n\u0027", + // ÷ 000A ÷ 002E ÷ # ÷ [0.2] (LF) ÷ [3.1] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\n\u002E", new String[] { }); - // ÷ 000A ÷ 0308 ÷ 0027 ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\n\u0308\u0027", + // ÷ 000A ÷ 0308 ÷ 002E ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\n\u0308\u002E", new String[] { }); // ÷ 000A ÷ 0030 ÷ # ÷ [0.2] (LF) ÷ [3.1] DIGIT ZERO (Numeric) ÷ [0.3] @@ -484,6 +549,38 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\n\u0308\u005F", new String[] { }); + // ÷ 000A ÷ 1F1E6 ÷ # ÷ [0.2] (LF) ÷ [3.1] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\n\uD83C\uDDE6", + new String[] { }); + + // ÷ 000A ÷ 0308 ÷ 1F1E6 ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\n\u0308\uD83C\uDDE6", + new String[] { }); + + // ÷ 000A ÷ 05D0 ÷ # ÷ [0.2] (LF) ÷ [3.1] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\n\u05D0", + new String[] { "\u05D0" }); + + // ÷ 000A ÷ 0308 ÷ 05D0 ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\n\u0308\u05D0", + new String[] { "\u05D0" }); + + // ÷ 000A ÷ 0022 ÷ # ÷ [0.2] (LF) ÷ [3.1] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\n\"", + new String[] { }); + + // ÷ 000A ÷ 0308 ÷ 0022 ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\n\u0308\"", + new String[] { }); + + // ÷ 000A ÷ 0027 ÷ # ÷ [0.2] (LF) ÷ [3.1] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\n\u0027", + new String[] { }); + + // ÷ 000A ÷ 0308 ÷ 0027 ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\n\u0308\u0027", + new String[] { }); + // ÷ 000A ÷ 00AD ÷ # ÷ [0.2] (LF) ÷ [3.1] SOFT HYPHEN (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\n\u00AD", new String[] { }); @@ -516,19 +613,19 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\n\u0308\u0061\u003A", new String[] { "\u0061" }); - // ÷ 000A ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] (LF) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 000A ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] (LF) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\n\u0061\u0027", new String[] { "\u0061" }); - // ÷ 000A ÷ 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 000A ÷ 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\n\u0308\u0061\u0027", new String[] { "\u0061" }); - // ÷ 000A ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] (LF) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 000A ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] (LF) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\n\u0061\u0027\u2060", new String[] { "\u0061" }); - // ÷ 000A ÷ 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 000A ÷ 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\n\u0308\u0061\u0027\u2060", new String[] { "\u0061" }); @@ -548,11 +645,11 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\n\u0308\u0031\u003A", new String[] { "\u0031" }); - // ÷ 000A ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] (LF) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 000A ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] (LF) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\n\u0031\u0027", new String[] { "\u0031" }); - // ÷ 000A ÷ 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 000A ÷ 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\n\u0308\u0031\u0027", new String[] { "\u0031" }); @@ -636,12 +733,12 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u000B\u0308\u002C", new String[] { }); - // ÷ 000B ÷ 0027 ÷ # ÷ [0.2] (Newline) ÷ [3.1] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u000B\u0027", + // ÷ 000B ÷ 002E ÷ # ÷ [0.2] (Newline) ÷ [3.1] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u000B\u002E", new String[] { }); - // ÷ 000B ÷ 0308 ÷ 0027 ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u000B\u0308\u0027", + // ÷ 000B ÷ 0308 ÷ 002E ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u000B\u0308\u002E", new String[] { }); // ÷ 000B ÷ 0030 ÷ # ÷ [0.2] (Newline) ÷ [3.1] DIGIT ZERO (Numeric) ÷ [0.3] @@ -660,6 +757,38 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u000B\u0308\u005F", new String[] { }); + // ÷ 000B ÷ 1F1E6 ÷ # ÷ [0.2] (Newline) ÷ [3.1] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u000B\uD83C\uDDE6", + new String[] { }); + + // ÷ 000B ÷ 0308 ÷ 1F1E6 ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u000B\u0308\uD83C\uDDE6", + new String[] { }); + + // ÷ 000B ÷ 05D0 ÷ # ÷ [0.2] (Newline) ÷ [3.1] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u000B\u05D0", + new String[] { "\u05D0" }); + + // ÷ 000B ÷ 0308 ÷ 05D0 ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u000B\u0308\u05D0", + new String[] { "\u05D0" }); + + // ÷ 000B ÷ 0022 ÷ # ÷ [0.2] (Newline) ÷ [3.1] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u000B\"", + new String[] { }); + + // ÷ 000B ÷ 0308 ÷ 0022 ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u000B\u0308\"", + new String[] { }); + + // ÷ 000B ÷ 0027 ÷ # ÷ [0.2] (Newline) ÷ [3.1] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u000B\u0027", + new String[] { }); + + // ÷ 000B ÷ 0308 ÷ 0027 ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u000B\u0308\u0027", + new String[] { }); + // ÷ 000B ÷ 00AD ÷ # ÷ [0.2] (Newline) ÷ [3.1] SOFT HYPHEN (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u000B\u00AD", new String[] { }); @@ -692,19 +821,19 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u000B\u0308\u0061\u003A", new String[] { "\u0061" }); - // ÷ 000B ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] (Newline) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 000B ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] (Newline) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u000B\u0061\u0027", new String[] { "\u0061" }); - // ÷ 000B ÷ 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 000B ÷ 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u000B\u0308\u0061\u0027", new String[] { "\u0061" }); - // ÷ 000B ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] (Newline) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 000B ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] (Newline) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u000B\u0061\u0027\u2060", new String[] { "\u0061" }); - // ÷ 000B ÷ 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 000B ÷ 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u000B\u0308\u0061\u0027\u2060", new String[] { "\u0061" }); @@ -724,11 +853,11 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u000B\u0308\u0031\u003A", new String[] { "\u0031" }); - // ÷ 000B ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] (Newline) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 000B ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] (Newline) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u000B\u0031\u0027", new String[] { "\u0031" }); - // ÷ 000B ÷ 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 000B ÷ 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u000B\u0308\u0031\u0027", new String[] { "\u0031" }); @@ -812,12 +941,12 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u3031\u0308\u002C", new String[] { "\u3031\u0308" }); - // ÷ 3031 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u3031\u0027", + // ÷ 3031 ÷ 002E ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u3031\u002E", new String[] { "\u3031" }); - // ÷ 3031 × 0308 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u3031\u0308\u0027", + // ÷ 3031 × 0308 ÷ 002E ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u3031\u0308\u002E", new String[] { "\u3031\u0308" }); // ÷ 3031 ÷ 0030 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] @@ -836,6 +965,38 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u3031\u0308\u005F", new String[] { "\u3031\u0308\u005F" }); + // ÷ 3031 ÷ 1F1E6 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u3031\uD83C\uDDE6", + new String[] { "\u3031" }); + + // ÷ 3031 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u3031\u0308\uD83C\uDDE6", + new String[] { "\u3031\u0308" }); + + // ÷ 3031 ÷ 05D0 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u3031\u05D0", + new String[] { "\u3031", "\u05D0" }); + + // ÷ 3031 × 0308 ÷ 05D0 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u3031\u0308\u05D0", + new String[] { "\u3031\u0308", "\u05D0" }); + + // ÷ 3031 ÷ 0022 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u3031\"", + new String[] { "\u3031" }); + + // ÷ 3031 × 0308 ÷ 0022 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u3031\u0308\"", + new String[] { "\u3031\u0308" }); + + // ÷ 3031 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u3031\u0027", + new String[] { "\u3031" }); + + // ÷ 3031 × 0308 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u3031\u0308\u0027", + new String[] { "\u3031\u0308" }); + // ÷ 3031 × 00AD ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u3031\u00AD", new String[] { "\u3031\u00AD" }); @@ -868,19 +1029,19 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u3031\u0308\u0061\u003A", new String[] { "\u3031\u0308", "\u0061" }); - // ÷ 3031 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 3031 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u3031\u0061\u0027", new String[] { "\u3031", "\u0061" }); - // ÷ 3031 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 3031 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u3031\u0308\u0061\u0027", new String[] { "\u3031\u0308", "\u0061" }); - // ÷ 3031 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 3031 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u3031\u0061\u0027\u2060", new String[] { "\u3031", "\u0061" }); - // ÷ 3031 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 3031 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u3031\u0308\u0061\u0027\u2060", new String[] { "\u3031\u0308", "\u0061" }); @@ -900,11 +1061,11 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u3031\u0308\u0031\u003A", new String[] { "\u3031\u0308", "\u0031" }); - // ÷ 3031 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 3031 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u3031\u0031\u0027", new String[] { "\u3031", "\u0031" }); - // ÷ 3031 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 3031 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u3031\u0308\u0031\u0027", new String[] { "\u3031\u0308", "\u0031" }); @@ -988,12 +1149,12 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0041\u0308\u002C", new String[] { "\u0041\u0308" }); - // ÷ 0041 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0041\u0027", + // ÷ 0041 ÷ 002E ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0041\u002E", new String[] { "\u0041" }); - // ÷ 0041 × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0041\u0308\u0027", + // ÷ 0041 × 0308 ÷ 002E ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0041\u0308\u002E", new String[] { "\u0041\u0308" }); // ÷ 0041 × 0030 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [9.0] DIGIT ZERO (Numeric) ÷ [0.3] @@ -1012,6 +1173,38 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0041\u0308\u005F", new String[] { "\u0041\u0308\u005F" }); + // ÷ 0041 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0041\uD83C\uDDE6", + new String[] { "\u0041" }); + + // ÷ 0041 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0041\u0308\uD83C\uDDE6", + new String[] { "\u0041\u0308" }); + + // ÷ 0041 × 05D0 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [5.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0041\u05D0", + new String[] { "\u0041\u05D0" }); + + // ÷ 0041 × 0308 × 05D0 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0041\u0308\u05D0", + new String[] { "\u0041\u0308\u05D0" }); + + // ÷ 0041 ÷ 0022 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0041\"", + new String[] { "\u0041" }); + + // ÷ 0041 × 0308 ÷ 0022 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0041\u0308\"", + new String[] { "\u0041\u0308" }); + + // ÷ 0041 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0041\u0027", + new String[] { "\u0041" }); + + // ÷ 0041 × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0041\u0308\u0027", + new String[] { "\u0041\u0308" }); + // ÷ 0041 × 00AD ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0041\u00AD", new String[] { "\u0041\u00AD" }); @@ -1044,19 +1237,19 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0041\u0308\u0061\u003A", new String[] { "\u0041\u0308\u0061" }); - // ÷ 0041 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0041 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0041\u0061\u0027", new String[] { "\u0041\u0061" }); - // ÷ 0041 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0041 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0041\u0308\u0061\u0027", new String[] { "\u0041\u0308\u0061" }); - // ÷ 0041 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0041 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0041\u0061\u0027\u2060", new String[] { "\u0041\u0061" }); - // ÷ 0041 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0041 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0041\u0308\u0061\u0027\u2060", new String[] { "\u0041\u0308\u0061" }); @@ -1076,11 +1269,11 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0041\u0308\u0031\u003A", new String[] { "\u0041\u0308\u0031" }); - // ÷ 0041 × 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0041 × 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0041\u0031\u0027", new String[] { "\u0041\u0031" }); - // ÷ 0041 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0041 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0041\u0308\u0031\u0027", new String[] { "\u0041\u0308\u0031" }); @@ -1164,12 +1357,12 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u003A\u0308\u002C", new String[] { }); - // ÷ 003A ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u003A\u0027", + // ÷ 003A ÷ 002E ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u003A\u002E", new String[] { }); - // ÷ 003A × 0308 ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u003A\u0308\u0027", + // ÷ 003A × 0308 ÷ 002E ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u003A\u0308\u002E", new String[] { }); // ÷ 003A ÷ 0030 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] @@ -1188,6 +1381,38 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u003A\u0308\u005F", new String[] { }); + // ÷ 003A ÷ 1F1E6 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u003A\uD83C\uDDE6", + new String[] { }); + + // ÷ 003A × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u003A\u0308\uD83C\uDDE6", + new String[] { }); + + // ÷ 003A ÷ 05D0 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u003A\u05D0", + new String[] { "\u05D0" }); + + // ÷ 003A × 0308 ÷ 05D0 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u003A\u0308\u05D0", + new String[] { "\u05D0" }); + + // ÷ 003A ÷ 0022 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u003A\"", + new String[] { }); + + // ÷ 003A × 0308 ÷ 0022 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u003A\u0308\"", + new String[] { }); + + // ÷ 003A ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u003A\u0027", + new String[] { }); + + // ÷ 003A × 0308 ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u003A\u0308\u0027", + new String[] { }); + // ÷ 003A × 00AD ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u003A\u00AD", new String[] { }); @@ -1220,19 +1445,19 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u003A\u0308\u0061\u003A", new String[] { "\u0061" }); - // ÷ 003A ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 003A ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u003A\u0061\u0027", new String[] { "\u0061" }); - // ÷ 003A × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 003A × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u003A\u0308\u0061\u0027", new String[] { "\u0061" }); - // ÷ 003A ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 003A ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u003A\u0061\u0027\u2060", new String[] { "\u0061" }); - // ÷ 003A × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 003A × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u003A\u0308\u0061\u0027\u2060", new String[] { "\u0061" }); @@ -1252,11 +1477,11 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u003A\u0308\u0031\u003A", new String[] { "\u0031" }); - // ÷ 003A ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 003A ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u003A\u0031\u0027", new String[] { "\u0031" }); - // ÷ 003A × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 003A × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u003A\u0308\u0031\u0027", new String[] { "\u0031" }); @@ -1340,12 +1565,12 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u002C\u0308\u002C", new String[] { }); - // ÷ 002C ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u002C\u0027", + // ÷ 002C ÷ 002E ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002C\u002E", new String[] { }); - // ÷ 002C × 0308 ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u002C\u0308\u0027", + // ÷ 002C × 0308 ÷ 002E ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002C\u0308\u002E", new String[] { }); // ÷ 002C ÷ 0030 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] @@ -1364,6 +1589,38 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u002C\u0308\u005F", new String[] { }); + // ÷ 002C ÷ 1F1E6 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002C\uD83C\uDDE6", + new String[] { }); + + // ÷ 002C × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002C\u0308\uD83C\uDDE6", + new String[] { }); + + // ÷ 002C ÷ 05D0 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002C\u05D0", + new String[] { "\u05D0" }); + + // ÷ 002C × 0308 ÷ 05D0 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002C\u0308\u05D0", + new String[] { "\u05D0" }); + + // ÷ 002C ÷ 0022 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002C\"", + new String[] { }); + + // ÷ 002C × 0308 ÷ 0022 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002C\u0308\"", + new String[] { }); + + // ÷ 002C ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002C\u0027", + new String[] { }); + + // ÷ 002C × 0308 ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002C\u0308\u0027", + new String[] { }); + // ÷ 002C × 00AD ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u002C\u00AD", new String[] { }); @@ -1396,19 +1653,19 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u002C\u0308\u0061\u003A", new String[] { "\u0061" }); - // ÷ 002C ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 002C ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u002C\u0061\u0027", new String[] { "\u0061" }); - // ÷ 002C × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 002C × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u002C\u0308\u0061\u0027", new String[] { "\u0061" }); - // ÷ 002C ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 002C ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u002C\u0061\u0027\u2060", new String[] { "\u0061" }); - // ÷ 002C × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 002C × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u002C\u0308\u0061\u0027\u2060", new String[] { "\u0061" }); @@ -1428,11 +1685,11 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u002C\u0308\u0031\u003A", new String[] { "\u0031" }); - // ÷ 002C ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 002C ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u002C\u0031\u0027", new String[] { "\u0031" }); - // ÷ 002C × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 002C × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u002C\u0308\u0031\u0027", new String[] { "\u0031" }); @@ -1452,180 +1709,212 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u002C\u0308\u0031\u002E\u2060", new String[] { "\u0031" }); - // ÷ 0027 ÷ 0001 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [999.0] (Other) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u0001", + // ÷ 002E ÷ 0001 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] (Other) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0001", new String[] { }); - // ÷ 0027 × 0308 ÷ 0001 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u0308\u0001", + // ÷ 002E × 0308 ÷ 0001 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0308\u0001", new String[] { }); - // ÷ 0027 ÷ 000D ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [3.2] (CR) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\r", + // ÷ 002E ÷ 000D ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [3.2] (CR) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\r", new String[] { }); - // ÷ 0027 × 0308 ÷ 000D ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u0308\r", + // ÷ 002E × 0308 ÷ 000D ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0308\r", new String[] { }); - // ÷ 0027 ÷ 000A ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [3.2] (LF) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\n", + // ÷ 002E ÷ 000A ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [3.2] (LF) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\n", new String[] { }); - // ÷ 0027 × 0308 ÷ 000A ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u0308\n", + // ÷ 002E × 0308 ÷ 000A ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0308\n", new String[] { }); - // ÷ 0027 ÷ 000B ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [3.2] (Newline) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u000B", + // ÷ 002E ÷ 000B ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [3.2] (Newline) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u000B", new String[] { }); - // ÷ 0027 × 0308 ÷ 000B ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u0308\u000B", + // ÷ 002E × 0308 ÷ 000B ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0308\u000B", new String[] { }); - // ÷ 0027 ÷ 3031 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u3031", + // ÷ 002E ÷ 3031 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u3031", new String[] { "\u3031" }); - // ÷ 0027 × 0308 ÷ 3031 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u0308\u3031", + // ÷ 002E × 0308 ÷ 3031 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0308\u3031", new String[] { "\u3031" }); - // ÷ 0027 ÷ 0041 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u0041", + // ÷ 002E ÷ 0041 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0041", new String[] { "\u0041" }); - // ÷ 0027 × 0308 ÷ 0041 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u0308\u0041", + // ÷ 002E × 0308 ÷ 0041 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0308\u0041", new String[] { "\u0041" }); - // ÷ 0027 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u003A", + // ÷ 002E ÷ 003A ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u003A", new String[] { }); - // ÷ 0027 × 0308 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u0308\u003A", + // ÷ 002E × 0308 ÷ 003A ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0308\u003A", new String[] { }); - // ÷ 0027 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u002C", + // ÷ 002E ÷ 002C ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u002C", new String[] { }); - // ÷ 0027 × 0308 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u0308\u002C", + // ÷ 002E × 0308 ÷ 002C ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0308\u002C", new String[] { }); - // ÷ 0027 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u0027", + // ÷ 002E ÷ 002E ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u002E", new String[] { }); - // ÷ 0027 × 0308 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u0308\u0027", + // ÷ 002E × 0308 ÷ 002E ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0308\u002E", new String[] { }); - // ÷ 0027 ÷ 0030 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u0030", + // ÷ 002E ÷ 0030 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0030", new String[] { "\u0030" }); - // ÷ 0027 × 0308 ÷ 0030 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u0308\u0030", + // ÷ 002E × 0308 ÷ 0030 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0308\u0030", new String[] { "\u0030" }); - // ÷ 0027 ÷ 005F ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u005F", + // ÷ 002E ÷ 005F ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u005F", new String[] { }); - // ÷ 0027 × 0308 ÷ 005F ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u0308\u005F", + // ÷ 002E × 0308 ÷ 005F ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0308\u005F", new String[] { }); - // ÷ 0027 × 00AD ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u00AD", + // ÷ 002E ÷ 1F1E6 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\uD83C\uDDE6", new String[] { }); - // ÷ 0027 × 0308 × 00AD ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u0308\u00AD", + // ÷ 002E × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0308\uD83C\uDDE6", new String[] { }); - // ÷ 0027 × 0300 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u0300", + // ÷ 002E ÷ 05D0 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u05D0", + new String[] { "\u05D0" }); + + // ÷ 002E × 0308 ÷ 05D0 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0308\u05D0", + new String[] { "\u05D0" }); + + // ÷ 002E ÷ 0022 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\"", new String[] { }); - // ÷ 0027 × 0308 × 0300 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u0308\u0300", + // ÷ 002E × 0308 ÷ 0022 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0308\"", new String[] { }); - // ÷ 0027 ÷ 0061 × 2060 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u0061\u2060", + // ÷ 002E ÷ 0027 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0027", + new String[] { }); + + // ÷ 002E × 0308 ÷ 0027 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0308\u0027", + new String[] { }); + + // ÷ 002E × 00AD ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u00AD", + new String[] { }); + + // ÷ 002E × 0308 × 00AD ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0308\u00AD", + new String[] { }); + + // ÷ 002E × 0300 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0300", + new String[] { }); + + // ÷ 002E × 0308 × 0300 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0308\u0300", + new String[] { }); + + // ÷ 002E ÷ 0061 × 2060 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0061\u2060", new String[] { "\u0061\u2060" }); - // ÷ 0027 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u0308\u0061\u2060", + // ÷ 002E × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0308\u0061\u2060", new String[] { "\u0061\u2060" }); - // ÷ 0027 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u0061\u003A", + // ÷ 002E ÷ 0061 ÷ 003A ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0061\u003A", new String[] { "\u0061" }); - // ÷ 0027 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u0308\u0061\u003A", + // ÷ 002E × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0308\u0061\u003A", new String[] { "\u0061" }); - // ÷ 0027 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u0061\u0027", + // ÷ 002E ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0061\u0027", new String[] { "\u0061" }); - // ÷ 0027 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u0308\u0061\u0027", + // ÷ 002E × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0308\u0061\u0027", new String[] { "\u0061" }); - // ÷ 0027 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u0061\u0027\u2060", + // ÷ 002E ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0061\u0027\u2060", new String[] { "\u0061" }); - // ÷ 0027 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u0308\u0061\u0027\u2060", + // ÷ 002E × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0308\u0061\u0027\u2060", new String[] { "\u0061" }); - // ÷ 0027 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u0061\u002C", + // ÷ 002E ÷ 0061 ÷ 002C ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0061\u002C", new String[] { "\u0061" }); - // ÷ 0027 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u0308\u0061\u002C", + // ÷ 002E × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0308\u0061\u002C", new String[] { "\u0061" }); - // ÷ 0027 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u0031\u003A", + // ÷ 002E ÷ 0031 ÷ 003A ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0031\u003A", new String[] { "\u0031" }); - // ÷ 0027 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u0308\u0031\u003A", + // ÷ 002E × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0308\u0031\u003A", new String[] { "\u0031" }); - // ÷ 0027 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u0031\u0027", + // ÷ 002E ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0031\u0027", new String[] { "\u0031" }); - // ÷ 0027 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u0308\u0031\u0027", + // ÷ 002E × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0308\u0031\u0027", new String[] { "\u0031" }); - // ÷ 0027 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u0031\u002C", + // ÷ 002E ÷ 0031 ÷ 002C ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0031\u002C", new String[] { "\u0031" }); - // ÷ 0027 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u0308\u0031\u002C", + // ÷ 002E × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0308\u0031\u002C", new String[] { "\u0031" }); - // ÷ 0027 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u0031\u002E\u2060", + // ÷ 002E ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0031\u002E\u2060", new String[] { "\u0031" }); - // ÷ 0027 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0027\u0308\u0031\u002E\u2060", + // ÷ 002E × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u002E\u0308\u0031\u002E\u2060", new String[] { "\u0031" }); // ÷ 0030 ÷ 0001 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] (Other) ÷ [0.3] @@ -1692,12 +1981,12 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0030\u0308\u002C", new String[] { "\u0030\u0308" }); - // ÷ 0030 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0030\u0027", + // ÷ 0030 ÷ 002E ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0030\u002E", new String[] { "\u0030" }); - // ÷ 0030 × 0308 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0030\u0308\u0027", + // ÷ 0030 × 0308 ÷ 002E ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0030\u0308\u002E", new String[] { "\u0030\u0308" }); // ÷ 0030 × 0030 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [8.0] DIGIT ZERO (Numeric) ÷ [0.3] @@ -1716,6 +2005,38 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0030\u0308\u005F", new String[] { "\u0030\u0308\u005F" }); + // ÷ 0030 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0030\uD83C\uDDE6", + new String[] { "\u0030" }); + + // ÷ 0030 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0030\u0308\uD83C\uDDE6", + new String[] { "\u0030\u0308" }); + + // ÷ 0030 × 05D0 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [10.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0030\u05D0", + new String[] { "\u0030\u05D0" }); + + // ÷ 0030 × 0308 × 05D0 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [10.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0030\u0308\u05D0", + new String[] { "\u0030\u0308\u05D0" }); + + // ÷ 0030 ÷ 0022 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0030\"", + new String[] { "\u0030" }); + + // ÷ 0030 × 0308 ÷ 0022 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0030\u0308\"", + new String[] { "\u0030\u0308" }); + + // ÷ 0030 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0030\u0027", + new String[] { "\u0030" }); + + // ÷ 0030 × 0308 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0030\u0308\u0027", + new String[] { "\u0030\u0308" }); + // ÷ 0030 × 00AD ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0030\u00AD", new String[] { "\u0030\u00AD" }); @@ -1748,19 +2069,19 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0030\u0308\u0061\u003A", new String[] { "\u0030\u0308\u0061" }); - // ÷ 0030 × 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0030 × 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0030\u0061\u0027", new String[] { "\u0030\u0061" }); - // ÷ 0030 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0030 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0030\u0308\u0061\u0027", new String[] { "\u0030\u0308\u0061" }); - // ÷ 0030 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0030 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0030\u0061\u0027\u2060", new String[] { "\u0030\u0061" }); - // ÷ 0030 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0030 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0030\u0308\u0061\u0027\u2060", new String[] { "\u0030\u0308\u0061" }); @@ -1780,11 +2101,11 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0030\u0308\u0031\u003A", new String[] { "\u0030\u0308\u0031" }); - // ÷ 0030 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [8.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0030 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [8.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0030\u0031\u0027", new String[] { "\u0030\u0031" }); - // ÷ 0030 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [8.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0030 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [8.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0030\u0308\u0031\u0027", new String[] { "\u0030\u0308\u0031" }); @@ -1868,12 +2189,12 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u005F\u0308\u002C", new String[] { }); - // ÷ 005F ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u005F\u0027", + // ÷ 005F ÷ 002E ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u005F\u002E", new String[] { }); - // ÷ 005F × 0308 ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u005F\u0308\u0027", + // ÷ 005F × 0308 ÷ 002E ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u005F\u0308\u002E", new String[] { }); // ÷ 005F × 0030 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] DIGIT ZERO (Numeric) ÷ [0.3] @@ -1892,6 +2213,38 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u005F\u0308\u005F", new String[] { }); + // ÷ 005F ÷ 1F1E6 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u005F\uD83C\uDDE6", + new String[] { }); + + // ÷ 005F × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u005F\u0308\uD83C\uDDE6", + new String[] { }); + + // ÷ 005F × 05D0 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u005F\u05D0", + new String[] { "\u005F\u05D0" }); + + // ÷ 005F × 0308 × 05D0 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u005F\u0308\u05D0", + new String[] { "\u005F\u0308\u05D0" }); + + // ÷ 005F ÷ 0022 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u005F\"", + new String[] { }); + + // ÷ 005F × 0308 ÷ 0022 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u005F\u0308\"", + new String[] { }); + + // ÷ 005F ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u005F\u0027", + new String[] { }); + + // ÷ 005F × 0308 ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u005F\u0308\u0027", + new String[] { }); + // ÷ 005F × 00AD ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u005F\u00AD", new String[] { }); @@ -1924,19 +2277,19 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u005F\u0308\u0061\u003A", new String[] { "\u005F\u0308\u0061" }); - // ÷ 005F × 0061 ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 005F × 0061 ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u005F\u0061\u0027", new String[] { "\u005F\u0061" }); - // ÷ 005F × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 005F × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u005F\u0308\u0061\u0027", new String[] { "\u005F\u0308\u0061" }); - // ÷ 005F × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 005F × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u005F\u0061\u0027\u2060", new String[] { "\u005F\u0061" }); - // ÷ 005F × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 005F × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u005F\u0308\u0061\u0027\u2060", new String[] { "\u005F\u0308\u0061" }); @@ -1956,11 +2309,11 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u005F\u0308\u0031\u003A", new String[] { "\u005F\u0308\u0031" }); - // ÷ 005F × 0031 ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 005F × 0031 ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u005F\u0031\u0027", new String[] { "\u005F\u0031" }); - // ÷ 005F × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 005F × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u005F\u0308\u0031\u0027", new String[] { "\u005F\u0308\u0031" }); @@ -1980,6 +2333,838 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u005F\u0308\u0031\u002E\u2060", new String[] { "\u005F\u0308\u0031" }); + // ÷ 1F1E6 ÷ 0001 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] (Other) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0001", + new String[] { }); + + // ÷ 1F1E6 × 0308 ÷ 0001 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0308\u0001", + new String[] { }); + + // ÷ 1F1E6 ÷ 000D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [3.2] (CR) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\r", + new String[] { }); + + // ÷ 1F1E6 × 0308 ÷ 000D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0308\r", + new String[] { }); + + // ÷ 1F1E6 ÷ 000A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [3.2] (LF) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\n", + new String[] { }); + + // ÷ 1F1E6 × 0308 ÷ 000A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0308\n", + new String[] { }); + + // ÷ 1F1E6 ÷ 000B ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [3.2] (Newline) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u000B", + new String[] { }); + + // ÷ 1F1E6 × 0308 ÷ 000B ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0308\u000B", + new String[] { }); + + // ÷ 1F1E6 ÷ 3031 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u3031", + new String[] { "\u3031" }); + + // ÷ 1F1E6 × 0308 ÷ 3031 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0308\u3031", + new String[] { "\u3031" }); + + // ÷ 1F1E6 ÷ 0041 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0041", + new String[] { "\u0041" }); + + // ÷ 1F1E6 × 0308 ÷ 0041 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0308\u0041", + new String[] { "\u0041" }); + + // ÷ 1F1E6 ÷ 003A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u003A", + new String[] { }); + + // ÷ 1F1E6 × 0308 ÷ 003A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0308\u003A", + new String[] { }); + + // ÷ 1F1E6 ÷ 002C ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u002C", + new String[] { }); + + // ÷ 1F1E6 × 0308 ÷ 002C ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0308\u002C", + new String[] { }); + + // ÷ 1F1E6 ÷ 002E ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u002E", + new String[] { }); + + // ÷ 1F1E6 × 0308 ÷ 002E ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0308\u002E", + new String[] { }); + + // ÷ 1F1E6 ÷ 0030 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0030", + new String[] { "\u0030" }); + + // ÷ 1F1E6 × 0308 ÷ 0030 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0308\u0030", + new String[] { "\u0030" }); + + // ÷ 1F1E6 ÷ 005F ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u005F", + new String[] { }); + + // ÷ 1F1E6 × 0308 ÷ 005F ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0308\u005F", + new String[] { }); + + // ÷ 1F1E6 × 1F1E6 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [13.3] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\uD83C\uDDE6", + new String[] { }); + + // ÷ 1F1E6 × 0308 × 1F1E6 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.3] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0308\uD83C\uDDE6", + new String[] { }); + + // ÷ 1F1E6 ÷ 05D0 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u05D0", + new String[] { "\u05D0" }); + + // ÷ 1F1E6 × 0308 ÷ 05D0 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0308\u05D0", + new String[] { "\u05D0" }); + + // ÷ 1F1E6 ÷ 0022 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\"", + new String[] { }); + + // ÷ 1F1E6 × 0308 ÷ 0022 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0308\"", + new String[] { }); + + // ÷ 1F1E6 ÷ 0027 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0027", + new String[] { }); + + // ÷ 1F1E6 × 0308 ÷ 0027 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0308\u0027", + new String[] { }); + + // ÷ 1F1E6 × 00AD ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u00AD", + new String[] { }); + + // ÷ 1F1E6 × 0308 × 00AD ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0308\u00AD", + new String[] { }); + + // ÷ 1F1E6 × 0300 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0300", + new String[] { }); + + // ÷ 1F1E6 × 0308 × 0300 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0308\u0300", + new String[] { }); + + // ÷ 1F1E6 ÷ 0061 × 2060 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0061\u2060", + new String[] { "\u0061\u2060" }); + + // ÷ 1F1E6 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0308\u0061\u2060", + new String[] { "\u0061\u2060" }); + + // ÷ 1F1E6 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0061\u003A", + new String[] { "\u0061" }); + + // ÷ 1F1E6 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0308\u0061\u003A", + new String[] { "\u0061" }); + + // ÷ 1F1E6 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0061\u0027", + new String[] { "\u0061" }); + + // ÷ 1F1E6 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0308\u0061\u0027", + new String[] { "\u0061" }); + + // ÷ 1F1E6 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0061\u0027\u2060", + new String[] { "\u0061" }); + + // ÷ 1F1E6 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0308\u0061\u0027\u2060", + new String[] { "\u0061" }); + + // ÷ 1F1E6 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0061\u002C", + new String[] { "\u0061" }); + + // ÷ 1F1E6 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0308\u0061\u002C", + new String[] { "\u0061" }); + + // ÷ 1F1E6 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0031\u003A", + new String[] { "\u0031" }); + + // ÷ 1F1E6 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0308\u0031\u003A", + new String[] { "\u0031" }); + + // ÷ 1F1E6 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0031\u0027", + new String[] { "\u0031" }); + + // ÷ 1F1E6 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0308\u0031\u0027", + new String[] { "\u0031" }); + + // ÷ 1F1E6 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0031\u002C", + new String[] { "\u0031" }); + + // ÷ 1F1E6 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0308\u0031\u002C", + new String[] { "\u0031" }); + + // ÷ 1F1E6 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0031\u002E\u2060", + new String[] { "\u0031" }); + + // ÷ 1F1E6 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u0308\u0031\u002E\u2060", + new String[] { "\u0031" }); + + // ÷ 05D0 ÷ 0001 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] (Other) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0001", + new String[] { "\u05D0" }); + + // ÷ 05D0 × 0308 ÷ 0001 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0308\u0001", + new String[] { "\u05D0\u0308" }); + + // ÷ 05D0 ÷ 000D ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [3.2] (CR) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\r", + new String[] { "\u05D0" }); + + // ÷ 05D0 × 0308 ÷ 000D ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0308\r", + new String[] { "\u05D0\u0308" }); + + // ÷ 05D0 ÷ 000A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [3.2] (LF) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\n", + new String[] { "\u05D0" }); + + // ÷ 05D0 × 0308 ÷ 000A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0308\n", + new String[] { "\u05D0\u0308" }); + + // ÷ 05D0 ÷ 000B ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [3.2] (Newline) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u000B", + new String[] { "\u05D0" }); + + // ÷ 05D0 × 0308 ÷ 000B ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0308\u000B", + new String[] { "\u05D0\u0308" }); + + // ÷ 05D0 ÷ 3031 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u3031", + new String[] { "\u05D0", "\u3031" }); + + // ÷ 05D0 × 0308 ÷ 3031 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0308\u3031", + new String[] { "\u05D0\u0308", "\u3031" }); + + // ÷ 05D0 × 0041 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [5.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0041", + new String[] { "\u05D0\u0041" }); + + // ÷ 05D0 × 0308 × 0041 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0308\u0041", + new String[] { "\u05D0\u0308\u0041" }); + + // ÷ 05D0 ÷ 003A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u003A", + new String[] { "\u05D0" }); + + // ÷ 05D0 × 0308 ÷ 003A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0308\u003A", + new String[] { "\u05D0\u0308" }); + + // ÷ 05D0 ÷ 002C ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u002C", + new String[] { "\u05D0" }); + + // ÷ 05D0 × 0308 ÷ 002C ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0308\u002C", + new String[] { "\u05D0\u0308" }); + + // ÷ 05D0 ÷ 002E ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u002E", + new String[] { "\u05D0" }); + + // ÷ 05D0 × 0308 ÷ 002E ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0308\u002E", + new String[] { "\u05D0\u0308" }); + + // ÷ 05D0 × 0030 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [9.0] DIGIT ZERO (Numeric) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0030", + new String[] { "\u05D0\u0030" }); + + // ÷ 05D0 × 0308 × 0030 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ZERO (Numeric) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0308\u0030", + new String[] { "\u05D0\u0308\u0030" }); + + // ÷ 05D0 × 005F ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u005F", + new String[] { "\u05D0\u005F" }); + + // ÷ 05D0 × 0308 × 005F ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0308\u005F", + new String[] { "\u05D0\u0308\u005F" }); + + // ÷ 05D0 ÷ 1F1E6 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\uD83C\uDDE6", + new String[] { "\u05D0" }); + + // ÷ 05D0 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0308\uD83C\uDDE6", + new String[] { "\u05D0\u0308" }); + + // ÷ 05D0 × 05D0 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [5.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u05D0", + new String[] { "\u05D0\u05D0" }); + + // ÷ 05D0 × 0308 × 05D0 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0308\u05D0", + new String[] { "\u05D0\u0308\u05D0" }); + + // ÷ 05D0 ÷ 0022 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\"", + new String[] { "\u05D0" }); + + // ÷ 05D0 × 0308 ÷ 0022 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0308\"", + new String[] { "\u05D0\u0308" }); + + // ÷ 05D0 × 0027 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [7.1] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0027", + new String[] { "\u05D0\u0027" }); + + // ÷ 05D0 × 0308 × 0027 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.1] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0308\u0027", + new String[] { "\u05D0\u0308\u0027" }); + + // ÷ 05D0 × 00AD ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u00AD", + new String[] { "\u05D0\u00AD" }); + + // ÷ 05D0 × 0308 × 00AD ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0308\u00AD", + new String[] { "\u05D0\u0308\u00AD" }); + + // ÷ 05D0 × 0300 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0300", + new String[] { "\u05D0\u0300" }); + + // ÷ 05D0 × 0308 × 0300 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0308\u0300", + new String[] { "\u05D0\u0308\u0300" }); + + // ÷ 05D0 × 0061 × 2060 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [5.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0061\u2060", + new String[] { "\u05D0\u0061\u2060" }); + + // ÷ 05D0 × 0308 × 0061 × 2060 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0308\u0061\u2060", + new String[] { "\u05D0\u0308\u0061\u2060" }); + + // ÷ 05D0 × 0061 ÷ 003A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0061\u003A", + new String[] { "\u05D0\u0061" }); + + // ÷ 05D0 × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0308\u0061\u003A", + new String[] { "\u05D0\u0308\u0061" }); + + // ÷ 05D0 × 0061 ÷ 0027 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0061\u0027", + new String[] { "\u05D0\u0061" }); + + // ÷ 05D0 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0308\u0061\u0027", + new String[] { "\u05D0\u0308\u0061" }); + + // ÷ 05D0 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0061\u0027\u2060", + new String[] { "\u05D0\u0061" }); + + // ÷ 05D0 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0308\u0061\u0027\u2060", + new String[] { "\u05D0\u0308\u0061" }); + + // ÷ 05D0 × 0061 ÷ 002C ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0061\u002C", + new String[] { "\u05D0\u0061" }); + + // ÷ 05D0 × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0308\u0061\u002C", + new String[] { "\u05D0\u0308\u0061" }); + + // ÷ 05D0 × 0031 ÷ 003A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0031\u003A", + new String[] { "\u05D0\u0031" }); + + // ÷ 05D0 × 0308 × 0031 ÷ 003A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0308\u0031\u003A", + new String[] { "\u05D0\u0308\u0031" }); + + // ÷ 05D0 × 0031 ÷ 0027 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0031\u0027", + new String[] { "\u05D0\u0031" }); + + // ÷ 05D0 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0308\u0031\u0027", + new String[] { "\u05D0\u0308\u0031" }); + + // ÷ 05D0 × 0031 ÷ 002C ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0031\u002C", + new String[] { "\u05D0\u0031" }); + + // ÷ 05D0 × 0308 × 0031 ÷ 002C ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0308\u0031\u002C", + new String[] { "\u05D0\u0308\u0031" }); + + // ÷ 05D0 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0031\u002E\u2060", + new String[] { "\u05D0\u0031" }); + + // ÷ 05D0 × 0308 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u05D0\u0308\u0031\u002E\u2060", + new String[] { "\u05D0\u0308\u0031" }); + + // ÷ 0022 ÷ 0001 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] (Other) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0001", + new String[] { }); + + // ÷ 0022 × 0308 ÷ 0001 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0308\u0001", + new String[] { }); + + // ÷ 0022 ÷ 000D ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [3.2] (CR) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\r", + new String[] { }); + + // ÷ 0022 × 0308 ÷ 000D ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0308\r", + new String[] { }); + + // ÷ 0022 ÷ 000A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [3.2] (LF) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\n", + new String[] { }); + + // ÷ 0022 × 0308 ÷ 000A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0308\n", + new String[] { }); + + // ÷ 0022 ÷ 000B ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [3.2] (Newline) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u000B", + new String[] { }); + + // ÷ 0022 × 0308 ÷ 000B ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0308\u000B", + new String[] { }); + + // ÷ 0022 ÷ 3031 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u3031", + new String[] { "\u3031" }); + + // ÷ 0022 × 0308 ÷ 3031 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0308\u3031", + new String[] { "\u3031" }); + + // ÷ 0022 ÷ 0041 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0041", + new String[] { "\u0041" }); + + // ÷ 0022 × 0308 ÷ 0041 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0308\u0041", + new String[] { "\u0041" }); + + // ÷ 0022 ÷ 003A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u003A", + new String[] { }); + + // ÷ 0022 × 0308 ÷ 003A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0308\u003A", + new String[] { }); + + // ÷ 0022 ÷ 002C ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u002C", + new String[] { }); + + // ÷ 0022 × 0308 ÷ 002C ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0308\u002C", + new String[] { }); + + // ÷ 0022 ÷ 002E ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u002E", + new String[] { }); + + // ÷ 0022 × 0308 ÷ 002E ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0308\u002E", + new String[] { }); + + // ÷ 0022 ÷ 0030 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0030", + new String[] { "\u0030" }); + + // ÷ 0022 × 0308 ÷ 0030 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0308\u0030", + new String[] { "\u0030" }); + + // ÷ 0022 ÷ 005F ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u005F", + new String[] { }); + + // ÷ 0022 × 0308 ÷ 005F ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0308\u005F", + new String[] { }); + + // ÷ 0022 ÷ 1F1E6 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\uD83C\uDDE6", + new String[] { }); + + // ÷ 0022 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0308\uD83C\uDDE6", + new String[] { }); + + // ÷ 0022 ÷ 05D0 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u05D0", + new String[] { "\u05D0" }); + + // ÷ 0022 × 0308 ÷ 05D0 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0308\u05D0", + new String[] { "\u05D0" }); + + // ÷ 0022 ÷ 0022 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\"", + new String[] { }); + + // ÷ 0022 × 0308 ÷ 0022 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0308\"", + new String[] { }); + + // ÷ 0022 ÷ 0027 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0027", + new String[] { }); + + // ÷ 0022 × 0308 ÷ 0027 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0308\u0027", + new String[] { }); + + // ÷ 0022 × 00AD ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u00AD", + new String[] { }); + + // ÷ 0022 × 0308 × 00AD ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0308\u00AD", + new String[] { }); + + // ÷ 0022 × 0300 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0300", + new String[] { }); + + // ÷ 0022 × 0308 × 0300 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0308\u0300", + new String[] { }); + + // ÷ 0022 ÷ 0061 × 2060 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0061\u2060", + new String[] { "\u0061\u2060" }); + + // ÷ 0022 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0308\u0061\u2060", + new String[] { "\u0061\u2060" }); + + // ÷ 0022 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0061\u003A", + new String[] { "\u0061" }); + + // ÷ 0022 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0308\u0061\u003A", + new String[] { "\u0061" }); + + // ÷ 0022 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0061\u0027", + new String[] { "\u0061" }); + + // ÷ 0022 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0308\u0061\u0027", + new String[] { "\u0061" }); + + // ÷ 0022 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0061\u0027\u2060", + new String[] { "\u0061" }); + + // ÷ 0022 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0308\u0061\u0027\u2060", + new String[] { "\u0061" }); + + // ÷ 0022 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0061\u002C", + new String[] { "\u0061" }); + + // ÷ 0022 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0308\u0061\u002C", + new String[] { "\u0061" }); + + // ÷ 0022 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0031\u003A", + new String[] { "\u0031" }); + + // ÷ 0022 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0308\u0031\u003A", + new String[] { "\u0031" }); + + // ÷ 0022 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0031\u0027", + new String[] { "\u0031" }); + + // ÷ 0022 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0308\u0031\u0027", + new String[] { "\u0031" }); + + // ÷ 0022 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0031\u002C", + new String[] { "\u0031" }); + + // ÷ 0022 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0308\u0031\u002C", + new String[] { "\u0031" }); + + // ÷ 0022 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0031\u002E\u2060", + new String[] { "\u0031" }); + + // ÷ 0022 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\"\u0308\u0031\u002E\u2060", + new String[] { "\u0031" }); + + // ÷ 0027 ÷ 0001 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] (Other) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0001", + new String[] { }); + + // ÷ 0027 × 0308 ÷ 0001 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0308\u0001", + new String[] { }); + + // ÷ 0027 ÷ 000D ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [3.2] (CR) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\r", + new String[] { }); + + // ÷ 0027 × 0308 ÷ 000D ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0308\r", + new String[] { }); + + // ÷ 0027 ÷ 000A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [3.2] (LF) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\n", + new String[] { }); + + // ÷ 0027 × 0308 ÷ 000A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0308\n", + new String[] { }); + + // ÷ 0027 ÷ 000B ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [3.2] (Newline) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u000B", + new String[] { }); + + // ÷ 0027 × 0308 ÷ 000B ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0308\u000B", + new String[] { }); + + // ÷ 0027 ÷ 3031 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u3031", + new String[] { "\u3031" }); + + // ÷ 0027 × 0308 ÷ 3031 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0308\u3031", + new String[] { "\u3031" }); + + // ÷ 0027 ÷ 0041 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0041", + new String[] { "\u0041" }); + + // ÷ 0027 × 0308 ÷ 0041 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0308\u0041", + new String[] { "\u0041" }); + + // ÷ 0027 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u003A", + new String[] { }); + + // ÷ 0027 × 0308 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0308\u003A", + new String[] { }); + + // ÷ 0027 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u002C", + new String[] { }); + + // ÷ 0027 × 0308 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0308\u002C", + new String[] { }); + + // ÷ 0027 ÷ 002E ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u002E", + new String[] { }); + + // ÷ 0027 × 0308 ÷ 002E ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0308\u002E", + new String[] { }); + + // ÷ 0027 ÷ 0030 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0030", + new String[] { "\u0030" }); + + // ÷ 0027 × 0308 ÷ 0030 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0308\u0030", + new String[] { "\u0030" }); + + // ÷ 0027 ÷ 005F ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u005F", + new String[] { }); + + // ÷ 0027 × 0308 ÷ 005F ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0308\u005F", + new String[] { }); + + // ÷ 0027 ÷ 1F1E6 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\uD83C\uDDE6", + new String[] { }); + + // ÷ 0027 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0308\uD83C\uDDE6", + new String[] { }); + + // ÷ 0027 ÷ 05D0 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u05D0", + new String[] { "\u05D0" }); + + // ÷ 0027 × 0308 ÷ 05D0 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0308\u05D0", + new String[] { "\u05D0" }); + + // ÷ 0027 ÷ 0022 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\"", + new String[] { }); + + // ÷ 0027 × 0308 ÷ 0022 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0308\"", + new String[] { }); + + // ÷ 0027 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0027", + new String[] { }); + + // ÷ 0027 × 0308 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0308\u0027", + new String[] { }); + + // ÷ 0027 × 00AD ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u00AD", + new String[] { }); + + // ÷ 0027 × 0308 × 00AD ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0308\u00AD", + new String[] { }); + + // ÷ 0027 × 0300 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0300", + new String[] { }); + + // ÷ 0027 × 0308 × 0300 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0308\u0300", + new String[] { }); + + // ÷ 0027 ÷ 0061 × 2060 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0061\u2060", + new String[] { "\u0061\u2060" }); + + // ÷ 0027 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0308\u0061\u2060", + new String[] { "\u0061\u2060" }); + + // ÷ 0027 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0061\u003A", + new String[] { "\u0061" }); + + // ÷ 0027 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0308\u0061\u003A", + new String[] { "\u0061" }); + + // ÷ 0027 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0061\u0027", + new String[] { "\u0061" }); + + // ÷ 0027 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0308\u0061\u0027", + new String[] { "\u0061" }); + + // ÷ 0027 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0061\u0027\u2060", + new String[] { "\u0061" }); + + // ÷ 0027 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0308\u0061\u0027\u2060", + new String[] { "\u0061" }); + + // ÷ 0027 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0061\u002C", + new String[] { "\u0061" }); + + // ÷ 0027 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0308\u0061\u002C", + new String[] { "\u0061" }); + + // ÷ 0027 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0031\u003A", + new String[] { "\u0031" }); + + // ÷ 0027 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0308\u0031\u003A", + new String[] { "\u0031" }); + + // ÷ 0027 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0031\u0027", + new String[] { "\u0031" }); + + // ÷ 0027 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0308\u0031\u0027", + new String[] { "\u0031" }); + + // ÷ 0027 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0031\u002C", + new String[] { "\u0031" }); + + // ÷ 0027 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0308\u0031\u002C", + new String[] { "\u0031" }); + + // ÷ 0027 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0031\u002E\u2060", + new String[] { "\u0031" }); + + // ÷ 0027 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0027\u0308\u0031\u002E\u2060", + new String[] { "\u0031" }); + // ÷ 00AD ÷ 0001 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] (Other) ÷ [0.3] assertAnalyzesTo(analyzer, "\u00AD\u0001", new String[] { }); @@ -2044,12 +3229,12 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u00AD\u0308\u002C", new String[] { }); - // ÷ 00AD ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u00AD\u0027", + // ÷ 00AD ÷ 002E ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u00AD\u002E", new String[] { }); - // ÷ 00AD × 0308 ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u00AD\u0308\u0027", + // ÷ 00AD × 0308 ÷ 002E ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u00AD\u0308\u002E", new String[] { }); // ÷ 00AD ÷ 0030 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] @@ -2068,6 +3253,38 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u00AD\u0308\u005F", new String[] { }); + // ÷ 00AD ÷ 1F1E6 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u00AD\uD83C\uDDE6", + new String[] { }); + + // ÷ 00AD × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u00AD\u0308\uD83C\uDDE6", + new String[] { }); + + // ÷ 00AD ÷ 05D0 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u00AD\u05D0", + new String[] { "\u05D0" }); + + // ÷ 00AD × 0308 ÷ 05D0 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u00AD\u0308\u05D0", + new String[] { "\u05D0" }); + + // ÷ 00AD ÷ 0022 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u00AD\"", + new String[] { }); + + // ÷ 00AD × 0308 ÷ 0022 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u00AD\u0308\"", + new String[] { }); + + // ÷ 00AD ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u00AD\u0027", + new String[] { }); + + // ÷ 00AD × 0308 ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u00AD\u0308\u0027", + new String[] { }); + // ÷ 00AD × 00AD ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u00AD\u00AD", new String[] { }); @@ -2100,19 +3317,19 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u00AD\u0308\u0061\u003A", new String[] { "\u0061" }); - // ÷ 00AD ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 00AD ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u00AD\u0061\u0027", new String[] { "\u0061" }); - // ÷ 00AD × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 00AD × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u00AD\u0308\u0061\u0027", new String[] { "\u0061" }); - // ÷ 00AD ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 00AD ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u00AD\u0061\u0027\u2060", new String[] { "\u0061" }); - // ÷ 00AD × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 00AD × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u00AD\u0308\u0061\u0027\u2060", new String[] { "\u0061" }); @@ -2132,11 +3349,11 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u00AD\u0308\u0031\u003A", new String[] { "\u0031" }); - // ÷ 00AD ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 00AD ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u00AD\u0031\u0027", new String[] { "\u0031" }); - // ÷ 00AD × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 00AD × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u00AD\u0308\u0031\u0027", new String[] { "\u0031" }); @@ -2220,12 +3437,12 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0300\u0308\u002C", new String[] { }); - // ÷ 0300 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0300\u0027", + // ÷ 0300 ÷ 002E ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0300\u002E", new String[] { }); - // ÷ 0300 × 0308 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0300\u0308\u0027", + // ÷ 0300 × 0308 ÷ 002E ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0300\u0308\u002E", new String[] { }); // ÷ 0300 ÷ 0030 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] @@ -2244,6 +3461,38 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0300\u0308\u005F", new String[] { }); + // ÷ 0300 ÷ 1F1E6 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0300\uD83C\uDDE6", + new String[] { }); + + // ÷ 0300 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0300\u0308\uD83C\uDDE6", + new String[] { }); + + // ÷ 0300 ÷ 05D0 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0300\u05D0", + new String[] { "\u05D0" }); + + // ÷ 0300 × 0308 ÷ 05D0 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0300\u0308\u05D0", + new String[] { "\u05D0" }); + + // ÷ 0300 ÷ 0022 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0300\"", + new String[] { }); + + // ÷ 0300 × 0308 ÷ 0022 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0300\u0308\"", + new String[] { }); + + // ÷ 0300 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0300\u0027", + new String[] { }); + + // ÷ 0300 × 0308 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0300\u0308\u0027", + new String[] { }); + // ÷ 0300 × 00AD ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0300\u00AD", new String[] { }); @@ -2276,19 +3525,19 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0300\u0308\u0061\u003A", new String[] { "\u0061" }); - // ÷ 0300 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0300 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0300\u0061\u0027", new String[] { "\u0061" }); - // ÷ 0300 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0300 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0300\u0308\u0061\u0027", new String[] { "\u0061" }); - // ÷ 0300 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0300 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0300\u0061\u0027\u2060", new String[] { "\u0061" }); - // ÷ 0300 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0300 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0300\u0308\u0061\u0027\u2060", new String[] { "\u0061" }); @@ -2308,11 +3557,11 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0300\u0308\u0031\u003A", new String[] { "\u0031" }); - // ÷ 0300 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0300 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0300\u0031\u0027", new String[] { "\u0031" }); - // ÷ 0300 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0300 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0300\u0308\u0031\u0027", new String[] { "\u0031" }); @@ -2396,12 +3645,12 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0061\u2060\u0308\u002C", new String[] { "\u0061\u2060\u0308" }); - // ÷ 0061 × 2060 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0061\u2060\u0027", + // ÷ 0061 × 2060 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u2060\u002E", new String[] { "\u0061\u2060" }); - // ÷ 0061 × 2060 × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0061\u2060\u0308\u0027", + // ÷ 0061 × 2060 × 0308 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u2060\u0308\u002E", new String[] { "\u0061\u2060\u0308" }); // ÷ 0061 × 2060 × 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [9.0] DIGIT ZERO (Numeric) ÷ [0.3] @@ -2420,6 +3669,38 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0061\u2060\u0308\u005F", new String[] { "\u0061\u2060\u0308\u005F" }); + // ÷ 0061 × 2060 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u2060\uD83C\uDDE6", + new String[] { "\u0061\u2060" }); + + // ÷ 0061 × 2060 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u2060\u0308\uD83C\uDDE6", + new String[] { "\u0061\u2060\u0308" }); + + // ÷ 0061 × 2060 × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u2060\u05D0", + new String[] { "\u0061\u2060\u05D0" }); + + // ÷ 0061 × 2060 × 0308 × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u2060\u0308\u05D0", + new String[] { "\u0061\u2060\u0308\u05D0" }); + + // ÷ 0061 × 2060 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u2060\"", + new String[] { "\u0061\u2060" }); + + // ÷ 0061 × 2060 × 0308 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u2060\u0308\"", + new String[] { "\u0061\u2060\u0308" }); + + // ÷ 0061 × 2060 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u2060\u0027", + new String[] { "\u0061\u2060" }); + + // ÷ 0061 × 2060 × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u2060\u0308\u0027", + new String[] { "\u0061\u2060\u0308" }); + // ÷ 0061 × 2060 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u2060\u00AD", new String[] { "\u0061\u2060\u00AD" }); @@ -2452,19 +3733,19 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0061\u2060\u0308\u0061\u003A", new String[] { "\u0061\u2060\u0308\u0061" }); - // ÷ 0061 × 2060 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0061 × 2060 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u2060\u0061\u0027", new String[] { "\u0061\u2060\u0061" }); - // ÷ 0061 × 2060 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0061 × 2060 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u2060\u0308\u0061\u0027", new String[] { "\u0061\u2060\u0308\u0061" }); - // ÷ 0061 × 2060 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0061 × 2060 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u2060\u0061\u0027\u2060", new String[] { "\u0061\u2060\u0061" }); - // ÷ 0061 × 2060 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0061 × 2060 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u2060\u0308\u0061\u0027\u2060", new String[] { "\u0061\u2060\u0308\u0061" }); @@ -2484,11 +3765,11 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0061\u2060\u0308\u0031\u003A", new String[] { "\u0061\u2060\u0308\u0031" }); - // ÷ 0061 × 2060 × 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0061 × 2060 × 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u2060\u0031\u0027", new String[] { "\u0061\u2060\u0031" }); - // ÷ 0061 × 2060 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0061 × 2060 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u2060\u0308\u0031\u0027", new String[] { "\u0061\u2060\u0308\u0031" }); @@ -2572,12 +3853,12 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0061\u003A\u0308\u002C", new String[] { "\u0061" }); - // ÷ 0061 ÷ 003A ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0061\u003A\u0027", + // ÷ 0061 ÷ 003A ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u003A\u002E", new String[] { "\u0061" }); - // ÷ 0061 ÷ 003A × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0061\u003A\u0308\u0027", + // ÷ 0061 ÷ 003A × 0308 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u003A\u0308\u002E", new String[] { "\u0061" }); // ÷ 0061 ÷ 003A ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] @@ -2596,6 +3877,38 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0061\u003A\u0308\u005F", new String[] { "\u0061" }); + // ÷ 0061 ÷ 003A ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u003A\uD83C\uDDE6", + new String[] { "\u0061" }); + + // ÷ 0061 ÷ 003A × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u003A\u0308\uD83C\uDDE6", + new String[] { "\u0061" }); + + // ÷ 0061 × 003A × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [7.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u003A\u05D0", + new String[] { "\u0061\u003A\u05D0" }); + + // ÷ 0061 × 003A × 0308 × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u003A\u0308\u05D0", + new String[] { "\u0061\u003A\u0308\u05D0" }); + + // ÷ 0061 ÷ 003A ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u003A\"", + new String[] { "\u0061" }); + + // ÷ 0061 ÷ 003A × 0308 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u003A\u0308\"", + new String[] { "\u0061" }); + + // ÷ 0061 ÷ 003A ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u003A\u0027", + new String[] { "\u0061" }); + + // ÷ 0061 ÷ 003A × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u003A\u0308\u0027", + new String[] { "\u0061" }); + // ÷ 0061 ÷ 003A × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u003A\u00AD", new String[] { "\u0061" }); @@ -2628,19 +3941,19 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0061\u003A\u0308\u0061\u003A", new String[] { "\u0061\u003A\u0308\u0061" }); - // ÷ 0061 × 003A × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0061 × 003A × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u003A\u0061\u0027", new String[] { "\u0061\u003A\u0061" }); - // ÷ 0061 × 003A × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0061 × 003A × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u003A\u0308\u0061\u0027", new String[] { "\u0061\u003A\u0308\u0061" }); - // ÷ 0061 × 003A × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0061 × 003A × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u003A\u0061\u0027\u2060", new String[] { "\u0061\u003A\u0061" }); - // ÷ 0061 × 003A × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0061 × 003A × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u003A\u0308\u0061\u0027\u2060", new String[] { "\u0061\u003A\u0308\u0061" }); @@ -2660,11 +3973,11 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0061\u003A\u0308\u0031\u003A", new String[] { "\u0061", "\u0031" }); - // ÷ 0061 ÷ 003A ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0061 ÷ 003A ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u003A\u0031\u0027", new String[] { "\u0061", "\u0031" }); - // ÷ 0061 ÷ 003A × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0061 ÷ 003A × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u003A\u0308\u0031\u0027", new String[] { "\u0061", "\u0031" }); @@ -2684,355 +3997,419 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0061\u003A\u0308\u0031\u002E\u2060", new String[] { "\u0061", "\u0031" }); - // ÷ 0061 ÷ 0027 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] (Other) ÷ [0.3] + // ÷ 0061 ÷ 0027 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] (Other) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u0001", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 × 0308 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 0308 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u0308\u0001", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [3.2] (CR) ÷ [0.3] + // ÷ 0061 ÷ 0027 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [3.2] (CR) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\r", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 × 0308 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 0308 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u0308\r", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [3.2] (LF) ÷ [0.3] + // ÷ 0061 ÷ 0027 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [3.2] (LF) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\n", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 × 0308 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 0308 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u0308\n", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [3.2] (Newline) ÷ [0.3] + // ÷ 0061 ÷ 0027 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [3.2] (Newline) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u000B", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 × 0308 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 0308 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u0308\u000B", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] + // ÷ 0061 ÷ 0027 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u3031", new String[] { "\u0061", "\u3031" }); - // ÷ 0061 ÷ 0027 × 0308 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 0308 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u0308\u3031", new String[] { "\u0061", "\u3031" }); - // ÷ 0061 × 0027 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [7.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] + // ÷ 0061 × 0027 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [7.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u0041", new String[] { "\u0061\u0027\u0041" }); - // ÷ 0061 × 0027 × 0308 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] + // ÷ 0061 × 0027 × 0308 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u0308\u0041", new String[] { "\u0061\u0027\u0308\u0041" }); - // ÷ 0061 ÷ 0027 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + // ÷ 0061 ÷ 0027 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] COLON (MidLetter) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u003A", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 × 0308 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 0308 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u0308\u003A", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + // ÷ 0061 ÷ 0027 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] COMMA (MidNum) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u002C", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 × 0308 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 0308 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u0308\u002C", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0061\u0027\u0027", + // ÷ 0061 ÷ 0027 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u0027\u002E", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0061\u0027\u0308\u0027", + // ÷ 0061 ÷ 0027 × 0308 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u0027\u0308\u002E", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] + // ÷ 0061 ÷ 0027 ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u0030", new String[] { "\u0061", "\u0030" }); - // ÷ 0061 ÷ 0027 × 0308 ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 0308 ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u0308\u0030", new String[] { "\u0061", "\u0030" }); - // ÷ 0061 ÷ 0027 ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] + // ÷ 0061 ÷ 0027 ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u005F", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 × 0308 ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 0308 ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u0308\u005F", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] + // ÷ 0061 ÷ 0027 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u0027\uD83C\uDDE6", + new String[] { "\u0061" }); + + // ÷ 0061 ÷ 0027 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u0027\u0308\uD83C\uDDE6", + new String[] { "\u0061" }); + + // ÷ 0061 × 0027 × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [7.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u0027\u05D0", + new String[] { "\u0061\u0027\u05D0" }); + + // ÷ 0061 × 0027 × 0308 × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u0027\u0308\u05D0", + new String[] { "\u0061\u0027\u0308\u05D0" }); + + // ÷ 0061 ÷ 0027 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u0027\"", + new String[] { "\u0061" }); + + // ÷ 0061 ÷ 0027 × 0308 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u0027\u0308\"", + new String[] { "\u0061" }); + + // ÷ 0061 ÷ 0027 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u0027\u0027", + new String[] { "\u0061" }); + + // ÷ 0061 ÷ 0027 × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u0027\u0308\u0027", + new String[] { "\u0061" }); + + // ÷ 0061 ÷ 0027 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u00AD", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 × 0308 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 0308 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u0308\u00AD", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u0300", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 × 0308 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 0308 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u0308\u0300", new String[] { "\u0061" }); - // ÷ 0061 × 0027 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [7.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0061 × 0027 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [7.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u0061\u2060", new String[] { "\u0061\u0027\u0061\u2060" }); - // ÷ 0061 × 0027 × 0308 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0061 × 0027 × 0308 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u0308\u0061\u2060", new String[] { "\u0061\u0027\u0308\u0061\u2060" }); - // ÷ 0061 × 0027 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + // ÷ 0061 × 0027 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u0061\u003A", new String[] { "\u0061\u0027\u0061" }); - // ÷ 0061 × 0027 × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + // ÷ 0061 × 0027 × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u0308\u0061\u003A", new String[] { "\u0061\u0027\u0308\u0061" }); - // ÷ 0061 × 0027 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0061 × 0027 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u0061\u0027", new String[] { "\u0061\u0027\u0061" }); - // ÷ 0061 × 0027 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0061 × 0027 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u0308\u0061\u0027", new String[] { "\u0061\u0027\u0308\u0061" }); - // ÷ 0061 × 0027 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0061 × 0027 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u0061\u0027\u2060", new String[] { "\u0061\u0027\u0061" }); - // ÷ 0061 × 0027 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0061 × 0027 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u0308\u0061\u0027\u2060", new String[] { "\u0061\u0027\u0308\u0061" }); - // ÷ 0061 × 0027 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + // ÷ 0061 × 0027 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u0061\u002C", new String[] { "\u0061\u0027\u0061" }); - // ÷ 0061 × 0027 × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + // ÷ 0061 × 0027 × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u0308\u0061\u002C", new String[] { "\u0061\u0027\u0308\u0061" }); - // ÷ 0061 ÷ 0027 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + // ÷ 0061 ÷ 0027 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u0031\u003A", new String[] { "\u0061", "\u0031" }); - // ÷ 0061 ÷ 0027 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u0308\u0031\u003A", new String[] { "\u0061", "\u0031" }); - // ÷ 0061 ÷ 0027 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0061 ÷ 0027 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u0031\u0027", new String[] { "\u0061", "\u0031" }); - // ÷ 0061 ÷ 0027 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u0308\u0031\u0027", new String[] { "\u0061", "\u0031" }); - // ÷ 0061 ÷ 0027 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + // ÷ 0061 ÷ 0027 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u0031\u002C", new String[] { "\u0061", "\u0031" }); - // ÷ 0061 ÷ 0027 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u0308\u0031\u002C", new String[] { "\u0061", "\u0031" }); - // ÷ 0061 ÷ 0027 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0061 ÷ 0027 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u0031\u002E\u2060", new String[] { "\u0061", "\u0031" }); - // ÷ 0061 ÷ 0027 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u0308\u0031\u002E\u2060", new String[] { "\u0061", "\u0031" }); - // ÷ 0061 ÷ 0027 × 2060 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] (Other) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 2060 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] (Other) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0001", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0308\u0001", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 × 2060 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] (CR) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 2060 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] (CR) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\r", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0308\r", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 × 2060 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] (LF) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 2060 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] (LF) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\n", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0308\n", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 × 2060 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] (Newline) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 2060 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] (Newline) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u000B", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0308\u000B", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 × 2060 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 2060 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u3031", new String[] { "\u0061", "\u3031" }); - // ÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0308\u3031", new String[] { "\u0061", "\u3031" }); - // ÷ 0061 × 0027 × 2060 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] + // ÷ 0061 × 0027 × 2060 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0041", new String[] { "\u0061\u0027\u2060\u0041" }); - // ÷ 0061 × 0027 × 2060 × 0308 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] + // ÷ 0061 × 0027 × 2060 × 0308 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0308\u0041", new String[] { "\u0061\u0027\u2060\u0308\u0041" }); - // ÷ 0061 ÷ 0027 × 2060 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 2060 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u003A", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0308\u003A", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 × 2060 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 2060 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u002C", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0308\u002C", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 × 2060 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0027", + // ÷ 0061 ÷ 0027 × 2060 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u002E", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0308\u0027", + // ÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0308\u002E", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 × 2060 ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 2060 ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0030", new String[] { "\u0061", "\u0030" }); - // ÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0308\u0030", new String[] { "\u0061", "\u0030" }); - // ÷ 0061 ÷ 0027 × 2060 ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 2060 ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u005F", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0308\u005F", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 × 2060 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 2060 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\uD83C\uDDE6", + new String[] { "\u0061" }); + + // ÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0308\uD83C\uDDE6", + new String[] { "\u0061" }); + + // ÷ 0061 × 0027 × 2060 × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [7.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u05D0", + new String[] { "\u0061\u0027\u2060\u05D0" }); + + // ÷ 0061 × 0027 × 2060 × 0308 × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0308\u05D0", + new String[] { "\u0061\u0027\u2060\u0308\u05D0" }); + + // ÷ 0061 ÷ 0027 × 2060 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\"", + new String[] { "\u0061" }); + + // ÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0308\"", + new String[] { "\u0061" }); + + // ÷ 0061 ÷ 0027 × 2060 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0027", + new String[] { "\u0061" }); + + // ÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0308\u0027", + new String[] { "\u0061" }); + + // ÷ 0061 ÷ 0027 × 2060 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u00AD", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 × 2060 × 0308 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 2060 × 0308 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0308\u00AD", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 × 2060 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 2060 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0300", new String[] { "\u0061" }); - // ÷ 0061 ÷ 0027 × 2060 × 0308 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 2060 × 0308 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0308\u0300", new String[] { "\u0061" }); - // ÷ 0061 × 0027 × 2060 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0061 × 0027 × 2060 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0061\u2060", new String[] { "\u0061\u0027\u2060\u0061\u2060" }); - // ÷ 0061 × 0027 × 2060 × 0308 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0061 × 0027 × 2060 × 0308 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0308\u0061\u2060", new String[] { "\u0061\u0027\u2060\u0308\u0061\u2060" }); - // ÷ 0061 × 0027 × 2060 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + // ÷ 0061 × 0027 × 2060 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0061\u003A", new String[] { "\u0061\u0027\u2060\u0061" }); - // ÷ 0061 × 0027 × 2060 × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + // ÷ 0061 × 0027 × 2060 × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0308\u0061\u003A", new String[] { "\u0061\u0027\u2060\u0308\u0061" }); - // ÷ 0061 × 0027 × 2060 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0061 × 0027 × 2060 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0061\u0027", new String[] { "\u0061\u0027\u2060\u0061" }); - // ÷ 0061 × 0027 × 2060 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0061 × 0027 × 2060 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0308\u0061\u0027", new String[] { "\u0061\u0027\u2060\u0308\u0061" }); - // ÷ 0061 × 0027 × 2060 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0061 × 0027 × 2060 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0061\u0027\u2060", new String[] { "\u0061\u0027\u2060\u0061" }); - // ÷ 0061 × 0027 × 2060 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0061 × 0027 × 2060 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0308\u0061\u0027\u2060", new String[] { "\u0061\u0027\u2060\u0308\u0061" }); - // ÷ 0061 × 0027 × 2060 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + // ÷ 0061 × 0027 × 2060 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0061\u002C", new String[] { "\u0061\u0027\u2060\u0061" }); - // ÷ 0061 × 0027 × 2060 × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + // ÷ 0061 × 0027 × 2060 × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0308\u0061\u002C", new String[] { "\u0061\u0027\u2060\u0308\u0061" }); - // ÷ 0061 ÷ 0027 × 2060 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 2060 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0031\u003A", new String[] { "\u0061", "\u0031" }); - // ÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0308\u0031\u003A", new String[] { "\u0061", "\u0031" }); - // ÷ 0061 ÷ 0027 × 2060 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 2060 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0031\u0027", new String[] { "\u0061", "\u0031" }); - // ÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0308\u0031\u0027", new String[] { "\u0061", "\u0031" }); - // ÷ 0061 ÷ 0027 × 2060 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 2060 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0031\u002C", new String[] { "\u0061", "\u0031" }); - // ÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0308\u0031\u002C", new String[] { "\u0061", "\u0031" }); - // ÷ 0061 ÷ 0027 × 2060 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 2060 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0031\u002E\u2060", new String[] { "\u0061", "\u0031" }); - // ÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u0027\u2060\u0308\u0031\u002E\u2060", new String[] { "\u0061", "\u0031" }); @@ -3100,12 +4477,12 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0061\u002C\u0308\u002C", new String[] { "\u0061" }); - // ÷ 0061 ÷ 002C ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0061\u002C\u0027", + // ÷ 0061 ÷ 002C ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u002C\u002E", new String[] { "\u0061" }); - // ÷ 0061 ÷ 002C × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0061\u002C\u0308\u0027", + // ÷ 0061 ÷ 002C × 0308 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u002C\u0308\u002E", new String[] { "\u0061" }); // ÷ 0061 ÷ 002C ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] @@ -3124,6 +4501,38 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0061\u002C\u0308\u005F", new String[] { "\u0061" }); + // ÷ 0061 ÷ 002C ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u002C\uD83C\uDDE6", + new String[] { "\u0061" }); + + // ÷ 0061 ÷ 002C × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u002C\u0308\uD83C\uDDE6", + new String[] { "\u0061" }); + + // ÷ 0061 ÷ 002C ÷ 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u002C\u05D0", + new String[] { "\u0061", "\u05D0" }); + + // ÷ 0061 ÷ 002C × 0308 ÷ 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u002C\u0308\u05D0", + new String[] { "\u0061", "\u05D0" }); + + // ÷ 0061 ÷ 002C ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u002C\"", + new String[] { "\u0061" }); + + // ÷ 0061 ÷ 002C × 0308 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u002C\u0308\"", + new String[] { "\u0061" }); + + // ÷ 0061 ÷ 002C ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u002C\u0027", + new String[] { "\u0061" }); + + // ÷ 0061 ÷ 002C × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\u002C\u0308\u0027", + new String[] { "\u0061" }); + // ÷ 0061 ÷ 002C × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u002C\u00AD", new String[] { "\u0061" }); @@ -3156,19 +4565,19 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0061\u002C\u0308\u0061\u003A", new String[] { "\u0061", "\u0061" }); - // ÷ 0061 ÷ 002C ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0061 ÷ 002C ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u002C\u0061\u0027", new String[] { "\u0061", "\u0061" }); - // ÷ 0061 ÷ 002C × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0061 ÷ 002C × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u002C\u0308\u0061\u0027", new String[] { "\u0061", "\u0061" }); - // ÷ 0061 ÷ 002C ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0061 ÷ 002C ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u002C\u0061\u0027\u2060", new String[] { "\u0061", "\u0061" }); - // ÷ 0061 ÷ 002C × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0061 ÷ 002C × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u002C\u0308\u0061\u0027\u2060", new String[] { "\u0061", "\u0061" }); @@ -3188,11 +4597,11 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0061\u002C\u0308\u0031\u003A", new String[] { "\u0061", "\u0031" }); - // ÷ 0061 ÷ 002C ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0061 ÷ 002C ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u002C\u0031\u0027", new String[] { "\u0061", "\u0031" }); - // ÷ 0061 ÷ 002C × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0061 ÷ 002C × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0061\u002C\u0308\u0031\u0027", new String[] { "\u0061", "\u0031" }); @@ -3276,12 +4685,12 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0031\u003A\u0308\u002C", new String[] { "\u0031" }); - // ÷ 0031 ÷ 003A ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0031\u003A\u0027", + // ÷ 0031 ÷ 003A ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u003A\u002E", new String[] { "\u0031" }); - // ÷ 0031 ÷ 003A × 0308 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0031\u003A\u0308\u0027", + // ÷ 0031 ÷ 003A × 0308 ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u003A\u0308\u002E", new String[] { "\u0031" }); // ÷ 0031 ÷ 003A ÷ 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] @@ -3300,6 +4709,38 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0031\u003A\u0308\u005F", new String[] { "\u0031" }); + // ÷ 0031 ÷ 003A ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u003A\uD83C\uDDE6", + new String[] { "\u0031" }); + + // ÷ 0031 ÷ 003A × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u003A\u0308\uD83C\uDDE6", + new String[] { "\u0031" }); + + // ÷ 0031 ÷ 003A ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u003A\u05D0", + new String[] { "\u0031", "\u05D0" }); + + // ÷ 0031 ÷ 003A × 0308 ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u003A\u0308\u05D0", + new String[] { "\u0031", "\u05D0" }); + + // ÷ 0031 ÷ 003A ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u003A\"", + new String[] { "\u0031" }); + + // ÷ 0031 ÷ 003A × 0308 ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u003A\u0308\"", + new String[] { "\u0031" }); + + // ÷ 0031 ÷ 003A ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u003A\u0027", + new String[] { "\u0031" }); + + // ÷ 0031 ÷ 003A × 0308 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u003A\u0308\u0027", + new String[] { "\u0031" }); + // ÷ 0031 ÷ 003A × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u003A\u00AD", new String[] { "\u0031" }); @@ -3332,19 +4773,19 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0031\u003A\u0308\u0061\u003A", new String[] { "\u0031", "\u0061" }); - // ÷ 0031 ÷ 003A ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0031 ÷ 003A ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u003A\u0061\u0027", new String[] { "\u0031", "\u0061" }); - // ÷ 0031 ÷ 003A × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0031 ÷ 003A × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u003A\u0308\u0061\u0027", new String[] { "\u0031", "\u0061" }); - // ÷ 0031 ÷ 003A ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0031 ÷ 003A ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u003A\u0061\u0027\u2060", new String[] { "\u0031", "\u0061" }); - // ÷ 0031 ÷ 003A × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0031 ÷ 003A × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u003A\u0308\u0061\u0027\u2060", new String[] { "\u0031", "\u0061" }); @@ -3364,11 +4805,11 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0031\u003A\u0308\u0031\u003A", new String[] { "\u0031", "\u0031" }); - // ÷ 0031 ÷ 003A ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0031 ÷ 003A ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u003A\u0031\u0027", new String[] { "\u0031", "\u0031" }); - // ÷ 0031 ÷ 003A × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0031 ÷ 003A × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u003A\u0308\u0031\u0027", new String[] { "\u0031", "\u0031" }); @@ -3388,179 +4829,211 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0031\u003A\u0308\u0031\u002E\u2060", new String[] { "\u0031", "\u0031" }); - // ÷ 0031 ÷ 0027 ÷ 0001 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] (Other) ÷ [0.3] + // ÷ 0031 ÷ 0027 ÷ 0001 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] (Other) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u0001", new String[] { "\u0031" }); - // ÷ 0031 ÷ 0027 × 0308 ÷ 0001 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] + // ÷ 0031 ÷ 0027 × 0308 ÷ 0001 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u0308\u0001", new String[] { "\u0031" }); - // ÷ 0031 ÷ 0027 ÷ 000D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [3.2] (CR) ÷ [0.3] + // ÷ 0031 ÷ 0027 ÷ 000D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [3.2] (CR) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\r", new String[] { "\u0031" }); - // ÷ 0031 ÷ 0027 × 0308 ÷ 000D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] + // ÷ 0031 ÷ 0027 × 0308 ÷ 000D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u0308\r", new String[] { "\u0031" }); - // ÷ 0031 ÷ 0027 ÷ 000A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [3.2] (LF) ÷ [0.3] + // ÷ 0031 ÷ 0027 ÷ 000A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [3.2] (LF) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\n", new String[] { "\u0031" }); - // ÷ 0031 ÷ 0027 × 0308 ÷ 000A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] + // ÷ 0031 ÷ 0027 × 0308 ÷ 000A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u0308\n", new String[] { "\u0031" }); - // ÷ 0031 ÷ 0027 ÷ 000B ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [3.2] (Newline) ÷ [0.3] + // ÷ 0031 ÷ 0027 ÷ 000B ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [3.2] (Newline) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u000B", new String[] { "\u0031" }); - // ÷ 0031 ÷ 0027 × 0308 ÷ 000B ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] + // ÷ 0031 ÷ 0027 × 0308 ÷ 000B ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u0308\u000B", new String[] { "\u0031" }); - // ÷ 0031 ÷ 0027 ÷ 3031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] + // ÷ 0031 ÷ 0027 ÷ 3031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u3031", new String[] { "\u0031", "\u3031" }); - // ÷ 0031 ÷ 0027 × 0308 ÷ 3031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] + // ÷ 0031 ÷ 0027 × 0308 ÷ 3031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u0308\u3031", new String[] { "\u0031", "\u3031" }); - // ÷ 0031 ÷ 0027 ÷ 0041 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] + // ÷ 0031 ÷ 0027 ÷ 0041 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u0041", new String[] { "\u0031", "\u0041" }); - // ÷ 0031 ÷ 0027 × 0308 ÷ 0041 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] + // ÷ 0031 ÷ 0027 × 0308 ÷ 0041 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u0308\u0041", new String[] { "\u0031", "\u0041" }); - // ÷ 0031 ÷ 0027 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + // ÷ 0031 ÷ 0027 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] COLON (MidLetter) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u003A", new String[] { "\u0031" }); - // ÷ 0031 ÷ 0027 × 0308 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + // ÷ 0031 ÷ 0027 × 0308 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u0308\u003A", new String[] { "\u0031" }); - // ÷ 0031 ÷ 0027 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + // ÷ 0031 ÷ 0027 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] COMMA (MidNum) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u002C", new String[] { "\u0031" }); - // ÷ 0031 ÷ 0027 × 0308 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + // ÷ 0031 ÷ 0027 × 0308 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u0308\u002C", new String[] { "\u0031" }); - // ÷ 0031 ÷ 0027 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0031\u0027\u0027", + // ÷ 0031 ÷ 0027 ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u0027\u002E", new String[] { "\u0031" }); - // ÷ 0031 ÷ 0027 × 0308 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0031\u0027\u0308\u0027", + // ÷ 0031 ÷ 0027 × 0308 ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u0027\u0308\u002E", new String[] { "\u0031" }); - // ÷ 0031 × 0027 × 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (MidNumLet) × [11.0] DIGIT ZERO (Numeric) ÷ [0.3] + // ÷ 0031 × 0027 × 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [11.0] DIGIT ZERO (Numeric) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u0030", new String[] { "\u0031\u0027\u0030" }); - // ÷ 0031 × 0027 × 0308 × 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ZERO (Numeric) ÷ [0.3] + // ÷ 0031 × 0027 × 0308 × 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ZERO (Numeric) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u0308\u0030", new String[] { "\u0031\u0027\u0308\u0030" }); - // ÷ 0031 ÷ 0027 ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] + // ÷ 0031 ÷ 0027 ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u005F", new String[] { "\u0031" }); - // ÷ 0031 ÷ 0027 × 0308 ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] + // ÷ 0031 ÷ 0027 × 0308 ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u0308\u005F", new String[] { "\u0031" }); - // ÷ 0031 ÷ 0027 × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] + // ÷ 0031 ÷ 0027 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u0027\uD83C\uDDE6", + new String[] { "\u0031" }); + + // ÷ 0031 ÷ 0027 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u0027\u0308\uD83C\uDDE6", + new String[] { "\u0031" }); + + // ÷ 0031 ÷ 0027 ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u0027\u05D0", + new String[] { "\u0031", "\u05D0" }); + + // ÷ 0031 ÷ 0027 × 0308 ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u0027\u0308\u05D0", + new String[] { "\u0031", "\u05D0" }); + + // ÷ 0031 ÷ 0027 ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u0027\"", + new String[] { "\u0031" }); + + // ÷ 0031 ÷ 0027 × 0308 ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u0027\u0308\"", + new String[] { "\u0031" }); + + // ÷ 0031 ÷ 0027 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u0027\u0027", + new String[] { "\u0031" }); + + // ÷ 0031 ÷ 0027 × 0308 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u0027\u0308\u0027", + new String[] { "\u0031" }); + + // ÷ 0031 ÷ 0027 × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u00AD", new String[] { "\u0031" }); - // ÷ 0031 ÷ 0027 × 0308 × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] + // ÷ 0031 ÷ 0027 × 0308 × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u0308\u00AD", new String[] { "\u0031" }); - // ÷ 0031 ÷ 0027 × 0300 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] + // ÷ 0031 ÷ 0027 × 0300 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u0300", new String[] { "\u0031" }); - // ÷ 0031 ÷ 0027 × 0308 × 0300 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] + // ÷ 0031 ÷ 0027 × 0308 × 0300 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u0308\u0300", new String[] { "\u0031" }); - // ÷ 0031 ÷ 0027 ÷ 0061 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0031 ÷ 0027 ÷ 0061 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u0061\u2060", new String[] { "\u0031", "\u0061\u2060" }); - // ÷ 0031 ÷ 0027 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0031 ÷ 0027 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u0308\u0061\u2060", new String[] { "\u0031", "\u0061\u2060" }); - // ÷ 0031 ÷ 0027 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + // ÷ 0031 ÷ 0027 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u0061\u003A", new String[] { "\u0031", "\u0061" }); - // ÷ 0031 ÷ 0027 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + // ÷ 0031 ÷ 0027 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u0308\u0061\u003A", new String[] { "\u0031", "\u0061" }); - // ÷ 0031 ÷ 0027 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0031 ÷ 0027 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u0061\u0027", new String[] { "\u0031", "\u0061" }); - // ÷ 0031 ÷ 0027 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0031 ÷ 0027 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u0308\u0061\u0027", new String[] { "\u0031", "\u0061" }); - // ÷ 0031 ÷ 0027 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0031 ÷ 0027 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u0061\u0027\u2060", new String[] { "\u0031", "\u0061" }); - // ÷ 0031 ÷ 0027 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0031 ÷ 0027 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u0308\u0061\u0027\u2060", new String[] { "\u0031", "\u0061" }); - // ÷ 0031 ÷ 0027 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + // ÷ 0031 ÷ 0027 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u0061\u002C", new String[] { "\u0031", "\u0061" }); - // ÷ 0031 ÷ 0027 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + // ÷ 0031 ÷ 0027 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u0308\u0061\u002C", new String[] { "\u0031", "\u0061" }); - // ÷ 0031 × 0027 × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (MidNumLet) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + // ÷ 0031 × 0027 × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u0031\u003A", new String[] { "\u0031\u0027\u0031" }); - // ÷ 0031 × 0027 × 0308 × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] + // ÷ 0031 × 0027 × 0308 × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u0308\u0031\u003A", new String[] { "\u0031\u0027\u0308\u0031" }); - // ÷ 0031 × 0027 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (MidNumLet) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0031 × 0027 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u0031\u0027", new String[] { "\u0031\u0027\u0031" }); - // ÷ 0031 × 0027 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0031 × 0027 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u0308\u0031\u0027", new String[] { "\u0031\u0027\u0308\u0031" }); - // ÷ 0031 × 0027 × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (MidNumLet) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + // ÷ 0031 × 0027 × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u0031\u002C", new String[] { "\u0031\u0027\u0031" }); - // ÷ 0031 × 0027 × 0308 × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] + // ÷ 0031 × 0027 × 0308 × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u0308\u0031\u002C", new String[] { "\u0031\u0027\u0308\u0031" }); - // ÷ 0031 × 0027 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (MidNumLet) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0031 × 0027 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u0031\u002E\u2060", new String[] { "\u0031\u0027\u0031" }); - // ÷ 0031 × 0027 × 0308 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0031 × 0027 × 0308 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u0027\u0308\u0031\u002E\u2060", new String[] { "\u0031\u0027\u0308\u0031" }); @@ -3628,12 +5101,12 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0031\u002C\u0308\u002C", new String[] { "\u0031" }); - // ÷ 0031 ÷ 002C ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0031\u002C\u0027", + // ÷ 0031 ÷ 002C ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u002C\u002E", new String[] { "\u0031" }); - // ÷ 0031 ÷ 002C × 0308 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0031\u002C\u0308\u0027", + // ÷ 0031 ÷ 002C × 0308 ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u002C\u0308\u002E", new String[] { "\u0031" }); // ÷ 0031 × 002C × 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [11.0] DIGIT ZERO (Numeric) ÷ [0.3] @@ -3652,6 +5125,38 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0031\u002C\u0308\u005F", new String[] { "\u0031" }); + // ÷ 0031 ÷ 002C ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u002C\uD83C\uDDE6", + new String[] { "\u0031" }); + + // ÷ 0031 ÷ 002C × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u002C\u0308\uD83C\uDDE6", + new String[] { "\u0031" }); + + // ÷ 0031 ÷ 002C ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u002C\u05D0", + new String[] { "\u0031", "\u05D0" }); + + // ÷ 0031 ÷ 002C × 0308 ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u002C\u0308\u05D0", + new String[] { "\u0031", "\u05D0" }); + + // ÷ 0031 ÷ 002C ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u002C\"", + new String[] { "\u0031" }); + + // ÷ 0031 ÷ 002C × 0308 ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u002C\u0308\"", + new String[] { "\u0031" }); + + // ÷ 0031 ÷ 002C ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u002C\u0027", + new String[] { "\u0031" }); + + // ÷ 0031 ÷ 002C × 0308 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u002C\u0308\u0027", + new String[] { "\u0031" }); + // ÷ 0031 ÷ 002C × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u002C\u00AD", new String[] { "\u0031" }); @@ -3684,19 +5189,19 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0031\u002C\u0308\u0061\u003A", new String[] { "\u0031", "\u0061" }); - // ÷ 0031 ÷ 002C ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0031 ÷ 002C ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u002C\u0061\u0027", new String[] { "\u0031", "\u0061" }); - // ÷ 0031 ÷ 002C × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0031 ÷ 002C × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u002C\u0308\u0061\u0027", new String[] { "\u0031", "\u0061" }); - // ÷ 0031 ÷ 002C ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0031 ÷ 002C ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u002C\u0061\u0027\u2060", new String[] { "\u0031", "\u0061" }); - // ÷ 0031 ÷ 002C × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0031 ÷ 002C × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u002C\u0308\u0061\u0027\u2060", new String[] { "\u0031", "\u0061" }); @@ -3716,11 +5221,11 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0031\u002C\u0308\u0031\u003A", new String[] { "\u0031\u002C\u0308\u0031" }); - // ÷ 0031 × 002C × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0031 × 002C × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u002C\u0031\u0027", new String[] { "\u0031\u002C\u0031" }); - // ÷ 0031 × 002C × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0031 × 002C × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u002C\u0308\u0031\u0027", new String[] { "\u0031\u002C\u0308\u0031" }); @@ -3804,12 +5309,12 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0031\u002E\u2060\u0308\u002C", new String[] { "\u0031" }); - // ÷ 0031 ÷ 002E × 2060 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0031\u002E\u2060\u0027", + // ÷ 0031 ÷ 002E × 2060 ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u002E\u2060\u002E", new String[] { "\u0031" }); - // ÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] - assertAnalyzesTo(analyzer, "\u0031\u002E\u2060\u0308\u0027", + // ÷ 0031 ÷ 002E × 2060 × 0308 ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u002E\u2060\u0308\u002E", new String[] { "\u0031" }); // ÷ 0031 × 002E × 2060 × 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [11.0] DIGIT ZERO (Numeric) ÷ [0.3] @@ -3828,6 +5333,38 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0031\u002E\u2060\u0308\u005F", new String[] { "\u0031" }); + // ÷ 0031 ÷ 002E × 2060 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u002E\u2060\uD83C\uDDE6", + new String[] { "\u0031" }); + + // ÷ 0031 ÷ 002E × 2060 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u002E\u2060\u0308\uD83C\uDDE6", + new String[] { "\u0031" }); + + // ÷ 0031 ÷ 002E × 2060 ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u002E\u2060\u05D0", + new String[] { "\u0031", "\u05D0" }); + + // ÷ 0031 ÷ 002E × 2060 × 0308 ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u002E\u2060\u0308\u05D0", + new String[] { "\u0031", "\u05D0" }); + + // ÷ 0031 ÷ 002E × 2060 ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u002E\u2060\"", + new String[] { "\u0031" }); + + // ÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u002E\u2060\u0308\"", + new String[] { "\u0031" }); + + // ÷ 0031 ÷ 002E × 2060 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u002E\u2060\u0027", + new String[] { "\u0031" }); + + // ÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0031\u002E\u2060\u0308\u0027", + new String[] { "\u0031" }); + // ÷ 0031 ÷ 002E × 2060 × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u002E\u2060\u00AD", new String[] { "\u0031" }); @@ -3860,19 +5397,19 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0031\u002E\u2060\u0308\u0061\u003A", new String[] { "\u0031", "\u0061" }); - // ÷ 0031 ÷ 002E × 2060 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0031 ÷ 002E × 2060 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u002E\u2060\u0061\u0027", new String[] { "\u0031", "\u0061" }); - // ÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u002E\u2060\u0308\u0061\u0027", new String[] { "\u0031", "\u0061" }); - // ÷ 0031 ÷ 002E × 2060 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0031 ÷ 002E × 2060 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u002E\u2060\u0061\u0027\u2060", new String[] { "\u0031", "\u0061" }); - // ÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u002E\u2060\u0308\u0061\u0027\u2060", new String[] { "\u0031", "\u0061" }); @@ -3892,11 +5429,11 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0031\u002E\u2060\u0308\u0031\u003A", new String[] { "\u0031\u002E\u2060\u0308\u0031" }); - // ÷ 0031 × 002E × 2060 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0031 × 002E × 2060 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u002E\u2060\u0031\u0027", new String[] { "\u0031\u002E\u2060\u0031" }); - // ÷ 0031 × 002E × 2060 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3] + // ÷ 0031 × 002E × 2060 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0031\u002E\u2060\u0308\u0031\u0027", new String[] { "\u0031\u002E\u2060\u0308\u0031" }); @@ -3916,7 +5453,7 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0031\u002E\u2060\u0308\u0031\u002E\u2060", new String[] { "\u0031\u002E\u2060\u0308\u0031" }); - // ÷ 0063 × 0061 × 006E × 0027 × 0074 ÷ # ÷ [0.2] LATIN SMALL LETTER C (ALetter) × [5.0] LATIN SMALL LETTER A (ALetter) × [5.0] LATIN SMALL LETTER N (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [7.0] LATIN SMALL LETTER T (ALetter) ÷ [0.3] + // ÷ 0063 × 0061 × 006E × 0027 × 0074 ÷ # ÷ [0.2] LATIN SMALL LETTER C (ALetter) × [5.0] LATIN SMALL LETTER A (ALetter) × [5.0] LATIN SMALL LETTER N (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [7.0] LATIN SMALL LETTER T (ALetter) ÷ [0.3] assertAnalyzesTo(analyzer, "\u0063\u0061\u006E\u0027\u0074", new String[] { "\u0063\u0061\u006E\u0027\u0074" }); @@ -3936,7 +5473,7 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u0033\u0061", new String[] { "\u0033\u0061" }); - // ÷ 2060 ÷ 0063 × 2060 × 0061 × 2060 × 006E × 2060 × 0027 × 2060 × 0074 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) ÷ [999.0] LATIN SMALL LETTER C (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER N (ALetter) × [4.0] WORD JOINER (Format_FE) × [6.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER T (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] + // ÷ 2060 ÷ 0063 × 2060 × 0061 × 2060 × 006E × 2060 × 0027 × 2060 × 0074 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) ÷ [999.0] LATIN SMALL LETTER C (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER N (ALetter) × [4.0] WORD JOINER (Format_FE) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER T (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] assertAnalyzesTo(analyzer, "\u2060\u0063\u2060\u0061\u2060\u006E\u2060\u0027\u2060\u0074\u2060\u2060", new String[] { "\u0063\u2060\u0061\u2060\u006E\u2060\u0027\u2060\u0074\u2060\u2060" }); @@ -3956,5 +5493,45 @@ public class WordBreakTestUnicode_6_1_0 extends BaseTokenStreamTestCase { assertAnalyzesTo(analyzer, "\u2060\u0033\u2060\u0061\u2060\u2060", new String[] { "\u0033\u2060\u0061\u2060\u2060" }); + // ÷ 0061 ÷ 1F1E6 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] LATIN SMALL LETTER B (ALetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0061\uD83C\uDDE6\u0062", + new String[] { "\u0061", "\u0062" }); + + // ÷ 1F1F7 × 1F1FA ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER R (Regional_Indicator) × [13.3] REGIONAL INDICATOR SYMBOL LETTER U (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDF7\uD83C\uDDFA", + new String[] { }); + + // ÷ 1F1F7 × 1F1FA × 1F1F8 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER R (Regional_Indicator) × [13.3] REGIONAL INDICATOR SYMBOL LETTER U (Regional_Indicator) × [13.3] REGIONAL INDICATOR SYMBOL LETTER S (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDF7\uD83C\uDDFA\uD83C\uDDF8", + new String[] { }); + + // ÷ 1F1F7 × 1F1FA × 1F1F8 × 1F1EA ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER R (Regional_Indicator) × [13.3] REGIONAL INDICATOR SYMBOL LETTER U (Regional_Indicator) × [13.3] REGIONAL INDICATOR SYMBOL LETTER S (Regional_Indicator) × [13.3] REGIONAL INDICATOR SYMBOL LETTER E (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDF7\uD83C\uDDFA\uD83C\uDDF8\uD83C\uDDEA", + new String[] { }); + + // ÷ 1F1F7 × 1F1FA ÷ 200B ÷ 1F1F8 × 1F1EA ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER R (Regional_Indicator) × [13.3] REGIONAL INDICATOR SYMBOL LETTER U (Regional_Indicator) ÷ [999.0] ZERO WIDTH SPACE (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER S (Regional_Indicator) × [13.3] REGIONAL INDICATOR SYMBOL LETTER E (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDF7\uD83C\uDDFA\u200B\uD83C\uDDF8\uD83C\uDDEA", + new String[] { }); + + // ÷ 1F1E6 × 1F1E7 × 1F1E8 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [13.3] REGIONAL INDICATOR SYMBOL LETTER B (Regional_Indicator) × [13.3] REGIONAL INDICATOR SYMBOL LETTER C (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\uD83C\uDDE7\uD83C\uDDE8", + new String[] { }); + + // ÷ 1F1E6 × 200D × 1F1E7 × 1F1E8 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] ZERO WIDTH JOINER (Extend_FE) × [13.3] REGIONAL INDICATOR SYMBOL LETTER B (Regional_Indicator) × [13.3] REGIONAL INDICATOR SYMBOL LETTER C (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\u200D\uD83C\uDDE7\uD83C\uDDE8", + new String[] { }); + + // ÷ 1F1E6 × 1F1E7 × 200D × 1F1E8 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [13.3] REGIONAL INDICATOR SYMBOL LETTER B (Regional_Indicator) × [4.0] ZERO WIDTH JOINER (Extend_FE) × [13.3] REGIONAL INDICATOR SYMBOL LETTER C (Regional_Indicator) ÷ [0.3] + assertAnalyzesTo(analyzer, "\uD83C\uDDE6\uD83C\uDDE7\u200D\uD83C\uDDE8", + new String[] { }); + + // ÷ 0020 × 200D ÷ 0646 ÷ # ÷ [0.2] SPACE (Other) × [4.0] ZERO WIDTH JOINER (Extend_FE) ÷ [999.0] ARABIC LETTER NOON (ALetter) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0020\u200D\u0646", + new String[] { "\u0646" }); + + // ÷ 0646 × 200D ÷ 0020 ÷ # ÷ [0.2] ARABIC LETTER NOON (ALetter) × [4.0] ZERO WIDTH JOINER (Extend_FE) ÷ [999.0] SPACE (Other) ÷ [0.3] + assertAnalyzesTo(analyzer, "\u0646\u200D\u0020", + new String[] { "\u0646\u200D" }); + } } diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/email.addresses.from.random.text.with.email.addresses.txt b/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/email.addresses.from.random.text.with.email.addresses.txt index 832a2aa749f..ae86ee6e316 100644 --- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/email.addresses.from.random.text.with.email.addresses.txt +++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/email.addresses.from.random.text.with.email.addresses.txt @@ -78,13 +78,13 @@ LTLNFsgB@[191.56.104.113] iT0LOq.jtPW=G06~cETxl2ge@Ah0.4hn72v.tQ.LU VGLn@z3E2.3an2.MM TWmfsxn@[112.192.017.029] -2tP07A@2twe6u0d6uw6o.sed7n.109mx.XN--KGBECHTV +2tP07A@2twe6u0d6uw6o.sed7n.109mx.XN--KPRW13D CjaPC63@['\RDrwk] Ayydpdoa@tdgypppmen.wf "gfKP9"@jo3-r0.mz -aTMgDW4@t5gax.XN--0ZWM56D +aTMgDW4@t5gax.XN--3E0B707E mcDrMO3FQ@nwc21.y5qd45lesryrp.IL -NZqj@v50egeveepk.z290kk.Bc3.xn--jxalpdlp +NZqj@v50egeveepk.z290kk.Bc3.xn--kprw13d XtAhFnq@[218.214.251.103] x0S8uos@[109.82.126.233] ALB4KFavj16pODdd@i206d6s.MM diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/generateJavaUnicodeWordBreakTest.pl b/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/generateJavaUnicodeWordBreakTest.pl index e4a83ff16ca..46ac3ef3568 100644 --- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/generateJavaUnicodeWordBreakTest.pl +++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/generateJavaUnicodeWordBreakTest.pl @@ -78,9 +78,10 @@ import org.junit.Ignore; * \\p{Script = Hiragana} * \\p{LineBreak = Complex_Context} (From $line_break_url) * \\p{WordBreak = ALetter} (From $word_break_url) + * \\p{WordBreak = Hebrew_Letter} * \\p{WordBreak = Katakana} * \\p{WordBreak = Numeric} (Excludes full-width Arabic digits) - * [\\uFF10-\\uFF19] (Full-width Arabic digits) + * [\\uFF10-\\uFF19] (Full-width Arabic digits) */ \@Ignore public class ${class_name} extends BaseTokenStreamTestCase { @@ -97,7 +98,7 @@ parse_Unicode_data_file($line_break_url, $codepoints, {'sa' => 1}); parse_Unicode_data_file($scripts_url, $codepoints, {'han' => 1, 'hiragana' => 1}); parse_Unicode_data_file($word_break_url, $codepoints, - {'aletter' => 1, 'katakana' => 1, 'numeric' => 1}); + {'aletter' => 1, 'hebrew_letter' => 1, 'katakana' => 1, 'numeric' => 1}); my @tests = split /\r?\n/, get_URL_content($word_break_test_url); my $output_path = File::Spec->catpath($volume, $directory, $output_filename); @@ -109,25 +110,33 @@ print STDERR "Writing '$output_path'..."; print OUT $header; for my $line (@tests) { - next if ($line =~ /^\s*\#/); - # ÷ 0001 × 0300 ÷ # ÷ [0.2] (Other) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] + next if ($line =~ /^\s*(?:|\#.*)$/); # Skip blank or comment-only lines + # Example line: ÷ 0001 × 0300 ÷ # ÷ [0.2] (Other) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] my ($sequence) = $line =~ /^(.*?)\s*\#/; + $line =~ s/\t/ /g; # Convert tabs to two spaces (no tabs allowed in Lucene source) print OUT " // $line\n"; $sequence =~ s/\s*÷\s*$//; # Trim trailing break character my $test_string = $sequence; $test_string =~ s/\s*÷\s*/\\u/g; $test_string =~ s/\s*×\s*/\\u/g; + $test_string =~ s/\\u([0-9A-F]{5,})/join('', map { "\\u$_" } above_BMP_char_to_surrogates($1))/ge; $test_string =~ s/\\u000A/\\n/g; $test_string =~ s/\\u000D/\\r/g; + $test_string =~ s/\\u0022/\\\"/g; $sequence =~ s/^\s*÷\s*//; # Trim leading break character my @tokens = (); for my $candidate (split /\s*÷\s*/, $sequence) { my @chars = (); my $has_wanted_char = 0; while ($candidate =~ /([0-9A-F]+)/gi) { - push @chars, $1; + my $hexchar = $1; + if (4 == length($hexchar)) { + push @chars, $hexchar; + } else { + push @chars, above_BMP_char_to_surrogates($hexchar); + } unless ($has_wanted_char) { - $has_wanted_char = 1 if (defined($codepoints->[hex($1)])); + $has_wanted_char = 1 if (defined($codepoints->[hex($hexchar)])); } } if ($has_wanted_char) { @@ -144,6 +153,21 @@ close OUT; print STDERR "done.\n"; +# sub above_BMP_char_to_surrogates +# +# Converts hex references to chars above the BMP (i.e., greater than 0xFFFF) +# to the corresponding UTF-16 surrogate pair +# +# Assumption: input string is a sequence more than four hex digits +# +sub above_BMP_char_to_surrogates { + my $ch = hex(shift); + my $high_surrogate = 0xD800 + (($ch - 0x10000) >> 10); + my $low_surrogate = 0xDC00 + ($ch & 0x3FF); + return map { sprintf("%04X", $_) } ($high_surrogate, $low_surrogate); +} + + # sub parse_Unicode_data_file # # Downloads and parses the specified Unicode data file, parses it, and diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/random.text.with.email.addresses.txt b/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/random.text.with.email.addresses.txt index 71ac34ccd84..84062cd794a 100644 --- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/random.text.with.email.addresses.txt +++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/random.text.with.email.addresses.txt @@ -121,14 +121,14 @@ Bzzzzzzzz! Bzzzzzzzzzzzzzzz! Tell them "0\!P?".shQVdSerA@2qmqj8ul.hm the leg of LTLNFsgB@[191.56.104.113] all, until it has read it is iT0LOq.jtPW=G06~cETxl2ge@Ah0.4hn72v.tQ.LU there. Once TWmfsxn@[112.192.017.029] Spiros under the place -2tP07A@2twe6u0d6uw6o.sed7n.109mx.XN--KGBECHTV as were not a house of the +2tP07A@2twe6u0d6uw6o.sed7n.109mx.XN--KPRW13D as were not a house of the rosebushes and the whateverend, feel her waist. She changes everything. We had decided to do you know CjaPC63@['\RDrwk] this, is what did leave, pray; let us come to, what history as died. Strange, Spiros with delight: That night "gfKP9"@jo3-r0.mz and gold case - is spring: the aeon arising, wherein he returned, + is spring: the aeon arising, wherein he returned, retraversing the mcDrMO3FQ@nwc21.y5qd45lesryrp.IL gates, first - to reach session. Initiating first + to reach session. Initiating first part of the main hall toward his own spurs. Hes an Irifix And older ones who wins? ADAM: x0S8uos@[109.82.126.233] The violin and reality. The hidden set up to come. ROSE WAKINS: No answer. The diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/random.text.with.urls.txt b/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/random.text.with.urls.txt index 241c806e1b5..ef5ad895e22 100644 --- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/random.text.with.urls.txt +++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/random.text.with.urls.txt @@ -24,7 +24,7 @@ and Joe recited this iron bars with their account, poor elth, and she had been almost drove me towards evening. At HTTP://173.202.175.16/Md7tF6lj7r/oioJ9TpL8/x%03PjXgMMBC7C3%BDWzoVMzH the sergeant and then on the raw - afternoon towards + afternoon towards the terror, merely wished him as biled M19nq.0URV4A.Me.CC/mj0kgt6hue/dRXv8YVLOw9v/CIOqb -- a conciliatory air on in @@ -47,7 +47,7 @@ to live. You didn't know nothing could attend more.' He had been a coming! Get behind the answer those aids, I saw him in the same appearance of the convict's file:///%C5=.%8by/uuFXEaW8.%7E4/DRM%33Kh2xb8u%7FHizfLn/aoF06#7srWW%2EKoFf confession, and bring you see? ' -HTTP://yA2O3F.XN--0ZWM56D/qPDTt/MwMXGQq2S7JT/TJ2iCND said my limbs. Joe in an +HTTP://yA2O3F.XN--3E0B707E/qPDTt/MwMXGQq2S7JT/TJ2iCND said my limbs. Joe in an accusatory manner as well known that Joe Gargery marry her cup. `I wonder and there was publicly made it was, as lookers on; me, I @@ -63,7 +63,7 @@ again FTP://Hi144dz6hctql2n3uom.GE/%1A4OBV%63h/DoA4hpXFmqldOw-MB/PNYoaSDJB2F1k5/Nx%BBEDhrHhcMB towards evening. At last, and kneaded, and a dead man taking any. There was publicly made out there?' said I, -ftp://w0yaysrl.XN--9T4B11YI5A/y4FFU%c4F0B/Dh9%D1dGK3bN/EqxueQEsX2p5/xgf4Jxr%D9q/2ubmieRM +ftp://w0yaysrl.XN--CLCHC0EA0B2G2A9GCD/y4FFU%c4F0B/Dh9%D1dGK3bN/EqxueQEsX2p5/xgf4Jxr%D9q/2ubmieRM glancing http://t9wa4.rjcahbc06qmyk9jkhu3f.ZA/vIwW3sc3Pg/Bwmeo6KAjkRY at the N54l6e.vu/1m2%8bMFjv/oBdy%36.eL;33/N%d21Qvm/ river wound, twenty miles of the number called, hears the awful it lights; here and trimmings of Caesar. This @@ -155,7 +155,7 @@ ftp://E1cdf-p.XN--MGBERP4A5D4AR:60510/qMaw4kSSgYM/7jgIuL/gSVW6O91/2bhnsj/kl7R5sg at me, and that her walking z3ymb.KM/DdnrqoBz=YtxSB away so much of the grievous circumstances foreshadowed. After receiving the way, that I thought, if she should go to?' `Good again!' cried the -FTP://7kgip3z.XN--HGBK6AJ7F53BBA:15983/OYEQzIA0 society of a savoury pork pie, +FTP://7kgip3z.XN--KPRY57D:15983/OYEQzIA0 society of a savoury pork pie, and nezt6awdc.lSZDSU14B1OH.4n6nkmjyyj.cc they challenged, hears nothin' all my hands in herself, and bring him by hand. `This,' ftp://085.062.055.011/bopfVV/ said he wore ftp://Mbbn8n.6ge03fiivyc7of.PS/mvb/X8VNt/5WrMZpw/flC6Rs a dog of @@ -191,7 +191,7 @@ and tingling, and that I had won of the shoulder. `Excuse me, and we departed from Richard the furthest end of http://ch43n.51rkj.rze.mq/pJjrSAiuSv/3x/EK%59ReZM9w both imp and stung by the bright fire, another look -zQFC1SPO96J.Jy20d8.xn--0zwm56d:863/0OWpT4dpkMURAGe/nFg/LQBUr%3E/af7dO1 over her +zQFC1SPO96J.Jy20d8.xn--3e0b707e:863/0OWpT4dpkMURAGe/nFg/LQBUr%3E/af7dO1 over her best use asking questions, and feet, hanging to try back was the poker. `It was not warmly. `Seems @@ -204,7 +204,7 @@ kitchen wall, Ftp://2gifamku.jqv10es.MX/yJ0rhtMYX/Y1Wq%F90RYO1F/NT0%aeAG3/r3Act1 he ate the house, end with the Ghost in order): Forty-three pence?' To five hundred Gargerys.' `I say, Pip; stay -7WO6F.XN--11B5BS3A9AJ6G/1L%f9G0NEu/L2lD/mQGNS9UhgCEb out with +7WO6F.XN--45BRJ9C/1L%f9G0NEu/L2lD/mQGNS9UhgCEb out with ftp://mIMU.t4d24n4lyx39.zURN708MCNGK-TJ42GLLBQRJHVENGPO.bw:59930/KmBYQKHfcjNRe/rK3fUjg%0Ad/.zHeVoCaC5/w%A2%F7up9o7J0Eq/ySBVhB his shot, and reposing no help to my seat. It was in the kitchen wall, because I calculated the sounds by giving me by the name for a rush of Joe's forge @@ -299,7 +299,7 @@ She drew the kitchen, carrying file:///Y?GG/BBqMPBJ/nsxX3qP/8P24WdqBxH so low wooden hut ftp://7vl2w.jp/b%a5fBYyDR/ZN%62LG9aYpjSwn0yWg/nG97gndK%69XZ#fet%55XXZhslTNrq5T where it seemed to give Pirrip as -<79wvzk3.24dyfkxg0f4z-hsqgqqzj2p9n59el0a.XN--DEBA0AD/:8epfLrewivg%488s/2ORX8M3/B0KpeeB/2rbuCnnBF/4P6%1cU6fTGNj/o%3aZMIHdO> +<79wvzk3.24dyfkxg0f4z-hsqgqqzj2p9n59el0a.XN--FIQS8S/:8epfLrewivg%488s/2ORX8M3/B0KpeeB/2rbuCnnBF/4P6%1cU6fTGNj/o%3aZMIHdO> to say, on the guiltily coarse his head, he tried to the Uow9.sF.GP/sF3FCFSbCRWGNJY%aaU/DVXA5nIOWmjc6S/FQXdiBw/Y7~cVmpypgft/vU1%D4z remark. `There's one sprinkled all I was possible she beggared me. All these @@ -311,7 +311,7 @@ Http://Ed095eimjy.rlb5698d.kp/_l5uoOO/aA494s?3nSxdIpE=y%79qu+2un1hGR&J%76=8&L%be he shook her veil so thick nor my milk and would impart all had returned, with soap-suds, I had FILE:///#F9Bgl just like thin snow. `Enough of his right side of thenceforth sitting -jyia054.l814D9SNHRRA5RJCCW.kvxga.XN--0ZWM56D/sBbx24%f2Tw2/Sd0Lul0Vg1bbIqW~/lveEw +jyia054.l814D9SNHRRA5RJCCW.kvxga.XN--3E0B707E/sBbx24%f2Tw2/Sd0Lul0Vg1bbIqW~/lveEw in File:///KKfIe63z/BETB.T%C6sG/RcYgnOycg my soul. I sat down on it, I have been a spoon that the pie, blacksmith?' asked Estella of it made a mouth wide open, and so @@ -324,7 +324,7 @@ FTP://7qf.hlj.TN/IXOeaf/t%c52Jxwy#YkcAy2 of the stranger looked at it, I pointed to Ftp://Gbu5t.HT/xad4fgjaN#GLpU3XQd6%7F(cHIz himself. No glimpse of file:///A1omJiPzafgAm/addqzG%dc%62/Lw1mamTg herself, I saw that he would have been there, I was too far and uncomfortable by it. -http://89qw34ksf0qf6iq264of-1nya4ds7qvpixw8c951aw8wcm3.qxk7usa.N8j1frzfgnkbi9y2.XN--9T4B11YI5A/Unwn3/%97gnj0/GQgJC~OFxsdE8ubC7/IWy450/8%7CQVgdI8/soi0BviZt/Zjs%10i5Xh?qi8t9=rBbPok,Si&*Xl=Q+fT&Hx4%D70=84+8W%18+sV2BU6xCDP%47M&Usbms= +http://89qw34ksf0qf6iq264of-1nya4ds7qvpixw8c951aw8wcm3.qxk7usa.N8j1frzfgnkbi9y2.XN--CLCHC0EA0B2G2A9GCD/Unwn3/%97gnj0/GQgJC~OFxsdE8ubC7/IWy450/8%7CQVgdI8/soi0BviZt/Zjs%10i5Xh?qi8t9=rBbPok,Si&*Xl=Q+fT&Hx4%D70=84+8W%18+sV2BU6xCDP%47M&Usbms= Under the Above,' I rather to become transfixed -- he gave me out of the kitchen empty-handed, to keep him, I had made a Z7tid0uh.eZMOI-M1.umlsyksuzovqdw6wozbd.BW/m%e684OhC/ErAhpGiG subject, if he had @@ -468,7 +468,7 @@ hard twist upon his -- `Well, boy,' Uncle Pumblechook: a look at the sermon he had heard it had hesitated as little window, violently plunging and she had committed, and had all about the present calling, which the fingers of tea on Saturdays than this country, gentlemen, but I could see those, -https://nWC9-RIA00RPVL4SSWRICWWX3NH5SMQIA7IPMCK174T30VQBL-M6.XN--0ZWM56D/CwE%e2rWaYZmE?X_coOVl=kqGQ&Pli=MjKg-+wO6Eh+lbbcN&x3M=3kQh99m92mRdf&iiO2wXgQ=qyWVG9G +https://nWC9-RIA00RPVL4SSWRICWWX3NH5SMQIA7IPMCK174T30VQBL-M6.XN--3E0B707E/CwE%e2rWaYZmE?X_coOVl=kqGQ&Pli=MjKg-+wO6Eh+lbbcN&x3M=3kQh99m92mRdf&iiO2wXgQ=qyWVG9G too, if you remember what stock she told me again. `But I know what file:///enqvF%EFLOBsZhl8h2z wittles is?' `Yes, ma'am.' `Estella, take me again and ftp://133.4.130.192/p%b1LgcONfo%bc&kmH/Ibh6Lq%DCJhnswT%1A refractory @@ -493,7 +493,7 @@ right-side ftp://zxmv98m49669kfvf24o12w3u93wbovfp-1smo6y90e27n133okplcjqrmv-a.CD/JM5RAAY/sJdBntYWuEY4uB7hz/ozRSmFJD/#Xv22:Xvg flaxen curls and tables, and a foot of the blacksmith's.' `Halloa!' said Joe, staring at that it had withered like a infunt, and took another look about the -rum <6S8.Crwllo5e3.jmtz.XN--G6W251D/6InlQn/hnhu2f%ac8tX/apq%0D6o/> out at once. +rum <6S8.Crwllo5e3.jmtz.XN--GECRJ9C/6InlQn/hnhu2f%ac8tX/apq%0D6o/> out at once. Three Jolly Bargemen to think she seemed to tell you were. When we saw the file coming at my slice. I have mentioned it with the wooden hut where we had got up trying to file:///gVW/nnRNxPfMXKb%72Aq%4A hand. If ever grateful for. If a @@ -662,7 +662,7 @@ open,' he https://227.086.128.010:64985/MDKuFInA86qto5/_cK=4S%49Ic/SPp76/TlV%0Arlwfx/ wiped the liquor. He was the bad; and some one Ftp://171.160.94.43/ALTgS46I4VM/55PbbK/5N%faTSE another -Ftp://3zd7z.etw.XN--JXALPDLP/4UztCuTbW2z/LL%2cDI/dTYSi9 turned to put straws +Ftp://3zd7z.etw.XN--KPRW13D/4UztCuTbW2z/LL%2cDI/dTYSi9 turned to put straws down by a most powerfully down t6xfr.wxjz5p2t5.zl8m4.MN/2cbpjk/gsdm/5Mvc-j3rc/16Wb65&c7x to me, and all that know the window, @@ -993,7 +993,7 @@ upon a door, which was gobbling mincemeat, meatbone, bread, some lace for it that Joe's blue file:///EYS2nDf%9671qsm34OZeB%e5lUA/rYBDn0DKs0/ eyes, had an hour longer than at me, and dismal, and gloves, and that's further than I mpuwl0.BA/MkvAvc?j%11K4=9gE%613&qOOEP0t=g7EXs looked on. `Now, boy! -g6tylc0.daeczh.4q.XN--9T4B11YI5A/1SbCR9cX1%3D/YfP8CpLKn5KzTL8/Kj11z%B7OuqJU;qM4P +g6tylc0.daeczh.4q.XN--CLCHC0EA0B2G2A9GCD/1SbCR9cX1%3D/YfP8CpLKn5KzTL8/Kj11z%B7OuqJU;qM4P Why, here's a ridiculous old chap. And looked up by hand. `Why don't like `sulks.' Therefore, I was in such game?' Everybody, myself drifting down his chest and he had made me worse by-and-by. I was a @@ -1035,7 +1035,7 @@ in every word out again. `You are prison-ships, and they fought for us heavy. `I Bolted, myself, 5.Piba4ac.JE/55M1H/AZXdj and thread, and we after him, or to inspire confidence. This was brought you spoke all the act, he -couldn't m-k6-ej7x.XN--HLCJ6AYA9ESC7A/suVrNQSIj9/TmRhHbe/o&0dbqR/ keep the fire +couldn't m-k6-ej7x.XN--J6W193G/suVrNQSIj9/TmRhHbe/o&0dbqR/ keep the fire between the forge was busy in it. Until hGE9YH3D6.SD/m%1EpDJrzO/Tf2Xxqq8L/YJT7BTEY%661PvcMgOr/29ZbuJuWl6q/ she jammed @@ -1329,7 +1329,7 @@ sort Http://w9ys35.wb55p6l.hxl.rs/Y97%58Lp8JjLZw/5L -- FILE://155.24.106.255/3VEZIT7 if it was to him, I might not do not afraid of report, and looking rather to make nothing of a confidential voice, d1y8zvhwq40bi3tom.hPCZ.gJ-286X.TG/ayWKrgAvF6tn/L4SgquZT6C/1DmNe/CI69rJ/%f6QrzZGkSQ -as lda5l5wc.XN--HGBK6AJ7F53BBA/pr80SSZ/eNM1%D50lp/Rc%8EimOET if he would be +as lda5l5wc.XN--KPRY57D/pr80SSZ/eNM1%D50lp/Rc%8EimOET if he would be supposed,' said the wind and so we were read the conversation consisted of it had so that we saw some bread, some l13t2t.sk/O%2BmRkw/@0AgGL@NX/wgt&aggDcp#0IYe'C brandy out: no black velvet diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/urls.from.random.text.with.urls.txt b/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/urls.from.random.text.with.urls.txt index bf0d419b2a6..cf216ca085a 100644 --- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/urls.from.random.text.with.urls.txt +++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/urls.from.random.text.with.urls.txt @@ -10,7 +10,7 @@ http://Rcbu6/Oxc%C0IkGSZ8rO9IUpd/BEvkvw3nWNXZ/P%17tp3gjATN/0ZRzs file:///2CdsP/U2GCLT Http://Pzw978uzb.ai/yB;mt/o8hVKG/%231Y/Xb1%bb6v1fhjfdkfkBvxed?8mq~=OvF&STpJJk=ws0ZO&0DRA= HTTP://173.202.175.16/Md7tF6lj7r/oioJ9TpL8/x%03PjXgMMBC7C3%BDWzoVMzH -Https://yu7v33rbt.vC6U3.XN--JXALPDLP/y%4fMSzkGFlm/wbDF4m +Https://yu7v33rbt.vC6U3.XN--KPRW13D/y%4fMSzkGFlm/wbDF4m M19nq.0URV4A.Me.CC/mj0kgt6hue/dRXv8YVLOw9v/CIOqb ftp://evzed8zvv.l2xkky.Dq85qcl1.eu:1184/07eY0/3X1OB7gPUk/J8la5OPUY3/y1oTItIs1HFPPp/5Q02N0cPyDH87hSy/jheYGF8s%F3P/%86PmYhi/ViKHoxsHqM8J ftp://213.7.210.47/%e5pFkj6e6Jczc/ypJGG/z%663jYR/37IxLQBPr/Ciq50EUIdueyj @@ -23,13 +23,13 @@ Ftp://Xmswrxn8d-1s.pe.gm/dB6C3xTk%D3x/EKOiTmk%7c/API/0cdgpi;Type=a FILE:///rKnQkS0MAF#tM%53_2%03%d6ZICH ftp://R5ecjkf1yx4wpskfh.tv0y3m90ak.0R605.se:51297/zpWcRRcG/1woSqw7ZUko/ file:///%C5=.%8by/uuFXEaW8.%7E4/DRM%33Kh2xb8u%7FHizfLn/aoF06#7srWW%2EKoFf -HTTP://yA2O3F.XN--0ZWM56D/qPDTt/MwMXGQq2S7JT/TJ2iCND +HTTP://yA2O3F.XN--3E0B707E/qPDTt/MwMXGQq2S7JT/TJ2iCND file:///Gdx5CDZYW%6cnzMJ/7HJ/J%63BSZDXtS/yfWXqq6# http://1qvgjd1.TP/7oq5gWW/Gwqf8fxBXR4/?Br,q=ayMz0&1IO%370N7=;Sl1czc2L+5bRISfD+w&ygP3FhV%E1w36=2Rx ftp://5SCC6BUYP.Knf1cvlc22z9.1dc3rixt5ugyq4/5OnYTSN/QpCdo/t3zqkI/pn5skT/oJgrGy7 http://2dkbeuwsto3i3e8jaxi6su9wjlmwygtpdp7g65611z-2bbr82uhjqkdv2jrh7.KZ/FiSvI/aaB&dPQ%42kLdM FTP://Hi144dz6hctql2n3uom.GE/%1A4OBV%63h/DoA4hpXFmqldOw-MB/PNYoaSDJB2F1k5/Nx%BBEDhrHhcMB -ftp://w0yaysrl.XN--9T4B11YI5A/y4FFU%c4F0B/Dh9%D1dGK3bN/EqxueQEsX2p5/xgf4Jxr%D9q/2ubmieRM +ftp://w0yaysrl.XN--CLCHC0EA0B2G2A9GCD/y4FFU%c4F0B/Dh9%D1dGK3bN/EqxueQEsX2p5/xgf4Jxr%D9q/2ubmieRM http://t9wa4.rjcahbc06qmyk9jkhu3f.ZA/vIwW3sc3Pg/Bwmeo6KAjkRY N54l6e.vu/1m2%8bMFjv/oBdy%36.eL;33/N%d21Qvm/ http://ah-2d4.ASIA/qmp @@ -75,7 +75,7 @@ http://4u3o/BKdhwRyzG file:///LdsHfPABFz1vRD1OB6Yl/RS6&1Gmz/mfYul/ ftp://E1cdf-p.XN--MGBERP4A5D4AR:60510/qMaw4kSSgYM/7jgIuL/gSVW6O91/2bhnsj/kl7R5sgn6&X5EiZdZ0WhTX3T/fa%f3Azz z3ymb.KM/DdnrqoBz=YtxSB -FTP://7kgip3z.XN--HGBK6AJ7F53BBA:15983/OYEQzIA0 +FTP://7kgip3z.XN--KPRY57D:15983/OYEQzIA0 nezt6awdc.lSZDSU14B1OH.4n6nkmjyyj.cc ftp://085.062.055.011/bopfVV/ ftp://Mbbn8n.6ge03fiivyc7of.PS/mvb/X8VNt/5WrMZpw/flC6Rs @@ -93,12 +93,12 @@ https://[3790:ad57:0B63::e5f7:f6ac:164C]/Obax;zcD/Y%48%9a/Z2xcdar bl60k0jqkc9.oow84o1.BF/Xly5cTna/BzoQuHi3r8e/o5BDNrvT/=6HRdBjH/Mrp5%02/p%e9pT2Ae ftp://Bs3ceuxd8ii66gt.X8wwdpt.BB:27095/3BfkvfzcmTS/FTffh&S/gIWvJ5Kd/AlOQ%3EnO http://ch43n.51rkj.rze.mq/pJjrSAiuSv/3x/EK%59ReZM9w -zQFC1SPO96J.Jy20d8.xn--0zwm56d:863/0OWpT4dpkMURAGe/nFg/LQBUr%3E/af7dO1 +zQFC1SPO96J.Jy20d8.xn--3e0b707e:863/0OWpT4dpkMURAGe/nFg/LQBUr%3E/af7dO1 ftp://Xctk9iigg.cat/u3cX1d/Sx6m3dql/d%46;type=d#0i%3cT1yMkZQ HTTPS://56aderic0knmip9lkqdqag14.uk:45885/lELiK:/vF%4C5Enwqy/P5NGJ2b/dD6sg1yMV ftp://vlt.3g45k63viz2.tcnm3.UA:60664/AJ9iqYk%c1/uKbohn2/K%D1kequ4z8rxFpJ Ftp://2gifamku.jqv10es.MX/yJ0rhtMYX/Y1Wq%F90RYO1F/NT0%aeAG3/r3Act1 -7WO6F.XN--11B5BS3A9AJ6G/1L%f9G0NEu/L2lD/mQGNS9UhgCEb +7WO6F.XN--45BRJ9C/1L%f9G0NEu/L2lD/mQGNS9UhgCEb ftp://mIMU.t4d24n4lyx39.zURN708MCNGK-TJ42GLLBQRJHVENGPO.bw:59930/KmBYQKHfcjNRe/rK3fUjg%0Ad/.zHeVoCaC5/w%A2%F7up9o7J0Eq/ySBVhB ftp://lv56pdepzu0b0fo-04qtxv5tt2jc0nsaukrhtz5-e3u1vcb517y3b135zl.e0r1hson.dk/3TVoqjp6%1FCFSkt/006VZfho/gxrWxgDawM3Uk Ftp://7n977.Niyt.2fgkzfhj.q7-DJ.Ow7a.it/5zfRi3PO8/1zfKT9%421tP/?SazEijJq%710COQKWeLE/TdUc%b2u/2AxBw9%4BUN6Zp4Z/KfUZd1MTdPv/L4m1tI3/WJvcK1 @@ -147,20 +147,20 @@ ftp://Lq.es/%B1ZPdTZgB2mNFW/qre92rM file:///IZ47ESCtX%aatQab1/V553gjR?Me/#9%68qPw file:///Y?GG/BBqMPBJ/nsxX3qP/8P24WdqBxH ftp://7vl2w.jp/b%a5fBYyDR/ZN%62LG9aYpjSwn0yWg/nG97gndK%69XZ#fet%55XXZhslTNrq5T -79wvzk3.24dyfkxg0f4z-hsqgqqzj2p9n59el0a.XN--DEBA0AD/:8epfLrewivg%488s/2ORX8M3/B0KpeeB/2rbuCnnBF/4P6%1cU6fTGNj/o%3aZMIHdO +79wvzk3.24dyfkxg0f4z-hsqgqqzj2p9n59el0a.XN--FIQS8S/:8epfLrewivg%488s/2ORX8M3/B0KpeeB/2rbuCnnBF/4P6%1cU6fTGNj/o%3aZMIHdO Uow9.sF.GP/sF3FCFSbCRWGNJY%aaU/DVXA5nIOWmjc6S/FQXdiBw/Y7~cVmpypgft/vU1%D4z ftp://[fd77:4982:C37F:a0a1:7651:E09C:117.093.145.017]/2l91g/s%79lJmUiZ/%A5R2qsJ [62c0::]/d1lmSzoB/5OBVnzn/kOXW%D23 Http://Ed095eimjy.rlb5698d.kp/_l5uoOO/aA494s?3nSxdIpE=y%79qu+2un1hGR&J%76=8&L%bed=uY5hO+s+IKk1S&Q=HHXEC+Gof86QIRHy&35QY5= FILE:///#F9Bgl -jyia054.l814D9SNHRRA5RJCCW.kvxga.XN--0ZWM56D/sBbx24%f2Tw2/Sd0Lul0Vg1bbIqW~/lveEw +jyia054.l814D9SNHRRA5RJCCW.kvxga.XN--3E0B707E/sBbx24%f2Tw2/Sd0Lul0Vg1bbIqW~/lveEw File:///KKfIe63z/BETB.T%C6sG/RcYgnOycg ftp://892f7.oel50j.32.9qj1p-g7lgw.MR:48021/XNKbk2PZQXSvOuGnOAnATDt3/XfHyJtvoC/PW7YrSgf#LmGWJgPw http://sisas.ua/4CU60ZLK4VgY8AR89 FTP://7qf.hlj.TN/IXOeaf/t%c52Jxwy#YkcAy2 Ftp://Gbu5t.HT/xad4fgjaN#GLpU3XQd6%7F(cHIz file:///A1omJiPzafgAm/addqzG%dc%62/Lw1mamTg -http://89qw34ksf0qf6iq264of-1nya4ds7qvpixw8c951aw8wcm3.qxk7usa.N8j1frzfgnkbi9y2.XN--9T4B11YI5A/Unwn3/%97gnj0/GQgJC~OFxsdE8ubC7/IWy450/8%7CQVgdI8/soi0BviZt/Zjs%10i5Xh?qi8t9=rBbPok,Si&*Xl=Q+fT&Hx4%D70=84+8W%18+sV2BU6xCDP%47M&Usbms= +http://89qw34ksf0qf6iq264of-1nya4ds7qvpixw8c951aw8wcm3.qxk7usa.N8j1frzfgnkbi9y2.XN--CLCHC0EA0B2G2A9GCD/Unwn3/%97gnj0/GQgJC~OFxsdE8ubC7/IWy450/8%7CQVgdI8/soi0BviZt/Zjs%10i5Xh?qi8t9=rBbPok,Si&*Xl=Q+fT&Hx4%D70=84+8W%18+sV2BU6xCDP%47M&Usbms= Z7tid0uh.eZMOI-M1.umlsyksuzovqdw6wozbd.BW/m%e684OhC/ErAhpGiG ftp://tw7d-6yu.im:2055/%66qbqzss/OmPGW;type=d FTP://zst.tn/QcUpaA/VKvJ2/JN6AKew/iXYIiHm7mfPFmD%21E5/yTQpoiqdbaaS1/LnzOX#VqsobH @@ -228,7 +228,7 @@ file:///UIIGOxv6jvF2%c0/%A8J3%677Gmq8im1zklKhqx/HMhCSY2QcyxvL/ http://Qhk9z.zm/cOGBen/mBsDycEI5V7L1s%84WUj7863/p%5f~okuRD51b0M?b%F2d%67ujGr=oh8PWUtK&j6uX7baX=&sg3RUocA9W=m5IaF&JWH9G=fyiOtnC3+7RJA+ippw96rvu+BxtGg&F6f1=jmPS&3PE0xX5=TGV%5c5J&%fc@NSEynhuvb=&MkRIt33= Http://[98cc:433d:2C25:62dd:54ba:d10b:63d3:4C40]/YlbNrJod/fdjuN/qYqSdqr5/KAbXYHO%F0m7Ws9 file:///ywFY5HK/XAv@v%66o/M2O4Wlny50hypf5%02A8 -https://nWC9-RIA00RPVL4SSWRICWWX3NH5SMQIA7IPMCK174T30VQBL-M6.XN--0ZWM56D/CwE%e2rWaYZmE?X_coOVl=kqGQ&Pli=MjKg-+wO6Eh+lbbcN&x3M=3kQh99m92mRdf&iiO2wXgQ=qyWVG9G +https://nWC9-RIA00RPVL4SSWRICWWX3NH5SMQIA7IPMCK174T30VQBL-M6.XN--3E0B707E/CwE%e2rWaYZmE?X_coOVl=kqGQ&Pli=MjKg-+wO6Eh+lbbcN&x3M=3kQh99m92mRdf&iiO2wXgQ=qyWVG9G file:///enqvF%EFLOBsZhl8h2z ftp://133.4.130.192/p%b1LgcONfo%bc&kmH/Ibh6Lq%DCJhnswT%1A ftp://1xf.ipl4f0y6c4.VA/LHuq~/p2nPbE/0YGGNJB%DEje2psef_B/aKOuMl1Q9 @@ -240,7 +240,7 @@ http://nEN5ZN.EG/%0efsf4v30L file:///19%9947/ksd3Sq7W78%27/2K_Ylzcu2q r8sht9qzsc1e2wp.ci/8SbPwlW%5ac/qKEqFi0Q ftp://zxmv98m49669kfvf24o12w3u93wbovfp-1smo6y90e27n133okplcjqrmv-a.CD/JM5RAAY/sJdBntYWuEY4uB7hz/ozRSmFJD/#Xv22:Xvg -6S8.Crwllo5e3.jmtz.XN--G6W251D/6InlQn/hnhu2f%ac8tX/apq%0D6o/ +6S8.Crwllo5e3.jmtz.XN--GECRJ9C/6InlQn/hnhu2f%ac8tX/apq%0D6o/ file:///gVW/nnRNxPfMXKb%72Aq%4A file:///Fzza388TQ file:/// @@ -314,7 +314,7 @@ file:///3%aexrb7UdZ5GpR4ZIfoxwL/vQV%4a2zQxki/QRji6gHpMGgBaM/d%71A2CTpZv-kF0tD/Ig f5ms.jp/%A1FpERWwTd%BFG/ExC8V5aqx5l2CLJr0mJb5u/DgMvEzAr2U/py9Vg/igr9PzANtw/FFiN1E7 https://227.086.128.010:64985/MDKuFInA86qto5/_cK=4S%49Ic/SPp76/TlV%0Arlwfx/ Ftp://171.160.94.43/ALTgS46I4VM/55PbbK/5N%faTSE -Ftp://3zd7z.etw.XN--JXALPDLP/4UztCuTbW2z/LL%2cDI/dTYSi9 +Ftp://3zd7z.etw.XN--KPRW13D/4UztCuTbW2z/LL%2cDI/dTYSi9 t6xfr.wxjz5p2t5.zl8m4.MN/2cbpjk/gsdm/5Mvc-j3rc/16Wb65&c7x ftp://D02-auxxaeqnv9ve-jlmo3.l10vqu.12jl.2mvjwrsqm.BA/r71QLLNu6oGJjG/HbxrX1Grq8/QR%2agZv4hR file:///XoCg%EDVf/A3ibJYjU @@ -476,7 +476,7 @@ ftp://53.151.134.240/uZqGXLUIu-J/=%0C2pO/PvL0%19MpQBv/ FILE:///Kywof5D5q/0TRS/zayrkrnENB file:///EYS2nDf%9671qsm34OZeB%e5lUA/rYBDn0DKs0/ mpuwl0.BA/MkvAvc?j%11K4=9gE%613&qOOEP0t=g7EXs -g6tylc0.daeczh.4q.XN--9T4B11YI5A/1SbCR9cX1%3D/YfP8CpLKn5KzTL8/Kj11z%B7OuqJU;qM4P +g6tylc0.daeczh.4q.XN--CLCHC0EA0B2G2A9GCD/1SbCR9cX1%3D/YfP8CpLKn5KzTL8/Kj11z%B7OuqJU;qM4P file:///TJa%86AczeCmM5QMhi/Wox~Ajl/WxUF%5eSA:y%0fD%E21/x%cca%d3Qgx/8iWJ5-h%26/fCK%01nQNrK8#ygTTB file:///~%303cUUVYTEaQU5%5DXbogiPKb/favR2rETEh/9TXM%15u/nYCOZpZgL file:///mJM%a1/jv5%53QDqE/bFMu0CBp @@ -496,7 +496,7 @@ http://gpu16lz.LS/9e%daJrwQfHEpFvsZ3jx/c4STIJ/CmvEGAUx9f/ file://ij9anjtok86ro.uN-BGDQ855IB.sDXAQR.5kr8kz.3J3M8XRM.18r3s0g-6.4rjsmwue0lwao0og17d-5-1.F1h3qgkul29yw2t4p4se5clomncxhmoy.g6c9tbz7.pa/5LMtmbl/1tfIF/pBOV7Hc HTTPS://bF2RA.kw/1TA9pTTBg/nM/VSRo%85Kt?%62mxNfo=HDowgwkM3&9oPOLH2=yKOxIe+YNtt 5.Piba4ac.JE/55M1H/AZXdj -m-k6-ej7x.XN--HLCJ6AYA9ESC7A/suVrNQSIj9/TmRhHbe/o&0dbqR/ +m-k6-ej7x.XN--J6W193G/suVrNQSIj9/TmRhHbe/o&0dbqR/ ftp://242.228.138.8/o%CC_QjILS%17aYH/%caw8CcVZyPRZ/ hGE9YH3D6.SD/m%1EpDJrzO/Tf2Xxqq8L/YJT7BTEY%661PvcMgOr/29ZbuJuWl6q/ Ftp://mez27g2tpmk.MC/%B8AHk%95etDns%46/gXbsCn%6C-/s8_Jmy/DhmfT~Di6KD @@ -633,7 +633,7 @@ http://047.014.184.200/Z_QdOwjzfBue4Nt/aEn/xuEQD/cXlnoxHIK%7d8h/1%eegEk7E0/8Ejku Http://w9ys35.wb55p6l.hxl.rs/Y97%58Lp8JjLZw/5L FILE://155.24.106.255/3VEZIT7 d1y8zvhwq40bi3tom.hPCZ.gJ-286X.TG/ayWKrgAvF6tn/L4SgquZT6C/1DmNe/CI69rJ/%f6QrzZGkSQ -lda5l5wc.XN--HGBK6AJ7F53BBA/pr80SSZ/eNM1%D50lp/Rc%8EimOET +lda5l5wc.XN--KPRY57D/pr80SSZ/eNM1%D50lp/Rc%8EimOET l13t2t.sk/O%2BmRkw/@0AgGL@NX/wgt&aggDcp#0IYe'C FILE://a6ys9a4.xj.BY/%99BGXp/F=yJtxc71/gvXuHuB9k 212.072.006.032/6kV8ce%2e/%e7lzm-HB%4artP/zg6tWMW7RIG?U7=HAXw$D3sM%7DyDJ&Gt= diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/standard/TestUAX29URLEmailTokenizerFactory.java b/lucene/analysis/common/src/test/org/apache/lucene/analysis/standard/TestUAX29URLEmailTokenizerFactory.java index f8de0fdae5d..1bad8ddfa73 100644 --- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/standard/TestUAX29URLEmailTokenizerFactory.java +++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/standard/TestUAX29URLEmailTokenizerFactory.java @@ -75,7 +75,7 @@ public class TestUAX29URLEmailTokenizerFactory extends BaseTokenStreamFactoryTes + " samba Halta gamba " + "ftp://119.220.152.185/JgJgdZ/31aW5c/viWlfQSTs5/1c8U5T/ih5rXx/YfUJ/xBW1uHrQo6.R\n" + "M19nq.0URV4A.Me.CC/mj0kgt6hue/dRXv8YVLOw9v/CIOqb\n" - + "Https://yu7v33rbt.vC6U3.XN--JXALPDLP/y%4fMSzkGFlm/wbDF4m" + + "Https://yu7v33rbt.vC6U3.XN--KPRW13D/y%4fMSzkGFlm/wbDF4m" + " inter Locutio " + "[c2d4::]/%471j5l/j3KFN%AAAn/Fip-NisKH/\n" + "file:///aXvSZS34is/eIgM8s~U5dU4Ifd%c7" @@ -91,7 +91,7 @@ public class TestUAX29URLEmailTokenizerFactory extends BaseTokenStreamFactoryTes "samba", "Halta", "gamba", "ftp://119.220.152.185/JgJgdZ/31aW5c/viWlfQSTs5/1c8U5T/ih5rXx/YfUJ/xBW1uHrQo6.R", "M19nq.0URV4A.Me.CC/mj0kgt6hue/dRXv8YVLOw9v/CIOqb", - "Https://yu7v33rbt.vC6U3.XN--JXALPDLP/y%4fMSzkGFlm/wbDF4m", + "Https://yu7v33rbt.vC6U3.XN--KPRW13D/y%4fMSzkGFlm/wbDF4m", "inter", "Locutio", "[c2d4::]/%471j5l/j3KFN%AAAn/Fip-NisKH/", "file:///aXvSZS34is/eIgM8s~U5dU4Ifd%c7", diff --git a/lucene/analysis/common/src/tools/java/org/apache/lucene/analysis/standard/GenerateJflexTLDMacros.java b/lucene/analysis/common/src/tools/java/org/apache/lucene/analysis/standard/GenerateJflexTLDMacros.java index 5d7c23d4ae5..0cfea3fafd8 100644 --- a/lucene/analysis/common/src/tools/java/org/apache/lucene/analysis/standard/GenerateJflexTLDMacros.java +++ b/lucene/analysis/common/src/tools/java/org/apache/lucene/analysis/standard/GenerateJflexTLDMacros.java @@ -60,20 +60,21 @@ public class GenerateJflexTLDMacros { private static final String APACHE_LICENSE = "/*" + NL - + " * Copyright 2001-2005 The Apache Software Foundation." + NL - + " *" + 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 obtain a copy of the License at" + NL - + " *" + NL - + " * http://www.apache.org/licenses/LICENSE-2.0" + NL - + " *" + 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 - + " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied." + NL - + " * See the License for the specific language governing permissions and" + NL - + " * limitations under the License." + NL - + " */" + NL + NL; + + " * Licensed to the Apache Software Foundation (ASF) under one or more" + NL + + " * contributor license agreements. See the NOTICE file distributed with" + NL + + " * this work for additional information regarding copyright ownership." + NL + + " * The ASF licenses this file to You under the Apache License, Version 2.0" + NL + + " * (the \"License\"); you may not use this file except in compliance with" + NL + + " * the License. You may obtain a copy of the License at" + NL + + " *" + NL + + " * http://www.apache.org/licenses/LICENSE-2.0" + NL + + " *" + 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 + + " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied." + NL + + " * See the License for the specific language governing permissions and" + NL + + " * limitations under the License." + NL + + " */" + NL; private static final Pattern TLD_PATTERN_1 = Pattern.compile("([-A-Za-z0-9]+)\\.\\s+NS\\s+.*"); diff --git a/lucene/analysis/icu/src/tools/java/org/apache/lucene/analysis/icu/GenerateJFlexSupplementaryMacros.java b/lucene/analysis/icu/src/tools/java/org/apache/lucene/analysis/icu/GenerateJFlexSupplementaryMacros.java index 23cc391879d..2b0ba48cfbb 100644 --- a/lucene/analysis/icu/src/tools/java/org/apache/lucene/analysis/icu/GenerateJFlexSupplementaryMacros.java +++ b/lucene/analysis/icu/src/tools/java/org/apache/lucene/analysis/icu/GenerateJFlexSupplementaryMacros.java @@ -36,40 +36,45 @@ public class GenerateJFlexSupplementaryMacros { static { DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC")); } - - private static final String APACHE_LICENSE - = "/*" + NL - + " * Copyright 2010 The Apache Software Foundation." + NL + + private static final String APACHE_LICENSE + = "/*" + NL + + " * Licensed to the Apache Software Foundation (ASF) under one or more" + NL + + " * contributor license agreements. See the NOTICE file distributed with" + NL + + " * this work for additional information regarding copyright ownership." + NL + + " * The ASF licenses this file to You under the Apache License, Version 2.0" + NL + + " * (the \"License\"); you may not use this file except in compliance with" + NL + + " * the License. You may obtain a copy of the License at" + NL + " *" + 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 obtain a copy of the License at" + NL - + " *" + NL - + " * http://www.apache.org/licenses/LICENSE-2.0" + NL + + " * http://www.apache.org/licenses/LICENSE-2.0" + NL + " *" + 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 + " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied." + NL + " * See the License for the specific language governing permissions and" + NL + " * limitations under the License." + NL - + " */" + NL + NL; + + " */" + NL; public static void main(String args[]) { outputHeader(); - outputMacro("ALetterSupp", "[:WordBreak=ALetter:]"); - outputMacro("FormatSupp", "[:WordBreak=Format:]"); - outputMacro("ExtendSupp", "[:WordBreak=Extend:]"); - outputMacro("NumericSupp", "[:WordBreak=Numeric:]"); - outputMacro("KatakanaSupp", "[:WordBreak=Katakana:]"); - outputMacro("MidLetterSupp", "[:WordBreak=MidLetter:]"); - outputMacro("MidNumSupp", "[:WordBreak=MidNum:]"); - outputMacro("MidNumLetSupp", "[:WordBreak=MidNumLet:]"); - outputMacro("ExtendNumLetSupp", "[:WordBreak=ExtendNumLet:]"); - outputMacro("ExtendNumLetSupp", "[:WordBreak=ExtendNumLet:]"); - outputMacro("ComplexContextSupp", "[:LineBreak=Complex_Context:]"); - outputMacro("HanSupp", "[:Script=Han:]"); - outputMacro("HiraganaSupp", "[:Script=Hiragana:]"); + outputMacro("ALetterSupp", "[:WordBreak=ALetter:]"); + outputMacro("FormatSupp", "[:WordBreak=Format:]"); + outputMacro("NumericSupp", "[:WordBreak=Numeric:]"); + outputMacro("ExtendSupp", "[:WordBreak=Extend:]"); + outputMacro("KatakanaSupp", "[:WordBreak=Katakana:]"); + outputMacro("MidLetterSupp", "[:WordBreak=MidLetter:]"); + outputMacro("MidNumSupp", "[:WordBreak=MidNum:]"); + outputMacro("MidNumLetSupp", "[:WordBreak=MidNumLet:]"); + outputMacro("ExtendNumLetSupp", "[:WordBreak=ExtendNumLet:]"); + outputMacro("ExtendNumLetSupp", "[:WordBreak=ExtendNumLet:]"); + outputMacro("ComplexContextSupp", "[:LineBreak=Complex_Context:]"); + outputMacro("HanSupp", "[:Script=Han:]"); + outputMacro("HiraganaSupp", "[:Script=Hiragana:]"); + outputMacro("SingleQuoteSupp", "[:WordBreak=Single_Quote:]"); + outputMacro("DoubleQuoteSupp", "[:WordBreak=Double_Quote:]"); + outputMacro("HebrewLetterSupp", "[:WordBreak=Hebrew_Letter:]"); + outputMacro("RegionalIndicatorSupp", "[:WordBreak=Regional_Indicator:]"); } static void outputHeader() { diff --git a/lucene/common-build.xml b/lucene/common-build.xml index ef292950c6e..6d79bb93090 100644 --- a/lucene/common-build.xml +++ b/lucene/common-build.xml @@ -476,7 +476,7 @@ - +   ################################################################## JFlex not found. JFlex Home: ${jflex.home} @@ -484,14 +484,14 @@ Please install the jFlex 1.5 version (currently not released) from its SVN repository: - svn co -r 623 http://jflex.svn.sourceforge.net/svnroot/jflex/trunk jflex + svn co -r 722 https://svn.code.sf.net/p/jflex/code/trunk jflex cd jflex mvn install Then, create a build.properties file either in your home directory, or within the Lucene directory and set the jflex.home property to the path where the JFlex trunk checkout is located - (in the above example its the directory called "jflex"). + (in the above example it's the directory called "jflex"). ################################################################## From 00b0209844a8043a87c2464d804f3ef38a1ef86f Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Fri, 6 Dec 2013 17:04:47 +0000 Subject: [PATCH 193/223] SOLR-1301: Fix a couple of bugs around setting up the embedded Solr instance. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1548600 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/solr/hadoop/SolrRecordWriter.java | 35 +++++++++---------- .../org/apache/solr/hadoop/MRUnitBase.java | 1 - .../solr/hadoop/MorphlineReducerTest.java | 2 ++ 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/SolrRecordWriter.java b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/SolrRecordWriter.java index e589c36313f..0850898601e 100644 --- a/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/SolrRecordWriter.java +++ b/solr/contrib/map-reduce/src/java/org/apache/solr/hadoop/SolrRecordWriter.java @@ -42,6 +42,7 @@ import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer; import org.apache.solr.common.SolrInputDocument; import org.apache.solr.core.CoreContainer; import org.apache.solr.core.CoreDescriptor; +import org.apache.solr.core.HdfsDirectoryFactory; import org.apache.solr.core.SolrCore; import org.apache.solr.core.SolrResourceLoader; import org.slf4j.Logger; @@ -138,20 +139,11 @@ class SolrRecordWriter extends RecordWriter { } LOG.info("Creating embedded Solr server with solrHomeDir: " + solrHomeDir + ", fs: " + fs + ", outputShardDir: " + outputShardDir); - Properties props = new Properties(); - // FIXME note this is odd (no scheme) given Solr doesn't currently - // support uris (just abs/relative path) Path solrDataDir = new Path(outputShardDir, "data"); - if (!fs.exists(solrDataDir) && !fs.mkdirs(solrDataDir)) { - throw new IOException("Unable to create " + solrDataDir); - } String dataDirStr = solrDataDir.toUri().toString(); - props.setProperty("solr.data.dir", dataDirStr); - props.setProperty("solr.home", solrHomeDir.toString()); - SolrResourceLoader loader = new SolrResourceLoader(solrHomeDir.toString(), - null, props); + SolrResourceLoader loader = new SolrResourceLoader(solrHomeDir.toString(), null, null); LOG.info(String .format(Locale.ENGLISH, @@ -159,18 +151,25 @@ class SolrRecordWriter extends RecordWriter { solrHomeDir, solrHomeDir.toUri(), loader.getInstanceDir(), loader.getConfigDir(), dataDirStr, outputShardDir)); - CoreContainer container = new CoreContainer(loader); - container.load(); - CoreDescriptor descr = new CoreDescriptor(container, "core1", - ".", props); - - SolrCore core = container.create(descr); - container.register(core, false); - + // TODO: This is fragile and should be well documented + System.setProperty("solr.directoryFactory", HdfsDirectoryFactory.class.getName()); + System.setProperty("solr.lock.type", "hdfs"); System.setProperty("solr.hdfs.nrtcachingdirectory", "false"); System.setProperty("solr.hdfs.blockcache.enabled", "false"); System.setProperty("solr.autoCommit.maxTime", "-1"); System.setProperty("solr.autoSoftCommit.maxTime", "-1"); + + CoreContainer container = new CoreContainer(loader); + container.load(); + + Properties props = new Properties(); + props.setProperty(CoreDescriptor.CORE_DATADIR, dataDirStr); + + CoreDescriptor descr = new CoreDescriptor(container, "core1", solrHomeDir.toString(), props); + + SolrCore core = container.create(descr); + container.register(core, false); + EmbeddedSolrServer solr = new EmbeddedSolrServer(container, "core1"); return solr; } diff --git a/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MRUnitBase.java b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MRUnitBase.java index 68f32cb07b0..93f620f85a5 100644 --- a/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MRUnitBase.java +++ b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MRUnitBase.java @@ -45,7 +45,6 @@ public abstract class MRUnitBase extends SolrTestCaseJ4 { } protected void setupHadoopConfig(Configuration config) throws IOException { - config.set(SolrOutputFormat.ZIP_NAME, solrHomeZip.getName()); String tempDir = TEMP_DIR + "/test-morphlines-" + System.currentTimeMillis(); new File(tempDir).mkdirs(); diff --git a/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineReducerTest.java b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineReducerTest.java index e33c651042f..665ef04f3ea 100644 --- a/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineReducerTest.java +++ b/solr/contrib/map-reduce/src/test/org/apache/solr/hadoop/MorphlineReducerTest.java @@ -36,6 +36,7 @@ import org.apache.lucene.util.Constants; import org.apache.solr.common.SolrInputDocument; import org.junit.AfterClass; import org.junit.BeforeClass; +import org.junit.Ignore; import org.junit.Test; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; @@ -95,6 +96,7 @@ public class MorphlineReducerTest extends MRUnitBase { } @Test + @Ignore("This test cannot currently work because it uses a local filesystem output path for the indexes and Solr requires hdfs output paths") public void testReducer() throws Exception { MySolrReducer myReducer = new MySolrReducer(); try { From d8f11614182474dc8f3c8a4bc2aec5fe94d087ec Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Fri, 6 Dec 2013 17:34:55 +0000 Subject: [PATCH 194/223] SOLR-1301: Update to Morphlines 0.9.0 git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1548605 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/ivy-versions.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lucene/ivy-versions.properties b/lucene/ivy-versions.properties index 78c1973b82b..b08b01f82bf 100644 --- a/lucene/ivy-versions.properties +++ b/lucene/ivy-versions.properties @@ -14,7 +14,7 @@ com.carrotsearch.randomizedtesting.version = 2.0.13 /com.carrotsearch/hppc = 0.5.2 -com.cloudera.cdk.cdk-morphlines.version = 0.8.1 +com.cloudera.cdk.cdk-morphlines.version = 0.9.0 /com.cloudera.cdk/cdk-morphlines-avro = ${com.cloudera.cdk.cdk-morphlines.version} /com.cloudera.cdk/cdk-morphlines-core = ${com.cloudera.cdk.cdk-morphlines.version} /com.cloudera.cdk/cdk-morphlines-hadoop-sequencefile = ${com.cloudera.cdk.cdk-morphlines.version} From c7a3b968937a2219bae7b6f83a5f2c85d08f15d7 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Fri, 6 Dec 2013 19:01:03 +0000 Subject: [PATCH 195/223] SOLR-5532: SolrJ Content-Type validation is too strict for some webcontainers / proxies. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1548659 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 8 ++++++-- .../apache/solr/client/solrj/impl/HttpSolrServer.java | 10 +++++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index d51fcb0df65..3ae9bcb31e3 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -192,8 +192,12 @@ Bug Fixes * SOLR-5524: Exception when using Query Function inside Scale Function. (Trey Grainger, yonik) -* SOLR-5540: HdfsLockFactory should explicitly create the lock parent directory if - necessary. (Mark Miller) +* SOLR-5540: HdfsLockFactory should explicitly create the lock parent directory + if necessary. (Mark Miller) + +* SOLR-5532: SolrJ Content-Type validation is too strict for some + webcontainers / proxies. (Jakob Furrer, hossman, Shawn Heisey, Uwe Schindler, + Mark Miller) Optimizations ---------------------- diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrServer.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrServer.java index ff4a5aa429a..11b680ff4c3 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrServer.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrServer.java @@ -26,6 +26,7 @@ import java.util.Collections; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.Locale; import java.util.Set; import org.apache.commons.io.IOUtils; @@ -41,6 +42,7 @@ import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.client.params.ClientPNames; import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.entity.ContentType; import org.apache.http.entity.InputStreamEntity; import org.apache.http.entity.mime.FormBodyPart; import org.apache.http.entity.mime.HttpMultipartMode; @@ -437,9 +439,11 @@ public class HttpSolrServer extends SolrServer { String procCt = processor.getContentType(); if (procCt != null) { - if (!contentType.equals(procCt)) { - // unexpected content type - String msg = "Expected content type " + procCt + " but got " + contentType + "."; + String procMimeType = ContentType.parse(procCt).getMimeType().trim().toLowerCase(Locale.ROOT); + String mimeType = ContentType.parse(contentType).getMimeType().trim().toLowerCase(Locale.ROOT); + if (!procMimeType.equals(mimeType)) { + // unexpected mime type + String msg = "Expected mime type " + procMimeType + " but got " + mimeType + "."; Header encodingHeader = response.getEntity().getContentEncoding(); String encoding; if (encodingHeader != null) { From 130808e4e3a33ac4953622f85d3423b690fa73eb Mon Sep 17 00:00:00 2001 From: Steven Rowe Date: Fri, 6 Dec 2013 23:11:12 +0000 Subject: [PATCH 196/223] LUCENE-5357: Sync small change (/Katakana/ => /Katakana [x ExtendNumLet] x Katakana/ in the pattern) from UAX29URLEmailTokenizerImpl.jflex to StandardTokenizerImpl.jflex git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1548746 13f79535-47bb-0310-9956-ffa450edef68 --- .../standard/StandardTokenizerImpl.java | 788 +++++++++--------- .../standard/StandardTokenizerImpl.jflex | 4 +- 2 files changed, 390 insertions(+), 402 deletions(-) diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/StandardTokenizerImpl.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/StandardTokenizerImpl.java index 974ed9de84a..4f33cfb0398 100644 --- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/StandardTokenizerImpl.java +++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/StandardTokenizerImpl.java @@ -221,11 +221,11 @@ public final class StandardTokenizerImpl implements StandardTokenizerInterface { private static final String ZZ_ACTION_PACKED_0 = "\1\0\26\1\1\2\1\3\1\4\1\1\1\5\1\6"+ "\1\7\1\2\1\10\21\0\1\2\1\0\1\2\12\0"+ - "\1\3\10\0\1\4\1\2\11\0\1\2\55\0\1\2"+ - "\74\0\1\2\1\1\36\0"; + "\1\3\10\0\1\2\11\0\1\2\55\0\1\2\65\0"+ + "\1\2\1\1\36\0"; private static int [] zzUnpackAction() { - int [] result = new int[221]; + int [] result = new int[213]; int offset = 0; offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); return result; @@ -260,7 +260,7 @@ public final class StandardTokenizerImpl implements StandardTokenizerInterface { "\0\u06a8\0\u1aa0\0\u1b2e\0\u1bbc\0\u1c4a\0\u1cd8\0\u1d66\0\u1df4"+ "\0\u1e82\0\u1f10\0\u1f9e\0\u202c\0\u20ba\0\u2148\0\u21d6\0\u2264"+ "\0\u22f2\0\u2380\0\u240e\0\u249c\0\u252a\0\u25b8\0\u2646\0\u26d4"+ - "\0\u2762\0\u0e6c\0\u27f0\0\u287e\0\u290c\0\u299a\0\u2a28\0\u2ab6"+ + "\0\u0e6c\0\u2762\0\u27f0\0\u287e\0\u290c\0\u299a\0\u2a28\0\u2ab6"+ "\0\u2b44\0\u2bd2\0\u2c60\0\u2cee\0\u2d7c\0\u2e0a\0\u2e98\0\u2f26"+ "\0\u2fb4\0\u3042\0\u30d0\0\u315e\0\u31ec\0\u327a\0\u3308\0\u3396"+ "\0\u3424\0\u34b2\0\u3540\0\u35ce\0\u365c\0\u36ea\0\u3778\0\u3806"+ @@ -276,11 +276,10 @@ public final class StandardTokenizerImpl implements StandardTokenizerInterface { "\0\u6084\0\u6112\0\u61a0\0\u622e\0\u62bc\0\u634a\0\u63d8\0\u6466"+ "\0\u64f4\0\u6582\0\u6610\0\u669e\0\u672c\0\u67ba\0\u6848\0\u68d6"+ "\0\u6964\0\u69f2\0\u6a80\0\u6b0e\0\u6b9c\0\u6c2a\0\u6cb8\0\u6d46"+ - "\0\u6dd4\0\u6e62\0\u6ef0\0\u6f7e\0\u700c\0\u709a\0\u7128\0\u71b6"+ - "\0\u7244\0\u72d2\0\u7360\0\u73ee\0\u747c"; + "\0\u6dd4\0\u6e62\0\u6ef0\0\u6f7e\0\u700c"; private static int [] zzUnpackRowMap() { - int [] result = new int[221]; + int [] result = new int[213]; int offset = 0; offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); return result; @@ -405,32 +404,32 @@ public final class StandardTokenizerImpl implements StandardTokenizerInterface { "\1\0\1\31\2\0\1\76\1\0\1\37\1\30\6\0"+ "\1\100\21\0\1\101\2\0\1\102\10\0\1\103\22\0"+ "\1\104\21\0\1\105\2\0\1\106\41\0\1\107\20\0"+ - "\1\32\1\0\1\110\3\0\1\111\1\0\1\32\7\0"+ - "\1\42\1\0\1\43\2\0\1\112\1\0\1\66\4\0"+ + "\1\32\1\0\1\32\3\0\1\110\1\0\1\32\7\0"+ + "\1\42\1\0\1\43\2\0\1\111\1\0\1\66\4\0"+ "\1\46\1\0\1\47\1\0\1\50\2\0\1\51\3\0"+ - "\1\113\2\0\1\114\4\0\1\71\3\0\1\115\17\0"+ - "\1\56\2\0\1\116\21\0\1\117\2\0\1\120\41\0"+ - "\1\121\17\0\1\30\1\122\1\31\1\123\3\0\1\122"+ - "\1\0\1\122\4\0\1\37\1\30\206\0\2\34\14\0"+ - "\1\124\21\0\1\125\2\0\1\126\10\0\1\127\22\0"+ - "\1\130\21\0\1\131\2\0\1\132\62\0\1\35\7\0"+ - "\1\35\14\0\1\133\21\0\1\134\2\0\1\135\10\0"+ - "\1\136\22\0\1\137\21\0\1\140\2\0\1\141\62\0"+ + "\1\112\2\0\1\113\4\0\1\71\3\0\1\114\17\0"+ + "\1\56\2\0\1\115\21\0\1\116\2\0\1\117\41\0"+ + "\1\120\17\0\1\30\1\121\1\31\1\122\3\0\1\121"+ + "\1\0\1\121\4\0\1\37\1\30\206\0\2\34\14\0"+ + "\1\123\21\0\1\124\2\0\1\125\10\0\1\126\22\0"+ + "\1\127\21\0\1\130\2\0\1\131\62\0\1\35\7\0"+ + "\1\35\14\0\1\132\21\0\1\133\2\0\1\134\10\0"+ + "\1\135\22\0\1\136\21\0\1\137\2\0\1\140\62\0"+ "\1\36\7\0\1\36\7\0\1\42\1\0\1\43\2\0"+ - "\1\142\1\0\1\45\4\0\1\46\1\0\1\47\1\0"+ - "\1\50\2\0\1\51\3\0\1\143\2\0\1\144\4\0"+ - "\1\54\3\0\1\145\17\0\1\56\2\0\1\146\21\0"+ - "\1\147\2\0\1\150\61\0\1\30\1\37\1\62\1\0"+ + "\1\141\1\0\1\45\4\0\1\46\1\0\1\47\1\0"+ + "\1\50\2\0\1\51\3\0\1\142\2\0\1\143\4\0"+ + "\1\54\3\0\1\144\17\0\1\56\2\0\1\145\21\0"+ + "\1\146\2\0\1\147\61\0\1\30\1\37\1\62\1\0"+ "\1\63\1\0\1\63\1\64\1\0\1\37\2\0\1\30"+ - "\1\151\1\37\1\30\1\0\1\42\1\0\1\43\2\0"+ - "\1\152\1\0\1\45\4\0\1\46\1\0\1\47\1\0"+ - "\1\50\2\0\1\51\3\0\1\153\2\0\1\154\4\0"+ - "\1\54\3\0\1\155\17\0\1\56\2\0\1\156\21\0"+ - "\1\157\2\0\1\160\61\0\1\30\1\40\1\62\1\0"+ + "\1\150\1\37\1\30\1\0\1\42\1\0\1\43\2\0"+ + "\1\151\1\0\1\45\4\0\1\46\1\0\1\47\1\0"+ + "\1\50\2\0\1\51\3\0\1\152\2\0\1\153\4\0"+ + "\1\54\3\0\1\154\17\0\1\56\2\0\1\155\21\0"+ + "\1\156\2\0\1\157\61\0\1\30\1\40\1\62\1\0"+ "\1\63\1\0\1\63\1\64\1\0\1\40\2\0\1\63"+ - "\1\0\1\37\1\40\6\0\1\161\21\0\1\162\2\0"+ - "\1\163\10\0\1\164\22\0\1\165\21\0\1\166\2\0"+ - "\1\167\55\0\1\170\4\0\1\41\7\0\1\41\15\0"+ + "\1\0\1\37\1\40\6\0\1\160\21\0\1\161\2\0"+ + "\1\162\10\0\1\163\22\0\1\164\21\0\1\165\2\0"+ + "\1\166\55\0\1\167\4\0\1\41\7\0\1\41\15\0"+ "\1\30\4\0\1\30\11\0\1\30\22\0\1\30\3\0"+ "\1\30\13\0\1\30\2\0\1\30\10\0\1\30\22\0"+ "\4\30\35\0\1\30\31\0\1\30\3\0\4\30\1\0"+ @@ -466,22 +465,22 @@ public final class StandardTokenizerImpl implements StandardTokenizerInterface { "\1\30\2\0\2\30\1\0\3\30\1\0\2\30\1\0"+ "\1\30\10\0\1\30\1\0\2\30\2\0\2\30\1\0"+ "\4\30\23\0\1\30\21\0\1\42\1\0\1\43\2\0"+ - "\1\171\1\0\1\45\4\0\1\46\1\0\1\47\1\0"+ - "\1\50\2\0\1\51\3\0\1\172\2\0\1\173\4\0"+ - "\1\54\3\0\1\174\17\0\1\56\2\0\1\175\21\0"+ - "\1\176\2\0\1\177\61\0\1\30\2\62\2\0\2\200"+ - "\1\201\1\0\1\62\2\0\1\200\1\0\1\37\1\30"+ - "\1\0\1\42\1\0\1\43\2\0\1\202\1\0\1\203"+ + "\1\170\1\0\1\45\4\0\1\46\1\0\1\47\1\0"+ + "\1\50\2\0\1\51\3\0\1\171\2\0\1\172\4\0"+ + "\1\54\3\0\1\173\17\0\1\56\2\0\1\174\21\0"+ + "\1\175\2\0\1\176\61\0\1\30\2\62\2\0\2\177"+ + "\1\200\1\0\1\62\2\0\1\177\1\0\1\37\1\30"+ + "\1\0\1\42\1\0\1\43\2\0\1\201\1\0\1\202"+ "\4\0\1\46\1\0\1\47\1\0\1\50\2\0\1\51"+ - "\3\0\1\204\2\0\1\205\4\0\1\206\3\0\1\207"+ - "\17\0\1\56\2\0\1\210\21\0\1\211\2\0\1\212"+ + "\3\0\1\203\2\0\1\204\4\0\1\205\3\0\1\206"+ + "\17\0\1\56\2\0\1\207\21\0\1\210\2\0\1\211"+ "\61\0\1\30\1\63\2\0\1\63\1\0\2\63\1\0"+ "\1\63\2\0\1\63\1\0\2\30\1\0\1\42\1\0"+ - "\1\43\2\0\1\213\1\0\1\45\4\0\1\46\1\0"+ - "\1\47\1\0\1\50\2\0\1\51\3\0\1\214\2\0"+ - "\1\215\4\0\1\54\3\0\1\216\17\0\1\56\2\0"+ - "\1\217\21\0\1\220\2\0\1\221\41\0\1\121\17\0"+ - "\1\30\1\64\1\62\1\123\1\63\1\0\1\63\1\64"+ + "\1\43\2\0\1\212\1\0\1\45\4\0\1\46\1\0"+ + "\1\47\1\0\1\50\2\0\1\51\3\0\1\213\2\0"+ + "\1\214\4\0\1\54\3\0\1\215\17\0\1\56\2\0"+ + "\1\216\21\0\1\217\2\0\1\220\41\0\1\120\17\0"+ + "\1\30\1\64\1\62\1\122\1\63\1\0\1\63\1\64"+ "\1\0\1\64\2\0\1\63\1\0\1\37\1\30\7\0"+ "\1\30\4\0\1\30\11\0\1\30\22\0\1\30\3\0"+ "\1\30\13\0\1\31\2\0\1\31\10\0\1\30\22\0"+ @@ -506,16 +505,16 @@ public final class StandardTokenizerImpl implements StandardTokenizerInterface { "\1\0\1\31\11\0\1\31\11\0\2\31\6\0\1\31"+ "\2\0\4\31\3\0\1\31\2\0\2\31\1\0\3\31"+ "\1\0\2\31\1\0\1\31\10\0\1\31\1\0\2\31"+ - "\2\0\2\31\1\0\4\31\23\0\1\31\26\0\1\222"+ - "\1\0\1\223\17\0\1\224\2\0\1\225\4\0\1\226"+ - "\3\0\1\227\22\0\1\230\21\0\1\231\2\0\1\232"+ - "\62\0\1\76\1\31\2\0\3\200\1\0\1\76\2\0"+ - "\1\200\4\0\1\42\1\0\1\43\2\0\1\233\1\0"+ + "\2\0\2\31\1\0\4\31\23\0\1\31\26\0\1\221"+ + "\1\0\1\222\17\0\1\223\2\0\1\224\4\0\1\225"+ + "\3\0\1\226\22\0\1\227\21\0\1\230\2\0\1\231"+ + "\62\0\1\76\1\31\2\0\3\177\1\0\1\76\2\0"+ + "\1\177\4\0\1\42\1\0\1\43\2\0\1\232\1\0"+ "\1\66\4\0\1\46\1\0\1\47\1\0\1\50\2\0"+ - "\1\51\3\0\1\234\2\0\1\235\4\0\1\71\3\0"+ - "\1\236\17\0\1\56\2\0\1\237\21\0\1\240\2\0"+ - "\1\241\41\0\1\121\17\0\1\30\1\77\1\31\1\123"+ - "\1\0\2\200\1\77\1\0\1\77\2\0\1\200\1\0"+ + "\1\51\3\0\1\233\2\0\1\234\4\0\1\71\3\0"+ + "\1\235\17\0\1\56\2\0\1\236\21\0\1\237\2\0"+ + "\1\240\41\0\1\120\17\0\1\30\1\77\1\31\1\122"+ + "\1\0\2\177\1\77\1\0\1\77\2\0\1\177\1\0"+ "\1\37\1\30\71\0\1\32\2\0\1\32\33\0\4\32"+ "\216\0\1\32\77\0\1\32\44\0\1\32\1\0\2\32"+ "\21\0\1\32\4\0\1\32\17\0\4\32\3\0\1\32"+ @@ -525,372 +524,361 @@ public final class StandardTokenizerImpl implements StandardTokenizerInterface { "\6\0\1\32\2\0\4\32\3\0\1\32\2\0\2\32"+ "\1\0\3\32\1\0\2\32\1\0\1\32\10\0\1\32"+ "\1\0\2\32\2\0\2\32\1\0\4\32\23\0\1\32"+ - "\177\0\1\110\44\0\1\242\21\0\1\243\2\0\1\244"+ - "\10\0\1\245\22\0\1\246\21\0\1\247\2\0\1\250"+ - "\41\0\1\107\20\0\1\110\1\0\1\110\5\0\1\110"+ - "\7\0\1\42\1\0\1\43\2\0\1\251\1\0\1\45"+ - "\4\0\1\46\1\0\1\47\1\0\1\50\2\0\1\51"+ - "\3\0\1\252\2\0\1\253\4\0\1\54\3\0\1\254"+ - "\17\0\1\56\2\0\1\255\21\0\1\256\2\0\1\257"+ - "\41\0\1\121\17\0\1\30\1\111\1\62\1\123\3\0"+ - "\1\111\1\0\1\111\4\0\1\37\1\30\7\0\1\30"+ - "\4\0\1\30\11\0\1\30\22\0\1\30\3\0\1\30"+ - "\13\0\1\122\2\0\1\122\10\0\1\30\22\0\4\122"+ - "\35\0\1\30\26\0\1\30\26\0\2\30\23\0\1\31"+ - "\1\30\40\0\1\31\13\0\1\122\65\0\1\31\11\0"+ - "\1\122\15\0\4\30\2\0\2\30\14\0\3\30\1\122"+ - "\1\0\2\122\11\0\3\30\3\0\1\30\1\0\1\122"+ - "\4\0\1\122\2\30\1\0\4\31\1\0\2\30\5\0"+ - "\4\122\2\0\1\30\1\122\12\0\1\122\7\0\1\30"+ - "\30\0\1\30\4\0\1\30\6\0\1\30\3\0\1\30"+ - "\6\0\1\30\5\0\1\30\2\0\2\30\1\0\17\30"+ - "\2\0\1\30\13\0\7\30\2\0\1\30\1\0\1\30"+ - "\1\0\2\30\2\0\1\30\1\0\3\30\2\0\1\30"+ - "\1\0\1\30\1\0\1\30\1\0\1\30\4\0\1\122"+ - "\1\0\2\30\6\0\1\30\7\0\1\30\1\0\1\30"+ - "\33\0\1\30\6\0\1\30\3\0\1\30\3\0\1\30"+ - "\7\0\1\30\31\0\20\30\5\0\3\30\4\0\1\30"+ - "\6\0\1\30\3\0\2\30\2\0\2\30\4\0\1\30"+ - "\4\122\1\0\1\30\2\0\1\30\4\0\1\30\1\0"+ - "\1\30\1\0\1\30\134\0\2\122\25\0\4\122\55\0"+ - "\1\122\15\0\2\122\10\0\2\122\1\0\1\122\1\0"+ - "\1\122\11\0\1\122\11\0\2\122\6\0\1\122\2\0"+ - "\4\122\3\0\1\122\2\0\2\122\1\0\3\122\1\0"+ - "\2\122\1\0\1\122\10\0\1\122\1\0\2\122\2\0"+ - "\2\122\1\0\4\122\23\0\1\122\177\0\1\123\44\0"+ - "\1\260\21\0\1\261\2\0\1\262\10\0\1\263\22\0"+ - "\1\264\21\0\1\265\2\0\1\266\62\0\1\123\5\0"+ - "\1\111\1\0\1\123\77\0\1\35\2\0\1\35\33\0"+ - "\4\35\216\0\1\35\77\0\1\35\44\0\1\35\1\0"+ - "\2\35\21\0\1\35\4\0\1\35\17\0\4\35\3\0"+ - "\1\35\12\0\1\35\203\0\1\35\222\0\4\35\152\0"+ - "\2\35\25\0\4\35\55\0\1\35\15\0\2\35\10\0"+ - "\2\35\1\0\1\35\1\0\1\35\11\0\1\35\11\0"+ - "\2\35\6\0\1\35\2\0\4\35\3\0\1\35\2\0"+ - "\2\35\1\0\3\35\1\0\2\35\1\0\1\35\10\0"+ - "\1\35\1\0\2\35\2\0\2\35\1\0\4\35\23\0"+ - "\1\35\111\0\1\36\2\0\1\36\33\0\4\36\216\0"+ - "\1\36\77\0\1\36\44\0\1\36\1\0\2\36\21\0"+ - "\1\36\4\0\1\36\17\0\4\36\3\0\1\36\12\0"+ - "\1\36\203\0\1\36\222\0\4\36\152\0\2\36\25\0"+ - "\4\36\55\0\1\36\15\0\2\36\10\0\2\36\1\0"+ - "\1\36\1\0\1\36\11\0\1\36\11\0\2\36\6\0"+ - "\1\36\2\0\4\36\3\0\1\36\2\0\2\36\1\0"+ - "\3\36\1\0\2\36\1\0\1\36\10\0\1\36\1\0"+ - "\2\36\2\0\2\36\1\0\4\36\23\0\1\36\27\0"+ - "\1\30\4\0\1\30\11\0\1\30\22\0\1\30\3\0"+ - "\1\30\13\0\1\37\2\0\1\37\10\0\1\30\22\0"+ - "\4\37\35\0\1\30\26\0\1\30\26\0\2\30\23\0"+ - "\1\62\1\30\40\0\1\62\13\0\1\37\65\0\1\62"+ - "\11\0\1\37\15\0\4\30\2\0\2\30\14\0\3\30"+ - "\1\37\1\0\2\37\11\0\3\30\3\0\1\30\1\0"+ - "\1\37\4\0\1\37\2\30\1\0\4\62\1\0\2\30"+ - "\5\0\4\37\2\0\1\30\1\37\12\0\1\37\7\0"+ - "\1\30\30\0\1\30\4\0\1\30\6\0\1\30\3\0"+ - "\1\30\6\0\1\30\5\0\1\30\2\0\2\30\1\0"+ - "\17\30\2\0\1\30\13\0\7\30\2\0\1\30\1\0"+ - "\1\30\1\0\2\30\2\0\1\30\1\0\3\30\2\0"+ - "\1\30\1\0\1\30\1\0\1\30\1\0\1\30\4\0"+ - "\1\37\1\0\2\30\6\0\1\30\7\0\1\30\1\0"+ - "\1\30\33\0\1\30\6\0\1\30\3\0\1\30\3\0"+ - "\1\30\7\0\1\30\31\0\20\30\5\0\3\30\4\0"+ - "\1\30\6\0\1\30\3\0\2\30\2\0\2\30\4\0"+ - "\1\30\4\37\1\0\1\30\2\0\1\30\4\0\1\30"+ - "\1\0\1\30\1\0\1\30\134\0\2\37\25\0\4\37"+ - "\55\0\1\37\15\0\2\37\10\0\2\37\1\0\1\37"+ - "\1\0\1\37\11\0\1\37\11\0\2\37\6\0\1\37"+ - "\2\0\4\37\3\0\1\37\2\0\2\37\1\0\3\37"+ - "\1\0\2\37\1\0\1\37\10\0\1\37\1\0\2\37"+ - "\2\0\2\37\1\0\4\37\23\0\1\37\26\0\1\267"+ - "\21\0\1\270\2\0\1\271\10\0\1\272\22\0\1\273"+ - "\21\0\1\274\2\0\1\275\62\0\1\151\7\0\1\151"+ - "\4\0\1\276\10\0\1\30\4\0\1\30\11\0\1\30"+ - "\22\0\1\30\3\0\1\30\13\0\1\40\2\0\1\40"+ - "\10\0\1\30\22\0\4\40\35\0\1\30\26\0\1\30"+ - "\26\0\2\30\23\0\1\62\1\30\40\0\1\62\13\0"+ - "\1\40\65\0\1\62\11\0\1\40\15\0\4\30\2\0"+ - "\2\30\14\0\3\30\1\40\1\0\2\40\11\0\3\30"+ - "\3\0\1\30\1\0\1\40\4\0\1\40\2\30\1\0"+ - "\4\62\1\0\2\30\5\0\4\40\2\0\1\30\1\40"+ - "\12\0\1\40\7\0\1\30\30\0\1\30\4\0\1\30"+ - "\6\0\1\30\3\0\1\30\6\0\1\30\5\0\1\30"+ - "\2\0\2\30\1\0\17\30\2\0\1\30\13\0\7\30"+ - "\2\0\1\30\1\0\1\30\1\0\2\30\2\0\1\30"+ - "\1\0\3\30\2\0\1\30\1\0\1\30\1\0\1\30"+ - "\1\0\1\30\4\0\1\40\1\0\2\30\6\0\1\30"+ - "\7\0\1\30\1\0\1\30\33\0\1\30\6\0\1\30"+ - "\3\0\1\30\3\0\1\30\7\0\1\30\31\0\20\30"+ - "\5\0\3\30\4\0\1\30\6\0\1\30\3\0\2\30"+ - "\2\0\2\30\4\0\1\30\4\40\1\0\1\30\2\0"+ - "\1\30\4\0\1\30\1\0\1\30\1\0\1\30\134\0"+ - "\2\40\25\0\4\40\55\0\1\40\15\0\2\40\10\0"+ - "\2\40\1\0\1\40\1\0\1\40\11\0\1\40\11\0"+ - "\2\40\6\0\1\40\2\0\4\40\3\0\1\40\2\0"+ - "\2\40\1\0\3\40\1\0\2\40\1\0\1\40\10\0"+ - "\1\40\1\0\2\40\2\0\2\40\1\0\4\40\23\0"+ - "\1\40\111\0\1\41\2\0\1\41\33\0\4\41\216\0"+ - "\1\41\77\0\1\41\44\0\1\41\1\0\2\41\21\0"+ - "\1\41\4\0\1\41\17\0\4\41\3\0\1\41\12\0"+ - "\1\41\203\0\1\41\222\0\4\41\152\0\2\41\25\0"+ - "\4\41\55\0\1\41\15\0\2\41\10\0\2\41\1\0"+ - "\1\41\1\0\1\41\11\0\1\41\11\0\2\41\6\0"+ - "\1\41\2\0\4\41\3\0\1\41\2\0\2\41\1\0"+ - "\3\41\1\0\2\41\1\0\1\41\10\0\1\41\1\0"+ - "\2\41\2\0\2\41\1\0\4\41\23\0\1\41\165\0"+ - "\1\277\26\0\2\277\27\0\1\30\4\0\1\30\11\0"+ - "\1\30\22\0\1\30\3\0\1\30\13\0\1\62\2\0"+ - "\1\62\10\0\1\30\22\0\4\62\35\0\1\30\26\0"+ - "\1\30\26\0\2\30\23\0\1\62\1\30\40\0\1\62"+ - "\13\0\1\62\65\0\1\62\11\0\1\62\15\0\4\30"+ - "\2\0\2\30\14\0\3\30\1\62\1\0\2\62\11\0"+ - "\3\30\3\0\1\30\1\0\1\62\4\0\1\62\2\30"+ - "\1\0\4\62\1\0\2\30\5\0\4\62\2\0\1\30"+ - "\1\62\12\0\1\62\7\0\1\30\30\0\1\30\4\0"+ - "\1\30\6\0\1\30\3\0\1\30\6\0\1\30\5\0"+ - "\1\30\2\0\2\30\1\0\17\30\2\0\1\30\13\0"+ - "\7\30\2\0\1\30\1\0\1\30\1\0\2\30\2\0"+ - "\1\30\1\0\3\30\2\0\1\30\1\0\1\30\1\0"+ - "\1\30\1\0\1\30\4\0\1\62\1\0\2\30\6\0"+ - "\1\30\7\0\1\30\1\0\1\30\33\0\1\30\6\0"+ - "\1\30\3\0\1\30\3\0\1\30\7\0\1\30\31\0"+ - "\20\30\5\0\3\30\4\0\1\30\6\0\1\30\3\0"+ - "\2\30\2\0\2\30\4\0\1\30\4\62\1\0\1\30"+ - "\2\0\1\30\4\0\1\30\1\0\1\30\1\0\1\30"+ - "\134\0\2\62\25\0\4\62\55\0\1\62\15\0\2\62"+ - "\10\0\2\62\1\0\1\62\1\0\1\62\11\0\1\62"+ - "\11\0\2\62\6\0\1\62\2\0\4\62\3\0\1\62"+ - "\2\0\2\62\1\0\3\62\1\0\2\62\1\0\1\62"+ - "\10\0\1\62\1\0\2\62\2\0\2\62\1\0\4\62"+ - "\23\0\1\62\26\0\1\300\1\0\1\301\17\0\1\302"+ - "\2\0\1\303\4\0\1\304\3\0\1\305\22\0\1\306"+ - "\21\0\1\307\2\0\1\310\62\0\1\200\1\62\2\0"+ - "\3\200\1\0\1\200\2\0\1\200\4\0\1\42\1\0"+ - "\1\43\2\0\1\311\1\0\1\45\4\0\1\46\1\0"+ - "\1\47\1\0\1\50\2\0\1\51\3\0\1\312\2\0"+ - "\1\313\4\0\1\54\3\0\1\314\17\0\1\56\2\0"+ - "\1\315\21\0\1\316\2\0\1\317\41\0\1\121\17\0"+ - "\1\30\1\201\1\62\1\123\1\0\2\200\1\201\1\0"+ - "\1\201\2\0\1\200\1\0\1\37\1\30\7\0\1\30"+ - "\4\0\1\30\11\0\1\30\22\0\1\30\3\0\1\30"+ - "\13\0\1\63\2\0\1\63\10\0\1\30\22\0\4\63"+ - "\35\0\1\30\31\0\1\30\3\0\4\30\1\0\1\30"+ - "\4\0\1\30\1\0\2\30\2\0\2\30\2\0\3\30"+ - "\1\0\1\30\1\0\1\30\2\0\4\30\1\0\3\30"+ - "\1\0\1\30\1\0\3\30\1\0\2\30\1\0\4\30"+ - "\1\0\2\30\2\0\10\30\1\0\2\30\1\0\10\30"+ - "\2\0\7\30\1\0\10\30\1\0\6\30\1\0\1\30"+ - "\1\0\2\30\2\0\1\30\1\0\1\30\3\0\3\30"+ - "\22\0\1\30\26\0\2\30\24\0\1\30\54\0\1\63"+ - "\77\0\1\63\15\0\4\30\2\0\2\30\14\0\3\30"+ - "\1\63\1\0\2\63\11\0\3\30\3\0\1\30\1\0"+ - "\1\63\4\0\1\63\2\30\6\0\2\30\5\0\4\63"+ - "\2\0\1\30\1\63\12\0\1\63\7\0\1\30\44\0"+ - "\1\30\3\0\2\30\12\0\2\30\1\0\3\30\7\0"+ - "\1\30\6\0\2\30\1\0\2\30\6\0\1\30\4\0"+ - "\2\30\2\0\2\30\5\0\3\30\2\0\1\30\15\0"+ - "\1\30\16\0\1\30\7\0\1\30\30\0\1\30\4\0"+ - "\1\30\6\0\1\30\3\0\1\30\6\0\1\30\5\0"+ - "\1\30\2\0\2\30\1\0\17\30\2\0\1\30\13\0"+ - "\7\30\2\0\1\30\1\0\1\30\1\0\2\30\2\0"+ - "\1\30\1\0\3\30\2\0\1\30\1\0\1\30\1\0"+ - "\1\30\1\0\1\30\4\0\1\63\1\0\2\30\6\0"+ - "\1\30\7\0\1\30\1\0\1\30\33\0\1\30\6\0"+ - "\1\30\3\0\1\30\3\0\1\30\7\0\1\30\31\0"+ - "\20\30\5\0\3\30\4\0\1\30\6\0\1\30\3\0"+ - "\2\30\2\0\2\30\4\0\1\30\4\63\1\0\1\30"+ - "\2\0\1\30\4\0\1\30\1\0\1\30\1\0\1\30"+ - "\134\0\2\63\25\0\4\63\55\0\1\63\15\0\2\63"+ - "\10\0\2\63\1\0\1\63\1\0\1\63\11\0\1\63"+ - "\11\0\2\63\6\0\1\63\2\0\4\63\3\0\1\63"+ - "\2\0\2\63\1\0\3\63\1\0\2\63\1\0\1\63"+ - "\10\0\1\63\1\0\2\63\2\0\2\63\1\0\4\63"+ - "\23\0\1\63\27\0\1\30\4\0\1\30\11\0\1\30"+ - "\22\0\1\30\3\0\1\30\13\0\1\64\2\0\1\64"+ - "\10\0\1\30\22\0\4\64\35\0\1\30\26\0\1\30"+ - "\26\0\2\30\23\0\1\62\1\30\40\0\1\62\13\0"+ - "\1\64\65\0\1\62\11\0\1\64\15\0\4\30\2\0"+ - "\2\30\14\0\3\30\1\64\1\0\2\64\11\0\3\30"+ - "\3\0\1\30\1\0\1\64\4\0\1\64\2\30\1\0"+ - "\4\62\1\0\2\30\5\0\4\64\2\0\1\30\1\64"+ - "\12\0\1\64\7\0\1\30\30\0\1\30\4\0\1\30"+ - "\6\0\1\30\3\0\1\30\6\0\1\30\5\0\1\30"+ - "\2\0\2\30\1\0\17\30\2\0\1\30\13\0\7\30"+ - "\2\0\1\30\1\0\1\30\1\0\2\30\2\0\1\30"+ - "\1\0\3\30\2\0\1\30\1\0\1\30\1\0\1\30"+ - "\1\0\1\30\4\0\1\64\1\0\2\30\6\0\1\30"+ - "\7\0\1\30\1\0\1\30\33\0\1\30\6\0\1\30"+ - "\3\0\1\30\3\0\1\30\7\0\1\30\31\0\20\30"+ - "\5\0\3\30\4\0\1\30\6\0\1\30\3\0\2\30"+ - "\2\0\2\30\4\0\1\30\4\64\1\0\1\30\2\0"+ - "\1\30\4\0\1\30\1\0\1\30\1\0\1\30\134\0"+ - "\2\64\25\0\4\64\55\0\1\64\15\0\2\64\10\0"+ - "\2\64\1\0\1\64\1\0\1\64\11\0\1\64\11\0"+ - "\2\64\6\0\1\64\2\0\4\64\3\0\1\64\2\0"+ - "\2\64\1\0\3\64\1\0\2\64\1\0\1\64\10\0"+ - "\1\64\1\0\2\64\2\0\2\64\1\0\4\64\23\0"+ - "\1\64\111\0\1\76\2\0\1\76\33\0\4\76\102\0"+ - "\1\31\104\0\1\31\146\0\1\31\41\0\1\31\13\0"+ - "\1\76\65\0\1\31\11\0\1\76\44\0\1\76\1\0"+ - "\2\76\21\0\1\76\4\0\1\76\3\0\4\31\10\0"+ - "\4\76\3\0\1\76\12\0\1\76\164\0\2\31\233\0"+ - "\1\76\222\0\4\76\152\0\2\76\25\0\4\76\55\0"+ - "\1\76\15\0\2\76\10\0\2\76\1\0\1\76\1\0"+ - "\1\76\11\0\1\76\11\0\2\76\6\0\1\76\2\0"+ - "\4\76\3\0\1\76\2\0\2\76\1\0\3\76\1\0"+ - "\2\76\1\0\1\76\10\0\1\76\1\0\2\76\2\0"+ - "\2\76\1\0\4\76\23\0\1\76\27\0\1\30\4\0"+ - "\1\30\11\0\1\30\22\0\1\30\3\0\1\30\13\0"+ - "\1\77\2\0\1\77\10\0\1\30\22\0\4\77\35\0"+ - "\1\30\26\0\1\30\26\0\2\30\23\0\1\31\1\30"+ - "\40\0\1\31\13\0\1\77\65\0\1\31\11\0\1\77"+ - "\15\0\4\30\2\0\2\30\14\0\3\30\1\77\1\0"+ - "\2\77\11\0\3\30\3\0\1\30\1\0\1\77\4\0"+ - "\1\77\2\30\1\0\4\31\1\0\2\30\5\0\4\77"+ - "\2\0\1\30\1\77\12\0\1\77\7\0\1\30\30\0"+ - "\1\30\4\0\1\30\6\0\1\30\3\0\1\30\6\0"+ - "\1\30\5\0\1\30\2\0\2\30\1\0\17\30\2\0"+ - "\1\30\13\0\7\30\2\0\1\30\1\0\1\30\1\0"+ - "\2\30\2\0\1\30\1\0\3\30\2\0\1\30\1\0"+ - "\1\30\1\0\1\30\1\0\1\30\4\0\1\77\1\0"+ - "\2\30\6\0\1\30\7\0\1\30\1\0\1\30\33\0"+ - "\1\30\6\0\1\30\3\0\1\30\3\0\1\30\7\0"+ - "\1\30\31\0\20\30\5\0\3\30\4\0\1\30\6\0"+ - "\1\30\3\0\2\30\2\0\2\30\4\0\1\30\4\77"+ - "\1\0\1\30\2\0\1\30\4\0\1\30\1\0\1\30"+ - "\1\0\1\30\134\0\2\77\25\0\4\77\55\0\1\77"+ - "\15\0\2\77\10\0\2\77\1\0\1\77\1\0\1\77"+ - "\11\0\1\77\11\0\2\77\6\0\1\77\2\0\4\77"+ - "\3\0\1\77\2\0\2\77\1\0\3\77\1\0\2\77"+ - "\1\0\1\77\10\0\1\77\1\0\2\77\2\0\2\77"+ - "\1\0\4\77\23\0\1\77\111\0\1\110\2\0\1\110"+ - "\33\0\4\110\216\0\1\110\77\0\1\110\44\0\1\110"+ - "\1\0\2\110\21\0\1\110\4\0\1\110\17\0\4\110"+ - "\3\0\1\110\12\0\1\110\203\0\1\110\222\0\4\110"+ - "\152\0\2\110\25\0\4\110\55\0\1\110\15\0\2\110"+ - "\10\0\2\110\1\0\1\110\1\0\1\110\11\0\1\110"+ - "\11\0\2\110\6\0\1\110\2\0\4\110\3\0\1\110"+ - "\2\0\2\110\1\0\3\110\1\0\2\110\1\0\1\110"+ - "\10\0\1\110\1\0\2\110\2\0\2\110\1\0\4\110"+ - "\23\0\1\110\27\0\1\30\4\0\1\30\11\0\1\30"+ - "\22\0\1\30\3\0\1\30\13\0\1\111\2\0\1\111"+ - "\10\0\1\30\22\0\4\111\35\0\1\30\26\0\1\30"+ - "\26\0\2\30\23\0\1\62\1\30\40\0\1\62\13\0"+ - "\1\111\65\0\1\62\11\0\1\111\15\0\4\30\2\0"+ - "\2\30\14\0\3\30\1\111\1\0\2\111\11\0\3\30"+ - "\3\0\1\30\1\0\1\111\4\0\1\111\2\30\1\0"+ - "\4\62\1\0\2\30\5\0\4\111\2\0\1\30\1\111"+ - "\12\0\1\111\7\0\1\30\30\0\1\30\4\0\1\30"+ - "\6\0\1\30\3\0\1\30\6\0\1\30\5\0\1\30"+ - "\2\0\2\30\1\0\17\30\2\0\1\30\13\0\7\30"+ - "\2\0\1\30\1\0\1\30\1\0\2\30\2\0\1\30"+ - "\1\0\3\30\2\0\1\30\1\0\1\30\1\0\1\30"+ - "\1\0\1\30\4\0\1\111\1\0\2\30\6\0\1\30"+ - "\7\0\1\30\1\0\1\30\33\0\1\30\6\0\1\30"+ - "\3\0\1\30\3\0\1\30\7\0\1\30\31\0\20\30"+ - "\5\0\3\30\4\0\1\30\6\0\1\30\3\0\2\30"+ - "\2\0\2\30\4\0\1\30\4\111\1\0\1\30\2\0"+ - "\1\30\4\0\1\30\1\0\1\30\1\0\1\30\134\0"+ - "\2\111\25\0\4\111\55\0\1\111\15\0\2\111\10\0"+ - "\2\111\1\0\1\111\1\0\1\111\11\0\1\111\11\0"+ - "\2\111\6\0\1\111\2\0\4\111\3\0\1\111\2\0"+ - "\2\111\1\0\3\111\1\0\2\111\1\0\1\111\10\0"+ - "\1\111\1\0\2\111\2\0\2\111\1\0\4\111\23\0"+ - "\1\111\111\0\1\123\2\0\1\123\33\0\4\123\216\0"+ - "\1\123\77\0\1\123\44\0\1\123\1\0\2\123\21\0"+ - "\1\123\4\0\1\123\17\0\4\123\3\0\1\123\12\0"+ - "\1\123\203\0\1\123\222\0\4\123\152\0\2\123\25\0"+ - "\4\123\55\0\1\123\15\0\2\123\10\0\2\123\1\0"+ - "\1\123\1\0\1\123\11\0\1\123\11\0\2\123\6\0"+ - "\1\123\2\0\4\123\3\0\1\123\2\0\2\123\1\0"+ - "\3\123\1\0\2\123\1\0\1\123\10\0\1\123\1\0"+ - "\2\123\2\0\2\123\1\0\4\123\23\0\1\123\111\0"+ - "\1\151\2\0\1\151\33\0\4\151\216\0\1\151\77\0"+ - "\1\151\44\0\1\151\1\0\2\151\21\0\1\151\4\0"+ - "\1\151\17\0\4\151\3\0\1\151\12\0\1\151\203\0"+ - "\1\151\222\0\4\151\152\0\2\151\25\0\4\151\55\0"+ - "\1\151\15\0\2\151\10\0\2\151\1\0\1\151\1\0"+ - "\1\151\11\0\1\151\11\0\2\151\6\0\1\151\2\0"+ - "\4\151\3\0\1\151\2\0\2\151\1\0\3\151\1\0"+ - "\2\151\1\0\1\151\10\0\1\151\1\0\2\151\2\0"+ - "\2\151\1\0\4\151\23\0\1\151\21\0\1\42\1\0"+ - "\1\43\2\0\1\320\1\0\1\45\4\0\1\46\1\0"+ - "\1\47\1\0\1\50\2\0\1\51\3\0\1\321\2\0"+ - "\1\322\4\0\1\54\3\0\1\323\17\0\1\56\2\0"+ - "\1\324\21\0\1\325\2\0\1\326\61\0\1\30\1\276"+ - "\1\62\4\0\1\111\1\0\1\276\4\0\1\37\1\30"+ - "\6\0\1\327\21\0\1\330\2\0\1\331\10\0\1\332"+ - "\22\0\1\333\21\0\1\334\2\0\1\335\55\0\1\170"+ - "\4\0\1\277\7\0\1\277\77\0\1\200\2\0\1\200"+ - "\33\0\4\200\102\0\1\62\104\0\1\62\146\0\1\62"+ - "\41\0\1\62\13\0\1\200\65\0\1\62\11\0\1\200"+ - "\44\0\1\200\1\0\2\200\21\0\1\200\4\0\1\200"+ - "\3\0\4\62\10\0\4\200\3\0\1\200\12\0\1\200"+ - "\164\0\2\62\233\0\1\200\222\0\4\200\152\0\2\200"+ - "\25\0\4\200\55\0\1\200\15\0\2\200\10\0\2\200"+ - "\1\0\1\200\1\0\1\200\11\0\1\200\11\0\2\200"+ - "\6\0\1\200\2\0\4\200\3\0\1\200\2\0\2\200"+ - "\1\0\3\200\1\0\2\200\1\0\1\200\10\0\1\200"+ - "\1\0\2\200\2\0\2\200\1\0\4\200\23\0\1\200"+ - "\27\0\1\30\4\0\1\30\11\0\1\30\22\0\1\30"+ - "\3\0\1\30\13\0\1\201\2\0\1\201\10\0\1\30"+ - "\22\0\4\201\35\0\1\30\26\0\1\30\26\0\2\30"+ - "\23\0\1\62\1\30\40\0\1\62\13\0\1\201\65\0"+ - "\1\62\11\0\1\201\15\0\4\30\2\0\2\30\14\0"+ - "\3\30\1\201\1\0\2\201\11\0\3\30\3\0\1\30"+ - "\1\0\1\201\4\0\1\201\2\30\1\0\4\62\1\0"+ - "\2\30\5\0\4\201\2\0\1\30\1\201\12\0\1\201"+ + "\177\0\1\32\37\0\1\42\1\0\1\43\2\0\1\241"+ + "\1\0\1\45\4\0\1\46\1\0\1\47\1\0\1\50"+ + "\2\0\1\51\3\0\1\242\2\0\1\243\4\0\1\54"+ + "\3\0\1\244\17\0\1\56\2\0\1\245\21\0\1\246"+ + "\2\0\1\247\41\0\1\120\17\0\1\30\1\110\1\62"+ + "\1\122\3\0\1\110\1\0\1\110\4\0\1\37\1\30"+ + "\7\0\1\30\4\0\1\30\11\0\1\30\22\0\1\30"+ + "\3\0\1\30\13\0\1\121\2\0\1\121\10\0\1\30"+ + "\22\0\4\121\35\0\1\30\26\0\1\30\26\0\2\30"+ + "\23\0\1\31\1\30\40\0\1\31\13\0\1\121\65\0"+ + "\1\31\11\0\1\121\15\0\4\30\2\0\2\30\14\0"+ + "\3\30\1\121\1\0\2\121\11\0\3\30\3\0\1\30"+ + "\1\0\1\121\4\0\1\121\2\30\1\0\4\31\1\0"+ + "\2\30\5\0\4\121\2\0\1\30\1\121\12\0\1\121"+ "\7\0\1\30\30\0\1\30\4\0\1\30\6\0\1\30"+ "\3\0\1\30\6\0\1\30\5\0\1\30\2\0\2\30"+ "\1\0\17\30\2\0\1\30\13\0\7\30\2\0\1\30"+ "\1\0\1\30\1\0\2\30\2\0\1\30\1\0\3\30"+ "\2\0\1\30\1\0\1\30\1\0\1\30\1\0\1\30"+ - "\4\0\1\201\1\0\2\30\6\0\1\30\7\0\1\30"+ + "\4\0\1\121\1\0\2\30\6\0\1\30\7\0\1\30"+ "\1\0\1\30\33\0\1\30\6\0\1\30\3\0\1\30"+ "\3\0\1\30\7\0\1\30\31\0\20\30\5\0\3\30"+ "\4\0\1\30\6\0\1\30\3\0\2\30\2\0\2\30"+ - "\4\0\1\30\4\201\1\0\1\30\2\0\1\30\4\0"+ - "\1\30\1\0\1\30\1\0\1\30\134\0\2\201\25\0"+ - "\4\201\55\0\1\201\15\0\2\201\10\0\2\201\1\0"+ - "\1\201\1\0\1\201\11\0\1\201\11\0\2\201\6\0"+ - "\1\201\2\0\4\201\3\0\1\201\2\0\2\201\1\0"+ - "\3\201\1\0\2\201\1\0\1\201\10\0\1\201\1\0"+ - "\2\201\2\0\2\201\1\0\4\201\23\0\1\201\27\0"+ + "\4\0\1\30\4\121\1\0\1\30\2\0\1\30\4\0"+ + "\1\30\1\0\1\30\1\0\1\30\134\0\2\121\25\0"+ + "\4\121\55\0\1\121\15\0\2\121\10\0\2\121\1\0"+ + "\1\121\1\0\1\121\11\0\1\121\11\0\2\121\6\0"+ + "\1\121\2\0\4\121\3\0\1\121\2\0\2\121\1\0"+ + "\3\121\1\0\2\121\1\0\1\121\10\0\1\121\1\0"+ + "\2\121\2\0\2\121\1\0\4\121\23\0\1\121\177\0"+ + "\1\122\44\0\1\250\21\0\1\251\2\0\1\252\10\0"+ + "\1\253\22\0\1\254\21\0\1\255\2\0\1\256\41\0"+ + "\1\120\20\0\1\122\1\0\1\122\3\0\1\110\1\0"+ + "\1\122\77\0\1\35\2\0\1\35\33\0\4\35\216\0"+ + "\1\35\77\0\1\35\44\0\1\35\1\0\2\35\21\0"+ + "\1\35\4\0\1\35\17\0\4\35\3\0\1\35\12\0"+ + "\1\35\203\0\1\35\222\0\4\35\152\0\2\35\25\0"+ + "\4\35\55\0\1\35\15\0\2\35\10\0\2\35\1\0"+ + "\1\35\1\0\1\35\11\0\1\35\11\0\2\35\6\0"+ + "\1\35\2\0\4\35\3\0\1\35\2\0\2\35\1\0"+ + "\3\35\1\0\2\35\1\0\1\35\10\0\1\35\1\0"+ + "\2\35\2\0\2\35\1\0\4\35\23\0\1\35\111\0"+ + "\1\36\2\0\1\36\33\0\4\36\216\0\1\36\77\0"+ + "\1\36\44\0\1\36\1\0\2\36\21\0\1\36\4\0"+ + "\1\36\17\0\4\36\3\0\1\36\12\0\1\36\203\0"+ + "\1\36\222\0\4\36\152\0\2\36\25\0\4\36\55\0"+ + "\1\36\15\0\2\36\10\0\2\36\1\0\1\36\1\0"+ + "\1\36\11\0\1\36\11\0\2\36\6\0\1\36\2\0"+ + "\4\36\3\0\1\36\2\0\2\36\1\0\3\36\1\0"+ + "\2\36\1\0\1\36\10\0\1\36\1\0\2\36\2\0"+ + "\2\36\1\0\4\36\23\0\1\36\27\0\1\30\4\0"+ + "\1\30\11\0\1\30\22\0\1\30\3\0\1\30\13\0"+ + "\1\37\2\0\1\37\10\0\1\30\22\0\4\37\35\0"+ + "\1\30\26\0\1\30\26\0\2\30\23\0\1\62\1\30"+ + "\40\0\1\62\13\0\1\37\65\0\1\62\11\0\1\37"+ + "\15\0\4\30\2\0\2\30\14\0\3\30\1\37\1\0"+ + "\2\37\11\0\3\30\3\0\1\30\1\0\1\37\4\0"+ + "\1\37\2\30\1\0\4\62\1\0\2\30\5\0\4\37"+ + "\2\0\1\30\1\37\12\0\1\37\7\0\1\30\30\0"+ + "\1\30\4\0\1\30\6\0\1\30\3\0\1\30\6\0"+ + "\1\30\5\0\1\30\2\0\2\30\1\0\17\30\2\0"+ + "\1\30\13\0\7\30\2\0\1\30\1\0\1\30\1\0"+ + "\2\30\2\0\1\30\1\0\3\30\2\0\1\30\1\0"+ + "\1\30\1\0\1\30\1\0\1\30\4\0\1\37\1\0"+ + "\2\30\6\0\1\30\7\0\1\30\1\0\1\30\33\0"+ + "\1\30\6\0\1\30\3\0\1\30\3\0\1\30\7\0"+ + "\1\30\31\0\20\30\5\0\3\30\4\0\1\30\6\0"+ + "\1\30\3\0\2\30\2\0\2\30\4\0\1\30\4\37"+ + "\1\0\1\30\2\0\1\30\4\0\1\30\1\0\1\30"+ + "\1\0\1\30\134\0\2\37\25\0\4\37\55\0\1\37"+ + "\15\0\2\37\10\0\2\37\1\0\1\37\1\0\1\37"+ + "\11\0\1\37\11\0\2\37\6\0\1\37\2\0\4\37"+ + "\3\0\1\37\2\0\2\37\1\0\3\37\1\0\2\37"+ + "\1\0\1\37\10\0\1\37\1\0\2\37\2\0\2\37"+ + "\1\0\4\37\23\0\1\37\26\0\1\257\21\0\1\260"+ + "\2\0\1\261\10\0\1\262\22\0\1\263\21\0\1\264"+ + "\2\0\1\265\62\0\1\150\7\0\1\150\4\0\1\266"+ + "\10\0\1\30\4\0\1\30\11\0\1\30\22\0\1\30"+ + "\3\0\1\30\13\0\1\40\2\0\1\40\10\0\1\30"+ + "\22\0\4\40\35\0\1\30\26\0\1\30\26\0\2\30"+ + "\23\0\1\62\1\30\40\0\1\62\13\0\1\40\65\0"+ + "\1\62\11\0\1\40\15\0\4\30\2\0\2\30\14\0"+ + "\3\30\1\40\1\0\2\40\11\0\3\30\3\0\1\30"+ + "\1\0\1\40\4\0\1\40\2\30\1\0\4\62\1\0"+ + "\2\30\5\0\4\40\2\0\1\30\1\40\12\0\1\40"+ + "\7\0\1\30\30\0\1\30\4\0\1\30\6\0\1\30"+ + "\3\0\1\30\6\0\1\30\5\0\1\30\2\0\2\30"+ + "\1\0\17\30\2\0\1\30\13\0\7\30\2\0\1\30"+ + "\1\0\1\30\1\0\2\30\2\0\1\30\1\0\3\30"+ + "\2\0\1\30\1\0\1\30\1\0\1\30\1\0\1\30"+ + "\4\0\1\40\1\0\2\30\6\0\1\30\7\0\1\30"+ + "\1\0\1\30\33\0\1\30\6\0\1\30\3\0\1\30"+ + "\3\0\1\30\7\0\1\30\31\0\20\30\5\0\3\30"+ + "\4\0\1\30\6\0\1\30\3\0\2\30\2\0\2\30"+ + "\4\0\1\30\4\40\1\0\1\30\2\0\1\30\4\0"+ + "\1\30\1\0\1\30\1\0\1\30\134\0\2\40\25\0"+ + "\4\40\55\0\1\40\15\0\2\40\10\0\2\40\1\0"+ + "\1\40\1\0\1\40\11\0\1\40\11\0\2\40\6\0"+ + "\1\40\2\0\4\40\3\0\1\40\2\0\2\40\1\0"+ + "\3\40\1\0\2\40\1\0\1\40\10\0\1\40\1\0"+ + "\2\40\2\0\2\40\1\0\4\40\23\0\1\40\111\0"+ + "\1\41\2\0\1\41\33\0\4\41\216\0\1\41\77\0"+ + "\1\41\44\0\1\41\1\0\2\41\21\0\1\41\4\0"+ + "\1\41\17\0\4\41\3\0\1\41\12\0\1\41\203\0"+ + "\1\41\222\0\4\41\152\0\2\41\25\0\4\41\55\0"+ + "\1\41\15\0\2\41\10\0\2\41\1\0\1\41\1\0"+ + "\1\41\11\0\1\41\11\0\2\41\6\0\1\41\2\0"+ + "\4\41\3\0\1\41\2\0\2\41\1\0\3\41\1\0"+ + "\2\41\1\0\1\41\10\0\1\41\1\0\2\41\2\0"+ + "\2\41\1\0\4\41\23\0\1\41\165\0\1\267\26\0"+ + "\2\267\27\0\1\30\4\0\1\30\11\0\1\30\22\0"+ + "\1\30\3\0\1\30\13\0\1\62\2\0\1\62\10\0"+ + "\1\30\22\0\4\62\35\0\1\30\26\0\1\30\26\0"+ + "\2\30\23\0\1\62\1\30\40\0\1\62\13\0\1\62"+ + "\65\0\1\62\11\0\1\62\15\0\4\30\2\0\2\30"+ + "\14\0\3\30\1\62\1\0\2\62\11\0\3\30\3\0"+ + "\1\30\1\0\1\62\4\0\1\62\2\30\1\0\4\62"+ + "\1\0\2\30\5\0\4\62\2\0\1\30\1\62\12\0"+ + "\1\62\7\0\1\30\30\0\1\30\4\0\1\30\6\0"+ + "\1\30\3\0\1\30\6\0\1\30\5\0\1\30\2\0"+ + "\2\30\1\0\17\30\2\0\1\30\13\0\7\30\2\0"+ + "\1\30\1\0\1\30\1\0\2\30\2\0\1\30\1\0"+ + "\3\30\2\0\1\30\1\0\1\30\1\0\1\30\1\0"+ + "\1\30\4\0\1\62\1\0\2\30\6\0\1\30\7\0"+ + "\1\30\1\0\1\30\33\0\1\30\6\0\1\30\3\0"+ + "\1\30\3\0\1\30\7\0\1\30\31\0\20\30\5\0"+ + "\3\30\4\0\1\30\6\0\1\30\3\0\2\30\2\0"+ + "\2\30\4\0\1\30\4\62\1\0\1\30\2\0\1\30"+ + "\4\0\1\30\1\0\1\30\1\0\1\30\134\0\2\62"+ + "\25\0\4\62\55\0\1\62\15\0\2\62\10\0\2\62"+ + "\1\0\1\62\1\0\1\62\11\0\1\62\11\0\2\62"+ + "\6\0\1\62\2\0\4\62\3\0\1\62\2\0\2\62"+ + "\1\0\3\62\1\0\2\62\1\0\1\62\10\0\1\62"+ + "\1\0\2\62\2\0\2\62\1\0\4\62\23\0\1\62"+ + "\26\0\1\270\1\0\1\271\17\0\1\272\2\0\1\273"+ + "\4\0\1\274\3\0\1\275\22\0\1\276\21\0\1\277"+ + "\2\0\1\300\62\0\1\177\1\62\2\0\3\177\1\0"+ + "\1\177\2\0\1\177\4\0\1\42\1\0\1\43\2\0"+ + "\1\301\1\0\1\45\4\0\1\46\1\0\1\47\1\0"+ + "\1\50\2\0\1\51\3\0\1\302\2\0\1\303\4\0"+ + "\1\54\3\0\1\304\17\0\1\56\2\0\1\305\21\0"+ + "\1\306\2\0\1\307\41\0\1\120\17\0\1\30\1\200"+ + "\1\62\1\122\1\0\2\177\1\200\1\0\1\200\2\0"+ + "\1\177\1\0\1\37\1\30\7\0\1\30\4\0\1\30"+ + "\11\0\1\30\22\0\1\30\3\0\1\30\13\0\1\63"+ + "\2\0\1\63\10\0\1\30\22\0\4\63\35\0\1\30"+ + "\31\0\1\30\3\0\4\30\1\0\1\30\4\0\1\30"+ + "\1\0\2\30\2\0\2\30\2\0\3\30\1\0\1\30"+ + "\1\0\1\30\2\0\4\30\1\0\3\30\1\0\1\30"+ + "\1\0\3\30\1\0\2\30\1\0\4\30\1\0\2\30"+ + "\2\0\10\30\1\0\2\30\1\0\10\30\2\0\7\30"+ + "\1\0\10\30\1\0\6\30\1\0\1\30\1\0\2\30"+ + "\2\0\1\30\1\0\1\30\3\0\3\30\22\0\1\30"+ + "\26\0\2\30\24\0\1\30\54\0\1\63\77\0\1\63"+ + "\15\0\4\30\2\0\2\30\14\0\3\30\1\63\1\0"+ + "\2\63\11\0\3\30\3\0\1\30\1\0\1\63\4\0"+ + "\1\63\2\30\6\0\2\30\5\0\4\63\2\0\1\30"+ + "\1\63\12\0\1\63\7\0\1\30\44\0\1\30\3\0"+ + "\2\30\12\0\2\30\1\0\3\30\7\0\1\30\6\0"+ + "\2\30\1\0\2\30\6\0\1\30\4\0\2\30\2\0"+ + "\2\30\5\0\3\30\2\0\1\30\15\0\1\30\16\0"+ + "\1\30\7\0\1\30\30\0\1\30\4\0\1\30\6\0"+ + "\1\30\3\0\1\30\6\0\1\30\5\0\1\30\2\0"+ + "\2\30\1\0\17\30\2\0\1\30\13\0\7\30\2\0"+ + "\1\30\1\0\1\30\1\0\2\30\2\0\1\30\1\0"+ + "\3\30\2\0\1\30\1\0\1\30\1\0\1\30\1\0"+ + "\1\30\4\0\1\63\1\0\2\30\6\0\1\30\7\0"+ + "\1\30\1\0\1\30\33\0\1\30\6\0\1\30\3\0"+ + "\1\30\3\0\1\30\7\0\1\30\31\0\20\30\5\0"+ + "\3\30\4\0\1\30\6\0\1\30\3\0\2\30\2\0"+ + "\2\30\4\0\1\30\4\63\1\0\1\30\2\0\1\30"+ + "\4\0\1\30\1\0\1\30\1\0\1\30\134\0\2\63"+ + "\25\0\4\63\55\0\1\63\15\0\2\63\10\0\2\63"+ + "\1\0\1\63\1\0\1\63\11\0\1\63\11\0\2\63"+ + "\6\0\1\63\2\0\4\63\3\0\1\63\2\0\2\63"+ + "\1\0\3\63\1\0\2\63\1\0\1\63\10\0\1\63"+ + "\1\0\2\63\2\0\2\63\1\0\4\63\23\0\1\63"+ + "\27\0\1\30\4\0\1\30\11\0\1\30\22\0\1\30"+ + "\3\0\1\30\13\0\1\64\2\0\1\64\10\0\1\30"+ + "\22\0\4\64\35\0\1\30\26\0\1\30\26\0\2\30"+ + "\23\0\1\62\1\30\40\0\1\62\13\0\1\64\65\0"+ + "\1\62\11\0\1\64\15\0\4\30\2\0\2\30\14\0"+ + "\3\30\1\64\1\0\2\64\11\0\3\30\3\0\1\30"+ + "\1\0\1\64\4\0\1\64\2\30\1\0\4\62\1\0"+ + "\2\30\5\0\4\64\2\0\1\30\1\64\12\0\1\64"+ + "\7\0\1\30\30\0\1\30\4\0\1\30\6\0\1\30"+ + "\3\0\1\30\6\0\1\30\5\0\1\30\2\0\2\30"+ + "\1\0\17\30\2\0\1\30\13\0\7\30\2\0\1\30"+ + "\1\0\1\30\1\0\2\30\2\0\1\30\1\0\3\30"+ + "\2\0\1\30\1\0\1\30\1\0\1\30\1\0\1\30"+ + "\4\0\1\64\1\0\2\30\6\0\1\30\7\0\1\30"+ + "\1\0\1\30\33\0\1\30\6\0\1\30\3\0\1\30"+ + "\3\0\1\30\7\0\1\30\31\0\20\30\5\0\3\30"+ + "\4\0\1\30\6\0\1\30\3\0\2\30\2\0\2\30"+ + "\4\0\1\30\4\64\1\0\1\30\2\0\1\30\4\0"+ + "\1\30\1\0\1\30\1\0\1\30\134\0\2\64\25\0"+ + "\4\64\55\0\1\64\15\0\2\64\10\0\2\64\1\0"+ + "\1\64\1\0\1\64\11\0\1\64\11\0\2\64\6\0"+ + "\1\64\2\0\4\64\3\0\1\64\2\0\2\64\1\0"+ + "\3\64\1\0\2\64\1\0\1\64\10\0\1\64\1\0"+ + "\2\64\2\0\2\64\1\0\4\64\23\0\1\64\111\0"+ + "\1\76\2\0\1\76\33\0\4\76\102\0\1\31\104\0"+ + "\1\31\146\0\1\31\41\0\1\31\13\0\1\76\65\0"+ + "\1\31\11\0\1\76\44\0\1\76\1\0\2\76\21\0"+ + "\1\76\4\0\1\76\3\0\4\31\10\0\4\76\3\0"+ + "\1\76\12\0\1\76\164\0\2\31\233\0\1\76\222\0"+ + "\4\76\152\0\2\76\25\0\4\76\55\0\1\76\15\0"+ + "\2\76\10\0\2\76\1\0\1\76\1\0\1\76\11\0"+ + "\1\76\11\0\2\76\6\0\1\76\2\0\4\76\3\0"+ + "\1\76\2\0\2\76\1\0\3\76\1\0\2\76\1\0"+ + "\1\76\10\0\1\76\1\0\2\76\2\0\2\76\1\0"+ + "\4\76\23\0\1\76\27\0\1\30\4\0\1\30\11\0"+ + "\1\30\22\0\1\30\3\0\1\30\13\0\1\77\2\0"+ + "\1\77\10\0\1\30\22\0\4\77\35\0\1\30\26\0"+ + "\1\30\26\0\2\30\23\0\1\31\1\30\40\0\1\31"+ + "\13\0\1\77\65\0\1\31\11\0\1\77\15\0\4\30"+ + "\2\0\2\30\14\0\3\30\1\77\1\0\2\77\11\0"+ + "\3\30\3\0\1\30\1\0\1\77\4\0\1\77\2\30"+ + "\1\0\4\31\1\0\2\30\5\0\4\77\2\0\1\30"+ + "\1\77\12\0\1\77\7\0\1\30\30\0\1\30\4\0"+ + "\1\30\6\0\1\30\3\0\1\30\6\0\1\30\5\0"+ + "\1\30\2\0\2\30\1\0\17\30\2\0\1\30\13\0"+ + "\7\30\2\0\1\30\1\0\1\30\1\0\2\30\2\0"+ + "\1\30\1\0\3\30\2\0\1\30\1\0\1\30\1\0"+ + "\1\30\1\0\1\30\4\0\1\77\1\0\2\30\6\0"+ + "\1\30\7\0\1\30\1\0\1\30\33\0\1\30\6\0"+ + "\1\30\3\0\1\30\3\0\1\30\7\0\1\30\31\0"+ + "\20\30\5\0\3\30\4\0\1\30\6\0\1\30\3\0"+ + "\2\30\2\0\2\30\4\0\1\30\4\77\1\0\1\30"+ + "\2\0\1\30\4\0\1\30\1\0\1\30\1\0\1\30"+ + "\134\0\2\77\25\0\4\77\55\0\1\77\15\0\2\77"+ + "\10\0\2\77\1\0\1\77\1\0\1\77\11\0\1\77"+ + "\11\0\2\77\6\0\1\77\2\0\4\77\3\0\1\77"+ + "\2\0\2\77\1\0\3\77\1\0\2\77\1\0\1\77"+ + "\10\0\1\77\1\0\2\77\2\0\2\77\1\0\4\77"+ + "\23\0\1\77\27\0\1\30\4\0\1\30\11\0\1\30"+ + "\22\0\1\30\3\0\1\30\13\0\1\110\2\0\1\110"+ + "\10\0\1\30\22\0\4\110\35\0\1\30\26\0\1\30"+ + "\26\0\2\30\23\0\1\62\1\30\40\0\1\62\13\0"+ + "\1\110\65\0\1\62\11\0\1\110\15\0\4\30\2\0"+ + "\2\30\14\0\3\30\1\110\1\0\2\110\11\0\3\30"+ + "\3\0\1\30\1\0\1\110\4\0\1\110\2\30\1\0"+ + "\4\62\1\0\2\30\5\0\4\110\2\0\1\30\1\110"+ + "\12\0\1\110\7\0\1\30\30\0\1\30\4\0\1\30"+ + "\6\0\1\30\3\0\1\30\6\0\1\30\5\0\1\30"+ + "\2\0\2\30\1\0\17\30\2\0\1\30\13\0\7\30"+ + "\2\0\1\30\1\0\1\30\1\0\2\30\2\0\1\30"+ + "\1\0\3\30\2\0\1\30\1\0\1\30\1\0\1\30"+ + "\1\0\1\30\4\0\1\110\1\0\2\30\6\0\1\30"+ + "\7\0\1\30\1\0\1\30\33\0\1\30\6\0\1\30"+ + "\3\0\1\30\3\0\1\30\7\0\1\30\31\0\20\30"+ + "\5\0\3\30\4\0\1\30\6\0\1\30\3\0\2\30"+ + "\2\0\2\30\4\0\1\30\4\110\1\0\1\30\2\0"+ + "\1\30\4\0\1\30\1\0\1\30\1\0\1\30\134\0"+ + "\2\110\25\0\4\110\55\0\1\110\15\0\2\110\10\0"+ + "\2\110\1\0\1\110\1\0\1\110\11\0\1\110\11\0"+ + "\2\110\6\0\1\110\2\0\4\110\3\0\1\110\2\0"+ + "\2\110\1\0\3\110\1\0\2\110\1\0\1\110\10\0"+ + "\1\110\1\0\2\110\2\0\2\110\1\0\4\110\23\0"+ + "\1\110\111\0\1\122\2\0\1\122\33\0\4\122\216\0"+ + "\1\122\77\0\1\122\44\0\1\122\1\0\2\122\21\0"+ + "\1\122\4\0\1\122\17\0\4\122\3\0\1\122\12\0"+ + "\1\122\203\0\1\122\222\0\4\122\152\0\2\122\25\0"+ + "\4\122\55\0\1\122\15\0\2\122\10\0\2\122\1\0"+ + "\1\122\1\0\1\122\11\0\1\122\11\0\2\122\6\0"+ + "\1\122\2\0\4\122\3\0\1\122\2\0\2\122\1\0"+ + "\3\122\1\0\2\122\1\0\1\122\10\0\1\122\1\0"+ + "\2\122\2\0\2\122\1\0\4\122\23\0\1\122\111\0"+ + "\1\150\2\0\1\150\33\0\4\150\216\0\1\150\77\0"+ + "\1\150\44\0\1\150\1\0\2\150\21\0\1\150\4\0"+ + "\1\150\17\0\4\150\3\0\1\150\12\0\1\150\203\0"+ + "\1\150\222\0\4\150\152\0\2\150\25\0\4\150\55\0"+ + "\1\150\15\0\2\150\10\0\2\150\1\0\1\150\1\0"+ + "\1\150\11\0\1\150\11\0\2\150\6\0\1\150\2\0"+ + "\4\150\3\0\1\150\2\0\2\150\1\0\3\150\1\0"+ + "\2\150\1\0\1\150\10\0\1\150\1\0\2\150\2\0"+ + "\2\150\1\0\4\150\23\0\1\150\21\0\1\42\1\0"+ + "\1\43\2\0\1\310\1\0\1\45\4\0\1\46\1\0"+ + "\1\47\1\0\1\50\2\0\1\51\3\0\1\311\2\0"+ + "\1\312\4\0\1\54\3\0\1\313\17\0\1\56\2\0"+ + "\1\314\21\0\1\315\2\0\1\316\61\0\1\30\1\266"+ + "\1\62\4\0\1\110\1\0\1\266\4\0\1\37\1\30"+ + "\6\0\1\317\21\0\1\320\2\0\1\321\10\0\1\322"+ + "\22\0\1\323\21\0\1\324\2\0\1\325\55\0\1\167"+ + "\4\0\1\267\7\0\1\267\77\0\1\177\2\0\1\177"+ + "\33\0\4\177\102\0\1\62\104\0\1\62\146\0\1\62"+ + "\41\0\1\62\13\0\1\177\65\0\1\62\11\0\1\177"+ + "\44\0\1\177\1\0\2\177\21\0\1\177\4\0\1\177"+ + "\3\0\4\62\10\0\4\177\3\0\1\177\12\0\1\177"+ + "\164\0\2\62\233\0\1\177\222\0\4\177\152\0\2\177"+ + "\25\0\4\177\55\0\1\177\15\0\2\177\10\0\2\177"+ + "\1\0\1\177\1\0\1\177\11\0\1\177\11\0\2\177"+ + "\6\0\1\177\2\0\4\177\3\0\1\177\2\0\2\177"+ + "\1\0\3\177\1\0\2\177\1\0\1\177\10\0\1\177"+ + "\1\0\2\177\2\0\2\177\1\0\4\177\23\0\1\177"+ + "\27\0\1\30\4\0\1\30\11\0\1\30\22\0\1\30"+ + "\3\0\1\30\13\0\1\200\2\0\1\200\10\0\1\30"+ + "\22\0\4\200\35\0\1\30\26\0\1\30\26\0\2\30"+ + "\23\0\1\62\1\30\40\0\1\62\13\0\1\200\65\0"+ + "\1\62\11\0\1\200\15\0\4\30\2\0\2\30\14\0"+ + "\3\30\1\200\1\0\2\200\11\0\3\30\3\0\1\30"+ + "\1\0\1\200\4\0\1\200\2\30\1\0\4\62\1\0"+ + "\2\30\5\0\4\200\2\0\1\30\1\200\12\0\1\200"+ + "\7\0\1\30\30\0\1\30\4\0\1\30\6\0\1\30"+ + "\3\0\1\30\6\0\1\30\5\0\1\30\2\0\2\30"+ + "\1\0\17\30\2\0\1\30\13\0\7\30\2\0\1\30"+ + "\1\0\1\30\1\0\2\30\2\0\1\30\1\0\3\30"+ + "\2\0\1\30\1\0\1\30\1\0\1\30\1\0\1\30"+ + "\4\0\1\200\1\0\2\30\6\0\1\30\7\0\1\30"+ + "\1\0\1\30\33\0\1\30\6\0\1\30\3\0\1\30"+ + "\3\0\1\30\7\0\1\30\31\0\20\30\5\0\3\30"+ + "\4\0\1\30\6\0\1\30\3\0\2\30\2\0\2\30"+ + "\4\0\1\30\4\200\1\0\1\30\2\0\1\30\4\0"+ + "\1\30\1\0\1\30\1\0\1\30\134\0\2\200\25\0"+ + "\4\200\55\0\1\200\15\0\2\200\10\0\2\200\1\0"+ + "\1\200\1\0\1\200\11\0\1\200\11\0\2\200\6\0"+ + "\1\200\2\0\4\200\3\0\1\200\2\0\2\200\1\0"+ + "\3\200\1\0\2\200\1\0\1\200\10\0\1\200\1\0"+ + "\2\200\2\0\2\200\1\0\4\200\23\0\1\200\27\0"+ "\1\30\4\0\1\30\11\0\1\30\22\0\1\30\3\0"+ - "\1\30\13\0\1\276\2\0\1\276\10\0\1\30\22\0"+ - "\4\276\35\0\1\30\26\0\1\30\26\0\2\30\23\0"+ - "\1\62\1\30\40\0\1\62\13\0\1\276\65\0\1\62"+ - "\11\0\1\276\15\0\4\30\2\0\2\30\14\0\3\30"+ - "\1\276\1\0\2\276\11\0\3\30\3\0\1\30\1\0"+ - "\1\276\4\0\1\276\2\30\1\0\4\62\1\0\2\30"+ - "\5\0\4\276\2\0\1\30\1\276\12\0\1\276\7\0"+ + "\1\30\13\0\1\266\2\0\1\266\10\0\1\30\22\0"+ + "\4\266\35\0\1\30\26\0\1\30\26\0\2\30\23\0"+ + "\1\62\1\30\40\0\1\62\13\0\1\266\65\0\1\62"+ + "\11\0\1\266\15\0\4\30\2\0\2\30\14\0\3\30"+ + "\1\266\1\0\2\266\11\0\3\30\3\0\1\30\1\0"+ + "\1\266\4\0\1\266\2\30\1\0\4\62\1\0\2\30"+ + "\5\0\4\266\2\0\1\30\1\266\12\0\1\266\7\0"+ "\1\30\30\0\1\30\4\0\1\30\6\0\1\30\3\0"+ "\1\30\6\0\1\30\5\0\1\30\2\0\2\30\1\0"+ "\17\30\2\0\1\30\13\0\7\30\2\0\1\30\1\0"+ "\1\30\1\0\2\30\2\0\1\30\1\0\3\30\2\0"+ "\1\30\1\0\1\30\1\0\1\30\1\0\1\30\4\0"+ - "\1\276\1\0\2\30\6\0\1\30\7\0\1\30\1\0"+ + "\1\266\1\0\2\30\6\0\1\30\7\0\1\30\1\0"+ "\1\30\33\0\1\30\6\0\1\30\3\0\1\30\3\0"+ "\1\30\7\0\1\30\31\0\20\30\5\0\3\30\4\0"+ "\1\30\6\0\1\30\3\0\2\30\2\0\2\30\4\0"+ - "\1\30\4\276\1\0\1\30\2\0\1\30\4\0\1\30"+ - "\1\0\1\30\1\0\1\30\134\0\2\276\25\0\4\276"+ - "\55\0\1\276\15\0\2\276\10\0\2\276\1\0\1\276"+ - "\1\0\1\276\11\0\1\276\11\0\2\276\6\0\1\276"+ - "\2\0\4\276\3\0\1\276\2\0\2\276\1\0\3\276"+ - "\1\0\2\276\1\0\1\276\10\0\1\276\1\0\2\276"+ - "\2\0\2\276\1\0\4\276\23\0\1\276\111\0\1\277"+ - "\2\0\1\277\33\0\4\277\216\0\1\277\77\0\1\277"+ - "\44\0\1\277\1\0\2\277\21\0\1\277\4\0\1\277"+ - "\17\0\4\277\3\0\1\277\12\0\1\277\203\0\1\277"+ - "\222\0\4\277\152\0\2\277\25\0\4\277\55\0\1\277"+ - "\15\0\2\277\10\0\2\277\1\0\1\277\1\0\1\277"+ - "\11\0\1\277\11\0\2\277\6\0\1\277\2\0\4\277"+ - "\3\0\1\277\2\0\2\277\1\0\3\277\1\0\2\277"+ - "\1\0\1\277\10\0\1\277\1\0\2\277\2\0\2\277"+ - "\1\0\4\277\23\0\1\277\20\0"; + "\1\30\4\266\1\0\1\30\2\0\1\30\4\0\1\30"+ + "\1\0\1\30\1\0\1\30\134\0\2\266\25\0\4\266"+ + "\55\0\1\266\15\0\2\266\10\0\2\266\1\0\1\266"+ + "\1\0\1\266\11\0\1\266\11\0\2\266\6\0\1\266"+ + "\2\0\4\266\3\0\1\266\2\0\2\266\1\0\3\266"+ + "\1\0\2\266\1\0\1\266\10\0\1\266\1\0\2\266"+ + "\2\0\2\266\1\0\4\266\23\0\1\266\111\0\1\267"+ + "\2\0\1\267\33\0\4\267\216\0\1\267\77\0\1\267"+ + "\44\0\1\267\1\0\2\267\21\0\1\267\4\0\1\267"+ + "\17\0\4\267\3\0\1\267\12\0\1\267\203\0\1\267"+ + "\222\0\4\267\152\0\2\267\25\0\4\267\55\0\1\267"+ + "\15\0\2\267\10\0\2\267\1\0\1\267\1\0\1\267"+ + "\11\0\1\267\11\0\2\267\6\0\1\267\2\0\4\267"+ + "\3\0\1\267\2\0\2\267\1\0\3\267\1\0\2\267"+ + "\1\0\1\267\10\0\1\267\1\0\2\267\2\0\2\267"+ + "\1\0\4\267\23\0\1\267\20\0"; private static int [] zzUnpackTrans() { - int [] result = new int[29962]; + int [] result = new int[28826]; int offset = 0; offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); return result; @@ -929,11 +917,11 @@ public final class StandardTokenizerImpl implements StandardTokenizerInterface { private static final String ZZ_ATTRIBUTE_PACKED_0 = "\1\0\1\11\36\1\21\0\1\1\1\0\1\1\12\0"+ - "\1\1\10\0\2\1\11\0\1\1\55\0\1\1\74\0"+ + "\1\1\10\0\1\1\11\0\1\1\55\0\1\1\65\0"+ "\2\1\36\0"; private static int [] zzUnpackAttribute() { - int [] result = new int[221]; + int [] result = new int[213]; int offset = 0; offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); return result; diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/StandardTokenizerImpl.jflex b/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/StandardTokenizerImpl.jflex index 76af5f4c937..a0ad6ad95fe 100644 --- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/StandardTokenizerImpl.jflex +++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/StandardTokenizerImpl.jflex @@ -157,13 +157,13 @@ RegionalIndicatorEx = {RegionalIndicator} // WB13a. (ALetter | Hebrew_Letter | Numeric | Katakana | ExtendNumLet) × ExtendNumLet // WB13b. ExtendNumLet × (ALetter | Hebrew_Letter | Numeric | Katakana) // -{ExtendNumLetEx}* ( {KatakanaEx} +{ExtendNumLetEx}* ( {KatakanaEx} ( {ExtendNumLetEx}* {KatakanaEx} )* | ( {HebrewLetterEx} ( {SingleQuoteEx} | {DoubleQuoteEx} {HebrewLetterEx} ) | {NumericEx} ( ( {ExtendNumLetEx}* | {MidNumericEx} )* {NumericEx} )* | {HebrewOrALetterEx} ( ( {ExtendNumLetEx}* | {MidLetterEx} )* {HebrewOrALetterEx} )* )+ ) -({ExtendNumLetEx}+ ( {KatakanaEx} +({ExtendNumLetEx}+ ( {KatakanaEx} ( {ExtendNumLetEx}* {KatakanaEx} )* | ( {HebrewLetterEx} ( {SingleQuoteEx} | {DoubleQuoteEx} {HebrewLetterEx} ) | {NumericEx} ( ( {ExtendNumLetEx}* | {MidNumericEx} )* {NumericEx} )* | {HebrewOrALetterEx} ( ( {ExtendNumLetEx}* | {MidLetterEx} )* {HebrewOrALetterEx} )* From 6df2115c56d5a2b73ca90742475e48593dd793c6 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Sat, 7 Dec 2013 06:17:30 +0000 Subject: [PATCH 197/223] SOLR-1301: Update jar checksums for Morphlines 0.9.0 git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1548795 13f79535-47bb-0310-9956-ffa450edef68 --- solr/licenses/cdk-morphlines-avro-0.8.1.jar.sha1 | 1 - solr/licenses/cdk-morphlines-avro-0.9.0.jar.sha1 | 1 + solr/licenses/cdk-morphlines-core-0.8.1-tests.jar.sha1 | 1 - solr/licenses/cdk-morphlines-core-0.8.1.jar.sha1 | 1 - solr/licenses/cdk-morphlines-core-0.9.0-tests.jar.sha1 | 1 + solr/licenses/cdk-morphlines-core-0.9.0.jar.sha1 | 1 + solr/licenses/cdk-morphlines-hadoop-sequencefile-0.8.1.jar.sha1 | 1 - solr/licenses/cdk-morphlines-hadoop-sequencefile-0.9.0.jar.sha1 | 1 + solr/licenses/cdk-morphlines-json-0.8.1.jar.sha1 | 1 - solr/licenses/cdk-morphlines-json-0.9.0.jar.sha1 | 1 + solr/licenses/cdk-morphlines-saxon-0.8.1.jar.sha1 | 1 - solr/licenses/cdk-morphlines-saxon-0.9.0.jar.sha1 | 1 + solr/licenses/cdk-morphlines-tika-core-0.8.1.jar.sha1 | 1 - solr/licenses/cdk-morphlines-tika-core-0.9.0.jar.sha1 | 1 + solr/licenses/cdk-morphlines-tika-decompress-0.8.1.jar.sha1 | 1 - solr/licenses/cdk-morphlines-tika-decompress-0.9.0.jar.sha1 | 1 + solr/licenses/cdk-morphlines-twitter-0.8.1.jar.sha1 | 1 - solr/licenses/cdk-morphlines-twitter-0.9.0.jar.sha1 | 1 + 18 files changed, 9 insertions(+), 9 deletions(-) delete mode 100644 solr/licenses/cdk-morphlines-avro-0.8.1.jar.sha1 create mode 100644 solr/licenses/cdk-morphlines-avro-0.9.0.jar.sha1 delete mode 100644 solr/licenses/cdk-morphlines-core-0.8.1-tests.jar.sha1 delete mode 100644 solr/licenses/cdk-morphlines-core-0.8.1.jar.sha1 create mode 100644 solr/licenses/cdk-morphlines-core-0.9.0-tests.jar.sha1 create mode 100644 solr/licenses/cdk-morphlines-core-0.9.0.jar.sha1 delete mode 100644 solr/licenses/cdk-morphlines-hadoop-sequencefile-0.8.1.jar.sha1 create mode 100644 solr/licenses/cdk-morphlines-hadoop-sequencefile-0.9.0.jar.sha1 delete mode 100644 solr/licenses/cdk-morphlines-json-0.8.1.jar.sha1 create mode 100644 solr/licenses/cdk-morphlines-json-0.9.0.jar.sha1 delete mode 100644 solr/licenses/cdk-morphlines-saxon-0.8.1.jar.sha1 create mode 100644 solr/licenses/cdk-morphlines-saxon-0.9.0.jar.sha1 delete mode 100644 solr/licenses/cdk-morphlines-tika-core-0.8.1.jar.sha1 create mode 100644 solr/licenses/cdk-morphlines-tika-core-0.9.0.jar.sha1 delete mode 100644 solr/licenses/cdk-morphlines-tika-decompress-0.8.1.jar.sha1 create mode 100644 solr/licenses/cdk-morphlines-tika-decompress-0.9.0.jar.sha1 delete mode 100644 solr/licenses/cdk-morphlines-twitter-0.8.1.jar.sha1 create mode 100644 solr/licenses/cdk-morphlines-twitter-0.9.0.jar.sha1 diff --git a/solr/licenses/cdk-morphlines-avro-0.8.1.jar.sha1 b/solr/licenses/cdk-morphlines-avro-0.8.1.jar.sha1 deleted file mode 100644 index d18d6607c4f..00000000000 --- a/solr/licenses/cdk-morphlines-avro-0.8.1.jar.sha1 +++ /dev/null @@ -1 +0,0 @@ -571c226f5ac71ce5fd23ae9aafb363eb4c58481f diff --git a/solr/licenses/cdk-morphlines-avro-0.9.0.jar.sha1 b/solr/licenses/cdk-morphlines-avro-0.9.0.jar.sha1 new file mode 100644 index 00000000000..4f83abddb7a --- /dev/null +++ b/solr/licenses/cdk-morphlines-avro-0.9.0.jar.sha1 @@ -0,0 +1 @@ +9c98c2cdcbfc7f8d540569a497217ac8f80501c7 diff --git a/solr/licenses/cdk-morphlines-core-0.8.1-tests.jar.sha1 b/solr/licenses/cdk-morphlines-core-0.8.1-tests.jar.sha1 deleted file mode 100644 index 9018483ca64..00000000000 --- a/solr/licenses/cdk-morphlines-core-0.8.1-tests.jar.sha1 +++ /dev/null @@ -1 +0,0 @@ -93b395579f13f4387c90d370f5f6fdb054070a3e diff --git a/solr/licenses/cdk-morphlines-core-0.8.1.jar.sha1 b/solr/licenses/cdk-morphlines-core-0.8.1.jar.sha1 deleted file mode 100644 index ea6f85d696c..00000000000 --- a/solr/licenses/cdk-morphlines-core-0.8.1.jar.sha1 +++ /dev/null @@ -1 +0,0 @@ -c0b87a3c7377db58e328dfecb850323d99655775 diff --git a/solr/licenses/cdk-morphlines-core-0.9.0-tests.jar.sha1 b/solr/licenses/cdk-morphlines-core-0.9.0-tests.jar.sha1 new file mode 100644 index 00000000000..89bca5cc405 --- /dev/null +++ b/solr/licenses/cdk-morphlines-core-0.9.0-tests.jar.sha1 @@ -0,0 +1 @@ +b9f7a4abae51560ef608d5504b72f11db9d402c3 diff --git a/solr/licenses/cdk-morphlines-core-0.9.0.jar.sha1 b/solr/licenses/cdk-morphlines-core-0.9.0.jar.sha1 new file mode 100644 index 00000000000..0dfca659c72 --- /dev/null +++ b/solr/licenses/cdk-morphlines-core-0.9.0.jar.sha1 @@ -0,0 +1 @@ +3f384eaf0160f364895d8e2d7cb9dd7165856110 diff --git a/solr/licenses/cdk-morphlines-hadoop-sequencefile-0.8.1.jar.sha1 b/solr/licenses/cdk-morphlines-hadoop-sequencefile-0.8.1.jar.sha1 deleted file mode 100644 index 5efdde56d53..00000000000 --- a/solr/licenses/cdk-morphlines-hadoop-sequencefile-0.8.1.jar.sha1 +++ /dev/null @@ -1 +0,0 @@ -c50c9ff93fcf4007dba04edb3f07872849b5aebb diff --git a/solr/licenses/cdk-morphlines-hadoop-sequencefile-0.9.0.jar.sha1 b/solr/licenses/cdk-morphlines-hadoop-sequencefile-0.9.0.jar.sha1 new file mode 100644 index 00000000000..3640bef5f5b --- /dev/null +++ b/solr/licenses/cdk-morphlines-hadoop-sequencefile-0.9.0.jar.sha1 @@ -0,0 +1 @@ +03c90cbe262fe43c53662a601956cb644347b9f4 diff --git a/solr/licenses/cdk-morphlines-json-0.8.1.jar.sha1 b/solr/licenses/cdk-morphlines-json-0.8.1.jar.sha1 deleted file mode 100644 index 6c50b027662..00000000000 --- a/solr/licenses/cdk-morphlines-json-0.8.1.jar.sha1 +++ /dev/null @@ -1 +0,0 @@ -494a6d3bcbba7abc8fddf25ac511e51c7c5a2ff9 diff --git a/solr/licenses/cdk-morphlines-json-0.9.0.jar.sha1 b/solr/licenses/cdk-morphlines-json-0.9.0.jar.sha1 new file mode 100644 index 00000000000..58c1dfd5c19 --- /dev/null +++ b/solr/licenses/cdk-morphlines-json-0.9.0.jar.sha1 @@ -0,0 +1 @@ +e94b58a71b5d80efad967bf94ab6e6ed303c70b2 diff --git a/solr/licenses/cdk-morphlines-saxon-0.8.1.jar.sha1 b/solr/licenses/cdk-morphlines-saxon-0.8.1.jar.sha1 deleted file mode 100644 index 486d6a6c692..00000000000 --- a/solr/licenses/cdk-morphlines-saxon-0.8.1.jar.sha1 +++ /dev/null @@ -1 +0,0 @@ -9805d7f1cf0240869c02832651fc4518bac77cf9 diff --git a/solr/licenses/cdk-morphlines-saxon-0.9.0.jar.sha1 b/solr/licenses/cdk-morphlines-saxon-0.9.0.jar.sha1 new file mode 100644 index 00000000000..e2b05641072 --- /dev/null +++ b/solr/licenses/cdk-morphlines-saxon-0.9.0.jar.sha1 @@ -0,0 +1 @@ +46d43cf30f18e3b9331379cc1e9a4220118871d8 diff --git a/solr/licenses/cdk-morphlines-tika-core-0.8.1.jar.sha1 b/solr/licenses/cdk-morphlines-tika-core-0.8.1.jar.sha1 deleted file mode 100644 index 312593060bd..00000000000 --- a/solr/licenses/cdk-morphlines-tika-core-0.8.1.jar.sha1 +++ /dev/null @@ -1 +0,0 @@ -96c3497423c8fb2c2fd75f836960e40b7e69454d diff --git a/solr/licenses/cdk-morphlines-tika-core-0.9.0.jar.sha1 b/solr/licenses/cdk-morphlines-tika-core-0.9.0.jar.sha1 new file mode 100644 index 00000000000..bbb8f5ef00f --- /dev/null +++ b/solr/licenses/cdk-morphlines-tika-core-0.9.0.jar.sha1 @@ -0,0 +1 @@ +53c19a5a442840e07eb1d53c1a6599af27998641 diff --git a/solr/licenses/cdk-morphlines-tika-decompress-0.8.1.jar.sha1 b/solr/licenses/cdk-morphlines-tika-decompress-0.8.1.jar.sha1 deleted file mode 100644 index 36e3c3f6628..00000000000 --- a/solr/licenses/cdk-morphlines-tika-decompress-0.8.1.jar.sha1 +++ /dev/null @@ -1 +0,0 @@ -060ccc1dda318af6826feca736c6c25ef9c8f207 diff --git a/solr/licenses/cdk-morphlines-tika-decompress-0.9.0.jar.sha1 b/solr/licenses/cdk-morphlines-tika-decompress-0.9.0.jar.sha1 new file mode 100644 index 00000000000..ecf3e63bfcf --- /dev/null +++ b/solr/licenses/cdk-morphlines-tika-decompress-0.9.0.jar.sha1 @@ -0,0 +1 @@ +071bc20a04d7c690525607ef160de87ea7eb7087 diff --git a/solr/licenses/cdk-morphlines-twitter-0.8.1.jar.sha1 b/solr/licenses/cdk-morphlines-twitter-0.8.1.jar.sha1 deleted file mode 100644 index 8368d3d6ab5..00000000000 --- a/solr/licenses/cdk-morphlines-twitter-0.8.1.jar.sha1 +++ /dev/null @@ -1 +0,0 @@ -d950d1f83ff52f4c8d948962c57bd60252c5e773 diff --git a/solr/licenses/cdk-morphlines-twitter-0.9.0.jar.sha1 b/solr/licenses/cdk-morphlines-twitter-0.9.0.jar.sha1 new file mode 100644 index 00000000000..a7ff1c67755 --- /dev/null +++ b/solr/licenses/cdk-morphlines-twitter-0.9.0.jar.sha1 @@ -0,0 +1 @@ +64c109f1e60214f871fb4ed7ed020c07d3d7d49d From 60bc097a7adabc308ac6a2b0abc6c340a8439d67 Mon Sep 17 00:00:00 2001 From: Uwe Schindler Date: Sat, 7 Dec 2013 09:29:37 +0000 Subject: [PATCH 198/223] Fix eol-style git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1548822 13f79535-47bb-0310-9956-ffa450edef68 From 0baa424980c9bd069465f5af7b49fb1cc0b2d8a6 Mon Sep 17 00:00:00 2001 From: Han Jiang Date: Sat, 7 Dec 2013 10:34:21 +0000 Subject: [PATCH 199/223] broken link police git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1548830 13f79535-47bb-0310-9956-ffa450edef68 --- .../src/java/org/apache/lucene/store/SimpleFSLockFactory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lucene/core/src/java/org/apache/lucene/store/SimpleFSLockFactory.java b/lucene/core/src/java/org/apache/lucene/store/SimpleFSLockFactory.java index 44ac8bf3587..67f440bfb13 100644 --- a/lucene/core/src/java/org/apache/lucene/store/SimpleFSLockFactory.java +++ b/lucene/core/src/java/org/apache/lucene/store/SimpleFSLockFactory.java @@ -25,7 +25,7 @@ import java.io.IOException; * File#createNewFile()}.

    * *

    NOTE: the javadocs + * href="http://docs.oracle.com/javase/7/docs/api/java/io/File.html#createNewFile()">javadocs * for File.createNewFile contain a vague * yet spooky warning about not using the API for file * locking. This warning was added due to Date: Sat, 7 Dec 2013 11:18:05 +0000 Subject: [PATCH 200/223] Better fix for the broken link using the native javadocs linking instead of HTML links: This makes the target of the link just work with compile version git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1548870 13f79535-47bb-0310-9956-ffa450edef68 --- .../java/org/apache/lucene/store/SimpleFSLockFactory.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lucene/core/src/java/org/apache/lucene/store/SimpleFSLockFactory.java b/lucene/core/src/java/org/apache/lucene/store/SimpleFSLockFactory.java index 67f440bfb13..92f58935ec9 100644 --- a/lucene/core/src/java/org/apache/lucene/store/SimpleFSLockFactory.java +++ b/lucene/core/src/java/org/apache/lucene/store/SimpleFSLockFactory.java @@ -24,9 +24,8 @@ import java.io.IOException; *

    Implements {@link LockFactory} using {@link * File#createNewFile()}.

    * - *

    NOTE: the javadocs - * for File.createNewFile contain a vague + *

    NOTE: the {@linkplain File#createNewFile() javadocs + * for File.createNewFile()} contain a vague * yet spooky warning about not using the API for file * locking. This warning was added due to this From 101f0b49785c88492d2b7a13ee9d22153a7ad22e Mon Sep 17 00:00:00 2001 From: "Chris M. Hostetter" Date: Sat, 7 Dec 2013 19:28:58 +0000 Subject: [PATCH 201/223] test to help verify that functions wrapping queries (or filtered by queries) are only evaluated for docs that match those queries git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1548955 13f79535-47bb-0310-9956-ffa450edef68 --- .../collection1/conf/solrconfig-SOLR-749.xml | 5 ++ .../core/CountUsageValueSourceParser.java | 88 +++++++++++++++++++ .../org/apache/solr/core/SOLR749Test.java | 35 ++++++++ 3 files changed, 128 insertions(+) create mode 100644 solr/core/src/test/org/apache/solr/core/CountUsageValueSourceParser.java diff --git a/solr/core/src/test-files/solr/collection1/conf/solrconfig-SOLR-749.xml b/solr/core/src/test-files/solr/collection1/conf/solrconfig-SOLR-749.xml index 1fabd5c202f..867a535f4a0 100644 --- a/solr/core/src/test-files/solr/collection1/conf/solrconfig-SOLR-749.xml +++ b/solr/core/src/test-files/solr/collection1/conf/solrconfig-SOLR-749.xml @@ -24,6 +24,11 @@ + + + + + diff --git a/solr/core/src/test/org/apache/solr/core/CountUsageValueSourceParser.java b/solr/core/src/test/org/apache/solr/core/CountUsageValueSourceParser.java new file mode 100644 index 00000000000..60f454ed4e9 --- /dev/null +++ b/solr/core/src/test/org/apache/solr/core/CountUsageValueSourceParser.java @@ -0,0 +1,88 @@ +package org.apache.solr.core; +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.apache.lucene.queries.function.FunctionValues; +import org.apache.lucene.queries.function.ValueSource; +import org.apache.lucene.queries.function.docvalues.DoubleDocValues; +import org.apache.lucene.queries.function.valuesource.DoubleConstValueSource; +import org.apache.lucene.index.AtomicReaderContext; +import org.apache.solr.common.util.NamedList; +import org.apache.solr.search.FunctionQParser; +import org.apache.solr.search.SyntaxError; +import org.apache.solr.search.ValueSourceParser; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * A Mock ValueSource parser that produces ValueSources that returns a constant + * value butalso keeps track of how many times it was asked for a value for any + * document via a static map and a user defined key. + **/ +public class CountUsageValueSourceParser extends ValueSourceParser { + + private static final ConcurrentMap counters + = new ConcurrentHashMap(); + + public static void clearCounters() { + counters.clear(); + } + public static int getAndClearCount(String key) { + AtomicInteger counter = counters.remove(key); + if (null == counter) { + throw new IllegalArgumentException("Key has never been used in function: " + key); + } + return counter.get(); + } + + @Override + public ValueSource parse(FunctionQParser fp) throws SyntaxError { + String key = fp.parseArg(); + double val = fp.parseDouble(); + + AtomicInteger counter = new AtomicInteger(); + if (null != counters.putIfAbsent(key, counter)) { + throw new IllegalArgumentException("Key has already been used: " + key); + } + return new CountDocsValueSource(counter, val); + } + + static final private class CountDocsValueSource extends DoubleConstValueSource { + private final AtomicInteger counter; + private final double value; + public CountDocsValueSource(AtomicInteger counter, double value) { + super(value); + this.value = value; + this.counter = counter; + } + @Override + public FunctionValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { + return new DoubleDocValues(this) { + @Override + public double doubleVal(int doc) { + counter.incrementAndGet(); + return value; + } + }; + } + } + +} diff --git a/solr/core/src/test/org/apache/solr/core/SOLR749Test.java b/solr/core/src/test/org/apache/solr/core/SOLR749Test.java index 243e59176f0..403c0cc2f3f 100644 --- a/solr/core/src/test/org/apache/solr/core/SOLR749Test.java +++ b/solr/core/src/test/org/apache/solr/core/SOLR749Test.java @@ -44,4 +44,39 @@ public class SOLR749Test extends SolrTestCaseJ4 { assertTrue("vsp is null and it shouldn't be", vsp != null); assertTrue("vsp is not an instanceof " + DummyValueSourceParser.class, vsp instanceof DummyValueSourceParser); } + + public void testHowManyDocsHaveBoostFunctionComputed() throws Exception { + for (int i = 0; i < 100; i++) { + assertU(adoc("id",""+i)); + } + assertU(commit()); + + // NOTE: we can't rely on the default lucene syntax because "FooQParser" is registered as "lucene" + assertQ(req("q","{!notfoo}*:*"), "//result[@numFound=100]"); + assertQ(req("q","{!notfoo}id:[* TO 49]"), "//result[@numFound=50]"); + try { + assertQ("query wrapped in boost func should only eval func for query matches", + req("q","{!boost b=$boostFunc defType=notfoo}id:[* TO 49]", + "boostFunc", "countUsage('boost_func',3.4)"), + "//result[@numFound=50]"); + assertEquals(50, CountUsageValueSourceParser.getAndClearCount("boost_func")); + + assertQ("func query that is filtered should be evaled only for filtered docs", + req("q","{!func}product(id,countUsage('func_q',4.5))", + "fq", "{!notfoo}id:[30 TO 59]"), + "//result[@numFound=30]"); + assertEquals(30, CountUsageValueSourceParser.getAndClearCount("func_q")); + + assertQ("func query that wraps a query which is also used as a should be evaled only for filtered docs", + req("q","{!func}product(query($qq),countUsage('func_q_wrapping_fq',4.5))", + "qq", "{!notfoo}id:[20 TO 39]", + "fq", "{!query v=$qq}"), + "//result[@numFound=20]"); + assertEquals(20, CountUsageValueSourceParser.getAndClearCount("func_q_wrapping_fq")); + + } finally { + CountUsageValueSourceParser.clearCounters(); + } + } + } From a0745eccea2b0b02378518c57ff80030df54cd16 Mon Sep 17 00:00:00 2001 From: Simon Willnauer Date: Sun, 8 Dec 2013 10:10:42 +0000 Subject: [PATCH 202/223] LUCENE-5362: IndexReader and SegmentCoreReaders now throw AlreadyClosedException if the refCount in incremented but is less that 1. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1549012 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/CHANGES.txt | 6 ++++++ .../src/java/org/apache/lucene/index/IndexReader.java | 5 +++-- .../java/org/apache/lucene/index/SegmentCoreReaders.java | 9 ++++++++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index b4757401478..072cdd2e352 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -101,6 +101,12 @@ Bug fixes * LUCENE-5285: Improved highlighting of multi-valued fields with FastVectorHighlighter. (Nik Everett via Adrien Grand) +Changes in Runtime Behavior + +* LUCENE-5362: IndexReader and SegmentCoreReaders now throw + AlreadyClosedException if the refCount in incremented but + is less that 1. (Simon Willnauer) + ======================= Lucene 4.6.0 ======================= New Features diff --git a/lucene/core/src/java/org/apache/lucene/index/IndexReader.java b/lucene/core/src/java/org/apache/lucene/index/IndexReader.java index 70174d5f23f..b416812fa55 100644 --- a/lucene/core/src/java/org/apache/lucene/index/IndexReader.java +++ b/lucene/core/src/java/org/apache/lucene/index/IndexReader.java @@ -168,8 +168,9 @@ public abstract class IndexReader implements Closeable { * @see #tryIncRef */ public final void incRef() { - ensureOpen(); - refCount.incrementAndGet(); + if (!tryIncRef()) { + ensureOpen(); + } } /** diff --git a/lucene/core/src/java/org/apache/lucene/index/SegmentCoreReaders.java b/lucene/core/src/java/org/apache/lucene/index/SegmentCoreReaders.java index 99d96570163..057c98dff51 100644 --- a/lucene/core/src/java/org/apache/lucene/index/SegmentCoreReaders.java +++ b/lucene/core/src/java/org/apache/lucene/index/SegmentCoreReaders.java @@ -32,6 +32,7 @@ import org.apache.lucene.codecs.PostingsFormat; import org.apache.lucene.codecs.StoredFieldsReader; import org.apache.lucene.codecs.TermVectorsReader; import org.apache.lucene.index.SegmentReader.CoreClosedListener; +import org.apache.lucene.store.AlreadyClosedException; import org.apache.lucene.store.CompoundFileDirectory; import org.apache.lucene.store.Directory; import org.apache.lucene.store.IOContext; @@ -139,7 +140,13 @@ final class SegmentCoreReaders { } void incRef() { - ref.incrementAndGet(); + int count; + while ((count = ref.get()) > 0) { + if (ref.compareAndSet(count, count+1)) { + return; + } + } + throw new AlreadyClosedException("SegmentCoreReaders is already closed"); } NumericDocValues getNormValues(FieldInfo fi) throws IOException { From 60a881a00b515f417ff0f89f357b70d4592a254e Mon Sep 17 00:00:00 2001 From: Noble Paul Date: Mon, 9 Dec 2013 11:22:29 +0000 Subject: [PATCH 203/223] SOLR-5525 git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1549552 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/solr/cloud/AssignTest.java | 2 +- .../apache/solr/cloud/ClusterStateTest.java | 31 ++++++++++++++++--- .../org/apache/solr/cloud/SliceStateTest.java | 5 +-- .../solr/common/cloud/ZkStateReader.java | 3 ++ 4 files changed, 33 insertions(+), 8 deletions(-) diff --git a/solr/core/src/test/org/apache/solr/cloud/AssignTest.java b/solr/core/src/test/org/apache/solr/cloud/AssignTest.java index 298f515f21f..7d05c2631b8 100644 --- a/solr/core/src/test/org/apache/solr/cloud/AssignTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/AssignTest.java @@ -86,7 +86,7 @@ public class AssignTest extends SolrTestCaseJ4 { collectionStates.put(cname, docCollection); Set liveNodes = new HashSet(); - ClusterState state = new ClusterState(liveNodes, collectionStates); + ClusterState state = new ClusterState(-1,liveNodes, collectionStates,ClusterStateTest.getMockZkStateReader(collectionStates.keySet())); String nodeName = Assign.assignNode("collection1", state); assertEquals("core_node2", nodeName); diff --git a/solr/core/src/test/org/apache/solr/cloud/ClusterStateTest.java b/solr/core/src/test/org/apache/solr/cloud/ClusterStateTest.java index 0af40e11da4..1e990d82c36 100644 --- a/solr/core/src/test/org/apache/solr/cloud/ClusterStateTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/ClusterStateTest.java @@ -17,6 +17,7 @@ package org.apache.solr.cloud; * the License. */ +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -26,12 +27,17 @@ import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.common.cloud.ClusterState; import org.apache.solr.common.cloud.DocCollection; import org.apache.solr.common.cloud.DocRouter; -import org.apache.solr.common.cloud.DocRouter; import org.apache.solr.common.cloud.Slice; import org.apache.solr.common.cloud.Replica; import org.apache.solr.common.cloud.ZkStateReader; +import org.easymock.EasyMock; +import org.easymock.IAnswer; import org.junit.Test; +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.createStrictMock; +import static org.easymock.EasyMock.expectLastCall; + public class ClusterStateTest extends SolrTestCaseJ4 { @Test public void testStoreAndRead() throws Exception { @@ -54,11 +60,12 @@ public class ClusterStateTest extends SolrTestCaseJ4 { slices.put("shard2", slice2); collectionStates.put("collection1", new DocCollection("collection1", slices, null, DocRouter.DEFAULT)); collectionStates.put("collection2", new DocCollection("collection2", slices, null, DocRouter.DEFAULT)); + ZkStateReader zkStateReaderMock = getMockZkStateReader(collectionStates.keySet()); - ClusterState clusterState = new ClusterState(liveNodes, collectionStates); + ClusterState clusterState = new ClusterState(-1,liveNodes, collectionStates,zkStateReaderMock); byte[] bytes = ZkStateReader.toJSON(clusterState); // System.out.println("#################### " + new String(bytes)); - ClusterState loadedClusterState = ClusterState.load(null, bytes, liveNodes,null); + ClusterState loadedClusterState = ClusterState.load(-1, bytes, liveNodes,zkStateReaderMock); assertEquals("Provided liveNodes not used properly", 2, loadedClusterState .getLiveNodes().size()); @@ -66,16 +73,30 @@ public class ClusterStateTest extends SolrTestCaseJ4 { assertEquals("Poperties not copied properly", replica.getStr("prop1"), loadedClusterState.getSlice("collection1", "shard1").getReplicasMap().get("node1").getStr("prop1")); assertEquals("Poperties not copied properly", replica.getStr("prop2"), loadedClusterState.getSlice("collection1", "shard1").getReplicasMap().get("node1").getStr("prop2")); - loadedClusterState = ClusterState.load(null, new byte[0], liveNodes,null); + loadedClusterState = ClusterState.load(-1, new byte[0], liveNodes, getMockZkStateReader(Collections.emptySet())); assertEquals("Provided liveNodes not used properly", 2, loadedClusterState .getLiveNodes().size()); assertEquals("Should not have collections", 0, loadedClusterState.getCollections().size()); - loadedClusterState = ClusterState.load(null, (byte[])null, liveNodes,null); + loadedClusterState = ClusterState.load(-1, (byte[])null, liveNodes,getMockZkStateReader(Collections.emptySet())); assertEquals("Provided liveNodes not used properly", 2, loadedClusterState .getLiveNodes().size()); assertEquals("Should not have collections", 0, loadedClusterState.getCollections().size()); } + + public static ZkStateReader getMockZkStateReader(final Set collections) { + ZkStateReader mock = createMock(ZkStateReader.class); + EasyMock.reset(mock); + mock.getAllCollections(); + EasyMock.expectLastCall().andAnswer(new IAnswer>() { + @Override + public Set answer() throws Throwable { + return collections; + } + }).anyTimes(); + + return mock; + } } diff --git a/solr/core/src/test/org/apache/solr/cloud/SliceStateTest.java b/solr/core/src/test/org/apache/solr/cloud/SliceStateTest.java index 2206f060981..cdf001a1393 100644 --- a/solr/core/src/test/org/apache/solr/cloud/SliceStateTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/SliceStateTest.java @@ -49,9 +49,10 @@ public class SliceStateTest extends SolrTestCaseJ4 { slices.put("shard1", slice); collectionStates.put("collection1", new DocCollection("collection1", slices, null, DocRouter.DEFAULT)); - ClusterState clusterState = new ClusterState(liveNodes, collectionStates); + ZkStateReader mockZkStateReader = ClusterStateTest.getMockZkStateReader(collectionStates.keySet()); + ClusterState clusterState = new ClusterState(-1,liveNodes, collectionStates, mockZkStateReader); byte[] bytes = ZkStateReader.toJSON(clusterState); - ClusterState loadedClusterState = ClusterState.load(null, bytes, liveNodes, null); + ClusterState loadedClusterState = ClusterState.load(-1, bytes, liveNodes, mockZkStateReader); assertEquals("Default state not set to active", "active", loadedClusterState.getSlice("collection1", "shard1").getState()); } diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java b/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java index e67a68776aa..7eecadd0d64 100644 --- a/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java +++ b/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java @@ -583,6 +583,9 @@ public class ZkStateReader { public SolrZkClient getZkClient() { return zkClient; } + public Set getAllCollections(){ + return clusterState.getCollections(); + } public void updateAliases() throws KeeperException, InterruptedException { byte[] data = zkClient.getData(ALIASES, null, null, true); From 07a2322efd1af4ba650803519e74421bf7692ff8 Mon Sep 17 00:00:00 2001 From: Noble Paul Date: Mon, 9 Dec 2013 14:58:53 +0000 Subject: [PATCH 204/223] SOLR-5525 git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1549591 13f79535-47bb-0310-9956-ffa450edef68 --- solr/core/src/test/org/apache/solr/cloud/ClusterStateTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/solr/core/src/test/org/apache/solr/cloud/ClusterStateTest.java b/solr/core/src/test/org/apache/solr/cloud/ClusterStateTest.java index 1e990d82c36..a438c319d59 100644 --- a/solr/core/src/test/org/apache/solr/cloud/ClusterStateTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/ClusterStateTest.java @@ -96,6 +96,7 @@ public class ClusterStateTest extends SolrTestCaseJ4 { return collections; } }).anyTimes(); + EasyMock.replay(mock); return mock; } From 0991a217d19a3ca732c04fed3e0318a0bcbb4e79 Mon Sep 17 00:00:00 2001 From: Simon Willnauer Date: Mon, 9 Dec 2013 21:40:39 +0000 Subject: [PATCH 205/223] Fix RandomSimilarityProvider Math#abs can return negative value for Integer.MIN_VALUE git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1549687 13f79535-47bb-0310-9956-ffa450edef68 --- .../java/org/apache/lucene/search/RandomSimilarityProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lucene/test-framework/src/java/org/apache/lucene/search/RandomSimilarityProvider.java b/lucene/test-framework/src/java/org/apache/lucene/search/RandomSimilarityProvider.java index 3fc0792a7be..d7aca2dc00f 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/search/RandomSimilarityProvider.java +++ b/lucene/test-framework/src/java/org/apache/lucene/search/RandomSimilarityProvider.java @@ -103,7 +103,7 @@ public class RandomSimilarityProvider extends PerFieldSimilarityWrapper { assert field != null; Similarity sim = previousMappings.get(field); if (sim == null) { - sim = knownSims.get(Math.abs(perFieldSeed ^ field.hashCode()) % knownSims.size()); + sim = knownSims.get(Math.max(0, Math.abs(perFieldSeed ^ field.hashCode())) % knownSims.size()); previousMappings.put(field, sim); } return sim; From a1461ad9b12fe4d9a62fc7a4aff2c7361584dedc Mon Sep 17 00:00:00 2001 From: Steven Rowe Date: Mon, 9 Dec 2013 22:53:38 +0000 Subject: [PATCH 206/223] LUCENE-5364: Replace hard-coded Version.LUCENE_XY that doesn't have to be hard-coded (because of back-compat testing or version dependent behavior, or demo code that should exemplify pinning versions in user code), with Version.LUCENE_CURRENT in non-test code, or with LuceneTestCase.TEST_VERSION_CURRENT in test code; upgrade hard-coded Version.LUCENE_XY constants that should track the next release version to the next release version if they aren't already there, and put a token near them so that they can be found and upgraded when the next release version changes: ':Post-Release-Update-Version.LUCENE_XY:' git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1549701 13f79535-47bb-0310-9956-ffa450edef68 --- .../charfilter/HTMLCharacterEntities.jflex | 2 +- .../charfilter/HTMLStripCharFilter.java | 4 +-- .../charfilter/HTMLStripCharFilter.jflex | 2 +- .../lucene/analysis/charfilter/htmlentity.py | 2 +- .../lucene/analysis/el/GreekStemmer.java | 32 +++++++++---------- .../apache/lucene/analysis/en/KStemmer.java | 5 +-- .../analysis/hunspell/HunspellStemmer.java | 5 +-- .../RemoveDuplicatesTokenFilter.java | 2 +- .../lucene/analysis/pt/RSLPStemmerBase.java | 2 +- .../synonym/SynonymFilterFactory.java | 6 ++-- .../analysis/core/TestStopAnalyzer.java | 2 +- .../lucene/analysis/core/TestStopFilter.java | 2 +- lucene/analysis/icu/src/java/overview.html | 17 +++++----- .../byTask/tasks/CreateIndexTask.java | 3 +- .../byTask/tasks/CreateIndexTaskTest.java | 3 +- .../classification/utils/DatasetSplitter.java | 1 + .../lucene/store/NRTCachingDirectory.java | 2 +- .../apache/lucene/search/TestPhraseQuery.java | 2 +- .../org/apache/lucene/demo/IndexFiles.java | 5 +-- .../org/apache/lucene/demo/SearchFiles.java | 6 ++-- .../lucene/demo/facet/FacetExamples.java | 3 +- .../demo/xmlparser/FormBasedXmlQueryDemo.java | 2 +- .../directory/DirectoryTaxonomyWriter.java | 3 +- .../lucene/queryparser/xml/TestParser.java | 2 +- .../suggest/analyzing/FreeTextSuggester.java | 2 +- .../apache/lucene/util/LuceneTestCase.java | 1 + .../apache/solr/schema/ICUCollationField.java | 3 +- .../apache/solr/schema/CollationField.java | 3 +- .../core/SolrCoreCheckLockOnStartupTest.java | 6 ++-- .../solr/core/TestArbitraryIndexDir.java | 2 +- .../apache/solr/search/TestStressLucene.java | 2 +- .../solr/spelling/SimpleQueryConverter.java | 4 +-- 32 files changed, 72 insertions(+), 66 deletions(-) diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/charfilter/HTMLCharacterEntities.jflex b/lucene/analysis/common/src/java/org/apache/lucene/analysis/charfilter/HTMLCharacterEntities.jflex index a32e1480828..c717b03489e 100644 --- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/charfilter/HTMLCharacterEntities.jflex +++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/charfilter/HTMLCharacterEntities.jflex @@ -73,7 +73,7 @@ CharacterEntities = ( "AElig" | "Aacute" | "Acirc" | "Agrave" | "Alpha" upperCaseVariantsAccepted.put("amp", "AMP"); } private static final CharArrayMap entityValues - = new CharArrayMap(Version.LUCENE_40, 253, false); + = new CharArrayMap(Version.LUCENE_CURRENT, 253, false); static { String[] entities = { "AElig", "\u00C6", "Aacute", "\u00C1", "Acirc", "\u00C2", diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/charfilter/HTMLStripCharFilter.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/charfilter/HTMLStripCharFilter.java index 4163a8f8c5d..f39f4ffa084 100644 --- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/charfilter/HTMLStripCharFilter.java +++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/charfilter/HTMLStripCharFilter.java @@ -30673,7 +30673,7 @@ public final class HTMLStripCharFilter extends BaseCharFilter { upperCaseVariantsAccepted.put("amp", "AMP"); } private static final CharArrayMap entityValues - = new CharArrayMap(Version.LUCENE_40, 253, false); + = new CharArrayMap(Version.LUCENE_CURRENT, 253, false); static { String[] entities = { "AElig", "\u00C6", "Aacute", "\u00C1", "Acirc", "\u00C2", @@ -30812,7 +30812,7 @@ public final class HTMLStripCharFilter extends BaseCharFilter { escapeSTYLE = true; } else { if (null == this.escapedTags) { - this.escapedTags = new CharArraySet(Version.LUCENE_40, 16, true); + this.escapedTags = new CharArraySet(Version.LUCENE_CURRENT, 16, true); } this.escapedTags.add(tag); } diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/charfilter/HTMLStripCharFilter.jflex b/lucene/analysis/common/src/java/org/apache/lucene/analysis/charfilter/HTMLStripCharFilter.jflex index 2a19332590f..cbef3f439bc 100755 --- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/charfilter/HTMLStripCharFilter.jflex +++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/charfilter/HTMLStripCharFilter.jflex @@ -197,7 +197,7 @@ InlineElment = ( [aAbBiIqQsSuU] | escapeSTYLE = true; } else { if (null == this.escapedTags) { - this.escapedTags = new CharArraySet(Version.LUCENE_40, 16, true); + this.escapedTags = new CharArraySet(Version.LUCENE_CURRENT, 16, true); } this.escapedTags.add(tag); } diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/charfilter/htmlentity.py b/lucene/analysis/common/src/java/org/apache/lucene/analysis/charfilter/htmlentity.py index ff9ee6bf3a1..8a080b9da3b 100644 --- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/charfilter/htmlentity.py +++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/charfilter/htmlentity.py @@ -61,7 +61,7 @@ def main(): print ' upperCaseVariantsAccepted.put("amp", "AMP");' print ' }' print ' private static final CharArrayMap entityValues' - print ' = new CharArrayMap(Version.LUCENE_40, %i, false);' % len(keys) + print ' = new CharArrayMap(Version.LUCENE_CURRENT, %i, false);' % len(keys) print ' static {' print ' String[] entities = {' output_line = ' ' diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/el/GreekStemmer.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/el/GreekStemmer.java index 815474f2b68..3db58dd9fe5 100644 --- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/el/GreekStemmer.java +++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/el/GreekStemmer.java @@ -196,7 +196,7 @@ public class GreekStemmer { return len; } - private static final CharArraySet exc4 = new CharArraySet(Version.LUCENE_50, + private static final CharArraySet exc4 = new CharArraySet(Version.LUCENE_CURRENT, Arrays.asList("θ", "δ", "ελ", "γαλ", "ν", "π", "ιδ", "παρ"), false); @@ -222,7 +222,7 @@ public class GreekStemmer { return len; } - private static final CharArraySet exc6 = new CharArraySet(Version.LUCENE_50, + private static final CharArraySet exc6 = new CharArraySet(Version.LUCENE_CURRENT, Arrays.asList("αλ", "αδ", "ενδ", "αμαν", "αμμοχαλ", "ηθ", "ανηθ", "αντιδ", "φυσ", "βρωμ", "γερ", "εξωδ", "καλπ", "καλλιν", "καταδ", "μουλ", "μπαν", "μπαγιατ", "μπολ", "μποσ", "νιτ", "ξικ", "συνομηλ", @@ -247,7 +247,7 @@ public class GreekStemmer { return len; } - private static final CharArraySet exc7 = new CharArraySet(Version.LUCENE_50, + private static final CharArraySet exc7 = new CharArraySet(Version.LUCENE_CURRENT, Arrays.asList("αναπ", "αποθ", "αποκ", "αποστ", "βουβ", "ξεθ", "ουλ", "πεθ", "πικρ", "ποτ", "σιχ", "χ"), false); @@ -274,11 +274,11 @@ public class GreekStemmer { return len; } - private static final CharArraySet exc8a = new CharArraySet(Version.LUCENE_50, + private static final CharArraySet exc8a = new CharArraySet(Version.LUCENE_CURRENT, Arrays.asList("τρ", "τσ"), false); - private static final CharArraySet exc8b = new CharArraySet(Version.LUCENE_50, + private static final CharArraySet exc8b = new CharArraySet(Version.LUCENE_CURRENT, Arrays.asList("βετερ", "βουλκ", "βραχμ", "γ", "δραδουμ", "θ", "καλπουζ", "καστελ", "κορμορ", "λαοπλ", "μωαμεθ", "μ", "μουσουλμ", "ν", "ουλ", "π", "πελεκ", "πλ", "πολισ", "πορτολ", "σαρακατσ", "σουλτ", @@ -337,7 +337,7 @@ public class GreekStemmer { return len; } - private static final CharArraySet exc9 = new CharArraySet(Version.LUCENE_50, + private static final CharArraySet exc9 = new CharArraySet(Version.LUCENE_CURRENT, Arrays.asList("αβαρ", "βεν", "εναρ", "αβρ", "αδ", "αθ", "αν", "απλ", "βαρον", "ντρ", "σκ", "κοπ", "μπορ", "νιφ", "παγ", "παρακαλ", "σερπ", "σκελ", "συρφ", "τοκ", "υ", "δ", "εμ", "θαρρ", "θ"), @@ -425,11 +425,11 @@ public class GreekStemmer { return len; } - private static final CharArraySet exc12a = new CharArraySet(Version.LUCENE_50, + private static final CharArraySet exc12a = new CharArraySet(Version.LUCENE_CURRENT, Arrays.asList("π", "απ", "συμπ", "ασυμπ", "ακαταπ", "αμεταμφ"), false); - private static final CharArraySet exc12b = new CharArraySet(Version.LUCENE_50, + private static final CharArraySet exc12b = new CharArraySet(Version.LUCENE_CURRENT, Arrays.asList("αλ", "αρ", "εκτελ", "ζ", "μ", "ξ", "παρακαλ", "αρ", "προ", "νισ"), false); @@ -449,7 +449,7 @@ public class GreekStemmer { return len; } - private static final CharArraySet exc13 = new CharArraySet(Version.LUCENE_50, + private static final CharArraySet exc13 = new CharArraySet(Version.LUCENE_CURRENT, Arrays.asList("διαθ", "θ", "παρακαταθ", "προσθ", "συνθ"), false); @@ -483,7 +483,7 @@ public class GreekStemmer { return len; } - private static final CharArraySet exc14 = new CharArraySet(Version.LUCENE_50, + private static final CharArraySet exc14 = new CharArraySet(Version.LUCENE_CURRENT, Arrays.asList("φαρμακ", "χαδ", "αγκ", "αναρρ", "βρομ", "εκλιπ", "λαμπιδ", "λεχ", "μ", "πατ", "ρ", "λ", "μεδ", "μεσαζ", "υποτειν", "αμ", "αιθ", "ανηκ", "δεσποζ", "ενδιαφερ", "δε", "δευτερευ", "καθαρευ", "πλε", @@ -521,7 +521,7 @@ public class GreekStemmer { return len; } - private static final CharArraySet exc15a = new CharArraySet(Version.LUCENE_50, + private static final CharArraySet exc15a = new CharArraySet(Version.LUCENE_CURRENT, Arrays.asList("αβαστ", "πολυφ", "αδηφ", "παμφ", "ρ", "ασπ", "αφ", "αμαλ", "αμαλλι", "ανυστ", "απερ", "ασπαρ", "αχαρ", "δερβεν", "δροσοπ", "ξεφ", "νεοπ", "νομοτ", "ολοπ", "ομοτ", "προστ", "προσωποπ", "συμπ", @@ -530,7 +530,7 @@ public class GreekStemmer { "ουλαμ", "ουρ", "π", "τρ", "μ"), false); - private static final CharArraySet exc15b = new CharArraySet(Version.LUCENE_50, + private static final CharArraySet exc15b = new CharArraySet(Version.LUCENE_CURRENT, Arrays.asList("ψοφ", "ναυλοχ"), false); @@ -567,7 +567,7 @@ public class GreekStemmer { return len; } - private static final CharArraySet exc16 = new CharArraySet(Version.LUCENE_50, + private static final CharArraySet exc16 = new CharArraySet(Version.LUCENE_CURRENT, Arrays.asList("ν", "χερσον", "δωδεκαν", "ερημον", "μεγαλον", "επταν"), false); @@ -587,7 +587,7 @@ public class GreekStemmer { return len; } - private static final CharArraySet exc17 = new CharArraySet(Version.LUCENE_50, + private static final CharArraySet exc17 = new CharArraySet(Version.LUCENE_CURRENT, Arrays.asList("ασβ", "σβ", "αχρ", "χρ", "απλ", "αειμν", "δυσχρ", "ευχρ", "κοινοχρ", "παλιμψ"), false); @@ -601,7 +601,7 @@ public class GreekStemmer { return len; } - private static final CharArraySet exc18 = new CharArraySet(Version.LUCENE_50, + private static final CharArraySet exc18 = new CharArraySet(Version.LUCENE_CURRENT, Arrays.asList("ν", "ρ", "σπι", "στραβομουτσ", "κακομουτσ", "εξων"), false); @@ -625,7 +625,7 @@ public class GreekStemmer { return len; } - private static final CharArraySet exc19 = new CharArraySet(Version.LUCENE_50, + private static final CharArraySet exc19 = new CharArraySet(Version.LUCENE_CURRENT, Arrays.asList("παρασουσ", "φ", "χ", "ωριοπλ", "αζ", "αλλοσουσ", "ασουσ"), false); diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/en/KStemmer.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/en/KStemmer.java index a0d5bc653ed..8f87d91dee9 100644 --- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/en/KStemmer.java +++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/en/KStemmer.java @@ -280,10 +280,7 @@ public class KStemmer { DictEntry defaultEntry; DictEntry entry; - CharArrayMap d = new CharArrayMap( - Version.LUCENE_50, 1000, false); - - d = new CharArrayMap(Version.LUCENE_50, 1000, false); + CharArrayMap d = new CharArrayMap(Version.LUCENE_CURRENT, 1000, false); for (int i = 0; i < exceptionWords.length; i++) { if (!d.containsKey(exceptionWords[i])) { entry = new DictEntry(exceptionWords[i], true); diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/hunspell/HunspellStemmer.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/hunspell/HunspellStemmer.java index b0ded28e1d1..ae2948284d6 100644 --- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/hunspell/HunspellStemmer.java +++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/hunspell/HunspellStemmer.java @@ -34,7 +34,7 @@ public class HunspellStemmer { private final int recursionCap; private final HunspellDictionary dictionary; private final StringBuilder segment = new StringBuilder(); - private CharacterUtils charUtils = CharacterUtils.getInstance(Version.LUCENE_40); + private CharacterUtils charUtils = CharacterUtils.getInstance(Version.LUCENE_CURRENT); /** * Constructs a new HunspellStemmer which will use the provided HunspellDictionary to create its stems. Uses the @@ -324,7 +324,8 @@ public class HunspellStemmer { InputStream affixInputStream = new FileInputStream(args[offset++]); InputStream dicInputStream = new FileInputStream(args[offset++]); - HunspellDictionary dictionary = new HunspellDictionary(affixInputStream, dicInputStream, Version.LUCENE_40, ignoreCase); + // :Post-Release-Update-Version.LUCENE_XY: + HunspellDictionary dictionary = new HunspellDictionary(affixInputStream, dicInputStream, Version.LUCENE_50, ignoreCase); affixInputStream.close(); dicInputStream.close(); diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/RemoveDuplicatesTokenFilter.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/RemoveDuplicatesTokenFilter.java index ac779812c67..e3c7a033bdb 100644 --- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/RemoveDuplicatesTokenFilter.java +++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/RemoveDuplicatesTokenFilter.java @@ -35,7 +35,7 @@ public final class RemoveDuplicatesTokenFilter extends TokenFilter { private final PositionIncrementAttribute posIncAttribute = addAttribute(PositionIncrementAttribute.class); // use a fixed version, as we don't care about case sensitivity. - private final CharArraySet previous = new CharArraySet(Version.LUCENE_50, 8, false); + private final CharArraySet previous = new CharArraySet(Version.LUCENE_CURRENT, 8, false); /** * Creates a new RemoveDuplicatesTokenFilter diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/pt/RSLPStemmerBase.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/pt/RSLPStemmerBase.java index 24cfed798b4..0915d536fb0 100644 --- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/pt/RSLPStemmerBase.java +++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/pt/RSLPStemmerBase.java @@ -134,7 +134,7 @@ public abstract class RSLPStemmerBase { if (!exceptions[i].endsWith(suffix)) throw new RuntimeException("useless exception '" + exceptions[i] + "' does not end with '" + suffix + "'"); } - this.exceptions = new CharArraySet(Version.LUCENE_50, + this.exceptions = new CharArraySet(Version.LUCENE_CURRENT, Arrays.asList(exceptions), false); } diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/synonym/SynonymFilterFactory.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/synonym/SynonymFilterFactory.java index 6aa504b976a..8c1de5ae048 100644 --- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/synonym/SynonymFilterFactory.java +++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/synonym/SynonymFilterFactory.java @@ -133,8 +133,8 @@ public class SynonymFilterFactory extends TokenFilterFactory implements Resource analyzer = new Analyzer() { @Override protected TokenStreamComponents createComponents(String fieldName, Reader reader) { - Tokenizer tokenizer = factory == null ? new WhitespaceTokenizer(Version.LUCENE_50, reader) : factory.create(reader); - TokenStream stream = ignoreCase ? new LowerCaseFilter(Version.LUCENE_50, tokenizer) : tokenizer; + Tokenizer tokenizer = factory == null ? new WhitespaceTokenizer(Version.LUCENE_CURRENT, reader) : factory.create(reader); + TokenStream stream = ignoreCase ? new LowerCaseFilter(Version.LUCENE_CURRENT, tokenizer) : tokenizer; return new TokenStreamComponents(tokenizer, stream); } }; @@ -201,7 +201,7 @@ public class SynonymFilterFactory extends TokenFilterFactory implements Resource private Analyzer loadAnalyzer(ResourceLoader loader, String cname) throws IOException { Class clazz = loader.findClass(cname, Analyzer.class); try { - Analyzer analyzer = clazz.getConstructor(Version.class).newInstance(Version.LUCENE_50); + Analyzer analyzer = clazz.getConstructor(Version.class).newInstance(Version.LUCENE_CURRENT); if (analyzer instanceof ResourceLoaderAware) { ((ResourceLoaderAware) analyzer).inform(loader); } diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestStopAnalyzer.java b/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestStopAnalyzer.java index e27adbb5883..0656c2832ae 100644 --- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestStopAnalyzer.java +++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestStopAnalyzer.java @@ -60,7 +60,7 @@ public class TestStopAnalyzer extends BaseTokenStreamTestCase { public void testStopList() throws IOException { CharArraySet stopWordsSet = new CharArraySet(TEST_VERSION_CURRENT, asSet("good", "test", "analyzer"), false); - StopAnalyzer newStop = new StopAnalyzer(Version.LUCENE_40, stopWordsSet); + StopAnalyzer newStop = new StopAnalyzer(TEST_VERSION_CURRENT, stopWordsSet); try (TokenStream stream = newStop.tokenStream("test", "This is a good test of the english stop analyzer")) { assertNotNull(stream); CharTermAttribute termAtt = stream.getAttribute(CharTermAttribute.class); diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestStopFilter.java b/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestStopFilter.java index 383fd7066d4..b363b0097f1 100644 --- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestStopFilter.java +++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestStopFilter.java @@ -94,7 +94,7 @@ public class TestStopFilter extends BaseTokenStreamTestCase { // LUCENE-3849: make sure after .end() we see the "ending" posInc public void testEndStopword() throws Exception { CharArraySet stopSet = StopFilter.makeStopSet(TEST_VERSION_CURRENT, "of"); - StopFilter stpf = new StopFilter(Version.LUCENE_40, new MockTokenizer(new StringReader("test of"), MockTokenizer.WHITESPACE, false), stopSet); + StopFilter stpf = new StopFilter(TEST_VERSION_CURRENT, new MockTokenizer(new StringReader("test of"), MockTokenizer.WHITESPACE, false), stopSet); assertTokenStreamContents(stpf, new String[] { "test" }, new int[] {0}, new int[] {4}, diff --git a/lucene/analysis/icu/src/java/overview.html b/lucene/analysis/icu/src/java/overview.html index 0c123bfa5d9..5411a4fcaee 100644 --- a/lucene/analysis/icu/src/java/overview.html +++ b/lucene/analysis/icu/src/java/overview.html @@ -14,6 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. --> + @@ -114,9 +115,9 @@ algorithm.

    Farsi Range Queries

       Collator collator = Collator.getInstance(new ULocale("ar"));
    -  ICUCollationKeyAnalyzer analyzer = new ICUCollationKeyAnalyzer(Version.LUCENE_40, collator);
    +  ICUCollationKeyAnalyzer analyzer = new ICUCollationKeyAnalyzer(Version.LUCENE_50, collator);
       RAMDirectory ramDir = new RAMDirectory();
    -  IndexWriter writer = new IndexWriter(ramDir, new IndexWriterConfig(Version.LUCENE_40, analyzer));
    +  IndexWriter writer = new IndexWriter(ramDir, new IndexWriterConfig(Version.LUCENE_50, analyzer));
       Document doc = new Document();
       doc.add(new Field("content", "\u0633\u0627\u0628", 
                         Field.Store.YES, Field.Index.ANALYZED));
    @@ -124,7 +125,7 @@ algorithm.
       writer.close();
       IndexSearcher is = new IndexSearcher(ramDir, true);
     
    -  QueryParser aqp = new QueryParser(Version.LUCENE_40, "content", analyzer);
    +  QueryParser aqp = new QueryParser(Version.LUCENE_50, "content", analyzer);
       aqp.setAnalyzeRangeTerms(true);
         
       // Unicode order would include U+0633 in [ U+062F - U+0698 ], but Farsi
    @@ -140,9 +141,9 @@ algorithm.
     

    Danish Sorting

       Analyzer analyzer 
    -    = new ICUCollationKeyAnalyzer(Version.LUCENE_40, Collator.getInstance(new ULocale("da", "dk")));
    +    = new ICUCollationKeyAnalyzer(Version.LUCENE_50, Collator.getInstance(new ULocale("da", "dk")));
       RAMDirectory indexStore = new RAMDirectory();
    -  IndexWriter writer = new IndexWriter(indexStore, new IndexWriterConfig(Version.LUCENE_40, analyzer));
    +  IndexWriter writer = new IndexWriter(indexStore, new IndexWriterConfig(Version.LUCENE_50, analyzer));
       String[] tracer = new String[] { "A", "B", "C", "D", "E" };
       String[] data = new String[] { "HAT", "HUT", "H\u00C5T", "H\u00D8T", "HOT" };
       String[] sortedTracerOrder = new String[] { "A", "E", "B", "D", "C" };
    @@ -168,15 +169,15 @@ algorithm.
     
       Collator collator = Collator.getInstance(new ULocale("tr", "TR"));
       collator.setStrength(Collator.PRIMARY);
    -  Analyzer analyzer = new ICUCollationKeyAnalyzer(Version.LUCENE_40, collator);
    +  Analyzer analyzer = new ICUCollationKeyAnalyzer(Version.LUCENE_50, collator);
       RAMDirectory ramDir = new RAMDirectory();
    -  IndexWriter writer = new IndexWriter(ramDir, new IndexWriterConfig(Version.LUCENE_40, analyzer));
    +  IndexWriter writer = new IndexWriter(ramDir, new IndexWriterConfig(Version.LUCENE_50, analyzer));
       Document doc = new Document();
       doc.add(new Field("contents", "DIGY", Field.Store.NO, Field.Index.ANALYZED));
       writer.addDocument(doc);
       writer.close();
       IndexSearcher is = new IndexSearcher(ramDir, true);
    -  QueryParser parser = new QueryParser(Version.LUCENE_40, "contents", analyzer);
    +  QueryParser parser = new QueryParser(Version.LUCENE_50, "contents", analyzer);
       Query query = parser.parse("d\u0131gy");   // U+0131: dotless i
       ScoreDoc[] result = is.search(query, null, 1000).scoreDocs;
       assertEquals("The index Term should be included.", 1, result.length);
    diff --git a/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/CreateIndexTask.java b/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/CreateIndexTask.java
    index 24087aad35f..9d0ee64ee2b 100644
    --- a/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/CreateIndexTask.java
    +++ b/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/CreateIndexTask.java
    @@ -97,7 +97,8 @@ public class CreateIndexTask extends PerfTask {
       }
       
       public static IndexWriterConfig createWriterConfig(Config config, PerfRunData runData, OpenMode mode, IndexCommit commit) {
    -    Version version = Version.valueOf(config.get("writer.version", Version.LUCENE_40.toString()));
    +    // :Post-Release-Update-Version.LUCENE_XY:
    +    Version version = Version.valueOf(config.get("writer.version", Version.LUCENE_50.toString()));
         IndexWriterConfig iwConf = new IndexWriterConfig(version, runData.getAnalyzer());
         iwConf.setOpenMode(mode);
         IndexDeletionPolicy indexDeletionPolicy = getIndexDeletionPolicy(config);
    diff --git a/lucene/benchmark/src/test/org/apache/lucene/benchmark/byTask/tasks/CreateIndexTaskTest.java b/lucene/benchmark/src/test/org/apache/lucene/benchmark/byTask/tasks/CreateIndexTaskTest.java
    index 3f1d0ccf040..4c1c8fd6285 100644
    --- a/lucene/benchmark/src/test/org/apache/lucene/benchmark/byTask/tasks/CreateIndexTaskTest.java
    +++ b/lucene/benchmark/src/test/org/apache/lucene/benchmark/byTask/tasks/CreateIndexTaskTest.java
    @@ -37,7 +37,8 @@ public class CreateIndexTaskTest extends BenchmarkTestCase {
     
       private PerfRunData createPerfRunData(String infoStreamValue) throws Exception {
         Properties props = new Properties();
    -    props.setProperty("writer.version", Version.LUCENE_40.toString());
    +    // :Post-Release-Update-Version.LUCENE_XY:
    +    props.setProperty("writer.version", Version.LUCENE_50.toString());
         props.setProperty("print.props", "false"); // don't print anything
         props.setProperty("directory", "RAMDirectory");
         if (infoStreamValue != null) {
    diff --git a/lucene/classification/src/java/org/apache/lucene/classification/utils/DatasetSplitter.java b/lucene/classification/src/java/org/apache/lucene/classification/utils/DatasetSplitter.java
    index 401da814b8d..5dbea2ee5c4 100644
    --- a/lucene/classification/src/java/org/apache/lucene/classification/utils/DatasetSplitter.java
    +++ b/lucene/classification/src/java/org/apache/lucene/classification/utils/DatasetSplitter.java
    @@ -69,6 +69,7 @@ public class DatasetSplitter {
                         Analyzer analyzer, String... fieldNames) throws IOException {
     
         // create IWs for train / test / cv IDXs
    +    // :Post-Release-Update-Version.LUCENE_XY:
         IndexWriter testWriter = new IndexWriter(testIndex, new IndexWriterConfig(Version.LUCENE_50, analyzer));
         IndexWriter cvWriter = new IndexWriter(crossValidationIndex, new IndexWriterConfig(Version.LUCENE_50, analyzer));
         IndexWriter trainingWriter = new IndexWriter(trainingIndex, new IndexWriterConfig(Version.LUCENE_50, analyzer));
    diff --git a/lucene/core/src/java/org/apache/lucene/store/NRTCachingDirectory.java b/lucene/core/src/java/org/apache/lucene/store/NRTCachingDirectory.java
    index 0d54d57f1c7..c4c092486ec 100644
    --- a/lucene/core/src/java/org/apache/lucene/store/NRTCachingDirectory.java
    +++ b/lucene/core/src/java/org/apache/lucene/store/NRTCachingDirectory.java
    @@ -50,7 +50,7 @@ import org.apache.lucene.util.IOUtils;
      * 
      *   Directory fsDir = FSDirectory.open(new File("/path/to/index"));
      *   NRTCachingDirectory cachedFSDir = new NRTCachingDirectory(fsDir, 5.0, 60.0);
    - *   IndexWriterConfig conf = new IndexWriterConfig(Version.LUCENE_32, analyzer);
    + *   IndexWriterConfig conf = new IndexWriterConfig(Version.LUCENE_50, analyzer);
      *   IndexWriter writer = new IndexWriter(cachedFSDir, conf);
      * 
    * diff --git a/lucene/core/src/test/org/apache/lucene/search/TestPhraseQuery.java b/lucene/core/src/test/org/apache/lucene/search/TestPhraseQuery.java index e78649a745e..d43c9b38cb5 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestPhraseQuery.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestPhraseQuery.java @@ -217,7 +217,7 @@ public class TestPhraseQuery extends LuceneTestCase { Directory directory = newDirectory(); Analyzer stopAnalyzer = new MockAnalyzer(random(), MockTokenizer.SIMPLE, true, MockTokenFilter.ENGLISH_STOPSET); RandomIndexWriter writer = new RandomIndexWriter(random(), directory, - newIndexWriterConfig( Version.LUCENE_40, stopAnalyzer)); + newIndexWriterConfig(TEST_VERSION_CURRENT, stopAnalyzer)); Document doc = new Document(); doc.add(newTextField("field", "the stop words are here", Field.Store.YES)); writer.addDocument(doc); diff --git a/lucene/demo/src/java/org/apache/lucene/demo/IndexFiles.java b/lucene/demo/src/java/org/apache/lucene/demo/IndexFiles.java index a4abadc21b8..5f1e48d66e8 100644 --- a/lucene/demo/src/java/org/apache/lucene/demo/IndexFiles.java +++ b/lucene/demo/src/java/org/apache/lucene/demo/IndexFiles.java @@ -86,8 +86,9 @@ public class IndexFiles { System.out.println("Indexing to directory '" + indexPath + "'..."); Directory dir = FSDirectory.open(new File(indexPath)); - Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_40); - IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_40, analyzer); + // :Post-Release-Update-Version.LUCENE_XY: + Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_50); + IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_50, analyzer); if (create) { // Create a new index in the directory, removing any diff --git a/lucene/demo/src/java/org/apache/lucene/demo/SearchFiles.java b/lucene/demo/src/java/org/apache/lucene/demo/SearchFiles.java index 7bb22f6ccbd..621ecf484c7 100644 --- a/lucene/demo/src/java/org/apache/lucene/demo/SearchFiles.java +++ b/lucene/demo/src/java/org/apache/lucene/demo/SearchFiles.java @@ -90,7 +90,8 @@ public class SearchFiles { IndexReader reader = DirectoryReader.open(FSDirectory.open(new File(index))); IndexSearcher searcher = new IndexSearcher(reader); - Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_40); + // :Post-Release-Update-Version.LUCENE_XY: + Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_50); BufferedReader in = null; if (queries != null) { @@ -98,7 +99,8 @@ public class SearchFiles { } else { in = new BufferedReader(new InputStreamReader(System.in, "UTF-8")); } - QueryParser parser = new QueryParser(Version.LUCENE_40, field, analyzer); + // :Post-Release-Update-Version.LUCENE_XY: + QueryParser parser = new QueryParser(Version.LUCENE_50, field, analyzer); while (true) { if (queries == null && queryString == null) { // prompt the user System.out.println("Enter query: "); diff --git a/lucene/demo/src/java/org/apache/lucene/demo/facet/FacetExamples.java b/lucene/demo/src/java/org/apache/lucene/demo/facet/FacetExamples.java index 23113960fe8..2e4844c6a31 100644 --- a/lucene/demo/src/java/org/apache/lucene/demo/facet/FacetExamples.java +++ b/lucene/demo/src/java/org/apache/lucene/demo/facet/FacetExamples.java @@ -25,7 +25,8 @@ import org.apache.lucene.util.Version; * @lucene.experimental */ public interface FacetExamples { - + + // :Post-Release-Update-Version.LUCENE_XY: /** The Lucene {@link Version} used by the example code. */ public static final Version EXAMPLES_VER = Version.LUCENE_50; diff --git a/lucene/demo/src/java/org/apache/lucene/demo/xmlparser/FormBasedXmlQueryDemo.java b/lucene/demo/src/java/org/apache/lucene/demo/xmlparser/FormBasedXmlQueryDemo.java index acef8a55730..bda9d3f1dad 100644 --- a/lucene/demo/src/java/org/apache/lucene/demo/xmlparser/FormBasedXmlQueryDemo.java +++ b/lucene/demo/src/java/org/apache/lucene/demo/xmlparser/FormBasedXmlQueryDemo.java @@ -133,7 +133,7 @@ public class FormBasedXmlQueryDemo extends HttpServlet { private void openExampleIndex() throws IOException { //Create a RAM-based index from our test data file RAMDirectory rd = new RAMDirectory(); - IndexWriterConfig iwConfig = new IndexWriterConfig(Version.LUCENE_40, analyzer); + IndexWriterConfig iwConfig = new IndexWriterConfig(Version.LUCENE_CURRENT, analyzer); IndexWriter writer = new IndexWriter(rd, iwConfig); InputStream dataIn = getServletContext().getResourceAsStream("/WEB-INF/data.tsv"); BufferedReader br = new BufferedReader(new InputStreamReader(dataIn, IOUtils.CHARSET_UTF_8)); diff --git a/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/directory/DirectoryTaxonomyWriter.java b/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/directory/DirectoryTaxonomyWriter.java index a269f5ccb92..39375655248 100644 --- a/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/directory/DirectoryTaxonomyWriter.java +++ b/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/directory/DirectoryTaxonomyWriter.java @@ -299,7 +299,8 @@ public class DirectoryTaxonomyWriter implements TaxonomyWriter { protected IndexWriterConfig createIndexWriterConfig(OpenMode openMode) { // TODO: should we use a more optimized Codec, e.g. Pulsing (or write custom)? // The taxonomy has a unique structure, where each term is associated with one document - + + // :Post-Release-Update-Version.LUCENE_XY: // Make sure we use a MergePolicy which always merges adjacent segments and thus // keeps the doc IDs ordered as well (this is crucial for the taxonomy index). return new IndexWriterConfig(Version.LUCENE_50, null).setOpenMode(openMode).setMergePolicy( diff --git a/lucene/queryparser/src/test/org/apache/lucene/queryparser/xml/TestParser.java b/lucene/queryparser/src/test/org/apache/lucene/queryparser/xml/TestParser.java index 9f5b6fe64eb..eaa71db5fe0 100644 --- a/lucene/queryparser/src/test/org/apache/lucene/queryparser/xml/TestParser.java +++ b/lucene/queryparser/src/test/org/apache/lucene/queryparser/xml/TestParser.java @@ -65,7 +65,7 @@ public class TestParser extends LuceneTestCase { BufferedReader d = new BufferedReader(new InputStreamReader( TestParser.class.getResourceAsStream("reuters21578.txt"), "US-ASCII")); dir = newDirectory(); - IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(Version.LUCENE_40, analyzer)); + IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(TEST_VERSION_CURRENT, analyzer)); String line = d.readLine(); while (line != null) { int endOfDate = line.indexOf('\t'); diff --git a/lucene/suggest/src/java/org/apache/lucene/search/suggest/analyzing/FreeTextSuggester.java b/lucene/suggest/src/java/org/apache/lucene/search/suggest/analyzing/FreeTextSuggester.java index 797acaea959..e901ef7f16e 100644 --- a/lucene/suggest/src/java/org/apache/lucene/search/suggest/analyzing/FreeTextSuggester.java +++ b/lucene/suggest/src/java/org/apache/lucene/search/suggest/analyzing/FreeTextSuggester.java @@ -301,7 +301,7 @@ public class FreeTextSuggester extends Lookup { Directory dir = FSDirectory.open(tempIndexPath); - IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_46, indexAnalyzer); + IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_CURRENT, indexAnalyzer); iwc.setOpenMode(IndexWriterConfig.OpenMode.CREATE); iwc.setRAMBufferSizeMB(ramBufferSizeMB); IndexWriter writer = new IndexWriter(dir, iwc); diff --git a/lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java index eb12f54eb13..862a9f459d2 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java +++ b/lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java @@ -228,6 +228,7 @@ public abstract class LuceneTestCase extends Assert { // for all suites ever since. // ----------------------------------------------------------------- + // :Post-Release-Update-Version.LUCENE_XY: /** * Use this constant when creating Analyzers and any other version-dependent stuff. *

    NOTE: Change this when development starts for new Lucene version: diff --git a/solr/contrib/analysis-extras/src/java/org/apache/solr/schema/ICUCollationField.java b/solr/contrib/analysis-extras/src/java/org/apache/solr/schema/ICUCollationField.java index 7c33a3dd335..c1b2ce7c09d 100644 --- a/solr/contrib/analysis-extras/src/java/org/apache/solr/schema/ICUCollationField.java +++ b/solr/contrib/analysis-extras/src/java/org/apache/solr/schema/ICUCollationField.java @@ -187,8 +187,7 @@ public class ICUCollationField extends FieldType { rbc.setVariableTop(variableTop); } - // we use 4.0 because it ensures we just encode the pure byte[] keys. - analyzer = new ICUCollationKeyAnalyzer(Version.LUCENE_40, collator); + analyzer = new ICUCollationKeyAnalyzer(Version.LUCENE_CURRENT, collator); } /** diff --git a/solr/core/src/java/org/apache/solr/schema/CollationField.java b/solr/core/src/java/org/apache/solr/schema/CollationField.java index 5b46159bae4..891e6736139 100644 --- a/solr/core/src/java/org/apache/solr/schema/CollationField.java +++ b/solr/core/src/java/org/apache/solr/schema/CollationField.java @@ -147,8 +147,7 @@ public class CollationField extends FieldType { else throw new SolrException(ErrorCode.SERVER_ERROR, "Invalid decomposition: " + decomposition); } - // we use 4.0 because it ensures we just encode the pure byte[] keys. - analyzer = new CollationKeyAnalyzer(Version.LUCENE_40, collator); + analyzer = new CollationKeyAnalyzer(Version.LUCENE_CURRENT, collator); } /** diff --git a/solr/core/src/test/org/apache/solr/core/SolrCoreCheckLockOnStartupTest.java b/solr/core/src/test/org/apache/solr/core/SolrCoreCheckLockOnStartupTest.java index e07b5ed6b75..9051bf295ce 100644 --- a/solr/core/src/test/org/apache/solr/core/SolrCoreCheckLockOnStartupTest.java +++ b/solr/core/src/test/org/apache/solr/core/SolrCoreCheckLockOnStartupTest.java @@ -43,7 +43,7 @@ public class SolrCoreCheckLockOnStartupTest extends SolrTestCaseJ4 { //explicitly creates the temp dataDir so we know where the index will be located createTempDir(); - IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LUCENE_40, null); + IndexWriterConfig indexWriterConfig = new IndexWriterConfig(TEST_VERSION_CURRENT, null); Directory directory = newFSDirectory(new File(dataDir, "index")); //creates a new index on the known location new IndexWriter( @@ -58,7 +58,7 @@ public class SolrCoreCheckLockOnStartupTest extends SolrTestCaseJ4 { Directory directory = newFSDirectory(new File(dataDir, "index"), new SimpleFSLockFactory()); //creates a new IndexWriter without releasing the lock yet - IndexWriter indexWriter = new IndexWriter(directory, new IndexWriterConfig(Version.LUCENE_40, null)); + IndexWriter indexWriter = new IndexWriter(directory, new IndexWriterConfig(TEST_VERSION_CURRENT, null)); ignoreException("locked"); try { @@ -84,7 +84,7 @@ public class SolrCoreCheckLockOnStartupTest extends SolrTestCaseJ4 { log.info("Acquiring lock on {}", indexDir.getAbsolutePath()); Directory directory = newFSDirectory(indexDir, new NativeFSLockFactory()); //creates a new IndexWriter without releasing the lock yet - IndexWriter indexWriter = new IndexWriter(directory, new IndexWriterConfig(Version.LUCENE_40, null)); + IndexWriter indexWriter = new IndexWriter(directory, new IndexWriterConfig(TEST_VERSION_CURRENT, null)); ignoreException("locked"); try { diff --git a/solr/core/src/test/org/apache/solr/core/TestArbitraryIndexDir.java b/solr/core/src/test/org/apache/solr/core/TestArbitraryIndexDir.java index d16456efcef..567b1bec9ce 100644 --- a/solr/core/src/test/org/apache/solr/core/TestArbitraryIndexDir.java +++ b/solr/core/src/test/org/apache/solr/core/TestArbitraryIndexDir.java @@ -118,7 +118,7 @@ public class TestArbitraryIndexDir extends AbstractSolrTestCase{ Directory dir = newFSDirectory(newDir); IndexWriter iw = new IndexWriter( dir, - new IndexWriterConfig(Version.LUCENE_40, new StandardAnalyzer(Version.LUCENE_40)) + new IndexWriterConfig(TEST_VERSION_CURRENT, new StandardAnalyzer(TEST_VERSION_CURRENT)) ); Document doc = new Document(); doc.add(new TextField("id", "2", Field.Store.YES)); diff --git a/solr/core/src/test/org/apache/solr/search/TestStressLucene.java b/solr/core/src/test/org/apache/solr/search/TestStressLucene.java index 38809f567c6..f27e363d115 100644 --- a/solr/core/src/test/org/apache/solr/search/TestStressLucene.java +++ b/solr/core/src/test/org/apache/solr/search/TestStressLucene.java @@ -101,7 +101,7 @@ public class TestStressLucene extends TestRTGBase { // RAMDirectory dir = new RAMDirectory(); - // final IndexWriter writer = new IndexWriter(dir, new IndexWriterConfig(Version.LUCENE_40, new WhitespaceAnalyzer(Version.LUCENE_40))); + // final IndexWriter writer = new IndexWriter(dir, new IndexWriterConfig(TEST_VERSION_CURRENT, new WhitespaceAnalyzer(TEST_VERSION_CURRENT))); Directory dir = newDirectory(); diff --git a/solr/core/src/test/org/apache/solr/spelling/SimpleQueryConverter.java b/solr/core/src/test/org/apache/solr/spelling/SimpleQueryConverter.java index 15ec62f6a2f..69d70ab644a 100644 --- a/solr/core/src/test/org/apache/solr/spelling/SimpleQueryConverter.java +++ b/solr/core/src/test/org/apache/solr/spelling/SimpleQueryConverter.java @@ -25,7 +25,7 @@ import org.apache.lucene.analysis.tokenattributes.OffsetAttribute; import org.apache.lucene.analysis.tokenattributes.PayloadAttribute; import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute; import org.apache.lucene.analysis.tokenattributes.TypeAttribute; -import org.apache.lucene.util.Version; +import org.apache.lucene.util.LuceneTestCase; import java.util.Collection; import java.util.HashSet; @@ -41,7 +41,7 @@ class SimpleQueryConverter extends SpellingQueryConverter { @Override public Collection convert(String origQuery) { Collection result = new HashSet(); - WhitespaceAnalyzer analyzer = new WhitespaceAnalyzer(Version.LUCENE_40); + WhitespaceAnalyzer analyzer = new WhitespaceAnalyzer(LuceneTestCase.TEST_VERSION_CURRENT); try (TokenStream ts = analyzer.tokenStream("", origQuery)) { // TODO: support custom attributes From 4b8d5f0d51da075e2856665e188006b4d9368a91 Mon Sep 17 00:00:00 2001 From: Shalin Shekhar Mangar Date: Tue, 10 Dec 2013 11:48:30 +0000 Subject: [PATCH 207/223] SOLR-5308: Handle route keys with bit separators. Route docs to target shard leader directly. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1549821 13f79535-47bb-0310-9956-ffa450edef68 --- .../cloud/OverseerCollectionProcessor.java | 5 +- .../processor/DistributedUpdateProcessor.java | 7 +- .../solr/cloud/MigrateRouteKeyTest.java | 205 +++++++++++------- 3 files changed, 129 insertions(+), 88 deletions(-) diff --git a/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java b/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java index 68ed988d119..9d427dca8a0 100644 --- a/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java +++ b/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java @@ -53,6 +53,7 @@ import org.apache.solr.common.util.StrUtils; import org.apache.solr.handler.component.ShardHandler; import org.apache.solr.handler.component.ShardRequest; import org.apache.solr.handler.component.ShardResponse; +import org.apache.solr.update.SolrIndexSplitter; import org.apache.zookeeper.KeeperException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -1145,7 +1146,7 @@ public class OverseerCollectionProcessor implements Runnable, ClosableThread { Overseer.QUEUE_OPERATION, Overseer.ADD_ROUTING_RULE, COLLECTION_PROP, sourceCollection.getName(), SHARD_ID_PROP, sourceSlice.getName(), - "routeKey", splitKey, + "routeKey", SolrIndexSplitter.getRouteKey(splitKey) + "!", "range", splitRange.toString(), "targetCollection", targetCollection.getName(), "expireAt", String.valueOf(System.currentTimeMillis() + timeout)); @@ -1161,7 +1162,7 @@ public class OverseerCollectionProcessor implements Runnable, ClosableThread { Thread.sleep(100); Map rules = zkStateReader.getClusterState().getSlice(sourceCollection.getName(), sourceSlice.getName()).getRoutingRules(); if (rules != null) { - RoutingRule rule = rules.get(splitKey); + RoutingRule rule = rules.get(SolrIndexSplitter.getRouteKey(splitKey) + "!"); if (rule != null && rule.getRouteRanges().contains(splitRange)) { added = true; break; diff --git a/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java b/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java index e2db6812b9c..de2b0885262 100644 --- a/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java +++ b/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java @@ -396,13 +396,12 @@ public class DistributedUpdateProcessor extends UpdateRequestProcessor { for (DocRouter.Range range : ranges) { if (range.includes(hash)) { if (nodes == null) nodes = new ArrayList(); - Collection activeSlices = cstate.getActiveSlices(rule.getTargetCollectionName()); + DocCollection targetColl = cstate.getCollection(rule.getTargetCollectionName()); + Collection activeSlices = targetColl.getRouter().getSearchSlicesSingle(id, null, targetColl); if (activeSlices == null || activeSlices.isEmpty()) { throw new SolrException(ErrorCode.SERVER_ERROR, - "No active slices found for target collection: " + rule.getTargetCollectionName()); + "No active slices serving " + id + " found for target collection: " + rule.getTargetCollectionName()); } - // it doesn't matter where we forward it so just choose the first one - // todo this can be optimized Replica targetLeader = cstate.getLeader(rule.getTargetCollectionName(), activeSlices.iterator().next().getName()); nodes.add(new StdNode(new ZkCoreNodeProps(targetLeader))); break; diff --git a/solr/core/src/test/org/apache/solr/cloud/MigrateRouteKeyTest.java b/solr/core/src/test/org/apache/solr/cloud/MigrateRouteKeyTest.java index 7774a759ec2..71d48d25e7b 100644 --- a/solr/core/src/test/org/apache/solr/cloud/MigrateRouteKeyTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/MigrateRouteKeyTest.java @@ -32,6 +32,7 @@ import org.apache.solr.common.cloud.ZkNodeProps; import org.apache.solr.common.params.CollectionParams; import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.update.DirectUpdateHandler2; +import org.apache.zookeeper.KeeperException; import org.junit.After; import org.junit.Before; @@ -89,21 +90,57 @@ public class MigrateRouteKeyTest extends BasicDistributedZkTest { public void doTest() throws Exception { waitForThingsToLevelOut(15); - final String splitKey = "a!"; - final int[] splitKeyCount = new int[1]; - for (int id = 0; id < 26*3; id++) { - String shardKey = "" + (char) ('a' + (id % 26)); // See comment in ShardRoutingTest for hash distribution + multipleShardMigrateTest(); + printLayout(); + } + + private boolean waitForRuleToExpire(String splitKey, long finishTime) throws KeeperException, InterruptedException, SolrServerException, IOException { + ClusterState state;Slice slice; + boolean ruleRemoved = false; + while (System.currentTimeMillis() - finishTime < 60000) { + getCommonCloudSolrServer().getZkStateReader().updateClusterState(true); + state = getCommonCloudSolrServer().getZkStateReader().getClusterState(); + slice = state.getSlice(AbstractDistribZkTestBase.DEFAULT_COLLECTION, SHARD2); + Map routingRules = slice.getRoutingRules(); + if (routingRules == null || routingRules.isEmpty() || !routingRules.containsKey(splitKey)) { + ruleRemoved = true; + break; + } SolrInputDocument doc = new SolrInputDocument(); - doc.addField("id", shardKey + "!" + id); - doc.addField("n_ti", id); + doc.addField("id", splitKey + System.currentTimeMillis()); cloudClient.add(doc); - if (splitKey.equals(shardKey + "!")) - splitKeyCount[0]++; + Thread.sleep(1000); } - assertTrue(splitKeyCount[0] > 0); + return ruleRemoved; + } - String targetCollection = "migrate_routekey_test_targetCollection"; + private void invokeMigrateApi(String sourceCollection, String splitKey, String targetCollection) throws SolrServerException, IOException { + ModifiableSolrParams params = new ModifiableSolrParams(); + params.set("action", CollectionParams.CollectionAction.MIGRATE.toString()); + params.set("collection", sourceCollection); + params.set("target.collection", targetCollection); + params.set("split.key", splitKey); + params.set("forward.timeout", 45); + invoke(params); + } + + private void invoke(ModifiableSolrParams params) throws SolrServerException, IOException { + SolrRequest request = new QueryRequest(params); + request.setPath("/admin/collections"); + + String baseUrl = ((HttpSolrServer) shardToJetty.get(SHARD1).get(0).client.solrClient) + .getBaseURL(); + baseUrl = baseUrl.substring(0, baseUrl.length() - "collection1".length()); + + HttpSolrServer baseServer = new HttpSolrServer(baseUrl); + baseServer.setConnectionTimeout(15000); + baseServer.setSoTimeout(60000 * 5); + baseServer.request(request); + baseServer.shutdown(); + } + + private void createCollection(String targetCollection) throws Exception { HashMap> collectionInfos = new HashMap>(); CloudSolrServer client = null; try { @@ -122,38 +159,34 @@ public class MigrateRouteKeyTest extends BasicDistributedZkTest { checkForCollection(targetCollection, list, null); waitForRecoveriesToFinish(targetCollection, false); + } - class Indexer extends Thread { - final int seconds; - - public Indexer(int seconds) { - this.seconds = seconds; - } - - @Override - public void run() { - long start = System.currentTimeMillis(); - for (int id = 26*3; id < 500 && System.currentTimeMillis() - start <= seconds*1000; id++) { - String shardKey = "" + (char) ('a' + (id % 26)); // See comment in ShardRoutingTest for hash distribution - SolrInputDocument doc = new SolrInputDocument(); - doc.addField("id", shardKey + "!" + id); - doc.addField("n_ti", id); - try { - cloudClient.add(doc); - if (splitKey.equals(shardKey + "!")) - splitKeyCount[0]++; - } catch (Exception e) { - log.error("Exception while adding document id: " + doc.getField("id"), e); - } - try { - Thread.sleep(50); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - } + private void multipleShardMigrateTest() throws Exception { + del("*:*"); + commit(); + assertTrue(cloudClient.query(new SolrQuery("*:*")).getResults().getNumFound() == 0); + final String splitKey = "a"; + final int BIT_SEP = 1; + final int[] splitKeyCount = new int[1]; + for (int id = 0; id < 26*3; id++) { + String shardKey = "" + (char) ('a' + (id % 26)); // See comment in ShardRoutingTest for hash distribution + String key = shardKey; + if (splitKey.equals(shardKey)) { + key += "/" + BIT_SEP; // spread it over half the collection } + SolrInputDocument doc = new SolrInputDocument(); + doc.addField("id", key + "!" + id); + doc.addField("n_ti", id); + cloudClient.add(doc); + if (splitKey.equals(shardKey)) + splitKeyCount[0]++; } - Thread indexer = new Indexer(30); + assertTrue(splitKeyCount[0] > 0); + + String targetCollection = "migrate_multipleshardtest_targetCollection"; + createCollection(targetCollection); + + Indexer indexer = new Indexer(cloudClient, splitKey, 1, 30); indexer.start(); String url = CustomCollectionTest.getUrlFromZk(getCommonCloudSolrServer().getZkStateReader().getClusterState(), targetCollection); @@ -162,68 +195,76 @@ public class MigrateRouteKeyTest extends BasicDistributedZkTest { SolrQuery solrQuery = new SolrQuery("*:*"); assertEquals("DocCount on target collection does not match", 0, collectionClient.query(solrQuery).getResults().getNumFound()); - ModifiableSolrParams params = new ModifiableSolrParams(); - params.set("action", CollectionParams.CollectionAction.MIGRATE.toString()); - params.set("collection", AbstractDistribZkTestBase.DEFAULT_COLLECTION); - params.set("target.collection", targetCollection); - params.set("split.key", splitKey); - params.set("forward.timeout", 45); - - SolrRequest request = new QueryRequest(params); - request.setPath("/admin/collections"); - - String baseUrl = ((HttpSolrServer) shardToJetty.get(SHARD1).get(0).client.solrClient) - .getBaseURL(); - baseUrl = baseUrl.substring(0, baseUrl.length() - "collection1".length()); - - HttpSolrServer baseServer = new HttpSolrServer(baseUrl); - baseServer.setConnectionTimeout(15000); - baseServer.setSoTimeout(60000 * 5); - baseServer.request(request); - baseServer.shutdown(); + invokeMigrateApi(AbstractDistribZkTestBase.DEFAULT_COLLECTION, splitKey + "/" + BIT_SEP + "!", targetCollection); long finishTime = System.currentTimeMillis(); indexer.join(); + splitKeyCount[0] += indexer.getSplitKeyCount(); try { - cloudClient.deleteById("a!104"); + cloudClient.deleteById("a/" + BIT_SEP + "!104"); splitKeyCount[0]--; } catch (Exception e) { - log.warn("Error deleting document a!104", e); + log.warn("Error deleting document a/" + BIT_SEP + "!104", e); } cloudClient.commit(); collectionClient.commit(); + solrQuery = new SolrQuery("*:*").setRows(1000); + QueryResponse response = collectionClient.query(solrQuery); + log.info("Response from target collection: " + response); + assertEquals("DocCount on target collection does not match", splitKeyCount[0], response.getResults().getNumFound()); + getCommonCloudSolrServer().getZkStateReader().updateClusterState(true); ClusterState state = getCommonCloudSolrServer().getZkStateReader().getClusterState(); Slice slice = state.getSlice(AbstractDistribZkTestBase.DEFAULT_COLLECTION, SHARD2); assertNotNull("Routing rule map is null", slice.getRoutingRules()); assertFalse("Routing rule map is empty", slice.getRoutingRules().isEmpty()); - assertNotNull("No routing rule exists for route key: " + splitKey, slice.getRoutingRules().get(splitKey)); + assertNotNull("No routing rule exists for route key: " + splitKey, slice.getRoutingRules().get(splitKey + "!")); - boolean ruleRemoved = false; - while (System.currentTimeMillis() - finishTime < 60000) { - getCommonCloudSolrServer().getZkStateReader().updateClusterState(true); - state = getCommonCloudSolrServer().getZkStateReader().getClusterState(); - slice = state.getSlice(AbstractDistribZkTestBase.DEFAULT_COLLECTION, SHARD2); - Map routingRules = slice.getRoutingRules(); - if (routingRules == null || routingRules.isEmpty() || !routingRules.containsKey(splitKey)) { - ruleRemoved = true; - break; - } - SolrInputDocument doc = new SolrInputDocument(); - doc.addField("id", splitKey + System.currentTimeMillis()); - cloudClient.add(doc); - Thread.sleep(1000); + boolean ruleRemoved = waitForRuleToExpire(splitKey, finishTime); + assertTrue("Routing rule was not expired", ruleRemoved); + } + + static class Indexer extends Thread { + final int seconds; + final CloudSolrServer cloudClient; + final String splitKey; + int splitKeyCount = 0; + final int bitSep; + + public Indexer(CloudSolrServer cloudClient, String splitKey, int bitSep, int seconds) { + this.seconds = seconds; + this.cloudClient = cloudClient; + this.splitKey = splitKey; + this.bitSep = bitSep; } - assertTrue("Routing rule was not expired", ruleRemoved); + @Override + public void run() { + long start = System.currentTimeMillis(); + for (int id = 26*3; id < 500 && System.currentTimeMillis() - start <= seconds*1000; id++) { + String shardKey = "" + (char) ('a' + (id % 26)); // See comment in ShardRoutingTest for hash distribution + SolrInputDocument doc = new SolrInputDocument(); + doc.addField("id", shardKey + (bitSep != -1 ? "/" + bitSep : "") + "!" + id); + doc.addField("n_ti", id); + try { + cloudClient.add(doc); + if (splitKey.equals(shardKey)) + splitKeyCount++; + } catch (Exception e) { + log.error("Exception while adding document id: " + doc.getField("id"), e); + } + try { + Thread.sleep(50); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + } - solrQuery = new SolrQuery("*:*").setRows(1000); - QueryResponse response = collectionClient.query(solrQuery); - log.info("Response from target collection: " + response); - assertEquals("DocCount on shard1_0 does not match", splitKeyCount[0], response.getResults().getNumFound()); - - printLayout(); + public int getSplitKeyCount() { + return splitKeyCount; + } } } From 05634cff5d6a4cef9d728a76c44662fbf3b88651 Mon Sep 17 00:00:00 2001 From: Steven Rowe Date: Tue, 10 Dec 2013 15:50:38 +0000 Subject: [PATCH 208/223] LUCENE-5360: Add support for developing in Netbeans IDE. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1549872 13f79535-47bb-0310-9956-ffa450edef68 --- .gitignore | 2 + build.xml | 36 ++++ dev-tools/netbeans/nb-project.xsl | 280 ++++++++++++++++++++++++++++++ lucene/CHANGES.txt | 3 + 4 files changed, 321 insertions(+) create mode 100644 dev-tools/netbeans/nb-project.xsl diff --git a/.gitignore b/.gitignore index a010ab8bb30..88502af3202 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,8 @@ /bin /bin.* /pom.xml +/nbproject +/nb-build # ./lucene diff --git a/build.xml b/build.xml index 01467634853..24ebc18c1dc 100644 --- a/build.xml +++ b/build.xml @@ -191,6 +191,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev-tools/netbeans/nb-project.xsl b/dev-tools/netbeans/nb-project.xsl new file mode 100644 index 00000000000..a61c733b44d --- /dev/null +++ b/dev-tools/netbeans/nb-project.xsl @@ -0,0 +1,280 @@ + + + + + + + + + + + + + org.netbeans.modules.ant.freeform + + + lucene + + + + + + + + + + + + + + + + java + + + + + + + + + + + + + + + + + + + java + + + + + + + + + + + + + + + + + + + + + + + + + + + compile + + + clean + + + documentation + + + test + + + clean + compile + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + build.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + : + + + : + + + + + + : + + + + nb-build/classes + 1.7 + + + + + + + + + + + + + + + + + + + + + + + + + : + + + : + + + + + + : + + + + nb-build/test-classes + 1.7 + + + + + + diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 072cdd2e352..681246b3309 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -95,6 +95,9 @@ Build Unicode 6.3; update UAX29URLEmailTokenizer's recognized top level domains in URLs and Emails from the IANA Root Zone Database. (Steve Rowe) + +* LUCENE-5360: Add support for developing in Netbeans IDE. + (Michal Hlavac via Steve Rowe) Bug fixes From 09d6a3c73c0ca64a3e87ed19b9ffd501e41a78a8 Mon Sep 17 00:00:00 2001 From: Uwe Schindler Date: Wed, 11 Dec 2013 11:39:27 +0000 Subject: [PATCH 209/223] reenable javadocs on JDK8 git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1550110 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/common-build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lucene/common-build.xml b/lucene/common-build.xml index 6d79bb93090..7d5c933a608 100644 --- a/lucene/common-build.xml +++ b/lucene/common-build.xml @@ -336,7 +336,7 @@ - + From bee606588d3ae2f310bcb19eb0ad770f7f8d52a4 Mon Sep 17 00:00:00 2001 From: Shalin Shekhar Mangar Date: Wed, 11 Dec 2013 14:12:26 +0000 Subject: [PATCH 210/223] SOLR-5492: Added shardAddress in grouping query responses. Added tests. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1550143 13f79535-47bb-0310-9956-ffa450edef68 --- .../SearchGroupShardResponseProcessor.java | 4 +++- .../TopGroupsShardResponseProcessor.java | 4 +++- .../test/org/apache/solr/TestDistributedSearch.java | 1 + .../org/apache/solr/cloud/CustomCollectionTest.java | 12 ++++++++++++ 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/solr/core/src/java/org/apache/solr/search/grouping/distributed/responseprocessor/SearchGroupShardResponseProcessor.java b/solr/core/src/java/org/apache/solr/search/grouping/distributed/responseprocessor/SearchGroupShardResponseProcessor.java index 8dea1d318ed..ce06e4f8155 100644 --- a/solr/core/src/java/org/apache/solr/search/grouping/distributed/responseprocessor/SearchGroupShardResponseProcessor.java +++ b/solr/core/src/java/org/apache/solr/search/grouping/distributed/responseprocessor/SearchGroupShardResponseProcessor.java @@ -92,7 +92,9 @@ public class SearchGroupShardResponseProcessor implements ShardResponseProcessor if (srsp.getSolrResponse() != null) { nl.add("time", srsp.getSolrResponse().getElapsedTime()); } - + if (srsp.getShardAddress() != null) { + nl.add("shardAddress", srsp.getShardAddress()); + } shardInfo.add(srsp.getShard(), nl); } if (rb.req.getParams().getBool(ShardParams.SHARDS_TOLERANT, false) && srsp.getException() != null) { diff --git a/solr/core/src/java/org/apache/solr/search/grouping/distributed/responseprocessor/TopGroupsShardResponseProcessor.java b/solr/core/src/java/org/apache/solr/search/grouping/distributed/responseprocessor/TopGroupsShardResponseProcessor.java index 1f41b073979..dd9bdbb62cd 100644 --- a/solr/core/src/java/org/apache/solr/search/grouping/distributed/responseprocessor/TopGroupsShardResponseProcessor.java +++ b/solr/core/src/java/org/apache/solr/search/grouping/distributed/responseprocessor/TopGroupsShardResponseProcessor.java @@ -108,7 +108,9 @@ public class TopGroupsShardResponseProcessor implements ShardResponseProcessor { if (srsp.getSolrResponse() != null) { individualShardInfo.add("time", srsp.getSolrResponse().getElapsedTime()); } - + if (srsp.getShardAddress() != null) { + individualShardInfo.add("shardAddress", srsp.getShardAddress()); + } shardInfo.add(srsp.getShard(), individualShardInfo); } if (rb.req.getParams().getBool(ShardParams.SHARDS_TOLERANT, false) && srsp.getException() != null) { diff --git a/solr/core/src/test/org/apache/solr/TestDistributedSearch.java b/solr/core/src/test/org/apache/solr/TestDistributedSearch.java index d0887f4f7c8..07655725e21 100644 --- a/solr/core/src/test/org/apache/solr/TestDistributedSearch.java +++ b/solr/core/src/test/org/apache/solr/TestDistributedSearch.java @@ -507,6 +507,7 @@ public class TestDistributedSearch extends BaseDistributedSearchTestCase { // make sure that it responded if it's up if (upShards.contains(s)) { assertTrue("Expected to find numFound in the up shard info",info.get("numFound") != null); + assertTrue("Expected to find shardAddress in the up shard info",info.get("shardAddress") != null); } else { assertTrue("Expected to find error in the down shard info",info.get("error") != null); diff --git a/solr/core/src/test/org/apache/solr/cloud/CustomCollectionTest.java b/solr/core/src/test/org/apache/solr/cloud/CustomCollectionTest.java index a84c9ea99b3..50ec13b2c5b 100644 --- a/solr/core/src/test/org/apache/solr/cloud/CustomCollectionTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/CustomCollectionTest.java @@ -57,6 +57,8 @@ import org.apache.solr.common.cloud.ZkNodeProps; import org.apache.solr.common.cloud.ZkStateReader; import org.apache.solr.common.params.CollectionParams.CollectionAction; import org.apache.solr.common.params.ModifiableSolrParams; +import org.apache.solr.common.params.ShardParams; +import org.apache.solr.common.util.NamedList; import org.apache.solr.update.DirectUpdateHandler2; import org.apache.solr.util.DefaultSolrThreadFactory; import org.junit.Before; @@ -243,6 +245,16 @@ public class CustomCollectionTest extends AbstractFullDistribZkTestBase { assertEquals(0, collectionClient.query(new SolrQuery("*:*").setParam(_ROUTE_,"b")).getResults().getNumFound()); assertEquals(3, collectionClient.query(new SolrQuery("*:*").setParam(_ROUTE_,"a")).getResults().getNumFound()); + // test shards.info with _route_ param + QueryResponse resp = collectionClient.query(new SolrQuery("*:*").setParam(_ROUTE_, "a").setParam(ShardParams.SHARDS_INFO, true)); + NamedList sinfo = (NamedList) resp.getResponse().get(ShardParams.SHARDS_INFO); + assertNotNull("missing shard info", sinfo); + for (Map.Entry entry : sinfo) { + NamedList info = (NamedList) entry.getValue(); + assertTrue("Expected to find numFound in the up shard info",info.get("numFound") != null); + assertTrue("Expected to find shardAddress in the up shard info",info.get("shardAddress") != null); + } + collectionClient.deleteByQuery("*:*"); collectionClient.commit(true,true); assertEquals(0, collectionClient.query(new SolrQuery("*:*")).getResults().getNumFound()); From 36fd83b0dfca0d2deafc1a071658d560946c91b2 Mon Sep 17 00:00:00 2001 From: Steven Rowe Date: Wed, 11 Dec 2013 15:53:18 +0000 Subject: [PATCH 211/223] LUCENE-5360: Netbeans support: streamline XSLT stylesheet; add basic code style git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1550178 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 33 +- dev-tools/netbeans/nb-project.xsl | 393 +++++++----------- .../netbeans/nbproject/project.properties | 9 + lucene/CHANGES.txt | 2 +- 4 files changed, 164 insertions(+), 273 deletions(-) create mode 100644 dev-tools/netbeans/nbproject/project.properties diff --git a/build.xml b/build.xml index 24ebc18c1dc..8cb28404cf0 100644 --- a/build.xml +++ b/build.xml @@ -193,32 +193,29 @@ - - + + - - - - - - - - - - - - - + + + + + + + - - - + + diff --git a/dev-tools/netbeans/nb-project.xsl b/dev-tools/netbeans/nb-project.xsl index a61c733b44d..69b19447d23 100644 --- a/dev-tools/netbeans/nb-project.xsl +++ b/dev-tools/netbeans/nb-project.xsl @@ -18,263 +18,148 @@ - - - - + xmlns:common="http://exslt.org/common" + extension-element-prefixes="str common"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + : + + + + - - - - org.netbeans.modules.ant.freeform - - - lucene - - - - - - - - - - - - - - - - java - - - - - - - - - - - - - - - - - - - java - - - - - - - - - - - - - - - - - - - - - - - - - - - compile - - - clean - - - documentation - - - test - - - clean - compile - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - build.xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - : - - - : - - - - - - : - - - - nb-build/classes - 1.7 - - - - - - - - - - - - - - - - - - - - - - - - - : - - - : - - - - - - : - - - - nb-build/test-classes - 1.7 - - - - - + + + org.netbeans.modules.ant.freeform + + + lucene + + + + + + + java + + + + + + + + + + compile + + + clean + + + documentation + + + test + + + clean + compile + + + + + + + + + packages + tree + + + + + + + + + + + build.xml + + + + + + + + + + + + + + + + + + + + + nb-build/classes + + + + + + + + + + + + + nb-build/test-classes + + + + + + + + diff --git a/dev-tools/netbeans/nbproject/project.properties b/dev-tools/netbeans/nbproject/project.properties new file mode 100644 index 00000000000..db66f9dda6c --- /dev/null +++ b/dev-tools/netbeans/nbproject/project.properties @@ -0,0 +1,9 @@ +auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.expand-tabs=true +auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.indent-shift-width=2 +auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.spaces-per-tab=2 +auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.tab-size=2 +auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.text-limit-width=80 +auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.text-line-wrap=none +auxiliary.org-netbeans-modules-editor-indent.CodeStyle.usedProfile=project +auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.continuationIndentSize=4 +auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceAfterTypeCast=false diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 681246b3309..14472cde63b 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -97,7 +97,7 @@ Build (Steve Rowe) * LUCENE-5360: Add support for developing in Netbeans IDE. - (Michal Hlavac via Steve Rowe) + (Michal Hlavac, Uwe Schindler, Steve Rowe) Bug fixes From 7e070c34a462ed51dfe62cbf2ee29b915346c55d Mon Sep 17 00:00:00 2001 From: Uwe Schindler Date: Thu, 12 Dec 2013 00:13:14 +0000 Subject: [PATCH 212/223] SOLR-5492: Ignore broken test git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1550323 13f79535-47bb-0310-9956-ffa450edef68 --- .../src/test/org/apache/solr/cloud/CustomCollectionTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/solr/core/src/test/org/apache/solr/cloud/CustomCollectionTest.java b/solr/core/src/test/org/apache/solr/cloud/CustomCollectionTest.java index 50ec13b2c5b..b5b269605e9 100644 --- a/solr/core/src/test/org/apache/solr/cloud/CustomCollectionTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/CustomCollectionTest.java @@ -63,11 +63,13 @@ import org.apache.solr.update.DirectUpdateHandler2; import org.apache.solr.util.DefaultSolrThreadFactory; import org.junit.Before; import org.junit.BeforeClass; +import org.junit.Ignore; /** * Tests the Custom Sharding API. */ @Slow +@Ignore("I am broken since SOLR-5492") public class CustomCollectionTest extends AbstractFullDistribZkTestBase { private static final String DEFAULT_COLLECTION = "collection1"; From 8f6343fb83aefd2b5d63bd975e2ba13ff7a273ed Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Thu, 12 Dec 2013 20:15:52 +0000 Subject: [PATCH 213/223] SOLR-5548: Give DistributedSearchTestCase / JettySolrRunner the ability to specify extra filters. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1550508 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 3 ++ .../solrj/embedded/JettySolrRunner.java | 36 ++++++++++++++++--- .../solr/BaseDistributedSearchTestCase.java | 10 ++++-- .../cloud/AbstractFullDistribZkTestBase.java | 4 +-- 4 files changed, 45 insertions(+), 8 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 3ae9bcb31e3..3ba5609c003 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -241,6 +241,9 @@ Other Changes * SOLR-5533: Improve out of the box support for running Solr on hdfs with SolrCloud. (Mark Miller) +* SOLR-5548: Give DistributedSearchTestCase / JettySolrRunner the ability to + specify extra filters. (Greg Chanan via Mark Miller) + ================== 4.6.0 ================== Versions of Major Components diff --git a/solr/core/src/java/org/apache/solr/client/solrj/embedded/JettySolrRunner.java b/solr/core/src/java/org/apache/solr/client/solrj/embedded/JettySolrRunner.java index b47fa3f314a..7dc0e0e4c88 100644 --- a/solr/core/src/java/org/apache/solr/client/solrj/embedded/JettySolrRunner.java +++ b/solr/core/src/java/org/apache/solr/client/solrj/embedded/JettySolrRunner.java @@ -93,6 +93,8 @@ public class JettySolrRunner { /** Maps servlet holders (i.e. factories: class + init params) to path specs */ private SortedMap extraServlets = new TreeMap(); + private SortedMap extraRequestFilters; + private LinkedList extraFilters; private SSLConfig sslConfig; @@ -167,16 +169,30 @@ public class JettySolrRunner { public JettySolrRunner(String solrHome, String context, int port, String solrConfigFilename, String schemaFileName, boolean stopAtShutdown, SortedMap extraServlets) { - if (null != extraServlets) { this.extraServlets.putAll(extraServlets); } - this.init(solrHome, context, port, stopAtShutdown); - this.solrConfigFilename = solrConfigFilename; - this.schemaFilename = schemaFileName; + this (solrHome, context, port, solrConfigFilename, schemaFileName, + stopAtShutdown, extraServlets, null, null); } public JettySolrRunner(String solrHome, String context, int port, String solrConfigFilename, String schemaFileName, boolean stopAtShutdown, SortedMap extraServlets, SSLConfig sslConfig) { + this (solrHome, context, port, solrConfigFilename, schemaFileName, + stopAtShutdown, extraServlets, sslConfig, null); + } + + /** + * Constructor taking an ordered list of additional (filter holder -> path spec) mappings. + * Filters are placed after the DebugFilter but before the SolrDispatchFilter. + */ + public JettySolrRunner(String solrHome, String context, int port, + String solrConfigFilename, String schemaFileName, boolean stopAtShutdown, + SortedMap extraServlets, SSLConfig sslConfig, + SortedMap extraRequestFilters) { if (null != extraServlets) { this.extraServlets.putAll(extraServlets); } + if (null != extraRequestFilters) { + this.extraRequestFilters = new TreeMap(extraRequestFilters.comparator()); + this.extraRequestFilters.putAll(extraRequestFilters); + } this.init(solrHome, context, port, stopAtShutdown); this.solrConfigFilename = solrConfigFilename; this.schemaFilename = schemaFileName; @@ -309,6 +325,13 @@ public class JettySolrRunner { // SolrDispatchFilter filter = new SolrDispatchFilter(); // FilterHolder fh = new FilterHolder(filter); debugFilter = root.addFilter(DebugFilter.class, "*", EnumSet.of(DispatcherType.REQUEST) ); + if (extraRequestFilters != null) { + extraFilters = new LinkedList(); + for (Class filterClass : extraRequestFilters.keySet()) { + extraFilters.add(root.addFilter(filterClass, extraRequestFilters.get(filterClass), + EnumSet.of(DispatcherType.REQUEST))); + } + } dispatchFilter = root.addFilter(SolrDispatchFilter.class, "*", EnumSet.of(DispatcherType.REQUEST) ); for (ServletHolder servletHolder : extraServlets.keySet()) { String pathSpec = extraServlets.get(servletHolder); @@ -445,6 +468,11 @@ public class JettySolrRunner { //server.destroy(); if (server.getState().equals(Server.FAILED)) { filter.destroy(); + if (extraFilters != null) { + for (FilterHolder f : extraFilters) { + f.getFilter().destroy(); + } + } } server.join(); diff --git a/solr/test-framework/src/java/org/apache/solr/BaseDistributedSearchTestCase.java b/solr/test-framework/src/java/org/apache/solr/BaseDistributedSearchTestCase.java index 877bed1f4f2..195949bcfd7 100644 --- a/solr/test-framework/src/java/org/apache/solr/BaseDistributedSearchTestCase.java +++ b/solr/test-framework/src/java/org/apache/solr/BaseDistributedSearchTestCase.java @@ -368,7 +368,8 @@ public abstract class BaseDistributedSearchTestCase extends SolrTestCaseJ4 { boolean stopAtShutdown = true; JettySolrRunner jetty = new JettySolrRunner - (solrHome.getAbsolutePath(), context, 0, solrConfigOverride, schemaOverride, stopAtShutdown, getExtraServlets()); + (solrHome.getAbsolutePath(), context, 0, solrConfigOverride, schemaOverride, stopAtShutdown, + getExtraServlets(), null, getExtraRequestFilters()); jetty.setShards(shardList); jetty.setDataDir(dataDir); if (explicitCoreNodeName) { @@ -383,7 +384,12 @@ public abstract class BaseDistributedSearchTestCase extends SolrTestCaseJ4 { public SortedMap getExtraServlets() { return null; } - + + /** Override this method to insert extra filters into the JettySolrRunners that are created using createJetty() */ + public SortedMap getExtraRequestFilters() { + return null; + } + protected SolrServer createNewSolrServer(int port) { try { // setup the server... diff --git a/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java b/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java index 9b118fbe9a9..11e790b3a55 100644 --- a/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java +++ b/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java @@ -453,7 +453,7 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes String solrConfigOverride) throws Exception { JettySolrRunner jetty = new JettySolrRunner(getSolrHome(), context, 0, - solrConfigOverride, null, false, getExtraServlets()); + solrConfigOverride, null, false, getExtraServlets(), null, getExtraRequestFilters()); jetty.setShards(shardList); jetty.setDataDir(getDataDir(dataDir)); jetty.start(); @@ -467,7 +467,7 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes solrHome = getRelativeSolrHomePath(solrHome); } - JettySolrRunner jetty = new JettySolrRunner(solrHome.getPath(), context, 0, solrConfigOverride, schemaOverride, false, getExtraServlets()); + JettySolrRunner jetty = new JettySolrRunner(solrHome.getPath(), context, 0, solrConfigOverride, schemaOverride, false, getExtraServlets(), null, getExtraRequestFilters()); jetty.setShards(shardList); jetty.setDataDir(getDataDir(dataDir)); jetty.start(); From 5b0ae51d63208d4499829b8bf48e254d41d32ae4 Mon Sep 17 00:00:00 2001 From: Mark Robert Miller Date: Thu, 12 Dec 2013 21:57:39 +0000 Subject: [PATCH 214/223] SOLR-5547: Creating a collection alias using SolrJ's CollectionAdminRequest sets the alias name and the collections to alias to the same value. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1550548 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 4 ++ .../solr/cloud/AliasIntegrationTest.java | 47 +++++++++++++------ .../solrj/request/CollectionAdminRequest.java | 2 +- 3 files changed, 37 insertions(+), 16 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 3ba5609c003..6687631b590 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -198,6 +198,10 @@ Bug Fixes * SOLR-5532: SolrJ Content-Type validation is too strict for some webcontainers / proxies. (Jakob Furrer, hossman, Shawn Heisey, Uwe Schindler, Mark Miller) + +* SOLR-5547: Creating a collection alias using SolrJ's CollectionAdminRequest + sets the alias name and the collections to alias to the same value. + (Aaron Schram, Mark Miller) Optimizations ---------------------- diff --git a/solr/core/src/test/org/apache/solr/cloud/AliasIntegrationTest.java b/solr/core/src/test/org/apache/solr/cloud/AliasIntegrationTest.java index 16d9b48467d..293c31d9ad5 100644 --- a/solr/core/src/test/org/apache/solr/cloud/AliasIntegrationTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/AliasIntegrationTest.java @@ -27,8 +27,10 @@ import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.embedded.JettySolrRunner; import org.apache.solr.client.solrj.impl.CloudSolrServer; import org.apache.solr.client.solrj.impl.HttpSolrServer; +import org.apache.solr.client.solrj.request.CollectionAdminRequest; import org.apache.solr.client.solrj.request.QueryRequest; import org.apache.solr.client.solrj.request.UpdateRequest; +import org.apache.solr.client.solrj.response.CollectionAdminResponse; import org.apache.solr.client.solrj.response.QueryResponse; import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrInputDocument; @@ -241,23 +243,38 @@ public class AliasIntegrationTest extends AbstractFullDistribZkTestBase { assertTrue(sawException); } - private void createAlias(String alias, String collections) throws SolrServerException, IOException { - ModifiableSolrParams params = new ModifiableSolrParams(); - params.set("collections", collections); - params.set("name", alias); - params.set("action", CollectionAction.CREATEALIAS.toString()); - QueryRequest request = new QueryRequest(params); - request.setPath("/admin/collections"); - NamedList result = createNewSolrServer("", getBaseUrl((HttpSolrServer) clients.get(0))).request(request); + private void createAlias(String alias, String collections) + throws SolrServerException, IOException { + if (random().nextBoolean()) { + ModifiableSolrParams params = new ModifiableSolrParams(); + params.set("collections", collections); + params.set("name", alias); + params.set("action", CollectionAction.CREATEALIAS.toString()); + QueryRequest request = new QueryRequest(params); + request.setPath("/admin/collections"); + NamedList result = createNewSolrServer("", + getBaseUrl((HttpSolrServer) clients.get(0))).request(request); + } else { + CollectionAdminResponse resp = CollectionAdminRequest.CreateAlias + .createAlias(alias, collections, createNewSolrServer("", + getBaseUrl((HttpSolrServer) clients.get(0)))); + } } - private void deleteAlias(String alias) throws SolrServerException, IOException { - ModifiableSolrParams params = new ModifiableSolrParams(); - params.set("name", alias); - params.set("action", CollectionAction.DELETEALIAS.toString()); - QueryRequest request = new QueryRequest(params); - request.setPath("/admin/collections"); - NamedList result = createNewSolrServer("", getBaseUrl((HttpSolrServer) clients.get(0))).request(request); + private void deleteAlias(String alias) throws SolrServerException, + IOException { + if (random().nextBoolean()) { + ModifiableSolrParams params = new ModifiableSolrParams(); + params.set("name", alias); + params.set("action", CollectionAction.DELETEALIAS.toString()); + QueryRequest request = new QueryRequest(params); + request.setPath("/admin/collections"); + NamedList result = createNewSolrServer("", + getBaseUrl((HttpSolrServer) clients.get(0))).request(request); + } else { + CollectionAdminResponse resp = CollectionAdminRequest.deleteAlias(alias, + createNewSolrServer("", getBaseUrl((HttpSolrServer) clients.get(0)))); + } } protected void indexDoc(List skipServers, Object... fields) throws IOException, diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/request/CollectionAdminRequest.java b/solr/solrj/src/java/org/apache/solr/client/solrj/request/CollectionAdminRequest.java index c48d73562bd..cc149ce4957 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/request/CollectionAdminRequest.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/request/CollectionAdminRequest.java @@ -197,7 +197,7 @@ public class CollectionAdminRequest extends SolrRequest @Override public SolrParams getParams() { ModifiableSolrParams params = (ModifiableSolrParams) super.getParams(); - params.set( "collections", collection ); + params.set( "collections", aliasedCollections ); return params; } From 78d8d0c53552473f52c60cf098ce2fc6d6658365 Mon Sep 17 00:00:00 2001 From: Shalin Shekhar Mangar Date: Fri, 13 Dec 2013 06:40:01 +0000 Subject: [PATCH 215/223] SOLR-3702: A 'concat' function query to support concatenation of Strings git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1550656 13f79535-47bb-0310-9956-ffa450edef68 --- .../valuesource/ConcatenateFunction.java | 75 +++++++++++++++++++ solr/CHANGES.txt | 3 + .../apache/solr/search/ValueSourceParser.java | 7 ++ .../search/function/TestFunctionQuery.java | 20 +++++ 4 files changed, 105 insertions(+) create mode 100644 lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/ConcatenateFunction.java diff --git a/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/ConcatenateFunction.java b/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/ConcatenateFunction.java new file mode 100644 index 00000000000..08fa8e9ef41 --- /dev/null +++ b/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/ConcatenateFunction.java @@ -0,0 +1,75 @@ +package org.apache.lucene.queries.function.valuesource; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import org.apache.lucene.index.AtomicReaderContext; +import org.apache.lucene.queries.function.FunctionValues; +import org.apache.lucene.queries.function.ValueSource; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +/** + * A {@link ValueSource} implementation which concatenates existing string + * values from the provided ValueSources into one string. + */ +public class ConcatenateFunction extends MultiFunction { + + public ConcatenateFunction(List sources) { + super(sources); + } + + @Override + protected String name() { + return "concat"; + } + + @Override + public FunctionValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { + return new Values(valsArr(sources, context, readerContext)) { + + @Override + public String strVal(int doc) { + StringBuilder stringBuilder = new StringBuilder(); + for (FunctionValues functionValues : valsArr) { + if (functionValues.exists(doc)) { + stringBuilder.append(functionValues.strVal(doc)); + } + } + return stringBuilder.toString(); + } + + @Override + public Object objectVal(int doc) { + return strVal(doc); + } + + @Override + public boolean exists(int doc) { + for (FunctionValues vals : valsArr) { + if (vals.exists(doc)) { + return true; + } + } + return false; + } + }; + } +} diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 6687631b590..83a5cc79abd 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -127,6 +127,9 @@ New Features * SOLR-1871: The 'map' function query accepts a ValueSource as target and default value. (Chris Harris, shalin) +* SOLR-3702: A 'concat' function query to support concatenation of Strings. + (Ted Strauss, Andrey Kudryavtsev via shalin) + Bug Fixes ---------------------- diff --git a/solr/core/src/java/org/apache/solr/search/ValueSourceParser.java b/solr/core/src/java/org/apache/solr/search/ValueSourceParser.java index 4c6cb941a3b..25c52489249 100644 --- a/solr/core/src/java/org/apache/solr/search/ValueSourceParser.java +++ b/solr/core/src/java/org/apache/solr/search/ValueSourceParser.java @@ -779,6 +779,13 @@ public abstract class ValueSourceParser implements NamedListInitializedPlugin { } }); + addParser("concat", new ValueSourceParser() { + @Override + public ValueSource parse(FunctionQParser fp) throws SyntaxError { + return new ConcatenateFunction(fp.parseValueSourceList()); + } + }); + } private static TInfo parseTerm(FunctionQParser fp) throws SyntaxError { diff --git a/solr/core/src/test/org/apache/solr/search/function/TestFunctionQuery.java b/solr/core/src/test/org/apache/solr/search/function/TestFunctionQuery.java index 1ed6dbcf4f3..2dbdde13da1 100644 --- a/solr/core/src/test/org/apache/solr/search/function/TestFunctionQuery.java +++ b/solr/core/src/test/org/apache/solr/search/function/TestFunctionQuery.java @@ -754,4 +754,24 @@ public class TestFunctionQuery extends SolrTestCaseJ4 { } } + public void testConcatFunction() { + clearIndex(); + + assertU(adoc("id", "1", "field1_t", "buzz", "field2_t", "word")); + assertU(adoc("id", "2", "field1_t", "1", "field2_t", "2","field4_t", "4")); + assertU(commit()); + + assertQ(req("q","id:1", + "fl","field:concat(field1_t,field2_t)"), + " //str[@name='field']='buzzword'"); + + assertQ(req("q","id:2", + "fl","field:concat(field1_t,field2_t, field3_t, field4_t)"), + " //str[@name='field']='124'"); + + assertQ(req("q","id:1", + "fl","field:def(concat(field3_t, field4_t), 'defValue')"), + " //str[@name='field']='defValue'"); + } + } From f590fe62a618810a0528d791911220290452ac29 Mon Sep 17 00:00:00 2001 From: Shalin Shekhar Mangar Date: Fri, 13 Dec 2013 10:25:43 +0000 Subject: [PATCH 216/223] SOLR-3702: Reverting commit because it breaks QueryEqualityTest git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1550676 13f79535-47bb-0310-9956-ffa450edef68 --- .../valuesource/ConcatenateFunction.java | 75 ------------------- solr/CHANGES.txt | 3 - .../apache/solr/search/ValueSourceParser.java | 7 -- .../search/function/TestFunctionQuery.java | 20 ----- 4 files changed, 105 deletions(-) delete mode 100644 lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/ConcatenateFunction.java diff --git a/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/ConcatenateFunction.java b/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/ConcatenateFunction.java deleted file mode 100644 index 08fa8e9ef41..00000000000 --- a/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/ConcatenateFunction.java +++ /dev/null @@ -1,75 +0,0 @@ -package org.apache.lucene.queries.function.valuesource; - -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -import org.apache.lucene.index.AtomicReaderContext; -import org.apache.lucene.queries.function.FunctionValues; -import org.apache.lucene.queries.function.ValueSource; - -import java.io.IOException; -import java.util.List; -import java.util.Map; - -/** - * A {@link ValueSource} implementation which concatenates existing string - * values from the provided ValueSources into one string. - */ -public class ConcatenateFunction extends MultiFunction { - - public ConcatenateFunction(List sources) { - super(sources); - } - - @Override - protected String name() { - return "concat"; - } - - @Override - public FunctionValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { - return new Values(valsArr(sources, context, readerContext)) { - - @Override - public String strVal(int doc) { - StringBuilder stringBuilder = new StringBuilder(); - for (FunctionValues functionValues : valsArr) { - if (functionValues.exists(doc)) { - stringBuilder.append(functionValues.strVal(doc)); - } - } - return stringBuilder.toString(); - } - - @Override - public Object objectVal(int doc) { - return strVal(doc); - } - - @Override - public boolean exists(int doc) { - for (FunctionValues vals : valsArr) { - if (vals.exists(doc)) { - return true; - } - } - return false; - } - }; - } -} diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 83a5cc79abd..6687631b590 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -127,9 +127,6 @@ New Features * SOLR-1871: The 'map' function query accepts a ValueSource as target and default value. (Chris Harris, shalin) -* SOLR-3702: A 'concat' function query to support concatenation of Strings. - (Ted Strauss, Andrey Kudryavtsev via shalin) - Bug Fixes ---------------------- diff --git a/solr/core/src/java/org/apache/solr/search/ValueSourceParser.java b/solr/core/src/java/org/apache/solr/search/ValueSourceParser.java index 25c52489249..4c6cb941a3b 100644 --- a/solr/core/src/java/org/apache/solr/search/ValueSourceParser.java +++ b/solr/core/src/java/org/apache/solr/search/ValueSourceParser.java @@ -779,13 +779,6 @@ public abstract class ValueSourceParser implements NamedListInitializedPlugin { } }); - addParser("concat", new ValueSourceParser() { - @Override - public ValueSource parse(FunctionQParser fp) throws SyntaxError { - return new ConcatenateFunction(fp.parseValueSourceList()); - } - }); - } private static TInfo parseTerm(FunctionQParser fp) throws SyntaxError { diff --git a/solr/core/src/test/org/apache/solr/search/function/TestFunctionQuery.java b/solr/core/src/test/org/apache/solr/search/function/TestFunctionQuery.java index 2dbdde13da1..1ed6dbcf4f3 100644 --- a/solr/core/src/test/org/apache/solr/search/function/TestFunctionQuery.java +++ b/solr/core/src/test/org/apache/solr/search/function/TestFunctionQuery.java @@ -754,24 +754,4 @@ public class TestFunctionQuery extends SolrTestCaseJ4 { } } - public void testConcatFunction() { - clearIndex(); - - assertU(adoc("id", "1", "field1_t", "buzz", "field2_t", "word")); - assertU(adoc("id", "2", "field1_t", "1", "field2_t", "2","field4_t", "4")); - assertU(commit()); - - assertQ(req("q","id:1", - "fl","field:concat(field1_t,field2_t)"), - " //str[@name='field']='buzzword'"); - - assertQ(req("q","id:2", - "fl","field:concat(field1_t,field2_t, field3_t, field4_t)"), - " //str[@name='field']='124'"); - - assertQ(req("q","id:1", - "fl","field:def(concat(field3_t, field4_t), 'defValue')"), - " //str[@name='field']='defValue'"); - } - } From d22cffebb7a6db7b9744fd00c4dd067b95f543ad Mon Sep 17 00:00:00 2001 From: Alan Woodward Date: Fri, 13 Dec 2013 19:47:06 +0000 Subject: [PATCH 217/223] SOLR-5555: CloudSolrServer and LBHttpSolrServer shouldn't throw MUE from constructors git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1550824 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 7 +++- .../solr/morphlines/solr/SolrLocator.java | 39 ++++++++----------- .../component/HttpShardHandlerFactory.java | 32 +++++++-------- .../client/solrj/impl/CloudSolrServer.java | 2 +- .../client/solrj/impl/LBHttpSolrServer.java | 8 ++-- 5 files changed, 39 insertions(+), 49 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 6687631b590..e001f738c82 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -73,7 +73,9 @@ Apache ZooKeeper 3.4.5 Upgrading from Solr 4.6.0 ---------------------- - + +* CloudSolrServer and LBHttpSolrServer no longer declare MalfurmedURLException + as thrown from their constructors. Detailed Change List ---------------------- @@ -248,6 +250,9 @@ Other Changes * SOLR-5548: Give DistributedSearchTestCase / JettySolrRunner the ability to specify extra filters. (Greg Chanan via Mark Miller) +* SOLR-5555: LBHttpSolrServer and CloudSolrServer constructors don't need to + declare MalformedURLExceptions (Sushil Bajracharya, Alan Woodward) + ================== 4.6.0 ================== Versions of Major Components diff --git a/solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/SolrLocator.java b/solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/SolrLocator.java index 2381a08b082..3254acd9326 100644 --- a/solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/SolrLocator.java +++ b/solr/contrib/morphlines-core/src/java/org/apache/solr/morphlines/solr/SolrLocator.java @@ -16,12 +16,15 @@ */ package org.apache.solr.morphlines.solr; -import java.io.File; -import java.io.IOException; -import java.net.MalformedURLException; - -import javax.xml.parsers.ParserConfigurationException; - +import com.cloudera.cdk.morphline.api.MorphlineCompilationException; +import com.cloudera.cdk.morphline.api.MorphlineContext; +import com.cloudera.cdk.morphline.api.MorphlineRuntimeException; +import com.cloudera.cdk.morphline.base.Configs; +import com.google.common.base.Preconditions; +import com.typesafe.config.Config; +import com.typesafe.config.ConfigFactory; +import com.typesafe.config.ConfigRenderOptions; +import com.typesafe.config.ConfigUtil; import org.apache.solr.client.solrj.SolrServer; import org.apache.solr.client.solrj.impl.CloudSolrServer; import org.apache.solr.common.cloud.SolrZkClient; @@ -35,15 +38,9 @@ import org.slf4j.LoggerFactory; import org.xml.sax.InputSource; import org.xml.sax.SAXException; -import com.cloudera.cdk.morphline.api.MorphlineCompilationException; -import com.cloudera.cdk.morphline.api.MorphlineContext; -import com.cloudera.cdk.morphline.api.MorphlineRuntimeException; -import com.cloudera.cdk.morphline.base.Configs; -import com.google.common.base.Preconditions; -import com.typesafe.config.Config; -import com.typesafe.config.ConfigFactory; -import com.typesafe.config.ConfigRenderOptions; -import com.typesafe.config.ConfigUtil; +import javax.xml.parsers.ParserConfigurationException; +import java.io.File; +import java.io.IOException; /** * Set of configuration parameters that identify the location and schema of a Solr server or @@ -94,14 +91,10 @@ public class SolrLocator { if (collectionName == null || collectionName.length() == 0) { throw new MorphlineCompilationException("Parameter 'zkHost' requires that you also pass parameter 'collection'", config); } - try { - CloudSolrServer cloudSolrServer = new CloudSolrServer(zkHost); - cloudSolrServer.setDefaultCollection(collectionName); - cloudSolrServer.connect(); - return new SolrServerDocumentLoader(cloudSolrServer, batchSize); - } catch (MalformedURLException e) { - throw new MorphlineRuntimeException(e); - } + CloudSolrServer cloudSolrServer = new CloudSolrServer(zkHost); + cloudSolrServer.setDefaultCollection(collectionName); + cloudSolrServer.connect(); + return new SolrServerDocumentLoader(cloudSolrServer, batchSize); } else { if (solrUrl == null || solrUrl.length() == 0) { throw new MorphlineCompilationException("Missing parameter 'solrUrl'", config); diff --git a/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java b/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java index d55e01f0701..a2432cd994f 100644 --- a/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java +++ b/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java @@ -16,19 +16,6 @@ package org.apache.solr.handler.component; * limitations under the License. */ -import java.io.IOException; -import java.net.MalformedURLException; -import java.util.Collections; -import java.util.List; -import java.util.Random; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.CompletionService; -import java.util.concurrent.ExecutorCompletionService; -import java.util.concurrent.SynchronousQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; - import org.apache.http.client.HttpClient; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.impl.HttpClientUtil; @@ -44,6 +31,18 @@ import org.apache.solr.util.DefaultSolrThreadFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.IOException; +import java.util.Collections; +import java.util.List; +import java.util.Random; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.CompletionService; +import java.util.concurrent.ExecutorCompletionService; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + public class HttpShardHandlerFactory extends ShardHandlerFactory implements org.apache.solr.util.plugin.PluginInfoInitialized { protected static Logger log = LoggerFactory.getLogger(HttpShardHandlerFactory.class); @@ -158,12 +157,7 @@ public class HttpShardHandlerFactory extends ShardHandlerFactory implements org. } protected LBHttpSolrServer createLoadbalancer(HttpClient httpClient){ - try { - return new LBHttpSolrServer(httpClient); - } catch (MalformedURLException e) { - // should be impossible since we're not passing any URLs here - throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, e); - } + return new LBHttpSolrServer(httpClient); } protected T getParameter(NamedList initArgs, String configKey, T defaultValue) { diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrServer.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrServer.java index 1130e15cd0b..e2f9c813840 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrServer.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrServer.java @@ -119,7 +119,7 @@ public class CloudSolrServer extends SolrServer { * @param zkHost The client endpoint of the zookeeper quorum containing the cloud state, * in the form HOST:PORT. */ - public CloudSolrServer(String zkHost) throws MalformedURLException { + public CloudSolrServer(String zkHost) { this.zkHost = zkHost; this.myClient = HttpClientUtil.createClient(null); this.lbServer = new LBHttpSolrServer(myClient); diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBHttpSolrServer.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBHttpSolrServer.java index 830b79e5dcb..e0ea9306a87 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBHttpSolrServer.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBHttpSolrServer.java @@ -192,14 +192,12 @@ public class LBHttpSolrServer extends SolrServer { } /** The provided httpClient should use a multi-threaded connection manager */ - public LBHttpSolrServer(HttpClient httpClient, String... solrServerUrl) - throws MalformedURLException { + public LBHttpSolrServer(HttpClient httpClient, String... solrServerUrl) { this(httpClient, new BinaryResponseParser(), solrServerUrl); } /** The provided httpClient should use a multi-threaded connection manager */ - public LBHttpSolrServer(HttpClient httpClient, ResponseParser parser, String... solrServerUrl) - throws MalformedURLException { + public LBHttpSolrServer(HttpClient httpClient, ResponseParser parser, String... solrServerUrl) { clientIsInternal = (httpClient == null); this.parser = parser; if (httpClient == null) { @@ -234,7 +232,7 @@ public class LBHttpSolrServer extends SolrServer { return server; } - protected HttpSolrServer makeServer(String server) throws MalformedURLException { + protected HttpSolrServer makeServer(String server) { HttpSolrServer s = new HttpSolrServer(server, httpClient, parser); if (requestWriter != null) { s.setRequestWriter(requestWriter); From 234acf76b5109a1f1443550db375839fd78b7786 Mon Sep 17 00:00:00 2001 From: Alan Woodward Date: Sat, 14 Dec 2013 21:11:18 +0000 Subject: [PATCH 218/223] SOLR-5543: Core Swaps result in duplicate entries in solr.xml git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1550969 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 5 +- .../org/apache/solr/core/CoreContainer.java | 50 ++++++++----------- .../solr/core/CorePropertiesLocator.java | 5 ++ .../org/apache/solr/core/CoresLocator.java | 8 +++ .../apache/solr/core/SolrXMLCoresLocator.java | 8 +-- .../solr/core/TestSolrXmlPersistence.java | 21 ++++++++ 6 files changed, 65 insertions(+), 32 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index e001f738c82..e9a05e6036e 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -74,7 +74,7 @@ Apache ZooKeeper 3.4.5 Upgrading from Solr 4.6.0 ---------------------- -* CloudSolrServer and LBHttpSolrServer no longer declare MalfurmedURLException +* CloudSolrServer and LBHttpSolrServer no longer declare MalformedURLException as thrown from their constructors. Detailed Change List @@ -204,6 +204,9 @@ Bug Fixes * SOLR-5547: Creating a collection alias using SolrJ's CollectionAdminRequest sets the alias name and the collections to alias to the same value. (Aaron Schram, Mark Miller) + +* SOLR-5543: Core swaps resulted in duplicate core entries in solr.xml when + using solr.xml persistence. (Bill Bell, Alan Woodward) Optimizations ---------------------- diff --git a/solr/core/src/java/org/apache/solr/core/CoreContainer.java b/solr/core/src/java/org/apache/solr/core/CoreContainer.java index 6edd781c56b..20b8e5dd3ee 100644 --- a/solr/core/src/java/org/apache/solr/core/CoreContainer.java +++ b/solr/core/src/java/org/apache/solr/core/CoreContainer.java @@ -17,14 +17,32 @@ package org.apache.solr.core; -import static com.google.common.base.Preconditions.checkNotNull; +import com.google.common.collect.Maps; +import org.apache.solr.cloud.ZkController; +import org.apache.solr.cloud.ZkSolrResourceLoader; +import org.apache.solr.common.SolrException; +import org.apache.solr.common.SolrException.ErrorCode; +import org.apache.solr.common.cloud.ZooKeeperException; +import org.apache.solr.common.util.ExecutorUtil; +import org.apache.solr.handler.admin.CollectionsHandler; +import org.apache.solr.handler.admin.CoreAdminHandler; +import org.apache.solr.handler.admin.InfoHandler; +import org.apache.solr.handler.component.ShardHandlerFactory; +import org.apache.solr.logging.LogWatcher; +import org.apache.solr.schema.IndexSchema; +import org.apache.solr.schema.IndexSchemaFactory; +import org.apache.solr.update.UpdateShardHandler; +import org.apache.solr.util.DefaultSolrThreadFactory; +import org.apache.solr.util.FileUtils; +import org.apache.zookeeper.KeeperException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.File; import java.text.SimpleDateFormat; import java.util.Collection; import java.util.Collections; import java.util.Date; -import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; @@ -41,31 +59,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; -import org.apache.http.client.HttpClient; -import org.apache.http.conn.ClientConnectionManager; -import org.apache.http.impl.conn.PoolingClientConnectionManager; -import org.apache.solr.cloud.ZkController; -import org.apache.solr.cloud.ZkSolrResourceLoader; -import org.apache.solr.common.SolrException; -import org.apache.solr.common.SolrException.ErrorCode; -import org.apache.solr.common.cloud.ZooKeeperException; -import org.apache.solr.common.util.ExecutorUtil; -import org.apache.solr.common.util.SolrjNamedThreadFactory; -import org.apache.solr.handler.admin.CollectionsHandler; -import org.apache.solr.handler.admin.CoreAdminHandler; -import org.apache.solr.handler.admin.InfoHandler; -import org.apache.solr.handler.component.ShardHandlerFactory; -import org.apache.solr.logging.LogWatcher; -import org.apache.solr.schema.IndexSchema; -import org.apache.solr.schema.IndexSchemaFactory; -import org.apache.solr.update.UpdateShardHandler; -import org.apache.solr.util.DefaultSolrThreadFactory; -import org.apache.solr.util.FileUtils; -import org.apache.zookeeper.KeeperException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.collect.Maps; +import static com.google.common.base.Preconditions.checkNotNull; /** @@ -737,7 +731,7 @@ public class CoreContainer { n1 = checkDefault(n1); solrCores.swap(n0, n1); - coresLocator.persist(this, solrCores.getCoreDescriptor(n0), solrCores.getCoreDescriptor(n1)); + coresLocator.swap(this, solrCores.getCoreDescriptor(n0), solrCores.getCoreDescriptor(n1)); log.info("swapped: "+n0 + " with " + n1); } diff --git a/solr/core/src/java/org/apache/solr/core/CorePropertiesLocator.java b/solr/core/src/java/org/apache/solr/core/CorePropertiesLocator.java index a4fa2ae0d1b..d167cb55895 100644 --- a/solr/core/src/java/org/apache/solr/core/CorePropertiesLocator.java +++ b/solr/core/src/java/org/apache/solr/core/CorePropertiesLocator.java @@ -110,6 +110,11 @@ public class CorePropertiesLocator implements CoresLocator { persist(cc, newCD); } + @Override + public void swap(CoreContainer cc, CoreDescriptor cd1, CoreDescriptor cd2) { + persist(cc, cd1, cd2); + } + @Override public List discover(CoreContainer cc) { logger.info("Looking for core definitions underneath {}", rootDirectory.getAbsolutePath()); diff --git a/solr/core/src/java/org/apache/solr/core/CoresLocator.java b/solr/core/src/java/org/apache/solr/core/CoresLocator.java index 6195ef92c4a..daeef04b88b 100644 --- a/solr/core/src/java/org/apache/solr/core/CoresLocator.java +++ b/solr/core/src/java/org/apache/solr/core/CoresLocator.java @@ -55,6 +55,14 @@ public interface CoresLocator { */ public void rename(CoreContainer cc, CoreDescriptor oldCD, CoreDescriptor newCD); + /** + * Swap two core definitions + * @param cc the CoreContainer + * @param cd1 the core descriptor of the first core, after swapping + * @param cd2 the core descriptor of the second core, after swapping + */ + public void swap(CoreContainer cc, CoreDescriptor cd1, CoreDescriptor cd2); + /** * Load all the CoreDescriptors from persistence store * @param cc the CoreContainer diff --git a/solr/core/src/java/org/apache/solr/core/SolrXMLCoresLocator.java b/solr/core/src/java/org/apache/solr/core/SolrXMLCoresLocator.java index 7c1d85844c2..632b4d6fef6 100644 --- a/solr/core/src/java/org/apache/solr/core/SolrXMLCoresLocator.java +++ b/solr/core/src/java/org/apache/solr/core/SolrXMLCoresLocator.java @@ -19,7 +19,6 @@ package org.apache.solr.core; import com.google.common.base.Charsets; import com.google.common.collect.ImmutableList; - import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; @@ -32,11 +31,9 @@ import java.io.OutputStreamWriter; import java.io.Writer; import java.util.ArrayList; import java.util.Arrays; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Properties; -import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -190,6 +187,11 @@ public class SolrXMLCoresLocator implements CoresLocator { this.persist(cc); } + @Override + public void swap(CoreContainer cc, CoreDescriptor cd1, CoreDescriptor cd2) { + this.persist(cc); + } + @Override public List discover(CoreContainer cc) { diff --git a/solr/core/src/test/org/apache/solr/core/TestSolrXmlPersistence.java b/solr/core/src/test/org/apache/solr/core/TestSolrXmlPersistence.java index 603e85c0be2..22a8c8aa3d4 100644 --- a/solr/core/src/test/org/apache/solr/core/TestSolrXmlPersistence.java +++ b/solr/core/src/test/org/apache/solr/core/TestSolrXmlPersistence.java @@ -48,6 +48,8 @@ import java.io.InputStream; import java.util.ArrayList; import java.util.List; +import static org.hamcrest.core.Is.is; + public class TestSolrXmlPersistence extends SolrTestCaseJ4 { private File solrHomeDirectory = new File(TEMP_DIR, this.getClass().getName()); @@ -186,8 +188,24 @@ public class TestSolrXmlPersistence extends SolrTestCaseJ4 { doTestSwap("SystemVars2", "SystemVars1"); } + /* + Count the number of times substring appears in target + */ + private int countOccurrences(String target, String substring) { + int pos = -1, count = 0; + while ((pos = target.indexOf(substring, pos + 1)) != -1) { + count++; + } + return count; + } + private void doTestSwap(String from, String to) throws Exception { CoreContainer cc = init(SOLR_XML_LOTS_SYSVARS, "SystemVars1", "SystemVars2"); + SolrXMLCoresLocator.NonPersistingLocator locator + = (SolrXMLCoresLocator.NonPersistingLocator) cc.getCoresLocator(); + + int coreCount = countOccurrences(locator.xml, " Date: Sun, 15 Dec 2013 20:46:27 +0000 Subject: [PATCH 219/223] Fix test bug git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1551053 13f79535-47bb-0310-9956-ffa450edef68 --- .../test/org/apache/solr/schema/ModifyConfFileTest.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/solr/core/src/test/org/apache/solr/schema/ModifyConfFileTest.java b/solr/core/src/test/org/apache/solr/schema/ModifyConfFileTest.java index 7d04a4d12a7..23bc5d5bf75 100644 --- a/solr/core/src/test/org/apache/solr/schema/ModifyConfFileTest.java +++ b/solr/core/src/test/org/apache/solr/schema/ModifyConfFileTest.java @@ -21,7 +21,6 @@ import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule; import org.apache.commons.codec.Charsets; import org.apache.commons.io.FileUtils; import org.apache.solr.SolrTestCaseJ4; -import org.apache.solr.client.solrj.request.QueryRequest; import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.util.ContentStream; import org.apache.solr.common.util.ContentStreamBase; @@ -40,6 +39,8 @@ import org.junit.rules.TestRule; import java.io.File; import java.util.ArrayList; +import static org.junit.internal.matchers.StringContains.containsString; + public class ModifyConfFileTest extends SolrTestCaseJ4 { private File solrHomeDirectory = new File(TEMP_DIR, this.getClass().getName()); @@ -99,11 +100,7 @@ public class ModifyConfFileTest extends SolrTestCaseJ4 { streams.add(new ContentStreamBase.StringStream(badConf)); locReq.setContentStreams(streams); core.execute(handler, locReq, rsp); - assertTrue("should have detected an error early!", - rsp.getException().getMessage().contains("\"dataDir\"")); - - assertTrue("should have detected an error early!", - rsp.getException().getMessage().contains("\"\"")); + assertThat("should have detected an error early!", rsp.getException().getMessage(), containsString("\"\"")); params = params("op", "test", "file", "schema.xml", "stream.body", "Testing rewrite of schema.xml file."); locReq = new LocalSolrQueryRequest(core, params); From 261127a06276e7d1ada36f4ca77c035648b21b6c Mon Sep 17 00:00:00 2001 From: Han Jiang Date: Mon, 16 Dec 2013 15:03:45 +0000 Subject: [PATCH 220/223] package summary fix git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1551222 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/core/src/java/org/apache/lucene/index/package.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lucene/core/src/java/org/apache/lucene/index/package.html b/lucene/core/src/java/org/apache/lucene/index/package.html index 6870e08e479..9235262f98f 100644 --- a/lucene/core/src/java/org/apache/lucene/index/package.html +++ b/lucene/core/src/java/org/apache/lucene/index/package.html @@ -94,7 +94,7 @@ and methods to access the term's documents and positions.
     // seek to a specific term
    -boolean found = termsEnum.seekExact(new BytesRef("foobar"), true);
    +boolean found = termsEnum.seekExact(new BytesRef("foobar"));
     if (found) {
       // get the document frequency
       System.out.println(termsEnum.docFreq());
    
    From 22baafc512ab4c4e291a4f452d842479bd7e4496 Mon Sep 17 00:00:00 2001
    From: Robert Muir 
    Date: Tue, 17 Dec 2013 23:14:11 +0000
    Subject: [PATCH 221/223] SOLR-5528: improve response format of the new
     SuggestComponent
    
    git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1551753 13f79535-47bb-0310-9956-ffa450edef68
    ---
     solr/CHANGES.txt                              |  2 +-
     .../handler/component/SuggestComponent.java   | 99 ++++++++++---------
     ...a => DistributedSuggestComponentTest.java} |  8 +-
     .../component/SuggestComponentTest.java       | 40 ++++----
     .../suggest/TestFileDictionaryLookup.java     | 20 ++--
     .../TestHighFrequencyDictionaryFactory.java   | 20 ++--
     6 files changed, 97 insertions(+), 92 deletions(-)
     rename solr/core/src/test/org/apache/solr/handler/component/{DistributedSuggesterComponentTest.java => DistributedSuggestComponentTest.java} (94%)
    
    diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
    index e9a05e6036e..2ec5a2125a2 100644
    --- a/solr/CHANGES.txt
    +++ b/solr/CHANGES.txt
    @@ -109,7 +109,7 @@ New Features
       set of distinct values and their count. This can also be specified per field
       e.g. 'f.field.stats.calcdistinct'. (Elran Dvir via shalin)
     
    -* SOLR-5378: A new SuggestComponent that fully utilizes the Lucene suggester
    +* SOLR-5378, SOLR-5528: A new SuggestComponent that fully utilizes the Lucene suggester
       module and adds pluggable dictionaries, payloads and better distributed support.
       This is intended to eventually replace the Suggester support through the
       SpellCheckComponent. (Areek Zillur, Varun Thacker via shalin)
    diff --git a/solr/core/src/java/org/apache/solr/handler/component/SuggestComponent.java b/solr/core/src/java/org/apache/solr/handler/component/SuggestComponent.java
    index 5aa08065f8f..c8aea7d93aa 100644
    --- a/solr/core/src/java/org/apache/solr/handler/component/SuggestComponent.java
    +++ b/solr/core/src/java/org/apache/solr/handler/component/SuggestComponent.java
    @@ -83,7 +83,6 @@ public class SuggestComponent extends SearchComponent implements SolrCoreAware,
       private static class SuggesterResultLabels {
         static final String SUGGEST = "suggest";
         static final String SUGGESTIONS = "suggestions";
    -    static final String SUGGESTION = "suggestion";
         static final String SUGGESTION_NUM_FOUND = "numFound";
         static final String SUGGESTION_TERM = "term";
         static final String SUGGESTION_WEIGHT = "weight";
    @@ -100,7 +99,7 @@ public class SuggestComponent extends SearchComponent implements SolrCoreAware,
       @Override
       public void inform(SolrCore core) {
         if (initParams != null) {
    -      LOG.info("Initializing SuggesterComponent");
    +      LOG.info("Initializing SuggestComponent");
           boolean hasDefault = false;
           for (int i = 0; i < initParams.size(); i++) {
             if (initParams.getName(i).equals(CONFIG_PARAM_LABEL)) {
    @@ -141,14 +140,18 @@ public class SuggestComponent extends SearchComponent implements SolrCoreAware,
       @Override
       public void prepare(ResponseBuilder rb) throws IOException {
         SolrParams params = rb.req.getParams();
    -    LOG.info("Suggester prepare with : " + params);
    +    LOG.info("SuggestComponent prepare with : " + params);
         if (!params.getBool(COMPONENT_NAME, false)) {
           return;
         }
     
         SolrSuggester suggester = getSuggester(params);
         if (suggester == null) {
    -      throw new IllegalArgumentException("Error in configuration, no suggester found");
    +      if (params.get(SUGGEST_DICT) != null) {
    +        throw new IllegalArgumentException("No suggester named " + params.get(SUGGEST_DICT) +" was configured");
    +      } else {
    +        throw new IllegalArgumentException("No default suggester was configured");
    +      }
         }
         if (params.getBool(SUGGEST_BUILD, false)) {
           suggester.build(rb.req.getCore(), rb.req.getSearcher());
    @@ -163,7 +166,7 @@ public class SuggestComponent extends SearchComponent implements SolrCoreAware,
       @Override
       public int distributedProcess(ResponseBuilder rb) {
         SolrParams params = rb.req.getParams();
    -    LOG.info("Suggester distributedProcess with : " + params);
    +    LOG.info("SuggestComponent distributedProcess with : " + params);
         if (rb.stage < ResponseBuilder.STAGE_EXECUTE_QUERY) 
           return ResponseBuilder.STAGE_EXECUTE_QUERY;
         if (rb.stage == ResponseBuilder.STAGE_EXECUTE_QUERY) {
    @@ -185,7 +188,7 @@ public class SuggestComponent extends SearchComponent implements SolrCoreAware,
       @Override
       public void process(ResponseBuilder rb) throws IOException {
         SolrParams params = rb.req.getParams();
    -    LOG.info("Suggester process with : " + params);
    +    LOG.info("SuggestComponent process with : " + params);
         if (!params.getBool(COMPONENT_NAME, false) || suggesters.isEmpty()) {
           return;
         }
    @@ -204,10 +207,8 @@ public class SuggestComponent extends SearchComponent implements SolrCoreAware,
           SuggesterOptions options = new SuggesterOptions(new CharsRef(query), count); 
           SuggesterResult suggesterResult = suggester.getSuggestions(options);
           
    -      NamedList response = new SimpleOrderedMap();
    -      NamedList namedListResult = toNamedList(suggesterResult);
    -      response.add(SuggesterResultLabels.SUGGESTIONS, namedListResult);
    -      rb.rsp.add(SuggesterResultLabels.SUGGEST, response);
    +      NamedList> namedListResult = toNamedList(suggesterResult);
    +      rb.rsp.add(SuggesterResultLabels.SUGGEST, namedListResult);
         }
       }
       
    @@ -217,22 +218,25 @@ public class SuggestComponent extends SearchComponent implements SolrCoreAware,
       @Override
       public void finishStage(ResponseBuilder rb) {
         SolrParams params = rb.req.getParams();
    -    LOG.info("Suggester finishStage with : " + params);
    +    LOG.info("SuggestComponent finishStage with : " + params);
         if (!params.getBool(COMPONENT_NAME, false) || rb.stage != ResponseBuilder.STAGE_GET_FIELDS)
           return;
         int count = params.getInt(SUGGEST_COUNT, 1);
         
         List suggesterResults = new ArrayList();
    -    NamedList response = new SimpleOrderedMap();
    -    NamedList namedListResult = null;
    +    NamedList> namedListResult = null;
         
         // Collect Shard responses
         for (ShardRequest sreq : rb.finished) {
           for (ShardResponse srsp : sreq.responses) {
    -        NamedList namedList = 
    -            (NamedList) srsp.getSolrResponse().getResponse().get(SuggesterResultLabels.SUGGEST);
    -        LOG.info(srsp.getShard() + " : " + namedList);
    -        suggesterResults.add(toSuggesterResult(namedList));
    +        NamedList resp;
    +        if((resp = srsp.getSolrResponse().getResponse()) != null) {
    +          @SuppressWarnings("unchecked")
    +          NamedList> namedList = 
    +              (NamedList>) resp.get(SuggesterResultLabels.SUGGEST);
    +          LOG.info(srsp.getShard() + " : " + namedList);
    +          suggesterResults.add(toSuggesterResult(namedList));
    +        }
           }
         }
         
    @@ -240,9 +244,8 @@ public class SuggestComponent extends SearchComponent implements SolrCoreAware,
         SuggesterResult suggesterResult = merge(suggesterResults, count);
         namedListResult = toNamedList(suggesterResult);
           
    -    response.add(SuggesterResultLabels.SUGGESTIONS, namedListResult);
    -    rb.rsp.add(SuggesterResultLabels.SUGGEST, response);
    -  };
    +    rb.rsp.add(SuggesterResultLabels.SUGGEST, namedListResult);
    +  }
     
       /** 
        * Given a list of {@link SuggesterResult} and count
    @@ -251,6 +254,9 @@ public class SuggestComponent extends SearchComponent implements SolrCoreAware,
        * weights
        * */
       private static SuggesterResult merge(List suggesterResults, int count) {
    +    if (suggesterResults.size() == 1) {
    +      return suggesterResults.get(0);
    +    }
         SuggesterResult result = new SuggesterResult();
         Set allTokens = new HashSet();
         
    @@ -300,7 +306,8 @@ public class SuggestComponent extends SearchComponent implements SolrCoreAware,
         return stats;
       }
       
    -  private long sizeInBytes() {
    +  /** Returns the total size of all the suggester */
    +  public long sizeInBytes() {
         long sizeInBytes = 0;
         for (SolrSuggester suggester : suggesters.values()) {
           sizeInBytes += suggester.sizeInBytes();
    @@ -321,60 +328,61 @@ public class SuggestComponent extends SearchComponent implements SolrCoreAware,
       }
       
       /** Convert {@link SuggesterResult} to NamedList for constructing responses */
    -  private NamedList toNamedList(SuggesterResult suggesterResult) {
    -    NamedList results = new NamedList();
    +  private NamedList> toNamedList(SuggesterResult suggesterResult) {
    +    NamedList> results = new SimpleOrderedMap>();
         for (String token : suggesterResult.getTokens()) {
    -      SimpleOrderedMap suggestionBody = new SimpleOrderedMap();
    +      SimpleOrderedMap suggestionBody = new SimpleOrderedMap();
           List lookupResults = suggesterResult.getLookupResult(token);
           suggestionBody.add(SuggesterResultLabels.SUGGESTION_NUM_FOUND, lookupResults.size());
    -      
    +      List> suggestEntriesNamedList = new ArrayList>();
           for (LookupResult lookupResult : lookupResults) {
             String suggestionString = lookupResult.key.toString();
             long weight = lookupResult.value;
             String payload = (lookupResult.payload != null) ? 
                 lookupResult.payload.utf8ToString()
                 : "";
    -            
    -        SimpleOrderedMap suggestEntryNamedList = new SimpleOrderedMap();
    +        
    +        SimpleOrderedMap suggestEntryNamedList = new SimpleOrderedMap();
             suggestEntryNamedList.add(SuggesterResultLabels.SUGGESTION_TERM, suggestionString);
             suggestEntryNamedList.add(SuggesterResultLabels.SUGGESTION_WEIGHT, weight);
             suggestEntryNamedList.add(SuggesterResultLabels.SUGGESTION_PAYLOAD, payload);
    +        suggestEntriesNamedList.add(suggestEntryNamedList);
             
    -        suggestionBody.add(SuggesterResultLabels.SUGGESTION, suggestEntryNamedList);
           }
    +      suggestionBody.add(SuggesterResultLabels.SUGGESTIONS, suggestEntriesNamedList);
           results.add(token, suggestionBody);
         }
         return results;
       }
       
       /** Convert NamedList (suggester response) to {@link SuggesterResult} */
    -  private SuggesterResult toSuggesterResult(NamedList suggesterRespNamedList) {
    +  private SuggesterResult toSuggesterResult(NamedList> suggestions) {
         SuggesterResult result = new SuggesterResult();
    -    if (suggesterRespNamedList == null) {
    +    if (suggestions == null) {
           return result;
         }
    -    NamedList suggestions = (NamedList) suggesterRespNamedList.get(SuggesterResultLabels.SUGGESTIONS);
    -    if (suggestions != null) {
    -      // for each token
    -      for(int i = 0; i < suggestions.size() ; i++) {
    -        String tokenString = suggestions.getName(i);
    -        List lookupResults = new ArrayList();
    -        NamedList suggestion = (NamedList) suggestions.getVal(i);
    -        // for each suggestion
    -        for (int j = 0; j < suggestion.size(); j++) {
    -          String property = suggestion.getName(j);
    -          if (property.equals(SuggesterResultLabels.SUGGESTION)) {
    -            NamedList suggestionEntry = (NamedList) suggestion.getVal(j);
    +    // for each token
    +    for(int i = 0; i < suggestions.size() ; i++) {
    +      String tokenString = suggestions.getName(i);
    +      List lookupResults = new ArrayList();
    +      NamedList suggestion = (NamedList) suggestions.getVal(i);
    +      // for each suggestion
    +      for (int j = 0; j < suggestion.size(); j++) {
    +        String property = suggestion.getName(j);
    +        if (property.equals(SuggesterResultLabels.SUGGESTIONS)) {
    +          @SuppressWarnings("unchecked")
    +          List> suggestionEntries = (List>) suggestion.getVal(j);
    +          for(NamedList suggestionEntry : suggestionEntries) {
                 String term = (String) suggestionEntry.get(SuggesterResultLabels.SUGGESTION_TERM);
                 Long weight = (Long) suggestionEntry.get(SuggesterResultLabels.SUGGESTION_WEIGHT);
                 String payload = (String) suggestionEntry.get(SuggesterResultLabels.SUGGESTION_PAYLOAD);
                 LookupResult res = new LookupResult(new CharsRef(term), weight, new BytesRef(payload));
                 lookupResults.add(res);
               }
    -          result.add(tokenString, lookupResults);
             }
    +        result.add(tokenString, lookupResults);
           }
    -    } 
    +    }
         return result;
       }
       
    @@ -393,8 +401,7 @@ public class SuggestComponent extends SearchComponent implements SolrCoreAware,
         }
     
         @Override
    -    public void init(NamedList args) {
    -    }
    +    public void init(NamedList args) {}
     
         @Override
         public void newSearcher(SolrIndexSearcher newSearcher,
    diff --git a/solr/core/src/test/org/apache/solr/handler/component/DistributedSuggesterComponentTest.java b/solr/core/src/test/org/apache/solr/handler/component/DistributedSuggestComponentTest.java
    similarity index 94%
    rename from solr/core/src/test/org/apache/solr/handler/component/DistributedSuggesterComponentTest.java
    rename to solr/core/src/test/org/apache/solr/handler/component/DistributedSuggestComponentTest.java
    index 764b5196177..bec861694a7 100644
    --- a/solr/core/src/test/org/apache/solr/handler/component/DistributedSuggesterComponentTest.java
    +++ b/solr/core/src/test/org/apache/solr/handler/component/DistributedSuggestComponentTest.java
    @@ -36,9 +36,9 @@ import org.junit.BeforeClass;
      * @see org.apache.solr.handler.component.SuggestComponent
      */
     @Slow
    -public class DistributedSuggesterComponentTest extends BaseDistributedSearchTestCase {
    +public class DistributedSuggestComponentTest extends BaseDistributedSearchTestCase {
       
    -  public DistributedSuggesterComponentTest() {
    +  public DistributedSuggestComponentTest() {
         //Helpful for debugging
         //fixShardCount=true;
         //shardCount=2;
    @@ -68,9 +68,7 @@ public class DistributedSuggesterComponentTest extends BaseDistributedSearchTest
         NamedList nl = control.getResponse();
         @SuppressWarnings("unchecked")
         NamedList sc = (NamedList) nl.get("suggest");
    -    @SuppressWarnings("unchecked")
    -    NamedList sug = (NamedList) sc.get("suggestions");
    -    if(sug.size()==0) {
    +    if(sc.size()==0) {
           Assert.fail("Control data did not return any suggestions.");
         }
       } 
    diff --git a/solr/core/src/test/org/apache/solr/handler/component/SuggestComponentTest.java b/solr/core/src/test/org/apache/solr/handler/component/SuggestComponentTest.java
    index 86bfc08bdfd..931f7933ba8 100644
    --- a/solr/core/src/test/org/apache/solr/handler/component/SuggestComponentTest.java
    +++ b/solr/core/src/test/org/apache/solr/handler/component/SuggestComponentTest.java
    @@ -66,11 +66,11 @@ public class SuggestComponentTest extends SolrTestCaseJ4 {
             SuggesterParams.SUGGEST_BUILD, "true",
             SuggesterParams.SUGGEST_Q, "exampel",
             SuggesterParams.SUGGEST_COUNT, "2"),
    -        "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='exampel']/int[@name='numFound'][.='2']",
    -        "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='exampel']/lst[@name='suggestion'][1]/str[@name='term'][.='example inputdata']",
    -        "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='exampel']/lst[@name='suggestion'][1]/long[@name='weight'][.='45']",
    -        "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='exampel']/lst[@name='suggestion'][2]/str[@name='term'][.='example data']",
    -        "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='exampel']/lst[@name='suggestion'][2]/long[@name='weight'][.='40']"
    +        "//lst[@name='suggest']/lst[@name='exampel']/int[@name='numFound'][.='2']",
    +        "//lst[@name='suggest']/lst[@name='exampel']/arr[@name='suggestions']/lst[1]/str[@name='term'][.='example inputdata']",
    +        "//lst[@name='suggest']/lst[@name='exampel']/arr[@name='suggestions']/lst[1]/long[@name='weight'][.='45']",
    +        "//lst[@name='suggest']/lst[@name='exampel']/arr[@name='suggestions']/lst[2]/str[@name='term'][.='example data']",
    +        "//lst[@name='suggest']/lst[@name='exampel']/arr[@name='suggestions']/lst[2]/long[@name='weight'][.='40']"
             );
         
         assertQ(req("qt", rh, 
    @@ -78,11 +78,11 @@ public class SuggestComponentTest extends SolrTestCaseJ4 {
             SuggesterParams.SUGGEST_BUILD, "true",
             SuggesterParams.SUGGEST_Q, "Rad",
             SuggesterParams.SUGGEST_COUNT, "2"),
    -        "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='Rad']/int[@name='numFound'][.='2']",
    -        "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='Rad']/lst[@name='suggestion'][1]/str[@name='term'][.='Rad fox']",
    -        "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='Rad']/lst[@name='suggestion'][1]/long[@name='weight'][.='35']",
    -        "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='Rad']/lst[@name='suggestion'][2]/str[@name='term'][.='Red fox']",
    -        "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='Rad']/lst[@name='suggestion'][2]/long[@name='weight'][.='30']"
    +        "//lst[@name='suggest']/lst[@name='Rad']/int[@name='numFound'][.='2']",
    +        "//lst[@name='suggest']/lst[@name='Rad']/arr[@name='suggestions']/lst[1]/str[@name='term'][.='Rad fox']",
    +        "//lst[@name='suggest']/lst[@name='Rad']/arr[@name='suggestions']/lst[1]/long[@name='weight'][.='35']",
    +        "//lst[@name='suggest']/lst[@name='Rad']/arr[@name='suggestions']/lst[2]/str[@name='term'][.='Red fox']",
    +        "//lst[@name='suggest']/lst[@name='Rad']/arr[@name='suggestions']/lst[2]/long[@name='weight'][.='30']"
             );
       }
       
    @@ -93,11 +93,11 @@ public class SuggestComponentTest extends SolrTestCaseJ4 {
             SuggesterParams.SUGGEST_BUILD, "true",
             SuggesterParams.SUGGEST_Q, "exampel",
             SuggesterParams.SUGGEST_COUNT, "2"),
    -        "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='exampel']/int[@name='numFound'][.='2']",
    -        "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='exampel']/lst[@name='suggestion'][1]/str[@name='term'][.='example inputdata']",
    -        "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='exampel']/lst[@name='suggestion'][1]/long[@name='weight'][.='120']",
    -        "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='exampel']/lst[@name='suggestion'][2]/str[@name='term'][.='example data']",
    -        "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='exampel']/lst[@name='suggestion'][2]/long[@name='weight'][.='110']"
    +        "//lst[@name='suggest']/lst[@name='exampel']/int[@name='numFound'][.='2']",
    +        "//lst[@name='suggest']/lst[@name='exampel']/arr[@name='suggestions']/lst[1]/str[@name='term'][.='example inputdata']",
    +        "//lst[@name='suggest']/lst[@name='exampel']/arr[@name='suggestions']/lst[1]/long[@name='weight'][.='120']",
    +        "//lst[@name='suggest']/lst[@name='exampel']/arr[@name='suggestions']/lst[2]/str[@name='term'][.='example data']",
    +        "//lst[@name='suggest']/lst[@name='exampel']/arr[@name='suggestions']/lst[2]/long[@name='weight'][.='110']"
             );
       }
       
    @@ -108,11 +108,11 @@ public class SuggestComponentTest extends SolrTestCaseJ4 {
             SuggesterParams.SUGGEST_BUILD, "true",
             SuggesterParams.SUGGEST_Q, "chn",
             SuggesterParams.SUGGEST_COUNT, "2"),
    -        "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='chn']/int[@name='numFound'][.='2']",
    -        "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='chn']/lst[@name='suggestion'][1]/str[@name='term'][.='chance']",
    -        "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='chn']/lst[@name='suggestion'][1]/long[@name='weight'][.='1']",
    -        "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='chn']/lst[@name='suggestion'][2]/str[@name='term'][.='change']",
    -        "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='chn']/lst[@name='suggestion'][2]/long[@name='weight'][.='1']"
    +        "//lst[@name='suggest']/lst[@name='chn']/int[@name='numFound'][.='2']",
    +        "//lst[@name='suggest']/lst[@name='chn']/arr[@name='suggestions']/lst[1]/str[@name='term'][.='chance']",
    +        "//lst[@name='suggest']/lst[@name='chn']/arr[@name='suggestions']/lst[1]/long[@name='weight'][.='1']",
    +        "//lst[@name='suggest']/lst[@name='chn']/arr[@name='suggestions']/lst[2]/str[@name='term'][.='change']",
    +        "//lst[@name='suggest']/lst[@name='chn']/arr[@name='suggestions']/lst[2]/long[@name='weight'][.='1']"
             );
       }
     }
    diff --git a/solr/core/src/test/org/apache/solr/spelling/suggest/TestFileDictionaryLookup.java b/solr/core/src/test/org/apache/solr/spelling/suggest/TestFileDictionaryLookup.java
    index 5603c93c4e4..31531d8a920 100644
    --- a/solr/core/src/test/org/apache/solr/spelling/suggest/TestFileDictionaryLookup.java
    +++ b/solr/core/src/test/org/apache/solr/spelling/suggest/TestFileDictionaryLookup.java
    @@ -33,28 +33,28 @@ public class TestFileDictionaryLookup extends SolrTestCaseJ4  {
         
         // tests to demonstrate default maxEdit parameter (value: 1), control for testWithMaxEdit2
         assertQ(req("qt", REQUEST_URI, "q", "chagn", SuggesterParams.SUGGEST_COUNT, "3"),
    -      "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='chagn']/int[@name='numFound'][.='2']",
    -      "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='chagn']/lst[@name='suggestion'][1]/str[@name='term'][.='chance']",
    -      "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='chagn']/lst[@name='suggestion'][2]/str[@name='term'][.='change']"
    +      "//lst[@name='suggest']/lst[@name='chagn']/int[@name='numFound'][.='2']",
    +      "//lst[@name='suggest']/lst[@name='chagn']/arr[@name='suggestions']/lst[1]/str[@name='term'][.='chance']",
    +      "//lst[@name='suggest']/lst[@name='chagn']/arr[@name='suggestions']/lst[2]/str[@name='term'][.='change']"
           );
         
         assertQ(req("qt", REQUEST_URI, "q", "chacn", SuggesterParams.SUGGEST_COUNT, "3"),
    -      "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='chacn']/int[@name='numFound'][.='2']",
    -      "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='chacn']/lst[@name='suggestion'][1]/str[@name='term'][.='chance']",
    -      "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='chacn']/lst[@name='suggestion'][2]/str[@name='term'][.='change']"
    +      "//lst[@name='suggest']/lst[@name='chacn']/int[@name='numFound'][.='2']",
    +      "//lst[@name='suggest']/lst[@name='chacn']/arr[@name='suggestions']/lst[1]/str[@name='term'][.='chance']",
    +      "//lst[@name='suggest']/lst[@name='chacn']/arr[@name='suggestions']/lst[2]/str[@name='term'][.='change']"
           );
         
         assertQ(req("qt", REQUEST_URI, "q", "chagr", SuggesterParams.SUGGEST_COUNT, "3"),
    -      "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='chagr']/int[@name='numFound'][.='1']",
    -      "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='chagr']/lst[@name='suggestion'][1]/str[@name='term'][.='charge']"
    +      "//lst[@name='suggest']/lst[@name='chagr']/int[@name='numFound'][.='1']",
    +      "//lst[@name='suggest']/lst[@name='chagr']/arr[@name='suggestions']/lst[1]/str[@name='term'][.='charge']"
           );
         
         assertQ(req("qt", REQUEST_URI, "q", "chanr", SuggesterParams.SUGGEST_COUNT, "3"),
    -    "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='chanr']/int[@name='numFound'][.='3']"
    +    "//lst[@name='suggest']/lst[@name='chanr']/int[@name='numFound'][.='3']"
         );
         
         assertQ(req("qt", REQUEST_URI, "q", "cyhnce", SuggesterParams.SUGGEST_COUNT, "3"),
    -    "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='cyhnce']/int[@name='numFound'][.='0']"
    +    "//lst[@name='suggest']/lst[@name='cyhnce']/int[@name='numFound'][.='0']"
         );
       }
     }
    diff --git a/solr/core/src/test/org/apache/solr/spelling/suggest/TestHighFrequencyDictionaryFactory.java b/solr/core/src/test/org/apache/solr/spelling/suggest/TestHighFrequencyDictionaryFactory.java
    index 4090a77819e..c5a6350f45f 100644
    --- a/solr/core/src/test/org/apache/solr/spelling/suggest/TestHighFrequencyDictionaryFactory.java
    +++ b/solr/core/src/test/org/apache/solr/spelling/suggest/TestHighFrequencyDictionaryFactory.java
    @@ -47,28 +47,28 @@ public class TestHighFrequencyDictionaryFactory extends SolrTestCaseJ4  {
         
      // tests to demonstrate default maxEdit parameter (value: 1), control for testWithMaxEdit2
         assertQ(req("qt", REQUEST_URI, "q", "chagn", SuggesterParams.SUGGEST_COUNT, "3"),
    -      "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='chagn']/int[@name='numFound'][.='2']",
    -      "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='chagn']/lst[@name='suggestion'][1]/str[@name='term'][.='chance']",
    -      "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='chagn']/lst[@name='suggestion'][2]/str[@name='term'][.='change']"
    +      "//lst[@name='suggest']/lst[@name='chagn']/int[@name='numFound'][.='2']",
    +      "//lst[@name='suggest']/lst[@name='chagn']/arr[@name='suggestions']/lst[1]/str[@name='term'][.='chance']",
    +      "//lst[@name='suggest']/lst[@name='chagn']/arr[@name='suggestions']/lst[2]/str[@name='term'][.='change']"
           );
         
         assertQ(req("qt", REQUEST_URI, "q", "chacn", SuggesterParams.SUGGEST_COUNT, "3"),
    -      "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='chacn']/int[@name='numFound'][.='2']",
    -      "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='chacn']/lst[@name='suggestion'][1]/str[@name='term'][.='chance']",
    -      "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='chacn']/lst[@name='suggestion'][2]/str[@name='term'][.='change']"
    +      "//lst[@name='suggest']/lst[@name='chacn']/int[@name='numFound'][.='2']",
    +      "//lst[@name='suggest']/lst[@name='chacn']/arr[@name='suggestions']/lst[1]/str[@name='term'][.='chance']",
    +      "//lst[@name='suggest']/lst[@name='chacn']/arr[@name='suggestions']/lst[2]/str[@name='term'][.='change']"
           );
         
         assertQ(req("qt", REQUEST_URI, "q", "chagr", SuggesterParams.SUGGEST_COUNT, "3"),
    -      "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='chagr']/int[@name='numFound'][.='1']",
    -      "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='chagr']/lst[@name='suggestion'][1]/str[@name='term'][.='charge']"
    +      "//lst[@name='suggest']/lst[@name='chagr']/int[@name='numFound'][.='1']",
    +      "//lst[@name='suggest']/lst[@name='chagr']/arr[@name='suggestions']/lst[1]/str[@name='term'][.='charge']"
           );
         
         assertQ(req("qt", REQUEST_URI, "q", "chanr", SuggesterParams.SUGGEST_COUNT, "3"),
    -    "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='chanr']/int[@name='numFound'][.='3']"
    +    "//lst[@name='suggest']/lst[@name='chanr']/int[@name='numFound'][.='3']"
         );
         
         assertQ(req("qt", REQUEST_URI, "q", "cyhnce", SuggesterParams.SUGGEST_COUNT, "3"),
    -    "//lst[@name='suggest']/lst[@name='suggestions']/lst[@name='cyhnce']/int[@name='numFound'][.='0']"
    +    "//lst[@name='suggest']/lst[@name='cyhnce']/int[@name='numFound'][.='0']"
         );
       }
     }
    
    From a18470e8588205020f331b9c533bf54737df6526 Mon Sep 17 00:00:00 2001
    From: Joel Bernstein 
    Date: Wed, 18 Dec 2013 16:06:13 +0000
    Subject: [PATCH 222/223] SOLR-5416: CollapsingQParserPlugin bug with tagging
    
    git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1551999 13f79535-47bb-0310-9956-ffa450edef68
    ---
     .../solr/search/CollapsingQParserPlugin.java  | 119 ++++++-------
     .../org/apache/solr/search/ScoreFilter.java   |  22 +++
     .../apache/solr/search/SolrIndexSearcher.java |  28 ++++
     .../search/TestCollapseQParserPlugin.java     | 156 ++++++++++++++++--
     4 files changed, 252 insertions(+), 73 deletions(-)
     create mode 100644 solr/core/src/java/org/apache/solr/search/ScoreFilter.java
    
    diff --git a/solr/core/src/java/org/apache/solr/search/CollapsingQParserPlugin.java b/solr/core/src/java/org/apache/solr/search/CollapsingQParserPlugin.java
    index e0ac59ef276..4195115e7a8 100644
    --- a/solr/core/src/java/org/apache/solr/search/CollapsingQParserPlugin.java
    +++ b/solr/core/src/java/org/apache/solr/search/CollapsingQParserPlugin.java
    @@ -118,21 +118,15 @@ public class CollapsingQParserPlugin extends QParserPlugin {
         }
       }
     
    -  private class CollapsingPostFilter extends ExtendedQueryBase implements PostFilter {
    +  public class CollapsingPostFilter extends ExtendedQueryBase implements PostFilter, ScoreFilter {
     
         private Object cacheId;
         private String field;
    -    private int leafCount;
    -    private SortedDocValues docValues;
    -    private int maxDoc;
         private String max;
         private String min;
    -    private FieldType fieldType;
    +    private boolean needsScores = true;
         private int nullPolicy;
    -    private SolrIndexSearcher searcher;
    -    private SolrParams solrParams;
         private Map context;
    -    private IndexSchema schema;
         public static final int NULL_POLICY_IGNORE = 0;
         public static final int NULL_POLICY_COLLAPSE = 1;
         public static final int NULL_POLICY_EXPAND = 2;
    @@ -180,7 +174,13 @@ public class CollapsingQParserPlugin extends QParserPlugin {
         public CollapsingPostFilter(SolrParams localParams, SolrParams params, SolrQueryRequest request) throws IOException {
           this.cacheId = new Object();
           this.field = localParams.get("field");
    -      this.solrParams = params;
    +      this.max = localParams.get("max");
    +      this.min = localParams.get("min");
    +      this.context = request.getContext();
    +      if(this.min != null || this.max != null) {
    +        this.needsScores = needsScores(params);
    +      }
    +
           String nPolicy = localParams.get("nullPolicy", NULL_IGNORE);
           if(nPolicy.equals(NULL_IGNORE)) {
             this.nullPolicy = NULL_POLICY_IGNORE;
    @@ -191,34 +191,12 @@ public class CollapsingQParserPlugin extends QParserPlugin {
           } else {
             throw new IOException("Invalid nullPolicy:"+nPolicy);
           }
    -      this.searcher = request.getSearcher();
    -      this.leafCount = searcher.getTopReaderContext().leaves().size();
    -      this.maxDoc = searcher.maxDoc();
    -      this.schema = searcher.getSchema();
    -      SchemaField schemaField = schema.getField(this.field);
    -      if(schemaField.hasDocValues()) {
    -        this.docValues = searcher.getAtomicReader().getSortedDocValues(this.field);
    -      } else {
    -        this.docValues = FieldCache.DEFAULT.getTermsIndex(searcher.getAtomicReader(), this.field);
    -      }
    -
    -      this.max = localParams.get("max");
    -      if(this.max != null) {
    -        this.fieldType = searcher.getSchema().getField(this.max).getType();
    -      }
    -
    -      this.min = localParams.get("min");
    -      if(this.min != null) {
    -        this.fieldType = searcher.getSchema().getField(this.min).getType();
    -      }
    -
    -      this.context = request.getContext();
         }
     
    -    private IntOpenHashSet getBoostDocs(IndexSearcher indexSearcher, Set boosted) throws IOException {
    +    private IntOpenHashSet getBoostDocs(SolrIndexSearcher indexSearcher, Set boosted) throws IOException {
           IntOpenHashSet boostDocs = null;
           if(boosted != null) {
    -        SchemaField idField = this.schema.getUniqueKeyField();
    +        SchemaField idField = indexSearcher.getSchema().getUniqueKeyField();
             String fieldName = idField.getName();
             HashSet localBoosts = new HashSet(boosted.size()*2);
             Iterator boostedIt = boosted.iterator();
    @@ -258,22 +236,47 @@ public class CollapsingQParserPlugin extends QParserPlugin {
     
         public DelegatingCollector getFilterCollector(IndexSearcher indexSearcher) {
           try {
    -        IntOpenHashSet boostDocs = getBoostDocs(indexSearcher, (Set) (this.context.get(QueryElevationComponent.BOOSTED)));
    +
    +        SolrIndexSearcher searcher = (SolrIndexSearcher)indexSearcher;
    +        IndexSchema schema = searcher.getSchema();
    +        SchemaField schemaField = schema.getField(this.field);
    +
    +        SortedDocValues docValues = null;
    +
    +        if(schemaField.hasDocValues()) {
    +          docValues = searcher.getAtomicReader().getSortedDocValues(this.field);
    +        } else {
    +          docValues = FieldCache.DEFAULT.getTermsIndex(searcher.getAtomicReader(), this.field);
    +        }
    +
    +        FieldType fieldType = null;
    +
    +        if(this.max != null) {
    +          fieldType = searcher.getSchema().getField(this.max).getType();
    +        }
    +
    +        if(this.min != null) {
    +          fieldType = searcher.getSchema().getField(this.min).getType();
    +        }
    +
    +        int maxDoc = searcher.maxDoc();
    +        int leafCount = searcher.getTopReaderContext().leaves().size();
    +
    +        IntOpenHashSet boostDocs = getBoostDocs(searcher, (Set) (this.context.get(QueryElevationComponent.BOOSTED)));
     
             if(this.min != null || this.max != null) {
     
    -          return new CollapsingFieldValueCollector(this.maxDoc,
    -              this.leafCount,
    -              this.docValues,
    -              this.searcher,
    -              this.nullPolicy,
    -              max != null ? this.max : this.min,
    -              max != null,
    -              needsScores(this.solrParams),
    -              this.fieldType,
    -              boostDocs);
    +          return new CollapsingFieldValueCollector(maxDoc,
    +                                                   leafCount,
    +                                                   docValues,
    +                                                   this.nullPolicy,
    +                                                   max != null ? this.max : this.min,
    +                                                   max != null,
    +                                                   this.needsScores,
    +                                                   fieldType,
    +                                                   boostDocs);
             } else {
    -          return new CollapsingScoreCollector(this.maxDoc, this.leafCount, this.docValues, this.nullPolicy, boostDocs);
    +          return new CollapsingScoreCollector(maxDoc, leafCount, docValues, this.nullPolicy, boostDocs);
             }
           } catch (Exception e) {
             throw new RuntimeException(e);
    @@ -283,7 +286,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
         private boolean needsScores(SolrParams params) {
     
           String sortSpec = params.get("sort");
    -      if(sortSpec != null) {
    +      if(sortSpec != null && sortSpec.length()!=0) {
             String[] sorts = sortSpec.split(",");
             for(String s: sorts) {
               String parts[] = s.split(" ");
    @@ -500,7 +503,6 @@ public class CollapsingQParserPlugin extends QParserPlugin {
         public CollapsingFieldValueCollector(int maxDoc,
                                              int segments,
                                              SortedDocValues values,
    -                                         SolrIndexSearcher searcher,
                                              int nullPolicy,
                                              String field,
                                              boolean max,
    @@ -516,11 +518,11 @@ public class CollapsingQParserPlugin extends QParserPlugin {
           this.needsScores = needsScores;
           this.boostDocs = boostDocs;
           if(fieldType instanceof TrieIntField) {
    -        this.fieldValueCollapse = new IntValueCollapse(searcher, field, nullPolicy, new int[valueCount], max, this.needsScores, boostDocs);
    +        this.fieldValueCollapse = new IntValueCollapse(maxDoc, field, nullPolicy, new int[valueCount], max, this.needsScores, boostDocs);
           } else if(fieldType instanceof TrieLongField) {
    -        this.fieldValueCollapse =  new LongValueCollapse(searcher, field, nullPolicy, new int[valueCount], max, this.needsScores, boostDocs);
    +        this.fieldValueCollapse =  new LongValueCollapse(maxDoc, field, nullPolicy, new int[valueCount], max, this.needsScores, boostDocs);
           } else if(fieldType instanceof TrieFloatField) {
    -        this.fieldValueCollapse =  new FloatValueCollapse(searcher, field, nullPolicy, new int[valueCount], max, this.needsScores, boostDocs);
    +        this.fieldValueCollapse =  new FloatValueCollapse(maxDoc, field, nullPolicy, new int[valueCount], max, this.needsScores, boostDocs);
           } else {
             throw new IOException("min/max must be either TrieInt, TrieLong or TrieFloat.");
           }
    @@ -616,7 +618,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
         public abstract void collapse(int ord, int contextDoc, int globalDoc) throws IOException;
         public abstract void setNextReader(AtomicReaderContext context) throws IOException;
     
    -    public FieldValueCollapse(SolrIndexSearcher searcher,
    +    public FieldValueCollapse(int maxDoc,
                                   String field,
                                   int nullPolicy,
                                   boolean max,
    @@ -626,7 +628,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
           this.nullPolicy = nullPolicy;
           this.max = max;
           this.needsScores = needsScores;
    -      this.collapsedSet = new OpenBitSet(searcher.maxDoc());
    +      this.collapsedSet = new OpenBitSet(maxDoc);
           this.boostDocs = boostDocs;
           if(this.boostDocs != null) {
             Iterator it = boostDocs.iterator();
    @@ -676,14 +678,14 @@ public class CollapsingQParserPlugin extends QParserPlugin {
         private int nullVal;
         private int[] ordVals;
     
    -    public IntValueCollapse(SolrIndexSearcher searcher,
    +    public IntValueCollapse(int maxDoc,
                                 String field,
                                 int nullPolicy,
                                 int[] ords,
                                 boolean max,
                                 boolean needsScores,
                                 IntOpenHashSet boostDocs) throws IOException {
    -      super(searcher, field, nullPolicy, max, needsScores, boostDocs);
    +      super(maxDoc, field, nullPolicy, max, needsScores, boostDocs);
           this.ords = ords;
           this.ordVals = new int[ords.length];
           Arrays.fill(ords, -1);
    @@ -745,14 +747,13 @@ public class CollapsingQParserPlugin extends QParserPlugin {
         private long nullVal;
         private long[] ordVals;
     
    -    public LongValueCollapse(SolrIndexSearcher searcher,
    -                             String field,
    +    public LongValueCollapse(int maxDoc, String field,
                                  int nullPolicy,
                                  int[] ords,
                                  boolean max,
                                  boolean needsScores,
                                  IntOpenHashSet boostDocs) throws IOException {
    -      super(searcher, field, nullPolicy, max, needsScores, boostDocs);
    +      super(maxDoc, field, nullPolicy, max, needsScores, boostDocs);
           this.ords = ords;
           this.ordVals = new long[ords.length];
           Arrays.fill(ords, -1);
    @@ -814,14 +815,14 @@ public class CollapsingQParserPlugin extends QParserPlugin {
         private float nullVal;
         private float[] ordVals;
     
    -    public FloatValueCollapse(SolrIndexSearcher searcher,
    +    public FloatValueCollapse(int maxDoc,
                                   String field,
                                   int nullPolicy,
                                   int[] ords,
                                   boolean max,
                                   boolean needsScores,
                                   IntOpenHashSet boostDocs) throws IOException {
    -      super(searcher, field, nullPolicy, max, needsScores, boostDocs);
    +      super(maxDoc, field, nullPolicy, max, needsScores, boostDocs);
           this.ords = ords;
           this.ordVals = new float[ords.length];
           Arrays.fill(ords, -1);
    diff --git a/solr/core/src/java/org/apache/solr/search/ScoreFilter.java b/solr/core/src/java/org/apache/solr/search/ScoreFilter.java
    new file mode 100644
    index 00000000000..dfe51b5997a
    --- /dev/null
    +++ b/solr/core/src/java/org/apache/solr/search/ScoreFilter.java
    @@ -0,0 +1,22 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.solr.search;
    +
    +public interface ScoreFilter {
    +
    +}
    \ No newline at end of file
    diff --git a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
    index bad1d954625..f2e6297390f 100644
    --- a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
    +++ b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
    @@ -863,6 +863,25 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable,SolrIn
         }
       };
     
    +  private DocSet getDocSetScore(List queries) throws IOException {
    +    Query main = queries.remove(0);
    +    ProcessedFilter pf = getProcessedFilter(null, queries);
    +    DocSetCollector setCollector = new DocSetCollector(maxDoc()>>6, maxDoc());
    +    Collector collector = setCollector;
    +    if (pf.postFilter != null) {
    +      pf.postFilter.setLastDelegate(collector);
    +      collector = pf.postFilter;
    +    }
    +
    +    search(main, pf.filter, collector);
    +
    +    if(collector instanceof DelegatingCollector) {
    +      ((DelegatingCollector) collector).finish();
    +    }
    +
    +    DocSet docSet = setCollector.getDocSet();
    +    return docSet;
    +  }
     
       /**
        * Returns the set of document ids matching all queries.
    @@ -873,6 +892,15 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable,SolrIn
        * The DocSet returned should not be modified.
        */
       public DocSet getDocSet(List queries) throws IOException {
    +
    +    if(queries != null) {
    +      for(Query q : queries) {
    +        if(q instanceof ScoreFilter) {
    +          return getDocSetScore(queries);
    +        }
    +      }
    +    }
    +
         ProcessedFilter pf = getProcessedFilter(null, queries);
         if (pf.answer != null) return pf.answer;
     
    diff --git a/solr/core/src/test/org/apache/solr/search/TestCollapseQParserPlugin.java b/solr/core/src/test/org/apache/solr/search/TestCollapseQParserPlugin.java
    index f79bb511adc..c198e50e27b 100644
    --- a/solr/core/src/test/org/apache/solr/search/TestCollapseQParserPlugin.java
    +++ b/solr/core/src/test/org/apache/solr/search/TestCollapseQParserPlugin.java
    @@ -47,24 +47,54 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
       public void testCollapseQueries() throws Exception {
         String[] doc = {"id","1", "term_s", "YYYY", "group_s", "group1", "test_ti", "5", "test_tl", "10", "test_tf", "2000"};
         assertU(adoc(doc));
    +    assertU(commit());
         String[] doc1 = {"id","2", "term_s","YYYY", "group_s", "group1", "test_ti", "50", "test_tl", "100", "test_tf", "200"};
         assertU(adoc(doc1));
     
    +
    +
         String[] doc2 = {"id","3", "term_s", "YYYY", "test_ti", "5000", "test_tl", "100", "test_tf", "200"};
         assertU(adoc(doc2));
    -
    +    assertU(commit());
         String[] doc3 = {"id","4", "term_s", "YYYY", "test_ti", "500", "test_tl", "1000", "test_tf", "2000"};
         assertU(adoc(doc3));
     
    +
    +    String[] doc4 = {"id","5", "term_s", "YYYY", "group_s", "group2", "test_ti", "4", "test_tl", "10", "test_tf", "2000"};
    +    assertU(adoc(doc4));
    +    assertU(commit());
    +    String[] doc5 = {"id","6", "term_s","YYYY", "group_s", "group2", "test_ti", "10", "test_tl", "100", "test_tf", "200"};
    +    assertU(adoc(doc5));
         assertU(commit());
     
    -    //Test collapse by score
    +
    +
    +    //Test collapse by score and following sort by score
         ModifiableSolrParams params = new ModifiableSolrParams();
         params.add("q", "*:*");
         params.add("fq", "{!collapse field=group_s}");
         params.add("defType", "edismax");
         params.add("bf", "field(test_ti)");
    -    assertQ(req(params), "*[count(//doc)=1]", "//doc[./int[@name='test_ti']='50']");
    +    assertQ(req(params), "*[count(//doc)=2]",
    +                       "//result/doc[1]/float[@name='id'][.='2.0']",
    +                       "//result/doc[2]/float[@name='id'][.='6.0']"
    +        );
    +
    +
    +    // SOLR-5544 test ordering with empty sort param
    +    params = new ModifiableSolrParams();
    +    params.add("q", "*:*");
    +    params.add("fq", "{!collapse field=group_s nullPolicy=expand min=test_tf}");
    +    params.add("defType", "edismax");
    +    params.add("bf", "field(test_ti)");
    +    params.add("sort","");
    +    assertQ(req(params), "*[count(//doc)=4]",
    +        "//result/doc[1]/float[@name='id'][.='3.0']",
    +        "//result/doc[2]/float[@name='id'][.='4.0']",
    +        "//result/doc[3]/float[@name='id'][.='2.0']",
    +        "//result/doc[4]/float[@name='id'][.='6.0']"
    +    );
    +
     
         //Test collapse by score with elevation
     
    @@ -75,54 +105,152 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
         params.add("bf", "field(test_ti)");
         params.add("qf", "term_s");
         params.add("qt", "/elevate");
    -    assertQ(req(params), "*[count(//doc)=3]", "//doc[./int[1][@name='test_ti']='5']");
    +    assertQ(req(params), "*[count(//doc)=4]",
    +                         "//result/doc[1]/float[@name='id'][.='1.0']");
     
    -    //Test collapse by min int field
    +
    +
    +
    +    //Test collapse by min int field and sort
         params = new ModifiableSolrParams();
         params.add("q", "*:*");
         params.add("fq", "{!collapse field=group_s min=test_ti}");
    -    assertQ(req(params), "*[count(//doc)=1]", "//doc[./int[@name='test_ti']='5']");
    +    params.add("sort", "id desc");
    +    assertQ(req(params), "*[count(//doc)=2]",
    +                           "//result/doc[1]/float[@name='id'][.='5.0']",
    +                           "//result/doc[2]/float[@name='id'][.='1.0']");
    +
    +    params = new ModifiableSolrParams();
    +    params.add("q", "*:*");
    +    params.add("fq", "{!collapse field=group_s min=test_ti}");
    +    params.add("sort", "id asc");
    +    assertQ(req(params), "*[count(//doc)=2]",
    +                         "//result/doc[1]/float[@name='id'][.='1.0']",
    +                         "//result/doc[2]/float[@name='id'][.='5.0']");
    +
    +    params = new ModifiableSolrParams();
    +    params.add("q", "*:*");
    +    params.add("fq", "{!collapse field=group_s min=test_ti}");
    +    params.add("sort", "test_tl asc,id desc");
    +    assertQ(req(params), "*[count(//doc)=2]",
    +        "//result/doc[1]/float[@name='id'][.='5.0']",
    +        "//result/doc[2]/float[@name='id'][.='1.0']");
    +
    +    params = new ModifiableSolrParams();
    +    params.add("q", "*:*");
    +    params.add("fq", "{!collapse field=group_s min=test_ti}");
    +    params.add("sort", "score desc,id asc");
    +    params.add("defType", "edismax");
    +    params.add("bf", "field(id)");
    +    assertQ(req(params), "*[count(//doc)=2]",
    +                          "//result/doc[1]/float[@name='id'][.='5.0']",
    +                          "//result/doc[2]/float[@name='id'][.='1.0']");
    +
    +
    +
     
         //Test collapse by max int field
         params = new ModifiableSolrParams();
         params.add("q", "*:*");
         params.add("fq", "{!collapse field=group_s max=test_ti}");
    -    assertQ(req(params), "*[count(//doc)=1]", "//doc[./int[@name='test_ti']='50']");
    +    params.add("sort", "test_ti asc");
    +    assertQ(req(params), "*[count(//doc)=2]",
    +                         "//result/doc[1]/float[@name='id'][.='6.0']",
    +                         "//result/doc[2]/float[@name='id'][.='2.0']"
    +        );
    +
    +
     
         //Test collapse by min long field
         params = new ModifiableSolrParams();
         params.add("q", "*:*");
         params.add("fq", "{!collapse field=group_s min=test_tl}");
    -    assertQ(req(params), "*[count(//doc)=1]", "//doc[./int[@name='test_ti']='5']");
    +    params.add("sort", "test_ti desc");
    +    assertQ(req(params), "*[count(//doc)=2]",
    +        "//result/doc[1]/float[@name='id'][.='1.0']",
    +        "//result/doc[2]/float[@name='id'][.='5.0']");
    +
     
         //Test collapse by max long field
         params = new ModifiableSolrParams();
         params.add("q", "*:*");
         params.add("fq", "{!collapse field=group_s max=test_tl}");
    -    assertQ(req(params), "*[count(//doc)=1]", "//doc[./int[@name='test_ti']='50']");
    +    params.add("sort", "test_ti desc");
    +    assertQ(req(params), "*[count(//doc)=2]",
    +                         "//result/doc[1]/float[@name='id'][.='2.0']",
    +                         "//result/doc[2]/float[@name='id'][.='6.0']");
    +
     
         //Test collapse by min float field
         params = new ModifiableSolrParams();
         params.add("q", "*:*");
         params.add("fq", "{!collapse field=group_s min=test_tf}");
    -    assertQ(req(params), "*[count(//doc)=1]", "//doc[./int[@name='test_ti']='50']");
    +    params.add("sort", "test_ti desc");
    +    assertQ(req(params), "*[count(//doc)=2]",
    +                         "//result/doc[1]/float[@name='id'][.='2.0']",
    +                         "//result/doc[2]/float[@name='id'][.='6.0']");
    +
    +
    +
     
         //Test collapse by min float field
         params = new ModifiableSolrParams();
         params.add("q", "*:*");
         params.add("fq", "{!collapse field=group_s max=test_tf}");
    -    assertQ(req(params), "*[count(//doc)=1]", "//doc[./int[@name='test_ti']='5']");
    +    params.add("sort", "test_ti asc");
    +    assertQ(req(params), "*[count(//doc)=2]",
    +                         "//result/doc[1]/float[@name='id'][.='5.0']",
    +                         "//result/doc[2]/float[@name='id'][.='1.0']");
    +
    +    //Test collapse by min float field sort by score
    +    params = new ModifiableSolrParams();
    +    params.add("q", "*:*");
    +    params.add("fq", "{!collapse field=group_s max=test_tf}");
    +    params.add("defType", "edismax");
    +    params.add("bf", "field(id)");
    +    params.add("fl", "score, id");
    +    params.add("facet","true");
    +    params.add("fq", "{!tag=test}term_s:YYYY");
    +    params.add("facet.field", "{!ex=test}term_s");
    +
    +    assertQ(req(params), "*[count(//doc)=2]",
    +        "//result/doc[1]/float[@name='id'][.='5.0']",
    +        "//result/doc[2]/float[@name='id'][.='1.0']");
    +
     
         //Test nullPolicy expand
         params = new ModifiableSolrParams();
         params.add("q", "*:*");
         params.add("fq", "{!collapse field=group_s max=test_tf nullPolicy=expand}");
    -    assertQ(req(params), "*[count(//doc)=3]");
    +    params.add("sort", "id desc");
    +    assertQ(req(params), "*[count(//doc)=4]",
    +        "//result/doc[1]/float[@name='id'][.='5.0']",
    +        "//result/doc[2]/float[@name='id'][.='4.0']",
    +        "//result/doc[3]/float[@name='id'][.='3.0']",
    +        "//result/doc[4]/float[@name='id'][.='1.0']");
     
         //Test nullPolicy collapse
    +
         params = new ModifiableSolrParams();
    -    params.add("q", "test_ti:(500 5000)");
    +    params.add("q", "*:*");
         params.add("fq", "{!collapse field=group_s max=test_tf nullPolicy=collapse}");
    -    assertQ(req(params), "*[count(//doc)=1]", "//doc[./int[@name='test_ti']='500']");
    +    params.add("sort", "id desc");
    +    assertQ(req(params), "*[count(//doc)=3]",
    +        "//result/doc[1]/float[@name='id'][.='5.0']",
    +        "//result/doc[2]/float[@name='id'][.='4.0']",
    +        "//result/doc[3]/float[@name='id'][.='1.0']");
    +
    +
    +    params = new ModifiableSolrParams();
    +    params.add("q", "*:*");
    +    params.add("fq", "{!collapse field=group_s}");
    +    params.add("defType", "edismax");
    +    params.add("bf", "field(test_ti)");
    +    params.add("fq","{!tag=test_ti}id:5");
    +    params.add("facet","true");
    +    params.add("facet.field","{!ex=test_ti}test_ti");
    +    params.add("facet.mincount", "1");
    +    assertQ(req(params), "*[count(//doc)=1]", "*[count(//lst[@name='facet_fields']/lst[@name='test_ti']/int)=2]");
    +
       }
     }
    
    From 25b53be6f97c7b579c46196d426e9f40cd0938fd Mon Sep 17 00:00:00 2001
    From: Alan Woodward 
    Date: Wed, 18 Dec 2013 17:35:24 +0000
    Subject: [PATCH 223/223] SOLR-5556: Allow CollectionsHandler and InfoHandler
     classes to be specified in solr.xml
    
    git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1552044 13f79535-47bb-0310-9956-ffa450edef68
    ---
     solr/CHANGES.txt                              |  3 ++
     .../java/org/apache/solr/core/ConfigSolr.java | 10 ++++
     .../org/apache/solr/core/ConfigSolrXml.java   |  2 +
     .../apache/solr/core/ConfigSolrXmlOld.java    |  2 +
     .../org/apache/solr/core/CoreContainer.java   | 33 ++++++------
     solr/core/src/test-files/solr/solr-50-all.xml |  2 +
     .../apache/solr/core/TestCoreContainer.java   | 50 +++++++++++++++++++
     .../org/apache/solr/core/TestSolrXml.java     |  2 +
     8 files changed, 87 insertions(+), 17 deletions(-)
    
    diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
    index 2ec5a2125a2..133fed69085 100644
    --- a/solr/CHANGES.txt
    +++ b/solr/CHANGES.txt
    @@ -129,6 +129,9 @@ New Features
     * SOLR-1871: The 'map' function query accepts a ValueSource as target and
       default value. (Chris Harris, shalin)
     
    +* SOLR-5556: Allow class of CollectionsHandler and InfoHandler to be specified
    +  in solr.xml. (Gregory Chanan, Alan Woodward)
    +
     Bug Fixes
     ----------------------
     
    diff --git a/solr/core/src/java/org/apache/solr/core/ConfigSolr.java b/solr/core/src/java/org/apache/solr/core/ConfigSolr.java
    index 45ffb1638bb..78f70d0a066 100644
    --- a/solr/core/src/java/org/apache/solr/core/ConfigSolr.java
    +++ b/solr/core/src/java/org/apache/solr/core/ConfigSolr.java
    @@ -187,6 +187,14 @@ public abstract class ConfigSolr {
         return get(CfgProp.SOLR_ADMINHANDLER, "org.apache.solr.handler.admin.CoreAdminHandler");
       }
     
    +  public String getCollectionsHandlerClass() {
    +    return get(CfgProp.SOLR_COLLECTIONSHANDLER, "org.apache.solr.handler.admin.CollectionsHandler");
    +  }
    +
    +  public String getInfoHandlerClass() {
    +    return get(CfgProp.SOLR_INFOHANDLER, "org.apache.solr.handler.admin.InfoHandler");
    +  }
    +
       public boolean hasSchemaCache() {
         return getBool(ConfigSolr.CfgProp.SOLR_SHARESCHEMA, false);
       }
    @@ -211,6 +219,7 @@ public abstract class ConfigSolr {
       // Ugly for now, but we'll at least be able to centralize all of the differences between 4x and 5x.
       protected static enum CfgProp {
         SOLR_ADMINHANDLER,
    +    SOLR_COLLECTIONSHANDLER,
         SOLR_CORELOADTHREADS,
         SOLR_COREROOTDIRECTORY,
         SOLR_DISTRIBUPDATECONNTIMEOUT,
    @@ -220,6 +229,7 @@ public abstract class ConfigSolr {
         SOLR_HOST,
         SOLR_HOSTCONTEXT,
         SOLR_HOSTPORT,
    +    SOLR_INFOHANDLER,
         SOLR_LEADERVOTEWAIT,
         SOLR_LOGGING_CLASS,
         SOLR_LOGGING_ENABLED,
    diff --git a/solr/core/src/java/org/apache/solr/core/ConfigSolrXml.java b/solr/core/src/java/org/apache/solr/core/ConfigSolrXml.java
    index f4186a51c14..35b7e5e8b6f 100644
    --- a/solr/core/src/java/org/apache/solr/core/ConfigSolrXml.java
    +++ b/solr/core/src/java/org/apache/solr/core/ConfigSolrXml.java
    @@ -103,6 +103,8 @@ public class ConfigSolrXml extends ConfigSolr {
       
       private void fillPropMap() {
         propMap.put(CfgProp.SOLR_ADMINHANDLER, doSub("solr/str[@name='adminHandler']"));
    +    propMap.put(CfgProp.SOLR_COLLECTIONSHANDLER, doSub("solr/str[@name='collectionsHandler']"));
    +    propMap.put(CfgProp.SOLR_INFOHANDLER, doSub("solr/str[@name='infoHandler']"));
         propMap.put(CfgProp.SOLR_CORELOADTHREADS, doSub("solr/int[@name='coreLoadThreads']"));
         propMap.put(CfgProp.SOLR_COREROOTDIRECTORY, doSub("solr/str[@name='coreRootDirectory']"));
         propMap.put(CfgProp.SOLR_DISTRIBUPDATECONNTIMEOUT, doSub("solr/solrcloud/int[@name='distribUpdateConnTimeout']"));
    diff --git a/solr/core/src/java/org/apache/solr/core/ConfigSolrXmlOld.java b/solr/core/src/java/org/apache/solr/core/ConfigSolrXmlOld.java
    index d18445fcef0..f33bf620327 100644
    --- a/solr/core/src/java/org/apache/solr/core/ConfigSolrXmlOld.java
    +++ b/solr/core/src/java/org/apache/solr/core/ConfigSolrXmlOld.java
    @@ -141,6 +141,8 @@ public class ConfigSolrXmlOld extends ConfigSolr {
         
         propMap.put(CfgProp.SOLR_ADMINHANDLER,
             config.getVal("solr/cores/@adminHandler", false));
    +    propMap.put(CfgProp.SOLR_COLLECTIONSHANDLER, config.getVal("solr/cores/@collectionsHandler", false));
    +    propMap.put(CfgProp.SOLR_INFOHANDLER, config.getVal("solr/cores/@infoHandler", false));
         propMap.put(CfgProp.SOLR_DISTRIBUPDATECONNTIMEOUT,
             config.getVal("solr/cores/@distribUpdateConnTimeout", false));
         propMap.put(CfgProp.SOLR_DISTRIBUPDATESOTIMEOUT,
    diff --git a/solr/core/src/java/org/apache/solr/core/CoreContainer.java b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
    index 20b8e5dd3ee..c088a5214ee 100644
    --- a/solr/core/src/java/org/apache/solr/core/CoreContainer.java
    +++ b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
    @@ -214,9 +214,9 @@ public class CoreContainer {
     
         zkSys.initZooKeeper(this, solrHome, cfg);
     
    -    collectionsHandler = new CollectionsHandler(this);
    -    infoHandler = new InfoHandler(this);
    -    coreAdminHandler = createMultiCoreHandler(cfg.getCoreAdminHandlerClass());
    +    collectionsHandler = createHandler(cfg.getCollectionsHandlerClass(), CollectionsHandler.class);
    +    infoHandler        = createHandler(cfg.getInfoHandlerClass(), InfoHandler.class);
    +    coreAdminHandler   = createHandler(cfg.getCoreAdminHandlerClass(), CoreAdminHandler.class);
     
         containerProperties = cfg.getSolrProperties("solr");
     
    @@ -778,10 +778,10 @@ public class CoreContainer {
         return null;
       }
     
    -  /** 
    +  /**
        * Gets a core by name and increase its refcount.
        *
    -   * @see SolrCore#close() 
    +   * @see SolrCore#close()
        * @param name the core name
        * @return the core if found, null if a SolrCore by this name does not exist
        * @exception SolrException if a SolrCore with this name failed to be initialized
    @@ -800,7 +800,7 @@ public class CoreContainer {
         // OK, it's not presently in any list, is it in the list of dynamic cores but not loaded yet? If so, load it.
         CoreDescriptor desc = solrCores.getDynamicDescriptor(name);
         if (desc == null) { //Nope, no transient core with this name
    -      
    +
           // if there was an error initalizing this core, throw a 500
           // error with the details for clients attempting to access it.
           Exception e = getCoreInitFailures().get(name);
    @@ -831,7 +831,7 @@ public class CoreContainer {
           }
         } catch(Exception ex){
           // remains to be seen how transient cores and such
    -      // will work in SolrCloud mode, but just to be future 
    +      // will work in SolrCloud mode, but just to be future
           // proof...
           /*if (isZooKeeperAware()) {
             try {
    @@ -851,34 +851,33 @@ public class CoreContainer {
         return core;
       }
     
    -  // ---------------- Multicore self related methods ---------------
    -  /** 
    -   * Creates a CoreAdminHandler for this MultiCore.
    -   * @return a CoreAdminHandler
    -   */
    -  protected CoreAdminHandler createMultiCoreHandler(final String adminHandlerClass) {
    -    return loader.newAdminHandlerInstance(CoreContainer.this, adminHandlerClass);
    +  // ---------------- CoreContainer request handlers --------------
    +
    +  protected  T createHandler(String handlerClass, Class clazz) {
    +    return loader.newInstance(handlerClass, clazz, null, new Class[] { CoreContainer.class }, new Object[] { this });
       }
     
       public CoreAdminHandler getMultiCoreHandler() {
         return coreAdminHandler;
       }
    -  
    +
       public CollectionsHandler getCollectionsHandler() {
         return collectionsHandler;
       }
    -  
    +
       public InfoHandler getInfoHandler() {
         return infoHandler;
       }
     
    +  // ---------------- Multicore self related methods ---------------
    +
       /**
        * the default core name, or null if there is no default core name
        */
       public String getDefaultCoreName() {
         return cfg.getDefaultCoreName();
       }
    -  
    +
       // all of the following properties aren't synchronized
       // but this should be OK since they normally won't be changed rapidly
       @Deprecated
    diff --git a/solr/core/src/test-files/solr/solr-50-all.xml b/solr/core/src/test-files/solr/solr-50-all.xml
    index cb6646abdae..32e52fb0028 100644
    --- a/solr/core/src/test-files/solr/solr-50-all.xml
    +++ b/solr/core/src/test-files/solr/solr-50-all.xml
    @@ -17,8 +17,10 @@
     
     
       testAdminHandler
    +  testCollectionsHandler
       11
       ${coreRootDirectory:testCoreRootDirectory}
    +  testInfoHandler
       testManagementPath
       testSharedLib
       ${shareSchema:testShareSchema}
    diff --git a/solr/core/src/test/org/apache/solr/core/TestCoreContainer.java b/solr/core/src/test/org/apache/solr/core/TestCoreContainer.java
    index 5679943c24a..1e62d639b59 100644
    --- a/solr/core/src/test/org/apache/solr/core/TestCoreContainer.java
    +++ b/solr/core/src/test/org/apache/solr/core/TestCoreContainer.java
    @@ -21,6 +21,9 @@ import org.apache.commons.io.FileUtils;
     import org.apache.lucene.util.IOUtils;
     import org.apache.lucene.util._TestUtil;
     import org.apache.solr.SolrTestCaseJ4;
    +import org.apache.solr.handler.admin.CollectionsHandler;
    +import org.apache.solr.handler.admin.CoreAdminHandler;
    +import org.apache.solr.handler.admin.InfoHandler;
     import org.junit.AfterClass;
     import org.junit.BeforeClass;
     import org.junit.Test;
    @@ -37,6 +40,9 @@ import java.util.List;
     import java.util.jar.JarEntry;
     import java.util.jar.JarOutputStream;
     
    +import static org.hamcrest.core.Is.is;
    +import static org.hamcrest.core.IsInstanceOf.instanceOf;
    +
     public class TestCoreContainer extends SolrTestCaseJ4 {
     
       private static String oldSolrHome;
    @@ -287,4 +293,48 @@ public class TestCoreContainer extends SolrTestCaseJ4 {
       private static final String EMPTY_SOLR_XML2 ="\n" +
           "\n" +
           "";
    +
    +  private static final String CUSTOM_HANDLERS_SOLR_XML = "\n" +
    +      "" +
    +      " " + CustomCollectionsHandler.class.getName() + "" +
    +      " " + CustomInfoHandler.class.getName() + "" +
    +      " " + CustomCoreAdminHandler.class.getName() + "" +
    +      "";
    +
    +  public static class CustomCollectionsHandler extends CollectionsHandler {
    +    public CustomCollectionsHandler(CoreContainer cc) {
    +      super(cc);
    +    }
    +  }
    +
    +  public static class CustomInfoHandler extends InfoHandler {
    +    public CustomInfoHandler(CoreContainer cc) {
    +      super(cc);
    +    }
    +  }
    +
    +  public static class CustomCoreAdminHandler extends CoreAdminHandler {
    +    public CustomCoreAdminHandler(CoreContainer cc) {
    +      super(cc);
    +    }
    +  }
    +
    +  @Test
    +  public void testCustomHandlers() throws Exception {
    +
    +    ConfigSolr config = ConfigSolr.fromString(CUSTOM_HANDLERS_SOLR_XML);
    +    SolrResourceLoader loader = new SolrResourceLoader("solr/collection1");
    +
    +    CoreContainer cc = new CoreContainer(loader, config);
    +    try {
    +      cc.load();
    +      assertThat(cc.getCollectionsHandler(), is(instanceOf(CustomCollectionsHandler.class)));
    +      assertThat(cc.getInfoHandler(), is(instanceOf(CustomInfoHandler.class)));
    +      assertThat(cc.getMultiCoreHandler(), is(instanceOf(CustomCoreAdminHandler.class)));
    +    }
    +    finally {
    +      cc.shutdown();
    +    }
    +
    +  }
     }
    diff --git a/solr/core/src/test/org/apache/solr/core/TestSolrXml.java b/solr/core/src/test/org/apache/solr/core/TestSolrXml.java
    index 566749a3749..b70c52da7b6 100644
    --- a/solr/core/src/test/org/apache/solr/core/TestSolrXml.java
    +++ b/solr/core/src/test/org/apache/solr/core/TestSolrXml.java
    @@ -47,6 +47,8 @@ public class TestSolrXml extends SolrTestCaseJ4 {
           ConfigSolr cfg = ConfigSolr.fromSolrHome(loader, solrHome.getAbsolutePath());
     
           assertEquals("Did not find expected value", cfg.get(ConfigSolr.CfgProp.SOLR_ADMINHANDLER, null), "testAdminHandler");
    +      assertEquals("Did not find expected value", cfg.get(ConfigSolr.CfgProp.SOLR_COLLECTIONSHANDLER, null), "testCollectionsHandler");
    +      assertEquals("Did not find expected value", cfg.get(ConfigSolr.CfgProp.SOLR_INFOHANDLER, null), "testInfoHandler");
           assertEquals("Did not find expected value", cfg.getInt(ConfigSolr.CfgProp.SOLR_CORELOADTHREADS, 0), 11);
           assertEquals("Did not find expected value", cfg.get(ConfigSolr.CfgProp.SOLR_COREROOTDIRECTORY, null), "testCoreRootDirectory");
           assertEquals("Did not find expected value", cfg.getInt(ConfigSolr.CfgProp.SOLR_DISTRIBUPDATECONNTIMEOUT, 0), 22);