You are viewing a plain text version of this content. The canonical link for it is here.
Posted to pluto-scm@portals.apache.org by ms...@apache.org on 2016/01/18 13:41:36 UTC

[34/35] portals-pluto git commit: Added bean portlet demo. Fixed null pointer exception in PortletParametersImpl. Fixed problem where two portlets using the same class were also using the same class instance.

Added bean portlet demo. Fixed null pointer exception in
PortletParametersImpl. Fixed problem where two portlets using the same
class were also using the same class instance.


Project: http://git-wip-us.apache.org/repos/asf/portals-pluto/repo
Commit: http://git-wip-us.apache.org/repos/asf/portals-pluto/commit/a0c6f1c9
Tree: http://git-wip-us.apache.org/repos/asf/portals-pluto/tree/a0c6f1c9
Diff: http://git-wip-us.apache.org/repos/asf/portals-pluto/diff/a0c6f1c9

Branch: refs/heads/V3Prototype
Commit: a0c6f1c90c34feb8a6fbe7858739c03986ec4b54
Parents: 43d2208
Author: Scott Nicklous <ms...@apache.org>
Authored: Sun Jan 17 19:52:40 2016 +0100
Committer: Scott Nicklous <ms...@apache.org>
Committed: Sun Jan 17 19:52:40 2016 +0100

----------------------------------------------------------------------
 .../java/basic/portlet/ColorSelPortlet.java     |   4 +-
 .../samples/CSSIncludingHeaderMethod.java       |  51 +++++++
 .../apache/portals/samples/HelloWorldImage.java | 119 ++++++++++++++++
 .../portals/samples/HelloWorldRender.java       |  60 ++++++++
 .../java/org/apache/portals/samples/Log.java    |  37 +++++
 .../portals/samples/LoggingInterceptor.java     |  70 ++++++++++
 .../org/apache/portals/samples/NameBean.java    | 138 +++++++++++++++++++
 .../src/main/webapp/WEB-INF/jsp/res-simple.jsp  |   9 ++
 .../src/main/webapp/resources/css/bluebold.css  |   4 +
 .../src/main/webapp/resources/css/infobox.css   |  19 +++
 .../main/webapp/resources/images/BabyChimp.gif  | Bin 0 -> 13652 bytes
 .../resources/images/ChimpEatingDollar.gif      | Bin 0 -> 10565 bytes
 .../images/Chimpanzee_thinking-small.gif        | Bin 0 -> 11055 bytes
 .../webapp/resources/images/bonoboMomKid.gif    | Bin 0 -> 28930 bytes
 .../driver/PortletContainerInitializer.java     |  16 +++
 .../container/impl/PortletParametersImpl.java   |   2 +-
 .../om/portlet/impl/ConfigurationProcessor.java |  19 ++-
 17 files changed, 538 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a0c6f1c9/PortletHubDemo/src/main/java/basic/portlet/ColorSelPortlet.java
----------------------------------------------------------------------
diff --git a/PortletHubDemo/src/main/java/basic/portlet/ColorSelPortlet.java b/PortletHubDemo/src/main/java/basic/portlet/ColorSelPortlet.java
index 4e3445b..80ac367 100644
--- a/PortletHubDemo/src/main/java/basic/portlet/ColorSelPortlet.java
+++ b/PortletHubDemo/src/main/java/basic/portlet/ColorSelPortlet.java
@@ -52,7 +52,7 @@ import javax.xml.namespace.QName;
 /**
  * An example color selection portlet that uses the portlet hub.
  */
