/* Copyright 2005-2006 Tim Fennell
*
* 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 net.sourceforge.stripes.controller;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
/**
* Encapsulates the name of a parameter in the HttpServletRequest. Detects whether or
* not the name refers to an indexed or mapped property.
*
* @author Tim Fennell
*/
public class ParameterName implements Comparable<ParameterName> {
/** Stores the regular expression that will remove all [] segments. */
public static final Pattern pattern = Pattern.compile("\\[.*?\\]");
/** Stores the name passed in at construction time. */
private String name;
/** Stores the name with all indexing and mapping stripped out of it. */
private String strippedName;
/** True if the name has indexing or mapping in it. */
private boolean indexed;
/**
* Constructs a ParameterName for a given name from the HttpServletRequest. As it is
* constructed, detects whether or not the name contains indexing or mapping components,
* and if it does, also creates and stores the stripped name.
*
* @param name a name that may or may not contain indexing or mapping
*/
public ParameterName(String name) {
this.name = name;
Matcher matcher = pattern.matcher(this.name);
this.indexed = matcher.find();
if (this.indexed) {
this.strippedName = matcher.replaceAll("");
}
else {
this.strippedName = this.name;
}
}
/** Returns true if the name has indexing or mapping components, otherwise false. */
public boolean isIndexed() {
return this.indexed;
}
/**
* Always returns the parameter name as passed in to the constructor. If it contained
* indexing or mapping components (e.g. [3] or (foo)) they will be present in the
* String returned.
*
* @return String the name as supplied in the request
*/
public String getName() {
return this.name;
}
/**
* Returns the name with all indexing and mapping components stripped. E.g. if the name
* in the request was 'foo[1].bar', this method will return 'foo.bar'.
*
* @return String the name minus indexing and mapping
*/
public String getStrippedName() {
return this.strippedName;
}
/**
* Orders ParameterNames so that those with shorter (unstripped) names come first. Two
* names of the same length are then ordered alphabetically by String.compareTo().
*
* @param that another ParameterName to compare to
* @return -1 if this value sorts first, 0 if the values are identical and +1 if the
* parameter passed in sorts first.
*/
public int compareTo(ParameterName that) {
int result = Integer.valueOf(this.name.length()).compareTo(that.name.length());
if (result == 0) {
result = this.name.compareTo(that.name);
}
return result;
}
/**
* Checks for equality as efficiently as possible. First checks for JVM equality to
* see if we can short circuit, and then checks for equality of the name attribute for
* a real test.
*/
@Override
public boolean equals(Object obj) {
return (obj instanceof ParameterName) &&
(this == obj || compareTo((ParameterName) obj) == 0);
}
/** Simple hashcode method based on the name of the parameter. */
@Override
public int hashCode() {
return this.name.hashCode();
}
/**
* Uses the original name as the string representation of the class. This is probably
* the most useful thing to see in log messages, which is the only place toString will
* be used.
*/
@Override
public String toString() {
return this.name;
}
}