org.amelia.dsl.lib.util.PairMatcher.java Source code

Java tutorial

Introduction

Here is the source code for org.amelia.dsl.lib.util.PairMatcher.java

Source

/*
 * Copyright  2015 Universidad Icesi
 * 
 * This file is part of the Amelia project.
 * 
 * The Amelia project is free software: you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or (at your
 * option) any later version.
 * 
 * The Amelia project is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
 * for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with the Amelia project. If not, see <http://www.gnu.org/licenses/>.
 */
package org.amelia.dsl.lib.util;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Stack;

import com.google.common.collect.Range;

/**
 * @author Miguel Jimnez - Initial contribution and API
 */
public class PairMatcher {

    private static Comparator<Range<Integer>> ascendent = new Comparator<Range<Integer>>() {
        public int compare(Range<Integer> r1, Range<Integer> r2) {
            if (r1.lowerEndpoint() < r2.lowerEndpoint()) {
                return -1;
            } else if (r1.lowerEndpoint() > r2.lowerEndpoint()) {
                return 1;
            }
            return 0;
        }
    };

    private static Comparator<Range<Integer>> descendent = new Comparator<Range<Integer>>() {
        public int compare(Range<Integer> r1, Range<Integer> r2) {
            if (r1.upperEndpoint() > r2.upperEndpoint()) {
                return -1;
            } else if (r1.upperEndpoint() < r2.upperEndpoint()) {
                return 1;
            }
            return 0;
        }
    };

    private final String text;

    private List<Range<Integer>> regions;

    private char leftDelimiter;

    private char rightDelimiter;

    public PairMatcher(final String text, final char leftDelimiter, final char rightDelimiter) {
        this.text = text;
        this.leftDelimiter = leftDelimiter;
        this.rightDelimiter = rightDelimiter;
    }

    public void removeRedundantRegions() {
        if (this.regions == null)
            calculateRegions();
        List<Range<Integer>> redundant = redundantRegions();
        List<Range<Integer>> cleaned = new ArrayList<Range<Integer>>();
        for (Range<Integer> r : this.regions) {
            if (!redundant.contains(r)) {
                cleaned.add(r);
            }
        }
        this.regions = cleaned;
    }

    public List<Range<Integer>> redundantRegions() {
        if (this.regions == null)
            calculateRegions();
        Collections.sort(this.regions, ascendent);
        List<Range<Integer>> redundantRegions = new ArrayList<Range<Integer>>();
        for (int i = 0; i < this.regions.size(); i++) {
            Range<Integer> r1 = this.regions.get(i);
            for (Range<Integer> r2 : this.regions.subList(i + 1, this.regions.size())) {
                if (r1.lowerEndpoint() <= r2.lowerEndpoint() && r1.upperEndpoint() >= r2.upperEndpoint()) {
                    redundantRegions.add(r2);
                }
            }
        }
        Collections.sort(this.regions, descendent);
        return redundantRegions;
    }

    private void calculateRegions() {
        final List<Range<Integer>> regions = new ArrayList<Range<Integer>>();
        final char[] characters = this.text.toCharArray();
        final Stack<Character> lefties = new Stack<Character>();
        final Stack<Integer> starts = new Stack<Integer>();
        for (int i = 0; i < characters.length; i++) {
            if (!lefties.isEmpty() && characters[i] == this.rightDelimiter) {
                lefties.pop();
                regions.add(Range.closed(starts.pop(), i));
            } else if (characters[i] == this.leftDelimiter) {
                lefties.add(characters[i]);
                starts.add(i);
            }
        }
        this.regions = regions;
    }

    public List<Range<Integer>> getRegions() {
        if (this.regions == null)
            calculateRegions();
        return this.regions;
    }

}