package org.apache.velocity.tools.generic; | |
/* | |
* 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. | |
*/ | |
import java.io.Serializable; | |
import java.util.Arrays; | |
import java.util.HashSet; | |
import java.util.Iterator; | |
import java.util.Map; | |
import java.util.Set; | |
import org.apache.velocity.context.AbstractContext; | |
import org.apache.velocity.context.Context; | |
import org.apache.velocity.tools.Scope; | |
import org.apache.velocity.tools.ToolContext; | |
import org.apache.velocity.tools.config.DefaultKey; | |
import org.apache.velocity.tools.config.InvalidScope; | |
import org.apache.velocity.tools.generic.ValueParser; | |
/** | |
* <p>Tool for convenient access to {@link Context} data and | |
* meta-data.</p> | |
* <p>Template example(s):</p> | |
* <pre> | |
* #foreach( $key in $context.keys ) | |
* $key = $context.get($key) | |
* #end | |
* | |
* Toolbox configuration: | |
* <tools> | |
* <toolbox scope="request"> | |
* <tool class="org.apache.velocity.tools.generic.ContextTool"/> | |
* </toolbox> | |
* </tools> | |
* </pre> | |
* | |
* <p>This class is only designed for use as a request-scope tool.</p> | |
* | |
* @author Nathan Bubna | |
* @since VelocityTools 2.0 | |
* @version $Id: ContextTool.java 385122 2006-03-11 18:37:42Z nbubna $ | |
*/ | |
@DefaultKey("context") | |
@InvalidScope({Scope.APPLICATION,Scope.SESSION}) | |
public class ContextTool extends SafeConfig implements Serializable | |
{ | |
private static final long serialVersionUID = 2214413657621101511L; | |
protected Context context; | |
protected Map<String,Object> toolbox; | |
/** | |
* Initializes this instance for the current request. | |
* Also looks for a safe-mode configuration setting. By default, | |
* safeMode is true and thus keys with '.' in them are hidden. | |
*/ | |
protected void configure(ValueParser parser) | |
{ | |
this.context = (Context)parser.getValue(ToolContext.CONTEXT_KEY); | |
} | |
/** | |
* Returns the context being analyzed by this tool. | |
* @return analyzed context | |
*/ | |
public Context getThis() | |
{ | |
return this.context; | |
} | |
/** | |
* <p>Returns a read-only view of the toolbox {@link Map} | |
* for this context.</p> | |
* @return a map of all available tools for this request | |
* or {@code null} if such a map is not available | |
*/ | |
public Map<String,Object> getToolbox() | |
{ | |
if (this.toolbox == null && this.context instanceof ToolContext) | |
{ | |
this.toolbox = ((ToolContext)context).getToolbox(); | |
} | |
return this.toolbox; | |
} | |
/** | |
* <p>Return a {@link Set} of the available reference keys in the current | |
* context.</p> | |
* @return keys set | |
*/ | |
public Set getKeys() | |
{ | |
Set keys = new HashSet(); | |
// fill the keyset in extendable method | |
fillKeyset(keys); | |
// if we're in safe mode, remove keys that contain '.' | |
if (isSafeMode()) | |
{ | |
for (Iterator i = keys.iterator(); i.hasNext(); ) | |
{ | |
String key = String.valueOf(i.next()); | |
if (key.indexOf('.') >= 0) | |
{ | |
i.remove(); | |
} | |
} | |
} | |
// return the key set | |
return keys; | |
} | |
/** | |
* Actually do the work of filling in the set of keys | |
* for {@link #getKeys} here so subclasses can add keys too. | |
* @param keys set to fill with keys | |
*/ | |
protected void fillKeyset(Set keys) | |
{ | |
//NOTE: we don't need to manually add the toolbox keys here | |
// because retrieval of those depends on the context being | |
// a ToolContext which would already give tool keys below | |
// recurse down the velocity context collecting keys | |
Context velctx = this.context; | |
while (velctx != null) | |
{ | |
Object[] ctxKeys = velctx.getKeys(); | |
keys.addAll(Arrays.asList(ctxKeys)); | |
if (velctx instanceof AbstractContext) | |
{ | |
velctx = ((AbstractContext)velctx).getChainedContext(); | |
} | |
else | |
{ | |
velctx = null; | |
} | |
} | |
} | |
/** | |
* <p>Return a {@link Set} of the available values in the current | |
* context.</p> | |
* @return values set | |
*/ | |
public Set getValues() | |
{ | |
//TODO: this could be a lot more efficient | |
Set keys = getKeys(); | |
Set values = new HashSet(keys.size()); | |
for (Iterator i = keys.iterator(); i.hasNext(); ) | |
{ | |
String key = String.valueOf(i.next()); | |
values.add(this.context.get(key)); | |
} | |
return values; | |
} | |
/** | |
* <p>Returns {@code true} if the context contains a value for the specified | |
* reference name (aka context key).</p> | |
* @param refName context key | |
* @return <code>true</code> if key is present in the context | |
*/ | |
public boolean contains(Object refName) | |
{ | |
return (get(refName) != null); | |
} | |
/** | |
* Retrieves the value for the specified reference name (aka context key). | |
* @param refName context key | |
* @return found value, or null | |
*/ | |
public Object get(Object refName) | |
{ | |
String key = String.valueOf(refName); | |
if (isSafeMode() && key.indexOf('.') >= 0) | |
{ | |
return null; | |
} | |
return this.context.get(key); | |
} | |
} |