Commits

jkuh...@d4b077e3-5828-0410-b394-cb2b42183085  committed 85d4f62

Added check in OgnlOps to throw an IllegalArgumentException if a value can't be converted to a requested type. Prevents setter expressions from silently failing when the wrong object type is used.

  • Participants
  • Parent commits 750835c

Comments (0)

Files changed (6)

   </component>
   <component name="ChangeListManager">
     <list default="true" name="Default" comment="">
-      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/java/ognl/MethodFailedException.java" afterPath="$PROJECT_DIR$/src/java/ognl/MethodFailedException.java" />
-      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/test/java/org/ognl/test/OperatorTest.java" afterPath="$PROJECT_DIR$/src/test/java/org/ognl/test/OperatorTest.java" />
-      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/OGNL.iml" afterPath="$PROJECT_DIR$/OGNL.iml" />
-      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/test/java/org/ognl/test/PropertyNotFoundTest.java" afterPath="$PROJECT_DIR$/src/test/java/org/ognl/test/PropertyNotFoundTest.java" />
-      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/java/ognl/ExpressionSyntaxException.java" afterPath="$PROJECT_DIR$/src/java/ognl/ExpressionSyntaxException.java" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/test/java/org/ognl/test/SetterTest.java" afterPath="$PROJECT_DIR$/src/test/java/org/ognl/test/SetterTest.java" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/java/ognl/ASTProperty.java" afterPath="$PROJECT_DIR$/src/java/ognl/ASTProperty.java" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/java/ognl/ObjectPropertyAccessor.java" afterPath="$PROJECT_DIR$/src/java/ognl/ObjectPropertyAccessor.java" />
       <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/java/ognl/OgnlOps.java" afterPath="$PROJECT_DIR$/src/java/ognl/OgnlOps.java" />
       <change type="MODIFICATION" beforePath="$PROJECT_DIR$/OGNL.iws" afterPath="$PROJECT_DIR$/OGNL.iws" />
-      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/OGNL.ipr" afterPath="$PROJECT_DIR$/OGNL.ipr" />
-      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/java/ognl/OgnlRuntime.java" afterPath="$PROJECT_DIR$/src/java/ognl/OgnlRuntime.java" />
-      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/java/ognl/NoSuchPropertyException.java" afterPath="$PROJECT_DIR$/src/java/ognl/NoSuchPropertyException.java" />
-      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/test/java/org/ognl/test/LambdaExpressionTest.java" afterPath="$PROJECT_DIR$/src/test/java/org/ognl/test/LambdaExpressionTest.java" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/test/java/org/ognl/test/objects/Root.java" afterPath="$PROJECT_DIR$/src/test/java/org/ognl/test/objects/Root.java" />
     </list>
   </component>
   <component name="ChangesViewManager" flattened_view="true" />
       <showLibraryContents />
       <hideEmptyPackages />
       <abbreviatePackageNames />
-      <showStructure ProjectPane="false" PackagesPane="false" Scope="false" Favorites="false" />
+      <showStructure Favorites="false" ProjectPane="false" Scope="false" PackagesPane="false" />
       <autoscrollToSource />
       <autoscrollFromSource />
       <sortByType />
     <option name="SHOW_DIALOG" value="true" />
   </component>
   <component name="RecentsManager" />
