001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2010–2011 ApexIdentity Inc. 015 * Portions Copyright 2011-2014 ForgeRock AS. 016 */ 017 018package org.forgerock.openig.regex; 019 020import java.util.regex.MatchResult; 021 022/** 023 * Expresses a transformation to be applied to a regular expression pattern match. A template 024 * may contain references to groups captured in the match. Each occurrence of 025 * {@code $}<em>g</em> will be substituted by capture group <em>g</em> in a match result. A 026 * dollar sign or numeral literal immediately following a capture group reference may be 027 * included as a literal in the template by preceding it with a backslash ({@code \}). 028 * Backslash itself must be also escaped in this manner. 029 */ 030public class PatternTemplate { 031 032 /** The transformation template to apply to regular expression pattern matches. */ 033 private final String value; 034 035 /** 036 * Constructs a new template with the specified value. 037 * 038 * @param value the template to apply to regular expression pattern matches. 039 */ 040 public PatternTemplate(final String value) { 041 this.value = value; 042 } 043 044 /** 045 * Performs a transformation of a match result by applying the template. References to 046 * matching groups that are not in the match result resolve to a blank ({@code ""}) value. 047 * 048 * @param result the match result to apply the template to. 049 * @return the value of the matching result with the template applied. 050 */ 051 public String applyTo(final MatchResult result) { 052 int len = value.length(); 053 int groups = result.groupCount(); 054 StringBuilder sb = new StringBuilder(); 055 boolean escaped = false; 056 for (int n = 0; n < len; n++) { 057 char c = value.charAt(n); 058 if (escaped) { 059 sb.append(c); 060 escaped = false; 061 } else if (c == '\\') { 062 escaped = true; 063 } else if (c == '$') { 064 int group = -1; 065 while (n + 1 < len) { 066 int digit = value.charAt(n + 1) - '0'; 067 if (digit < 0 || digit > 9) { 068 break; 069 } 070 // add digit 071 group = (group == -1 ? 0 : group) * 10 + digit; 072 n++; 073 } 074 if (group >= 0 && group <= groups) { 075 sb.append(result.group(group)); 076 } 077 } else { 078 sb.append(c); 079 } 080 } 081 return sb.toString(); 082 } 083 084 /** 085 * Returns the literal template value. 086 * @return the literal template value. 087 */ 088 @Override 089 public String toString() { 090 return value; 091 } 092}