Author: asoldano Date: Tue Oct 30 14:05:53 2012 New Revision: 1403707 URL: http://svn.apache.org/viewvc?rev=1403707&view=rev Log: Merged revisions 1401804 via svnmerge from https://svn.apache.org/repos/asf/cxf/branches/2.6.x-fixes
................ r1401804 | dkulp | 2012-10-24 20:17:02 +0200 (Wed, 24 Oct 2012) | 9 lines Merged revisions 1401614 via git cherry-pick from https://svn.apache.org/repos/asf/cxf/trunk ........ r1401614 | asoldano | 2012-10-24 06:42:00 -0400 (Wed, 24 Oct 2012) | 2 lines [CXF-4591] Applying patch from Richard Opalka ........ ................ Added: cxf/branches/2.5.x-fixes/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/Utils.java - copied unchanged from r1401804, cxf/branches/2.6.x-fixes/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/Utils.java Modified: cxf/branches/2.5.x-fixes/ (props changed) cxf/branches/2.5.x-fixes/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBContextInitializer.java cxf/branches/2.5.x-fixes/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBEncoderDecoder.java cxf/branches/2.5.x-fixes/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBSchemaInitializer.java Propchange: cxf/branches/2.5.x-fixes/ ------------------------------------------------------------------------------ svn:mergeinfo = /cxf/branches/2.6.x-fixes:1401804 Propchange: cxf/branches/2.5.x-fixes/ ------------------------------------------------------------------------------ Binary property 'svnmerge-integrated' - no diff available. Modified: cxf/branches/2.5.x-fixes/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBContextInitializer.java URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBContextInitializer.java?rev=1403707&r1=1403706&r2=1403707&view=diff ============================================================================== --- cxf/branches/2.5.x-fixes/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBContextInitializer.java (original) +++ cxf/branches/2.5.x-fixes/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBContextInitializer.java Tue Oct 30 14:05:53 2012 @@ -34,13 +34,11 @@ import java.util.HashSet; import java.util.Set; import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlSeeAlso; import javax.xml.bind.annotation.XmlTransient; import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.adapters.XmlAdapter; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters; import javax.xml.namespace.QName; @@ -200,7 +198,7 @@ class JAXBContextInitializer extends Ser if (anns != null) { for (Annotation a : anns) { if (XmlJavaTypeAdapter.class.isAssignableFrom(a.annotationType())) { - Type t = getTypeFromXmlAdapter((XmlJavaTypeAdapter)a); + Type t = Utils.getTypeFromXmlAdapter((XmlJavaTypeAdapter)a); if (t != null) { addType(t); } @@ -209,7 +207,7 @@ class JAXBContextInitializer extends Ser } XmlJavaTypeAdapter xjta = clazz.getAnnotation(XmlJavaTypeAdapter.class); if (xjta != null) { - Type t = getTypeFromXmlAdapter(xjta); + Type t = Utils.getTypeFromXmlAdapter(xjta); if (t != null) { addType(t); } @@ -221,7 +219,7 @@ class JAXBContextInitializer extends Ser globalAdapters.add(a.type()); } for (XmlJavaTypeAdapter a: adapt.value()) { - Type t = getTypeFromXmlAdapter(a); + Type t = Utils.getTypeFromXmlAdapter(a); if (t != null) { addType(t); } @@ -314,7 +312,7 @@ class JAXBContextInitializer extends Ser //has an adapter. We need to inspect the adapter and then //return as the adapter will handle the superclass //and interfaces and such - Type t = getTypeFromXmlAdapter(xjta); + Type t = Utils.getTypeFromXmlAdapter(xjta); if (t != null) { addType(t); } @@ -333,65 +331,6 @@ class JAXBContextInitializer extends Ser } } - static XmlJavaTypeAdapter getFieldXJTA(final Field f) { - XmlJavaTypeAdapter adapter = f.getAnnotation(XmlJavaTypeAdapter.class); - if (adapter == null) { - adapter = f.getType().getAnnotation(XmlJavaTypeAdapter.class); - } - if (adapter == null) { - XmlJavaTypeAdapters adapters = f.getDeclaringClass().getPackage().getAnnotation(XmlJavaTypeAdapters.class); - if (adapters != null) { - for (XmlJavaTypeAdapter candidate : adapters.value()) { - if (candidate != null && candidate.type().equals(f.getType())) { - adapter = candidate; - break; - } - } - } - } - return adapter; - } - - static XmlJavaTypeAdapter getMethodXJTA(final Method m) { - XmlJavaTypeAdapter adapter = m.getAnnotation(XmlJavaTypeAdapter.class); - if (adapter == null) { - adapter = m.getReturnType().getAnnotation(XmlJavaTypeAdapter.class); - } - if (adapter == null) { - XmlJavaTypeAdapters adapters = m.getDeclaringClass().getPackage().getAnnotation(XmlJavaTypeAdapters.class); - if (adapters != null) { - for (XmlJavaTypeAdapter candidate : adapters.value()) { - if (candidate != null && candidate.type().equals(m.getGenericReturnType())) { - adapter = candidate; - break; - } - } - } - } - return adapter; - } - - static Class<?> getTypeFromXmlAdapter(XmlJavaTypeAdapter xjta) { - if (xjta != null) { - Class<?> c2 = xjta.value(); - Type sp = c2.getGenericSuperclass(); - while (!XmlAdapter.class.equals(c2) && c2 != null) { - sp = c2.getGenericSuperclass(); - c2 = c2.getSuperclass(); - } - if (sp instanceof ParameterizedType) { - return (Class<?>)((ParameterizedType)sp).getActualTypeArguments()[0]; - } - } - return null; - } - - @SuppressWarnings("rawtypes") - static XmlAdapter getXmlAdapter(XmlJavaTypeAdapter adapterAnnotation) - throws InstantiationException, IllegalAccessException { - return adapterAnnotation != null ? adapterAnnotation.value().newInstance() : null; - } - private void walkReferences(Class<?> cls) { if (cls == null) { return; @@ -406,11 +345,7 @@ class JAXBContextInitializer extends Ser //We'll grab the public field/method types and then add the ObjectFactory stuff //as well as look for jaxb.index files in those packages. - XmlAccessorType accessorType = cls.getAnnotation(XmlAccessorType.class); - if (accessorType == null && cls.getPackage() != null) { - accessorType = cls.getPackage().getAnnotation(XmlAccessorType.class); - } - XmlAccessType accessType = accessorType != null ? accessorType.value() : XmlAccessType.PUBLIC_MEMBER; + XmlAccessType accessType = Utils.getXmlAccessType(cls); if (accessType != XmlAccessType.PROPERTY) { // only look for fields if we are instructed to //fields are accessible even if not public, must look at the declared fields @@ -506,7 +441,7 @@ class JAXBContextInitializer extends Ser * @param annotations the array of annotations from the class member * @return true if JAXB annotations are present, false otherwise */ - private static boolean checkJaxbAnnotation(Annotation[] annotations) { + static boolean checkJaxbAnnotation(Annotation[] annotations) { // must check if there are any jaxb annotations Package jaxbAnnotationsPackage = XmlElement.class.getPackage(); for (Annotation annotation : annotations) { Modified: cxf/branches/2.5.x-fixes/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBEncoderDecoder.java URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBEncoderDecoder.java?rev=1403707&r1=1403706&r2=1403707&view=diff ============================================================================== --- cxf/branches/2.5.x-fixes/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBEncoderDecoder.java (original) +++ cxf/branches/2.5.x-fixes/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBEncoderDecoder.java Tue Oct 30 14:05:53 2012 @@ -45,17 +45,13 @@ import java.util.Set; import java.util.TreeMap; import java.util.logging.Logger; - import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.adapters.HexBinaryAdapter; -import javax.xml.bind.annotation.adapters.XmlAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import javax.xml.bind.attachment.AttachmentMarshaller; import javax.xml.bind.attachment.AttachmentUnmarshaller; import javax.xml.namespace.NamespaceContext; @@ -74,7 +70,6 @@ import org.w3c.dom.Attr; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; - import org.apache.cxf.common.i18n.Message; import org.apache.cxf.common.logging.LogUtils; import org.apache.cxf.common.util.ReflectionUtil; @@ -266,6 +261,11 @@ public final class JAXBEncoderDecoder { } } } + @SuppressWarnings({ "unchecked", "rawtypes" }) + private static JAXBElement<?> newJAXBElement(QName elName, Class<?> cls, Object mObj) { + return new JAXBElement(elName, cls, mObj); + } + //TODO: cache the JAXBRIContext public static void marshalWithBridge(QName qname, Class<?> cls, @@ -346,12 +346,7 @@ public final class JAXBEncoderDecoder { try { writer.writeStartElement("ns1", qn.getLocalPart(), qn.getNamespaceURI()); Class<?> cls = part.getTypeClass(); - XmlAccessorType accessorType = cls.getAnnotation(XmlAccessorType.class); - if (accessorType == null && cls.getPackage() != null) { - accessorType = cls.getPackage().getAnnotation(XmlAccessorType.class); - } - XmlAccessType accessType = accessorType != null - ? accessorType.value() : XmlAccessType.PUBLIC_MEMBER; + XmlAccessType accessType = Utils.getXmlAccessType(cls); String namespace = part.getElementQName().getNamespaceURI(); SchemaInfo sch = part.getMessageInfo().getOperation().getInterface() @@ -363,33 +358,29 @@ public final class JAXBEncoderDecoder { } else { LOG.warning("Schema associated with " + namespace + " is null"); } - for (Field f : ReflectionUtil.getDeclaredFields(cls)) { - if (JAXBContextInitializer.isFieldAccepted(f, accessType)) { - XmlAttribute at = f.getAnnotation(XmlAttribute.class); - if (at == null) { - QName fname = new QName(namespace, f.getName()); - ReflectionUtil.setAccessible(f); - if (JAXBSchemaInitializer.isArray(f.getGenericType())) { - writeArrayObject(marshaller, writer, fname, f.get(elValue)); - } else { - Object o = getFieldValue(f, elValue); - writeObject(marshaller, writer, new JAXBElement(fname, String.class, o)); - } + for (Field f : Utils.getFields(cls, accessType)) { + XmlAttribute at = f.getAnnotation(XmlAttribute.class); + if (at == null) { + QName fname = new QName(namespace, f.getName()); + ReflectionUtil.setAccessible(f); + if (JAXBSchemaInitializer.isArray(f.getGenericType())) { + writeArrayObject(marshaller, writer, fname, f.get(elValue)); + } else { + Object o = Utils.getFieldValue(f, elValue); + writeObject(marshaller, writer, newJAXBElement(fname, String.class, o)); } } } - for (Method m : cls.getMethods()) { - if (JAXBContextInitializer.isMethodAccepted(m, accessType)) { - int idx = m.getName().startsWith("get") ? 3 : 2; - String name = m.getName().substring(idx); - name = Character.toLowerCase(name.charAt(0)) + name.substring(1); - QName mname = new QName(namespace, name); - if (JAXBSchemaInitializer.isArray(m.getGenericReturnType())) { - writeArrayObject(marshaller, writer, mname, m.invoke(elValue)); - } else { - Object o = getMethodValue(m, elValue); - writeObject(marshaller, writer, new JAXBElement(mname, String.class, o)); - } + for (Method m : Utils.getGetters(cls, accessType)) { + int idx = m.getName().startsWith("get") ? 3 : 2; + String name = m.getName().substring(idx); + name = Character.toLowerCase(name.charAt(0)) + name.substring(1); + QName mname = new QName(namespace, name); + if (JAXBSchemaInitializer.isArray(m.getGenericReturnType())) { + writeArrayObject(marshaller, writer, mname, m.invoke(elValue)); + } else { + Object o = Utils.getMethodValue(m, elValue); + writeObject(marshaller, writer, newJAXBElement(mname, String.class, o)); } } @@ -401,7 +392,7 @@ public final class JAXBEncoderDecoder { StaxUtils.close(writer); } } - + @SuppressWarnings("unchecked") private static void writeArrayObject(Marshaller marshaller, Object source, @@ -463,61 +454,44 @@ public final class JAXBEncoderDecoder { obj = cons.newInstance(new Object[1]); } - XmlAccessorType accessorType = cls.getAnnotation(XmlAccessorType.class); - if (accessorType == null && cls.getPackage() != null) { - accessorType = cls.getPackage().getAnnotation(XmlAccessorType.class); - } - XmlAccessType accessType = accessorType != null - ? accessorType.value() : XmlAccessType.PUBLIC_MEMBER; + XmlAccessType accessType = Utils.getXmlAccessType(cls); reader.nextTag(); while (reader.getEventType() == XMLStreamReader.START_ELEMENT) { QName q = reader.getName(); - try { - Field f = ReflectionUtil.getDeclaredField(cls, q.getLocalPart()); - if (f == null) { - f = cls.getField(q.getLocalPart()); - } + String fieldName = q.getLocalPart(); + Field f = Utils.getField(cls, accessType, fieldName); + if (f != null) { Type type = f.getGenericType(); - if (JAXBContextInitializer.isFieldAccepted(f, accessType)) { - f.setAccessible(true); - if (JAXBSchemaInitializer.isArray(type)) { - Class<?> compType = JAXBSchemaInitializer - .getArrayComponentType(type); - List<Object> ret = unmarshallArray(u, reader, - q, - compType, - createList(type)); - Object o = ret; - if (!isList(type)) { - if (compType.isPrimitive()) { - o = java.lang.reflect.Array.newInstance(compType, ret.size()); - for (int x = 0; x < ret.size(); x++) { - Array.set(o, x, ret.get(x)); - } - } else { - o = ret.toArray((Object[])Array.newInstance(compType, ret.size())); + f.setAccessible(true); + if (JAXBSchemaInitializer.isArray(type)) { + Class<?> compType = JAXBSchemaInitializer.getArrayComponentType(type); + List<Object> ret = unmarshallArray(u, reader, q, compType, createList(type)); + Object o = ret; + if (!isList(type)) { + if (compType.isPrimitive()) { + o = java.lang.reflect.Array.newInstance(compType, ret.size()); + for (int x = 0; x < ret.size(); x++) { + Array.set(o, x, ret.get(x)); } + } else { + o = ret.toArray((Object[]) Array.newInstance(compType, ret.size())); } - - f.set(obj, o); - } else { - Object o = getElementValue(u.unmarshal(reader, getFieldType(f))); - setFieldValue(f, obj, o); } + + f.set(obj, o); } else { - throw new NoSuchFieldException("No accessible field " + q.getLocalPart()); + Object o = getElementValue(u.unmarshal(reader, Utils.getFieldType(f))); + Utils.setFieldValue(f, obj, o); } - } catch (NoSuchFieldException ex) { + } else { String s = Character.toUpperCase(q.getLocalPart().charAt(0)) + q.getLocalPart().substring(1); - Method m = null; - try { - m = cls.getMethod("get" + s); - } catch (NoSuchMethodException mex) { - m = cls.getMethod("is" + s); + Method m = Utils.getMethod(cls, accessType, "get" + s); + if (m == null) { + m = Utils.getMethod(cls, accessType, "is" + s); } Type type = m.getGenericReturnType(); - Method m2 = cls.getMethod("set" + s, m.getReturnType()); + Method m2 = Utils.getMethod(cls, accessType, "set" + s, m.getReturnType()); if (JAXBSchemaInitializer.isArray(type)) { Class<?> compType = JAXBSchemaInitializer .getArrayComponentType(type); @@ -539,8 +513,8 @@ public final class JAXBEncoderDecoder { m2.invoke(obj, o); } else { - Object o = getElementValue(u.unmarshal(reader, getMethodReturnType(m))); - setMethodValue(m, m2, obj, o); + Object o = getElementValue(u.unmarshal(reader, Utils.getMethodReturnType(m))); + Utils.setMethodValue(m, m2, obj, o); } } } @@ -550,46 +524,6 @@ public final class JAXBEncoderDecoder { } } - private static Class<?> getFieldType(final Field f) { - XmlJavaTypeAdapter adapter = JAXBContextInitializer.getFieldXJTA(f); - Class<?> adapterType = JAXBContextInitializer.getTypeFromXmlAdapter(adapter); - return adapterType != null ? adapterType : f.getType(); - } - - private static Class<?> getMethodReturnType(final Method m) { - XmlJavaTypeAdapter adapter = JAXBContextInitializer.getMethodXJTA(m); - Class<?> adapterType = JAXBContextInitializer.getTypeFromXmlAdapter(adapter); - return adapterType != null ? adapterType : m.getReturnType(); - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - private static Object getFieldValue(Field f, Object target) throws Exception { - XmlJavaTypeAdapter adapterAnnotation = JAXBContextInitializer.getFieldXJTA(f); - XmlAdapter adapter = JAXBContextInitializer.getXmlAdapter(adapterAnnotation); - return adapter != null ? adapter.marshal(f.get(target)) : f.get(target); - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - private static Object getMethodValue(Method m, Object target) throws Exception { - XmlJavaTypeAdapter adapterAnnotation = JAXBContextInitializer.getMethodXJTA(m); - XmlAdapter adapter = JAXBContextInitializer.getXmlAdapter(adapterAnnotation); - return adapter != null ? adapter.marshal(m.invoke(target)) : m.invoke(target); - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - private static void setFieldValue(Field f, Object target, Object value) throws Exception { - XmlJavaTypeAdapter xjta = JAXBContextInitializer.getFieldXJTA(f); - XmlAdapter adapter = JAXBContextInitializer.getXmlAdapter(xjta); - f.set(target, adapter != null ? adapter.unmarshal(value) : value); - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - private static void setMethodValue(Method getter, Method setter, Object target, Object value) throws Exception { - XmlJavaTypeAdapter xjta = JAXBContextInitializer.getMethodXJTA(getter); - XmlAdapter adapter = JAXBContextInitializer.getXmlAdapter(xjta); - setter.invoke(target, adapter != null ? adapter.unmarshal(value) : value); - } - private static void writeObject(Marshaller u, Object source, Object mObj) throws Fault, JAXBException { if (source instanceof XMLStreamWriter) { u.marshal(mObj, (XMLStreamWriter)source); Modified: cxf/branches/2.5.x-fixes/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBSchemaInitializer.java URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBSchemaInitializer.java?rev=1403707&r1=1403706&r2=1403707&view=diff ============================================================================== --- cxf/branches/2.5.x-fixes/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBSchemaInitializer.java (original) +++ cxf/branches/2.5.x-fixes/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBSchemaInitializer.java Tue Oct 30 14:05:53 2012 @@ -32,7 +32,6 @@ import java.util.logging.Logger; import javax.xml.bind.JAXBContext; import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlList; import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.adapters.XmlAdapter; @@ -512,35 +511,25 @@ class JAXBSchemaInitializer extends Serv XmlSchemaSequence seq = new XmlSchemaSequence(); ct.setParticle(seq); String namespace = part.getElementQName().getNamespaceURI(); + XmlAccessType accessType = Utils.getXmlAccessType(cls); - XmlAccessorType accessorType = cls.getAnnotation(XmlAccessorType.class); - if (accessorType == null && cls.getPackage() != null) { - accessorType = cls.getPackage().getAnnotation(XmlAccessorType.class); - } - XmlAccessType accessType = accessorType != null ? accessorType.value() : XmlAccessType.PUBLIC_MEMBER; - - - for (Field f : cls.getDeclaredFields()) { - if (JAXBContextInitializer.isFieldAccepted(f, accessType)) { - //map field - Type type = getFieldType(f); - JAXBBeanInfo beanInfo = getBeanInfo(type); - if (beanInfo != null) { - addElement(schema, seq, beanInfo, new QName(namespace, f.getName()), isArray(type)); - } - } - } - for (Method m : cls.getMethods()) { - if (JAXBContextInitializer.isMethodAccepted(m, accessType)) { - //map method - Type type = getMethodReturnType(m); - JAXBBeanInfo beanInfo = getBeanInfo(type); - if (beanInfo != null) { - int idx = m.getName().startsWith("get") ? 3 : 2; - String name = m.getName().substring(idx); - name = Character.toLowerCase(name.charAt(0)) + name.substring(1); - addElement(schema, seq, beanInfo, new QName(namespace, name), isArray(type)); - } + for (Field f : Utils.getFields(cls, accessType)) { + //map field + Type type = Utils.getFieldType(f); + JAXBBeanInfo beanInfo = getBeanInfo(type); + if (beanInfo != null) { + addElement(schema, seq, beanInfo, new QName(namespace, f.getName()), isArray(type)); + } + } + for (Method m : Utils.getGetters(cls, accessType)) { + //map method + Type type = Utils.getMethodReturnType(m); + JAXBBeanInfo beanInfo = getBeanInfo(type); + if (beanInfo != null) { + int idx = m.getName().startsWith("get") ? 3 : 2; + String name = m.getName().substring(idx); + name = Character.toLowerCase(name.charAt(0)) + name.substring(1); + addElement(schema, seq, beanInfo, new QName(namespace, name), isArray(type)); } } // Create element in xsd:sequence for Exception.class @@ -557,18 +546,6 @@ class JAXBSchemaInitializer extends Serv part.setProperty(JAXBDataBinding.class.getName() + ".CUSTOM_EXCEPTION", Boolean.TRUE); } - private static Type getFieldType(final Field f) { - XmlJavaTypeAdapter adapter = JAXBContextInitializer.getFieldXJTA(f); - Class<?> adapterType = JAXBContextInitializer.getTypeFromXmlAdapter(adapter); - return adapterType != null ? adapterType : f.getGenericType(); - } - - private static Type getMethodReturnType(final Method m) { - XmlJavaTypeAdapter adapter = JAXBContextInitializer.getMethodXJTA(m); - Class<?> adapterType = JAXBContextInitializer.getTypeFromXmlAdapter(adapter); - return adapterType != null ? adapterType : m.getGenericReturnType(); - } - static boolean isArray(Type cls) { if (cls instanceof Class) { return ((Class<?>)cls).isArray();