-  <component name="RestoreUpdateTree">
-    <UpdateInfo date="3/18/07 12:38 PM" ActionInfo="_Update">
-      <UpdatedFiles>
-        <FILE-GROUP>
-          <option name="myUpdateName" value="Updated from server" />
-          <option name="myStatusName" value="Changed on server" />
-          <option name="mySupportsDeletion" value="false" />
-          <option name="myCanBeAbsent" value="false" />
-          <option name="myId" value="CHANGED_ON_SERVER" />
-          <FILE-GROUP>
-            <option name="myUpdateName" value="Updated" />
-            <option name="myStatusName" value="Changed" />
-            <option name="mySupportsDeletion" value="false" />
-            <option name="myCanBeAbsent" value="false" />
-            <option name="myId" value="UPDATED" />
-          </FILE-GROUP>
-          <FILE-GROUP>
-            <option name="myUpdateName" value="Created" />
-            <option name="myStatusName" value="Created" />
-            <option name="mySupportsDeletion" value="false" />
-            <option name="myCanBeAbsent" value="false" />
-            <option name="myId" value="CREATED" />
-          </FILE-GROUP>
-          <FILE-GROUP>
-            <option name="myUpdateName" value="Deleted" />
-            <option name="myStatusName" value="Deleted" />
-            <option name="mySupportsDeletion" value="false" />
-            <option name="myCanBeAbsent" value="true" />
-            <option name="myId" value="REMOVED_FROM_REPOSITORY" />
-          </FILE-GROUP>
-          <FILE-GROUP>
-            <option name="myUpdateName" value="Restored" />
-            <option name="myStatusName" value="Will be restored" />
-            <option name="mySupportsDeletion" value="false" />
-            <option name="myCanBeAbsent" value="false" />
-            <option name="myId" value="RESTORED" />
-          </FILE-GROUP>
-        </FILE-GROUP>
-        <FILE-GROUP>
-          <option name="myUpdateName" value="Modified" />
-          <option name="myStatusName" value="Modified" />
-          <option name="mySupportsDeletion" value="false" />
-          <option name="myCanBeAbsent" value="false" />
-          <option name="myId" value="MODIFIED" />
-          <PATH>$PROJECT_DIR$/OGNL.ipr</PATH>
-          <PATH>$PROJECT_DIR$/OGNL.iws</PATH>
-        </FILE-GROUP>
-        <FILE-GROUP>
-          <option name="myUpdateName" value="Skipped" />
-          <option name="myStatusName" value="Skipped" />
-          <option name="mySupportsDeletion" value="false" />
-          <option name="myCanBeAbsent" value="false" />
-          <option name="myId" value="SKIPPED" />
-        </FILE-GROUP>
-        <FILE-GROUP>
-          <option name="myUpdateName" value="Merged with conflicts" />
-          <option name="myStatusName" value="Will be merged with conflicts" />
-          <option name="mySupportsDeletion" value="false" />
-          <option name="myCanBeAbsent" value="false" />
-          <option name="myId" value="MERGED_WITH_CONFLICTS" />
-        </FILE-GROUP>
-        <FILE-GROUP>
-          <option name="myUpdateName" value="Merged" />
-          <option name="myStatusName" value="Will be merged" />
-          <option name="mySupportsDeletion" value="false" />
-          <option name="myCanBeAbsent" value="false" />
-          <option name="myId" value="MERGED" />
-        </FILE-GROUP>
-        <FILE-GROUP>
-          <option name="myUpdateName" value="Not in repository" />
-          <option name="myStatusName" value="Not in repository" />
-          <option name="mySupportsDeletion" value="true" />
-          <option name="myCanBeAbsent" value="false" />
-          <option name="myId" value="UNKNOWN" />
-          <PATH>$PROJECT_DIR$/test-output</PATH>
-        </FILE-GROUP>
-        <FILE-GROUP>
-          <option name="myUpdateName" value="Locally added" />
-          <option name="myStatusName" value="Locally added" />
-          <option name="mySupportsDeletion" value="false" />
-          <option name="myCanBeAbsent" value="false" />
-          <option name="myId" value="LOCALLY_ADDED" />
-        </FILE-GROUP>
-        <FILE-GROUP>
-          <option name="myUpdateName" value="Locally removed" />
-          <option name="myStatusName" value="Locally removed" />
-          <option name="mySupportsDeletion" value="false" />
-          <option name="myCanBeAbsent" value="false" />
-          <option name="myId" value="LOCALLY_REMOVED" />
-        </FILE-GROUP>
-      </UpdatedFiles>
-    </UpdateInfo>
-  </component>
-  <component name="RunManager" selected="JUnit.PropertyTest">
-    <tempConfiguration default="false" name="PropertyTest" type="JUnit" factoryName="JUnit" enabled="false" merge="false">
+  <component name="RestoreUpdateTree" />
+  <component name="RunManager" selected="JUnit.SetterTest">
+    <tempConfiguration default="false" name="SetterTest" type="JUnit" factoryName="JUnit" enabled="false" merge="false">
       <pattern value="org.ognl.test.*" />
       <module name="OGNL" />
       <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
       <option name="ALTERNATIVE_JRE_PATH" />
       <option name="PACKAGE_NAME" value="org.ognl.test" />
