org.trnltk.morphology.contextless.rootfinder.RootFinderChain.java Source code

Java tutorial

Introduction

Here is the source code for org.trnltk.morphology.contextless.rootfinder.RootFinderChain.java

Source

/*
 * Copyright  2013  Ali Ok (aliokATapacheDOTorg)
 *
 *  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.trnltk.morphology.contextless.rootfinder;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.Validate;
import org.trnltk.model.lexicon.Root;
import org.trnltk.model.letter.TurkishSequence;

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

public class RootFinderChain {

    private RootValidator rootValidator;
    private LinkedList<RootFinderChainItem> rootFinderChainItems = new LinkedList<RootFinderChainItem>();

    public RootFinderChain(RootValidator rootValidator) {
        this.rootValidator = rootValidator;
    }

    public RootFinderChain offer(RootFinder rootFinder, RootFinderPolicy rootFinderPolicy) {
        if (RootFinderPolicy.STOP_CHAIN_WHEN_INPUT_IS_HANDLED.equals(rootFinderPolicy)) {
            final RootFinderChainItem lastChainItem = rootFinderChainItems.peekLast();
            if (lastChainItem != null
                    && lastChainItem.getRootFinderPolicy().equals(RootFinderPolicy.CONTINUE_ON_CHAIN))
                throw new IllegalStateException(String.format("Unoptimal RootFinderChain! RootFinder instance %s "
                        + "with policy STOP_CHAIN_WHEN_INPUT_IS_HANDLED was tried to be added after a RootFinder instance with policy CONTINUE_ON_CHAIN",
                        rootFinder.getClass().getName()));
        }
        this.rootFinderChainItems.offer(new RootFinderChainItem(rootFinder, rootFinderPolicy));
        return this;
    }

    public List<Root> findRootsForPartialInput(TurkishSequence partialInput, TurkishSequence input) {
        LinkedList<Root> roots = new LinkedList<Root>();
        for (RootFinderChainItem rootFinderChainItem : rootFinderChainItems) {
            final RootFinder rootFinder = rootFinderChainItem.getRootFinder();
            final RootFinderPolicy rootFinderPolicy = rootFinderChainItem.getRootFinderPolicy();

            if (!rootFinder.handles(partialInput, input))
                continue;
            final Collection<? extends Root> rootsForPartialInput = rootFinder
                    .findRootsForPartialInput(partialInput, input);
            if (CollectionUtils.isNotEmpty(rootsForPartialInput)) {
                //roots must be beginning of the partial input
                for (Root rootForPartialInput : rootsForPartialInput) {
                    final boolean isPartialInputValid = rootValidator.isValid(rootForPartialInput, partialInput);
                    if (!isPartialInputValid)
                        throw new IllegalArgumentException("Invalid root " + rootForPartialInput.toString()
                                + " for partial input " + partialInput);
                }
                roots.addAll(rootsForPartialInput);
            }

            if (RootFinderPolicy.CONTINUE_ON_CHAIN.equals(rootFinderPolicy))
                //noinspection UnnecessaryContinue
                continue;
            else if (RootFinderPolicy.STOP_CHAIN_WHEN_INPUT_IS_HANDLED.equals(rootFinderPolicy))
                break;
            else
                throw new IllegalStateException();
        }
        return roots;
    }

    public boolean hasRootFinders() {
        return !rootFinderChainItems.isEmpty();
    }

    public enum RootFinderPolicy {
        STOP_CHAIN_WHEN_INPUT_IS_HANDLED, CONTINUE_ON_CHAIN
    }

    private static class RootFinderChainItem {
        private final RootFinder rootFinder;
        private final RootFinderPolicy rootFinderPolicy;

        private RootFinderChainItem(RootFinder rootFinder, RootFinderPolicy rootFinderPolicy) {
            Validate.notNull(rootFinder);
            Validate.notNull(rootFinderPolicy);

            this.rootFinder = rootFinder;
            this.rootFinderPolicy = rootFinderPolicy;
        }

        public RootFinder getRootFinder() {
            return rootFinder;
        }

        public RootFinderPolicy getRootFinderPolicy() {
            return rootFinderPolicy;
        }
    }
}