com.github.sommeri.less4j.utils.ListsComparator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of less4j Show documentation
Show all versions of less4j Show documentation
Less language is an extension of css and less4j compiles it into regular css. It adds several dynamic features into css: variables, expressions, nested rules.
Less4j is a port. The original compiler was written in JavaScript and is called less.js. The less language is mostly defined in less.js documentation/issues and by what less.js actually do. Links to less.js:
* home page: http://lesscss.org/
* source code & issues: https://github.com/cloudhead/less.js
package com.github.sommeri.less4j.utils;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ListsComparator {
public boolean equals(List first, List second, ListMemberComparator comparator) {
if (first.size() != second.size())
return false;
Iterator i1 = first.iterator();
Iterator i2 = second.iterator();
while (i1.hasNext()) {
T firstMember = i1.next();
T secondMember = i2.next();
if (!comparator.equals(firstMember, secondMember))
return false;
}
return true;
}
public boolean prefix(List lookFor, List inList, ListMemberComparator comparator) {
if (lookFor.isEmpty())
return true;
if (lookFor.size() > inList.size())
return false;
List relevantInList = ArraysUtils.sameLengthPrefix(inList, lookFor);
List relevantInListWithoutLast = ArraysUtils.sublistWithoutLast(relevantInList);
List lookForWithoutLast = ArraysUtils.sublistWithoutLast(lookFor);
if (!equals(lookForWithoutLast, relevantInListWithoutLast, comparator))
return false;
return comparator.prefix(ArraysUtils.last(lookFor), ArraysUtils.last(relevantInList));
}
public MatchMarker prefixMatches(List lookFor, List inList, ListMemberComparator comparator) {
if (lookFor.isEmpty() || lookFor.size() > inList.size())
return null;
List relevantInList = ArraysUtils.sameLengthPrefix(inList, lookFor);
List relevantInListWithoutLast = ArraysUtils.sublistWithoutLast(relevantInList);
List lookForWithoutLast = ArraysUtils.sublistWithoutLast(lookFor);
if (!equals(lookForWithoutLast, relevantInListWithoutLast, comparator))
return null ;
boolean isPrefix = comparator.prefix(ArraysUtils.last(lookFor), ArraysUtils.last(relevantInList));
if (isPrefix)
return new MatchMarker(ArraysUtils.first(relevantInList), ArraysUtils.last(relevantInList), false);
return null;
}
public T prefixEnd(List lookFor, List inList, ListMemberComparator comparator) {
if (lookFor.isEmpty())
return inList.isEmpty() ? null : inList.get(0);
if (lookFor.size() > inList.size())
return null;
List relevantInList = ArraysUtils.sameLengthPrefix(inList, lookFor);
List relevantInListWithoutLast = ArraysUtils.sublistWithoutLast(relevantInList);
List lookForWithoutLast = ArraysUtils.sublistWithoutLast(lookFor);
if (!equals(lookForWithoutLast, relevantInListWithoutLast, comparator))
return null;
if (comparator.prefix(ArraysUtils.last(lookFor), ArraysUtils.last(relevantInList)))
return ArraysUtils.last(relevantInList);
return null;
}
public boolean suffix(List lookFor, List inList, ListMemberComparator comparator) {
return null!=suffixMatches(lookFor, inList, comparator);
}
public MatchMarker suffixMatches(List lookFor, List inList, ListMemberComparator comparator) {
if (lookFor.isEmpty() || lookFor.size() > inList.size())
return null;
List relevantInList = ArraysUtils.sameLengthSuffix(inList, lookFor);
List relevantInListWithoutFirst = ArraysUtils.sublistWithoutFirst(relevantInList);
List lookForWithoutFirst = ArraysUtils.sublistWithoutFirst(lookFor);
if (!equals(lookForWithoutFirst, relevantInListWithoutFirst, comparator))
return null;
boolean isSuffix = comparator.suffix(ArraysUtils.first(lookFor), ArraysUtils.first(relevantInList));
if (isSuffix)
return new MatchMarker(ArraysUtils.first(relevantInList), ArraysUtils.last(relevantInList), false);
return null;
}
public boolean contains(List lookFor, List inList, ListMemberComparator comparator) {
return !findMatches(lookFor, inList, comparator).isEmpty();
}
public List> findMatches(List lookFor, List inList, ListMemberComparator comparator) {
return collectMatches(lookFor, inList, comparator, new ArrayList>());
}
public List> collectMatches(List lookFor, List inList, ListMemberComparator comparator, List> result) {
if (lookFor.isEmpty() || lookFor.size() > inList.size())
return result;
if (lookFor.size() == 1) {
return collectMatches(ArraysUtils.first(lookFor), inList, comparator, result);
}
T firstLookFor = ArraysUtils.first(lookFor);
T firstInList = ArraysUtils.first(inList);
List remainderLookFor = ArraysUtils.sublistWithoutFirst(lookFor);
List remainderInList = ArraysUtils.sublistWithoutFirst(inList);
boolean firstIsSuffix = comparator.suffix(firstLookFor, firstInList);
T prefixEnd = prefixEnd(remainderLookFor, remainderInList, comparator);
boolean remainderIsPrefix = prefixEnd != null;
if (firstIsSuffix && remainderIsPrefix) {
result.add(new MatchMarker(firstInList, prefixEnd, false));
}
collectMatches(lookFor, remainderInList, comparator, result);
return result;
}
private List> collectMatches(T lookFor, List inParts, ListMemberComparator comparator, List> result) {
for (T inPart : inParts) {
if (comparator.contains(lookFor, inPart))
result.add(new MatchMarker(inPart, inPart, false));
}
return result;
}
public static interface ListMemberComparator {
public boolean equals(T first, T second);
public boolean prefix(T lookFor, T inside);
public boolean suffix(T lookFor, T inside);
public boolean contains(T lookFor, T inside);
}
public static interface ModifiedListBuilder {
public boolean splitInside(T lookFor, T inPart, List replaceBy);
public boolean cutSuffix(T lookFor, T inside, List replaceBy);
public boolean cutPrefix(T lookFor, T inside, List replaceBy);
}
public class MatchMarker {
private T first;
private T last;
private boolean isEquals;
public MatchMarker(T first, T last, boolean isEquals) {
this.first = first;
this.last = last;
this.isEquals = isEquals;
}
public T getFirst() {
return first;
}
public void setFirst(T first) {
this.first = first;
}
public T getLast() {
return last;
}
public void setLast(T last) {
this.last = last;
}
public boolean isEquals() {
return isEquals;
}
public void setEquals(boolean isEquals) {
this.isEquals = isEquals;
}
public boolean firstIsLast() {
return first==last;
}
public boolean isIn(List list) {
return list.contains(getFirst()) && list.contains(getLast());
}
}
}