-      <option name="MAIN_CLASS_NAME" value="org.ognl.test.PropertyTest" />
+      <option name="MAIN_CLASS_NAME" value="org.ognl.test.SetterTest" />
       <option name="METHOD_NAME" />
       <option name="TEST_OBJECT" value="class" />
       <option name="VM_PARAMETERS" />
       <option name="HOST" value="localhost" />
       <option name="PORT" value="5005" />
     </configuration>
+    <configuration default="true" type="Applet" factoryName="Applet">
+      <module name="" />
+      <option name="MAIN_CLASS_NAME" />
+      <option name="HTML_FILE_NAME" />
+      <option name="HTML_USED" value="false" />
+      <option name="WIDTH" value="400" />
+      <option name="HEIGHT" value="300" />
+      <option name="POLICY_FILE" value="$APPLICATION_HOME_DIR$/bin/appletviewer.policy" />
+      <option name="VM_PARAMETERS" />
+      <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+      <option name="ALTERNATIVE_JRE_PATH" />
+    </configuration>
     <configuration default="true" type="TestNG" factoryName="TestNG" enabled="false" merge="false">
       <module name="" />
       <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
       <option name="ENABLE_SWING_INSPECTOR" value="false" />
       <module name="" />
     </configuration>
-    <configuration default="true" type="Applet" factoryName="Applet">
-      <module name="" />
-      <option name="MAIN_CLASS_NAME" />
-      <option name="HTML_FILE_NAME" />
-      <option name="HTML_USED" value="false" />
-      <option name="WIDTH" value="400" />
-      <option name="HEIGHT" value="300" />
-      <option name="POLICY_FILE" value="$APPLICATION_HOME_DIR$/bin/appletviewer.policy" />
-      <option name="VM_PARAMETERS" />
-      <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
-      <option name="ALTERNATIVE_JRE_PATH" />
-    </configuration>
     <configuration default="true" type="#com.intellij.j2ee.web.tomcat.TomcatRunConfigurationFactory" factoryName="Remote">
       <option name="WORKING_DIRECTORY" />
       <option name="HOST" value="localhost" />
       <window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.2755187" order="3" />
       <window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.24046434" order="8" />
       <window_info id="Messages" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.2307054" order="8" />
-      <window_info id="Maven" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="-1" />
+      <window_info id="Maven" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="8" />
       <window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="7" />
       <window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" order="1" />
       <window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" order="0" />
       <window_info id="Module Dependencies" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="3" />
       <window_info id="Dependency Viewer" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="8" />
       <window_info id="File View" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="3" />
-      <window_info id="Project" active="true" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.21859786" order="0" />
+      <window_info id="Project" active="true" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.22346641" order="0" />
       <window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" order="2" />
       <window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" order="6" />
       <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25975105" order="2" />
     <option name="myLastEditedConfigurable" />
   </component>
   <component name="editorHistoryManager">
-    <entry file="file://$PROJECT_DIR$/src/java/ognl/ASTMethod.java">
-      <provider selected="true" editor-type-id="text-editor">
-        <state line="247" column="0" selection-start="9268" selection-end="9268" vertical-scroll-proportion="0.5494037">
-          <folding />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/src/test/java/org/ognl/test/StaticsAndConstructorsTest.java">
-      <provider selected="true" editor-type-id="text-editor">
-        <state line="61" column="0" selection-start="3438" selection-end="3438" vertical-scroll-proportion="0.38330495">
-          <folding />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/src/test/java/org/ognl/test/PropertyNotFoundTest.java">
-      <provider selected="true" editor-type-id="text-editor">
-        <state line="46" column="0" selection-start="2186" selection-end="2186" vertical-scroll-proportion="0.14054514">
-          <folding />
-        </state>
-      </provider>
-    </entry>
     <entry file="file://$PROJECT_DIR$/src/test/java/org/ognl/test/OperatorTest.java">
       <provider selected="true" editor-type-id="text-editor">
         <state line="46" column="52" selection-start="2491" selection-end="2491" vertical-scroll-proportion="0.21720614">
         </state>
       </provider>
     </entry>
