You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Yunfeng Hou <ho...@yahoo.com> on 2005/12/07 05:43:30 UTC

cached property

I add cached property support to tapestry. A cached
property is actually a method in the form of a getter,
which will return an object could be used by page
components for several times, and worth cache it. For
example, a selection model containing data retrieved
from database, and the selection model could be used
several times in the template and the page class. 
The implementation consists of the following:
1. an EnhancementWorker class - CachePropertyWorker
2. hivemind config
========================
	<service-point id="CachePropertyWorker"
	
interface="org.apache.tapestry.enhance.EnhancementWorker">

		<invoke-factory>
			<construct
			
class="com.newtouch.newtouchone.tapestry.CachePropertyWorker"
/>
		</invoke-factory>
	</service-point>

	<contribution
	
configuration-id="tapestry.enhance.EnhancementWorkers">
		<command id="cache-properties"
			object="service:CachePropertyWorker"
before="tapestry.enhance.abstract-property" />
	</contribution>
================================================

3. page spec definition, an specified property named
_cache will be defined, with its initial value as the
properties need to be cached. For example,
    <property name="_cache"
initial-value="literal:foo,bar" />
which will cache the result of getFoo() and getBar().
Maybe a better solution would be add an special tag,
such as <cache property="foo" />, but the
implementation might be more complex.

Yunfeng Hou



CachePropertyWorker.java
==============================
package com.newtouch.newtouchone.tapestry;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;

import org.apache.hivemind.ErrorLog;
import org.apache.hivemind.Location;
import org.apache.hivemind.service.MethodSignature;
import org.apache.hivemind.util.StringUtils;
import org.apache.tapestry.enhance.EnhanceUtils;
import
org.apache.tapestry.enhance.EnhancementOperation;
import org.apache.tapestry.enhance.EnhancementWorker;
import org.apache.tapestry.event.PageDetachListener;
import
org.apache.tapestry.spec.IComponentSpecification;
import
org.apache.tapestry.spec.IPropertySpecification;

public class CachePropertyWorker implements
EnhancementWorker {

	private static final String LITERAL_PREFIX =
"literal:";

	private static final Class[] NULL_ARGS = new
Class[0];

	private ErrorLog _errorLog;

	private static final String GETTERBODY = "return
_cache.containsKey(\"XXX\")?"
		+ "(TTT) _cache.get(\"XXX\"): "
		+ "(TTT)
com.newtouch.newtouchone.tapestry.CachePropertyWorker"
		+ ".cachedObject(\"XXX\", _cache, super.getXXX());";

	public void performEnhancement(EnhancementOperation
op,
			IComponentSpecification spec) {
		Location location = (Location) spec.getLocation();

		IPropertySpecification propSpec = spec
				.getPropertySpecification("_cache");
		if (propSpec == null)
			return;
		String names = propSpec.getInitialValue();
		if (names == null ||
!names.startsWith(LITERAL_PREFIX))
			return;

		String pageClassName = spec.getComponentClassName();
		Class pageClass = null;
		try {
			pageClass = Class.forName(pageClassName);
		} catch (ClassNotFoundException e) {
			_errorLog.error("page class not found:" +
pageClassName, location,
					e);
			return;
		}

		op.addInjectedField("_cache", java.util.Map.class,
new HashMap());
		// createGetCacheMethod(op, location);

		names = names.substring(LITERAL_PREFIX.length());
		StringTokenizer st = new StringTokenizer(names, ",;
");
		while (st.hasMoreTokens()) {
			String name = st.nextToken();
			String getterName = "get" + name.substring(0,
1).toUpperCase()
					+ name.substring(1);

			try {
				Method getter = pageClass.getMethod(getterName,
NULL_ARGS);
				createProperty(op, getter, location);
			} catch (Exception e) {
				_errorLog.error("getter not found:" + getterName,
location, e);
			}
		}

	}

	private void createProperty(EnhancementOperation op,
Method getter,
			Location location) {

		String name = getter.getName().substring(3);
		String body = StringUtils.replace(GETTERBODY, "XXX",
name);
		body = StringUtils.replace(body, "TTT",
getter.getReturnType()
				.getName());

		op
				.addMethod(Modifier.PUBLIC, new
MethodSignature(getter
						.getReturnType(), getter.getName(), null, null),
body,
						location);
		
	
op.extendMethodImplementation(PageDetachListener.class,
				EnhanceUtils.PAGE_DETACHED_SIGNATURE,
"_cache.clear();");
	}

	public void setErrorLog(ErrorLog errorLog) {
		_errorLog = errorLog;
	}

	public static Object cachedObject(String name, Map
cache, Object obj) {
		cache.put(name, obj);
		return obj;
	}

}


		
__________________________________________ 
Yahoo! DSL � Something to write home about. 
Just $16.99/mo. or less. 
dsl.yahoo.com 

Re: cached property

Posted by Yunfeng Hou <ho...@yahoo.com>.
Yes, good idea. But I am still using java 1.4, and
have no idea to enable annotation. Actually I think
cachable methods should be a solid method rather than
an abstract one.


Yunfeng Hou 


--- "Dmitry I. Zubarovsky"
<dm...@gmail.com> wrote:

> Hello Yunfeng!
> 
> Do not you think its also make sense to annotate
> getter methods,needs
> to be cached, in component class.
> like this:
> 
> @Cached
> public abstract void getFoo()
> 
> Regards,
> Dima
> 
> YH> I add cached property support to tapestry. A
> cached
> YH> property is actually a method in the form of a
> getter,
> YH> which will return an object could be used by
> page
> YH> components for several times, and worth cache
> it. For
> 
> 
> 
>
---------------------------------------------------------------------
> To unsubscribe, e-mail:
> tapestry-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail:
> tapestry-user-help@jakarta.apache.org
> 
> 


__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 

---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org


Re: cached property

Posted by "Dmitry I. Zubarovsky" <dm...@gmail.com>.
Hello Yunfeng!

Do not you think its also make sense to annotate getter methods,needs
to be cached, in component class.
like this:

@Cached
public abstract void getFoo()

Regards,
Dima

YH> I add cached property support to tapestry. A cached
YH> property is actually a method in the form of a getter,
YH> which will return an object could be used by page
YH> components for several times, and worth cache it. For



---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org