/**
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2008 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
* https://opensso.dev.java.net/public/CDDLv1.0.html or
* opensso/legal/CDDLv1.0.txt
* 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: FilterModeValueValidator.java,v 1.3 2008/07/03 09:39:14 veiming Exp $
*
*/
package com.sun.identity.common.configuration;
import com.sun.identity.sm.ServiceAttributeValidator;
import java.util.Iterator;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Validates Filter Mode property value in Agent Properties. e.g.
* com.sun.identity.agents.config.filter.mode
* The values in set of properties can be application specific:
* -for example [somecontextroot]=J2EE_POLICY or one of other valid values
* from NONE, SSO_ONLY, URL_POLICY, J2EE_POLICY, ALL
* Can also have *one* global value:
* -where value has no brackets or context root key and is just a value
* NONE, SSO_ONLY, URL_POLICY, J2EE_POLICY, ALL
* -also allow a global value format: "=ALL" or none etc, which includes an
* equal sign since in property file style an entry like
* com.sun.someprop=ALL would have a value "=ALL"
*
* Does not allow []=ALL or none etc.
* Does not allow the characters "[" or "]" inside the brackets since this is
* not a likely valid character in a context root name and it helps us avoid
* the user error of a typo and we use bracket as a special character in parsing.
* Ultimately this regular expression could be stricter since the key inside
* of brackets is a context root of a web app [somecontextroot] and context
* root values only allow certain value, but since agent code and
* other places dont validate for this strictness, this validator should be
* close to as loose as rest of code for consistency.
*
* Overall set of values:
* -Empty set is not allowed since user must specify something.
* -Set can only have *one* global value value of NONE, SSO_ONLY, URL_POLICY,
* J2EE_POLICY, ALL so java code checks for repeats.
* -Duplicates: The validation logic does not check for duplicates in terms of
* the whole value ie [somecontextroot]=ALL being included twice. Since a set
* is used to hold the values, and Set add method only adds the specified
* element to this set if it is not already present so it will not contain any
* duplicates. So no check necessary. The UI may allow a user to enter
* duplicates but ultimately they are ignored and not stored as part of
* agents config.
* Duplicates are exact duplicates, since set does not distinguish between
* letter case of a key, so "Key" is a different key from "key". We dont check
* for duplicates such as this type of possible case.
* However, we do check for exact duplicate context root name within whole
* values, so if user inputs [mycontextroot]=ALL and [mycontextroot]=NONE then
* both values will be in the set, and this code will detect that
* "mycontextroot" is a duplicate so set will be considered invalid.
*/
public class FilterModeValueValidator implements ServiceAttributeValidator {
private static final String globalRegularExpression =
"(\\s*=?\\s*(NONE|SSO_ONLY|URL_POLICY|J2EE_POLICY|ALL)\\s*)";
private static final String appSpecificRegularExpression =
"(\\s*\\[\\s*[\\S&&[^\\[]&&[^\\]]]+\\s*\\]\\s*=\\s*(NONE|SSO_ONLY|URL_POLICY|J2EE_POLICY|ALL)\\s*)";
private static final String regularExpression =
"(" + appSpecificRegularExpression + "|" + globalRegularExpression + ")";
private static final Pattern pattern = Pattern.compile(regularExpression);
private static final Pattern globalPattern =
Pattern.compile(globalRegularExpression);
public FilterModeValueValidator() {
}
/**
* Returns true
if values are of filter mode type.
*
* @param values the set of values to be validated
* @return true
if values are of filter mode type.
*/
public boolean validate(Set values) {
boolean valid = true;
boolean globalFound = false; //can only have zero or one global value
if ((values != null) && !values.isEmpty()) {
for (Iterator i = values.iterator(); (i.hasNext() && valid);) {
String str = (String)i.next();
if (str!=null) {
str = str.trim();
Matcher m = pattern.matcher(str);
valid = m.matches();
//now test for duplicate global value
Matcher globalMatcher = globalPattern.matcher(str);
boolean globalMatch = globalMatcher.matches();
//if value matches global and previously found one too
if (globalFound && globalMatch && valid) {
valid = false; //more than one global value so invalid
} else if (globalMatch && valid) {
globalFound = true; //found first global
}
}
}
} else {
valid = false; //empty set not valid
}
if (valid)
valid = MapDuplicateKeyChecker.checkForNoDuplicateKeyInValue(values);
return valid;
}
}