-    <entry file="file://$PROJECT_DIR$/src/test/java/org/ognl/test/objects/Root.java">
-      <provider selected="true" editor-type-id="text-editor">
-        <state line="229" column="4" selection-start="6886" selection-end="6886" vertical-scroll-proportion="1.5834754">
-          <folding />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/src/java/ognl/OgnlOps.java">
-      <provider selected="true" editor-type-id="text-editor">
-        <state line="798" column="0" selection-start="29745" selection-end="29745" vertical-scroll-proportion="0.28194207">
-          <folding />
-        </state>
-      </provider>
-    </entry>
     <entry file="file://$PROJECT_DIR$/src/test/java/org/ognl/test/OgnlTestCase.java">
       <provider selected="true" editor-type-id="text-editor">
         <state line="181" column="4" selection-start="7002" selection-end="7002" vertical-scroll-proportion="0.36115843">
         </state>
       </provider>
     </entry>
+    <entry file="file://$PROJECT_DIR$/src/test/java/org/ognl/test/objects/Root.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state line="294" column="21" selection-start="7964" selection-end="7964" vertical-scroll-proportion="1.2166276">
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/java/ognl/ASTProperty.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state line="372" column="13" selection-start="16026" selection-end="16026" vertical-scroll-proportion="0.40800682">
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/java/ognl/ObjectPropertyAccessor.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state line="270" column="0" selection-start="9969" selection-end="9969" vertical-scroll-proportion="0.923339">
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/test/java/org/ognl/test/SetterTest.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state line="74" column="0" selection-start="3877" selection-end="3877" vertical-scroll-proportion="0.33560476">
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/java/ognl/OgnlOps.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state line="596" column="12" selection-start="22373" selection-end="22373" vertical-scroll-proportion="0.4846678">
+          <folding />
+        </state>
+      </provider>
+    </entry>
   </component>
   <component name="testng.defaultConfiguration">
     <outputDirectory />

File src/java/ognl/ASTProperty.java

         result = OgnlRuntime.getProperty(context, source, property);
         
         if (result == null) {
-            result = OgnlRuntime.getNullHandler(OgnlRuntime.getTargetClass(source)).nullPropertyValue(context, source,
-                    property);
+            
+            result = OgnlRuntime.getNullHandler(OgnlRuntime.getTargetClass(source)).nullPropertyValue(context, source, property);
         }
         
         return result;
         if (context.getCurrentObject() == null)
             throw new UnsupportedCompilationException("Current target is null.");
         
-        //System.out.println("astproperty(setter) is indexed? : " + isIndexedAccess() + " child: " + _children[0].getClass().getName()
-         //       + " target: " + target.getClass().getName());
+        // System.out.println("astproperty(setter) is indexed? : " + isIndexedAccess() + " child: " + _children[0].getClass().getName()
+           //     + " target: " + target.getClass().getName());
         
         try {
             
             
             String name = ((ASTConst) _children[0]).getValue().toString();
             
-            Object tmp = target; //context.getCurrentObject();
+            Object tmp = target;
             
-            //System.out.println(" astprop(setter) : trying to get " + name + " on object target " + context.getCurrentObject().getClass().getName());
+            //System.out.println(" astprop(setter) : trying to set " + name + " on object target " + context.getCurrentObject().getClass().getName());
             
             if (!Iterator.class.isAssignableFrom(context.getCurrentObject().getClass()) 
                     || (Iterator.class.isAssignableFrom(context.getCurrentObject().getClass()) &&  name.indexOf("next") < 0)) {
             context.setCurrentType(m.getReturnType());
             context.setCurrentAccessor(OgnlRuntime.getSuperOrInterfaceClass(m, m.getDeclaringClass()));
         }
-        
+
         return result;
     }
 }

File src/java/ognl/ObjectPropertyAccessor.java

 /**
  * Implementation of PropertyAccessor that uses reflection on the target object's class to find a
  * field or a pair of set/get methods with the given property name.
- * 
+ *
  * @author Luke Blanshard (blanshlu@netscape.net)
  * @author Drew Davidson (drew@ognl.org)
  */
