Author: taylor
Date: Thu Jun 21 17:39:22 2007
New Revision: 549652
URL: http://svn.apache.org/viewvc?view=rev&rev=549652
Log:
https://issues.apache.org/jira/browse/PB-70
contribution from Woonsan Ko
In summary, the followings are expected:
- One can add a portlet preferences validator class into the portlet.xml. The
class is a wrapper class for groovy script.
- The wrapper class reads (read-only) preferences to find the script file and
auto-refresh mode.
- When auto-refresh mode is true, the modification of the validator script
should be applied instantly.
- Also, one can write a groovy portlet to support pre-286 header phase.
Currently Jetspeed-2 API provides this interface. So the script developer
implements SupportsHeaderPhase interface of Jetspeed-2 to provide header phase.
- In such case, the developer can set the portlet-class to another wrapper
class.
Added:
portals/bridges/trunk/groovy/src/java/org/apache/portals/bridges/groovy/GroovyPortletHeaderPhaseSupport.java
portals/bridges/trunk/groovy/src/java/org/apache/portals/bridges/groovy/GroovyPreferencesValidator.java
portals/bridges/trunk/groovy/xdocs/headersupport.xml
portals/bridges/trunk/groovy/xdocs/prefvalidate.xml
Modified:
portals/bridges/trunk/.classpath
portals/bridges/trunk/groovy/pom.xml
portals/bridges/trunk/groovy/project.xml
portals/bridges/trunk/groovy/xdocs/index.xml
portals/bridges/trunk/groovy/xdocs/navigation.xml
portals/bridges/trunk/project.properties
Modified: portals/bridges/trunk/.classpath
URL:
http://svn.apache.org/viewvc/portals/bridges/trunk/.classpath?view=diff&rev=549652&r1=549651&r2=549652
==============================================================================
--- portals/bridges/trunk/.classpath (original)
+++ portals/bridges/trunk/.classpath Thu Jun 21 17:39:22 2007
@@ -42,6 +42,7 @@
<classpathentry kind="var"
path="MAVEN_REPO/org.springframework/jars/spring-web-2.0.5.jar"/>
<classpathentry kind="var"
path="MAVEN_REPO/org.springframework/jars/spring-portlet-2.0.5.jar"/>
<classpathentry kind="var"
path="MAVEN_REPO/commons-collections/jars/commons-collections-3.2.jar"/>
- <classpathentry kind="var"
path="MAVEN_REPO/commons-lang/jars/commons-lang-2.1.jar"/>
+ <classpathentry kind="var"
path="MAVEN_REPO/commons-lang/jars/commons-lang-2.1.jar"/>
+ <classpathentry kind="var"
path="MAVEN_REPO/org.apache.portals.jetspeed-2/jars/jetspeed-api-2.1.1-dev.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
Modified: portals/bridges/trunk/groovy/pom.xml
URL:
http://svn.apache.org/viewvc/portals/bridges/trunk/groovy/pom.xml?view=diff&rev=549652&r1=549651&r2=549652
==============================================================================
--- portals/bridges/trunk/groovy/pom.xml (original)
+++ portals/bridges/trunk/groovy/pom.xml Thu Jun 21 17:39:22 2007
@@ -72,6 +72,12 @@
<version>1.0</version>
<scope>compile</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.portals.jetspeed-2</groupId>
+ <artifactId>jetspeed-api</artifactId>
+ <version>${jetspeed.version}</version>
+ <type>jar</type>
+ </dependency>
</dependencies>
<!-- Build Configuration -->
Modified: portals/bridges/trunk/groovy/project.xml
URL:
http://svn.apache.org/viewvc/portals/bridges/trunk/groovy/project.xml?view=diff&rev=549652&r1=549651&r2=549652
==============================================================================
--- portals/bridges/trunk/groovy/project.xml (original)
+++ portals/bridges/trunk/groovy/project.xml Thu Jun 21 17:39:22 2007
@@ -53,11 +53,17 @@
</contributor>
</contributors>
<dependencies>
- <dependency>
+ <dependency>
<id>groovy:groovy</id>
<version>1.0</version>
<type>jar</type>
</dependency>
+ <dependency>
+ <groupId>org.apache.portals.jetspeed-2</groupId>
+ <artifactId>jetspeed-api</artifactId>
+ <version>${jetspeed.api.version}</version>
+ <type>jar</type>
+ </dependency>
</dependencies>
<build>
Added:
portals/bridges/trunk/groovy/src/java/org/apache/portals/bridges/groovy/GroovyPortletHeaderPhaseSupport.java
URL:
http://svn.apache.org/viewvc/portals/bridges/trunk/groovy/src/java/org/apache/portals/bridges/groovy/GroovyPortletHeaderPhaseSupport.java?view=auto&rev=549652
==============================================================================
---
portals/bridges/trunk/groovy/src/java/org/apache/portals/bridges/groovy/GroovyPortletHeaderPhaseSupport.java
(added)
+++
portals/bridges/trunk/groovy/src/java/org/apache/portals/bridges/groovy/GroovyPortletHeaderPhaseSupport.java
Thu Jun 21 17:39:22 2007
@@ -0,0 +1,68 @@
+/*
+ * 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.portals.bridges.groovy;
+
+import java.io.IOException;
+
+import javax.portlet.PortletException;
+
+import org.codehaus.groovy.control.CompilationFailedException;
+
+import org.apache.jetspeed.portlet.SupportsHeaderPhase;
+import org.apache.jetspeed.portlet.PortletHeaderRequest;
+import org.apache.jetspeed.portlet.PortletHeaderResponse;
+
+/**
+ * <p>
+ * GroovyPortletHeaderPhaseSupport parses and invokes a groovy-scripted
portlet. A groovy-scripted
+ * portlet just need to be implemented like any other Java-based portlet. So, a
+ * groovy-scripted portlet does not support only full features of JSR-168
portlet, but
+ * it also supports JSR-286 header phase.
+ *
+ * @author <a href="mailto:[EMAIL PROTECTED]">Woonsan Ko</a>
+ * @Id@
+ */
+public class GroovyPortletHeaderPhaseSupport extends GroovyPortlet implements
SupportsHeaderPhase
+{
+ protected SupportsHeaderPhase scriptPortletInstanceWithHeaderPhase;
+
+ public GroovyPortletHeaderPhaseSupport()
+ {
+ super();
+ }
+
+ public void doHeader(PortletHeaderRequest request, PortletHeaderResponse
response) throws PortletException
+ {
+ refreshPortletInstance();
+
+ if (this.scriptPortletInstanceWithHeaderPhase != null)
+ {
+ this.scriptPortletInstanceWithHeaderPhase.doHeader(request,
response);
+ }
+ }
+
+ protected void createScriptPortletInstance() throws
CompilationFailedException, InstantiationException,
+ IOException, IllegalAccessException, PortletException
+ {
+ super.createScriptPortletInstance();
+
+ if (scriptPortletInstance instanceof SupportsHeaderPhase)
+ {
+ this.scriptPortletInstanceWithHeaderPhase = (SupportsHeaderPhase)
scriptPortletInstance;
+ }
+ }
+}
Added:
portals/bridges/trunk/groovy/src/java/org/apache/portals/bridges/groovy/GroovyPreferencesValidator.java
URL:
http://svn.apache.org/viewvc/portals/bridges/trunk/groovy/src/java/org/apache/portals/bridges/groovy/GroovyPreferencesValidator.java?view=auto&rev=549652
==============================================================================
---
portals/bridges/trunk/groovy/src/java/org/apache/portals/bridges/groovy/GroovyPreferencesValidator.java
(added)
+++
portals/bridges/trunk/groovy/src/java/org/apache/portals/bridges/groovy/GroovyPreferencesValidator.java
Thu Jun 21 17:39:22 2007
@@ -0,0 +1,216 @@
+/*
+ * 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.portals.bridges.groovy;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.Collection;
+import java.util.ArrayList;
+
+import javax.portlet.PortletPreferences;
+import javax.portlet.PreferencesValidator;
+import javax.portlet.ValidatorException;
+
+import groovy.lang.GroovyClassLoader;
+import groovy.lang.GroovyCodeSource;
+import org.codehaus.groovy.control.CompilationFailedException;
+
+/**
+ * <p>
+ * GroovyPreferencesValidator parses and invokes a groovy-scripted validator.
A groovy-scripted
+ * PreferencesValidator just need to be implemented like any other Java-based
preferences validator.
+ *
+ * @author <a href="mailto:[EMAIL PROTECTED]">Woonsan Ko</a>
+ * @Id@
+ */
+public class GroovyPreferencesValidator implements PreferencesValidator
+{
+ public static final String SCRIPT_SOURCE_PREF_KEY =
"validator-script-source";
+
+ public static final String SCRIPT_SOURCE_URL_ENCODING_PREF_KEY =
"validator-script-source-uri-encoding";
+
+ public static final String AUTO_REFRESH_PREF_KEY =
"validator-auto-refresh";
+
+ protected String scriptSourceUri;
+
+ protected String scriptSourceUriEncoding = "UTF-8";
+
+ protected boolean autoRefresh;
+
+ protected long parsedFileLastModified;
+
+ protected GroovyCodeSource groovyCodeSource;
+
+ protected PreferencesValidator scriptPreferencesValidatorInstance;
+
+ protected GroovyClassLoader groovyClassLoader;
+
+ public GroovyPreferencesValidator()
+ {
+ }
+
+ public void validate(PortletPreferences preferences) throws
ValidatorException
+ {
+ if (this.groovyCodeSource == null)
+ {
+ initialize(preferences);
+ }
+
+ refreshPreferencesValidatorInstance();
+
+ this.scriptPreferencesValidatorInstance.validate(preferences);
+ }
+
+ public void initialize(PortletPreferences preferences) throws
ValidatorException
+ {
+ this.groovyClassLoader = new GroovyClassLoader();
+
+ this.autoRefresh =
"true".equals(preferences.getValue(AUTO_REFRESH_PREF_KEY, null));
+
+ String param =
preferences.getValue(SCRIPT_SOURCE_URL_ENCODING_PREF_KEY, null);
+
+ if (param != null)
+ {
+ this.scriptSourceUriEncoding = param;
+ }
+
+ this.scriptSourceUri = preferences.getValue(SCRIPT_SOURCE_PREF_KEY,
null);
+
+ if (this.scriptSourceUri == null)
+ {
+ Collection failedKeys = new ArrayList();
+ failedKeys.add(SCRIPT_SOURCE_PREF_KEY);
+ throw new ValidatorException("Configuration failed: " +
SCRIPT_SOURCE_PREF_KEY + " should be set properly!", failedKeys);
+ }
+ else
+ {
+ try
+ {
+ if (this.scriptSourceUri.startsWith("file:"))
+ {
+ String decodedScriptSourceUri = this.scriptSourceUri;
+
+ try
+ {
+ decodedScriptSourceUri =
URLDecoder.decode(this.scriptSourceUri, this.scriptSourceUriEncoding);
+ }
+ catch (UnsupportedEncodingException encodingEx)
+ {
+ Collection failedKeys = new ArrayList();
+ failedKeys.add(SCRIPT_SOURCE_URL_ENCODING_PREF_KEY);
+ throw new ValidatorException("Unsupported encoding: "
+ this.scriptSourceUriEncoding, failedKeys);
+ }
+
+ this.groovyCodeSource = new GroovyCodeSource(new
File(decodedScriptSourceUri.substring(5)));
+ }
+ else if (this.scriptSourceUri.startsWith("classpath:"))
+ {
+ String resourceURL =
this.groovyClassLoader.getResource(this.scriptSourceUri.substring(10))
+ .toString();
+
+ if (resourceURL.startsWith("file:"))
+ {
+ String decodedScriptSourceUri = resourceURL;
+
+ try
+ {
+ decodedScriptSourceUri =
URLDecoder.decode(resourceURL, this.scriptSourceUriEncoding);
+ }
+ catch (UnsupportedEncodingException encodingEx)
+ {
+ Collection failedKeys = new ArrayList();
+
failedKeys.add(SCRIPT_SOURCE_URL_ENCODING_PREF_KEY);
+ throw new ValidatorException("Unsupported
encoding: " + this.scriptSourceUriEncoding, failedKeys);
+ }
+
+ this.groovyCodeSource = new GroovyCodeSource(new
File(decodedScriptSourceUri.substring(5)));
+ }
+ else
+ {
+ Collection failedKeys = new ArrayList();
+ failedKeys.add(SCRIPT_SOURCE_PREF_KEY);
+ throw new ValidatorException(SCRIPT_SOURCE_PREF_KEY
+ + " with 'classpath:' prefix should indicate
to a local resource", failedKeys);
+ }
+ }
+ else
+ {
+ Collection failedKeys = new ArrayList();
+ failedKeys.add(SCRIPT_SOURCE_PREF_KEY);
+ throw new ValidatorException("Configuration failed: " +
SCRIPT_SOURCE_PREF_KEY + " should be prefixed by 'file:' or 'classpath'.",
failedKeys);
+ }
+ }
+ catch (FileNotFoundException e)
+ {
+ Collection failedKeys = new ArrayList();
+ failedKeys.add(SCRIPT_SOURCE_PREF_KEY);
+ throw new ValidatorException("File not found: " +
this.scriptSourceUri, failedKeys);
+ }
+
+ this.groovyCodeSource.setCachable(!this.autoRefresh);
+ }
+ }
+
+ protected void refreshPreferencesValidatorInstance() throws
ValidatorException
+ {
+ if (this.scriptPreferencesValidatorInstance == null)
+ {
+ try
+ {
+ createScriptPreferencesValidatorInstance();
+ }
+ catch (Exception ex)
+ {
+ Collection failedKeys = new ArrayList();
+ failedKeys.add(SCRIPT_SOURCE_PREF_KEY);
+ throw new ValidatorException("Could not compile script: " +
this.scriptSourceUri, failedKeys);
+ }
+ }
+ else if (this.autoRefresh && isScriptFileModified())
+ {
+ synchronized (this.scriptPreferencesValidatorInstance)
+ {
+ try
+ {
+ createScriptPreferencesValidatorInstance();
+ }
+ catch (Exception ex)
+ {
+ Collection failedKeys = new ArrayList();
+ failedKeys.add(SCRIPT_SOURCE_PREF_KEY);
+ throw new ValidatorException("Could not compile script: "
+ this.scriptSourceUri, failedKeys);
+ }
+ }
+ }
+ }
+
+ protected boolean isScriptFileModified()
+ {
+ return (this.groovyCodeSource.getFile().lastModified() >
this.parsedFileLastModified);
+ }
+
+ protected void createScriptPreferencesValidatorInstance() throws
CompilationFailedException, InstantiationException,
+ IOException, IllegalAccessException, ValidatorException
+ {
+ Class scriptPreferencesValidatorClass =
this.groovyClassLoader.parseClass(this.groovyCodeSource);
+ this.scriptPreferencesValidatorInstance = (PreferencesValidator)
scriptPreferencesValidatorClass.newInstance();
+ this.parsedFileLastModified =
this.groovyCodeSource.getFile().lastModified();
+ }
+}
Added: portals/bridges/trunk/groovy/xdocs/headersupport.xml
URL:
http://svn.apache.org/viewvc/portals/bridges/trunk/groovy/xdocs/headersupport.xml?view=auto&rev=549652
==============================================================================
--- portals/bridges/trunk/groovy/xdocs/headersupport.xml (added)
+++ portals/bridges/trunk/groovy/xdocs/headersupport.xml Thu Jun 21 17:39:22
2007
@@ -0,0 +1,125 @@
+<?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.
+-->
+<document>
+ <properties>
+ <title>Jetspeed Header Phase Support</title>
+ <subtitle>Documentation for Creating a Groovy Portlet with
Header Phase Support</subtitle>
+ <authors>
+ <person name="Woonsan Ko" email="[EMAIL PROTECTED]" />
+ </authors>
+ </properties>
+ <body>
+ <section name="Jetspeed Groovy Portlet with Header Phase
Support Guide">
+ <p>Jetspeed-2 provides an interface for a portlet to be able to
support the pre-286 header phase. If you want your portlet to support this,
just use GroovyPortletHeaderPhaseSupport class instead of GroovyPortlet, and
implement SupportsHeaderPhase interface.</p>
+
+ <subsection name="1. The Portlet Class supporting header phase">
+ <p>
+ Create the file HelloGroovyHeaderSupport.groovy
in a directory called
+ groovy-simplest/WEB-INF/classes:
+ <source><![CDATA[
+import javax.portlet.GenericPortlet;
+import javax.portlet.PortletContext;
+import javax.portlet.PortletRequestDispatcher;
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+import javax.portlet.ActionRequest;
+import javax.portlet.ActionResponse;
+import javax.portlet.PortletPreferences;
+import javax.portlet.ValidatorException;
+
+import org.apache.jetspeed.headerresource.HeaderResource;
+import org.apache.jetspeed.portlet.PortletHeaderRequest;
+import org.apache.jetspeed.portlet.PortletHeaderResponse;
+import org.apache.jetspeed.portlet.SupportsHeaderPhase;
+
+public class HelloGroovyHeaderSupport extends GenericPortlet implements
SupportsHeaderPhase
+{
+ public void doHeader(PortletHeaderRequest request, PortletHeaderResponse
response)
+ {
+ // use header resource component to ensure header logic is included
only once
+ HeaderResource headerResource = response.getHeaderResource();
+ headerResource.dojoEnable();
+
+ headerResource.dojoAddCoreLibraryRequire( "dojo.lang.*" );
+ headerResource.dojoAddCoreLibraryRequire( "dojo.event.*" );
+ headerResource.dojoAddCoreLibraryRequire( "dojo.io.*" );
+ headerResource.dojoAddCoreLibraryRequire( "dojo.widget.*" );
+ headerResource.dojoAddCoreLibraryRequire( "dojo.widget.Button" );
+ }
+
+ public void doView(RenderRequest request, RenderResponse response)
+ {
+ response.setContentType("text/html");
+
+ // Let's put a dojo widget button for simplicity here.
+ response.getWriter().println """
+ <button widgetId="helloGroovyButton" dojoType="Button"
onclick="alert('Hello, Groovy');">
+ Say Hello
+ </button>
+ """
+ }
+
+}
+ ]]></source>
+ For simplicity, in the above example, the doView() method just
writes a simple HTML fragment to show DOJO button widget.
+ </p>
+ </subsection>
+ <subsection name="2. The portlet.xml">
+ <p>
+ <source><![CDATA[
+<?xml version="1.0" encoding="UTF-8"?>
+<portlet-app id="velocitysimplest" version="1.0">
+ <portlet id="HelloGroovyHeaderSupport">
+ <portlet-name>HelloGroovyHeaderSupport</portlet-name>
+ <display-name>Hello Groovy with Header Support Display Name</display-name>
+
<portlet-class>org.apache.portals.bridges.groovy.GroovyPortletHeaderPhaseSupport</portlet-class>
+ <init-param>
+ <name>script-source</name>
+ <!-- Note: You can set script source in three ways.
+ The first is to use relative path uri,
+ the second is to use file: url,
+ and the last is to classpath: uri -->
+ <!--
+ <value>/WEB-INF/groovy/HelloGroovy.groovy</value>
+ <value>file:/C:/Program Files/Apache Software Foundation/Tomcat
5.5/webapps/demo/WEB-INF/groovy/HelloGroovy.groovy</value>
+ -->
+ <value>classpath:HelloGroovyHeaderSupport.groovy</value>
+ </init-param>
+ <!-- If auto-refresh is true, then a modification of script source applies
instantly. -->
+ <init-param>
+ <name>auto-refresh</name>
+ <value>true</value>
+ </init-param>
+ <supports>
+ <mime-type>text/html</mime-type>
+ <portlet-mode>VIEW</portlet-mode>
+ </supports>
+ <supported-locale>en</supported-locale>
+ <portlet-info>
+ <title>Hello Groovy with Header Support Title</title>
+ <short-title>Hello Groovy with Header Support Short Title</short-title>
+ </portlet-info>
+ </portlet>
+</portlet-app>
+ ]]></source>
+ The <portlet-class> was replaced with
'org.apache.portals.bridges.groovy.GroovyPortletHeaderPhaseSupport' instead of
'org.apache.portals.bridges.groovy.GroovyPortlet' to support header phase.
+ </p>
+ </subsection>
+ </section>
+ </body>
+</document>
Modified: portals/bridges/trunk/groovy/xdocs/index.xml
URL:
http://svn.apache.org/viewvc/portals/bridges/trunk/groovy/xdocs/index.xml?view=diff&rev=549652&r1=549651&r2=549652
==============================================================================
--- portals/bridges/trunk/groovy/xdocs/index.xml (original)
+++ portals/bridges/trunk/groovy/xdocs/index.xml Thu Jun 21 17:39:22 2007
@@ -228,11 +228,24 @@
</subsection>
<subsection name="9. Additional Notes">
<ul>
- <li>In this example, JSP and JSTL is used for view pages.
However, you can use other technologies such as Velocity, Groovlet or Groovy
template.</li>
- <li>GroovyPortlet instantiates a groovy-scripted portlet
instance just like any Java portlet, and so you can use any techniques used in
Java portlet programming. For example, your groovy script portlet can extend
org.apache.portals.bridges.common.GenericServletPortlet to simplify
implementation.</li>
<li>You can make the script source simpler than Java. See
the groovy documentation.</li>
+ <li>GroovyPortlet instantiates a groovy-scripted portlet
instance just like any Java portlet, and so you can use any techniques used in
Java portlet programming. For example, your groovy script portlet can extend
org.apache.portals.bridges.common.GenericServletPortlet to simplify
implementation.</li>
+ <li>In this example, JSP and JSTL is used for view pages.
However, you can use other technologies such as Velocity, Groovlet or Groovy
template.</li>
+ <li>If you use Groovlet or Groovy template, a solution for
getting renderRequest and renderResponse can be like this:
+ <source>
+def renderRequest = request.getAttribute("javax.portlet.request")
+def renderResponse = request.getAttribute("javax.portlet.response")
+ </source>
+ </li>
</ul>
</subsection>
+ <subsection name="10. See Also">
+ <p>You can write preferences validator with groovy, and you
can write a groovy script portlet supporting header phase (pre-286 feature).</p>
+ <ul>
+ <li><a href="prefvalidate.html">Jetspeed Groovy
PreferencesValidator Guide</a></li>
+ <li><a href="headersupport.html">Jetspeed Groovy Portlet
with Header Phase Support Guide</a></li>
+ </ul>
+ </subsection>
</section>
</body>
</document>
Modified: portals/bridges/trunk/groovy/xdocs/navigation.xml
URL:
http://svn.apache.org/viewvc/portals/bridges/trunk/groovy/xdocs/navigation.xml?view=diff&rev=549652&r1=549651&r2=549652
==============================================================================
--- portals/bridges/trunk/groovy/xdocs/navigation.xml (original)
+++ portals/bridges/trunk/groovy/xdocs/navigation.xml Thu Jun 21 17:39:22 2007
@@ -25,7 +25,9 @@
</links>
<menu name="Groovy Bridge">
- <item name="Guide" href="index.html"/>
+ <item name="Jetspeed Groovy Portlet Guide" href="index.html"/>
+ <item name="Jetspeed Groovy PreferencesValidator Guide"
href="prefvalidate.html"/>
+ <item name="Jetspeed Groovy Portlet with Header Phase Support Guide"
href="headersupport.html"/>
</menu>
</body>
Added: portals/bridges/trunk/groovy/xdocs/prefvalidate.xml
URL:
http://svn.apache.org/viewvc/portals/bridges/trunk/groovy/xdocs/prefvalidate.xml?view=auto&rev=549652
==============================================================================
--- portals/bridges/trunk/groovy/xdocs/prefvalidate.xml (added)
+++ portals/bridges/trunk/groovy/xdocs/prefvalidate.xml Thu Jun 21 17:39:22 2007
@@ -0,0 +1,157 @@
+<?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.
+-->
+<document>
+ <properties>
+ <title>How to use Groovy PreferencesValidator</title>
+ <subtitle>Documentation for Creating a Groovy
PreferencesValidator</subtitle>
+ <authors>
+ <person name="Woonsan Ko" email="[EMAIL PROTECTED]" />
+ </authors>
+ </properties>
+ <body>
+ <section name="Jetspeed Groovy PreferencesValidator Guide">
+ <p>
+ This guide provides a tutorial for creating a
Groovy Preferences Validator.
+ </p>
+ <subsection name="1. The Groovy PreferencesValidator
Class">
+ <p>Create the file HelloGroovyValidator.groovy in a directory
called groovy-simplest/WEB-INF/classes:
+ <source><![CDATA[
+import javax.portlet.PortletPreferences;
+import javax.portlet.PreferencesValidator;
+import javax.portlet.ValidatorException;
+
+public class HelloGroovyValidator implements PreferencesValidator
+{
+ public void validate(PortletPreferences preferences)
+ {
+ String message = preferences.getValue("message", null);
+
+ if (message == null || "".equals(message.trim()))
+ {
+ def failedKeys = [ "message" ];
+ throw new ValidatorException("message must be set!", failedKeys);
+ }
+ }
+} ]]></source>
+ </p>
+ </subsection>
+ <subsection name="2. The portlet.xml">
+ <p>
+ Edit the file portlet.xml in the
groovy-simplest/WEB-INF directory to add Groovy PreferencesValidator. In this
case, <portlet-preferences> element is added to the previous example.
+ <source><![CDATA[
+<?xml version="1.0" encoding="UTF-8"?>
+<portlet-app id="velocitysimplest" version="1.0">
+ <portlet id="HelloGroovy">
+ <portlet-name>HelloGroovy</portlet-name>
+ <display-name>Hello Groovy Display Name</display-name>
+
<portlet-class>org.apache.portals.bridges.groovy.GroovyPortlet</portlet-class>
+ <init-param>
+ <name>script-source</name>
+ <!-- Note: You can set script source in three ways.
+ The first is to use relative path uri,
+ the second is to use file: url,
+ and the last is to classpath: uri -->
+ <!--
+ <value>/WEB-INF/groovy/HelloGroovy.groovy</value>
+ <value>file:/C:/Program Files/Apache Software Foundation/Tomcat
5.5/webapps/demo/WEB-INF/groovy/HelloGroovy.groovy</value>
+ -->
+ <value>classpath:HelloGroovy.groovy</value>
+ </init-param>
+ <!-- If auto-refresh is true, then a modification of script source applies
instantly. -->
+ <init-param>
+ <name>auto-refresh</name>
+ <value>true</value>
+ </init-param>
+ <supports>
+ <mime-type>text/html</mime-type>
+ <portlet-mode>VIEW</portlet-mode>
+ <portlet-mode>EDIT</portlet-mode>
+ <portlet-mode>HELP</portlet-mode>
+ </supports>
+ <supported-locale>en</supported-locale>
+ <portlet-info>
+ <title>Hello Groovy Title</title>
+ <short-title>Hello Groovy Short Title</short-title>
+ </portlet-info>
+ <portlet-preferences>
+ <preference>
+ <name>validator-script-source</name>
+ <!-- Note: You can set script source in two ways.
+ The first is to use classpath: path uri,
+ and the other is to file: url.
+ Note that relative path uri is not supported for
preferences validator. -->
+ <value>classpath:HelloGroovyValidator.groovy</value>
+ <!--
+ <value>file:/C:/Program Files/Apache Software Foundation/Tomcat
5.5/webapps/demo/WEB-INF/groovy/HelloGroovyValidator.groovy</value>
+ -->
+ <read-only>true</read-only>
+ </preference>
+ <preference>
+ <name>validator-auto-refresh</name>
+ <!-- If validator-auto-refresh is true,
+ then a modification of script source applies instantly. -->
+ <value>true</value>
+ <read-only>true</read-only>
+ </preference>
+
<preferences-validator>org.apache.portals.bridges.groovy.GroovyPreferencesValidator</preferences-validator>
+ </portlet-preferences>
+ </portlet>
+</portlet-app>]]>
+ </source>
+ </p>
+ </subsection>
+ <subsection name="3. How to handle validation
exception">
+ <p>If you set a preferences validator, you should
handle a validation exception in your portlet code like the following example.
The HelloGroovy.groovy in the previous example now handles validation exception
during PortletPreferences.store() call.
+ <source><![CDATA[
+ public void processAction(ActionRequest request, ActionResponse response)
+ {
+ String message = request.getParameter("message");
+
+ PortletPreferences prefs = request.getPreferences();
+ prefs.setValue("message", message);
+
+ try {
+ prefs.store();
+ } catch (ValidatorException e) {
+ // send this error information to the rendering phase.
+ response.setRenderParameter("errorMessage", e.getMessage());
+ }
+ }
+ ]]></source>
+ </p>
+ </subsection>
+ <subsection name="4. Additional Notes">
+ <p>In groovy, you can use powerful regular expressions like
the following example:
+ <source><![CDATA[
+ public void validate(PortletPreferences preferences)
+ {
+ // Let's assume that we have a preference for an email address.
+ String email = preferences.getValue("email", "");
+
+ if (!(email ==~ /[EMAIL PROTECTED]/))
+ {
+ def failedKeys = [ "email" ];
+ throw new ValidatorException("message must be set!", failedKeys);
+ }
+ }
+ ]]></source>
+ </p>
+ </subsection>
+ </section>
+ </body>
+</document>
Modified: portals/bridges/trunk/project.properties
URL:
http://svn.apache.org/viewvc/portals/bridges/trunk/project.properties?view=diff&rev=549652&r1=549651&r2=549652
==============================================================================
--- portals/bridges/trunk/project.properties (original)
+++ portals/bridges/trunk/project.properties Thu Jun 21 17:39:22 2007
@@ -106,6 +106,7 @@
tomahawk.version=1.1.5
spring.version=2.0.5
jython.version=2.2a1
+jetspeed.api.version=2.1.1-beta1
jetspeed.rewriter.version=2.1.1-beta1
log4j.version=1.2.14
# Whether or not to include log4j in war files. Your container may already
have this.
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]