/*
 * Copyright 2004-2005 the original author or authors.
 *
 * 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.codehaus.groovy.grails.web.mapping;

import java.util.Map;

import org.codehaus.groovy.grails.validation.ConstrainedProperty;

/**
 * <p>Defines a URL mapping. A URL mapping is a mapping between a URI such as /book/list and
 * a controller, action and/or id.</p>
 *
 * <p>A UrlMapping should implement Comparable so that UrlMapping instances can be ordered to allow for precendence rules.
 * In other words the URL /book/list should be matched before /book/* as the wildcard is of lesser precedence. By implementing
 * Comparable this can be allowed for.
 * </p>
 *
 * @author Graeme Rocher
 * @since 0.5
 */
@SuppressWarnings("rawtypes")
public interface UrlMapping extends Comparable, UrlCreator {

    String CONTROLLER = "controller";
    String ACTION = "action";

    /**
     * Matches the given URI and returns an instance of the UrlMappingInfo interface or null
     * if a match couldn't be established
     *
     * @param uri The URI to match
     * @return An instance of UrlMappingInfo or null if the URI doesn't match
     */
    UrlMappingInfo match(String uri);

    /**
     * Retrieves the UrlMappingData instance that describes this UrlMapping
     *
     * @return The UrlMappingData instance
     */
    UrlMappingData getUrlData();

    /**
     * <p>The constraints the apply to this UrlMapping. Each constraint maps to a GString token in a
     * URL mapping in order. For example consider the URL:
     *
     * <pre>
     * <code>
     *     /blog/$author/$title/$year?/$month?/$day?
     * </code></pre>
     *
     * <p>This results in 5 ConstrainedProperty instances called author, title, year, month and day
     *
     * @return An array containing the ConstrainedProperty objects of this URLMapping
     */
    ConstrainedProperty[] getConstraints();

    /**
     * Retrieves the controller name which is either a groovy.lang.Closure that evaluates the controller
     * name at runtime or a java.lang.String that represents the controller name
     *
     * @return The controller name as a {@link groovy.lang.Closure} or {@link java.lang.String}
     */
    Object getControllerName();

    /**
     * Retrieves the action name which is either a groovy.lang.Closure that evaluates the action
     * name at runtime or a java.lang.String that represents the action name
     *
     * @return The action name as a {@link groovy.lang.Closure} or {@link java.lang.String}
     */
    Object getActionName();

    /**
     * Returns the name of the view to map to
     * @return The view name
     */
    Object getViewName();

    /**
     * Sets any parameter values that should be populated into the request
     * @param parameterValues The parameter values to set
     */
    void setParameterValues(Map parameterValues);

    /**
     * Sets whether this UrlMapping should parse the request
     *
     * @param shouldParse True if it should
     */
    void setParseRequest(boolean shouldParse);

    String getMappingName();

    void setMappingName(String name);

    /**
     * @param isREST Set whether this is a RESTful mapping
     */
    void setRestfulMapping(boolean isREST);

    /**
     * @return Whether this is a RESTful mapping
     */
    boolean isRestfulMapping();

    /**
     * Whether the mapping has a runtime variable with the given name such as "/$foo"
     * @param name The name of the variable
     * @return True if the mapping has the variable
     */
    boolean hasRuntimeVariable(String name);
}
