I don't think that anyone will port your complete code and give you a
complete solution ;)

The biggest problem is AFAIR that the renderer implementations are not in
the API packages. So you have to rebuild all this functionality without
dependencies to the Impl.

e.g.
Attribute,AttributeManager -> String[] with attribute namens
Move all the utils functions to your own code (Util.componentIsDisabled,
RenderKitUtils.getSelectItems. etc.)

The most code doesn't really depent on the IMPL code.


2014-02-13 12:44 GMT+01:00 Rene Perschon <chummer_r...@gmx.net>:

> Hi everyone!
>
> I'm currently migrating an application from Glassfish 3.1.1 to TomEE. Now
> the problem is that this application contains a custom component which was
> unfortunately coded with hard dependencies on com.sun.faces classes (maven
> dependency jsf-impl).
>
> Now my question is how can i port this component in such a way that it is
> independent from any concrete JSF implementation (or at least in such a way
> that it works with MyFaces).
>
> Here's the component:
>
> import java.io.IOException;
> import java.util.Iterator;
> import java.util.Map;
>
> import javax.faces.component.UIComponent;
> import javax.faces.component.UINamingContainer;
> import javax.faces.component.ValueHolder;
> import javax.faces.context.FacesContext;
> import javax.faces.context.ResponseWriter;
> import javax.faces.convert.Converter;
> import javax.faces.model.SelectItem;
> import javax.faces.model.SelectItemGroup;
>
> import com.sun.faces.renderkit.Attribute;
> import com.sun.faces.renderkit.AttributeManager;
> import com.sun.faces.renderkit.RenderKitUtils;
> import com.sun.faces.renderkit.html_basic.MenuRenderer;
> import com.sun.faces.util.RequestStateManager;
> import com.sun.faces.util.Util;
>
> /**
>  * {@inheritDoc}.
>  */
> public class CustomSelectManyCheckboxListRenderer extends MenuRenderer
> {
>     /** {@inheritDoc}. */
>     private static final Attribute[] ATTRIBUTES =
> AttributeManager.getAttributes(AttributeManager.Key.SELECTMANYCHECKBOX);
>     /** Representing the border string. */
>     private static final String BORDER = "border";
>     /** Representing the tr string. */
>     private static final String TR = "tr";
>     /** Representing the td string. */
>     private static final String TD = "td";
>     /** Representing the label string. */
>     private static final String LABEL = "label";
>     /** Representing the newline string. */
>     private static final String NEWLINE = "\n";
>     /** Representing the tab string. */
>     private static final String TAB = "\t";
>     /** Representing the class string. */
>     private static final String CLASS = "class";
>     /** Representing the style string. */
>     private static final String STYLE = "style";
>     /** Representing the valign string. */
>     private static final String VALIGN = "valign";
>
>
>     // ---------------------------------------------------------- Public
> Methods
>
>
>     @Override
>     public void encodeEnd(FacesContext context, UIComponent component)
> throws IOException
>     {
>
>         rendererParamsNotNull(context, component);
>
>         if (!shouldEncode(component))
>         {
>             return;
>         }
>
>         ResponseWriter writer = context.getResponseWriter();
>         assert (writer != null);
>
>         String alignStr;
>         Object borderObj;
>         boolean alignVertical = false;
>         int border = 0;
>
>
>
>         if (null != component.getAttributes().get("layout"))
>         {
>             alignStr = (String) component.getAttributes().get("layout");
>             alignVertical = alignStr.equalsIgnoreCase("pageDirection");
>         }
>
>         if (null != component.getAttributes().get(BORDER))
>         {
>             borderObj = component.getAttributes().get(BORDER);
>             border = (Integer) borderObj;
>         }
>
>         Converter converter = null;
>         if (component instanceof ValueHolder)
>         {
>             converter = ((ValueHolder)component).getConverter();
>         }
>
>         renderBeginText(component, border, alignVertical, context, true);
>
>         Iterator<SelectItem> items =
>               RenderKitUtils.getSelectItems(context, component);
>
>         Object currentSelections = getCurrentSelectedValues(component);
>         Object[] submittedValues = getSubmittedSelectedValues(component);
>         Map<String, Object> attributes = component.getAttributes();
>         OptionComponentInfo optionInfo =
>               new OptionComponentInfo((String)
> attributes.get("disabledClass"),
>                                       (String)
> attributes.get("enabledClass"),
>                                       (String)
> attributes.get("unselectedClass"),
>                                       (String)
> attributes.get("selectedClass"),
>                                       Util.componentIsDisabled(component),
>                                       isHideNoSelection(component));
>         int idx = -1;
>         while (items.hasNext())
>         {
>             SelectItem curItem = items.next();
>             idx++;
>             // If we come across a group of options, render them as a
> nested
>             // table.
>             if (curItem instanceof SelectItemGroup)
>             {
>                 // write out the label for the group.
>                 if (curItem.getLabel() != null)
>                 {
>                     if (alignVertical)
>                     {
>                         writer.startElement(TR, component);
>                     }
>                     writer.startElement(TD, component);
>                     writer.writeText(curItem.getLabel(), component, LABEL);
>                     writer.endElement(TD);
>                     if (alignVertical)
>                     {
>                         writer.endElement(TR);
>                     }
>
>                 }
>                 if (alignVertical)
>                 {
>                     writer.startElement(TR, component);
>                 }
>                 writer.startElement(TD, component);
>                 writer.writeText(NEWLINE, component, null);
>                 renderBeginText(component, 0, alignVertical,
>                                 context, false);
>                 // render options of this group.
>                 SelectItem[] itemsArray =
>                       ((SelectItemGroup) curItem).getSelectItems();
>                 for (int i = 0; i < itemsArray.length; ++i)
>                 {
>                     renderOption(context,
>                                  component,
>                                  converter,
>                                  itemsArray[i],
>                                  currentSelections,
>                                  submittedValues,
>                                  alignVertical,
>                                  i,
>                                  optionInfo);
>                 }
>                 renderEndText(component, alignVertical, context);
>                 writer.endElement(TD);
>                 if (alignVertical)
>                 {
>                     writer.endElement(TR);
>                     writer.writeText(NEWLINE, component, null);
>                 }
>             }
>             else
>             {
>                 renderOption(context,
>                              component,
>                              converter,
>                              curItem,
>                              currentSelections,
>                              submittedValues,
>                              alignVertical,
>                              idx,
>                              optionInfo);
>             }
>         }
>
>         renderEndText(component, alignVertical, context);
>
>     }
>
>     // ------------------------------------------------------- Protected
> Methods
>
>
>     /**
>      * {@inheritDoc}
>      */
>     @Override
>     protected boolean isBehaviorSource(FacesContext ctx,
>                                        String behaviorSourceId,
>                                        String componentClientId)
>     {
>
>         if (behaviorSourceId == null)
>         {
>             return false;
>         }
>         char sepChar = UINamingContainer.getSeparatorChar(ctx);
>         String actualBehaviorId =
>               behaviorSourceId.substring(0,
> behaviorSourceId.lastIndexOf(sepChar));
>         return (actualBehaviorId.equals(componentClientId));
>
>     }
>
>     /**
>      * {@inheritDoc}
>      */
>     protected void renderBeginText(UIComponent component, int border,
>                                    boolean alignVertical, FacesContext
> context,
>                                    boolean outerTable) throws IOException
>         {
>         ResponseWriter writer = context.getResponseWriter();
>         assert (writer != null);
>
>         writer.startElement("table", component);
>         if (border != Integer.MIN_VALUE)
>         {
>             writer.writeAttribute(BORDER, border, BORDER);
>         }
>
>         // render style and styleclass attribute on the outer table
> instead of
>         // rendering it as pass through attribute on every option in the
> list.
>         if (outerTable)
>         {
>             // render "id" only for outerTable.
>             if (shouldWriteIdAttribute(component))
>             {
>                 writeIdAttributeIfNecessary(context, writer, component);
>             }
>             String styleClass = (String) component.getAttributes().get(
>                   "styleClass");
>             String style = (String) component.getAttributes().get(STYLE);
>             if (styleClass != null)
>             {
>                 writer.writeAttribute(CLASS, styleClass, CLASS);
>             }
>             if (style != null)
>             {
>                 writer.writeAttribute(STYLE, style, STYLE);
>             }
>         }
>         writer.writeText(NEWLINE, component, null);
>
>         if (!alignVertical)
>         {
>             writer.writeText(TAB, component, null);
>             writer.startElement(TR, component);
>             writer.writeText(NEWLINE, component, null);
>         }
>
>     }
>
>     /**
>      * {@inheritDoc}
>      */
>     protected void renderEndText(UIComponent component,
>                                  boolean alignVertical,
>                                  FacesContext context) throws IOException
>     {
>
>         ResponseWriter writer = context.getResponseWriter();
>         assert (writer != null);
>
>         if (!alignVertical)
>         {
>             writer.writeText(TAB, component, null);
>             writer.endElement(TR);
>             writer.writeText(NEWLINE, component, null);
>         }
>         writer.endElement("table");
>
>     }
>
>     /**
>      * {@inheritDoc}
>      */
>     protected void renderOption(FacesContext context,
>                                 UIComponent component,
>                                 Converter converter,
>                                 SelectItem curItem,
>                                 Object currentSelections,
>                                 Object[] submittedValues,
>                                 boolean alignVertical,
>                                 int itemNumber,
>                                 OptionComponentInfo optionInfo) throws
> IOException
>         {
>
>         String valueString = getFormattedValue(context, component,
>                                                curItem.getValue(),
> converter);
>
>         Object valuesArray;
>         Object itemValue;
>         if (submittedValues != null)
>         {
>             valuesArray = submittedValues;
>             itemValue = valueString;
>         }
>         else
>         {
>             valuesArray = currentSelections;
>             itemValue = curItem.getValue();
>         }
>
>         RequestStateManager.set(context,
>
> RequestStateManager.TARGET_COMPONENT_ATTRIBUTE_NAME,
>                                 component);
>
>         boolean isSelected = isSelected(context, component, itemValue,
> valuesArray, converter);
>         if (optionInfo.isHideNoSelection() &&
>             curItem.isNoSelectionOption() &&
>             currentSelections != null &&
>             !isSelected)
>         {
>             return;
>         }
>
>         ResponseWriter writer = context.getResponseWriter();
>         assert (writer != null);
>
>         if (alignVertical)
>         {
>             writer.writeText(TAB, component, null);
>             writer.startElement(TR, component);
>             writer.writeText(NEWLINE, component, null);
>         }
>         writer.startElement(TD, component);
>         writer.writeAttribute(VALIGN, "top", VALIGN);
>         writer.writeText(NEWLINE, component, null);
>
>         writer.startElement("input", component);
>         writer.writeAttribute("name", component.getClientId(context),
>                               "clientId");
>         String idString = component.getClientId(context) +
>                           UINamingContainer.getSeparatorChar(context) +
>                           Integer.toString(itemNumber);
>         writer.writeAttribute("id", idString, "id");
>
>         writer.writeAttribute("value", valueString, "value");
>         writer.writeAttribute("type", "checkbox", null);
>
>         if (isSelected)
>         {
>             writer.writeAttribute(getSelectedTextString(), Boolean.TRUE,
> null);
>         }
>
>         // Don't render the disabled attribute twice if the 'parent'
>         // component is already marked disabled.
>         if (!optionInfo.isDisabled())
>         {
>             if (curItem.isDisabled())
>             {
>                 writer.writeAttribute("disabled", true, "disabled");
>             }
>         }
>
>         // Apply HTML 4.x attributes specified on UISelectMany component
> to all
>         // items in the list except styleClass and style which are
> rendered as
>         // attributes of outer most table.
>         RenderKitUtils.renderPassThruAttributes(context,
>                                                 writer,
>                                                 component,
>                                                 ATTRIBUTES,
>
> getNonOnClickSelectBehaviors(component));
>
>         RenderKitUtils.renderXHTMLStyleBooleanAttributes(writer,
> component);
>
>         RenderKitUtils.renderSelectOnclick(context, component, true);
>
>         writer.endElement("input");
>
>         //--------------------------------------------------------
>         // New stuff for event selecting
>         //--------------------------------------------------------
>
>         writer.endElement(TD);
>
>         // starting the label td
>         writer.startElement(TD, component);
>         writer.writeAttribute(VALIGN, "top", VALIGN);
>         writer.writeAttribute("width", "80px", "width");
>         writer.writeAttribute(STYLE, "padding-top:4px", STYLE);
>
>         String itemLabel = curItem.getLabel();
>         if (itemLabel == null)
>         {
>             itemLabel = valueString;
>         }
>
>         writer.writeText(" ", component, null);
>         writer.startElement(LABEL, component);
>         writer.writeAttribute("for", component.getClientId() + ":" +
> itemNumber, "for");
>         if (!curItem.isEscape())
>         {
>             // It seems the ResponseWriter API should
>             // have a writeText() with a boolean property
>             // to determine if it content written should
>             // be escaped or not.
>             writer.write(itemLabel);
>         }
>         else
>         {
>             writer.writeText(itemLabel, component, null);
>         }
>         writer.endElement(LABEL);
>
>         isSelected(context, component, itemValue, valuesArray, converter);
> //            if (isSelected(context, component, itemValue, valuesArray,
> converter))
> //            {
> //                // selected
> //            }
> //            else
> //            {
> //                // not selected
> //            }
>         writer.endElement(TD);
>
>         // starting the description td
>         writer.startElement(TD, component);
>         writer.writeAttribute(VALIGN, "top", VALIGN);
>         writer.writeAttribute(STYLE, "padding-top:4px", STYLE);
>
>         String itemLabelDesc = curItem.getDescription();
>         if (itemLabelDesc == null)
>         {
>             itemLabelDesc = "";
>         }
>         writer.writeText(" ", component, null);
>         if (!curItem.isEscape())
>         {
>             // It seems the ResponseWriter API should
>             // have a writeText() with a boolean property
>             // to determine if it content written should
>             // be escaped or not.
>             writer.write(itemLabelDesc);
>         }
>         else
>         {
>             writer.writeText(itemLabelDesc, component, null);
>         }
>
>         writer.endElement(TD);
>
>         //--------------------------------------------------------
>         // New stuff for event selecting end
>         //--------------------------------------------------------
>
>         writer.writeText(NEWLINE, component, null);
>         if (alignVertical)
>         {
>             writer.writeText(TAB, component, null);
>             writer.endElement(TR);
>             writer.writeText(NEWLINE, component, null);
>         }
>     }
>
>
>     // ------------------------------------------------- Package Private
> Methods
>
>     /**
>      * {@inheritDoc}
>      */
>     String getSelectedTextString()
>     {
>         return "checked";
>     }
> }
>
>
> Any help is appreciated!
> Thanks!
>
> René
>

Reply via email to