weaver 2003/03/20 10:09:39
Added: src/java/org/apache/jetspeed/portal/portlets/viewprocessor
XSLViewProcessor.java JSPViewProcessor.java
ViewProcessorFactory.java ViewProcessor.java
VelocityViewProcessor.java RSSViewProcessor.java
src/java/org/apache/jetspeed/portal/portlets
GenericMVCPortlet.java GenericMVCContext.java
src/java/org/apache/jetspeed/modules/actions/portlets
GenericMVCAction.java PortletAction.java
PortletActionEvent.java
Log:
Relative to enhancement bug id's17747 and 17756.
The MVC portlet api will allow developers to create template-portlets from a single
base class as opposed to previously having to extending entirely different classes
based on the view/template technology that was to be implemented.
Added:
-GenericMVCPortlet: view-agnostic portlet for template-based presentation
development.
Easily replaces all JspPortlet/VelocityPortlet classes and sub-classes.
-PortletActionEvent: extends ActionEvent,
-PortletAction: Extends PortletActionEvent and provides support for event execution.
-GenericMVCAction: Concrete implementation of the PortletAction. Should be used in
combination
with the GenericMVCPortlet
- view processors: These classes are used by the MVCPortlet to render content base
on the "viewtype"
registry setting.
Revision Changes Path
1.1
jakarta-jetspeed/src/java/org/apache/jetspeed/portal/portlets/viewprocessor/XSLViewProcessor.java
Index: XSLViewProcessor.java
===================================================================
/* ===================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000-2001 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 acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Jetspeed" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache" or
* "Apache Jetspeed", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* 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/>.
*/
package org.apache.jetspeed.portal.portlets.viewprocessor;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import org.apache.ecs.ConcreteElement;
import org.apache.jetspeed.capability.CapabilityMap;
import org.apache.jetspeed.portal.Portlet;
import org.apache.jetspeed.portal.portlets.*;
import org.apache.jetspeed.portal.portlets.GenericMVCContext;
import org.apache.jetspeed.portal.portlets.viewprocessor.*;
import org.apache.jetspeed.services.rundata.JetspeedRunData;
//Element Construction Set
import org.apache.jetspeed.util.JetspeedClearElement;
import org.apache.jetspeed.util.MimeType;
import org.apache.jetspeed.util.SimpleTransform;
//turbine
import org.apache.turbine.util.Log;
//SAX
import org.xml.sax.SAXException;
/**
* Simple ViewProcessor which does a basic XSLT transform with the stylesheet
parameter
* and the given URL.
*
* @author [EMAIL PROTECTED]
* @version $Id: XSLViewProcessor.java,v 1.1.2.2 2003/02/24 21:52:27 tkuebler Exp $
*
*/
public class XSLViewProcessor
implements ViewProcessor
{
/**
The stylesheet parameter
*/
public static final String STYLESHEET = "stylesheet";
public static final String ERROR_NOT_VALID = "This does not appear to be an XML
document";
public static final String INVALID_TYPE = "Unable to display for this browser";
private Hashtable stylesheets = null;
/**
Constructor
*/
public XSLViewProcessor()
{
}
/**
This methods outputs the content of the portlet for a given
request.
@param data the RunData object for the request
@return the content to be displayed to the user-agent
*/
public Object processView(GenericMVCContext context)
{
getStylesheets((Portlet) context.get("portlet")); // used to be in portlet
init, do we
// need to get this functionality
// into the model?
CapabilityMap map = ((JetspeedRunData) context.get("data")).getCapability();
String type = map.getPreferredType().toString();
ConcreteElement content = new JetspeedClearElement(INVALID_TYPE);
String stylesheet = (String) stylesheets.get(type);
if (stylesheet != null)
{
try
{
content = new JetspeedClearElement(
SimpleTransform.transform(
((Portlet)
context.get("portlet")).getPortletConfig().getURL(),
stylesheet,
((Portlet)
context.get("portlet")).getPortletConfig().getInitParameters()));
}
catch (SAXException e)
{
Log.error(e);
content = new JetspeedClearElement(e.getMessage());
}
}
return content;
}
/**
This portlet supports has many types as those
it has stylesheets defined for in its parameters
@see Portlet#supportsType
@param mimeType the MIME type queried
@return true if the portlet knows how to display
content for mimeType
*/
public boolean supportsType(MimeType mimeType)
{
Enumeration en = stylesheets.keys();
while (en.hasMoreElements())
{
String type = (String) en.nextElement();
if (type.equals(mimeType.toString()))
{
return true;
}
}
return false;
}
private void getStylesheets(Portlet portlet)
{
stylesheets = new Hashtable();
Iterator en = portlet.getPortletConfig().getInitParameterNames();
while (en.hasNext())
{
String name = (String) en.next();
String base = MimeType.HTML.toString();
if (name.startsWith(STYLESHEET))
{
int idx = -1;
if ((idx = name.indexOf(".")) > -1)
{
base = name.substring(idx + 1, name.length());
}
stylesheets.put(base,
portlet.getPortletConfig().getInitParameter(name));
}
}
}
/** Process the template passed in the context
* (context.get("template")). Invoked by the GenericMVCPortlet
* after action handling to process the template type
* in question.
*
*/
public void init(Portlet portlet)
{
}
}
1.1
jakarta-jetspeed/src/java/org/apache/jetspeed/portal/portlets/viewprocessor/JSPViewProcessor.java
Index: JSPViewProcessor.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000-2001 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 acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Jetspeed" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache" or
* "Apache Jetspeed", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* 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/>.
*/
/*
* JSPViewProcessor.java
*
* Created on January 27, 2003, 5:37 PM
*/
package org.apache.jetspeed.portal.portlets.viewprocessor;
// Ecs
import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement;
// Jetspeed portal
import org.apache.jetspeed.portal.Portlet;
import org.apache.jetspeed.portal.portlets.*;
import org.apache.jetspeed.portal.portlets.GenericMVCContext;
import org.apache.jetspeed.portal.portlets.viewprocessor.*;
import org.apache.jetspeed.services.TemplateLocator;
import org.apache.turbine.services.TurbineServices;
import org.apache.turbine.services.jsp.JspService;
import org.apache.turbine.util.Log;
// Turbine util
import org.apache.turbine.util.RunData;
/**
*
* @author tkuebler
*/
public class JSPViewProcessor
implements ViewProcessor
{
/** Creates a new instance of JSPViewProcessor */
public JSPViewProcessor()
{
}
public Object processView(GenericMVCContext context)
{
String template = (String) context.get("template");
Log.info("JSPViewProcessor - processing template " + template);
try
{
//
// gets the jsp page from the xreg configuration
// NOTE: wouldn't it be better to get the param from the PSML?
//
if (-1 == template.indexOf(".jsp"))
{
template = template + ".jsp";
}
Log.info("JSPViewProcessor - locating template - " + ((RunData)
context.get("data")).toString() + " - " + template);
//we use the template locator to translate the template
String locatedTemplate = TemplateLocator.locatePortletTemplate((RunData)
context.get("data"), template);
Log.info("JSPViewProcessor - located template: " + locatedTemplate);
JspService service = (JspService)
TurbineServices.getInstance().getService(JspService.SERVICE_NAME);
// this is only necessary if we ddon't run in a JSP page environment
// but better be safe than sorry...
service.addDefaultObjects((RunData) context.get("data"));
// Allow access to portlet from .jsp template
((RunData) context.get("data")).getRequest().setAttribute("portlet",
(Portlet) context.get("portlet"));
// put context in attribute so you can get to it from .jsp template
((RunData) context.get("data")).getRequest().setAttribute("context",
context);
// Add js_peid out of convenience
((RunData) context.get("data")).getRequest().setAttribute("js_peid",
((Portlet) context.get("portlet")).getID());
// handle request
service.handleRequest((RunData) context.get("data"), locatedTemplate);
}
catch (Exception e)
{
String message = "JspViewProcessor: Could not include the following JSP
Page: [" + template + "] :\n\t" +
e.getMessage();
Log.error(message, e);
return new StringElement(message);
}
return new ElementContainer();
}
/** Process the template passed in the context
* (context.get("template")). Invoked by the GenericMVCPortlet
* after action handling to process the template type
* in question.
*
*/
public void init(Portlet portlet)
{
}
}
1.1
jakarta-jetspeed/src/java/org/apache/jetspeed/portal/portlets/viewprocessor/ViewProcessorFactory.java
Index: ViewProcessorFactory.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000-2001 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 acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Jetspeed" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache" or
* "Apache Jetspeed", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* 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/>.
*/
/*
* ViewProcessorFactory.java
*
* Created on January 27, 2003, 5:16 PM
*/
package org.apache.jetspeed.portal.portlets.viewprocessor;
import org.apache.jetspeed.portal.portlets.*;
import org.apache.jetspeed.portal.portlets.viewprocessor.*;
import org.apache.turbine.util.Log;
/**
* Creates the appropriate ViewProcessor to process the template
*
* @author tkuebler
* @version $Id: ViewProcessorFactory.java,v 1.1.2.2 2003/02/24 21:52:27 tkuebler
Exp $
* @stereotype factory
*
*/
public class ViewProcessorFactory
{
/** Creates a new instance of ViewProcessorFactory */
public ViewProcessorFactory()
{
// load the type -> processor map
// this should probably be a turbine service...
}
public static ViewProcessor getViewProcessor(String viewType)
{
ViewProcessor viewProcessor;
// figure out the type of portlet based on the map
// will use properties file or xreg based map later
// create and return appropriate processor
// hardcoded for now, will use some config file map in future
if (viewType.equals("Velocity"))
{
Log.info("ViewProcessorFactory - creating Velocity processor");
viewProcessor = new VelocityViewProcessor();
}
else if (viewType.equals("JSP"))
{
Log.info("ViewProcessorFactory - creating JSP processor");
viewProcessor = new JSPViewProcessor();
}
else if (viewType.equals("XSL"))
{
Log.info("ViewProcessorFactory - creating XSL processor");
viewProcessor = new XSLViewProcessor();
}
else if (viewType.equals("RSS"))
{
Log.info("ViewProcessorFactory - creating RSS processor");
viewProcessor = new RSSViewProcessor();
}
else
{
Log.error("ViewProcessorFactory - problem figuring out what view
processor type you want - " +
viewType);
Log.error("ViewProcessorFactory - returing a JSP processor");
viewProcessor = new JSPViewProcessor();
}
return viewProcessor;
}
}
1.1
jakarta-jetspeed/src/java/org/apache/jetspeed/portal/portlets/viewprocessor/ViewProcessor.java
Index: ViewProcessor.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000-2001 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 acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Jetspeed" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache" or
* "Apache Jetspeed", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* 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/>.
*/
/*
* ViewProcessor.java
*
* Created on January 27, 2003, 5:18 PM
*/
package org.apache.jetspeed.portal.portlets.viewprocessor;
import org.apache.ecs.ConcreteElement;
import org.apache.jetspeed.portal.Portlet;
import org.apache.jetspeed.portal.PortletException;
import org.apache.jetspeed.portal.portlets.*;
/**
* Interface that defines a ViewProcessor. This is what the
* GenericMVCPortlet uses via the ViewProcessorFactory to
* do the template processing portion of the MVC design pattern.
*
* @author tkuebler
* @version 1.0
* @stereotype plug-in point
*/
public interface ViewProcessor
{
/**
* Process the template passed in the context
* (context.get("template")). Invoked by the GenericMVCPortlet
* after action handling to process the template type
* in question.
*/
void init(Portlet portlet)
throws PortletException;
Object processView(GenericMVCContext context);
}
1.1
jakarta-jetspeed/src/java/org/apache/jetspeed/portal/portlets/viewprocessor/VelocityViewProcessor.java
Index: VelocityViewProcessor.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000-2001 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 acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Jetspeed" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache" or
* "Apache Jetspeed", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* 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/>.
*/
/*
* VelocityViewProcessor.java
*
*
* Created on January 27, 2003, 8:54 PM
*/
package org.apache.jetspeed.portal.portlets.viewprocessor;
import org.apache.jetspeed.portal.Portlet;
import org.apache.jetspeed.portal.PortletException;
import org.apache.jetspeed.portal.portlets.*;
import org.apache.jetspeed.portal.portlets.GenericMVCContext;
import org.apache.jetspeed.portal.portlets.viewprocessor.*;
import org.apache.jetspeed.services.TemplateLocator;
import org.apache.jetspeed.util.JetspeedClearElement;
import org.apache.turbine.services.velocity.TurbineVelocity;
import org.apache.turbine.util.Log;
import org.apache.turbine.util.RunData;
/**
*
* @author tkuebler
*/
public class VelocityViewProcessor
implements ViewProcessor
{
/** Creates a new instance of VelocityViewProcessor */
public VelocityViewProcessor()
{
}
public void init(Portlet portlet)
throws PortletException
{
}
/** Process the template passed in the context
* (context.get("template")). Invoked by the GenericMVCPortlet
* after action handling to process the template type
* in question.
*
*/
public Object processView(GenericMVCContext context)
{
// generate the content
JetspeedClearElement element = null;
String template = (String) context.get("template");
Log.info("VelocityViewProcessor - processing " + template);
try
{
if (-1 == template.indexOf(".vm"))
{
template = template + ".vm";
}
Log.info("VelocityViewProcessor - locating template - " +
((RunData) context.get("data")).toString() + template);
String templatePath = TemplateLocator.locatePortletTemplate(
(RunData) context.get("data"),
template);
// need to add cache support
String s = TurbineVelocity.handleRequest(context, templatePath);
//setExpirationMillis(cachePeriod + System.currentTimeMillis());
element = new JetspeedClearElement(s);
}
catch (Exception e)
{
element = new JetspeedClearElement(e.toString());
Log.error("VelocityViewProcessor - had problems handling request - " +
e);
e.printStackTrace();
}
TurbineVelocity.requestFinished(context);
if (element == null)
{
element = new JetspeedClearElement("");
}
return element;
}
}
1.1
jakarta-jetspeed/src/java/org/apache/jetspeed/portal/portlets/viewprocessor/RSSViewProcessor.java
Index: RSSViewProcessor.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000-2001 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 acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Jetspeed" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache" or
* "Apache Jetspeed", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* 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/>.
*/
package org.apache.jetspeed.portal.portlets.viewprocessor;
import java.io.IOException;
//standard java stuff
import java.io.Reader;
import java.io.StringReader;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
//JAXP support
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.ecs.ConcreteElement;
import org.apache.jetspeed.cache.disk.JetspeedDiskCache;
import org.apache.jetspeed.capability.CapabilityMap;
import org.apache.jetspeed.capability.CapabilityMapFactory;
import org.apache.jetspeed.portal.Portlet;
import org.apache.jetspeed.portal.PortletException;
import org.apache.jetspeed.portal.portlets.*;
import org.apache.jetspeed.portal.portlets.GenericMVCContext;
import org.apache.jetspeed.portal.portlets.viewprocessor.*;
import org.apache.jetspeed.services.rundata.JetspeedRunData;
// Element Construction Set
import org.apache.jetspeed.util.JetspeedClearElement;
import org.apache.jetspeed.util.MimeType;
import org.apache.jetspeed.util.SimpleTransform;
import org.apache.jetspeed.xml.JetspeedXMLEntityResolver;
import org.apache.turbine.util.Log;
import org.apache.turbine.util.RunData;
// XML stuff
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
<p>Portlet which renders RDF Site Summary.</p>
<p>This portlet uses XML stylesheet for transforming the RSS
content into display markup depending on the MimeType requested
by the user-agent</p>
<p>It accepts the following parameters :
<dl>
<dt>itemDisplayed</dt>
<dd>The number of items from the RSS file to display on screen. Default 15 for HTML,
5 for WML</dd>
<dt>showDescription</dt>
<dd>Should the portlet show the item descriptions. Must be true or false. Default:
true for HTML, false for WML</dd>
<dt>showTitle</dt>
<dd>Should the portlet show the channel description. Must be true or false. Default:
true for HTML, false for WML</dd>
<dt>stylesheet[.<mime>]</dt>
<dd>The stylesheet URL. If a mime-type is specified, the stylesheet
is only used for this mime-type</dd>
</dl>
@author <A HREF="mailto:[EMAIL PROTECTED]">Rapha�l Luta</A>
@version $Id: RSSViewProcessor.java,v 1.1.2.2 2003/02/24 21:52:27 tkuebler Exp $
*/
public class RSSViewProcessor
implements ViewProcessor
{
private static final String XMLDECL = "<?xml version=";
public static final String ERROR_NOT_VALID = "This does not appear to be an RSS
document";
public static final String INVALID_TYPE = "Unable to display for this browser";
private Document document = null;
private Hashtable stylesheets = null;
private Hashtable params = null;
/**
This method loads the init parameters and
parse the document tied to this portlet
*/
public void init(Portlet portlet)
throws PortletException
{
DocumentBuilder parser = null;
String url = null;
// load stylesheets available
stylesheets = new Hashtable();
params = new Hashtable();
Iterator i = portlet.getPortletConfig().getInitParameterNames();
while (i.hasNext())
{
String name = (String) i.next();
String base = MimeType.HTML.toString();
if (name.startsWith("stylesheet"))
{
int idx = -1;
if ((idx = name.indexOf(".")) > -1)
{
base = name.substring(idx + 1, name.length());
}
stylesheets.put(base,
portlet.getPortletConfig().getInitParameter(name));
}
else
{
params.put(name.toLowerCase(),
portlet.getPortletConfig().getInitParameter(name));
}
}
// read content, clean it, parse it and cache the DOM
try
{
final DocumentBuilderFactory docfactory =
DocumentBuilderFactory.newInstance();
//Have it non-validating
docfactory.setValidating(false);
parser = docfactory.newDocumentBuilder();
parser.setEntityResolver(new JetspeedXMLEntityResolver());
url = portlet.getPortletConfig().getURL();
String content = JetspeedDiskCache.getInstance().getEntry(url).getData();
CapabilityMap xmap =
CapabilityMapFactory.getCapabilityMap(CapabilityMapFactory.AGENT_XML);
// no cache yet // portlet.setContent( new
JetspeedClearElement(content), xmap );
InputSource isrc = new InputSource(this.cleanse(content));
isrc.setSystemId(url);
isrc.setEncoding("UTF-8");
this.document = parser.parse(isrc);
}
catch (Throwable t)
{
String message = "RSSPortlet: Couldn't parse out XML document -> " +
url;
Log.error(message, t);
throw new PortletException(t.getMessage());
}
//Determine title and description for this portlet
String title = null;
String description = null;
//now find the channel node.
Node channel = null;
NodeList list = document.getElementsByTagName("channel");
if (list.getLength() != 1)
{
throw new PortletException(ERROR_NOT_VALID);
}
channel = list.item(0);
Node tn = getNode(channel, "title");
if (tn == null)
{
throw new PortletException(ERROR_NOT_VALID);
}
else
{
title = tn.getFirstChild().getNodeValue();
}
Node dn = getNode(channel, "description");
if (dn != null)
{
description = dn.getFirstChild().getNodeValue();
}
portlet.setTitle(title);
portlet.setDescription(description);
}
/**
This methods outputs the content of the portlet for a given
request.
@param data the RunData object for the request
@return the content to be displayed to the user-agent
*/
public Object processView(GenericMVCContext context)
{
try
{
init((Portlet) context.get("portlet"));
}
catch (PortletException pe)
{
pe.printStackTrace();
Log.error("RSSViewProcessor - error: " + pe);
}
RunData data = (RunData) context.get("data");
CapabilityMap map = ((JetspeedRunData) data).getCapability();
String type = map.getPreferredType().toString();
ConcreteElement content = new JetspeedClearElement(INVALID_TYPE);
String stylesheet = (String) stylesheets.get(type);
if (stylesheet != null)
{
try
{
content = new
JetspeedClearElement(SimpleTransform.transform(this.document, stylesheet,
this.params));
// no caching yet // setContent( content, map );
}
catch (SAXException e)
{
Log.error(e);
content = new JetspeedClearElement(e.getMessage());
}
}
else
{
content = new JetspeedClearElement("stylesheet not defined");
}
return content;
}
/**
This portlet supports has many types as those
it has stylesheets defined for in its parameters
@see Portlet#supportsType
@param mimeType the MIME type queried
@return true if the portlet knows how to display
content for mimeType
*/
public boolean supportsType(MimeType mimeType)
{
Enumeration en = stylesheets.keys();
while (en.hasMoreElements())
{
String type = (String) en.nextElement();
if (type.equals(mimeType.toString()))
{
return true;
}
}
return false;
}
/**
Utility method for traversing the document parsed
DOM tree and retrieving a Node by tagname
@param start the parent node for the search
@param name the tag name to be searched for
@return the first child node of start whose tagname
is name
*/
private final Node getNode(Node start, String name)
{
NodeList list = start.getChildNodes();
for (int i = 0; i < list.getLength(); ++i)
{
Node node = list.item(i);
if (node.getNodeName().equals(name))
{
return node;
}
}
return null;
}
/**
Given a URL to some content, clean the content to Xerces can handle it
better. Right now this involves:
<ul>
<li>
If the document doesn't begin with "<?xml version=" truncate the
content until this is the first line
</li>
</ul>
*/
private Reader cleanse(String content)
throws IOException
{
String filtered = null;
int start = content.indexOf(XMLDECL);
if (start <= 0)
{
filtered = content;
}
else
{
filtered = content.substring(start, content.length());
}
return new StringReader(filtered);
}
}
1.1
jakarta-jetspeed/src/java/org/apache/jetspeed/portal/portlets/GenericMVCPortlet.java
Index: GenericMVCPortlet.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000-2001 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 acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Jetspeed" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache" or
* "Apache Jetspeed", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* 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/>.
*/
/*
* GenericMVCPortlet.java
*
* Created on January 27, 2003, 5:10 PM
*/
package org.apache.jetspeed.portal.portlets;
import javax.servlet.http.HttpServletRequest;
import org.apache.ecs.ConcreteElement;
import org.apache.jetspeed.portal.PortletException;
import org.apache.jetspeed.portal.portlets.viewprocessor.*;
// using the * form due to the puggable nature
//ie no recompile to support new view processors
import org.apache.jetspeed.util.template.JetspeedLink;
import org.apache.jetspeed.util.template.JetspeedTemplateLink;
import org.apache.turbine.modules.ActionLoader;
import org.apache.turbine.services.pull.TurbinePull;
import org.apache.turbine.util.Log;
import org.apache.turbine.util.RunData;
/**
* Provides the basic MVC Portlet functionality independant of any
* specific view technology (ie jsp, velocity, xslt, etc). It handles
* the views via a ViewProcessor, which is a pluggable, factory
* created, run time module for which ever view technology your portlet
* uses.
*
* There is no need to extend this portlet class, just define your porlet
* entry in the registy as a child of this class and provide your template
* and action class (extened from GenericMVCAction of course) and you
* are good to go.
*
* Example .xreg entry:
*
* <portlet-entry name="GenericMVCPortlet" hidden="false"
* type="abstract" application="false">
* <security-ref parent="default"/>
* <classname>com.cisco.it.psf.portal.portlets.GenericMVCPortlet</classname>
* <media-type ref="html"/>
* <url cachedOnURL="true"/>
* </portlet-entry>
* <portlet-entry name="VelocityMVCExample" hidden="false" type="ref"
* parent="GenericMVCPortlet" application="false">
* <meta-info>
* <title>Velocity MVC Portlet</title>
* <description>Velocity Generic MVC Portlet</description>
* </meta-info>
* <classname>com.cisco.it.psf.portal.portlets.GenericMVCPortlet</classname>
* <parameter name="template" value="mvc-example" hidden="true"
* cachedOnName="true" cachedOnValue="true"/>
* <parameter name="viewtype" value="Velocity" hidden="true"
* cachedOnName="true" cachedOnValue="true"/>
* <parameter name="action"
* value="portlets.ExampleGenericMVCAction" hidden="true"
* cachedOnName="true" cachedOnValue="true"/>
* <url cachedOnURL="true"/>
* </portlet-entry>
*
* See the Velocity and JSP MVC Portlet examples for template and action class clues.
*
* To add new view processor types, simply implement the ViewProcessor
* interface and add your type into the <b>viewprocessor.properties</b> file as
* shown in the example below:
*
* mvc.viewprocessor.Velocity =
org.apache.jetspeedportlets.viewprocessors.VelocityViewProcessor
* mvc.viewprocessor.JSP =
org.apache.jetspeedportlets.viewprocessors.JSPViewProcessor
* mvc.viewprocessor.XSL =
org.apache.jetspeedportlets.viewprocessors.XSLViewProcessor
*
* @author tkuebler
* @author <a href="mailto:[EMAIL PROTECTED]">Scott Weaver</a>
* @version $Id: GenericMVCPortlet.java,v 1.11 2003/02/11 23:09:18 tkuebler Exp $
* @stereotype role
*/
public class GenericMVCPortlet extends AbstractInstancePortlet
{
// need cache timer, etc
private String viewType = "ERROR: not set in config";
private String actionName = "ERROR: not set in config";
private String template = "ERROR: not set in config";
private String configureTemplate;
private String maximizedTemplate;
private ViewProcessor processor = null;
private boolean providesCustomization;
public void init() throws PortletException
{
//STW: Added caching setUp
if (isCacheable())
{
try
{
setExpirationMillis(
Long.parseLong(
getPortletConfig().getInitParameter("cache-period-milliseconds", "0")));
}
catch (NumberFormatException e)
{
setExpirationMillis(0);
}
}
//STW: check custimization attribute
String provConf =
getPortletConfig().getInitParameter("provides.customization", "false");
providesCustomization = new Boolean(provConf).booleanValue();
// pull the important info out of the portlet config
actionName = getPortletConfig().getInitParameter("action");
// STW: Allow subclasses to set viewtype for backward compatibillity
if (getPortletConfig().getInitParameter("viewtype") != null)
{
viewType = getPortletConfig().getInitParameter("viewtype");
}
template = getPortletConfig().getInitParameter("template");
// get viewprocessor from factory
Log.info(
"GenericMVCPortlet - creating view processor for viewtype = "
+ viewType
+ ", template = "
+ template);
processor = ViewProcessorFactory.getViewProcessor(viewType);
// initialize view processor with portlet info
processor.init(this);
// should make this config file driven
// STW removed this so subclasses can decide this for
// themselves.
// setCacheable(false);
}
/**
* Whether or not this portlet provides it's own customizer.
* This can be set at the registry level by adding a
* boolean paramter "provides.customization"
* Defaults to "false"
*/
public boolean providesCustomization()
{
return providesCustomization;
}
public ConcreteElement getContent(RunData rundata)
{
//if caching is turned off or no expiration time set, generate and return
the content
if (!isCacheable() || null == getExpirationMillis())
{
return buildContent(rundata);
}
//is the cached content still valid, if not, generate and return the content
if (getExpirationMillis().longValue() <= System.currentTimeMillis())
{
return buildContent(rundata);
}
//else, the cached content is fine to be returned
return getContent(rundata, null, true);
}
protected ConcreteElement buildContent(RunData rundata)
{
// create a new context
// populate it with data
GenericMVCContext context = new
GenericMVCContext(TurbinePull.getGlobalContext());
context.put("data", rundata);
context.put("portlet", this);
context.put("conf", this.getPortletConfig());
context.put("skin", this.getPortletConfig().getPortletSkin());
context.put("template", template);
context.put("viewType", viewType);
populateRequest(rundata);
// put references to the pull tools in the context
TurbinePull.populateContext(context, rundata);
Object fTool = context.get("format");
// Initialize jlink and jslink tools with ourselves
// to enable links between portlets
Object jlink = context.get("jlink");
if (jlink instanceof JetspeedTemplateLink)
{
((JetspeedTemplateLink) jlink).setPortlet(this);
}
Object jslink = context.get("jslink");
if (jslink instanceof JetspeedLink)
{
((JetspeedLink) jslink).setPortlet(this);
}
// Handle Action
if (actionName != null)
{
try
{
// store the context so that the action can retrieve it
//Log.debug("VelocityPortlet found action "+actionName+" context
"+context);
// note: the name it is stored under is legacy, leaving it this way
// because some of the routines fall back to old default behavior
// of the velocity portlet and might depend on the name
rundata.getTemplateInfo().setTemplateContext("VelocityPortletContext", context);
if (Log.getLogger().isDebugEnabled())
{
Log.debug(
"GenericMVCPortlet: Executing action ["
+ actionName
+ "] for portlet ["
+ this.getName()
+ "]");
}
ActionLoader.getInstance().exec(rundata, actionName);
}
catch (Exception e)
{
Log.error("GenericMVCPortlet - error executing action" + e);
e.printStackTrace();
}
}
// Process View
// call processView method
Log.info("GenericMVCPortlet - calling processView on processor");
ConcreteElement result = (ConcreteElement) processor.processView(context);
Log.info("GenericMVCPortlet - setting this portlet's content");
clearContent();
setContent(result); // only needed when caching is true I believe
// return result
return result;
}
/**
* @see setViewType()
* @return String
*/
protected String getViewType()
{
return viewType;
}
/**
* STW: Added for backward compatibility when using this
* class to subclass the existing Jsp and Velocity portlets
* so they can set their view prior to super.init();
* @param viewType The viewType to set
*/
protected void setViewType(String viewType)
{
this.viewType = viewType;
}
/**
* This is called before any action execution happens.
* This provides backward compatibility to JspPortletActions
* who retreive information, like Portlet, from the request
* BEFORE the ViewProcessor.processView() is called
* which normally populates the request with Context objects.
* @author <a href="mailto:[EMAIL PROTECTED]">Scott Weaver</a>
*/
protected void populateRequest(RunData rundata)
{
HttpServletRequest request = rundata.getRequest();
request.setAttribute("data", rundata);
request.setAttribute("portlet", this);
request.setAttribute("conf", this.getPortletConfig());
request.setAttribute("skin", this.getPortletConfig().getPortletSkin());
request.setAttribute("template", template);
request.setAttribute("viewType", viewType);
}
}
1.1
jakarta-jetspeed/src/java/org/apache/jetspeed/portal/portlets/GenericMVCContext.java
Index: GenericMVCContext.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000-2001 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 acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Jetspeed" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache" or
* "Apache Jetspeed", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* 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/>.
*/
/*
* GenericMVCContext.java
*
* Created on January 27, 2003, 8:47 PM
*/
package org.apache.jetspeed.portal.portlets;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.apache.velocity.context.Context;
/**
*
* Context that holds all the data you want to transfer to your view. You
* populate this during your action handling.
* <p>
* This context also supports chaining of additional contexts. The initial
* context created by this object always has priority over an addtional
* chained objects. In short matching keys within the initial context
* will "hide" matching keys within the addtional context(s).
* </p>
*
* @author tkuebler
* @author <a href="mailto:[EMAIL PROTECTED]">Scott Weaver</a>
* @version $Id: GenericMVCContext.java,v 1.3 2003/02/05 00:32:13 tkuebler Exp $
* @stereotype thing
*
*/
/*
* Note:
*
* create the generic context interface later
* just use Velocity's for now
*
*/
public class GenericMVCContext implements Context
{
private HashMap data;
private HashSet additionalContexts;
/** Creates a new instance of GenericMVCContext */
public GenericMVCContext()
{
data = new HashMap();
additionalContexts = new HashSet();
}
/**
* Adds an existing Collection of contexts into this one.
* Externally added contexts are maintained indvidually
* and are not merged into the existing context.
* Done to facilitate the context chanining.
* @author <a href="mailto:[EMAIL PROTECTED]">Scott Weaver</a>
*/
public GenericMVCContext(Collection contexts)
{
this();
additionalContexts.addAll(contexts);
}
/**
* Adds an existing context into this one.
* Externally added contexts are maintained indvidually
* and are not merged into the existing context
* Done to facilitate the context chanining.
* @author <a href="mailto:[EMAIL PROTECTED]">Scott Weaver</a>
*/
public GenericMVCContext(Context context)
{
this();
additionalContexts.add(context);
}
public boolean containsKey(java.lang.Object key)
{
boolean found = data.containsKey(key);
if (!found)
{
Iterator itr = additionalContexts.iterator();
while (itr.hasNext() && !found)
{
found = ((Context) itr.next()).containsKey(key);
}
}
return found;
}
public Object get(java.lang.String key)
{
Object value = data.get(key);
// Proceed to search chained contexts
if (value == null)
{
Iterator itr = additionalContexts.iterator();
while (itr.hasNext() && value == null)
{
value = ((Context) itr.next()).get(key);
}
}
return value;
}
public Object[] getKeys()
{
Set keySet = data.keySet();
Iterator itr = additionalContexts.iterator();
while (itr.hasNext())
{
Object[] keys = ((Context) itr.next()).getKeys();
for (int i = 0; i < keys.length; i++)
{
keySet.add(keys[i]);
}
}
// (Object[])java.lang.reflect.Array.newInstance((new
Object()).getClass(),2);
return data.keySet().toArray();
}
public Object put(java.lang.String key, java.lang.Object value)
{
return data.put(key, value);
}
public Object remove(java.lang.Object key)
{
Object obj = data.remove(key);
if (obj == null)
{
Iterator itr = additionalContexts.iterator();
while (itr.hasNext() && obj == null)
{
obj = ((Context) itr.next()).remove(key);
}
}
return obj;
}
/**
* Add an additional context to this one
* @param Context context Additional Context object to add.
* @author <a href="mailto:[EMAIL PROTECTED]">Scott Weaver</a>
*/
public void addContext(Context context)
{
additionalContexts.add(context);
}
/**
* This Collection is "live" as it is the same Collection
* that maintains this Context's chained contexts. This
* Collection DOES NOT include objects maintained in
* the initial context.
* @return a Collection all the chained contexts
* @author <a href="mailto:[EMAIL PROTECTED]">Scott Weaver</a>-
*/
public Collection getChainedContexts()
{
return additionalContexts;
}
}
1.1
jakarta-jetspeed/src/java/org/apache/jetspeed/modules/actions/portlets/GenericMVCAction.java
Index: GenericMVCAction.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000-2001 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 acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Jetspeed" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache" or
* "Apache Jetspeed", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* 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/>.
*/
/*
* GenericMVCAction.java
*
* Created on January 29, 2003, 2:56 PM
*/
package org.apache.jetspeed.modules.actions.portlets;
import org.apache.jetspeed.portal.Portlet;
import org.apache.jetspeed.portal.PortletInstance;
import org.apache.jetspeed.portal.portlets.GenericMVCContext;
import org.apache.jetspeed.portal.portlets.GenericMVCPortlet;
import org.apache.jetspeed.services.persistence.PersistenceManager;
import org.apache.jetspeed.services.persistence.PortalPersistenceException;
import org.apache.jetspeed.services.rundata.JetspeedRunData;
import org.apache.jetspeed.util.PortletSessionState;
import org.apache.turbine.util.Log;
import org.apache.turbine.util.RunData;
import org.apache.velocity.context.Context;
/**
* Provides standard portal and MVC related action functionality. Developers
* extend this class for thier own actions and provide implementations of the
* build*Context methods apropos to thier portlet needs.
*
* @author tkuebler
* @version $Id: GenericMVCAction.java,v 1.8 2003/02/11 23:09:17 tkuebler Exp $
* @stereotype moment-interval
*/
public class GenericMVCAction
extends PortletAction
{
/** Creates a new instance of GenericMVCAction */
public GenericMVCAction()
{
// remove if empty at end of design phase
}
// override what you need to here
protected void perform(RunData rundata)
throws Exception
{
Context context = getContext(rundata);
if ((context != null) && (rundata.getParameters().getString("action") !=
null))
{
// if context is already defined and Actions defined, events
// have already been processed, call doPerform
Log.debug("Action detected with action + context");
doPerform(rundata, context);
}
else
{
// if context is null, create a new one
if (context == null)
{
Log.debug("Action: building action context");
context = new GenericMVCContext();
rundata.getTemplateInfo().setTemplateContext("VelocityActionContext", context);
}
try
{
// process implicit ActionEvent invocation
Log.debug("Action: try executing events");
GenericMVCPortlet portlet = (GenericMVCPortlet)
context.get("portlet");
if (portlet != null)
{
// verify this portlet is the one requested by checking the
// js_peid request var. If there is no js_peid
// do not worry a about verifing. helps with backward compat.
if (rundata.getParameters().getString("js_peid") == null ||
PortletSessionState.isMyRequest(rundata, portlet))
{
executeEvents(rundata, context);
}
else
{
Log.debug("Action: calling doPerform");
doPerform(rundata, context);
}
}
else
{
executeEvents(rundata, context);
}
}
catch (NoSuchMethodException e)
{
// no event selected, process normal context generation
Log.debug("Action: calling doPerform");
doPerform(rundata, context);
}
}
}
public void doPerform(RunData rundata, Context context)
throws Exception
{
GenericMVCPortlet portlet = null;
JetspeedRunData jdata = (JetspeedRunData) rundata;
Log.debug("GenericMVCAction: retrieved context: " + context);
if (context != null)
{
portlet = (GenericMVCPortlet) context.get("portlet");
}
Log.debug("GenericMVCAction: retrieved portlet: " + portlet);
if (portlet != null)
{
//System.out.println("class = " + this.getClass().getName());
//rundata.getUser().setTemp(this.getClass().getName(), portlet.getID());
// we're bein configured
if ((jdata.getMode() == jdata.CUSTOMIZE) &&
(portlet.getName().equals(jdata.getCustomized().getName())))
{
Log.debug("GenericMVCAction: building customize");
buildConfigureContext(portlet, context, rundata);
return;
}
// we're maximized
if (jdata.getMode() == jdata.MAXIMIZE)
{
Log.debug("GenericMVCAction: building maximize");
buildMaximizedContext(portlet, context, rundata);
return;
}
Log.debug("GenericMVCAction: building normal");
buildNormalContext(portlet, context, rundata);
}
}
/**
* Subclasses should override this method if they wish to
* build specific content when maximized. Default behavior is
* to do the same as normal content.
*/
protected void buildMaximizedContext(Portlet portlet, Context context, RunData
rundata)
throws Exception
{
buildNormalContext(portlet, context, rundata);
}
/**
* Subclasses should override this method if they wish to
* provide their own customization behavior.
* Default is to use Portal base customizer action
*/
protected void buildConfigureContext(Portlet portlet, Context context, RunData
rundata)
throws Exception
{
// code goes here. :)
}
/**
* Subclasses must override this method to provide default behavior
* for the portlet action
*/
protected void buildNormalContext(Portlet portlet, Context context, RunData
rundata)
throws Exception
{
}
/**
* Convenience method for retreiving this action's Portlet
* @param Context context Current context object.
* @return Portlet the Portlet for this action
* @author <a href="mailto:[EMAIL PROTECTED]">Scott Weaver</a>
*/
public Portlet getPortlet(Context context)
{
return (Portlet) context.get("portlet");
}
/**
* Convenience method for retreiving this action's PortletInstance
* @param Context context Current context object.
* @return Portlet the Portlet for this action
* @author <a href="mailto:[EMAIL PROTECTED]">Scott Weaver</a>
*/
public PortletInstance getPortletInstance(Context context)
{
return getPortlet(context).getInstance((RunData) context.get("data"));
}
/**
* Convenience method for retreiving this action's PortletInstance
* attribute.
* @param String Attribute Name
* @param Context context Current context object.
* @return String portlet attribute
* @author <a href="mailto:[EMAIL PROTECTED]">Scott Weaver</a>
*/
public String getAttribute(String attrName, Context context)
{
return getPortletInstance(context).getAttribute(attrName);
}
/**
* Convenience method for retreiving this action's PortletInstance
* attribute.
* @param String Attribute Name
* @param String Default to return if no attribute is found
* @param Context context Current context object.
* @return String portlet attribute
* @author <a href="mailto:[EMAIL PROTECTED]">Scott Weaver</a>
*/
public String getAttribute(String attrName, String defaultValue, Context context)
{
return getPortletInstance(context).getAttribute(attrName, defaultValue);
}
/**
* Convenience method for setting this action's PortletInstance
* attribute.
* @param String Attribute Name
* @param String Attribute Value
* @param Context context Current context object.
* @author <a href="mailto:[EMAIL PROTECTED]">Scott Weaver</a>
*/
public void setAttribute(String attrName, String value, Context context)
throws PortalPersistenceException
{
PortletInstance instance = getPortletInstance(context);
instance.setAttribute(attrName, value);
PersistenceManager.store(instance);
}
}
1.1
jakarta-jetspeed/src/java/org/apache/jetspeed/modules/actions/portlets/PortletAction.java
Index: PortletAction.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000-2001 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 acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Jetspeed" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache" or
* "Apache Jetspeed", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* 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/>.
*/
/*
* PortletAction.java
*
*
* $Id: PortletAction.java,v 1.8.2.1 2003/02/24 18:45:42 tkuebler Exp $
*
* Created on January 29, 2003, 2:52 PM
*/
package org.apache.jetspeed.modules.actions.portlets;
import org.apache.jetspeed.portal.Portlet;
import org.apache.turbine.util.RunData;
import org.apache.velocity.context.Context;
/**
*
* Abstract holder for the portlet specific methods required above and
* beyond the standard turbine action.
*
* Extends the PortletActionEvent, which
* encapsulates the event handling feature.
*
* @author tkuebler
* @version $Id: PortletAction.java,v 1.8.2.1 2003/02/24 18:45:42 tkuebler Exp $
* @stereotype moment-interval
*
*/
/*
* Note:
* assumes a templated portlet, maybe should break this up into two classes
* the portletaction would only have the build*Context methods
* the templatedportletaction would have the rest
* skipping this complexity for now since non-templated portlet actions can just
* extend ActionEvent and forget about the context probably
*/
public abstract class PortletAction
extends PortletActionEvent
{
/** Creates a new instance of PortletAction */
public PortletAction()
{
}
public void doPerform(RunData data)
throws Exception
{
// assumes a context for the portlet...
// should check for null and create one
doPerform(data, getContext(data));
}
/**
* You SHOULD override this method and implement it in your
* action.
*
* @param data Turbine information.
* @param context Context for web pages.
* @exception Exception, a generic exception.
*/
public abstract void doPerform(RunData data, Context context)
throws Exception;
/**
* Return the Context
*
* @param RunData data
* @return Context, a context for web pages.
*/
protected Context getContext(RunData data)
{
return (Context)
data.getTemplateInfo().getTemplateContext("VelocityPortletContext");
}
/**
* This method is used when you want to short circuit an Action
* and change the template that will be executed next.
*
* @param data Turbine information.
* @param template The template that will be executed next.
*/
public void setTemplate(RunData data, String template)
{
getContext(data).put("template", template);
}
protected abstract void buildConfigureContext(Portlet portlet, Context context,
RunData data)
throws Exception;
protected abstract void buildMaximizedContext(Portlet portlet, Context context,
RunData data)
throws Exception;
protected abstract void buildNormalContext(Portlet portlet, Context context,
RunData data)
throws Exception;
}
1.1
jakarta-jetspeed/src/java/org/apache/jetspeed/modules/actions/portlets/PortletActionEvent.java
Index: PortletActionEvent.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000-2001 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 acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Jetspeed" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache" or
* "Apache Jetspeed", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* 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/>.
*/
/*
* PortletActionEvent.java
*
* Created on January 29, 2003, 4:20 PM
*/
package org.apache.jetspeed.modules.actions.portlets;
import java.lang.reflect.Method;
import java.util.Enumeration;
import org.apache.turbine.modules.ActionEvent;
import org.apache.turbine.services.velocity.TurbineVelocity;
import org.apache.turbine.util.ParameterParser;
import org.apache.turbine.util.RunData;
import org.apache.velocity.context.Context;
/**
* Provides form based action handling via the eventSubmit_do[action] pattern.
* Works just like the mechanism described for the velocity portlet. Extends
* this convienent functionality to all GenericMVCPortlets
*
* @author tkuebler
* @version $Id: PortletActionEvent.java,v 1.3.2.1 2003/02/24 18:45:42 tkuebler Exp $
* @stereotype moment-interval
*/
public abstract class PortletActionEvent
extends ActionEvent
{
/**
* You need to implement this in your classes that extend this
* class.
*
* @param data A Turbine RunData object.
* @exception Exception, a generic exception.
*/
public abstract void doPerform(RunData data)
throws Exception;
/**
* This overrides the default Action.perform() to execute the
* doEvent() method. If that fails, then it will execute the
* doPerform() method instead.
*
* @param data A Turbine RunData object.
* @exception Exception, a generic exception.
*/
protected void perform(RunData data)
throws Exception
{
try
{
executeEvents(data, TurbineVelocity.getContext(data));
}
catch (NoSuchMethodException e)
{
doPerform(data);
}
}
/**
* This method should be called to execute the event based system.
*
* @param data A Turbine RunData object.
* @param context context information.
* @exception Exception, a generic exception.
*/
public void executeEvents(RunData data, Context context)
throws Exception
{
// Name of the button.
String theButton = null;
// ParameterParser.
ParameterParser pp = data.getParameters();
String button = pp.convert(BUTTON);
// Loop through and find the button.
for (Enumeration e = pp.keys(); e.hasMoreElements();)
{
String key = (String) e.nextElement();
if (key.startsWith(button))
{
theButton = formatString(key);
break;
}
}
if (theButton == null)
{
throw new NoSuchMethodException("ActionEvent: The button was null");
}
try
{
// The arguments to the method to find.
Class[] classes = new Class[2];
classes[0] = RunData.class;
classes[1] = Context.class;
// The arguments to pass to the method to execute.
Object[] args = new Object[2];
Method method = getClass().getMethod(theButton, classes);
args[0] = data;
args[1] = context;
method.invoke(this, args);
}
catch (NoSuchMethodException nsme)
{
// Attempt to execut things the old way..
super.executeEvents(data);
}
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]