package org.apache.lucene.analysis.fr;

/**
 * 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.Set;
import java.util.HashSet;
import java.util.Arrays;
import java.util.Iterator;
import org.apache.lucene.analysis.standard.StandardTokenizer; // for javadocs
import org.apache.lucene.analysis.Token;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.TokenFilter;
import org.apache.lucene.analysis.tokenattributes.TermAttribute;

/**
 * Removes elisions from a {@link TokenStream}. For example, "l'avion" (the plane) will be
 * tokenized as "avion" (plane).
 * <p>
 * Note that {@link StandardTokenizer} sees " ' " as a space, and cuts it out.
 * 
 * @see <a href="http://fr.wikipedia.org/wiki/%C3%89lision">Elision in Wikipedia</a>
 */
public final class ElisionFilter extends TokenFilter {
  private Set articles = null;
  private TermAttribute termAtt;
  
  private static char[] apostrophes = {'\'', '’'};

  public void setArticles(Set articles) {
    this.articles = new HashSet();
    Iterator iter = articles.iterator();
    while (iter.hasNext()) {
      this.articles.add(((String) iter.next()).toLowerCase());
    }
  }

  /**
   * Constructs an elision filter with standard stop words
   */
  protected ElisionFilter(TokenStream input) {
    super(input);
    this.articles = new HashSet(Arrays.asList(new String[] { "l", "m", "t",
        "qu", "n", "s", "j" }));
    termAtt = addAttribute(TermAttribute.class);
  }

  /**
   * Constructs an elision filter with a Set of stop words
   */
  public ElisionFilter(TokenStream input, Set articles) {
    super(input);
    setArticles(articles);
    termAtt = addAttribute(TermAttribute.class);
  }

  /**
   * Constructs an elision filter with an array of stop words
   */
  public ElisionFilter(TokenStream input, String[] articles) {
    super(input);
    setArticles(new HashSet(Arrays.asList(articles)));
    termAtt = addAttribute(TermAttribute.class);
  }

  /**
   * Increments the {@link TokenStream} with a {@link TermAttribute} without elisioned start
   */
  public final boolean incrementToken() throws IOException {
    if (input.incrementToken()) {
      char[] termBuffer = termAtt.termBuffer();
      int termLength = termAtt.termLength();

      int minPoz = Integer.MAX_VALUE;
      for (int i = 0; i < apostrophes.length; i++) {
        char apos = apostrophes[i];
        // The equivalent of String.indexOf(ch)
        for (int poz = 0; poz < termLength ; poz++) {
          if (termBuffer[poz] == apos) {
            minPoz = Math.min(poz, minPoz);
            break;
          }
        }
      }

      // An apostrophe has been found. If the prefix is an article strip it off.
      if (minPoz != Integer.MAX_VALUE
          && articles.contains(new String(termAtt.termBuffer(), 0, minPoz).toLowerCase())) {
        termAtt.setTermBuffer(termAtt.termBuffer(), minPoz + 1, termAtt.termLength() - (minPoz + 1));
      }

      return true;
    } else {
      return false;
    }
  }
}

@@ -908,67 +908,14 @@
 til.
-HashSet;%0Aimport java.util.Arrays;%0Aimport java.util.Iterator
+Arrays
 ;%0Aim
@@ -1024,21 +1024,28 @@
 nalysis.
-Token
+CharArraySet
 ;%0Aimport
@@ -1570,16 +1570,25 @@
 private 
+CharArray
 Set arti
@@ -1717,16 +1717,19 @@
 cles(Set
+%3C?%3E
  article
@@ -1733,29 +1733,28 @@
 cles) %7B%0A    
-this.
+if (
 articles = n
@@ -1754,163 +1754,144 @@
 les 
-= new HashSet();%0A    Iterator iter = articles.iterator();%0A    while (iter.hasNext()) %7B%0A      this.articles.add(((String) iter.next()).toLowerCase());%0A    %7D
+instanceof CharArraySet)%0A      this.articles = (CharArraySet) articles;%0A    else%0A      this.articles = new CharArraySet(articles, true);
 %0A  %7D
@@ -2048,28 +2048,33 @@
 icles = new 
-Hash
+CharArray
 Set(Arrays.a
@@ -2083,22 +2083,16 @@
 ist(
-new String%5B%5D %7B
+%0A       
  %22l%22
@@ -2102,24 +2102,16 @@
 m%22, %22t%22,
-%0A       
  %22qu%22, %22
@@ -2126,11 +2126,15 @@
  %22j%22
- %7D)
+), true
 );%0A 
@@ -2302,16 +2302,19 @@
 put, Set
+%3C?%3E
  article
@@ -2580,28 +2580,37 @@
     
-setA
+this.a
 rticles
-(
+ = 
 new 
-Hash
+CharArray
 Set(
@@ -2632,17 +2632,22 @@
 rticles)
-)
+, true
 );%0A    t
@@ -3507,19 +3507,8 @@
 ins(
-new String(
 term
@@ -3539,23 +3539,8 @@
 Poz)
-.toLowerCase())
 ) %7B%0A

use chararrayset in french elision filter