-@PortletConfiguration(portletName = "ColorSelPortlet", publicParams = "color", 
+@PortletConfiguration(portletName = "PH-ColorSelPortlet", publicParams = "color", 
                       title = @LocaleString("PH Color Selection Portlet"))
 public class ColorSelPortlet extends GenericPortlet {
 
@@ -84,7 +84,7 @@ public class ColorSelPortlet extends GenericPortlet {
          throws PortletException, IOException {
    }
 
-   @ActionMethod(portletName="ColorSelPortlet", publishingEvents= {
+   @ActionMethod(portletName="PH-ColorSelPortlet", publishingEvents= {
          @PortletQName(namespaceURI="http://www.apache.org/portals/pluto/ResourcePortlet", localPart="Message")
    })
    public void processAction(ActionRequest req, ActionResponse resp)

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a0c6f1c9/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/CSSIncludingHeaderMethod.java
----------------------------------------------------------------------
diff --git a/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/CSSIncludingHeaderMethod.java b/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/CSSIncludingHeaderMethod.java
new file mode 100644
index 0000000..f5f56b6
--- /dev/null
+++ b/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/CSSIncludingHeaderMethod.java
@@ -0,0 +1,51 @@
+/*  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.samples;
+
+import java.io.IOException;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.portlet.HeaderRequest;
+import javax.portlet.HeaderResponse;
+import javax.portlet.annotations.HeaderMethod;
+
+/**
+ * Header method to include a css file.
+ */
+@ApplicationScoped
+public class CSSIncludingHeaderMethod {
+   
+   // The header method can apply to a list of portlets. If the asterisk is specified 
+   // as first portlet name, the header method is executed for all portlets in
+   // the portlet application.
+   @HeaderMethod(portletNames="*")
+   public void header(HeaderRequest req, HeaderResponse resp) throws IOException {
+
+      // Add link tag to head section to include the style sheet
+
+      String contextRoot = req.getContextPath();
+      StringBuilder txt = new StringBuilder(128);
+      txt.append("<link href='").append(contextRoot);
+      txt.append("/resources/css/styles.css' rel='stylesheet' type='text/css'>");
+      
+      resp.getWriter().write(txt.toString());
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a0c6f1c9/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/HelloWorldImage.java
----------------------------------------------------------------------
diff --git a/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/HelloWorldImage.java b/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/HelloWorldImage.java
new file mode 100644
index 0000000..870b46f
--- /dev/null
+++ b/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/HelloWorldImage.java
@@ -0,0 +1,119 @@
+/*  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.samples;
+
+import javax.inject.Inject;
+import javax.portlet.PortletRequest;
+import javax.portlet.ResourceURL;
+
+import javax.portlet.annotations.ContextPath;
+import javax.portlet.annotations.Namespace;
+import javax.portlet.annotations.RenderMethod;
+import javax.portlet.annotations.ResourceParam;
+import javax.portlet.annotations.ServeResourceMethod;
+import javax.portlet.annotations.URLFactory;
+
+/**
+ * Contains a resource method and associated markup generator to insert 
+ * an image.
+ */
+public class HelloWorldImage {
+
+   public static final String RESPARAM_DISPLAY = "display";
+   
+   // Injecting the namespace & URLFactory
+   @Inject @Namespace private String pid;
+   @Inject private            URLFactory uf;
+   
+   @Inject @ContextPath
+   String ctxPath;
+   
+   @Inject
+   PortletRequest req;
+
+   @Inject
+   NameBean nameBean;
+   
+   // Some chimp pictures to associate with a name
+   private final static String[] chimps = new String[] {
+      "/resources/images/BabyChimp.gif",
+      "/resources/images/bonoboMomKid.gif",
+      "/resources/images/Chimpanzee_thinking-small.gif",
+      "/resources/images/ChimpEatingDollar.gif"
+   };
+
+   @RenderMethod(portletNames = {"BeanPortlet"}, ordinal=100)
+   public String getImageInclude() {
+      
+      StringBuilder txt = new StringBuilder(128);
+      ResourceURL resurl = uf.createResourceURL();
+      if (nameBean.getName() != null) {
+         resurl.getResourceParameters().setValue(RESPARAM_DISPLAY, "true");
+      }
+      
+      txt.append("<div class='infobox' id='").append(pid).append("-putResourceHere'></div>\n");
+      txt.append("<script>\n");
+      txt.append("(function () {\n");
+      txt.append("   var xhr = new XMLHttpRequest();\n");
+      txt.append("   xhr.onreadystatechange=function() {\n");
+      txt.append("      if (xhr.readyState==4 && xhr.status==200) {\n");
+      txt.append("         document.getElementById('").append(pid).append("-putResourceHere').innerHTML=xhr.responseText;\n");
+      txt.append("      }\n");
+      txt.append("   };\n");
+      txt.append("   xhr.open(\"GET\",\"").append(resurl.toString()).append("\",true);\n");
+      txt.append("   xhr.send();\n");
+      txt.append("})();\n");
+      txt.append("</script>\n");
+
+      return txt.toString();
+   }
+
+   // Inject the resource parameter to see if image should be displayed.
+   @Inject @ResourceParam(RESPARAM_DISPLAY)
+   String   display;
+   
+   /**
+    *  This resource method generates some output directly, then includes output
+    *  from a JSP as specified in the annotation.
+    *  
+    * @return  The string for inclusion in the output.
+    */
+   @ServeResourceMethod(portletNames={"BeanPortlet"}, include="/WEB-INF/jsp/res-simple.jsp")
+   public String getImage() {
+      String result = "";
+      
+      // illustrate use of the injected display resource parameter
+      if (display != null) {
+         
+         // pick a chimp
+         
+         int ind = (int) (Math.random() * chimps.length);
+         String imgSrc = ctxPath + chimps[ind];
+         imgSrc = uf.encodeURL(imgSrc);
+         req.setAttribute("imgSrc", imgSrc);
+         
+         // set the output
+         
+         result = "<p>Your image appears here:</p>";
+      }
+      return result;
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a0c6f1c9/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/HelloWorldRender.java
----------------------------------------------------------------------
diff --git a/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/HelloWorldRender.java b/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/HelloWorldRender.java
new file mode 100644
index 0000000..b835d00
--- /dev/null
+++ b/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/HelloWorldRender.java
@@ -0,0 +1,60 @@
+/*  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.samples;
+
+import javax.inject.Inject;
+
+import javax.portlet.annotations.RenderMethod;
+
+/**
+ * Simple hello world bean portlet
+ */
+public class HelloWorldRender {
+   
+   // This is an @PortletStateScoped bean containing the name 
+   // entered through the form.
+   @Inject
+   private NameBean nameBean;
+
+   /**
+    * Bean portlet render method for "BeanHelloWorld" portlet.
+    */
+   @RenderMethod(portletNames = {"BeanPortlet"})
+   public String methodName() {
+      
+      // In it's simplest form, the render method just returns text.
+      // The content type is set through the annotation.
+      
+      StringBuilder txt = new StringBuilder(128);
+      
+      txt.append("<h3>Hello ");
+      
+      // Get the name from the bean. If it hasn't been set, just greet the world.
+      if (nameBean.getName() != null) {
+         txt.append(nameBean.getName());
+      } else {
+         txt.append("World");
+      }
+      txt.append("!!</h3>");
+      
+      return txt.toString();
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a0c6f1c9/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/Log.java
----------------------------------------------------------------------
diff --git a/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/Log.java b/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/Log.java
new file mode 100644
index 0000000..5242c98
--- /dev/null
+++ b/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/Log.java
@@ -0,0 +1,37 @@
+/*  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.samples;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.interceptor.InterceptorBinding;
+
+/**
+ * Annotation defining an interceptor binding for logging
+ * 
+ * @author nick
+ */
+@Inherited
+@InterceptorBinding
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE, ElementType.METHOD})
+public @interface Log {}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a0c6f1c9/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/LoggingInterceptor.java
----------------------------------------------------------------------
diff --git a/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/LoggingInterceptor.java b/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/LoggingInterceptor.java
new file mode 100644
index 0000000..13905a3
--- /dev/null
+++ b/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/LoggingInterceptor.java
@@ -0,0 +1,70 @@
+/*  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.samples;
+
+import java.io.Serializable;
+import java.util.logging.Logger;
+
+import javax.interceptor.AroundInvoke;
+import javax.interceptor.Interceptor;
+import javax.interceptor.InvocationContext;
+
+/**
+ * Interceptor to provide logging for our project
+ * 
+ * @author Scott Nicklous
+ */
+@Interceptor
+@Log
+public class LoggingInterceptor implements Serializable {
+
+   private static final long serialVersionUID = -73481963162413796L;
+
+   private static final Logger logger = Logger.getLogger(LoggingInterceptor.class.getCanonicalName());
+
+   /**
+    * Method called for use as an interceptor. Called before the intercepted method is 
+    * called. 
+    * 
+    * @param ic
+    * @return
+    * @throws Exception
+    */
+   @AroundInvoke
+   public Object log(InvocationContext ic) throws Exception {
+
+      String cls = ic.getMethod().getDeclaringClass().getCanonicalName();
+      String meth = ic.getMethod().getName();
+      
+      // Log method entry
+      Logger mlogger = Logger.getLogger(cls);
+      mlogger.entering(cls, meth);
+      
+      // Continue through chain until actual bean method is executed
+      Object obj = ic.proceed(); 
+   
+      // this logging statement is only for debugging.
+      logger.fine("Method " + meth + " has been called.");
+      
+      // Now log the exit
+      mlogger.exiting(cls, meth);
+
+      return obj;
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a0c6f1c9/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/NameBean.java
----------------------------------------------------------------------
diff --git a/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/NameBean.java b/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/NameBean.java
new file mode 100644
index 0000000..25dd88e
--- /dev/null
+++ b/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/NameBean.java
@@ -0,0 +1,138 @@
+/*  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.samples;
+
+import java.io.IOException;
+
+import javax.inject.Inject;
+import javax.portlet.ActionRequest;
+import javax.portlet.ActionResponse;
+import javax.portlet.PortletException;
+import javax.portlet.PortletURL;
+
+import javax.portlet.annotations.ActionMethod;
+import javax.portlet.annotations.ActionParam;
+import javax.portlet.annotations.Namespace;
+import javax.portlet.annotations.PortletSerializable;
+import javax.portlet.annotations.PortletStateScoped;
+import javax.portlet.annotations.RenderMethod;
+import javax.portlet.annotations.URLFactory;
+import javax.portlet.MimeResponse.Copy;
+
+/**
+ * Portlet state scoped bean. The bean is stored as a render parameter,
+ * so it needs to be portlet serializable.
+ */
+@PortletStateScoped
+public class NameBean implements PortletSerializable {
+   
+   // Inject the portlet namespace 
+   @Inject @Namespace private String pid;
+   
+   // Inject the URLFactory to allow URL creation
+   @Inject private            URLFactory uf;
+   
+   private final static String PARAM_NAME = "name";
+
+   //========== bean state in this block =======================
+   private String name;
+   //===========================================================
+
+   @Inject @ActionParam(PARAM_NAME)
+   private String apName;
+
+   // getters & setters
+   //================
+   public String getName() {
+      return name;
+   }
+
+   public void setName(String name) {
+      this.name = name;
+   }
+   //================
+   
+   
+   /**
+    * writes the action form as string. This method is placed within the bean 
+    * to allow easier access to form state data, which might be part of the bean
+    * state, but not part of the bean public API.  
+    * 
+    * @return the action form as string
+    */
+   @RenderMethod(portletNames = {"BeanPortlet"}, ordinal=200)
+   public String getActionForm() {
+      StringBuilder txt = new StringBuilder(128);
+      
+      PortletURL aurl = uf.createActionURL(Copy.ALL);
+      txt.append("<FORM id='").append(pid).append("-setParams' METHOD='POST' ACTION='").append(aurl);
+      txt.append("' enctype='application/x-www-form-urlencoded' accept-charset='UTF-8'>");
+      txt.append("   <table><tr><td align='left'>");
+      txt.append("   Enter your name:");
+      txt.append("   </td><td>");
+      txt.append("   <input name='").append(PARAM_NAME);
+      txt.append("' type='text' value='").append((name == null) ? "" : name);
+      txt.append("' size='50' maxlength='50'>");
+      txt.append("   <input type='hidden' name='").append(ActionRequest.ACTION_NAME);
+      txt.append("' value='setName'>");
+      txt.append("   </td></tr><tr><td>");
+      txt.append("   <INPUT VALUE='send' TYPE='submit'>");
+      txt.append("   </td></tr></table>");
+      txt.append("</FORM>");
+
+      return txt.toString();
+   }
+   
+   /**
+    * Bean portlet action method for the "BeanHelloWorld" portlet.
+    * Since the submitted form contains a hidden field with the action 
+    * name set to "setName", the portlet container routes the request
+    * to exactly this method.
+    */
+   @ActionMethod(portletName = "BeanPortlet", actionName="setName")
+   public void setName(ActionRequest req, ActionResponse resp)
+         throws PortletException, IOException {
+      // The action parameter is injected, so just need to check it or
+      // in this case, copy it to the state. Note that you can't inject directly 
+      // into the state, since the injection is performed before the deserialization.
+      name = apName;
+   }
+
+   /**
+    * This method is called by the portlet container to 
+    * initialize the bean at the beginning of a request.
+    */
+   @Override
+   public void deserialize(String[] state) {
+      if (state.length == 1) {
+         name = state[0];
+      }
+   }
+
+   /**
+    * Called by the portlet container at the end of an action or event request
+    * to store the serialized data as a portlet render parameter.
+    */
+   @Override
+   public String[] serialize() {
+      return new String[] {name};
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a0c6f1c9/PortletV3AnnotatedDemo/src/main/webapp/WEB-INF/jsp/res-simple.jsp
----------------------------------------------------------------------
diff --git a/PortletV3AnnotatedDemo/src/main/webapp/WEB-INF/jsp/res-simple.jsp b/PortletV3AnnotatedDemo/src/main/webapp/WEB-INF/jsp/res-simple.jsp
new file mode 100644
index 0000000..e182a58
--- /dev/null
+++ b/PortletV3AnnotatedDemo/src/main/webapp/WEB-INF/jsp/res-simple.jsp
@@ -0,0 +1,9 @@
+<%@ page session="false" %>
+<%@ taglib uri="http://java.sun.com/portlet_2_0"  prefix="portlet" %>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
+
+<portlet:defineObjects />
+
+<c:if test="${imgSrc != null}">
+   <img src="${imgSrc}" style='border:1px solid blue;' >
+</c:if>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a0c6f1c9/PortletV3AnnotatedDemo/src/main/webapp/resources/css/bluebold.css
----------------------------------------------------------------------
diff --git a/PortletV3AnnotatedDemo/src/main/webapp/resources/css/bluebold.css b/PortletV3AnnotatedDemo/src/main/webapp/resources/css/bluebold.css
new file mode 100644
index 0000000..847c8d6
--- /dev/null
+++ b/PortletV3AnnotatedDemo/src/main/webapp/resources/css/bluebold.css
@@ -0,0 +1,4 @@
+.bluebold {
+	color:#00A; 
+	font: bold;
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a0c6f1c9/PortletV3AnnotatedDemo/src/main/webapp/resources/css/infobox.css
----------------------------------------------------------------------
diff --git a/PortletV3AnnotatedDemo/src/main/webapp/resources/css/infobox.css b/PortletV3AnnotatedDemo/src/main/webapp/resources/css/infobox.css
new file mode 100644
index 0000000..e38c4e9
--- /dev/null
+++ b/PortletV3AnnotatedDemo/src/main/webapp/resources/css/infobox.css
@@ -0,0 +1,19 @@
+.infobox {
+   border-style:solid; 
+   border-width:2px; 
+   padding:4px; 
+   margin-bottom:10px;
+   overflow:auto;
+   border-color:#000088; 
+   background:#E0E0FF;
+}
+
+.parmbox {
+   border-style:solid; 
+   border-width:2px; 
+   padding:4px; 
+   margin:3px;
+   overflow:auto;
+   border-color:#008800; 
+   background:#E0FFE0;
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a0c6f1c9/PortletV3AnnotatedDemo/src/main/webapp/resources/images/BabyChimp.gif
----------------------------------------------------------------------
diff --git a/PortletV3AnnotatedDemo/src/main/webapp/resources/images/BabyChimp.gif b/PortletV3AnnotatedDemo/src/main/webapp/resources/images/BabyChimp.gif
new file mode 100644
index 0000000..16513c0
Binary files /dev/null and b/PortletV3AnnotatedDemo/src/main/webapp/resources/images/BabyChimp.gif differ

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a0c6f1c9/PortletV3AnnotatedDemo/src/main/webapp/resources/images/ChimpEatingDollar.gif
----------------------------------------------------------------------
diff --git a/PortletV3AnnotatedDemo/src/main/webapp/resources/images/ChimpEatingDollar.gif b/PortletV3AnnotatedDemo/src/main/webapp/resources/images/ChimpEatingDollar.gif
new file mode 100644
index 0000000..000879f
Binary files /dev/null and b/PortletV3AnnotatedDemo/src/main/webapp/resources/images/ChimpEatingDollar.gif differ

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a0c6f1c9/PortletV3AnnotatedDemo/src/main/webapp/resources/images/Chimpanzee_thinking-small.gif
----------------------------------------------------------------------
diff --git a/PortletV3AnnotatedDemo/src/main/webapp/resources/images/Chimpanzee_thinking-small.gif b/PortletV3AnnotatedDemo/src/main/webapp/resources/images/Chimpanzee_thinking-small.gif
new file mode 100644
index 0000000..5a11b72
Binary files /dev/null and b/PortletV3AnnotatedDemo/src/main/webapp/resources/images/Chimpanzee_thinking-small.gif differ

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a0c6f1c9/PortletV3AnnotatedDemo/src/main/webapp/resources/images/bonoboMomKid.gif
----------------------------------------------------------------------
diff --git a/PortletV3AnnotatedDemo/src/main/webapp/resources/images/bonoboMomKid.gif b/PortletV3AnnotatedDemo/src/main/webapp/resources/images/bonoboMomKid.gif
new file mode 100644
index 0000000..f89dcb1
Binary files /dev/null and b/PortletV3AnnotatedDemo/src/main/webapp/resources/images/bonoboMomKid.gif differ

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a0c6f1c9/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java
----------------------------------------------------------------------
diff --git a/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java b/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java
index e48566f..5861889 100644
--- a/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java
+++ b/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java
@@ -19,12 +19,15 @@
 package org.apache.pluto.container.driver;
 
 import java.io.InputStream;
+import java.util.EnumSet;
 import java.util.Set;
 
 import javax.portlet.annotations.PortletApplication;
 import javax.portlet.annotations.PortletConfiguration;
 import javax.portlet.annotations.PortletConfigurations;
 import javax.portlet.annotations.PortletRequestFilter;
+import javax.servlet.DispatcherType;
+import javax.servlet.FilterRegistration;
 import javax.servlet.ServletContainerInitializer;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
@@ -157,6 +160,19 @@ public class PortletContainerInitializer implements ServletContainerInitializer
                sr.setLoadOnStartup(100);
 
             }
+            
+            // Add the cross-context filter & terminal listener
+            
+            FilterRegistration.Dynamic fr = ctx.addFilter("WeldCrossContextFilter", "org.jboss.weld.servlet.WeldCrossContextFilter");
+            EnumSet<DispatcherType> dt = EnumSet.noneOf(DispatcherType.class);
+            dt.add(DispatcherType.FORWARD);
+            dt.add(DispatcherType.INCLUDE);
+            dt.add(DispatcherType.ERROR);
+            fr.addMappingForUrlPatterns(dt, false, "/*");
+            
+            ctx.addListener("org.jboss.weld.servlet.WeldTerminalListener");
+
+            LOG.debug("Completed deployment of servlets & filters for context: " + ctx.getContextPath());
 
          } else {
             LOG.debug("No portlet definitions for context: " + ctx.getServletContextName());

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a0c6f1c9/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletParametersImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletParametersImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletParametersImpl.java
index 938a4a5..cd0d27d 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletParametersImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletParametersImpl.java
@@ -126,7 +126,7 @@ public abstract class PortletParametersImpl implements PortletParameters {
     */
    public String[] getValues(String name) {
       checkNull("name", name);
-      String[] vals = params.get(name).clone();
+      String[] vals = (params.get(name) == null) ? null : params.get(name).clone();
       if (isTrace) {
          LOGGER.debug("Name: " + name + ", Values: " + Arrays.toString(vals));
       }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a0c6f1c9/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java
index 92c2803..40e16f4 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java
@@ -378,15 +378,18 @@ public abstract class ConfigurationProcessor {
     */
    public void reconcileBeanConfig(AnnotatedMethodStore ams) {
       
+      Set<String> portletNames = ams.getPortletNames();
+      // the wildcard is only in the store for display / debug purposes. don't reconcile.
+      portletNames.remove("*");     
       if (isDebug) {
          StringBuilder txt = new StringBuilder();
-         txt.append("Beginning reconciliation. Annotated portlets: ").append(ams.getPortletNames().toString());
+         txt.append("Beginning reconciliation. Annotated portlets: ").append(portletNames.toString());
          LOG.debug(txt.toString());
       }
 
       ams.setDefaultNamespace(pad.getDefaultNamespace());
       
-      for (String pn : ams.getPortletNames()) {
+      for (String pn : portletNames) {
          
          PortletDefinition pd = pad.getPortlet(pn);
          if (pd == null) {
@@ -478,19 +481,19 @@ public abstract class ConfigurationProcessor {
             StringBuilder txt = new StringBuilder(128);
             BeanManager bm = ams.getBeanMgr();
             if (bm == null) {
-               txt.append("Could not instantiate portlet class. Bean manager is null.");
+               txt.append("Could not get portlet bean. Bean manager is null.");
             } else {
                Set<Bean<?>> beans = bm.getBeans(cls);
                if (beans == null || beans.size() == 0) {
-                  txt.append("Could not instantiate portlet class. No beans found.");
+                  txt.append("Could not get portlet bean. No beans found.");
                } else {
                   Bean<?> bean = bm.resolve(beans);
                   if (bean == null) {
-                     txt.append("Could not instantiate portlet class. Could not resolve bean.");
+                     txt.append("Could not get portlet bean. Could not resolve bean.");
                   } else {
                      instance = bm.getReference(bean, bean.getBeanClass(), bm.createCreationalContext(bean));
                      if (instance == null) {
-                        txt.append("Could not instantiate portlet class. Could not get bean instance.");
+                        txt.append("Could not get portlet bean. Could not get bean instance.");
                      }
                   }
                }
@@ -620,7 +623,9 @@ public abstract class ConfigurationProcessor {
       if (isDebug) {
          StringBuilder txt = new StringBuilder();
          txt.append("Finished reconciling bean config. ");
-         txt.append("Resulting portlet list: ").append(ams.getPortletNames().toString());
+         Set<String> finalNames = ams.getPortletNames();
+         finalNames.remove("*");    // don't display wildcard
+         txt.append("Resulting portlet list: ").append(finalNames.toString());
          LOG.debug(txt.toString());
       }