-public class ObjectPropertyAccessor implements PropertyAccessor
-{
+public class ObjectPropertyAccessor implements PropertyAccessor {
 
     /**
      * Returns OgnlRuntime.NotFound if the property does not exist.
      */
     public Object getPossibleProperty(Map context, Object target, String name)
-        throws OgnlException
+            throws OgnlException
     {
         Object result;
         OgnlContext ognlContext = (OgnlContext) context;
      * Returns OgnlRuntime.NotFound if the property does not exist.
      */
     public Object setPossibleProperty(Map context, Object target, String name, Object value)
-        throws OgnlException
+            throws OgnlException
     {
         Object result = null;
         OgnlContext ognlContext = (OgnlContext) context;
     }
 
     public boolean hasGetProperty(OgnlContext context, Object target, Object oname)
-        throws OgnlException
+            throws OgnlException
     {
         try {
             return OgnlRuntime.hasGetProperty(context, target, oname);
     }
 
     public boolean hasGetProperty(Map context, Object target, Object oname)
-        throws OgnlException
+            throws OgnlException
     {
         return hasGetProperty((OgnlContext) context, target, oname);
     }
 
     public boolean hasSetProperty(OgnlContext context, Object target, Object oname)
-        throws OgnlException
+            throws OgnlException
     {
         try {
             return OgnlRuntime.hasSetProperty(context, target, oname);
     }
 
     public boolean hasSetProperty(Map context, Object target, Object oname)
-        throws OgnlException
+            throws OgnlException
     {
         return hasSetProperty((OgnlContext) context, target, oname);
     }
 
     public Object getProperty(Map context, Object target, Object oname)
-        throws OgnlException
+            throws OgnlException
     {
         Object result = null;
         String name = oname.toString();
-        
+
         result = getPossibleProperty(context, target, name);
-        
-        if (result == OgnlRuntime.NotFound) { 
-            throw new NoSuchPropertyException(target, name); 
+
+        if (result == OgnlRuntime.NotFound) {
+            throw new NoSuchPropertyException(target, name);
         }
         return result;
     }
-    
+
     public void setProperty(Map context, Object target, Object oname, Object value)
-        throws OgnlException
+            throws OgnlException
     {
         String name = oname.toString();
 
-        if (setPossibleProperty(context, target, name, value) == OgnlRuntime.NotFound) { throw new NoSuchPropertyException(
-                target, name); }
+        if (setPossibleProperty(context, target, name, value) == OgnlRuntime.NotFound) {
+            throw new NoSuchPropertyException(target, name);
+        }
     }
-    
+
     public Class getPropertyClass(OgnlContext context, Object target, Object index)
     {
         try {
             Method m = OgnlRuntime.getReadMethod(target.getClass(), index.toString());
-            
+
             if (m == null) {
-                
+
                 if (String.class.isAssignableFrom(index.getClass()) && !target.getClass().isArray()) {
-                    String key = ((String)index).replaceAll("\"", "");
+                    String key = ((String) index).replaceAll("\"", "");
                     try {
                         Field f = target.getClass().getField(key);
                         if (f != null) {
-                            
+
                             return f.getType();
                         }
                     } catch (NoSuchFieldException e) {
                         return null;
                     }
                 }
-                
+
                 return null;
             }
-            
+
             return m.getReturnType();
-            
-        } catch (Throwable t) { throw new RuntimeException(t); }
+
+        } catch (Throwable t) {
+            throw new RuntimeException(t);
+        }
     }
-    
+
     public String getSourceAccessor(OgnlContext context, Object target, Object index)
     {
         try {
             Method m = OgnlRuntime.getReadMethod(target.getClass(), index.toString());
-            
+
             // try to get field if no method could be found 
-            
+
             if (m == null) {
-                
+
                 try {
                     if (String.class.isAssignableFrom(index.getClass()) && !target.getClass().isArray()) {
-                        String key = ((String)index).replaceAll("\"", "");
+                        String key = ((String) index).replaceAll("\"", "");
                         Field f = target.getClass().getField(key);
                         if (f != null) {
-                            
+
                             context.setCurrentType(f.getType());
                             context.setCurrentAccessor(f.getDeclaringClass());
-                            
+
                             return "." + f.getName();
                         }
                     }
                 } catch (NoSuchFieldException e) {
                     return "";
                 }
-                
-                
+
+
                 return "";
             }
-            
+
             context.setCurrentType(m.getReturnType());
             context.setCurrentAccessor(OgnlRuntime.getSuperOrInterfaceClass(m, m.getDeclaringClass()));
-            
+
             return "." + m.getName() + "()";
-            
-        } catch (Throwable t) { 
+
+        } catch (Throwable t) {
             if (UnsupportedCompilationException.class.isInstance(t))
-                throw (UnsupportedCompilationException)t;
+                throw (UnsupportedCompilationException) t;
             else
                 throw new RuntimeException(t);
         }
     }
-    
+
     public String getSourceSetter(OgnlContext context, Object target, Object index)
     {
         try {
             Method m = OgnlRuntime.getWriteMethod(target.getClass(), index.toString());
-            
+
             if (m == null)
                 return "";
-            
+
             if (m.getParameterTypes() == null || m.getParameterTypes().length <= 0)
                 return "";
-            
+
             Class parm = m.getParameterTypes()[0];
             String conversion = null;
-            
+
             if (m.getParameterTypes().length > 1)
                 throw new UnsupportedCompilationException("Object property accessors can only support single parameter setters.");
-            
+
             if (parm.isPrimitive()) {
-                
+
                 Class wrapClass = OgnlRuntime.getPrimitiveWrapperClass(parm);
-                
+
                 conversion = "((" + wrapClass.getName() + ")ognl.OgnlOps.convertValue($3," + wrapClass.getName()
-                + ".class, true))." + OgnlRuntime.getNumericValueGetter(wrapClass);
+                             + ".class, true))." + OgnlRuntime.getNumericValueGetter(wrapClass);
             } else if (parm.isArray()) {
-                
+
                 conversion = "((" + ExpressionCompiler.getCastString(parm) + ")ognl.OgnlOps.convertValue($3,"
-                +  ExpressionCompiler.getCastString(parm) + ".class))";
+                             + ExpressionCompiler.getCastString(parm) + ".class))";
             } else {
-                
-                conversion = "((" +parm.getName() + ")ognl.OgnlOps.convertValue($3," 
-                + parm.getName()
-                + ".class))";
+
+                conversion = "((" + parm.getName() + ")ognl.OgnlOps.convertValue($3,"
+                             + parm.getName()
+                             + ".class))";
             }
-            
+
             context.setCurrentType(m.getReturnType());
             context.setCurrentAccessor(OgnlRuntime.getSuperOrInterfaceClass(m, m.getDeclaringClass()));
-            
+
             return "." + m.getName() + "(" + conversion + ")";
-            
-        } catch (Throwable t) { 
+
+        } catch (Throwable t) {
             if (UnsupportedCompilationException.class.isInstance(t))
-                throw (UnsupportedCompilationException)t;
+                throw (UnsupportedCompilationException) t;
             else
                 throw new RuntimeException(t);
         }

File src/java/ognl/OgnlOps.java

         
         if (result == null && preventNulls)
             return value;
-        
+
+        if (value != null && result == null) {
+            
+            throw new IllegalArgumentException("Unable to convert type " + value.getClass().getName() + " of " + value + " to type of " + toType.getName());
+        }
+
         return result;
     }
     

File src/test/java/org/ognl/test/SetterTest.java

 import org.ognl.test.objects.Root;
 
 import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
 
 public class SetterTest extends OgnlTestCase
 {
     private static Root             ROOT = new Root();
 
+    static Set _list = new HashSet();
+    static {
+        _list.add("Test1");
+    }
+
     private static Object[][]       TESTS = {
             // Setting values
             { ROOT.getMap(), "newValue", null, new Integer(101) },
             { ROOT, "map.(newValue && aKey)", null, new Integer(54321)},
             { ROOT, "map.(someMissingKey && newValue)", null, null }, // again, no setting
             { null, "0", new Integer(0), null, InappropriateExpressionException.class }, // illegal for setting, no property
-            { ROOT, "map[0]=\"map.newValue\", map[0](#this)", new Integer(666), new Integer(888) }
+            { ROOT, "map[0]=\"map.newValue\", map[0](#this)", new Integer(666), new Integer(888) },
+            { ROOT, "selectedList", null, _list, IllegalArgumentException.class}
     };
 
     /*===================================================================

File src/test/java/org/ognl/test/objects/Root.java

     public int                      six = 6;
     private boolean _disabled;
     private Locale _selected = Locale.getDefault();
-    
+
+    private List _list;
+
     private int verbosity = 87;
     
     private BeanProvider _beanProvider = new BeanProviderImpl();
     {
         return _render;
     }
+
+    public void setSelectedList(List selected)
+    {
+        _list = selected;
+    }
+
+    public List getSelectedList()
+    {
+        return _list;
+    }
 }