You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@velocity.apache.org by ge...@locus.apache.org on 2000/12/31 00:46:22 UTC
cvs commit: jakarta-velocity/whiteboard/geir_context_20001228 InternalContextAdapter.java Template.java AbstractContext.java Context.java DBContext.java HashMapContext.java InternalContext.java InternalContextBase.java README.txt TreeMapContext.java VelocityContext.java velocity-0.71.jar
geirm 00/12/30 15:46:20
Modified: whiteboard/geir_context_20001228 AbstractContext.java
Context.java DBContext.java HashMapContext.java
InternalContext.java InternalContextBase.java
README.txt TreeMapContext.java VelocityContext.java
velocity-0.71.jar
Added: whiteboard/geir_context_20001228 InternalContextAdapter.java
Template.java
Log:
Another update to decouple the internal context from app level context in
a safe and secure way. Now the two are separate. All caching functionality
is still supported across context uses if so desired. See notes.
Revision Changes Path
1.4 +3 -3 jakarta-velocity/whiteboard/geir_context_20001228/AbstractContext.java
Index: AbstractContext.java
===================================================================
RCS file: /home/cvs/jakarta-velocity/whiteboard/geir_context_20001228/AbstractContext.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- AbstractContext.java 2000/12/30 14:42:00 1.3
+++ AbstractContext.java 2000/12/30 23:46:18 1.4
@@ -1,4 +1,4 @@
-package org.apache.velocity;
+package org.apache.velocity.context;
/*
* The Apache Software License, Version 1.1
@@ -62,7 +62,7 @@
import java.util.Enumeration;
import org.apache.velocity.util.ArrayIterator;
-import org.apache.velocity.InternalContextBase;
+import org.apache.velocity.context.InternalContextBase;
/**
* This class is the abstract base class for all Velocity Context
@@ -70,10 +70,10 @@
* abstract routines that access your preferred storage method.
*
* @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
- * @version $Id: AbstractContext.java,v 1.3 2000/12/30 14:42:00 geirm Exp $
+ * @version $Id: AbstractContext.java,v 1.4 2000/12/30 23:46:18 geirm Exp $
*/
-public abstract class AbstractContext extends InternalContextBase implements Context, InternalContext, Serializable
+public abstract class AbstractContext extends InternalContextBase implements Context, Serializable
{
/**
* we handle the context wrapping
1.3 +1 -2 jakarta-velocity/whiteboard/geir_context_20001228/Context.java
Index: Context.java
===================================================================
RCS file: /home/cvs/jakarta-velocity/whiteboard/geir_context_20001228/Context.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- Context.java 2000/12/30 14:42:00 1.2
+++ Context.java 2000/12/30 23:46:18 1.3
@@ -1,4 +1,4 @@
-package org.apache.velocity;
+package org.apache.velocity.context;
/*
* The Apache Software License, Version 1.1
@@ -58,7 +58,6 @@
import java.io.Serializable;
import org.apache.velocity.util.ArrayIterator;
-import org.apache.velocity.InternalContext;
/**
* This class provides the storage location for all dynamic
@@ -69,7 +68,7 @@
* are stored in a Hashtable.
* @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
* @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
- * @version $Id: Context.java,v 1.2 2000/12/30 14:42:00 geirm Exp $
+ * @version $Id: Context.java,v 1.3 2000/12/30 23:46:18 geirm Exp $
*/
public interface Context
{
1.2 +3 -0 jakarta-velocity/whiteboard/geir_context_20001228/DBContext.java
Index: DBContext.java
===================================================================
RCS file: /home/cvs/jakarta-velocity/whiteboard/geir_context_20001228/DBContext.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- DBContext.java 2000/12/29 23:09:00 1.1
+++ DBContext.java 2000/12/30 23:46:18 1.2
@@ -4,6 +4,9 @@
import java.io.Serializable;
import java.io.*;
+import org.apache.velocity.context.AbstractContext;
+import org.apache.velocity.context.Context;
+
/**
* Example context impl that uses a database to store stuff :)
*
@@ -19,7 +22,7 @@
* very fragile, crappy code.... just a demo!
*
* @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
- * @version $Id: DBContext.java,v 1.1 2000/12/29 23:09:00 geirm Exp $
+ * @version $Id: DBContext.java,v 1.2 2000/12/30 23:46:18 geirm Exp $
*/
public class DBContext extends AbstractContext
1.2 +2 -0 jakarta-velocity/whiteboard/geir_context_20001228/HashMapContext.java
Index: HashMapContext.java
===================================================================
RCS file: /home/cvs/jakarta-velocity/whiteboard/geir_context_20001228/HashMapContext.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- HashMapContext.java 2000/12/29 19:21:28 1.1
+++ HashMapContext.java 2000/12/30 23:46:18 1.2
@@ -56,12 +56,14 @@
import java.util.HashMap;
import java.io.Serializable;
+import org.apache.velocity.context.AbstractContext;
+import org.apache.velocity.context.Context;
/**
* Example context impl that uses a HashMap
*
* @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
- * @version $Id: HashMapContext.java,v 1.1 2000/12/29 19:21:28 geirm Exp $
+ * @version $Id: HashMapContext.java,v 1.2 2000/12/30 23:46:18 geirm Exp $
*/
public class HashMapContext extends AbstractContext
1.2 +5 -5 jakarta-velocity/whiteboard/geir_context_20001228/InternalContext.java
Index: InternalContext.java
===================================================================
RCS file: /home/cvs/jakarta-velocity/whiteboard/geir_context_20001228/InternalContext.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- InternalContext.java 2000/12/30 14:42:00 1.1
+++ InternalContext.java 2000/12/30 23:46:18 1.2
@@ -1,4 +1,4 @@
-package org.apache.velocity;
+package org.apache.velocity.context;
/*
* The Apache Software License, Version 1.1
@@ -68,7 +68,7 @@
* support, as well as node-local context data introspection caching.
*
* @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
- * @version $Id: InternalContext.java,v 1.1 2000/12/30 14:42:00 geirm Exp $
+ * @version $Id: InternalContext.java,v 1.2 2000/12/30 23:46:18 geirm Exp $
*/
public interface InternalContext
{
@@ -77,14 +77,14 @@
*
* @param s current template name to set
*/
- public void setCurrentTemplateName( String s );
+ void setCurrentTemplateName( String s );
/**
* get the current template name
*
* @return String current template name
*/
- public String getCurrentTemplateName();
+ String getCurrentTemplateName();
/**
* returns an IntrospectionCache Data (@see IntrospectionCacheData)
@@ -93,7 +93,7 @@
* @param key key to find in cache
* @return cache object
*/
- public IntrospectionCacheData icacheGet( Object key );
+ IntrospectionCacheData icacheGet( Object key );
/**
* places an IntrospectionCache Data (@see IntrospectionCacheData)
@@ -102,5 +102,5 @@
* @param key key
* @param o IntrospectionCacheData object to place in cache
*/
- public void icachePut( Object key, IntrospectionCacheData o );
+ void icachePut( Object key, IntrospectionCacheData o );
}
1.2 +6 -6 jakarta-velocity/whiteboard/geir_context_20001228/InternalContextBase.java
Index: InternalContextBase.java
===================================================================
RCS file: /home/cvs/jakarta-velocity/whiteboard/geir_context_20001228/InternalContextBase.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- InternalContextBase.java 2000/12/30 14:42:00 1.1
+++ InternalContextBase.java 2000/12/30 23:46:18 1.2
@@ -1,4 +1,4 @@
-package org.apache.velocity;
+package org.apache.velocity.context;
/*
* The Apache Software License, Version 1.1
@@ -68,9 +68,9 @@
* support, as well as node-local context data introspection caching.
*
* @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
- * @version $Id: InternalContextBase.java,v 1.1 2000/12/30 14:42:00 geirm Exp $
+ * @version $Id: InternalContextBase.java,v 1.2 2000/12/30 23:46:18 geirm Exp $
*/
-public class InternalContextBase implements InternalContext, Serializable
+public class InternalContextBase implements Serializable
{
/**
* cache for node/context specific introspection information
@@ -87,7 +87,7 @@
*
* @param s current template name to set
*/
- public void setCurrentTemplateName( String s )
+ protected void setCurrentTemplateName( String s )
{
strCurrentTemplate = s;
return;
@@ -98,7 +98,7 @@
*
* @return String current template name
*/
- public String getCurrentTemplateName()
+ protected String getCurrentTemplateName()
{
return strCurrentTemplate;
}
@@ -110,7 +110,7 @@
* @param key key to find in cache
* @return cache object
*/
- public IntrospectionCacheData icacheGet( Object key )
+ protected IntrospectionCacheData icacheGet( Object key )
{
return ( IntrospectionCacheData ) introspectionCache.get( key );
}
@@ -122,7 +122,7 @@
* @param key key
* @param o IntrospectionCacheData object to place in cache
*/
- public void icachePut( Object key, IntrospectionCacheData o )
+ protected void icachePut( Object key, IntrospectionCacheData o )
{
introspectionCache.put( key, o );
}
1.3 +61 -5 jakarta-velocity/whiteboard/geir_context_20001228/README.txt
Index: README.txt
===================================================================
RCS file: /home/cvs/jakarta-velocity/whiteboard/geir_context_20001228/README.txt,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- README.txt 2000/12/30 14:42:00 1.2
+++ README.txt 2000/12/30 23:46:18 1.3
@@ -1,8 +1,21 @@
Here is my impl of all the context stuff we have been
talking about for a while.
+New approach :
+
+The code now reflects a new approach to dealing with the whole context issue.
+The big issue was that we have an internal 'context' that is used for a few
+purposes (and more in the future), and the first rev or so of this code showed
+that. This latest rev hides completely the internal context, allows us to add
+more kinds of 'stuff' to the internal context in the future. It places no
+requirements upon users, and app level code is unable to access the internal context
+methods.
+
+The big difference is that Context is now in it's own package. VelocityContext is
+still at org.apache.velocity level, but all the guts are safe in their own package.
+
Note that this code won't drop in and run as it requires
-small non-functional mods to a few AST nodes to decouple
+lots of non-functional mods to a few AST nodes to decouple
the internal context stuff from the app-level context stuff,
which is a Good Thing. There are also changes to
everything from VelocityServlet to Anakia to Texen etc to
@@ -32,18 +45,57 @@
Included
---------
-Context.java : basic interface defintion. It looks exactly like
-the current Context, for the most part, except that put optionally
+
+Context.java : interface defintion for app-level data context. This is
+what the application writer thinks of the context to be. The app
+writer has several choices for using this :
+
+1) Use the provided VelocityContext() implementation, providing the current
+facilities of the current Context class. It looks exactly like
+the current Context, for the most part, except that put() optionally
returns the Object it replaces.
+2) Create their own class to use as a context by extending AbstractContext.
+This would automatically support context chaining/wrapping, tool support if
+we decide to do that, and fully caches node-specific cache info across merges.
+This would be the most efficient and easy way to make a Context-compatible
+object. It could be stored in a servlet session and reused with any applicable
+cache information preserved. The included HashMapContext, TreeMapContext,
+and DBContext are examples of how this is done.
+
+3) Create their own class to use as a context by simply implementing the
+Context interface. They would be responsible for supporting chaining if desired.
+This seems to be more appropriate for specialized applications, frameworks,
+whatever. The disadvange to this is that node-specific cache info is lost
+after use. This is fine for codeing patterns where the context is created, used
+and destroyed. (Our current VelocityServlet does this...)
+
AbstractContext.java : abstract class for a usable app-level Context.
Handles the wrapping/chaining support as well as interfacing with the
-maybe upcoming 'toolsmith', the global context tool manager/dispenser.
+possibly upcoming tool management. To make a usable Context object, a user
+could simply subclass this and implement the storage mechanism and the 5 required
+methods.
VelocityContext.java : replaces the current Context.java implementation.
This is a working hashtable-based concrete implementation of
AbstractContext.java. You would use it wherever you use Context now.
-(and indeed, it is used in the included jar)
+(and indeed, it is used in the included jar). The name isn't important...
+we can also change to hashmap or whatever. The point is to have a default
+concrete context for people to use easily.
+
+InternalContextBase.java : internal cache object, used for node-specific caching of
+introspection information, carrying temlpate names, etc. Will need to extend
+or add another in the future, I bet. The functionality is inaccessable to any
+app-layer code.
+
+InternalContextAdapter.java : used by Template to carry all context and internalContext
+information down into the AST. Decouples the app-level context from the 'context'
+expected by the AST internals. Further, provides the InternalContext support for
+app-level Contexts that don't subclass from AbstractContext, so performance is
+preserved. And further, we can add more kinds of information to be carried into
+the AST free of app-level code changes. Used by Template.java as well as all AST nodes.
+Fundamentally, all AST nodes would no longer care about the 'Context' interface, but expect
+InternalContextAdapter to support it.
HashMapContext.java : example of creating another kind of Context, it uses
a HashMap for storage.
@@ -72,6 +124,10 @@
be completely hidden from app level if possible - needed to remove
the getInternalContext() accessor method from the Context interface and
the AbstractContext abstract base class. So that's done.
+
+12/30/00 pm
+-----------
+not done enough.... See above notes and new code if you care...
geir
1.2 +2 -0 jakarta-velocity/whiteboard/geir_context_20001228/TreeMapContext.java
Index: TreeMapContext.java
===================================================================
RCS file: /home/cvs/jakarta-velocity/whiteboard/geir_context_20001228/TreeMapContext.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- TreeMapContext.java 2000/12/29 19:21:28 1.1
+++ TreeMapContext.java 2000/12/30 23:46:19 1.2
@@ -56,12 +56,14 @@
import java.util.TreeMap;
import java.io.Serializable;
+import org.apache.velocity.context.AbstractContext;
+import org.apache.velocity.context.Context;
/**
* Example context impl that uses a HashMap
*
* @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
- * @version $Id: TreeMapContext.java,v 1.1 2000/12/29 19:21:28 geirm Exp $
+ * @version $Id: TreeMapContext.java,v 1.2 2000/12/30 23:46:19 geirm Exp $
*/
public class TreeMapContext extends AbstractContext
1.2 +4 -1 jakarta-velocity/whiteboard/geir_context_20001228/VelocityContext.java
Index: VelocityContext.java
===================================================================
RCS file: /home/cvs/jakarta-velocity/whiteboard/geir_context_20001228/VelocityContext.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- VelocityContext.java 2000/12/29 19:21:28 1.1
+++ VelocityContext.java 2000/12/30 23:46:19 1.2
@@ -58,11 +58,14 @@
import java.util.Properties;
import java.io.Serializable;
+import org.apache.velocity.context.AbstractContext;
+import org.apache.velocity.context.Context;
+
/**
* Default basic implementation of a Context object
*
* @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
- * @version $Id: VelocityContext.java,v 1.1 2000/12/29 19:21:28 geirm Exp $
+ * @version $Id: VelocityContext.java,v 1.2 2000/12/30 23:46:19 geirm Exp $
*/
public class VelocityContext extends AbstractContext implements Cloneable
@@ -78,7 +81,7 @@
{
super( inner );
}
-
+
public Object internalGet( String key )
{
return context.get( key );
1.4 +483 -490 jakarta-velocity/whiteboard/geir_context_20001228/velocity-0.71.jar
<<Binary file>>
1.1 jakarta-velocity/whiteboard/geir_context_20001228/InternalContextAdapter.java
Index: InternalContextAdapter.java
===================================================================
package org.apache.velocity.context;
import org.apache.velocity.util.introspection.IntrospectionCacheData;
public final class InternalContextAdapter implements Context
{
Context context = null;
InternalContextBase icb = null;
public InternalContextAdapter( Context c )
{
context = c;
if ( !( c instanceof InternalContextBase ))
{
System.out.println("Woog!");
icb = new InternalContextBase();
}
else
icb = (InternalContextBase) context;
}
public void setCurrentTemplateName( String s )
{
icb.setCurrentTemplateName( s );
}
public String getCurrentTemplateName()
{
return icb.getCurrentTemplateName();
}
public IntrospectionCacheData icacheGet( Object key )
{
return icb.icacheGet( key );
}
public void icachePut( Object key, IntrospectionCacheData o )
{
icb.icachePut( key, o );
}
/** ----------------- */
public Object put(String key, Object value)
{
return context.put( key , value );
}
public Object get(String key)
{
return context.get( key );
}
public boolean containsKey(Object key)
{
return context.containsKey( key );
}
public Object[] getKeys()
{
return context.getKeys();
}
public Object remove(Object key)
{
return context.remove( key );
}
}
1.1 jakarta-velocity/whiteboard/geir_context_20001228/Template.java
Index: Template.java
===================================================================
package org.apache.velocity;
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Velocity", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
import java.io.InputStream;
import java.io.IOException;
import java.io.Writer;
import org.apache.velocity.runtime.Runtime;
import org.apache.velocity.runtime.resource.Resource;
import org.apache.velocity.runtime.parser.ParseException;
import org.apache.velocity.runtime.parser.node.SimpleNode;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.context.Context;
import org.apache.velocity.context.InternalContext;
import org.apache.velocity.context.InternalContextAdapter;
/**
* This class is used for controlling all template
* operations. This class uses a parser created
* by JavaCC to create an AST that is subsequently
* traversed by a ProcessVisitor. This class is in
* the process of changing over to use the
* InjectorVistor, this is part of the planned
* caching mechanism.
*
* <pre>
* Template template = Runtime.getTemplate("test.wm");
* Context context = new Context();
*
* context.put("foo", "bar");
* context.put("customer", new Customer());
*
* template.merge(context, writer);
* </pre>
*
* @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
* @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
* @version $Id: Template.java,v 1.1 2000/12/30 23:46:19 geirm Exp $
*/
public class Template extends Resource
{
/**
* To keep track of whether this template has been
* initialized. We use the document.init(context)
* to perform this. The AST walks itself optimizing
* nodes creating objects that can be reused during
* rendering. For example all reflection metadata
* is stored in ASTReference nodes, the Method objects
* are determine in the init() phase and reused
* during rendering.
*/
private boolean initialized = false;
/** Default constructor */
public Template()
{
}
public boolean process()
{
try
{
InputStream is = resourceLoader.getResourceStream(name);
if (is != null)
{
data = Runtime.parse(is, name);
initDocument();
return true;
}
else
return false;
}
catch (Exception e)
{
return false;
}
}
/**
* initializes the document. init() is not longer
* dependant upon context, but we need to let the
* init() carry the template name down throught for VM
* namespace features
*/
public void initDocument() throws Exception
{
VelocityContext c = new VelocityContext();
InternalContextAdapter ica = new InternalContextAdapter( c );
ica.setCurrentTemplateName( name );
((SimpleNode)data).init( ica, null);
}
/**
* The AST node structure is merged with the
* context to produce the final output. We
* also init() the AST node structure if
* it hasn't been already. It might actually
* be better to move the init() phase up into
* the parse(), but it would require the passing
* in of the context. The context is required to
* determine the objects being used by reflection.
*/
public void merge( Context context, Writer writer)
throws IOException, Exception
{
if( data != null)
{
InternalContextAdapter ica = new InternalContextAdapter( context );
ica.setCurrentTemplateName( name );
((SimpleNode)data).render( ica, writer);
}
else
Runtime.error("Template.merge() failure. The document is null, " +
"most likely due to parsing error.");
}
}