Added:
incubator/solr/trunk/src/java/org/apache/solr/analysis/StandardFilterFactory.java
URL:
http://svn.apache.org/viewcvs/incubator/solr/trunk/src/java/org/apache/solr/analysis/StandardFilterFactory.java?rev=372455&view=auto
==============================================================================
---
incubator/solr/trunk/src/java/org/apache/solr/analysis/StandardFilterFactory.java
(added)
+++
incubator/solr/trunk/src/java/org/apache/solr/analysis/StandardFilterFactory.java
Wed Jan 25 21:37:29 2006
@@ -0,0 +1,30 @@
+/**
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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.
+ */
+
+package org.apache.solr.analysis;
+
+import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.standard.StandardFilter;
+
+/**
+ * @author yonik
+ * @version $Id$
+ */
+public class StandardFilterFactory extends BaseTokenFilterFactory {
+ public TokenStream create(TokenStream input) {
+ return new StandardFilter(input);
+ }
+}
Propchange:
incubator/solr/trunk/src/java/org/apache/solr/analysis/StandardFilterFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
incubator/solr/trunk/src/java/org/apache/solr/analysis/StandardTokenizerFactory.java
URL:
http://svn.apache.org/viewcvs/incubator/solr/trunk/src/java/org/apache/solr/analysis/StandardTokenizerFactory.java?rev=372455&view=auto
==============================================================================
---
incubator/solr/trunk/src/java/org/apache/solr/analysis/StandardTokenizerFactory.java
(added)
+++
incubator/solr/trunk/src/java/org/apache/solr/analysis/StandardTokenizerFactory.java
Wed Jan 25 21:37:29 2006
@@ -0,0 +1,33 @@
+/**
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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.
+ */
+
+package org.apache.solr.analysis;
+
+import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.standard.StandardTokenizer;
+
+import java.io.Reader;
+
+/**
+ * @author yonik
+ * @version $Id$
+ */
+
+public class StandardTokenizerFactory extends BaseTokenizerFactory {
+ public TokenStream create(Reader input) {
+ return new StandardTokenizer(input);
+ }
+}
Propchange:
incubator/solr/trunk/src/java/org/apache/solr/analysis/StandardTokenizerFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
incubator/solr/trunk/src/java/org/apache/solr/analysis/StopFilterFactory.java
URL:
http://svn.apache.org/viewcvs/incubator/solr/trunk/src/java/org/apache/solr/analysis/StopFilterFactory.java?rev=372455&view=auto
==============================================================================
---
incubator/solr/trunk/src/java/org/apache/solr/analysis/StopFilterFactory.java
(added)
+++
incubator/solr/trunk/src/java/org/apache/solr/analysis/StopFilterFactory.java
Wed Jan 25 21:37:29 2006
@@ -0,0 +1,55 @@
+/**
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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.
+ */
+
+package org.apache.solr.analysis;
+
+import org.apache.solr.core.Config;
+import org.apache.lucene.analysis.StopFilter;
+import org.apache.lucene.analysis.StopAnalyzer;
+import org.apache.lucene.analysis.TokenStream;
+
+import java.util.Map;
+import java.util.List;
+import java.util.Set;
+import java.io.IOException;
+
+/**
+ * @author yonik
+ * @version $Id$
+ */
+public class StopFilterFactory extends BaseTokenFilterFactory {
+ public void init(Map<String, String> args) {
+ super.init(args);
+ String stopWordFile = args.get("words");
+ ignoreCase = getBoolean("ignoreCase",false);
+
+ if (stopWordFile != null) {
+ try {
+ List<String> wlist = Config.getLines(stopWordFile);
+ stopWords = StopFilter.makeStopSet((String[])wlist.toArray(new
String[0]), ignoreCase);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ private Set stopWords =
StopFilter.makeStopSet(StopAnalyzer.ENGLISH_STOP_WORDS);
+ private boolean ignoreCase;
+
+ public TokenStream create(TokenStream input) {
+ return new StopFilter(input,stopWords,ignoreCase);
+ }
+}
Propchange:
incubator/solr/trunk/src/java/org/apache/solr/analysis/StopFilterFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
incubator/solr/trunk/src/java/org/apache/solr/analysis/SynonymFilterFactory.java
URL:
http://svn.apache.org/viewcvs/incubator/solr/trunk/src/java/org/apache/solr/analysis/SynonymFilterFactory.java?rev=372455&view=auto
==============================================================================
---
incubator/solr/trunk/src/java/org/apache/solr/analysis/SynonymFilterFactory.java
(added)
+++
incubator/solr/trunk/src/java/org/apache/solr/analysis/SynonymFilterFactory.java
Wed Jan 25 21:37:29 2006
@@ -0,0 +1,125 @@
+/**
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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.
+ */
+
+package org.apache.solr.analysis;
+
+import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.SynonymFilter;
+import org.apache.lucene.analysis.SynonymMap;
+
+import java.util.Map;
+import java.util.ArrayList;
+import java.util.List;
+import java.io.IOException;
+
+import org.apache.solr.util.StrUtils;
+import org.apache.solr.analysis.BaseTokenFilterFactory;
+import org.apache.solr.core.Config;
+import org.apache.solr.core.SolrCore;
+/**
+ * @author yonik
+ * @version $Id$
+ */
+public class SynonymFilterFactory extends BaseTokenFilterFactory {
+ public void init(Map<String, String> args) {
+ super.init(args);
+ String synonyms = args.get("synonyms");
+
+ ignoreCase = getBoolean("ignoreCase",false);
+ expand = getBoolean("expand",true);
+
+ if (synonyms != null) {
+ List<String> wlist=null;
+ try {
+ wlist = Config.getLines(synonyms);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ synMap = new SynonymMap();
+ parseRules(wlist, synMap, "=>", ",", ignoreCase,expand);
+ if (wlist.size()<=20) {
+ SolrCore.log.fine("SynonymMap "+synonyms +":"+synMap);
+ }
+ }
+
+ }
+
+ private SynonymMap synMap;
+ private boolean ignoreCase;
+ private boolean expand;
+
+ private static void parseRules(List<String> rules, SynonymMap map, String
mappingSep, String synSep, boolean ignoreCase, boolean expansion) {
+ int count=0;
+ for (String rule : rules) {
+ // To use regexes, we need an expression that specifies an odd number of
chars.
+ // This can't really be done with string.split(), and since we need to
+ // do unescaping at some point anyway, we wouldn't be saving any effort
+ // by using regexes.
+
+ List<String> mapping = StrUtils.splitSmart(rule, mappingSep, false);
+
+ List<List<String>> source;
+ List<List<String>> target;
+
+ if (mapping.size() > 2) {
+ throw new RuntimeException("Invalid Synonym Rule:" + rule);
+ } else if (mapping.size()==2) {
+ source = getSynList(mapping.get(0), synSep);
+ target = getSynList(mapping.get(1), synSep);
+ } else {
+ source = getSynList(mapping.get(0), synSep);
+ if (expansion) {
+ // expand to all arguments
+ target = source;
+ } else {
+ // reduce to first argument
+ target = new ArrayList<List<String>>(1);
+ target.add(source.get(0));
+ }
+ }
+
+ boolean includeOrig=false;
+ for (List<String> fromToks : source) {
+ count++;
+ for (List<String> toToks : target) {
+ map.add(ignoreCase ? StrUtils.toLower(fromToks) : fromToks,
+ SynonymMap.makeTokens(toToks),
+ includeOrig,
+ true);
+ }
+ }
+ }
+ }
+
+ // a , b c , d e f => [[a],[b,c],[d,e,f]]
+ private static List<List<String>> getSynList(String str, String separator) {
+ List<String> strList = StrUtils.splitSmart(str, separator, false);
+ // now split on whitespace to get a list of token strings
+ List<List<String>> synList = new ArrayList<List<String>>();
+ for (String toks : strList) {
+ List<String> tokList = StrUtils.splitWS(toks, true);
+ synList.add(tokList);
+ }
+ return synList;
+ }
+
+
+ public TokenStream create(TokenStream input) {
+ return new SynonymFilter(input,synMap,ignoreCase);
+ }
+
+
+}
Propchange:
incubator/solr/trunk/src/java/org/apache/solr/analysis/SynonymFilterFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
incubator/solr/trunk/src/java/org/apache/solr/analysis/TokenFilterFactory.java
URL:
http://svn.apache.org/viewcvs/incubator/solr/trunk/src/java/org/apache/solr/analysis/TokenFilterFactory.java?rev=372455&view=auto
==============================================================================
---
incubator/solr/trunk/src/java/org/apache/solr/analysis/TokenFilterFactory.java
(added)
+++
incubator/solr/trunk/src/java/org/apache/solr/analysis/TokenFilterFactory.java
Wed Jan 25 21:37:29 2006
@@ -0,0 +1,34 @@
+/**
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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.
+ */
+
+package org.apache.solr.analysis;
+
+import org.apache.lucene.analysis.TokenStream;
+
+import java.util.Map;
+
+/**
+ * Factory to create a token filter that transforms one TokenStream to another.
+ *
+ * @author yonik
+ * @version $Id: TokenFilterFactory.java,v 1.3 2005/09/20 04:58:28 yonik Exp $
+ */
+
+public interface TokenFilterFactory {
+ public void init(Map<String,String> args);
+ public Map<String,String> getArgs();
+ public TokenStream create(TokenStream input);
+}
Propchange:
incubator/solr/trunk/src/java/org/apache/solr/analysis/TokenFilterFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
incubator/solr/trunk/src/java/org/apache/solr/analysis/TokenizerChain.java
URL:
http://svn.apache.org/viewcvs/incubator/solr/trunk/src/java/org/apache/solr/analysis/TokenizerChain.java?rev=372455&view=auto
==============================================================================
--- incubator/solr/trunk/src/java/org/apache/solr/analysis/TokenizerChain.java
(added)
+++ incubator/solr/trunk/src/java/org/apache/solr/analysis/TokenizerChain.java
Wed Jan 25 21:37:29 2006
@@ -0,0 +1,65 @@
+/**
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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.
+ */
+
+package org.apache.solr.analysis;
+
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.analysis.TokenStream;
+import org.apache.solr.analysis.TokenizerFactory;
+
+import java.io.Reader;
+
+/**
+ * @author yonik
+ * @version $Id: TokenizerChain.java,v 1.3 2005/08/26 05:21:08 yonik Exp $
+ */
+
+//
+// An analyzer that uses a tokenizer and a list of token filters to
+// create a TokenStream.
+//
+public class TokenizerChain extends Analyzer {
+ final private TokenizerFactory tokenizer;
+ final private TokenFilterFactory[] filters;
+
+ public TokenizerChain(TokenizerFactory tokenizer, TokenFilterFactory[]
filters) {
+ this.tokenizer = tokenizer;
+ this.filters = filters;
+ }
+
+ public TokenizerFactory getTokenizerFactory() { return tokenizer; }
+ public TokenFilterFactory[] getTokenFilterFactories() { return filters; }
+
+ public TokenStream tokenStream(String fieldName, Reader reader) {
+ TokenStream ts = tokenizer.create(reader);
+ for (int i=0; i<filters.length; i++) {
+ ts = filters[i].create(ts);
+ }
+ return ts;
+ }
+
+ public String toString() {
+ StringBuilder sb = new StringBuilder("TokenizerChain(");
+ sb.append(tokenizer);
+ for (TokenFilterFactory filter: filters) {
+ sb.append(", ");
+ sb.append(filter);
+ }
+ sb.append(')');
+ return sb.toString();
+ }
+
+}
Propchange:
incubator/solr/trunk/src/java/org/apache/solr/analysis/TokenizerChain.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
incubator/solr/trunk/src/java/org/apache/solr/analysis/TokenizerFactory.java
URL:
http://svn.apache.org/viewcvs/incubator/solr/trunk/src/java/org/apache/solr/analysis/TokenizerFactory.java?rev=372455&view=auto
==============================================================================
---
incubator/solr/trunk/src/java/org/apache/solr/analysis/TokenizerFactory.java
(added)
+++
incubator/solr/trunk/src/java/org/apache/solr/analysis/TokenizerFactory.java
Wed Jan 25 21:37:29 2006
@@ -0,0 +1,37 @@
+/**
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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.
+ */
+
+package org.apache.solr.analysis;
+
+import java.io.*;
+import java.util.Map;
+
+import org.apache.lucene.analysis.*;
+
+
+/**
+ * A <code>TokenizerFactory</code> creates a <code>Tokenizer</code> on demand
+ * that breaks up a stream of characters into tokens.
+ *
+ * @author yonik
+ * @version $Id: TokenizerFactory.java,v 1.10 2005/12/13 05:16:03 yonik Exp $
+ */
+public interface TokenizerFactory {
+ public void init(Map<String,String> args);
+ public Map<String,String> getArgs();
+ public TokenStream create(Reader input);
+}
+
Propchange:
incubator/solr/trunk/src/java/org/apache/solr/analysis/TokenizerFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
incubator/solr/trunk/src/java/org/apache/solr/analysis/WhitespaceTokenizerFactory.java
URL:
http://svn.apache.org/viewcvs/incubator/solr/trunk/src/java/org/apache/solr/analysis/WhitespaceTokenizerFactory.java?rev=372455&view=auto
==============================================================================
---
incubator/solr/trunk/src/java/org/apache/solr/analysis/WhitespaceTokenizerFactory.java
(added)
+++
incubator/solr/trunk/src/java/org/apache/solr/analysis/WhitespaceTokenizerFactory.java
Wed Jan 25 21:37:29 2006
@@ -0,0 +1,32 @@
+/**
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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.
+ */
+
+package org.apache.solr.analysis;
+
+import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.WhitespaceTokenizer;
+
+import java.io.Reader;
+
+/**
+ * @author yonik
+ * @version $Id$
+ */
+public class WhitespaceTokenizerFactory extends BaseTokenizerFactory {
+ public TokenStream create(Reader input) {
+ return new WhitespaceTokenizer(input);
+ }
+}
Propchange:
incubator/solr/trunk/src/java/org/apache/solr/analysis/WhitespaceTokenizerFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
incubator/solr/trunk/src/java/org/apache/solr/analysis/WordDelimiterFilter.java
URL:
http://svn.apache.org/viewcvs/incubator/solr/trunk/src/java/org/apache/solr/analysis/WordDelimiterFilter.java?rev=372455&view=auto
==============================================================================
---
incubator/solr/trunk/src/java/org/apache/solr/analysis/WordDelimiterFilter.java
(added)
+++
incubator/solr/trunk/src/java/org/apache/solr/analysis/WordDelimiterFilter.java
Wed Jan 25 21:37:29 2006
@@ -0,0 +1,444 @@
+/**
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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.
+ */
+
+package org.apache.solr.analysis;
+
+import org.apache.lucene.analysis.TokenFilter;
+import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.Token;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Splits words into subwords and performs optional transformations on subword
groups.
+ * Words are split into subwords with the following rules:
+ * - split on intra-word delimiters (by default, all non alpha-numeric
characters).
+ * - "Wi-Fi" -> "Wi", "Fi"
+ * - split on case transitions
+ * - "PowerShot" -> "Power", "Shot"
+ * - split on letter-number transitions
+ * - "SD500" -> "SD", "500"
+ * - leading and trailing intra-word delimiters on each subword are ignored
+ * - "//hello---there, 'dude'" -> "hello", "there", "dude"
+ * - trailing "'s" are removed for each subword
+ * - "O'Neil's" -> "O", "Neil"
+ * - Note: this step isn't performed in a separate filter because of
possible subword combinations.
+ *
+ * The <b>combinations</b> parameter affects how subwords are combined:
+ * - combinations="0" causes no subword combinations.
+ * - "PowerShot" -> 0:"Power", 1:"Shot" (0 and 1 are the token positions)
+ * - combinations="1" means that in addition to the subwords, maximum runs of
non-numeric subwords are catenated and produced at the same position of the
last subword in the run.
+ * - "PowerShot" -> 0:"Power", 1:"Shot" 1:"PowerShot"
+ * - "A's+B's&C's" -> 0:"A", 1:"B", 2:"C", 2:"ABC"
+ * - "Super-Duper-XL500-42-AutoCoder!" -> 0:"Super", 1:"Duper", 2:"XL",
2:"SuperDuperXL", 3:"500" 4:"42", 5:"Auto", 6:"Coder", 6:"AutoCoder"
+ *
+ * One use for WordDelimiterFilter is to help match words with different
subword delimiters.
+ * For example, if the source text contained "wi-fi" one may want "wifi"
"WiFi" "wi-fi" "wi+fi"
+ * queries to all match.
+ * One way of doing so is to specify combinations="1" in the analyzer
+ * used for indexing, and combinations="0" (the default) in the analyzer
+ * used for querying. Given that the current StandardTokenizer
+ * immediately removes many intra-word delimiters, it is recommended that
+ * this filter be used after a tokenizer that does not do this
+ * (such as WhitespaceTokenizer).
+ *
+ * @author yonik
+ * @version $Id: WordDelimiterFilter.java,v 1.6 2005/09/20 03:54:05 yonik Exp
$
+ */
+final class WordDelimiterFilter extends TokenFilter {
+ private final byte[] charTypeTable;
+
+ public static final int LOWER=0x01;
+ public static final int UPPER=0x02;
+ public static final int DIGIT=0x04;
+ public static final int SUBWORD_DELIM=0x08;
+
+ // combinations: for testing, not for setting bits
+ public static final int ALPHA=0x03;
+ public static final int ALPHANUM=0x07;
+
+ // TODO: should there be a WORD_DELIM category for
+ // chars that only separate words (no catenation of subwords
+ // will be done if separated by these chars?)
+ // "," would be an obvious candidate...
+
+ static byte[] defaultWordDelimTable;
+ static {
+ byte[] tab = new byte[256];
+ for (int i=0; i<256; i++) {
+ byte code = 0;
+ if (Character.isLowerCase(i)) code |= LOWER;
+ else if (Character.isUpperCase(i)) code |= UPPER;
+ else if (Character.isDigit(i)) code |= DIGIT;
+ if (code==0) code=SUBWORD_DELIM;
+ tab[i]=code;
+ }
+ defaultWordDelimTable = tab;
+ }
+
+ final int generateWordParts;
+ final int generateNumberParts;
+ final int catenateWords;
+ final int catenateNumbers;
+ final int catenateAll;
+
+ public WordDelimiterFilter(TokenStream in, byte[] charTypeTable, int
generateWordParts, int generateNumberParts, int catenateWords, int
catenateNumbers, int catenateAll) {
+ super(in);
+ this.generateWordParts = generateWordParts;
+ this.generateNumberParts = generateNumberParts;
+ this.catenateWords = catenateWords;
+ this.catenateNumbers = catenateNumbers;
+ this.catenateAll = catenateAll;
+ this.charTypeTable = charTypeTable;
+ }
+
+ public WordDelimiterFilter(TokenStream in, int generateWordParts, int
generateNumberParts, int catenateWords, int catenateNumbers, int catenateAll) {
+ this(in, defaultWordDelimTable, generateWordParts, generateNumberParts,
catenateWords, catenateNumbers, catenateAll);
+ }
+
+ int charType(int ch) {
+ if (ch<charTypeTable.length) {
+ return charTypeTable[ch];
+ } else if (Character.isLowerCase(ch)) {
+ return LOWER;
+ } else if (Character.isLetter(ch)) {
+ return UPPER;
+ } else {
+ return SUBWORD_DELIM;
+ }
+ }
+
+ private int charType(String s, int pos) {
+ return charType(s.charAt(pos));
+ }
+
+ // use the type of the first char as the type
+ // of the token.
+ private int tokType(Token t) {
+ return charType(t.termText().charAt(0));
+ }
+
+ // There isn't really an efficient queue class, so we will
+ // just use an array for now.
+ private ArrayList<Token> queue = new ArrayList<Token>(4);
+ private int queuePos=0;
+
+ // temporary working queue
+ private ArrayList<Token> tlist = new ArrayList<Token>(4);
+
+
+ private Token newTok(Token orig, int start, int end) {
+ return new Token(orig.termText().substring(start,end),
+ orig.startOffset() + start,
+ orig.startOffset() + end,
+ orig.type());
+ }
+
+
+ public final Token next() throws IOException {
+
+ // check the queue first
+ if (queuePos<queue.size()) {
+ return queue.get(queuePos++);
+ }
+
+ // reset the queue if it had been previously used
+ if (queuePos!=0) {
+ queuePos=0;
+ queue.clear();
+ }
+
+
+ // optimize for the common case: assume there will be
+ // no subwords (just a simple word)
+ //
+ // Would it actually be faster to check for the common form
+ // of isLetter() isLower()*, and then backtrack if it doesn't match?
+
+ while(true) {
+ Token t = input.next();
+ if (t == null) return null;
+
+ String s = t.termText();
+ int off=t.startOffset();
+ int start=0;
+ int end=s.length();
+ if (end==0) continue;
+
+ // Avoid calling charType more than once for each char (basically
+ // avoid any backtracking).
+ // makes code slightly more difficult, but faster.
+ int ch=s.charAt(start);
+ int type=charType(ch);
+
+ int numWords=0;
+
+ while (start<end) {
+ // first eat delimiters at the start of this subword
+ while ((type & SUBWORD_DELIM)!=0 && ++start<end) {
+ ch=s.charAt(start);
+ type=charType(ch);
+ }
+
+ int pos=start;
+
+ // save the type of the first char of the subword
+ // as a way to tell what type of subword token this is (number, word,
etc)
+ int firstType=type;
+ int lastType=type; // type of the previously read char
+
+
+ while (pos<end) {
+
+ if (type!=lastType) {
+ // check and remove "'s" from the end of a token.
+ // the pattern to check for is
+ // ALPHA "'" ("s"|"S") (SUBWORD_DELIM | END)
+ if ((lastType & ALPHA)!=0) {
+ if (ch=='\'' && pos+1<end
+ && (s.charAt(pos+1)=='s' || s.charAt(pos+1)=='S'))
+ {
+ int subWordEnd=pos;
+ if (pos+2>=end) {
+ // end of string detected after "'s"
+ pos+=2;
+ } else {
+ // make sure that a delimiter follows "'s"
+ int ch2 = s.charAt(pos+2);
+ int type2 = charType(ch2);
+ if ((type2 & SUBWORD_DELIM)!=0) {
+ // if delimiter, move position pointer
+ // to it (skipping over "'s"
+ ch=ch2;
+ type=type2;
+ pos+=2;
+ }
+ }
+
+ queue.add(newTok(t,start,subWordEnd));
+ if ((firstType & ALPHA)!=0) numWords++;
+ break;
+ }
+ }
+
+ // For case changes, only split on a transition from
+ // lower to upper case, not vice-versa.
+ // That will correctly handle the
+ // case of a word starting with a capital (won't split).
+ // It will also handle pluralization of
+ // an uppercase word such as FOOs (won't split).
+
+ if ((lastType & UPPER)!=0 && (type & LOWER)!=0) {
+ // UPPER->LOWER: Don't split
+ } else {
+ // NOTE: this code currently assumes that only one flag
+ // is set for each character now, so we don't have
+ // to explicitly check for all the classes of transitions
+ // listed below.
+
+ // LOWER->UPPER
+ // ALPHA->NUMERIC
+ // NUMERIC->ALPHA
+ // *->DELIMITER
+ queue.add(newTok(t,start,pos));
+ if ((firstType & ALPHA)!=0) numWords++;
+ break;
+ }
+ }
+
+ if (++pos >= end) {
+ if (start==0) {
+ // the subword is the whole original token, so
+ // return it unchanged.
+ return t;
+ }
+
+ Token newtok = newTok(t,start,pos);
+
+ // optimization... if this is the only token,
+ // return it immediately.
+ if (queue.size()==0) {
+ return newtok;
+ }
+
+ queue.add(newtok);
+ if ((firstType & ALPHA)!=0) numWords++;
+ break;
+ }
+
+ lastType = type;
+ ch = s.charAt(pos);
+ type = charType(ch);
+ }
+
+ // start of the next subword is the current position
+ start=pos;
+ }
+
+ // System.out.println("##########TOKEN=" + s + " ######### WORD
DELIMITER QUEUE=" + str(queue));
+
+ final int numtok = queue.size();
+
+ // We reached the end of the current token.
+ // If the queue is empty, we should continue by reading
+ // the next token
+ if (numtok==0) {
+ continue;
+ }
+
+ // if number of tokens is 1, always return the single tok
+ if (numtok==1) {
+ break;
+ }
+
+ final int numNumbers = numtok - numWords;
+
+ // check conditions under which the current token
+ // queue may be used as-is (no catenations needed)
+ if (catenateAll==0 // no "everything" to catenate
+ && (catenateWords==0 || numWords<=1) // no words to catenate
+ && (catenateNumbers==0 || numNumbers<=1) // no numbers to catenate
+ && (generateWordParts!=0 || numWords==0) // word generation is on
+ && (generateNumberParts!=0 || numNumbers==0)) // number generation is
on
+ {
+ break;
+ }
+
+
+ // swap queue and the temporary working list, then clear the
+ // queue in preparation for adding all combinations back to it.
+ ArrayList<Token> tmp=tlist;
+ tlist=queue;
+ queue=tmp;
+ queue.clear();
+
+ if (numWords==0) {
+ // all numbers
+ addCombos(tlist,0,numtok,generateNumberParts!=0,catenateNumbers!=0 ||
catenateAll!=0, 1);
+ break;
+ } else if (numNumbers==0) {
+ // all words
+ addCombos(tlist,0,numtok,generateWordParts!=0,catenateWords!=0 ||
catenateAll!=0, 1);
+ break;
+ } else if (generateNumberParts==0 && generateWordParts==0 &&
catenateNumbers==0 && catenateWords==0) {
+ // catenate all *only*
+ // OPT:could be optimized to add to current queue...
+ addCombos(tlist,0,numtok,false,catenateAll!=0, 1);
+ break;
+ }
+
+ //
+ // Find all adjacent tokens of the same type.
+ //
+ Token tok = tlist.get(0);
+ boolean isWord = (tokType(tok) & ALPHA) != 0;
+ boolean wasWord=isWord;
+
+ for(int i=0; i<numtok;) {
+ int j;
+ for (j=i+1; j<numtok; j++) {
+ wasWord=isWord;
+ tok = tlist.get(j);
+ isWord = (tokType(tok) & ALPHA) != 0;
+ if (isWord != wasWord) break;
+ }
+ if (wasWord) {
+ addCombos(tlist,i,j,generateWordParts!=0,catenateWords!=0,1);
+ } else {
+ addCombos(tlist,i,j,generateNumberParts!=0,catenateNumbers!=0,1);
+ }
+ i=j;
+ }
+
+ // take care catenating all subwords
+ if (catenateAll!=0) {
+ addCombos(tlist,0,numtok,false,true,0);
+ }
+
+ break;
+ }
+
+ // System.out.println("##########AFTER COMBINATIONS:"+ str(queue));
+
+ queuePos=1;
+ return queue.get(0);
+ }
+
+
+ // index "a","b","c" as pos0="a", pos1="b", pos2="c", pos2="abc"
+ private void addCombos(List<Token> lst, int start, int end, boolean
generateSubwords, boolean catenateSubwords, int posOffset) {
+ if (end-start==1) {
+ // always generate a word alone, even if generateSubwords=0 because
+ // the catenation of all the subwords *is* the subword.
+ queue.add(lst.get(start));
+ return;
+ }
+
+ StringBuilder sb = null;
+ if (catenateSubwords) sb=new StringBuilder();
+ Token firstTok=null;
+ Token tok=null;
+ for (int i=start; i<end; i++) {
+ tok = lst.get(i);
+ if (catenateSubwords) {
+ if (i==start) firstTok=tok;
+ sb.append(tok.termText());
+ }
+ if (generateSubwords) {
+ queue.add(tok);
+ }
+ }
+
+ if (catenateSubwords) {
+ Token concatTok = new Token(sb.toString(),
+ firstTok.startOffset(),
+ tok.endOffset(),
+ firstTok.type());
+ // if we indexed some other tokens, then overlap concatTok with the last.
+ // Otherwise, use the value passed in as the position offset.
+ concatTok.setPositionIncrement(generateSubwords==true ? 0 : posOffset);
+ queue.add(concatTok);
+ }
+ }
+
+ private String str(List<Token> lst) {
+ StringBuilder sb = new StringBuilder();
+ sb.append('{');
+ for (Token t : lst) {
+ sb.append('(');
+ sb.append('"');
+ sb.append(t.termText());
+ sb.append("\",increment=");
+ sb.append(Integer.toString(t.getPositionIncrement()));
+ sb.append(')');
+
+ sb.append(',');
+ }
+ sb.append('}');
+ return sb.toString();
+ }
+
+
+
+ // questions:
+ // negative numbers? -42 indexed as just 42?
+ // dollar sign? $42
+ // percent sign? 33%
+ // downsides: if source text is "powershot" then a query of "PowerShot"
won't match!
+
+}
Propchange:
incubator/solr/trunk/src/java/org/apache/solr/analysis/WordDelimiterFilter.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
incubator/solr/trunk/src/java/org/apache/solr/analysis/WordDelimiterFilterFactory.java
URL:
http://svn.apache.org/viewcvs/incubator/solr/trunk/src/java/org/apache/solr/analysis/WordDelimiterFilterFactory.java?rev=372455&view=auto
==============================================================================
---
incubator/solr/trunk/src/java/org/apache/solr/analysis/WordDelimiterFilterFactory.java
(added)
+++
incubator/solr/trunk/src/java/org/apache/solr/analysis/WordDelimiterFilterFactory.java
Wed Jan 25 21:37:29 2006
@@ -0,0 +1,48 @@
+/**
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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.
+ */
+
+package org.apache.solr.analysis;
+
+import org.apache.lucene.analysis.TokenStream;
+
+import java.util.Map;
+
+/**
+ * @author yonik
+ * @version $Id$
+ */
+public class WordDelimiterFilterFactory extends BaseTokenFilterFactory {
+ int generateWordParts=0;
+ int generateNumberParts=0;
+ int catenateWords=0;
+ int catenateNumbers=0;
+ int catenateAll=0;
+
+ public void init(Map<String, String> args) {
+ super.init(args);
+ generateWordParts = getInt("generateWordParts",1);
+ generateNumberParts = getInt("generateNumberParts",1);
+ catenateWords = getInt("catenateWords",0);
+ catenateNumbers = getInt("catenateNumbers",0);
+ catenateAll = getInt("catenateAll",0);
+ }
+
+ public TokenStream create(TokenStream input) {
+ return new WordDelimiterFilter(input,
+ generateWordParts, generateNumberParts,
+ catenateWords, catenateNumbers, catenateAll);
+ }
+}
Propchange:
incubator/solr/trunk/src/java/org/apache/solr/analysis/WordDelimiterFilterFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
incubator/solr/trunk/src/java/org/apache/solr/core/AbstractSolrEventListener.java
URL:
http://svn.apache.org/viewcvs/incubator/solr/trunk/src/java/org/apache/solr/core/AbstractSolrEventListener.java?rev=372455&view=auto
==============================================================================
---
incubator/solr/trunk/src/java/org/apache/solr/core/AbstractSolrEventListener.java
(added)
+++
incubator/solr/trunk/src/java/org/apache/solr/core/AbstractSolrEventListener.java
Wed Jan 25 21:37:29 2006
@@ -0,0 +1,43 @@
+/**
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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.
+ */
+
+package org.apache.solr.core;
+
+import org.apache.solr.search.SolrIndexSearcher;
+import org.apache.solr.util.NamedList;
+
+/**
+ * @author yonik
+ */
+class AbstractSolrEventListener implements SolrEventListener {
+ protected NamedList args;
+
+ public void init(NamedList args) {
+ this.args = args;
+ }
+
+ public void postCommit() {
+ throw new UnsupportedOperationException();
+ }
+
+ public void newSearcher(SolrIndexSearcher newSearcher, SolrIndexSearcher
currentSearcher) {
+ throw new UnsupportedOperationException();
+ }
+
+ public String toString() {
+ return getClass().getName() + args;
+ }
+}
Propchange:
incubator/solr/trunk/src/java/org/apache/solr/core/AbstractSolrEventListener.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/solr/trunk/src/java/org/apache/solr/core/Config.java
URL:
http://svn.apache.org/viewcvs/incubator/solr/trunk/src/java/org/apache/solr/core/Config.java?rev=372455&view=auto
==============================================================================
--- incubator/solr/trunk/src/java/org/apache/solr/core/Config.java (added)
+++ incubator/solr/trunk/src/java/org/apache/solr/core/Config.java Wed Jan 25
21:37:29 2006
@@ -0,0 +1,260 @@
+/**
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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.
+ */
+
+package org.apache.solr.core;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
+import org.apache.solr.core.SolrCore;
+import org.apache.solr.core.SolrException;
+
+import javax.xml.parsers.*;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathFactory;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.namespace.QName;
+import java.io.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Logger;
+
+/**
+ * @author yonik
+ * @version $Id: Config.java,v 1.10 2005/12/20 16:05:46 yonik Exp $
+ */
+public class Config {
+ public static final Logger log = Logger.getLogger(SolrCore.class.getName());
+
+ static final XPathFactory xpathFactory = XPathFactory.newInstance();
+
+ private Document doc;
+ private String prefix;
+ private String name;
+
+ public Config(String name, InputStream is, String prefix) throws
ParserConfigurationException, IOException, SAXException {
+ this.name = name;
+ this.prefix = prefix;
+ if (prefix!=null && !prefix.endsWith("/")) prefix += '/';
+
+ javax.xml.parsers.DocumentBuilder builder =
DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ doc = builder.parse(is);
+ }
+
+ public Document getDocument() {
+ return doc;
+ }
+
+ public XPath getXPath() {
+ return xpathFactory.newXPath();
+ }
+
+ private String normalize(String path) {
+ return (prefix==null || path.startsWith("/")) ? path : prefix+path;
+ }
+
+
+ public Object evaluate(String path, QName type) {
+ XPath xpath = xpathFactory.newXPath();
+ try {
+ String xstr=normalize(path);
+
+ // TODO: instead of prepending /prefix/, we could do the search rooted
at /prefix...
+ Object o = xpath.evaluate(xstr, doc, type);
+ return o;
+
+ } catch (XPathExpressionException e) {
+ throw new SolrException(500,"Error in xpath:" + path +" for " +
name,e,false);
+ }
+ }
+
+ public Node getNode(String path, boolean errIfMissing) {
+ XPath xpath = xpathFactory.newXPath();
+ Node nd = null;
+ String xstr = normalize(path);
+
+ try {
+ nd = (Node)xpath.evaluate(xstr, doc, XPathConstants.NODE);
+
+ if (nd==null) {
+ if (errIfMissing) {
+ throw new RuntimeException(name + " missing "+path);
+ } else {
+ log.fine(name + " missing optional " + path);
+ return null;
+ }
+ }
+
+ log.finest(name + ":" + path + "=" + nd);
+ return nd;
+
+ } catch (XPathExpressionException e) {
+ SolrException.log(log,"Error in xpath",e);
+ throw new SolrException(500,"Error in xpath:" + xstr + " for " +
name,e,false);
+ } catch (SolrException e) {
+ throw(e);
+ } catch (Throwable e) {
+ SolrException.log(log,"Error in xpath",e);
+ throw new SolrException(500,"Error in xpath:" + xstr+ " for " +
name,e,false);
+ }
+ }
+
+ public String getVal(String path, boolean errIfMissing) {
+ Node nd = getNode(path,errIfMissing);
+ if (nd==null) return null;
+
+ // should do the right thing for both attributes and elements.
+ // Oops, when running in Resin, I get an unsupported operation
+ // exception... need to use Sun default (apache)
+ String txt = nd.getTextContent();
+ log.fine(name + ' '+path+'='+txt);
+ return txt;
+
+ /******
+ short typ = nd.getNodeType();
+ if (typ==Node.ATTRIBUTE_NODE || typ==Node.TEXT_NODE) {
+ return nd.getNodeValue();
+ }
+ return nd.getTextContent();
+ ******/
+ }
+
+
+ public String get(String path) {
+ return getVal(path,true);
+ }
+
+ public String get(String path, String def) {
+ String val = getVal(path, false);
+ return val!=null ? val : def;
+ }
+
+ public int getInt(String path) {
+ return Integer.parseInt(getVal(path, false));
+ }
+
+ public int getInt(String path, int def) {
+ String val = getVal(path, false);
+ return val!=null ? Integer.parseInt(val) : def;
+ }
+
+ public boolean getBool(String path) {
+ return Boolean.parseBoolean(getVal(path, false));
+ }
+
+ public boolean getBool(String path, boolean def) {
+ String val = getVal(path, false);
+ return val!=null ? Boolean.parseBoolean(val) : def;
+ }
+
+ public float getFloat(String path) {
+ return Float.parseFloat(getVal(path, false));
+ }
+
+ public float getFloat(String path, float def) {
+ String val = getVal(path, false);
+ return val!=null ? Float.parseFloat(val) : def;
+ }
+
+
+ //
+ // classloader related functions
+ //
+
+ private static final String project = "solr";
+ private static final String base = "org.apache" + "." + project;
+ private static final String[] packages =
{"","analysis.","schema.","search.","update.","core.","request.","util."};
+
+ public static Class findClass(String cname, String... subpackages) {
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ if (subpackages.length==0) subpackages = packages;
+
+ // first try cname == full name
+ try {
+ return Class.forName(cname, true, loader);
+ } catch (ClassNotFoundException e) {
+ String newName=cname;
+ if (newName.startsWith("solar.")) {
+ // handle legacy package names
+ newName = cname.substring("solar.".length());
+ } else if (cname.startsWith(project+".")) {
+ newName = cname.substring(project.length()+1);
+ }
+
+ for (String subpackage : subpackages) {
+ try {
+ String name = base + '.' + subpackage + newName;
+ log.finest("Trying class name " + name);
+ return Class.forName(name, true, loader);
+ } catch (ClassNotFoundException e1) {
+ // ignore... assume first exception is best.
+ }
+ }
+
+ throw new SolrException(500, "Error loading class '" + cname + "'", e,
false);
+ }
+ }
+
+ public static Object newInstance(String cname, String... subpackages) {
+ Class clazz = findClass(cname,subpackages);
+ try {
+ return clazz.newInstance();
+ } catch (Exception e) {
+ throw new SolrException(500,"Error instantiating class " + clazz, e,
false);
+ }
+ }
+
+
+ public static InputStream openResource(String resource) {
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ InputStream is = loader.getResourceAsStream(resource);
+ if (is==null) {
+ throw new SolrException(500,"Can't open " + resource);
+ }
+ return is;
+ }
+
+ /**
+ * Returns a list of non-blank non-comment lines with whitespace trimmed
from front and back.
+ * @param resource
+ * @return
+ * @throws IOException
+ */
+ public static List<String> getLines(String resource) throws IOException {
+ BufferedReader input = null;
+ try {
+ // todo - allow configurable charset?
+ input = new BufferedReader(new InputStreamReader(openResource(resource),
"UTF-8"));
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+ ArrayList<String> lines = new ArrayList<String>();
+ for (String word=null; (word=input.readLine())!=null;) {
+ // skip comments
+ if (word.startsWith("#")) continue;
+ word=word.trim();
+ // skip blank lines
+ if (word.length()==0) continue;
+ lines.add(word);
+ }
+ return lines;
+ }
+
+
+
+
+}
Propchange: incubator/solr/trunk/src/java/org/apache/solr/core/Config.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
incubator/solr/trunk/src/java/org/apache/solr/core/QuerySenderListener.java
URL:
http://svn.apache.org/viewcvs/incubator/solr/trunk/src/java/org/apache/solr/core/QuerySenderListener.java?rev=372455&view=auto
==============================================================================
--- incubator/solr/trunk/src/java/org/apache/solr/core/QuerySenderListener.java
(added)
+++ incubator/solr/trunk/src/java/org/apache/solr/core/QuerySenderListener.java
Wed Jan 25 21:37:29 2006
@@ -0,0 +1,51 @@
+/**
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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.
+ */
+
+package org.apache.solr.core;
+
+import org.apache.solr.search.SolrIndexSearcher;
+import org.apache.solr.request.LocalSolrQueryRequest;
+import org.apache.solr.request.SolrQueryResponse;
+import org.apache.solr.util.NamedList;
+
+import java.util.List;
+
+/**
+ * @author yonik
+ * @version $Id$
+ */
+class QuerySenderListener extends AbstractSolrEventListener {
+
+ public void newSearcher(SolrIndexSearcher newSearcher, SolrIndexSearcher
currentSearcher) {
+ SolrCore core = SolrCore.getSolrCore();
+ log.info("QuerySenderListener sending requests to " + newSearcher);
+ for (NamedList nlst : (List<NamedList>)args.get("queries")) {
+ try {
+ LocalSolrQueryRequest req = new LocalSolrQueryRequest(core, nlst);
+
+ SolrQueryResponse rsp = new SolrQueryResponse();
+ core.execute(req,rsp);
+ } catch (Exception e) {
+ // do nothing... we want to continue with the other requests.
+ // the failure should have already been logged.
+ }
+ log.info("QuerySenderListener done.");
+ }
+ }
+
+
+
+}
Propchange:
incubator/solr/trunk/src/java/org/apache/solr/core/QuerySenderListener.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/solr/trunk/src/java/org/apache/solr/core/RequestHandlers.java
URL:
http://svn.apache.org/viewcvs/incubator/solr/trunk/src/java/org/apache/solr/core/RequestHandlers.java?rev=372455&view=auto
==============================================================================
--- incubator/solr/trunk/src/java/org/apache/solr/core/RequestHandlers.java
(added)
+++ incubator/solr/trunk/src/java/org/apache/solr/core/RequestHandlers.java Wed
Jan 25 21:37:29 2006
@@ -0,0 +1,91 @@
+/**
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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.
+ */
+
+package org.apache.solr.core;
+
+import org.apache.solr.util.DOMUtil;
+import org.apache.solr.request.SolrRequestHandler;
+import org.apache.solr.request.StandardRequestHandler;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Node;
+
+import javax.xml.xpath.XPathConstants;
+import java.util.logging.Logger;
+import java.util.HashMap;
+
+/**
+ * @author yonik
+ */
+final class RequestHandlers {
+ public static Logger log =
Logger.getLogger(org.apache.solr.core.RequestHandlers.class.getName());
+
+ public static final String DEFAULT_HANDLER_NAME="standard";
+
+ final HashMap<String, SolrRequestHandler> map = new
HashMap<String,SolrRequestHandler>();
+
+ public RequestHandlers(Config config) {
+ NodeList nodes = (NodeList)config.evaluate("requestHandler",
XPathConstants.NODESET);
+
+ if (nodes!=null) {
+ for (int i=0; i<nodes.getLength(); i++) {
+ Node node = nodes.item(i);
+
+ // We can tolerate an error in some request handlers, still load the
+ // others, and have a working system.
+ try {
+ String name = DOMUtil.getAttr(node,"name","requestHandler config");
+ String className = DOMUtil.getAttr(node,"class","requestHandler
config");
+ log.info("adding requestHandler " + name + "=" + className);
+
+ SolrRequestHandler handler = (SolrRequestHandler)
Config.newInstance(className);
+ handler.init(DOMUtil.childNodesToNamedList(node));
+
+ put(name, handler);
+
+ } catch (Exception e) {
+ SolrException.logOnce(log,null,e);
+ }
+ }
+ }
+
+ //
+ // Get the default handler and add it in the map under null and empty
+ // to act as the default.
+ //
+ SolrRequestHandler handler = get(DEFAULT_HANDLER_NAME);
+ if (handler == null) {
+ handler = new StandardRequestHandler();
+ put(DEFAULT_HANDLER_NAME, handler);
+ }
+ put(null, handler);
+ put("", handler);
+
+ }
+
+ public SolrRequestHandler get(String handlerName) {
+ return map.get(handlerName);
+ }
+
+ public void put(String handlerName, SolrRequestHandler handler) {
+ map.put(handlerName, handler);
+ if (handlerName != null && handlerName != "") {
+ if (handler instanceof SolrInfoMBean) {
+ SolrInfoRegistry.getRegistry().put(handlerName,
(SolrInfoMBean)handler);
+ }
+ }
+ }
+
+}
Propchange:
incubator/solr/trunk/src/java/org/apache/solr/core/RequestHandlers.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
incubator/solr/trunk/src/java/org/apache/solr/core/RunExecutableListener.java
URL:
http://svn.apache.org/viewcvs/incubator/solr/trunk/src/java/org/apache/solr/core/RunExecutableListener.java?rev=372455&view=auto
==============================================================================
---
incubator/solr/trunk/src/java/org/apache/solr/core/RunExecutableListener.java
(added)
+++
incubator/solr/trunk/src/java/org/apache/solr/core/RunExecutableListener.java
Wed Jan 25 21:37:29 2006
@@ -0,0 +1,103 @@
+/**
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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.
+ */
+
+package org.apache.solr.core;
+
+import org.apache.solr.util.NamedList;
+import org.apache.solr.search.SolrIndexSearcher;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.logging.Level;
+
+/**
+ * @author yonik
+ */
+class RunExecutableListener extends AbstractSolrEventListener {
+ protected String[] cmd;
+ protected File dir;
+ protected String[] envp;
+ protected boolean wait=true;
+
+ public void init(NamedList args) {
+ super.init(args);
+
+ List cmdlist = new ArrayList();
+ cmdlist.add(args.get("exe"));
+ List lst = (List)args.get("args");
+ if (lst != null) cmdlist.addAll(lst);
+ cmd = (String[])cmdlist.toArray(new String[cmdlist.size()]);
+
+ lst = (List)args.get("env");
+ if (lst != null) {
+ envp = (String[])lst.toArray(new String[lst.size()]);
+ }
+
+ String str = (String)args.get("dir");
+ if (str==null || str.equals("") || str.equals(".") || str.equals("./")) {
+ dir = null;
+ } else {
+ dir = new File(str);
+ }
+
+ if ("false".equals(args.get("wait"))) wait=false;
+ }
+
+ protected int exec(String callback) {
+ int ret = 0;
+
+ try {
+ boolean doLog = log.isLoggable(Level.FINE);
+ if (doLog) {
+ log.fine("About to exec " + cmd[0]);
+ }
+ Process proc = Runtime.getRuntime().exec(cmd, envp ,dir);
+
+ if (wait) {
+ try {
+ ret = proc.waitFor();
+ } catch (InterruptedException e) {
+ SolrException.log(log,e);
+ }
+ }
+
+ if (wait && doLog) {
+ log.fine("Executable " + cmd[0] + " returned " + ret);
+ }
+
+ } catch (IOException e) {
+ // don't throw exception, just log it...
+ SolrException.log(log,e);
+ }
+
+ return ret;
+ }
+
+
+ public void postCommit() {
+ // anything generic need to be passed to the external program?
+ // the directory of the index? the command that caused it to be
+ // invoked? the version of the index?
+ exec("postCommit");
+ }
+
+ public void newSearcher(SolrIndexSearcher newSearcher, SolrIndexSearcher
currentSearcher) {
+ exec("newSearcher");
+ }
+
+}
Propchange:
incubator/solr/trunk/src/java/org/apache/solr/core/RunExecutableListener.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/solr/trunk/src/java/org/apache/solr/core/SolrConfig.java
URL:
http://svn.apache.org/viewcvs/incubator/solr/trunk/src/java/org/apache/solr/core/SolrConfig.java?rev=372455&view=auto
==============================================================================
--- incubator/solr/trunk/src/java/org/apache/solr/core/SolrConfig.java (added)
+++ incubator/solr/trunk/src/java/org/apache/solr/core/SolrConfig.java Wed Jan
25 21:37:29 2006
@@ -0,0 +1,51 @@
+/**
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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.
+ */
+
+package org.apache.solr.core;
+
+import java.io.InputStream;
+
+
+/**
+ * @author yonik
+ * @version $Id: SolrConfig.java,v 1.3 2005/12/02 04:31:06 yonik Exp $
+ */
+public class SolrConfig {
+ public static Config config;
+ static {
+ Exception e=null;
+ String file="solrconfig.xml";
+ InputStream is;
+ try {
+ is = Config.openResource(file);
+ } catch (Exception ee) {
+ e=ee;
+ file = "solarconfig.xml"; // backward compat
+ is = Config.openResource(file);
+ }
+ if (is!=null) {
+ try {
+ config=new Config(file, is, "/config/");
+ is.close();
+ } catch (Exception ee) {
+ throw new RuntimeException(ee);
+ }
+ Config.log.info("Loaded Config solarconfig.xml");
+ } else {
+ throw new RuntimeException(e);
+ }
+ }
+}
Propchange: incubator/solr/trunk/src/java/org/apache/solr/core/SolrConfig.java
------------------------------------------------------------------------------
svn:eol-style = native