/*
* =============================================================================
*
* Copyright (c) 2011-2016, The THYMELEAF team (http://www.thymeleaf.org)
*
* 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.thymeleaf.util;
import java.util.Comparator;
import org.thymeleaf.postprocessor.IPostProcessor;
import org.thymeleaf.preprocessor.IPreProcessor;
import org.thymeleaf.processor.IProcessor;
/**
*
* @author Daniel Fernández
* @since 3.0.0
*
*/
public final class ProcessorComparators {
public static final Comparator<IProcessor> PROCESSOR_COMPARATOR = new ProcessorPrecedenceComparator();
public static final Comparator<IPreProcessor> PRE_PROCESSOR_COMPARATOR = new PreProcessorPrecedenceComparator();
public static final Comparator<IPostProcessor> POST_PROCESSOR_COMPARATOR = new PostProcessorPrecedenceComparator();
private ProcessorComparators() {
super();
}
private static final class ProcessorPrecedenceComparator implements Comparator<IProcessor> {
ProcessorPrecedenceComparator() {
super();
}
public int compare(final IProcessor o1, final IProcessor o2) {
if (o1 == o2) {
// This is the only case in which the comparison of two processors will return 0
return 0;
}
if (o1 instanceof ProcessorConfigurationUtils.AbstractProcessorWrapper && o2 instanceof ProcessorConfigurationUtils.AbstractProcessorWrapper) {
return compareWrapped((ProcessorConfigurationUtils.AbstractProcessorWrapper)o1, (ProcessorConfigurationUtils.AbstractProcessorWrapper)o2);
}
final int processorPrecedenceComp = compareInts(o1.getPrecedence(), o2.getPrecedence());
if (processorPrecedenceComp != 0) {
return processorPrecedenceComp;
}
final int classNameComp = o1.getClass().getName().compareTo(o2.getClass().getName());
if (classNameComp != 0) {
return classNameComp;
}
return compareInts(System.identityHashCode(o1), System.identityHashCode(o2)); // Cannot be 0
}
/*
* Processors are wrapped and therefore we can apply dialect precedence
*/
private int compareWrapped(final ProcessorConfigurationUtils.AbstractProcessorWrapper o1w, final ProcessorConfigurationUtils.AbstractProcessorWrapper o2w) {
final int dialectPrecedenceComp = compareInts(o1w.getDialectPrecedence(), o2w.getDialectPrecedence());
if (dialectPrecedenceComp != 0) {
return dialectPrecedenceComp;
}
final IProcessor o1 = o1w.unwrap();
final IProcessor o2 = o2w.unwrap();
final int processorPrecedenceComp = compareInts(o1.getPrecedence(), o2.getPrecedence());
if (processorPrecedenceComp != 0) {
return processorPrecedenceComp;
}
final int classNameComp = o1.getClass().getName().compareTo(o2.getClass().getName());
if (classNameComp != 0) {
return classNameComp;
}
return compareInts(System.identityHashCode(o1), System.identityHashCode(o2)); // Cannot be 0
}
private static int compareInts(int x, int y) {
return (x < y) ? -1 : ((x == y) ? 0 : 1);
}
}
private static final class PreProcessorPrecedenceComparator implements Comparator<IPreProcessor> {
PreProcessorPrecedenceComparator() {
super();
}
public int compare(final IPreProcessor o1, final IPreProcessor o2) {
if (o1 == o2) {
// This is the only case in which the comparison of two processors will return 0
return 0;
}
if (o1 instanceof ProcessorConfigurationUtils.PreProcessorWrapper && o2 instanceof ProcessorConfigurationUtils.PreProcessorWrapper) {
return compareWrapped((ProcessorConfigurationUtils.PreProcessorWrapper)o1, (ProcessorConfigurationUtils.PreProcessorWrapper)o2);
}
final int preProcessorPrecedenceComp = compareInts(o1.getPrecedence(), o2.getPrecedence());
if (preProcessorPrecedenceComp != 0) {
return preProcessorPrecedenceComp;
}
final int classNameComp = o1.getClass().getName().compareTo(o2.getClass().getName());
if (classNameComp != 0) {
return classNameComp;
}
return compareInts(System.identityHashCode(o1), System.identityHashCode(o2)); // Cannot be 0
}
/*
* Processors are wrapped and therefore we can apply dialect precedence
*/
private int compareWrapped(final ProcessorConfigurationUtils.PreProcessorWrapper o1w, final ProcessorConfigurationUtils.PreProcessorWrapper o2w) {
final int dialectPrecedenceComp = compareInts(o1w.getDialect().getDialectProcessorPrecedence(), o2w.getDialect().getDialectProcessorPrecedence());
if (dialectPrecedenceComp != 0) {
return dialectPrecedenceComp;
}
final IPreProcessor o1 = o1w.unwrap();
final IPreProcessor o2 = o2w.unwrap();
final int processorPrecedenceComp = compareInts(o1.getPrecedence(), o2.getPrecedence());
if (processorPrecedenceComp != 0) {
return processorPrecedenceComp;
}
final int classNameComp = o1.getClass().getName().compareTo(o2.getClass().getName());
if (classNameComp != 0) {
return classNameComp;
}
return compareInts(System.identityHashCode(o1), System.identityHashCode(o2)); // Cannot be 0
}
private static int compareInts(int x, int y) {
return (x < y) ? -1 : ((x == y) ? 0 : 1);
}
}
private static final class PostProcessorPrecedenceComparator implements Comparator<IPostProcessor> {
PostProcessorPrecedenceComparator() {
super();
}
public int compare(final IPostProcessor o1, final IPostProcessor o2) {
if (o1 == o2) {
// This is the only case in which the comparison of two processors will return 0
return 0;
}
if (o1 instanceof ProcessorConfigurationUtils.PostProcessorWrapper && o2 instanceof ProcessorConfigurationUtils.PostProcessorWrapper) {
return compareWrapped((ProcessorConfigurationUtils.PostProcessorWrapper)o1, (ProcessorConfigurationUtils.PostProcessorWrapper)o2);
}
final int postProcessorPrecedenceComp = compareInts(o1.getPrecedence(), o2.getPrecedence());
if (postProcessorPrecedenceComp != 0) {
return postProcessorPrecedenceComp;
}
final int classNameComp = o1.getClass().getName().compareTo(o2.getClass().getName());
if (classNameComp != 0) {
return classNameComp;
}
return compareInts(System.identityHashCode(o1), System.identityHashCode(o2)); // Cannot be 0
}
/*
* Processors are wrapped and therefore we can apply dialect precedence
*/
private int compareWrapped(final ProcessorConfigurationUtils.PostProcessorWrapper o1w, final ProcessorConfigurationUtils.PostProcessorWrapper o2w) {
final int dialectPrecedenceComp = compareInts(o1w.getDialect().getDialectProcessorPrecedence(), o2w.getDialect().getDialectProcessorPrecedence());
if (dialectPrecedenceComp != 0) {
return dialectPrecedenceComp;
}
final IPostProcessor o1 = o1w.unwrap();
final IPostProcessor o2 = o2w.unwrap();
final int processorPrecedenceComp = compareInts(o1.getPrecedence(), o2.getPrecedence());
if (processorPrecedenceComp != 0) {
return processorPrecedenceComp;
}
final int classNameComp = o1.getClass().getName().compareTo(o2.getClass().getName());
if (classNameComp != 0) {
return classNameComp;
}
return compareInts(System.identityHashCode(o1), System.identityHashCode(o2)); // Cannot be 0
}
private static int compareInts(int x, int y) {
return (x < y) ? -1 : ((x == y) ? 0 : 1);
}
}
}