Coverage Report - org.kuali.rice.core.web.format.Formatter
 
Classes in this File Line Coverage Branch Coverage Complexity
Formatter
20%
37/178
5%
5/98
5.233
Formatter$ArrayUtils
0%
0/62
0%
0/56
5.233
 
 1  
 /*
 2  
  * Copyright 2006-2011 The Kuali Foundation
 3  
  *
 4  
  * Licensed under the Educational Community 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.opensource.org/licenses/ecl2.php
 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  
 // begin Kuali Foundation modification
 17  
 package org.kuali.rice.core.web.format;
 18  
 // end Kuali Foundation modification
 19  
 
 20  
 import org.apache.commons.beanutils.PropertyUtils;
 21  
 import org.apache.commons.lang.StringUtils;
 22  
 import org.kuali.rice.core.api.util.type.AbstractKualiDecimal;
 23  
 import org.kuali.rice.core.api.util.type.KualiDecimal;
 24  
 import org.kuali.rice.core.api.util.type.KualiInteger;
 25  
 import org.kuali.rice.core.api.util.type.KualiPercent;
 26  
 
 27  
 import java.io.Serializable;
 28  
 import java.lang.reflect.Array;
 29  
 import java.math.BigDecimal;
 30  
 import java.sql.Date;
 31  
 import java.sql.Timestamp;
 32  
 import java.util.ArrayList;
 33  
 import java.util.Collection;
 34  
 import java.util.Collections;
 35  
 import java.util.HashMap;
 36  
 import java.util.HashSet;
 37  
 import java.util.Iterator;
 38  
 import java.util.List;
 39  
 import java.util.Map;
 40  
 import java.util.Set;
 41  
 
 42  
 
 43  
 
 44  
 // begin Kuali Foundation modification
 45  
 /**
 46  
  * This is the base class for all other Formatters.
 47  
  */
 48  
 /**
 49  
  * It provides default formatting and conversion behavior for most value types, including primitives, arrays, and instances of most
 50  
  * {@link Collection}types. <code>Formatter</code> and its subclasses were designed primarily to be used by web app framework
 51  
  * components, though they can also be used in other contexts.
 52  
  * <p>
 53  
  * During request processing, the {@link PojoActionForm}uses <code>Formatter</code> instances to convert inbound request values
 54  
  * to JavaBean property types. Whenever a given value cannot be converted to its target type, the conversion method
 55  
  * {@link PropertyUtils#getProperty(Object, String)}throws a {@link FormatException}to signal this condition to the
 56  
  * calling code.
 57  
  * <p>
 58  
  * During the response phase, Struts tags make calls to the {@link PojoRequestProcessor}in order to access bean property values.
 59  
  * The <code>PojoRequestProcessor</code> then uses <code>Formatter</code> instances to format the bean values for presentation
 60  
  * in the user interface.
 61  
  * <p>
 62  
  * In either case, <code>Formatter</code> instances are obtained by calling {@link #getFormatter(Class)}, which looks in an
 63  
  * internal registry to determine which <code>Formatter</code> class to instantiate, and returns a new instance. The StrutsLive
 64  
  * framework includes a number of <code>Formatter</code> classes that are registered statically; additional
 65  
  * <code>Formatter classes can be registered at compile
 66  
  * time or at run time. 
 67  
  * <p>
 68  
  * Subclasses of <code>Formatter</code> typically override the callback methods
 69  
  * {@link #convertToObject(String)} and {@link #formatObject(Object)}, which
 70  
  * otherwise provide default conversion and formmating behavior needed for
 71  
  * atomic values (i.e., an ordinary bean property such as a <code>String</code>
 72  
  * or <code>Integer</code>, or else an element of a property typed as
 73  
  * array or Collection).
 74  
  *
 75  
  */
 76  
 // end Kuali Foundation modification
 77  1
 public class Formatter implements Serializable {
 78  
 
 79  
         // begin Kuali Foundation modification
 80  
         // removed serialVersionUID and logger members
 81  
         // end Kuali Foundation modification
 82  
         
 83  
     static final String CREATE_MSG = "Couldn't create an instance of class ";
 84  
     // begin Kuali Foundation modification
 85  
     // registry changed from AppLocal instance to a Map
 86  1
     private static Map registry = Collections.synchronizedMap(new HashMap());
 87  
     // end Kuali Foundation modification
 88  
     
 89  
     protected Map settings;
 90  
     
 91  
     // begin Kuali Foundation modification
 92  
     // removed keypath and rootObject variables
 93  
     // end Kuali Foundation modification
 94  
     
 95  
     protected Class propertyType;
 96  
 
 97  
     static { 
 98  
             // begin Kuali Foundation modification
 99  1
         registerFormatter(String.class, Formatter.class);
 100  1
         registerFormatter(String[].class, Formatter.class);
 101  1
         registerFormatter(AbstractKualiDecimal.class, BigDecimalFormatter.class);
 102  1
         registerFormatter(KualiDecimal.class, CurrencyFormatter.class); 
 103  1
         registerFormatter(KualiInteger.class, KualiIntegerCurrencyFormatter.class);
 104  1
         registerFormatter(KualiPercent.class, PercentageFormatter.class);
 105  1
         registerFormatter(BigDecimal.class, BigDecimalFormatter.class);
 106  1
         registerFormatter(Date.class, DateFormatter.class);
 107  1
         registerFormatter(Integer.class, IntegerFormatter.class);
 108  1
         registerFormatter(int.class, IntegerFormatter.class);
 109  1
         registerFormatter(int[].class, IntegerFormatter.class);
 110  1
         registerFormatter(Boolean.class, BooleanFormatter.class);
 111  1
         registerFormatter(Boolean.TYPE, BooleanFormatter.class);
 112  1
         registerFormatter(boolean[].class, BooleanFormatter.class);
 113  1
         registerFormatter(Long.class, LongFormatter.class);
 114  1
         registerFormatter(Timestamp.class, DateViewTimestampObjectFormatter.class);
 115  1
         registerFormatter(boolean.class, LittleBooleanFormatter.class);
 116  1
         registerFormatter(Collection.class, ArrayFormatter.class);
 117  
         // end Kuali Foundation modification
 118  1
     }
 119  
 
 120  
     public static Formatter getFormatter(Class aType) {
 121  0
         return getFormatter(aType, null);
 122  
     }
 123  
 
 124  
     // begin Kuali Foundation modification
 125  
     // param aType was valueType, comment changes, major code changes
 126  
     /**
 127  
      * Returns an instance of the Formatter class to be used to format the provided value type.
 128  
      * 
 129  
      * @param type the class of the value to be formatted
 130  
      * @param settings parameters used by subclasses to customize behavior
 131  
      * @return an instance of Formatter or one of its subclasses
 132  
      */
 133  
     public static Formatter getFormatter(Class aType, Map settings) {
 134  
             // original code: return createFormatter(formatterForType(valueType), valueType, settings);
 135  
                         
 136  1
         Class type = formatterForType(aType);
 137  1
         Formatter formatter = null;
 138  
         try {
 139  1
             formatter = (Formatter) type.newInstance();
 140  
         }
 141  0
         catch (InstantiationException e) {
 142  0
             throw new FormatException(CREATE_MSG + type, e);
 143  
         }
 144  0
         catch (IllegalAccessException e) {
 145  0
             throw new FormatException(CREATE_MSG + type, e);
 146  1
         }
 147  
 
 148  1
         if (settings != null)
 149  0
             formatter.setSettings(Collections.unmodifiableMap(settings));
 150  1
         formatter.propertyType = aType;
 151  
 
 152  1
         return formatter;
 153  
     }
 154  
 
 155  
     // removed getFormatterByName, formatterClassForName, createFormatter methods
 156  
     // end Kuali Foundation modification
 157  
 
 158  
     /**
 159  
      * Binds the provided value type to a Formatter type. Note that a single Formatter class can be associated with more than one
 160  
      * type.
 161  
      * 
 162  
      * @param type a value type
 163  
      * @param formatterType a Formatter type
 164  
      */
 165  
     public static void registerFormatter(Class type, Class formatterType) {
 166  18
         registry.put(type, formatterType);
 167  18
     }
 168  
 
 169  
     /**
 170  
      * Returns <code>true</code> if the provided class is an array type, implements either the {@link List}or {@link Set}
 171  
      * interfaces, or is one of the Formatter classes currently registered.
 172  
      * 
 173  
      * @see registerFormatter(Class, Class)
 174  
      */
 175  
     public static boolean isSupportedType(Class type) {
 176  
         // begin Kuali Foundation modification
 177  0
         if (type == null)
 178  0
             return false;
 179  
         // end Kuali Foundation modification
 180  0
         if (List.class.isAssignableFrom(type))
 181  0
             return true;
 182  0
         if (Set.class.isAssignableFrom(type))
 183  0
             return true;
 184  
 
 185  0
         return findFormatter(type) != null;
 186  
     }
 187  
 
 188  
     /**
 189  
      * Return the Formatter associated with the given type, by consulting an internal registry. Additional associations can be made
 190  
      * by calling {@link registerFormatter(Class, Class)}.
 191  
      * 
 192  
      * @return a new Formatter instance
 193  
      */
 194  
     public static Class formatterForType(Class type) {
 195  1
         if (type == null)
 196  0
             throw new IllegalArgumentException("Type can not be null");
 197  
 
 198  1
         Class formatterType = findFormatter(type);
 199  
 
 200  1
         return formatterType == null ? Formatter.class : formatterType;
 201  
     }
 202  
 
 203  
         // Kuali Foundation modification: comment removed
 204  
     public static Class findFormatter(Class type) {
 205  
             // begin Kuali Foundation modification
 206  1
         if (type == null)
 207  0
             return null;
 208  
 
 209  1
         if (registry.containsKey(type)) {
 210  1
             return (Class) registry.get(type);
 211  
         }
 212  
 
 213  
 
 214  0
         Iterator typeIter = registry.keySet().iterator();
 215  0
         while (typeIter.hasNext()) {
 216  0
             Class currType = (Class) typeIter.next();
 217  0
             if (currType.isAssignableFrom(type)) {
 218  0
                 Class currFormatter = (Class) registry.get(currType);
 219  0
                 registerFormatter(type, currFormatter);
 220  0
                 return currFormatter;
 221  
             }
 222  0
         }
 223  
 
 224  0
         return null;
 225  
         // end Kuali Foundation modification
 226  
     }
 227  
 
 228  
         // begin Kuali Foundation modification
 229  
     public String getImplementationClass() {
 230  0
         return this.getClass().getName();
 231  
     }
 232  
     // end Kuali Foundation modification
 233  
 
 234  
     public Class getPropertyType() {
 235  0
         return propertyType;
 236  
     }
 237  
 
 238  
     public void setPropertyType(Class propertyType) {
 239  0
         this.propertyType = propertyType;
 240  0
     }
 241  
 
 242  
     public Map getSettings() {
 243  0
         return settings;
 244  
     }
 245  
 
 246  
     public void setSettings(Map settings) {
 247  0
         this.settings = settings;
 248  0
     }
 249  
 
 250  
         // begin Kuali Foundation modification
 251  
         // removed getKeypath, setKeyPath, getRootObject, setRootObject, hasSettingForKey, settingForKey, typeForKey, getErrorKey
 252  
         // end Kuali Foundation modification
 253  
         
 254  
     /**
 255  
      * begin Kuali Foundation modification
 256  
      * Returns a String representation of the given value. May be overridden by subclasses to provide customized behavior for
 257  
      * different types, though generally the callback method {@link #format(Object)}provides a better customization hook.
 258  
      * <p>
 259  
      * Provides default handling for properties typed as array or Collection. Subclass implementations of this method must invoke
 260  
      * <code>super.formatForPresentation()</code> to take advantage of this built-in behavior.
 261  
      * <p>
 262  
      * Delegates to callback method {@link formatObject}for all other types. This method in turn invokes the callback method
 263  
      * <code>format</code>, which serves as an extension point for subclasses; the default implementation simply returns its
 264  
      * argument. Overriding <code>format</code> allows subclasses to take advantage of all of the array, primitive type, and
 265  
      * Collection handling functionality provided by the base class.
 266  
      * 
 267  
      * @param value the object to be formatted
 268  
      * @return a formatted string representation of the given object
 269  
      * @see #formatObject(Object)
 270  
      * end Kuali Foundation modification
 271  
      */
 272  
     public Object formatForPresentation(Object value) {
 273  0
         if (isNullValue(value))
 274  0
             return formatNull();
 275  
 
 276  
                 // begin Kuali Foundation modification
 277  
                 // removed code
 278  
                 /*
 279  
             // TODO: add registry for non-navigable classes so there's a way to
 280  
         // disable formatting selectively for given types contained in arrays
 281  
         // or Collections.
 282  
         if (Collection.class.isAssignableFrom(value.getClass()))
 283  
             return formatCollection((Collection) value);
 284  
         
 285  
         if (propertyType != null && propertyType.isArray())
 286  
             return formatArray(value);
 287  
                 */
 288  
                 // end Kuali Foundation modification
 289  
                 
 290  0
         return formatObject(value);
 291  
     }
 292  
 
 293  
     /**
 294  
      * May be overridden by subclasses to provide special handling for <code>null</code> values when formatting a bean property
 295  
      * value for presentation. The default implementation simply returns <code>null</code>
 296  
      */
 297  
     protected Object formatNull() {
 298  0
         return null;
 299  
     }
 300  
 
 301  
     /**
 302  
      * May be overridden by subclasses to provide custom formatting behavior. Provides default formatting implementation for
 303  
      * primitive types. (Note that primitive types are will always be wrapped in an array in order to be passed as an argument of
 304  
      * type <code>Object</code>).
 305  
      */
 306  
     public Object formatObject(Object value) {
 307  0
         if (value == null)
 308  0
             return formatNull();
 309  
 
 310  
         // Collections and arrays have already been handled at this point, so
 311  
         // if value is an array, assume it's a wrapper for a primitive type.
 312  0
         Class<?> type = value.getClass();
 313  0
         if (type.isArray())
 314  
                 // begin Kuali Foundation modification
 315  0
             return ArrayUtils.toString(value, type.getComponentType());
 316  
             // end begin Kuali Foundation modification
 317  
 
 318  0
         if (!(isSupportedType(value.getClass())))
 319  
             // begin Kuali Foundation modification
 320  0
             formatBean(value);
 321  
             // end Kuali Foundation modification
 322  
 
 323  0
         return format(value);
 324  
     }
 325  
 
 326  
     /**
 327  
      * If an element of the Collection isn't a supported type, assume it's a JavaBean, and format each of its properties. Returns a
 328  
      * Map containing the formatted properties keyed by property name.
 329  
      */
 330  
     protected Object formatBean(Object bean) {
 331  0
         Map properties = null;
 332  
         try {
 333  
                 // begin Kuali Foundation modification
 334  0
             properties = PropertyUtils.describe(bean);
 335  
             // end Kuali Foundation modification
 336  
         }
 337  0
         catch (Exception e) {
 338  0
             throw new FormatException("Unable to format values for bean " + bean, e);
 339  0
         }
 340  
 
 341  0
         Map formattedVals = new HashMap();
 342  
         // begin Kuali Foundation modification
 343  0
         Iterator propIter = properties.entrySet().iterator();
 344  
 
 345  0
         while (propIter.hasNext()) {
 346  0
             Map.Entry entry = (Map.Entry) propIter.next();
 347  0
             Object value = entry.getValue();
 348  0
             if (value != null && isSupportedType(value.getClass())) {
 349  0
                 Formatter formatter = getFormatter(value.getClass());
 350  0
                 formattedVals.put(entry.getKey(), formatter.formatForPresentation(value));
 351  
             }
 352  0
         }
 353  
         // end Kuali Foundation modification
 354  0
         return formattedVals;
 355  
     }
 356  
 
 357  
     public Object format(Object value) {
 358  0
         return value;
 359  
     }
 360  
 
 361  
     public Object formatArray(Object value) {
 362  
             // begin Kuali Foundation modification
 363  0
         Class elementType = value.getClass().getComponentType();
 364  0
         if (!isSupportedType(elementType))
 365  0
             return value;
 366  
 
 367  0
         int length = Array.getLength(value);
 368  0
         Object[] formattedVals = new String[length];
 369  
 
 370  0
         for (int i = 0; i < length; i++) {
 371  0
             Object element = Array.get(value, i);
 372  0
             Object objValue = ArrayUtils.toObject(element);
 373  0
             Formatter elementFormatter = getFormatter(elementType);
 374  0
             formattedVals[i] = elementFormatter.formatForPresentation(objValue);
 375  
         }
 376  
 
 377  0
         return formattedVals;
 378  
         // end Kuali Foundation modification
 379  
     }
 380  
 
 381  
     public Object formatCollection(Collection value) {
 382  0
         List stringVals = new ArrayList();
 383  0
         Iterator iter = value.iterator();
 384  0
         while (iter.hasNext()) {
 385  0
             Object obj = iter.next();
 386  0
             Formatter formatter = getFormatter(obj.getClass());
 387  
             // begin Kuali Foundation modification
 388  0
             stringVals.add(formatter.formatForPresentation(obj));
 389  
             // end Kuali Foundation modification
 390  0
         }
 391  0
         return stringVals.toArray();
 392  
     }
 393  
 
 394  
     /**
 395  
      * Returns an object representation of the provided string after first removing any extraneous formatting characters. If the
 396  
      * argument is a native array wrapping the actual value, the value is removed (unwrapped) from the array prior to invoking the
 397  
      * callback method {@link #convertToObject(String)}, which performs the actual conversion.
 398  
      * <p>
 399  
      * If the provided object is <code>null</code>, a blank <code>String</code>, or a <code>String[]</code> of length <b>0
 400  
      * </b> or that has <code>null</code> or a blank <code>String</code> in the first position, returns <code>null</code>.
 401  
      * Otherwise, If the destination property is a <code>Collection</code>, returns an instance of that type containing the
 402  
      * string values of the array elements.
 403  
      * <p>
 404  
      * If the provided object is an array, uses a Formatter corresponding to the array's component type to convert each of its
 405  
      * elements, and returns a new array containing the converted values.
 406  
      * 
 407  
      * May be overidden by subclasses to customize conversion, though ordinarily {@link #convertToObject(String)}is a better choice
 408  
      * since it takes advantage of <code>convertFromPresentationFormat</code>'s built-in behavior.
 409  
      * 
 410  
      * @param value the string value to be converted
 411  
      * @return the object value corresponding to the provided string value
 412  
      * @see convertToObject(String)
 413  
      */
 414  
     public Object convertFromPresentationFormat(Object value) {
 415  0
         if (isEmptyValue(value))
 416  0
             return getNullObjectValue();
 417  
 
 418  0
         Class type = value.getClass();
 419  0
         boolean isArray = propertyType != null && propertyType.isArray();
 420  0
         boolean isCollection = propertyType != null && Collection.class.isAssignableFrom(propertyType);
 421  
 
 422  0
         if (!(isArray || isCollection)) {
 423  0
             value = unwrapString(value);
 424  0
             return convertToObject((String) value);
 425  
         }
 426  
 
 427  0
         String[] strings = type.isArray() ? (String[]) value : new String[] { (String) value };
 428  
 
 429  0
         return isArray ? convertToArray(strings) : convertToCollection(strings);
 430  
     }
 431  
 
 432  
     /**
 433  
      * May be overridden by subclasses to provide special handling for <code>null</code> values when converting from presentation
 434  
      * format to a bean property type. The default implementation simply returns <code>null</code>
 435  
      */
 436  
     protected Object getNullObjectValue() {
 437  0
         return null;
 438  
     }
 439  
 
 440  
     /**
 441  
      * May be orverridden by subclasses to customize its behavior. The default implementation simply trims and returns the provided
 442  
      * string.
 443  
      */
 444  
     protected Object convertToObject(String string) {
 445  0
         return string == null ? null : string.replace( "\r\n", "\n" ).trim();        
 446  
     }
 447  
 
 448  
     /**
 449  
      * Converts an array of strings to a Collection type corresponding to the value of <code>propertyType</code>. Since we don't
 450  
      * have type information for the elements of the collection, no attempt is made to convert the elements from <code>String</code>
 451  
      * to other types. However, subclasses can override this method if they need to provide the ability to convert the elements to a
 452  
      * given type.
 453  
      */
 454  
     protected Collection convertToCollection(String[] strings) {
 455  0
         Collection collection = null;
 456  0
         Class type = propertyType;
 457  
 
 458  0
         if (propertyType.isAssignableFrom(List.class))
 459  0
             type = ArrayList.class;
 460  0
         else if (propertyType.isAssignableFrom(Set.class))
 461  0
             type = HashSet.class;
 462  
 
 463  
         try {
 464  0
             collection = (Collection) type.newInstance();
 465  
         }
 466  0
         catch (Exception e) {
 467  0
             throw new FormatException(CREATE_MSG + propertyType, e);
 468  0
         }
 469  
 
 470  0
         for (int i = 0; i < strings.length; i++)
 471  0
             collection.add(strings[i]);
 472  
 
 473  0
         return collection;
 474  
     }
 475  
 
 476  
     /**
 477  
      * Converts an array of strings to an array of objects by calling {@link #convertToObject(String)}on each element of the
 478  
      * provided array in turn, using instances of a Formatter class that corresponds to this Formatter's property type.
 479  
      * 
 480  
      * @see #propertyType
 481  
      */
 482  
     protected Object convertToArray(String[] strings) {
 483  0
         Class type = propertyType.getComponentType();
 484  
         // begin Kuali Foundation modification
 485  0
         Formatter formatter = getFormatter(type);
 486  
         // end Kuali Foundation modification
 487  0
         Object array = null;
 488  
         try {
 489  0
             array = Array.newInstance(type, strings.length);
 490  
         }
 491  0
         catch (Exception e) {
 492  0
             throw new FormatException(CREATE_MSG + type, e);
 493  0
         }
 494  
 
 495  0
         for (int i = 0; i < strings.length; i++) {
 496  0
             Object value = formatter.convertToObject(strings[i]);
 497  
             // begin Kuali Foundation modification
 498  0
             ArrayUtils.setArrayValue(array, type, value, i);
 499  
             // end Kuali Foundation modification
 500  
         }
 501  
 
 502  0
         return array;
 503  
     }
 504  
 
 505  
     public static String unwrapString(Object target) {
 506  
 
 507  0
         if (target.getClass().isArray()) {
 508  0
             String wrapper[] = (String[]) target;
 509  0
             return wrapper.length > 0 ? wrapper[0] : null;
 510  
         }
 511  
                 // begin Kuali Foundation modification
 512  
         // if target object is null, return a null String
 513  0
         else if (target == null) {
 514  0
             return new String();
 515  
         }
 516  
 
 517  
         // otherwise, return the string value of the object, with the hope
 518  
         // that the toString() has been meaningfully overriden
 519  
         else {
 520  0
             return target.toString();
 521  
         }
 522  
         // end Kuali Foundation modification
 523  
     }
 524  
 
 525  
     public static boolean isNullValue(Object obj) {
 526  0
         if (obj == null)
 527  0
             return true;
 528  
 
 529  
                 // begin Kuali Foundation modification
 530  0
         if ((obj instanceof String) && StringUtils.isEmpty((String) obj))
 531  0
             return true;
 532  
         // end Kuali Foundation modification
 533  
 
 534  0
         return false;
 535  
     }
 536  
 
 537  
     public static boolean isEmptyValue(Object obj) {
 538  0
         if (obj == null)
 539  0
             return true;
 540  
         // begin Kuali Foundation modification
 541  0
         if ((obj instanceof String) && StringUtils.isEmpty((String) obj))
 542  0
             return true;
 543  
         // end Kuali Foundation modification
 544  0
         Class type = obj.getClass();
 545  0
         if (type.isArray()) {
 546  0
             Class compType = type.getComponentType();
 547  0
             if (compType.isPrimitive())
 548  0
                 return false;
 549  0
             if (((Object[]) obj).length == 0)
 550  0
                 return true;
 551  0
             if (((Object[]) obj)[0] == null)
 552  0
                 return true;
 553  0
             if (String.class.isAssignableFrom(compType)) {
 554  
                     // begin Kuali Foundation modification
 555  0
                 return StringUtils.isEmpty(((String[]) obj)[0]);
 556  
                 // end Kuali Foundation modification
 557  
             }
 558  
         }
 559  0
         return false;
 560  
     }
 561  
 
 562  
     /**
 563  
      * begin Kuali Foundation modification
 564  
      * This class sets the value of an element of an array of primitives at the supplied index.
 565  
      * end Kuali Foundation modification
 566  
      * @author Kuali Rice Team (rice.collab@kuali.org)
 567  
      */
 568  1
     protected static final class ArrayUtils {
 569  
 
 570  0
         private ArrayUtils() {
 571  0
             throw new UnsupportedOperationException("do not call");
 572  
         }
 573  
 
 574  
         /**
 575  
          * Sets the value of an element of an array of primitives at the supplied index.
 576  
          *
 577  
          * @param array An array.
 578  
          * @param type The component type of the array.
 579  
          * @param index An array index.
 580  
          */
 581  
         public static void setArrayValue(Object array, Class type, Object value, int index) {
 582  0
             if (!type.isPrimitive())
 583  0
                 Array.set(array, index, value);
 584  0
             else if (type.isAssignableFrom(Boolean.TYPE))
 585  0
                 Array.setBoolean(array, index, (Boolean) value);
 586  0
             else if (type.isAssignableFrom(Character.TYPE))
 587  0
                 Array.setChar(array, index, (Character) value);
 588  0
             else if (type.isAssignableFrom(Byte.TYPE))
 589  0
                 Array.setByte(array, index, (Byte) value);
 590  0
             else if (type.isAssignableFrom(Integer.TYPE))
 591  0
                 Array.setInt(array, index, (Integer) value);
 592  0
             else if (type.isAssignableFrom(Short.TYPE))
 593  0
                 Array.setShort(array, index, (Short) value);
 594  0
             else if (type.isAssignableFrom(Long.TYPE))
 595  0
                 Array.setLong(array, index, (Long) value);
 596  0
             else if (type.isAssignableFrom(Float.TYPE))
 597  0
                 Array.setFloat(array, index, (Float) value);
 598  0
             else if (type.isAssignableFrom(Double.TYPE))
 599  0
                 Array.setDouble(array, index, (Double) value);
 600  0
         }
 601  
 
 602  
         public static Object toObject(Object value) {
 603  0
             if (!value.getClass().isArray())
 604  0
                 return value;
 605  
 
 606  0
             Class type = value.getClass().getComponentType();
 607  0
             if (Array.getLength(value) == 0)
 608  0
                 return null;
 609  0
             if (!type.isPrimitive())
 610  0
                 return Array.get(value, 0);
 611  0
             if (boolean.class.isAssignableFrom(type))
 612  0
                 return Array.getBoolean(value, 0);
 613  0
             if (char.class.isAssignableFrom(type))
 614  0
                 return new Character(Array.getChar(value, 0));
 615  0
             if (byte.class.isAssignableFrom(type))
 616  0
                 return new Byte(Array.getByte(value, 0));
 617  0
             if (int.class.isAssignableFrom(type))
 618  0
                 return new Integer(Array.getInt(value, 0));
 619  0
             if (long.class.isAssignableFrom(type))
 620  0
                 return new Long(Array.getLong(value, 0));
 621  0
             if (short.class.isAssignableFrom(type))
 622  0
                 return new Short(Array.getShort(value, 0));
 623  0
             if (double.class.isAssignableFrom(type))
 624  0
                 return new Double(Array.getDouble(value, 0));
 625  0
             if (float.class.isAssignableFrom(type))
 626  0
                 return new Float(Array.getFloat(value, 0));
 627  
 
 628  0
             return null;
 629  
         }
 630  
 
 631  
         public static Object toString(Object array, Class type) {
 632  0
             if (boolean.class.isAssignableFrom(type))
 633  0
                 return Boolean.toString(((boolean[]) array)[0]);
 634  0
             if (char.class.isAssignableFrom(type))
 635  0
                 return Character.toString(((char[]) array)[0]);
 636  0
             if (byte.class.isAssignableFrom(type))
 637  0
                 return Byte.toString(((byte[]) array)[0]);
 638  0
             if (int.class.isAssignableFrom(type))
 639  0
                 return Integer.toString(((int[]) array)[0]);
 640  0
             if (long.class.isAssignableFrom(type))
 641  0
                 return Long.toString(((long[]) array)[0]);
 642  0
             if (short.class.isAssignableFrom(type))
 643  0
                 return Short.toString(((short[]) array)[0]);
 644  0
             if (double.class.isAssignableFrom(type))
 645  0
                 return Double.toString(((double[]) array)[0]);
 646  0
             if (float.class.isAssignableFrom(type))
 647  0
                 return Float.toString(((float[]) array)[0]);
 648  
 
 649  0
             return ((String[]) array)[0];
 650  
         }
 651  
     }
 652  
 }