diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/JSON.java b/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/JSON.java index d40567752eb..894a17fa860 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/JSON.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/JSON.java @@ -39,8 +39,7 @@ import org.eclipse.jetty.util.log.Logger; /** * JSON Parser and Generator. - * - *
+ *
* This class provides some static methods to convert POJOs to and from JSON * notation. The mapping from JSON to java is: * @@ -52,9 +51,7 @@ import org.eclipse.jetty.util.log.Logger; * null ==> null * bool ==> Boolean * - * - * - *+ * The java to JSON mapping is: * *
@@ -68,30 +65,27 @@ import org.eclipse.jetty.util.log.Logger; * Object --> string (dubious!) ** - * - *
* The interface {@link JSON.Convertible} may be implemented by classes that * wish to externalize and initialize specific fields to and from JSON objects. * Only directed acyclic graphs of objects are supported. - *
- *+ *
* The interface {@link JSON.Generator} may be implemented by classes that know * how to render themselves as JSON and the {@link #toString(Object)} method * will use {@link JSON.Generator#addJSON(Appendable)} to generate the JSON. * The class {@link JSON.Literal} may be used to hold pre-generated JSON object. - *+ *
* The interface {@link JSON.Convertor} may be implemented to provide static - * convertors for objects that may be registered with - * {@link #registerConvertor(Class, org.eclipse.jetty.util.ajax.JSON.Convertor)} - * . These convertors are looked up by class, interface and super class by + * converters for objects that may be registered with + * {@link #registerConvertor(Class, Convertor)}. + * These converters are looked up by class, interface and super class by * {@link #getConvertor(Class)}. - * - *If a JSON object has a "class" field, then a java class for that name is - * looked up and the method {@link convertTo(Class,Map)} is used to find a - * Convertor for that class. If a JSON object has a "x-class" field then a - * direct lookup for a Convertor for that named x-class is done, so that none - * java classes may be converted. - *
+ * + * If a JSON object has a "class" field, then a java class for that name is + * loaded and the method {@link #convertTo(Class,Map)} is used to find a + * {@link JSON.Convertor} for that class. + * + * If a JSON object has a "x-class" field then a direct lookup for a + * {@link JSON.Convertor} for that class name is done (without loading the class). */ public class JSON { @@ -105,7 +99,6 @@ public class JSON { } - /* ------------------------------------------------------------ */ /** * @return the initial stringBuffer size to use when creating JSON strings * (default 1024) @@ -115,7 +108,6 @@ public class JSON return _stringBufferSize; } - /* ------------------------------------------------------------ */ /** * @param stringBufferSize * the initial stringBuffer size to use when creating JSON @@ -126,7 +118,6 @@ public class JSON _stringBufferSize = stringBufferSize; } - /* ------------------------------------------------------------ */ /** * Register a {@link Convertor} for a class or interface. * @@ -140,19 +131,16 @@ public class JSON DEFAULT.addConvertor(forClass,convertor); } - /* ------------------------------------------------------------ */ public static JSON getDefault() { return DEFAULT; } - /* ------------------------------------------------------------ */ @Deprecated public static void setDefault(JSON json) { } - /* ------------------------------------------------------------ */ public static String toString(Object object) { StringBuilder buffer = new StringBuilder(DEFAULT.getStringBufferSize()); @@ -160,7 +148,6 @@ public class JSON return buffer.toString(); } - /* ------------------------------------------------------------ */ public static String toString(Map object) { StringBuilder buffer = new StringBuilder(DEFAULT.getStringBufferSize()); @@ -168,7 +155,6 @@ public class JSON return buffer.toString(); } - /* ------------------------------------------------------------ */ public static String toString(Object[] array) { StringBuilder buffer = new StringBuilder(DEFAULT.getStringBufferSize()); @@ -176,7 +162,6 @@ public class JSON return buffer.toString(); } - /* ------------------------------------------------------------ */ /** * @param s * String containing JSON object or array. @@ -187,7 +172,6 @@ public class JSON return DEFAULT.parse(new StringSource(s),false); } - /* ------------------------------------------------------------ */ /** * @param s * String containing JSON object or array. @@ -200,7 +184,6 @@ public class JSON return DEFAULT.parse(new StringSource(s),stripOuterComment); } - /* ------------------------------------------------------------ */ /** * @param in * Reader containing JSON object or array. @@ -211,7 +194,6 @@ public class JSON return DEFAULT.parse(new ReaderSource(in),false); } - /* ------------------------------------------------------------ */ /** * @param in * Reader containing JSON object or array. @@ -224,7 +206,6 @@ public class JSON return DEFAULT.parse(new ReaderSource(in),stripOuterComment); } - /* ------------------------------------------------------------ */ /** * @deprecated use {@link #parse(Reader)} * @param in @@ -237,7 +218,6 @@ public class JSON return DEFAULT.parse(new StringSource(IO.toString(in)),false); } - /* ------------------------------------------------------------ */ /** * @deprecated use {@link #parse(Reader, boolean)} * @param in @@ -252,7 +232,6 @@ public class JSON return DEFAULT.parse(new StringSource(IO.toString(in)),stripOuterComment); } - /* ------------------------------------------------------------ */ /** * Convert Object to JSON * @@ -267,7 +246,6 @@ public class JSON return buffer.toString(); } - /* ------------------------------------------------------------ */ /** * Convert JSON to Object * @@ -287,7 +265,6 @@ public class JSON append((Appendable)buffer,object); } - /* ------------------------------------------------------------ */ /** * Append object as JSON to string buffer. * @@ -301,32 +278,58 @@ public class JSON try { if (object == null) + { buffer.append("null"); - else if (object instanceof Convertible) - appendJSON(buffer,(Convertible)object); - else if (object instanceof Generator) - appendJSON(buffer,(Generator)object); + } + // Most likely first else if (object instanceof Map) + { appendMap(buffer,(Map)object); - else if (object instanceof Collection) - appendArray(buffer,(Collection)object); - else if (object.getClass().isArray()) - appendArray(buffer,object); - else if (object instanceof Number) - appendNumber(buffer,(Number)object); - else if (object instanceof Boolean) - appendBoolean(buffer,(Boolean)object); - else if (object instanceof Character) - appendString(buffer,object.toString()); + } else if (object instanceof String) + { appendString(buffer,(String)object); + } + else if (object instanceof Number) + { + appendNumber(buffer,(Number)object); + } + else if (object instanceof Boolean) + { + appendBoolean(buffer,(Boolean)object); + } + else if (object.getClass().isArray()) + { + appendArray(buffer,object); + } + else if (object instanceof Character) + { + appendString(buffer,object.toString()); + } + else if (object instanceof Convertible) + { + appendJSON(buffer,(Convertible)object); + } + else if (object instanceof Generator) + { + appendJSON(buffer,(Generator)object); + } else { + // Check Convertor before Collection to support JSONCollectionConvertor Convertor convertor = getConvertor(object.getClass()); if (convertor != null) + { appendJSON(buffer,convertor,object); + } + else if (object instanceof Collection) + { + appendArray(buffer,(Collection)object); + } else + { appendString(buffer,object.toString()); + } } } catch (IOException e) @@ -335,14 +338,12 @@ public class JSON } } - /* ------------------------------------------------------------ */ @Deprecated public void appendNull(StringBuffer buffer) { appendNull((Appendable)buffer); } - /* ------------------------------------------------------------ */ public void appendNull(Appendable buffer) { try @@ -355,14 +356,12 @@ public class JSON } } - /* ------------------------------------------------------------ */ @Deprecated public void appendJSON(final StringBuffer buffer, final Convertor convertor, final Object object) { appendJSON((Appendable)buffer,convertor,object); } - /* ------------------------------------------------------------ */ public void appendJSON(final Appendable buffer, final Convertor convertor, final Object object) { appendJSON(buffer,new Convertible() @@ -378,14 +377,12 @@ public class JSON }); } - /* ------------------------------------------------------------ */ @Deprecated public void appendJSON(final StringBuffer buffer, Convertible converter) { appendJSON((Appendable)buffer,converter); } - /* ------------------------------------------------------------ */ public void appendJSON(final Appendable buffer, Convertible converter) { ConvertableOutput out=new ConvertableOutput(buffer); @@ -393,27 +390,23 @@ public class JSON out.complete(); } - /* ------------------------------------------------------------ */ @Deprecated public void appendJSON(StringBuffer buffer, Generator generator) { generator.addJSON(buffer); } - /* ------------------------------------------------------------ */ public void appendJSON(Appendable buffer, Generator generator) { generator.addJSON(buffer); } - /* ------------------------------------------------------------ */ @Deprecated public void appendMap(StringBuffer buffer, Map,?> map) { appendMap((Appendable)buffer,map); } - /* ------------------------------------------------------------ */ public void appendMap(Appendable buffer, Map,?> map) { try @@ -444,14 +437,12 @@ public class JSON } } - /* ------------------------------------------------------------ */ @Deprecated public void appendArray(StringBuffer buffer, Collection collection) { - appendArray((Appendable)buffer,collection); + appendArray((Appendable)buffer,collection); } - /* ------------------------------------------------------------ */ public void appendArray(Appendable buffer, Collection collection) { try @@ -482,14 +473,12 @@ public class JSON } } - /* ------------------------------------------------------------ */ @Deprecated public void appendArray(StringBuffer buffer, Object array) { - appendArray((Appendable)buffer,array); + appendArray((Appendable)buffer,array); } - /* ------------------------------------------------------------ */ public void appendArray(Appendable buffer, Object array) { try @@ -518,14 +507,12 @@ public class JSON } } - /* ------------------------------------------------------------ */ @Deprecated public void appendBoolean(StringBuffer buffer, Boolean b) { appendBoolean((Appendable)buffer,b); } - /* ------------------------------------------------------------ */ public void appendBoolean(Appendable buffer, Boolean b) { try @@ -535,7 +522,7 @@ public class JSON appendNull(buffer); return; } - buffer.append(b.booleanValue()?"true":"false"); + buffer.append(b?"true":"false"); } catch (IOException e) { @@ -543,14 +530,12 @@ public class JSON } } - /* ------------------------------------------------------------ */ @Deprecated public void appendNumber(StringBuffer buffer, Number number) { - appendNumber((Appendable)buffer,number); + appendNumber((Appendable)buffer,number); } - /* ------------------------------------------------------------ */ public void appendNumber(Appendable buffer, Number number) { try @@ -568,14 +553,12 @@ public class JSON } } - /* ------------------------------------------------------------ */ @Deprecated public void appendString(StringBuffer buffer, String string) { - appendString((Appendable)buffer,string); + appendString((Appendable)buffer,string); } - /* ------------------------------------------------------------ */ public void appendString(Appendable buffer, String string) { if (string == null) @@ -589,37 +572,31 @@ public class JSON // Parsing utilities - /* ------------------------------------------------------------ */ protected String toString(char[] buffer, int offset, int length) { return new String(buffer,offset,length); } - /* ------------------------------------------------------------ */ protected Map@@ -677,7 +652,7 @@ public class JSON if (convertor == null && this != DEFAULT) convertor = DEFAULT.getConvertor(cls); - while (convertor == null && cls != null && cls != Object.class) + while (convertor == null && cls != Object.class) { Class[] ifs = cls.getInterfaces(); int i = 0; @@ -692,7 +667,6 @@ public class JSON return convertor; } - /* ------------------------------------------------------------ */ /** * Register a {@link JSON.Convertor} for a named class or interface. * @@ -706,7 +680,6 @@ public class JSON _convertors.put(name,convertor); } - /* ------------------------------------------------------------ */ /** * Lookup a convertor for a named class. * @@ -716,14 +689,12 @@ public class JSON */ public Convertor getConvertorFor(String name) { - String clsName = name; - Convertor convertor = _convertors.get(clsName); + Convertor convertor = _convertors.get(name); if (convertor == null && this != DEFAULT) - convertor = DEFAULT.getConvertorFor(clsName); + convertor = DEFAULT.getConvertorFor(name); return convertor; } - /* ------------------------------------------------------------ */ public Object parse(Source source, boolean stripOuterComment) { int comment_state = 0; // 0=no comment, 1="/", 2="/*", 3="/* *" -1="//" @@ -811,7 +782,6 @@ public class JSON return o; } - /* ------------------------------------------------------------ */ public Object parse(Source source) { int comment_state = 0; // 0=no comment, 1="/", 2="/*", 3="/* *" -1="//" @@ -911,13 +881,11 @@ public class JSON return null; } - /* ------------------------------------------------------------ */ protected Object handleUnknown(Source source, char c) { throw new IllegalStateException("unknown char '" + c + "'(" + (int)c + ") in " + source); } - /* ------------------------------------------------------------ */ protected Object parseObject(Source source) { if (source.next() != '{') @@ -952,10 +920,10 @@ public class JSON String xclassname = (String)map.get("x-class"); if (xclassname != null) { - Convertor c = getConvertorFor(xclassname); - if (c != null) - return c.fromJSON(map); - LOG.warn("no Convertor for xclassname '%s'", xclassname); + Convertor c = getConvertorFor(xclassname); + if (c != null) + return c.fromJSON(map); + LOG.warn("No Convertor for x-class '{}'", xclassname); } String classname = (String)map.get("class"); @@ -968,14 +936,13 @@ public class JSON } catch (ClassNotFoundException e) { - LOG.warn("no Class for classname '%s'", classname); + LOG.warn("No Class for '{}'", classname); } } - + return map; } - /* ------------------------------------------------------------ */ protected Object parseArray(Source source) { if (source.next() != '[') @@ -1042,7 +1009,6 @@ public class JSON throw new IllegalStateException("unexpected end of array"); } - /* ------------------------------------------------------------ */ protected String parseString(Source source) { if (source.next() != '"') @@ -1110,7 +1076,6 @@ public class JSON else if (c == '\\') { escape = true; - continue; } else if (c == '\"') { @@ -1118,7 +1083,9 @@ public class JSON return toString(scratch,0,i); } else + { scratch[i++] = c; + } } // Missing end quote, but return string anyway ? @@ -1175,17 +1142,19 @@ public class JSON else if (c == '\\') { escape = true; - continue; } else if (c == '\"') + { break; + } else + { builder.append(c); + } } return builder.toString(); } - /* ------------------------------------------------------------ */ public Number parseNumber(Source source) { boolean minus = false; @@ -1270,7 +1239,6 @@ public class JSON } - /* ------------------------------------------------------------ */ protected void seekTo(char seek, Source source) { while (source.hasNext()) @@ -1287,7 +1255,6 @@ public class JSON throw new IllegalStateException("Expected '" + seek + "'"); } - /* ------------------------------------------------------------ */ protected char seekTo(String seek, Source source) { while (source.hasNext()) @@ -1306,7 +1273,6 @@ public class JSON throw new IllegalStateException("Expected one of '" + seek + "'"); } - /* ------------------------------------------------------------ */ protected static void complete(String seek, Source source) { int i = 0; @@ -1398,7 +1364,7 @@ public class JSON _buffer.append(c); QuotedStringTokenizer.quote(_buffer,name); _buffer.append(':'); - appendNumber(_buffer,new Double(value)); + appendNumber(_buffer, value); c = ','; } catch (IOException e) @@ -1444,7 +1410,6 @@ public class JSON } } - /* ------------------------------------------------------------ */ public interface Source { boolean hasNext(); @@ -1456,7 +1421,6 @@ public class JSON char[] scratchBuffer(); } - /* ------------------------------------------------------------ */ public static class StringSource implements Source { private final String string; @@ -1500,7 +1464,6 @@ public class JSON } } - /* ------------------------------------------------------------ */ public static class ReaderSource implements Source { private Reader _reader; @@ -1567,7 +1530,6 @@ public class JSON } - /* ------------------------------------------------------------ */ /** * JSON Output class for use by {@link Convertible}. */ @@ -1586,7 +1548,6 @@ public class JSON public void add(String name, boolean value); } - /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ /** * JSON Convertible object. Object can implement this interface in a similar @@ -1607,7 +1568,6 @@ public class JSON public void fromJSON(Map object); } - /* ------------------------------------------------------------ */ /** * Static JSON Convertor. *
@@ -1626,7 +1586,6 @@ public class JSON
public Object fromJSON(Map object);
}
- /* ------------------------------------------------------------ */
/**
* JSON Generator. A class that can add it's JSON representation directly to
* a StringBuffer. This is useful for object instances that are frequently
@@ -1637,7 +1596,6 @@ public class JSON
public void addJSON(Appendable buffer);
}
- /* ------------------------------------------------------------ */
/**
* A Literal JSON generator A utility instance of {@link JSON.Generator}
* that holds a pre-generated string on JSON text.
@@ -1646,7 +1604,6 @@ public class JSON
{
private String _json;
- /* ------------------------------------------------------------ */
/**
* Construct a literal JSON instance for use by
* {@link JSON#toString(Object)}. If {@link Log#isDebugEnabled()} is
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/JSONCollectionConvertor.java b/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/JSONCollectionConvertor.java
new file mode 100644
index 00000000000..9629e3c8f6e
--- /dev/null
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/JSONCollectionConvertor.java
@@ -0,0 +1,50 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+//
+
+package org.eclipse.jetty.util.ajax;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import org.eclipse.jetty.util.Loader;
+
+public class JSONCollectionConvertor implements JSON.Convertor
+{
+ public void toJSON(Object obj, JSON.Output out)
+ {
+ out.addClass(obj.getClass());
+ out.add("list", ((Collection)obj).toArray());
+ }
+
+ public Object fromJSON(Map object)
+ {
+ try
+ {
+ Collection result = (Collection)Loader.loadClass(getClass(), (String)object.get("class")).newInstance();
+ Collections.addAll(result, (Object[])object.get("list"));
+ return result;
+ }
+ catch (Exception x)
+ {
+ if (x instanceof RuntimeException)
+ throw (RuntimeException)x;
+ throw new RuntimeException(x);
+ }
+ }
+}
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/JSONDateConvertor.java b/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/JSONDateConvertor.java
index a244b1fc7c8..e50206b0f87 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/JSONDateConvertor.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/JSONDateConvertor.java
@@ -40,9 +40,10 @@ import org.eclipse.jetty.util.log.Logger;
public class JSONDateConvertor implements JSON.Convertor
{
private static final Logger LOG = Log.getLogger(JSONDateConvertor.class);
- private boolean _fromJSON;
- DateCache _dateCache;
- SimpleDateFormat _format;
+
+ private final boolean _fromJSON;
+ private final DateCache _dateCache;
+ private final SimpleDateFormat _format;
public JSONDateConvertor()
{
@@ -53,7 +54,7 @@ public class JSONDateConvertor implements JSON.Convertor
{
this(DateCache.DEFAULT_FORMAT,TimeZone.getTimeZone("GMT"),fromJSON);
}
-
+
public JSONDateConvertor(String format,TimeZone zone,boolean fromJSON)
{
_dateCache=new DateCache(format);
@@ -62,7 +63,7 @@ public class JSONDateConvertor implements JSON.Convertor
_format=new SimpleDateFormat(format);
_format.setTimeZone(zone);
}
-
+
public JSONDateConvertor(String format, TimeZone zone, boolean fromJSON, Locale locale)
{
_dateCache = new DateCache(format, locale);
@@ -71,7 +72,7 @@ public class JSONDateConvertor implements JSON.Convertor
_format = new SimpleDateFormat(format, new DateFormatSymbols(locale));
_format.setTimeZone(zone);
}
-
+
public Object fromJSON(Map map)
{
if (!_fromJSON)
@@ -85,7 +86,7 @@ public class JSONDateConvertor implements JSON.Convertor
}
catch(Exception e)
{
- LOG.warn(e);
+ LOG.warn(e);
}
return null;
}
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/JSONEnumConvertor.java b/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/JSONEnumConvertor.java
index 83f8ba29daa..54c10c62f7b 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/JSONEnumConvertor.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/JSONEnumConvertor.java
@@ -32,7 +32,7 @@ import org.eclipse.jetty.util.log.Logger;
* If fromJSON is true in the constructor, the JSON generated will
* be of the form {class="com.acme.TrafficLight",value="Green"}
* If fromJSON is false, then only the string value of the enum is generated.
- *
+ *
*
*/
public class JSONEnumConvertor implements JSON.Convertor
@@ -43,8 +43,8 @@ public class JSONEnumConvertor implements JSON.Convertor
{
try
{
- Class e = Loader.loadClass(getClass(),"java.lang.Enum");
- _valueOf=e.getMethod("valueOf",new Class[]{Class.class,String.class});
+ Class> e = Loader.loadClass(getClass(),"java.lang.Enum");
+ _valueOf=e.getMethod("valueOf",Class.class,String.class);
}
catch(Exception e)
{
@@ -56,12 +56,12 @@ public class JSONEnumConvertor implements JSON.Convertor
{
this(false);
}
-
+
public JSONEnumConvertor(boolean fromJSON)
{
_fromJSON=fromJSON;
}
-
+
public Object fromJSON(Map map)
{
if (!_fromJSON)
@@ -69,11 +69,11 @@ public class JSONEnumConvertor implements JSON.Convertor
try
{
Class c=Loader.loadClass(getClass(),(String)map.get("class"));
- return _valueOf.invoke(null,new Object[]{c,map.get("value")});
+ return _valueOf.invoke(null,c,map.get("value"));
}
catch(Exception e)
{
- LOG.warn(e);
+ LOG.warn(e);
}
return null;
}
@@ -90,5 +90,4 @@ public class JSONEnumConvertor implements JSON.Convertor
out.add(((Enum)obj).name());
}
}
-
}
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/ajax/JSONCollectionConvertorTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/ajax/JSONCollectionConvertorTest.java
new file mode 100644
index 00000000000..65344839473
--- /dev/null
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/ajax/JSONCollectionConvertorTest.java
@@ -0,0 +1,112 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+//
+
+package org.eclipse.jetty.util.ajax;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class JSONCollectionConvertorTest
+{
+ @Test
+ public void testArrayList() throws Exception
+ {
+ List