| Method from com.sun.faces.renderkit.html_basic.MenuRenderer Detail: |
protected boolean containsaValue(Object valueArray) {
if (null != valueArray) {
int len = Array.getLength(valueArray);
for (int i = 0; i < len; i++) {
Object value = Array.get(valueArray, i);
if (value != null && !(value.equals(RIConstants.NO_VALUE))) {
return true;
}
}
}
return false;
}
|
public Object convertSelectManyValue(FacesContext context,
UISelectMany uiSelectMany,
String[] newValues) throws ConverterException {
// ---------------------------------------------------------- Public Methods
// if we have no local value, try to get the valueExpression.
ValueExpression valueExpression =
uiSelectMany.getValueExpression("value");
Object result = newValues; // default case, set local value
boolean throwException = false;
// If we have a ValueExpression
if (null != valueExpression) {
Class modelType = valueExpression.getType(context.getELContext());
// Does the valueExpression resolve properly to something with
// a type?
if(modelType != null) {
result = convertSelectManyValuesForModel(context,
uiSelectMany,
modelType,
newValues);
}
// If it could not be converted, as a fall back try the type of
// the valueExpression's current value covering some edge cases such
// as where the current value came from a Map.
if(result == null) {
Object value = valueExpression.getValue(context.getELContext());
if(value != null) {
result = convertSelectManyValuesForModel(context,
uiSelectMany,
value.getClass(),
newValues);
}
}
if(result == null) {
throwException = true;
}
} else {
// No ValueExpression, just use Object array.
result = convertSelectManyValues(context, uiSelectMany,
Object[].class,
newValues);
}
if (throwException) {
StringBuffer values = new StringBuffer();
if (null != newValues) {
for (int i = 0; i < newValues.length; i++) {
if (i == 0) {
values.append(newValues[i]);
} else {
values.append(' ").append(newValues[i]);
}
}
}
Object[] params = {
values.toString(),
valueExpression.getExpressionString()
};
throw new ConverterException
(MessageUtils.getExceptionMessage(MessageUtils.CONVERSION_ERROR_MESSAGE_ID,
params));
}
// At this point, result is ready to be set as the value
if (logger.isLoggable(Level.FINE)) {
logger.fine("SelectMany Component " + uiSelectMany.getId() +
" convertedValues " + result);
}
return result;
}
|
protected Object convertSelectManyValues(FacesContext context,
UISelectMany uiSelectMany,
Class arrayClass,
String[] newValues) throws ConverterException {
Object result;
Converter converter;
int len = (null != newValues ? newValues.length : 0);
Class elementType = arrayClass.getComponentType();
// Optimization: If the elementType is String, we don't need
// conversion. Just return newValues.
if (elementType.equals(String.class)) {
return newValues;
}
try {
result = Array.newInstance(elementType, len);
} catch (Exception e) {
throw new ConverterException(e);
}
// bail out now if we have no new values, returning our
// oh-so-useful zero-length array.
if (null == newValues) {
return result;
}
// obtain a converter.
// attached converter takes priority
if (null == (converter = uiSelectMany.getConverter())) {
// Otherwise, look for a by-type converter
if (null == (converter = Util.getConverterForClass(elementType,
context))) {
// if that fails, and the attached values are of Object type,
// we don't need conversion.
if (elementType.equals(Object.class)) {
return newValues;
}
StringBuffer valueStr = new StringBuffer();
for (int i = 0; i < len; i++) {
if (i == 0) {
valueStr.append(newValues[i]);
} else {
valueStr.append(' ").append(newValues[i]);
}
}
Object[] params = {
valueStr.toString(),
"null Converter"
};
throw new ConverterException(MessageUtils.getExceptionMessage(
MessageUtils.CONVERSION_ERROR_MESSAGE_ID, params));
}
}
assert(null != result);
if (elementType.isPrimitive()) {
for (int i = 0; i < len; i++) {
if (elementType.equals(Boolean.TYPE)) {
Array.setBoolean(result, i,
((Boolean) converter.getAsObject(context,
uiSelectMany,
newValues[i])));
} else if (elementType.equals(Byte.TYPE)) {
Array.setByte(result, i,
((Byte) converter.getAsObject(context,
uiSelectMany,
newValues[i])));
} else if (elementType.equals(Double.TYPE)) {
Array.setDouble(result, i,
((Double) converter.getAsObject(context,
uiSelectMany,
newValues[i])));
} else if (elementType.equals(Float.TYPE)) {
Array.setFloat(result, i,
((Float) converter.getAsObject(context,
uiSelectMany,
newValues[i])));
} else if (elementType.equals(Integer.TYPE)) {
Array.setInt(result, i,
((Integer) converter.getAsObject(context,
uiSelectMany,
newValues[i])));
} else if (elementType.equals(Character.TYPE)) {
Array.setChar(result, i,
((Character) converter.getAsObject(context,
uiSelectMany,
newValues[i])));
} else if (elementType.equals(Short.TYPE)) {
Array.setShort(result, i,
((Short) converter.getAsObject(context,
uiSelectMany,
newValues[i])));
} else if (elementType.equals(Long.TYPE)) {
Array.setLong(result, i,
((Long) converter.getAsObject(context,
uiSelectMany,
newValues[i])));
}
}
} else {
for (int i = 0; i < len; i++) {
if (logger.isLoggable(Level.FINE)) {
Object converted = converter.getAsObject(context,
uiSelectMany,
newValues[i]);
logger.fine("String value: " + newValues[i] +
" converts to : " + converted);
}
Array.set(result, i, converter.getAsObject(context,
uiSelectMany,
newValues[i]));
}
}
return result;
}
|
protected Object convertSelectManyValuesForModel(FacesContext context,
UISelectMany uiSelectMany,
Class modelType,
String[] newValues) {
Object result = null;
if (modelType.isArray()) {
result = convertSelectManyValues(context,
uiSelectMany,
modelType,
newValues);
} else if (List.class.isAssignableFrom(modelType)) {
Object[] values = (Object[]) convertSelectManyValues(context,
uiSelectMany,
Object[].class,
newValues);
// perform a manual copy as the Array returned from
// Arrays.asList() isn't mutable. It seems a waste
// to also call Collections.addAll(Arrays.asList())
List< Object > l = new ArrayList< Object >(values.length);
//noinspection ManualArrayToCollectionCopy
for (Object v : values) {
l.add(v);
}
result = l;
}
return result;
}
|
public Object convertSelectOneValue(FacesContext context,
UISelectOne uiSelectOne,
String newValue) throws ConverterException {
if (RIConstants.NO_VALUE.equals(newValue)) {
return null;
}
if (newValue == null) {
if (logger.isLoggable(Level.FINE)) {
logger.fine("No conversion necessary for SelectOne Component "
+ uiSelectOne.getId()
+ " since the new value is null ");
}
return null;
}
Object convertedValue =
super.getConvertedValue(context, uiSelectOne, newValue);
if (logger.isLoggable(Level.FINE)) {
logger.fine("SelectOne Component " + uiSelectOne.getId() +
" convertedValue " + convertedValue);
}
return convertedValue;
}
|
public void decode(FacesContext context,
UIComponent component) {
rendererParamsNotNull(context, component);
if (!shouldDecode(component)) {
return;
}
String clientId = component.getClientId(context);
assert(clientId != null);
// currently we assume the model type to be of type string or
// convertible to string and localized by the application.
if (component instanceof UISelectMany) {
Map< String, String[] > requestParameterValuesMap =
context.getExternalContext().
getRequestParameterValuesMap();
if (requestParameterValuesMap.containsKey(clientId)) {
String newValues[] = requestParameterValuesMap.
get(clientId);
setSubmittedValue(component, newValues);
if (logger.isLoggable(Level.FINE)) {
logger.fine("submitted values for UISelectMany component "
+
component.getId()
+ " after decoding "
+ Arrays.toString(newValues));
}
} else {
// Use the empty array, not null, to distinguish
// between an deselected UISelectMany and a disabled one
setSubmittedValue(component, new String[0]);
if (logger.isLoggable(Level.FINE)) {
logger.fine("Set empty array for UISelectMany component " +
component.getId() + " after decoding ");
}
}
} else {
// this is a UISelectOne
Map< String, String > requestParameterMap =
context.getExternalContext().
getRequestParameterMap();
if (requestParameterMap.containsKey(clientId)) {
String newValue = requestParameterMap.get(clientId);
setSubmittedValue(component, newValue);
if (logger.isLoggable(Level.FINE)) {
logger.fine("submitted value for UISelectOne component "
+
component.getId()
+ " after decoding "
+ newValue);
}
} else {
// there is no value, but this is different from a null
// value.
setSubmittedValue(component, RIConstants.NO_VALUE);
}
}
}
|
public void encodeBegin(FacesContext context,
UIComponent component) throws IOException {
rendererParamsNotNull(context, component);
}
|
public void encodeEnd(FacesContext context,
UIComponent component) throws IOException {
rendererParamsNotNull(context, component);
if (!shouldEncode(component)) {
return;
}
renderSelect(context, component);
}
|
public Object getConvertedValue(FacesContext context,
UIComponent component,
Object submittedValue) throws ConverterException {
if (component instanceof UISelectMany) {
// need to set the 'TARGET_COMPONENT_ATTRIBUTE_NAME' request attr so the
// coerce-value call in the jsf-api UISelectMany.matchValue will work
// (need a better way to determine the currently processing UIComponent ...)
RequestStateManager.set(context,
RequestStateManager.TARGET_COMPONENT_ATTRIBUTE_NAME,
component);
return convertSelectManyValue(context,
((UISelectMany) component),
(String[]) submittedValue);
} else {
return convertSelectOneValue(context,
((UISelectOne) component),
(String) submittedValue);
}
}
|
protected Object getCurrentSelectedValues(UIComponent component) {
if (component instanceof UISelectMany) {
UISelectMany select = (UISelectMany) component;
Object value = select.getValue();
if (value instanceof Collection) {
return ((Collection) value).toArray();
} else if (value != null && !value.getClass().isArray()) {
logger.warning(
"The UISelectMany value should be an array or a collection type, the actual type is " +
value.getClass().getName());
}
return value;
}
UISelectOne select = (UISelectOne) component;
Object val = select.getValue();
if (val != null) {
return new Object[] { val };
}
return null;
}
|
protected String getMultipleText(UIComponent component) {
if (component instanceof UISelectMany) {
return " multiple ";
}
return "";
}
|
protected int getOptionNumber(List selectItems) {
int itemCount = 0;
if (!selectItems.isEmpty()) {
for (Iterator items = selectItems.iterator(); items.hasNext();) {
itemCount++;
SelectItem item = (SelectItem) items.next();
if (item instanceof SelectItemGroup) {
int optionsLength =
((SelectItemGroup) item).getSelectItems().length;
itemCount += optionsLength;
}
}
}
return itemCount;
}
|
protected int getOptionNumber(FacesContext context,
UIComponent component,
List selectItems) {
return getOptionNumber(selectItems);
}
|
protected Object[] getSubmittedSelectedValues(UIComponent component) {
if (component instanceof UISelectMany) {
UISelectMany select = (UISelectMany) component;
return (Object[]) select.getSubmittedValue();
}
UISelectOne select = (UISelectOne) component;
Object val = select.getSubmittedValue();
if (val != null) {
return new Object[] { val };
}
return null;
}
|
protected boolean isSelected(FacesContext context,
Object itemValue,
Object valueArray) {
if (null != valueArray) {
if (!valueArray.getClass().isArray()) {
logger.warning("valueArray is not an array, the actual type is " +
valueArray.getClass());
return valueArray.equals(itemValue);
}
int len = Array.getLength(valueArray);
for (int i = 0; i < len; i++) {
Object value = Array.get(valueArray, i);
if (value == null) {
if (itemValue == null) {
return true;
}
} else {
Object newValue;
if (value.getClass().isInstance(itemValue)) {
newValue = itemValue;
} else {
try {
newValue =
context.getApplication()
.getExpressionFactory().
coerceToType(itemValue, value.getClass());
} catch (ELException ele) {
newValue = itemValue;
} catch (IllegalArgumentException iae) {
// If coerceToType fails, per the docs it should throw
// an ELException, however, GF 9.0 and 9.0u1 will throw
// an IllegalArgumentException instead (see GF issue 1527).
newValue = itemValue;
}
}
if (value.equals(newValue)) {
return true;
}
}
}
}
return false;
}
|
protected void renderOption(FacesContext context,
UIComponent component,
Converter converter,
SelectItem curItem) throws IOException {
this.renderOption(context,
component,
converter,
curItem,
getCurrentSelectedValues(component),
getSubmittedSelectedValues(component));
}
|
protected void renderOption(FacesContext context,
UIComponent component,
Converter converter,
SelectItem curItem,
Object currentSelections,
Object[] submittedValues) throws IOException {
ResponseWriter writer = context.getResponseWriter();
assert (writer != null);
writer.writeText("\t", component, null);
writer.startElement("option", component);
String valueString = getFormattedValue(context, component,
curItem.getValue(), converter);
writer.writeAttribute("value", valueString, "value");
Object valuesArray;
Object itemValue;
boolean containsValue;
if (submittedValues != null) {
containsValue = containsaValue(submittedValues);
if (containsValue) {
valuesArray = submittedValues;
itemValue = valueString;
} else {
valuesArray = currentSelections;
itemValue = curItem.getValue();
}
} else {
valuesArray = currentSelections;
itemValue = curItem.getValue();
}
if (isSelected(context, itemValue, valuesArray)) {
writer.writeAttribute("selected", true, "selected");
}
Boolean disabledAttr =
(Boolean) component.getAttributes().get("disabled");
boolean componentDisabled = false;
if (disabledAttr != null) {
if (disabledAttr.equals(Boolean.TRUE)) {
componentDisabled = true;
}
}
// if the component is disabled, "disabled" attribute would be rendered
// on "select" tag, so don't render "disabled" on every option.
if ((!componentDisabled) && curItem.isDisabled()) {
writer.writeAttribute("disabled", true, "disabled");
}
String labelClass;
if (componentDisabled || curItem.isDisabled()) {
labelClass = (String) component.
getAttributes().get("disabledClass");
} else {
labelClass = (String) component.
getAttributes().get("enabledClass");
}
if (labelClass != null) {
writer.writeAttribute("class", labelClass, "labelClass");
}
if (curItem.isEscape()) {
String label = curItem.getLabel();
if (label == null) {
label = valueString;
}
writer.writeText(label, component, "label");
} else {
writer.write(curItem.getLabel());
}
writer.endElement("option");
writer.writeText("\n", component, null);
}
|
protected void renderOptions(FacesContext context,
UIComponent component,
List items) throws IOException {
ResponseWriter writer = context.getResponseWriter();
assert(writer != null);
Converter converter = null;
if(component instanceof ValueHolder) {
converter = ((ValueHolder)component).getConverter();
}
if (!items.isEmpty()) {
Object currentSelections = getCurrentSelectedValues(component);
Object[] submittedValues = getSubmittedSelectedValues(component);
RequestStateManager.set(context,
RequestStateManager.TARGET_COMPONENT_ATTRIBUTE_NAME,
component);
for (SelectItem item : items) {
if (item instanceof SelectItemGroup) {
// render OPTGROUP
writer.startElement("optgroup", component);
writer.writeAttribute("label", item.getLabel(), "label");
// if the component is disabled, "disabled" attribute would be rendered
// on "select" tag, so don't render "disabled" on every option.
boolean componentDisabled =
Boolean.TRUE.equals(component.getAttributes().get("disabled"));
if ((!componentDisabled) && item.isDisabled()) {
writer.writeAttribute("disabled", true, "disabled");
}
// render options of this group.
SelectItem[] itemsArray =
((SelectItemGroup) item).getSelectItems();
for (int i = 0; i < itemsArray.length; ++i) {
renderOption(context,
component,
converter,
itemsArray[i],
currentSelections,
submittedValues);
}
writer.endElement("optgroup");
} else {
renderOption(context,
component,
converter,
item,
currentSelections,
submittedValues);
}
}
}
}
|
protected void renderSelect(FacesContext context,
UIComponent component) throws IOException {
ResponseWriter writer = context.getResponseWriter();
assert(writer != null);
if (logger.isLoggable(Level.FINER)) {
logger.log(Level.FINER, "Rendering 'select'");
}
writer.startElement("select", component);
writeIdAttributeIfNecessary(context, writer, component);
writer.writeAttribute("name", component.getClientId(context),
"clientId");
// render styleClass attribute if present.
String styleClass;
if (null !=
(styleClass =
(String) component.getAttributes().get("styleClass"))) {
writer.writeAttribute("class", styleClass, "styleClass");
}
if (!getMultipleText(component).equals("")) {
writer.writeAttribute("multiple", true, "multiple");
}
// Determine how many option(s) we need to render, and update
// the component's "size" attribute accordingly; The "size"
// attribute will be rendered as one of the "pass thru" attributes
List< SelectItem > items = RenderKitUtils.getSelectItems(context, component);
int itemCount = getOptionNumber(items);
if (logger.isLoggable(Level.FINE)) {
logger.fine("Rendering " + itemCount + " options");
}
// If "size" is *not* set explicitly, we have to default it correctly
Integer size = (Integer) component.getAttributes().get("size");
if (size == null || size == Integer.MIN_VALUE) {
size = itemCount;
}
writeDefaultSize(writer, size);
RenderKitUtils.renderPassThruAttributes(writer,
component,
ATTRIBUTES);
RenderKitUtils.renderXHTMLStyleBooleanAttributes(writer,
component);
// Now, render the "options" portion...
renderOptions(context, component, items);
writer.endElement("select");
}
|
protected void writeDefaultSize(ResponseWriter writer,
int itemCount) throws IOException {
// if size is not specified default to 1.
writer.writeAttribute("size", "1", "size");
}
|