| /* |
| * 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)); |
| // häckidy-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); |
| } |
| } |
| } |
| ; |
| } |