blob: 0cfdc2945de76b1665b108ce9f3ecea9c16c7264 [file] [log] [blame]
/*
* $Id$
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.tiles.request.scope;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import org.apache.tiles.request.Request;
import org.apache.tiles.request.RequestWrapper;
/**
* Resolves scopes and contexts by using reflection.
* To expose a scope, add a <code>get&lt;name_of_the_scope&gt;Scope</code> without parameters
* that returns a <code>Map&lt;String, Object&gt;</code>.
*
* @version $Rev$ $Date$
*/
public final class ReflectionContextResolver{
/**
* Maps a request class to all available scopes.
*/
private Map<Class<? extends Request>, Set<String>> class2scopes =
new HashMap<Class<? extends Request>, Set<String>>();
public Map<String, Object> getContext(Request request, String scope) {
String methodName = "get" + Character.toUpperCase(scope.charAt(0))
+ scope.substring(1) + "Scope";
Method method;
try {
method = request.getClass().getMethod(methodName);
} catch (NoSuchMethodException e) {
if (request instanceof RequestWrapper) {
RequestWrapper wrapper = (RequestWrapper) request;
return getContext(wrapper.getWrappedRequest(), scope);
}
throw new IllegalArgumentException("No accessor method for '" + scope
+ "' scope.", e);
}
try {
return (Map<String, Object>) method.invoke(request);
} catch (IllegalAccessException e) {
// Should not ever happen, since method is public.
throw new IllegalArgumentException("No accessible method for '" + scope
+ "' scope.", e);
} catch (InvocationTargetException e) {
throw new IllegalArgumentException(
"Exception during execution of accessor method for '"
+ scope + "' scope.", e);
}
}
public String[] getAvailableScopes(Request r) {
Request request = r;
Set<String> scopes = new LinkedHashSet<String>();
boolean finished = false;
do {
scopes.addAll(getSpecificScopeSet(request));
if (request instanceof RequestWrapper) {
request = ((RequestWrapper) request).getWrappedRequest();
} else {
finished = true;
}
} while(!finished);
String[] retValue = new String[scopes.size()];
return scopes.toArray(retValue);
}
/**
* Returns the scopes for a single class. To be used in an iteration to get the scopes
* of all the hierarchy of the request.
*
* @param request The request to analyze.
* @return The scope set.
*/
private Set<String> getSpecificScopeSet(Request request) {
Set<String> scopes = class2scopes.get(request.getClass());
if (scopes == null) {
scopes = new LinkedHashSet<String>();
for (String scopeName : request.getNativeScopes()) {
scopes.add(scopeName);
}
class2scopes.put(request.getClass(), scopes);
}
return scopes;
}
}