1 /* 2 * Copyright 2004 The Apache Software Foundation. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package javax.faces.component; 17 18 import javax.faces.FacesException; 19 import javax.faces.context.FacesContext; 20 import javax.faces.convert.Converter; 21 import javax.faces.convert.ConverterException; 22 import javax.faces.el.ValueBinding; 23 import java.lang.reflect.Array; 24 import java.util.ArrayList; 25 import java.util.List; 26 27 /** 28 * The util methods in this class are shared between the javax.faces.component package and 29 * the org.apache.myfaces.renderkit package. 30 * Please note: Any changes here must also apply to the class in the other package! 31 * 32 * @author Manfred Geiler (latest modification by $Author: baranda $) 33 * @version $Revision: 291887 $ $Date: 2005-09-27 06:09:38 -0400 (Tue, 27 Sep 2005) $ 34 */ 35 class _SharedRendererUtils 36 { 37 static Converter findUIOutputConverter(FacesContext facesContext, UIOutput component) 38 { 39 // Attention! 40 // This code is duplicated in myfaces implementation renderkit package. 41 // If you change something here please do the same in the other class! 42 43 Converter converter = component.getConverter(); 44 if (converter != null) return converter; 45 46 //Try to find out by value binding 47 ValueBinding vb = component.getValueBinding("value"); 48 if (vb == null) return null; 49 50 Class valueType = vb.getType(facesContext); 51 if (valueType == null) return null; 52 53 if (String.class.equals(valueType)) return null; //No converter needed for String type 54 if (Object.class.equals(valueType)) return null; //There is no converter for Object class 55 56 try 57 { 58 return facesContext.getApplication().createConverter(valueType); 59 } 60 catch (FacesException e) 61 { 62 log(facesContext, "No Converter for type " + valueType.getName() + " found", e); 63 return null; 64 } 65 } 66 67 static Object getConvertedUISelectManyValue(FacesContext facesContext, 68 UISelectMany component, 69 String[] submittedValue) 70 throws ConverterException 71 { 72 // Attention! 73 // This code is duplicated in myfaces implementation renderkit package. 74 // If you change something here please do the same in the other class! 75 76 if (submittedValue == null) throw new NullPointerException("submittedValue"); 77 78 ValueBinding vb = component.getValueBinding("value"); 79 Class valueType = null; 80 Class arrayComponentType = null; 81 if (vb != null) 82 { 83 valueType = vb.getType(facesContext); 84 if (valueType != null && valueType.isArray()) 85 { 86 arrayComponentType = valueType.getComponentType(); 87 } 88 } 89 90 Converter converter = component.getConverter(); 91 if (converter == null) 92 { 93 if (valueType == null) 94 { 95 // No converter, and no idea of expected type 96 // --> return the submitted String array 97 return submittedValue; 98 } 99 100 if (List.class.isAssignableFrom(valueType)) 101 { 102 // expected type is a List 103 // --> according to javadoc of UISelectMany we assume that the element type 104 // is java.lang.String, and copy the String array to a new List 105 int len = submittedValue.length; 106 List lst = new ArrayList(len); 107 for (int i = 0; i < len; i++) 108 { 109 lst.add(submittedValue[i]); 110 } 111 return lst; 112 } 113 114 if (arrayComponentType == null) 115 { 116 throw new IllegalArgumentException("ValueBinding for UISelectMany must be of type List or Array"); 117 } 118 119 if (String.class.equals(arrayComponentType)) return submittedValue; //No conversion needed for String type 120 if (Object.class.equals(arrayComponentType)) return submittedValue; //No conversion for Object class 121 122 try 123 { 124 converter = facesContext.getApplication().createConverter(arrayComponentType); 125 } 126 catch (FacesException e) 127 { 128 log(facesContext, "No Converter for type " + arrayComponentType.getName() + " found", e); 129 return submittedValue; 130 } 131 } 132 133 // Now, we have a converter... 134 if (valueType == null) 135 { 136 // ...but have no idea of expected type 137 // --> so let's convert it to an Object array 138 int len = submittedValue.length; 139 Object [] convertedValues = (Object []) Array.newInstance(arrayComponentType, len); 140 for (int i = 0; i < len; i++) 141 { 142 convertedValues[i] 143 = converter.getAsObject(facesContext, component, submittedValue[i]); 144 } 145 return convertedValues; 146 } 147 148 if (List.class.isAssignableFrom(valueType)) 149 { 150 // Curious case: According to specs we should assume, that the element type 151 // of this List is java.lang.String. But there is a Converter set for this 152 // component. Because the user must know what he is doing, we will convert the values. 153 int len = submittedValue.length; 154 List lst = new ArrayList(len); 155 for (int i = 0; i < len; i++) 156 { 157 lst.add(converter.getAsObject(facesContext, component, submittedValue[i])); 158 } 159 return lst; 160 } 161 162 if (arrayComponentType == null) 163 { 164 throw new IllegalArgumentException("ValueBinding for UISelectMany must be of type List or Array"); 165 } 166 167 if (arrayComponentType.isPrimitive()) 168 { 169 //primitive array 170 int len = submittedValue.length; 171 Object convertedValues = Array.newInstance(arrayComponentType, len); 172 for (int i = 0; i < len; i++) 173 { 174 Array.set(convertedValues, i, 175 converter.getAsObject(facesContext, component, submittedValue[i])); 176 } 177 return convertedValues; 178 } 179 else 180 { 181 //Object array 182 int len = submittedValue.length; 183 ArrayList convertedValues = new ArrayList(len); 184 for (int i = 0; i < len; i++) 185 { 186 convertedValues.add(i, converter.getAsObject(facesContext, component, submittedValue[i])); 187 } 188 return convertedValues.toArray((Object[]) Array.newInstance(arrayComponentType, len)); 189 } 190 } 191 192 193 194 /** 195 * This method is different in the two versions of _SharedRendererUtils. 196 */ 197 private static void log(FacesContext context, String msg, Exception e) 198 { 199 context.getExternalContext().log(msg, e); 200 } 201 }