org.apache.lucene.analysis.DelegatingAnalyzerWrapper.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.lucene.analysis.DelegatingAnalyzerWrapper.java

Source

/*
 * 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.lucene.analysis;

import java.io.Reader;

/**
 * An analyzer wrapper, that doesn't allow to wrap components or readers.
 * By disallowing it, it means that the thread local resources can be delegated
 * to the delegate analyzer, and not also be allocated on this analyzer.
 * This wrapper class is the base class of all analyzers that just delegate to
 * another analyzer, e.g. per field name.
 * 
 * <p>This solves the problem of per field analyzer wrapper, where it also
 * maintains a thread local per field token stream components, while it can
 * safely delegate those and not also hold these data structures, which can
 * become expensive memory wise.
 * 
 * <p><b>Please note:</b> This analyzer uses a private {@link Analyzer.ReuseStrategy},
 * which is returned by {@link #getReuseStrategy()}. This strategy is used when
 * delegating. If you wrap this analyzer again and reuse this strategy, no
 * delegation is done and the given fallback is used.
 *
 * @since 4.10.0
 */
public abstract class DelegatingAnalyzerWrapper extends AnalyzerWrapper {

    /**
     * Constructor.
     * @param fallbackStrategy is the strategy to use if delegation is not possible
     *  This is to support the common pattern:
     *  {@code new OtherWrapper(thisWrapper.getReuseStrategy())} 
     */
    protected DelegatingAnalyzerWrapper(ReuseStrategy fallbackStrategy) {
        super(new DelegatingReuseStrategy(fallbackStrategy));
        // hckidy-hick-hack, because we cannot call super() with a reference to "this":
        ((DelegatingReuseStrategy) getReuseStrategy()).wrapper = this;
    }

    @Override
    protected final TokenStreamComponents wrapComponents(String fieldName, TokenStreamComponents components) {
        return super.wrapComponents(fieldName, components);
    }

    @Override
    protected final TokenStream wrapTokenStreamForNormalization(String fieldName, TokenStream in) {
        return super.wrapTokenStreamForNormalization(fieldName, in);
    }

    @Override
    protected final Reader wrapReader(String fieldName, Reader reader) {
        return super.wrapReader(fieldName, reader);
    }

    @Override
    protected final Reader wrapReaderForNormalization(String fieldName, Reader reader) {
        return super.wrapReaderForNormalization(fieldName, reader);
    }

    private static final class DelegatingReuseStrategy extends ReuseStrategy {
        DelegatingAnalyzerWrapper wrapper;
        private final ReuseStrategy fallbackStrategy;

        DelegatingReuseStrategy(ReuseStrategy fallbackStrategy) {
            this.fallbackStrategy = fallbackStrategy;
        }

        @Override
        public TokenStreamComponents getReusableComponents(Analyzer analyzer, String fieldName) {
            if (analyzer == wrapper) {
                final Analyzer wrappedAnalyzer = wrapper.getWrappedAnalyzer(fieldName);
                return wrappedAnalyzer.getReuseStrategy().getReusableComponents(wrappedAnalyzer, fieldName);
            } else {
                return fallbackStrategy.getReusableComponents(analyzer, fieldName);
            }
        }

        @Override
        public void setReusableComponents(Analyzer analyzer, String fieldName, TokenStreamComponents components) {
            if (analyzer == wrapper) {
                final Analyzer wrappedAnalyzer = wrapper.getWrappedAnalyzer(fieldName);
                wrappedAnalyzer.getReuseStrategy().setReusableComponents(wrappedAnalyzer, fieldName, components);
            } else {
                fallbackStrategy.setReusableComponents(analyzer, fieldName, components);
            }
        }
    };

}