Ken,
If this works, I would like to get this change as well. Also you have
sent me MultipleListDataProvider.jar before, please let me know when all
these are in and then I would rebuild jsftemplating.jar and use it in my
app.
thanks
Karam
Ken Paulsen wrote:
>
> Hi Anissa,
>
> Can you please test out the attached TableRowGroupFactory.java change
> to see if this meets your needs? I logged the message at the "CONFIG"
> level. So in order to see this message you will need to set the
> "com.sun.jsftemplating" logger to "CONFIG". This can be done via our
> GUI without restarting by going to the Log Levels page and adding a
> Property "com.sun.jsftemplating" with value "CONFIG".
>
> If this works feel free to check it in, or I can do this.
>
> Thanks!
>
> Ken
>
> anilam_at_dev.java.net wrote:
>> TableRowGroupFactory shouldn't throw exception when List is null:
>> https://jsftemplating.dev.java.net/issues/show_bug.cgi?id=6
>> Issue #|6
>> Summary|TableRowGroupFactory shouldn't throw
>> exception when Li
>> |st is null
>> Component|jsftemplating
>> Version|current
>> Platform|Linux
>> OS/Version|All
>> URL|
>> Status|NEW
>> Status whiteboard|
>> Keywords|
>> Resolution|
>> Issue type|ENHANCEMENT
>> Priority|P2
>> Subcomponent|Component Factories
>> Assigned to|kenpaulsen
>> Reported by|anilam
>>
>>
>>
>>
>>
>>
>> ------- Additional comments from anilam_at_dev.java.net Fri Jan 26
>> 17:02:31 +0000 2007 -------
>> In a handler for generating the list to be used as the input to the
>> TableRowGroupFractory, very often there may be
>> exception thrown. If the application code doesn't catch the
>> exception or catching the exception but 'forget' to return
>> an empty list as the handler output, which will be passed to the
>> Factory, JSFTemplating throws exception which prevents
>> the page to be displayed at all.
>> It will be a lot helpful if jsftemplating can just LOG the SEVERE
>> message that a NULL is passed to the factory, and
>> treat that NULl as en empty list. This way, the table is at least
>> showed as an empty table.
>>
>> Here is the exception thrown:
>> [#|2007-01-26T08:49:17.356-0800|SEVERE|sun-appserver9.1|javax.enterprise.system.container.web|_ThreadID=12;_ThreadName=httpSSLWorkerThread-8080-2;_RequestID=aad70e12-38b3-41f1-bf2b-764be5452495;|StandardWrapperValve[FacesServlet]:
>>
>> PWC1406: Servlet.service() for servlet FacesServlet threw exception
>> java.lang.IllegalArgumentException: TableRowGroupFactory expects a
>> List<List<Object>>. Where the outer List should be a
>> List of sources, and the inner List should be a List of rows.
>> However, the following was passed in: List<(null)>.
>> at
>> com.sun.jsftemplating.component.factory.sun.TableRowGroupFactory.create(TableRowGroupFactory.java:88)
>>
>> at
>> com.sun.jsftemplating.component.ComponentUtil.createChildComponent(ComponentUtil.java:401)
>>
>> at
>> com.sun.jsftemplating.layout.descriptors.LayoutComponent.getChild(LayoutComponent.java:273)
>>
>> at
>> com.sun.jsftemplating.layout.LayoutViewHandler.buildUIComponentTree(LayoutViewHandler.java:345)
>>
>> at
>> com.sun.jsftemplating.layout.LayoutViewHandler.buildUIComponentTree(LayoutViewHandler.java:360)
>>
>> at
>> com.sun.jsftemplating.layout.LayoutViewHandler.buildUIComponentTree(LayoutViewHandler.java:360)
>>
>> at
>> com.sun.jsftemplating.layout.LayoutViewHandler.buildUIComponentTree(LayoutViewHandler.java:360)
>>
>> at
>> com.sun.jsftemplating.layout.LayoutViewHandler.buildUIComponentTree(LayoutViewHandler.java:360)
>>
>> at
>> com.sun.jsftemplating.layout.LayoutViewHandler.buildUIComponentTree(LayoutViewHandler.java:360)
>>
>> at
>> com.sun.jsftemplating.layout.LayoutViewHandler.createView(LayoutViewHandler.java:177)
>>
>> at
>> com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:196)
>>
>> at
>> com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:248)
>>
> ------------------------------------------------------------------------
>
> /*
> * The contents of this file are subject to the terms
> * of the Common Development and Distribution License
> * (the License). You may not use this file except in
> * compliance with the License.
> *
> * You can obtain a copy of the license at
> * https://jsftemplating.dev.java.net/cddl1.html or
> * jsftemplating/cddl1.txt.
> * See the License for the specific language governing
> * permissions and limitations under the License.
> *
> * When distributing Covered Code, include this CDDL
> * Header Notice in each file and include the License file
> * at jsftemplating/cddl1.txt.
> * If applicable, add the following below the CDDL Header,
> * with the fields enclosed by brackets [] replaced by
> * you own identifying information:
> * "Portions Copyrighted [year] [name of copyright owner]"
> *
> * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
> */
> package com.sun.jsftemplating.component.factory.sun;
>
> import com.sun.jsftemplating.annotation.UIComponentFactory;
> import com.sun.jsftemplating.component.factory.ComponentFactoryBase;
> import com.sun.jsftemplating.layout.descriptors.LayoutComponent;
> import com.sun.jsftemplating.util.LogUtil;
> import com.sun.jsftemplating.util.Util;
>
> import java.lang.reflect.InvocationTargetException;
> import java.util.List;
> import java.util.Map;
>
> import javax.faces.component.UIComponent;
> import javax.faces.context.FacesContext;
>
>
> /**
> * <p> This factory is responsible for instantiating a <code>TableRowGroup
> * UIComponent</code>.</p>
> *
> * <p> The {_at_link com.sun.jsftemplating.layout.descriptors.ComponentType}
> * id for this factory is: "sun:tableRowGroup".</p>
> *
> * @author Ken Paulsen (ken.paulsen_at_sun.com)
> */
> @UIComponentFactory("sun:tableRowGroup")
> public class TableRowGroupFactory extends ComponentFactoryBase {
>
> /**
> * <p> This is the factory method responsible for creating the
> * <code>UIComponent</code>.</p>
> *
> * @param context The <code>FacesContext</code>
> * @param descriptor The {_at_link LayoutComponent} descriptor associated
> * with the requested <code>UIComponent</code>.
> * @param parent The parent <code>UIComponent</code>
> *
> * @return The newly created <code>TableRowGroup</code>.
> */
> public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) {
> // Create the UIComponent
> UIComponent comp = context.getApplication().createComponent(COMPONENT_TYPE);
>
> // This needs to be done here (before setOptions) so that $...{...}
> // expressions can be resolved... may want to defer these?
> if (parent != null) {
> addChild(context, descriptor, parent, comp);
> }
>
> // Set all the attributes / properties
> setOptions(context, descriptor, comp);
>
> // Handle "data" option specially...
> Object data = descriptor.getEvaluatedOption(context, "data", comp);
> if (data != null) {
> // Create a DataProvider
> if (!(data instanceof List)) {
> throw new IllegalArgumentException("TableRowGroupFactory "
> + "only supports values of type \"java.util.List\" "
> + "for the 'data' attribute.");
> }
> if ((((List) data).size() > 0) &&
> !(((List) data).get(0) instanceof List)) {
> Object obj = ((List) data).get(0);
> if (obj == null) {
> if (LogUtil.configEnabled()) {
> LogUtil.config("WEBUI0008");
> }
> } else {
> obj = obj.getClass().getName();
> // We don't have a List of List of Object!
> throw new IllegalArgumentException("TableRowGroupFactory "
> + "expects a List<List<Object>>. Where the outer "
> + "List should be a List of sources, and the inner"
> + " List should be a List of rows. However, the "
> + "following was passed in: List<" + obj + ">.");
> }
> }
> List<List<Object>> lists = (List<List<Object>>) data;
> Object dataProvider = createDataProvider(lists);
>
> // Remove the data object from the UIComponent, not needed
> Map<String, Object> atts = comp.getAttributes();
> atts.remove("data");
> // FIXME: This stores the *data* in the UIComponent... change to use a #{} value binding to push the data somewhere else. Session?? Configurable?
> atts.put("sourceData", dataProvider);
> }
>
> // Return the component
> return comp;
> }
>
> /**
> * <p> This is a factory method for creating an appropriate
> * DataProvider.</p>
> */
> private Object createDataProvider(List<List<Object>> data) {
> // Use reflection (for now) to avoid a build dependency
> // Find the Option constuctor...
> try {
> return Util.getClassLoader(data).
> // loadClass("com.sun.data.provider.impl.ObjectListDataProvider").
> loadClass("com.sun.enterprise.tools.admingui.dataprovider.MultipleListDataProvider").
> getConstructor(List.class, Boolean.TYPE).
> newInstance(data, false);
> } catch (ClassNotFoundException ex) {
> throw new RuntimeException("Unable to find DataProvider API's! "
> + "Ensure dataprovider.jar is present.", ex);
> } catch (NoSuchMethodException ex) {
> throw new RuntimeException("Unable to create DataProvider! "
> + "Ensure correct dataprovider.jar is present.", ex);
> } catch (InstantiationException ex) {
> throw new RuntimeException("Unable to create DataProvider! "
> + "Ensure correct dataprovider.jar is present.", ex);
> } catch (IllegalAccessException ex) {
> throw new RuntimeException("Unable to create DataProvider! "
> + "Ensure correct dataprovider.jar is accessible.", ex);
> } catch (InvocationTargetException ex) {
> throw new RuntimeException("Unable to create DataProvider!", ex);
> }
> }
>
> /**
> * <p> The <code>UIComponent</code> type that must be registered in the
> * <code>faces-config.xml</code> file mapping to the UIComponent class
> * to use for this <code>UIComponent</code>.</p>
> */
> public static final String COMPONENT_TYPE = "com.sun.webui.jsf.TableRowGroup";
> }
>