* @return the base URL, without a query string
* @see #UrlBuilder(Locale, Class, boolean)
* @see #UrlBuilder(Locale, String, boolean)
*/
protected String getBaseURL(String baseUrl, Collection<Parameter> parameters) {
UrlBinding binding = null;
try {
binding = UrlBindingFactory.getInstance().getBindingPrototype(baseUrl);
}
catch (UrlBindingConflictException e) {
// This can be safely ignored
}
if (binding == null || binding.getParameters().size() == 0) {
return baseUrl;
}
// if we have a parameterized binding then we need to trim it down to the path
if (baseUrl.equals(binding.toString())) {
baseUrl = binding.getPath();
}
// if any extra path info is present then do not add URI parameters
if (binding.getPath().length() < baseUrl.length()) {
return baseUrl;
}
// lookup validation info for the bean class to find encrypted properties
Map<String, ValidationMetadata> validations = getValidationMetadata();
// map the declared URI parameter names to values
Map<String, Parameter> map = new HashMap<String, Parameter>();
for (Parameter p : parameters) {
if (!map.containsKey(p.name))
map.put(p.name, p);
}
StringBuilder buf = new StringBuilder(256);
buf.append(baseUrl);
String nextLiteral = null;
for (Object component : binding.getComponents()) {
if (component instanceof String) {
nextLiteral = (String) component;
}
else if (component instanceof UrlBindingParameter) {
boolean ok = false;
// get the value for the parameter, falling back to default value if present
UrlBindingParameter parameter = (UrlBindingParameter) component;
Parameter assigned = map.get(parameter.getName());
Object value;
if (assigned != null && (assigned.value != null || assigned.isEvent()))
value = assigned.value;
else
value = parameter.getDefaultValue();
if (value != null) {
// format (and maybe encrypt) the value as a string
String formatted = format(value);
ValidationMetadata validation = validations.get(parameter.getName());
if (validation != null && validation.encrypted())
formatted = CryptoUtil.encrypt(formatted);
// if after formatting we still have a value then embed it in the URI
if (formatted != null && formatted.length() > 0) {
if (nextLiteral != null) {
buf.append(nextLiteral);
}
buf.append(StringUtil.urlEncode(formatted));
parameters.remove(assigned);
ok = true;
}
}
else if (assigned != null && assigned.isEvent()) {
// remove event parameter even if value is null
parameters.remove(assigned);
}
nextLiteral = null;
if (!ok)
break;
}
}
// always append trailing literal if one is present
if (nextLiteral != null) {
buf.append(nextLiteral);
}
else if (binding.getSuffix() != null) {
buf.append(binding.getSuffix());
}
// Test the URL to make sure it won't throw an exception when Stripes tries to dispatch it
String url = buf.toString();
try {
StripesFilter.getConfiguration().getActionResolver().getActionBeanType(url);
}
catch (UrlBindingConflictException e) {
if (binding != null) {
UrlBindingConflictException tmp = new UrlBindingConflictException(binding
.getBeanType(), e.getPath(), e.getMatches());
tmp.setStackTrace(e.getStackTrace());
e = tmp;
}
throw e;