PrefixResourceName.java revision 344a0d1046c7f52b7740e3f4a30b383b3215abda
/**
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2009 Sun Microsystems Inc. All Rights Reserved
*
* The contents of this file are subject to the terms
* of the Common Development and Distribution License
* (the License). You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the License at
* See the License for the specific language governing
* permission and limitations under the License.
*
* When distributing Covered Code, include this CDDL
* Header Notice in each file and include the License file
* at opensso/legal/CDDLv1.0.txt.
* If applicable, add the following below the CDDL Header,
* with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* $Id: PrefixResourceName.java,v 1.1 2009/08/19 05:40:33 veiming Exp $
*
* Portions Copyrighted 2011-2014 ForgeRock AS
*/
/**
* This is a plugin impelmentation of the <code>ResourceName</code> interface
* it provides methods to do resource comparisons and resource
* handling based on prefix based string match going left to right.
* This kind of pattern matching would be used by URL kind of resources.
*/
public class PrefixResourceName implements ResourceName {
private boolean caseSensitive = false;
/**
* String indicating default wild card pattern.
*/
protected int wildcardLength = 1;
/**
* String indicating default one level wild card pattern.
*/
protected int oneLevelWildcardLength = 3;
/**
* boolean indicating if the wild card pattern is embedded
* in the one level wild card pattern eg. wildcard is "*"
* while one level wild card pattern is "-*-".
*/
protected boolean wildcardEmbedded = true;
/**
* boolean indicating if the one level wild card pattern is embedded
* in the wild card pattern eg. one level wildcard is "*"
* while wild card pattern is "-*-".
*/
protected boolean oneLevelWildcardEmbedded = false;
//parameter wildcard is no longer required in the entitlement framework
/**
* empty no argument constructor.
*/
public PrefixResourceName() {
// do nothing
}
/**
* Initializes the resource name with configuration information,
* usally set by the administrators. The main configration information
* retrived is mainly like wild card pattern used, one level wild card
* pattern used, case sensitivity etc.
*
* @param configParams configuration parameters as a map.
* The keys of the map are the configuration paramaters.
* Each key is corresponding to one <code>String</code> value
* which specifies the configuration paramater value.
*/
this.delimiter = "/";
this.caseSensitive = false;
this.wildcard = "*";
this.oneLevelWildcard = "-*-";
this.oneLevelWildcardEmbedded =
}
public Set getServiceTypeNames()
{
return null;
}
/**
* Compares two resources.
*
* Description: The targetResource may contain wildcard or
* one level wildcard pattern but not both which
* matches zero or more characters. The wildcard character
* can show up anywhere within the string. The targetResource
* can contain any number of one type of wildcard characters.
* Based on the type of wild card in the resource either
* regular wildcard comparison is done or one level wild card
* comparison is done.
* One of the five possible match types is returned based
* on how the two resource strings are related. The comparison
* starts from the beginning of the reource strings.
*
* ResourceMatch.NO_MATCH means two resources don't match.
* ResourceMatch.EXACT_MATCH means two resources match.
* ResourceMatch.SUB_RESOURCE_MATCH means targetResource is
* the sub resource of the requestResource.
* ResourceMatch.SUPER_RESOURCE_MATCH means targetResource
* is the super resource of the requestResource.
* ResourceMatch.WILDCARD_MATCH means two resources match
* with respect to the wildcard.
*
* @param requestResource name of the resource which will be compared
* @param targetResource name of the resource which will be compared with
* @param wildcardCompare flag for wildcard comparison
*
* @return returns <code>ResourceMatch</code> that
* specifies if the resources are exact match, or
* otherwise.
*/
public ResourceMatch compare(String requestResource, String targetResource, boolean wildcardCompare) {
// if both strings are null, we consider them exact match
return (ResourceMatch.EXACT_MATCH);
}
// if only one of the strings is null, they are not match
return (ResourceMatch.NO_MATCH);
}
/** make them all in lower cases before comapring if we
* want to do case insensitive comparison
*/
if (!caseSensitive) {
}
// end delimiter means we treat this resource as a directory
}
}
// get rid of ending '?*' if any from requestResource
// new entitlement engine no longer evaluates parameter wildcard
}
// get rid of ending '?*' if any from targetResource
// new entitlement engine no longer evaluates parameter wildcard
}
/**
* checks if one level wild card pattern is embedded in wildcard pattern
* and wild card pattern is not in the resource, then implies that
* resource contains only one level wild card and hence call the
* oneLevelWildcardCompare() method.
*/
}
}
/** if wild card is embedded or
* neither of the wild card patterns are embedded in each other,
* different patterns like "abc" and "def".
* Then checks if one level wild card pattern exists in resource
* if yes, call oneLevelWildcardCompare() method.
*/
}
}
int reqLen = 0;
int tarLen = 0;
// non-wildcard comparison
// Compare for equality
return (ResourceMatch.EXACT_MATCH);
}
return (ResourceMatch.SUB_RESOURCE_MATCH);
}
return (ResourceMatch.SUPER_RESOURCE_MATCH);
}
return (ResourceMatch.NO_MATCH);
}
// now we have to do wildcard comparison
// get the sub string prior to the first wildcard char
// checks if the first char in targetResource is the wildcard, i.e.
// the substr is null
// check if requestResource starts with the substr
return (ResourceMatch.SUB_RESOURCE_MATCH);
}
return (ResourceMatch.NO_MATCH);
}
}
// yes, requestResource does start with substr
// move the pointers to the next char after the substring
// which is already matched
return (ResourceMatch.WILDCARD_MATCH);
}
// if there are more wildcards in the targetResource
return (ResourceMatch.SUB_RESOURCE_MATCH);
}
}
return (ResourceMatch.WILDCARD_MATCH);
}
}
// we just pass the last wildcard in targetResource
return (ResourceMatch.SUB_RESOURCE_MATCH);
}
return (ResourceMatch.SUB_RESOURCE_MATCH);
}
return (ResourceMatch.WILDCARD_MATCH);
}
return (ResourceMatch.SUPER_RESOURCE_MATCH);
}
return (ResourceMatch.SUB_RESOURCE_MATCH);
}
/**
* Compares two resources containing one level wild card(s).
*
* Description: The targetResource may contain one level wildcard '-*-'
* ( configurable) which matches zero or more characters, at the same level.
* but not a/b/c/f/d since -*- does not match "c/f". So in other words
* the matching pattern for the one level wildcard cannot go across
* delimiter boundary. The wildcard character can show up anywhere within
* the string. The targetResource can contain any number of wildcard
* characters. One of the five possible match types is returned based
* on how the two resource strings are related. The comparison
* starts from the beginning of the reource strings.
*
* ResourceMatch.NO_MATCH means two resources don't match.
* ResourceMatch.EXACT_MATCH means two resources match.
* ResourceMatch.SUB_RESOURCE_MATCH means targetResource is
* the sub resource of the requestResource.
* ResourceMatch.SUPER_RESOURCE_MATCH means targetResource
* is the super resource of the requestResource.
* ResourceMatch.WILDCARD_MATCH means two resources match
* with respect to the wildcard.
*
* @param requestResource name of the resource which will be compared
* @param targetResource name of the resource which will be compared with
* @param wildcardCompare flag for wildcard comparison
*
* @return returns <code>ResourceMatch</code> that
* specifies if the resources are exact match, or
* otherwise.
*/
boolean wildcardCompare)
{
// requestResource & targetResource are not null,
// have no ending delimiters and if case insensitive
// compare is defined, are already lowercase.
int i = 0;
int j = 0;
while (st1.hasMoreTokens()) {
}
while (st2.hasMoreTokens()) {
}
boolean wildcardMatch = false;
j = 0;
{
if (j < targetTokens.length) {
return matchTokensResult;
}
if (matchTokensResult ==
{
wildcardMatch = true;
}
} else {
if ( i <= requestTokens.length ) {
return ResourceMatch.SUPER_RESOURCE_MATCH;
} else {
return ResourceMatch.NO_MATCH;
}
}
}
// request tokens are over
// check if target tokens still remain
if ( j < targetTokens.length) {
// last token is a wildcard
{
return ResourceMatch.WILDCARD_MATCH;
}
return ResourceMatch.SUB_RESOURCE_MATCH;
}
if (wildcardMatch) {
return ResourceMatch.WILDCARD_MATCH;
}
return ResourceMatch.EXACT_MATCH;
}
/**
* This method is used to reduce mutiple oocurrences of
* one level wildcard immediately following a previous one
* to just one. So "a[*][*][*]b" where one level wild pattern is
* "[*]" reduces to "a[*]b".
*/
int len = 0;
return targetToken;
}
int i = 0;
int j = 0;
int k = 0;
boolean foundWildcard = false;
while (i < len) {
if (!foundWildcard) {
k = i;
while (i < k + oneLevelWildcardLength) {
}
foundWildcard = true;
} else { // ignore the wildcard
i = i + oneLevelWildcardLength;
}
} else {
foundWildcard = false;
}
}
}
/**
* matches individual request and target tokens. This method is
* used to compare tokens in one level wild card compare to compare
* tokens between delimiter boundaries.
*/
{
int wildcardIndex = 0;
return ResourceMatch.EXACT_MATCH;
}
return ResourceMatch.NO_MATCH;
}
int beginTargetIndex = 0;
int beginRequestIndex = 0;
beginTargetIndex)) != -1 ) {
if (wildcardIndex > beginTargetIndex) {
{
return ResourceMatch.NO_MATCH;
}
} else {
if (wildcardIndex == beginTargetIndex) {
// check if only wild card
if (targetTokenLength == oneLevelWildcardLength) {
return ResourceMatch.WILDCARD_MATCH;
} else {// has more string after wild card
// advance over the wildcard and go back to while
continue;
}
}
}
}
//check if wildcard was last in the target string
if (beginTargetIndex >= targetTokenLength) {
return ResourceMatch.WILDCARD_MATCH;
}
// match the target string after last wildcard
// against the remaining request going backwards
// get the remaining request
int remRequestIndex = -1;
{
return ResourceMatch.NO_MATCH;
} else {
// check if we are at the end of request or still
// chars remain
{
return ResourceMatch.WILDCARD_MATCH;
} else { // some non matching chars remain in request
return ResourceMatch.NO_MATCH;
}
}
} else {
return ResourceMatch.EXACT_MATCH;
}
}
return ResourceMatch.NO_MATCH;
}
/**
* Appends sub-resource to super-resource.
*
* @param superResource name of the super-resource to be appended to
* @param subResource name of the sub-resource to be appended
*
* @return returns the combination resource.
*/
// Remove duplicate /
{
}
{
}
return superResource+subResource;
}
/**
* Gets sub-resource from an original resource minus
* a super resource. This is the complementary method of
* append().
*
* @param resource name of the original resource consisting of
* the second parameter superResource and the returned value
* @param superResource name of the super-resource which the first
* parameter begins with.
*
* @return returns the sub-resource which the first paramter
* ends with. If the first parameter doesn't begin with the
* the first parameter, then the return value is null.
*/
}
}
return subResource;
}
/* Splits the given resource name
* @param res the resource name to be split
* @return an array of (String) split resource names
*/
if (doubleD != -1) {
}
int n = st.countTokens();
for (int i=0; i<n; i++) {
}
}
}
return retVal;
}
/**
* This method is used to canonicalize a prefix resource
* It throws an Exception if both regular multi wildcard and
* one level wild card appears is same resource String.
* Also removes ( purges) mutiple consecutive delimiters to 1,
* in the URI.
* <li>So http://xyz.com///abc///d becomes http://xyz.com/abc/d
* where "/" is the delimiter.</li>
*
* @param res the prefix resource string to be canonicalized
* @return the prefix resource string in its canonicalized form.
* @throws PolicyException if resource is invalid
*/
{
boolean errorCondition = false;
boolean oneLevelFound = false;
if (wildcardEmbedded) {
while (startWildcardIndex != -1 &&
{
if (startOneLevelIndex != -1 ) {
if ( startWildcardIndex >=startOneLevelIndex &&
{
oneLevelFound = true;
} else {
errorCondition = true;
break;
}
} else { // wildcard encountered but not one level wildcard
// if previous occurence of one level was found
if (oneLevelFound) {
errorCondition = true;
break;
}
}
endOneLevelIndex +1);
}
}
boolean wildcardFound = false;
if (oneLevelWildcardEmbedded) {
while (startOneLevelIndex != -1 &&
{
if (startWildcardIndex != -1 ) {
&& endWildcardIndex >= endOneLevelIndex)
{
wildcardFound = true;
} else {
errorCondition = true;
break;
}
} else { // one level found, but not wildcard
// if previous occurence of wildcard was found
if (wildcardFound) {
errorCondition = true;
break;
}
}
endOneLevelIndex +1);
}
}
if (!oneLevelWildcardEmbedded && !wildcardEmbedded) {
{
errorCondition = true;
}
}
if (errorCondition) {
//throw new PolicyException(ResBundleUtils.rbName,
//"both_type_wildcards_unsupported", null, null);
throw new EntitlementException(300);
}
if (idx >= 0) {
} else {
return purgeNullPath(res);
}
}
/**
* eliminates the null path (consecutive delimiters) from the resource
*/
return "";
}
boolean preceedingDelimiter = false;
int i = 0;
int j = 0;
while (i < len) {
if (!preceedingDelimiter) {
preceedingDelimiter = true;
} else {
i++;
}
} else {
preceedingDelimiter = false;
}
}
}
}