| <?xml version="1.0"?> |
| <!-- |
| 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. |
| --> |
| |
| <!-- |
| XSP event-based cache sample. |
| |
| Cvs $Id$ |
| --> |
| |
| |
| <xsp:page language="java" |
| xmlns:xsp="http://apache.org/xsp" |
| xmlns:esql="http://apache.org/cocoon/SQL/v2" |
| xmlns:xsp-request="http://apache.org/xsp/request/2.0"> |
| |
| <xsp:structure> |
| <xsp:include>org.apache.excalibur.source.SourceValidity</xsp:include> |
| <xsp:include>org.apache.excalibur.source.impl.validity.AggregatedValidity</xsp:include> |
| <xsp:include>org.apache.excalibur.source.impl.validity.TimeStampValidity</xsp:include> |
| <xsp:include>org.apache.cocoon.caching.validity.EventValidity</xsp:include> |
| <xsp:include>org.apache.cocoon.caching.validity.NamedEvent</xsp:include> |
| <xsp:include>java.io.Serializable</xsp:include> |
| </xsp:structure> |
| |
| <xsp:logic> |
| |
| // artificial slowdown to make the effects of the cache visible |
| final int DELAY_SECS = 2; |
| final String DATABASE_TABLE = "user"; |
| |
| /** |
| * Generate the unique key for the cache. |
| * |
| * This key must be unique inside the space of this XSP page, it is used |
| * to find the page contents in the cache (if getValidity says that the |
| * contents are still valid). |
| * |
| * This method will be invoked before the getValidity() method. |
| * |
| * @return The generated key or null if the component |
| * is currently not cacheable. |
| */ |
| public Serializable getKey() |
| { |
| // this page will only render a single view |
| // depending on the database table. Therefore |
| // there is no need to distinguish different |
| // outcomes in the cache. If we were paging |
| // through the result set, those parameters |
| // should be used for the key. |
| return ""; |
| } |
| |
| /** |
| * Generate the validity object, tells the cache how long to |
| * keep contents having this key around. In this case, it will |
| * be until an Event is retrieved matching the NamedEvent created below. |
| * |
| * Before this method can be invoked the getKey() method |
| * will be invoked. |
| * |
| * @return The generated validity object or null if the |
| * component is currently not cacheable. |
| */ |
| public SourceValidity getValidity() { |
| String key = DATABASE_TABLE; |
| // a composite validity is required here since changes to |
| // the source XSP file should invalid the cache as well as |
| // changes to the database table. |
| AggregatedValidity validity = new AggregatedValidity(); |
| // invalidate on external events |
| // multiple events can be added, the cache will be invalidated |
| // when any of those events occur. |
| validity.add(new EventValidity(new NamedEvent(key))); |
| // invalidate on changes to XSP source |
| validity.add(new TimeStampValidity(this.dateCreated)); |
| return validity; |
| } |
| </xsp:logic> |
| |
| |
| <page> |
| <title>Demonstrating Event-Aware Caching or Database Generated Pages.</title> |
| <content> |
| <para> |
| This xsp page is based on (copied from) the event aware cacheable |
| xsp sample. |
| </para> |
| <para> |
| I pause for <xsp:expr>DELAY_SECS</xsp:expr> seconds during generation, so |
| that you can tell if I'm being served from the cache or not. |
| <br/> |
| What you see here was generated on <b><xsp:expr>new java.util.Date()</xsp:expr></b>. |
| </para> |
| |
| <para> |
| I'm cached for a specific database table name: <b><xsp:expr>DATABASE_TABLE</xsp:expr></b>. |
| Other parameters ie. request parameters do not matter. |
| </para> |
| |
| <para> |
| Unlike other cacheable pages in Cocoon, I can be un-cached by events external |
| to Cocoon - for instance, when a database table or row is updated. I will also |
| be invalidated when the XSP source is modified. |
| <br/> |
| My cache entry will be invalidated (actually, removed) when an event named |
| <i><xsp:expr>DATABASE_TABLE</xsp:expr></i> occurs. Go to the |
| <a href="../../databases/mod-db/user-list">database samples</a> and modify, |
| insert, or delete a user and check if this page is updated. |
| </para> |
| |
| <para>Test links: |
| <ul> |
| <li><a href="invalidate?table=user">uncache with action</a></li> |
| <li><a href="jms-invalidate?table=user">uncache with action emitting JMS messages</a><br/> |
| This is particularily useful if your DBMS of choice can easily do HTTP |
| requests but hooking on JMS would be difficult. Still you would like to |
| control several Cocoon caches through JMS. |
| </li> |
| <li><a href="install?what=http">install HTTP database triggers with HSQLDB</a><br/> |
| For the HTTP example triggers, this sample needs to be available at |
| <b>http://localhost:8888/samples/jms/database/eventcache</b> because |
| that location is hard-coded into the trigger. This is usually the case if you |
| have started the provided <i>cocoon.sh</i> resp. <i>cocoon.bat</i>. |
| </li> |
| <li><a href="install?what=jms">install JMS database triggers with HSQLDB</a><br/> |
| For the JMS example triggers, you need to have setup a JMS system, e.g. |
| <a href="http://openjms.sf.net">OpenJMS</a></li> |
| <li><a href="remove">uninstall database triggers</a></li> |
| </ul> |
| </para> |
| |
| <para> |
| <esql:connection> |
| <esql:pool>personnel</esql:pool> |
| <esql:execute-query> |
| <esql:query>select * from user order by name, firstname, uname, uid</esql:query> |
| <esql:results> |
| <table> |
| <tbody> |
| <esql:row-results> |
| <tr> |
| <td><esql:get-string column="uname"/></td> |
| <td><esql:get-string column="firstname"/></td> |
| <td><esql:get-string column="name"/></td> |
| <td><esql:get-string column="uid"/></td> |
| </tr> |
| </esql:row-results> |
| </tbody> |
| </table> |
| </esql:results> |
| </esql:execute-query> |
| </esql:connection> |
| </para> |
| |
| <para> |
| Please refer to the <a href="../../eventcache/">event based cache example</a> for more details |
| on the event based cache invalidation. |
| </para> |
| |
| <xsp:logic> |
| // slowdown page generation. |
| try { |
| Thread.sleep(DELAY_SECS * 1000L); |
| } catch (InterruptedException ie) { |
| // Not much that can be done... |
| } |
| </xsp:logic> |
| </content> |
| </page> |
| </xsp:page> |