/* * Copyright (C) 2014 Civilian Framework. * * Licensed under the Civilian License (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.civilian-framework.org/license.txt * * 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.civilian.resource; import java.util.regex.Pattern; import org.civilian.type.DateType; import org.civilian.type.Type; import org.civilian.type.TypeLib; import org.civilian.internal.pathparam.MultiSegmentPathParam; import org.civilian.internal.pathparam.RegexPathParam; import org.civilian.internal.pathparam.SegmentPathParam; import org.civilian.internal.pathparam.SegmentWcPathParam; import org.civilian.internal.pathparam.YMDPathParam; /** * PathParams contains factory methods for PathParam objects. * The following table shows which paths the different patterns match and what * path parameter values are extracted from the path: * <table> * <tr> * <th>Pattern</th> * <th>Accepted path or segment</th> * <th>Extracted path parameter</th> * </tr> * <tr> * <td>{@link #forSegment(String)}</td> * <td>/abc</td> * <td>String "abc"</td> * </tr> * <tr> * <td>{@link #forIntSegment(String)}</td> * <td>/123</td> * <td>Integer 123</td> * </tr> * <tr> * <td>{@link #forDateSegment(String, DateType) PathParams.forDateSegment(TypeLibrary.DATE_CIVILIAN)}</td> * <td>/20130131</td> * <td>Date year=2013, month=01, day=31</td> * </tr> * <tr> * <td>{@link #forSegment(String, Type) PathParams.forSegment(TypeLibrary.DOUBLE)}</td> * <td>/1.23</td> * <td>Double 1.23</td> * </tr> * <tr> * <td>{@link #forSegmentPattern(String, String) PathParams.forSegment(TypeLibrary.INTEGER, "id*")}</td> * <td>/id567</td> * <td>Integer 567</td> * </tr> * <tr> * <td>{@link #forYearMonthDay(String, DateType)}</td> * <td>/2013/01/31</td> * <td>Date year=2013, month=01, day=31</td> * </tr> * </table> */ public abstract class PathParams { /** * Creates a PathParam which matches a path segment. The associated * path parameter value is the path segment. * @param name the name of the path parameter */ public static PathParam<String> forSegment(String name) { return forSegment(name, TypeLib.STRING); } /** * Creates a PathParam which matches a path segment. The associated * path parameter value is the path segment, converted into an integer. * @param name the name of the path parameter */ public static PathParam<Integer> forIntSegment(String name) { return forSegment(name, TypeLib.INTEGER); } /** * Creates a PathParam which matches a path segment. The associated * path parameter value is the path segment, converted into a date object. * The formatting scheme is "yyyyMMdd". * @param name the name of the path parameter */ public static <T> PathParam<T> forDateSegment(String name, DateType<T> dateType) { return forSegment(name, dateType); } /** * Creates a PathParam which matches a path segment. The associated * path parameter value is the path segment, converted into a object * of the given type. * @param name the name of the path parameter */ public static <T> PathParam<T> forSegment(String name, Type<T> type) { return new SegmentPathParam<>(name, type); } /** * Creates a PathParam which matches a path segment. The associated * path parameter value is the part of the segment which is matched by the * wildcard '*' inside the segmentPattern, converted into an object * of the given type. * @param name the name of the path parameter * @param segmentPattern a string containing exactly one wildcard '*' character * and no '/' characters. */ public static PathParam<String> forSegmentPattern(String name, String segmentPattern) { return new SegmentWcPathParam(name, segmentPattern); } /** * Creates a PathParam which uses a regex pattern to match a path segment. * Example: to match segments * @param name the name of the path parameter * @param matchPattern a regex pattern for the segment. The pattern must have a single * match group and should not match any slashes. * Example: Pattern.compile("id([^/]+)" to match segments of the form "id*" * @param buildPattern equals the matchPattern, whose match group is replaced by a '*' */ public static PathParam<String> forPattern(String name, Pattern matchPattern, String buildPattern) { return forPattern(name, matchPattern, buildPattern, TypeLib.STRING); } /** * Creates a PathParam which uses a regex pattern to match a path segment. * Example: to match segments * @param name the name of the path parameter * @param matchPattern a regex pattern for the segment. The pattern must have a single * match group and should not match any slashes. * Example: Pattern.compile("id([^/]+)" to match segments of the form "id*" * @param buildPattern equals the matchPattern, whose match group is replaced by a '*' * @param type a type for the path param values */ public static <T> PathParam<T> forPattern(String name, Pattern matchPattern, String buildPattern, Type<T> type) { return new RegexPathParam<>(name, type, matchPattern, buildPattern); } /** * Creates a PathParam which matches three segments, encoding a date value: * The segments have the form yyyy/mm/dd, i.e. a 4 digit year, a 2 digit month (from 01 to 12) * and a 2 digit day of month (01-31). * @param name the name of the path parameter */ public static <T> PathParam<T> forYearMonthDay(String name, DateType<T> type) { return new YMDPathParam<>(name, type); } /** * Creates a PathParam which matches multiple segment. The associated * path parameter value are the matched segments as string array. * Since this path parameter has variable size, it only makes sense to * use it at the end of a path. * @param name the name of the path parameter * @param minSize the minimum number of segments which must be present on * the path. */ public static PathParam<String[]> forMultiSegments(String name, int minSize) { return new MultiSegmentPathParam(name, minSize); } }