use of grails.web.mapping.UrlMapping in project grails-core by grails.
the class DefaultUrlMappingEvaluatorTests method testRedirectMappings.
public void testRedirectMappings() throws Exception {
GroovyShell shell = new GroovyShell();
Binding binding = new Binding();
Script script = shell.parse("mappings = {\n" + "\"/first\"(redirect:[controller: 'foo', action: 'bar'])\n" + "\"/second\"(redirect: '/bing/bang')\n" + "}");
script.setBinding(binding);
script.run();
Closure closure = (Closure) binding.getVariable("mappings");
List<UrlMapping> mappings = evaluator.evaluateMappings(closure);
assertEquals(2, mappings.size());
Object redirectInfo = mappings.get(0).getRedirectInfo();
assertTrue(redirectInfo instanceof Map);
Map redirectMap = (Map) redirectInfo;
assertEquals(2, redirectMap.size());
assertEquals("foo", redirectMap.get("controller"));
assertEquals("bar", redirectMap.get("action"));
assertEquals("/bing/bang", mappings.get(1).getRedirectInfo());
}
use of grails.web.mapping.UrlMapping 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);
}
}
}
use of grails.web.mapping.UrlMapping in project grails-core by grails.
the class DefaultUrlMappingsHolder method addMappings.
@Override
public Collection<UrlMapping> addMappings(Closure mappings) {
WebApplicationContext applicationContext = (WebApplicationContext) Holders.findApplicationContext();
UrlMappingEvaluator evaluator = new DefaultUrlMappingEvaluator(applicationContext);
List<UrlMapping> newMappings = evaluator.evaluateMappings(mappings);
this.urlMappings.addAll(newMappings);
initialize();
return newMappings;
}
use of grails.web.mapping.UrlMapping in project grails-core by grails.
the class DefaultUrlMappingsHolder method matchAll.
public UrlMappingInfo[] matchAll(String uri, String httpMethod, String version) {
if (isExcluded(uri))
return EMPTY_RESULTS;
UriToUrlMappingKey cacheKey = new UriToUrlMappingKey(uri, httpMethod, version);
List<UrlMappingInfo> matchingUrls = cachedListMatches.getIfPresent(cacheKey);
if (matchingUrls == null) {
matchingUrls = new ArrayList<>();
boolean anyHttpMethod = httpMethod != null && httpMethod.equals(UrlMapping.ANY_HTTP_METHOD);
boolean anyVersion = version != null && version.equals(UrlMapping.ANY_VERSION);
for (UrlMapping mapping : mappings) {
if (LOG.isDebugEnabled()) {
LOG.debug("Attempting to match URI [" + uri + "] with pattern [" + mapping.getUrlData().getUrlPattern() + "]");
}
UrlMappingInfo current = mapping.match(uri);
if (current != null) {
if (LOG.isDebugEnabled()) {
LOG.debug("Matched URI [" + uri + "] with pattern [" + mapping.getUrlData().getUrlPattern() + "], adding to posibilities");
}
String mappingHttpMethod = current.getHttpMethod();
String mappingVersion = current.getVersion();
boolean isValidHttpMethod = mappingHttpMethod == null || anyHttpMethod || mappingHttpMethod.equalsIgnoreCase(UrlMapping.ANY_HTTP_METHOD) || mappingHttpMethod.equalsIgnoreCase(httpMethod);
boolean isValidVersion = mappingVersion == null || anyVersion || mappingVersion.equals(UrlMapping.ANY_VERSION) || mappingVersion.equals(version);
if (isValidHttpMethod && isValidVersion) {
matchingUrls.add(current);
}
}
}
cachedListMatches.put(cacheKey, matchingUrls);
}
return matchingUrls.toArray(new UrlMappingInfo[matchingUrls.size()]);
}
use of grails.web.mapping.UrlMapping in project grails-core by grails.
the class DefaultUrlMappingsHolder method matchStatusCode.
public UrlMappingInfo matchStatusCode(int responseCode) {
for (UrlMapping mapping : mappings) {
if (mapping instanceof ResponseCodeUrlMapping) {
ResponseCodeUrlMapping responseCodeUrlMapping = (ResponseCodeUrlMapping) mapping;
if (responseCodeUrlMapping.getExceptionType() != null)
continue;
final UrlMappingInfo current = responseCodeUrlMapping.match(responseCode);
if (current != null)
return current;
}
}
return null;
}
Aggregations