public int compareTo()

in grails-web-url-mappings/src/main/groovy/org/grails/web/mapping/RegexUrlMapping.java [742:944]


    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);
            }
        }
    }