Search in sources :

Example 1 with VersionComparator

use of grails.plugins.VersionComparator in project grails-core by grails.

the class RegexUrlMapping method compareTo.

/**
 * Compares this UrlMapping instance with the specified UrlMapping instance and deals with URL mapping precedence rules.
 *
 *  URL Mapping Precedence Order
 *
 *   1. Less wildcard tokens.
 *
 *       /foo          <- match
 *       /foo/(*)
 *
 *      /foo/(*)/bar/  <- match
 *      /foo/(*)/(*)
 *
 *    2. More static tokens.
 *
 *      /foo/(*)/bar   <- match
 *      /foo/(*)
 *
 * @param o An instance of the UrlMapping interface
 * @return greater than 0 if this UrlMapping should match before the specified UrlMapping. 0 if they are equal or less than 0 if this UrlMapping should match after the given UrlMapping
 */
public int compareTo(Object o) {
    if (!(o instanceof UrlMapping)) {
        throw new IllegalArgumentException("Cannot compare with Object [" + o + "]. It is not an instance of UrlMapping!");
    }
    if (equals(o))
        return 0;
    UrlMapping other = (UrlMapping) o;
    // this wild card count
    final int thisStaticTokenCount = getStaticTokenCount(this);
    final int thisSingleWildcardCount = getSingleWildcardCount(this);
    final int thisDoubleWildcardCount = getDoubleWildcardCount(this);
    // the other wild card count
    final int otherStaticTokenCount = getStaticTokenCount(other);
    final int otherSingleWildcardCount = getSingleWildcardCount(other);
    final int otherDoubleWildcardCount = getDoubleWildcardCount(other);
    final boolean hasWildCards = thisDoubleWildcardCount > 0 || thisSingleWildcardCount > 0;
    final boolean otherHasWildCards = otherDoubleWildcardCount > 0 || otherSingleWildcardCount > 0;
    // Always prioritise the / root mapping
    boolean isThisRoot = thisStaticTokenCount == 0 && thisSingleWildcardCount == 0 && thisDoubleWildcardCount == 0;
    boolean isThatRoot = otherStaticTokenCount == 0 && otherDoubleWildcardCount == 0 && otherSingleWildcardCount == 0;
    if (isThisRoot && isThatRoot) {
        return evaluatePluginOrder(other);
    } else if (isThisRoot) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Mapping [{}] has a higher precedence than [{}] because it is the root", this.toString(), other.toString());
        }
        return 1;
    } else if (isThatRoot) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Mapping [{}] has a lower precedence than [{}] because the latter is the root", this.toString(), other.toString());
        }
        return -1;
    }
    if (otherStaticTokenCount == 0 && thisStaticTokenCount > 0) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Mapping [{}] has a higher precedence than [{}] because it has more path tokens", this.toString(), other.toString());
        }
        return 1;
    }
    if (thisStaticTokenCount == 0 && otherStaticTokenCount > 0) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Mapping [{}] has a lower precedence than [{}] because it has fewer path tokens", this.toString(), other.toString());
        }
        return -1;
    }
    final int thisStaticAndWildcardTokenCount = getStaticAndWildcardTokenCount(this);
    final int otherStaticAndWildcardTokenCount = getStaticAndWildcardTokenCount(other);
    if (otherStaticAndWildcardTokenCount == 0 && thisStaticAndWildcardTokenCount > 0) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Mapping [{}] has a higher precedence than [{}] because it has more path tokens [{} vs {}]", this.toString(), other.toString(), thisStaticAndWildcardTokenCount, otherStaticAndWildcardTokenCount);
        }
        return 1;
    }
    if (thisStaticAndWildcardTokenCount == 0 && otherStaticAndWildcardTokenCount > 0) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Mapping [{}] has a higher precedence than [{}] because the latter has more path tokens [{} vs {}]", this.toString(), other.toString(), thisStaticAndWildcardTokenCount, otherStaticAndWildcardTokenCount);
        }
        return -1;
    }
    final int staticDiff = thisStaticTokenCount - otherStaticTokenCount;
    if (staticDiff < 0 && !otherHasWildCards) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Mapping [{}] has a lower precedence than [{}] because the latter has more concrete path tokens [{} vs {}]", this.toString(), other.toString(), thisStaticTokenCount, otherStaticTokenCount);
        }
        return -1;
    } else if (staticDiff > 0 && !hasWildCards) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Mapping [{}] has a higher precedence than [{}] because it has more concrete path tokens [{} vs {}]", this.toString(), other.toString(), thisStaticTokenCount, otherStaticTokenCount);
        }
        return 1;
    }
    String[] thisTokens = getUrlData().getTokens();
    String[] otherTokens = other.getUrlData().getTokens();
    final int thisTokensLength = thisTokens.length;
    final int otherTokensLength = otherTokens.length;
    int greaterLength = thisTokensLength > otherTokensLength ? thisTokensLength : otherTokensLength;
    for (int i = 0; i < greaterLength; i++) {
        final boolean thisHasMoreTokens = i < thisTokensLength;
        final boolean otherHasMoreTokens = i < otherTokensLength;
        boolean thisTokenIsWildcard = !thisHasMoreTokens || isSingleWildcard(thisTokens[i]);
        boolean otherTokenIsWildcard = !otherHasMoreTokens || isSingleWildcard(otherTokens[i]);
        if (thisTokenIsWildcard && !otherTokenIsWildcard) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("Mapping [{}] has a lower precedence than [{}] because the latter contains more concrete tokens", this.toString(), other.toString());
            }
            return -1;
        }
        if (!thisTokenIsWildcard && otherTokenIsWildcard) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("Mapping [{}] has a higher precedence than [{}] because it contains more concrete tokens", this.toString(), other.toString());
            }
            return 1;
        }
    }
    final int doubleWildcardDiff = otherDoubleWildcardCount - thisDoubleWildcardCount;
    if (doubleWildcardDiff != 0) {
        if (LOG.isDebugEnabled()) {
            if (doubleWildcardDiff > 0) {
                LOG.debug("Mapping [{}] has a higher precedence than [{}] due containing more double wild cards [{} vs. {}]", this.toString(), other.toString(), thisDoubleWildcardCount, otherDoubleWildcardCount);
            } else if (doubleWildcardDiff < 0) {
                LOG.debug("Mapping [{}] has a lower precedence than [{}] due to the latter containing more double wild cards [{} vs. {}]", this.toString(), other.toString(), thisDoubleWildcardCount, otherDoubleWildcardCount);
            }
        }
        return doubleWildcardDiff;
    }
    final int singleWildcardDiff = otherSingleWildcardCount - thisSingleWildcardCount;
    if (singleWildcardDiff != 0) {
        if (LOG.isDebugEnabled()) {
            if (singleWildcardDiff > 0) {
                LOG.debug("Mapping [{}] has a higher precedence than [{}] because it contains more single wild card matches [{} vs. {}]", this.toString(), other.toString(), thisSingleWildcardCount, otherSingleWildcardCount);
            } else if (singleWildcardDiff < 0) {
                LOG.debug("Mapping [{}] has a lower precedence than [{}] due to the latter containing more single wild card matches[{} vs. {}]", this.toString(), other.toString(), thisSingleWildcardCount, otherSingleWildcardCount);
            }
        }
        return singleWildcardDiff;
    }
    int thisConstraintCount = getAppliedConstraintsCount(this);
    int thatConstraintCount = getAppliedConstraintsCount(other);
    int constraintDiff = thisConstraintCount - thatConstraintCount;
    if (constraintDiff != 0) {
        if (LOG.isDebugEnabled()) {
            if (constraintDiff > 0) {
                LOG.debug("Mapping [{}] has a higher precedence than [{}] since it defines more constraints [{} vs. {}]", this.toString(), other.toString(), thisConstraintCount, thatConstraintCount);
            } else if (constraintDiff < 0) {
                LOG.debug("Mapping [{}] has a lower precedence than [{}] since the latter defines more constraints [{} vs. {}]", this.toString(), other.toString(), thisConstraintCount, thatConstraintCount);
            }
        }
        return constraintDiff;
    }
    int allDiff = (thisStaticTokenCount - otherStaticTokenCount) + (thisSingleWildcardCount - otherSingleWildcardCount) + (thisDoubleWildcardCount - otherDoubleWildcardCount);
    if (allDiff != 0) {
        if (LOG.isDebugEnabled()) {
            if (allDiff > 0) {
                LOG.debug("Mapping [{}] has a higher precedence than [{}] due to the overall diff", this.toString(), other.toString());
            } else if (allDiff < 0) {
                LOG.debug("Mapping [{}] has a lower precedence than [{}] due to the overall diff", this.toString(), other.toString());
            }
        }
        return allDiff;
    }
    String thisVersion = getVersion();
    String thatVersion = other.getVersion();
    if ((thisVersion.equals(thatVersion))) {
        return evaluatePluginOrder(other);
    } else if (thisVersion.equals(ANY_VERSION) && !thatVersion.equals(ANY_VERSION)) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Mapping [{}] has a lower precedence than [{}] due to version precedence [{} vs {}]", this.toString(), other.toString(), thisVersion, thatVersion);
        }
        return -1;
    } else if (!thisVersion.equals(ANY_VERSION) && thatVersion.equals(ANY_VERSION)) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Mapping [{}] has a higher precedence than [{}] due to version precedence [{} vs {}]", this.toString(), other.toString(), thisVersion, thatVersion);
        }
        return 1;
    } else {
        int i = new VersionComparator().compare(thisVersion, thatVersion);
        if (i > 0) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("Mapping [{}] has a higher precedence than [{}] due to version precedence [{} vs. {}]", this.toString(), other.toString(), thisVersion, thatVersion);
            }
            return 1;
        } else if (i < 0) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("Mapping [{}] has a lower precedence than [{}] due to version precedence [{} vs. {}]", this.toString(), other.toString(), thisVersion, thatVersion);
            }
            return -1;
        } else {
            return evaluatePluginOrder(other);
        }
    }
}
Also used : UrlMapping(grails.web.mapping.UrlMapping) VersionComparator(grails.plugins.VersionComparator)

Aggregations

VersionComparator (grails.plugins.VersionComparator)1 UrlMapping (grails.web.mapping.UrlMapping)1