Author: thomas.diesler(a)jboss.com
Date: 2006-11-02 16:19:22 -0500 (Thu, 02 Nov 2006)
New Revision: 1348
Added:
trunk/src/main/java/org/jboss/ws/integration/jboss50/WebAppClassLoaderFactory.java
Modified:
trunk/build.xml
trunk/src/main/java/org/jboss/ws/deployment/AbstractServiceEndpointPublisher.java
trunk/src/main/java/org/jboss/ws/integration/jboss50/DeploymentInfoAdaptor.java
trunk/src/main/java/org/jboss/ws/integration/jboss50/JAXWSDeployerJSE.java
trunk/src/main/java/org/jboss/ws/integration/jboss50/ServiceEndpointGeneratorEJB.java
trunk/src/main/java/org/jboss/ws/integration/jboss50/WebAppClassLoaderDeployer.java
trunk/src/main/java/org/jboss/ws/metadata/ParameterMetaData.java
trunk/src/main/java/org/jboss/ws/utils/IOUtils.java
trunk/src/main/java/org/jboss/ws/utils/JavaUtils.java
Log:
JAXWS deployer JSE, more to come
Modified: trunk/build.xml
===================================================================
--- trunk/build.xml 2006-11-02 21:03:00 UTC (rev 1347)
+++ trunk/build.xml 2006-11-02 21:19:22 UTC (rev 1348)
@@ -412,7 +412,7 @@
<target name="jbossws-thirdparty-jar"
unless="jbossws.thirdparty.available">
<!-- Build jbossws-thirdparty.jar -->
<mkdir dir="${build.lib.dir}/build"/>
- <unjar dest="${build.lib.dir}/build"
src="${jboss.lib}/jboss-common.jar"/>
+ <!--unjar dest="${build.lib.dir}/build"
src="${jboss.lib}/jboss-common.jar"/-->
<unjar dest="${build.lib.dir}/build"
src="${jboss.server.lib}/jboss-j2ee.jar"/>
<unjar dest="${build.lib.dir}/build"
src="${thirdparty.dir}/jboss-container.jar"/>
<unjar dest="${build.lib.dir}/build"
src="${thirdparty.dir}/jboss-dependency.jar"/>
Modified:
trunk/src/main/java/org/jboss/ws/deployment/AbstractServiceEndpointPublisher.java
===================================================================
---
trunk/src/main/java/org/jboss/ws/deployment/AbstractServiceEndpointPublisher.java 2006-11-02
21:03:00 UTC (rev 1347)
+++
trunk/src/main/java/org/jboss/ws/deployment/AbstractServiceEndpointPublisher.java 2006-11-02
21:19:22 UTC (rev 1348)
@@ -75,7 +75,7 @@
public abstract String destroyServiceEndpoint(UnifiedDeploymentInfo udi) throws
Exception;
- public Map<String, String> rewriteWebXML(URL warURL)
+ public URL rewriteWebXML(URL warURL)
{
File warFile = new File(warURL.getFile());
if (warFile.isDirectory() == false)
@@ -104,7 +104,7 @@
new DOMWriter(fos).setPrettyprint(true).print(root);
fos.close();
- return sepTargetMap;
+ return warURL;
}
catch (RuntimeException rte)
{
Modified: trunk/src/main/java/org/jboss/ws/integration/jboss50/DeploymentInfoAdaptor.java
===================================================================
---
trunk/src/main/java/org/jboss/ws/integration/jboss50/DeploymentInfoAdaptor.java 2006-11-02
21:03:00 UTC (rev 1347)
+++
trunk/src/main/java/org/jboss/ws/integration/jboss50/DeploymentInfoAdaptor.java 2006-11-02
21:19:22 UTC (rev 1348)
@@ -48,9 +48,8 @@
{
if (unit.getDeploymentContext().getParent() != null)
{
- log.warn("parent deployment not yet supported");
- //udi.parent = new UnifiedDeploymentInfo(null);
- //buildDeploymentInfo(udi.parent,
unit.getDeploymentContext().getParent().getDeploymentUnit());
+ udi.parent = new UnifiedDeploymentInfo(null);
+ buildDeploymentInfo(udi.parent,
unit.getDeploymentContext().getParent().getDeploymentUnit());
}
udi.shortName = getShortName(unit);
Modified: trunk/src/main/java/org/jboss/ws/integration/jboss50/JAXWSDeployerJSE.java
===================================================================
--- trunk/src/main/java/org/jboss/ws/integration/jboss50/JAXWSDeployerJSE.java 2006-11-02
21:03:00 UTC (rev 1347)
+++ trunk/src/main/java/org/jboss/ws/integration/jboss50/JAXWSDeployerJSE.java 2006-11-02
21:19:22 UTC (rev 1348)
@@ -24,10 +24,11 @@
//$Id$
import java.io.File;
-import java.net.MalformedURLException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Set;
@@ -37,15 +38,17 @@
import javax.jws.WebService;
import org.jboss.deployers.spi.DeploymentException;
-import org.jboss.deployers.spi.classloader.ClassLoaderFactory;
import org.jboss.deployers.spi.deployer.DeploymentUnit;
-import org.jboss.deployers.spi.structure.DeploymentContext;
-import org.jboss.logging.Logger;
import org.jboss.metadata.NameValuePair;
import org.jboss.metadata.WebMetaData;
import org.jboss.metadata.web.Servlet;
+import org.jboss.virtual.VirtualFile;
+import org.jboss.ws.WSException;
import org.jboss.ws.deployment.JSR181Deployment;
import org.jboss.ws.deployment.UnifiedDeploymentInfo;
+import org.jboss.ws.server.ServerConfig;
+import org.jboss.ws.server.ServerConfigFactory;
+import org.jboss.ws.utils.IOUtils;
/**
* A deployer JAXWS JSE Endpoints
@@ -57,7 +60,7 @@
{
// The servlet init param in web.xml that is the service endpoint class
public static final String INIT_PARAM_SERVICE_ENDPOINT_IMPL =
"ServiceEndpointImpl";
-
+
// The default relative order after the JBossWebAppParsingDeployer
public int getRelativeOrder()
{
@@ -75,6 +78,7 @@
@Override
public void deploy(DeploymentUnit unit) throws DeploymentException
{
+ // Install an annotation class loader, if there is none already
boolean removeLoader = false;
try
{
@@ -85,11 +89,20 @@
unit.getDeploymentContext().createClassLoader(new WebAppClassLoaderFactory());
removeLoader = true;
}
-
+
try
{
super.deploy(unit);
+
+ // modify the WebMetaData
+ modifyWebMetaData(unit);
+
+ // FIXME: JBAS-3812 - TomcatDeployment should use modified WebMetaData
}
+ catch (Exception ex)
+ {
+ DeploymentException.rethrowAsDeploymentException(ex.getMessage(), ex);
+ }
finally
{
if (removeLoader == true)
@@ -106,14 +119,10 @@
if (allMetaData.size() > 0)
{
WebMetaData webMetaData = allMetaData.iterator().next();
- if (allMetaData.size() > 1)
- log.warn("More than one WebMetaData not supported");
-
try
{
ClassLoader anLoader = unit.getClassLoader();
- String serviceEndpointServlet =
getServiceEndpointPublisher().getServiceEndpointServlet();
-
+
Iterator it = webMetaData.getServlets().iterator();
while (it.hasNext())
{
@@ -122,14 +131,8 @@
Class<?> servletClass = anLoader.loadClass(beanName);
if (servletClass.isAnnotationPresent(WebService.class))
{
- // Nothing to do if we have an <init-param>
- if (isAlreadyModified(servlet) == false)
- {
- servlet.setServletClass(serviceEndpointServlet);
- NameValuePair initParam = new
NameValuePair(INIT_PARAM_SERVICE_ENDPOINT_IMPL, beanName);
- servlet.addInitParam(initParam);
- }
isRelevant = true;
+ break;
}
}
}
@@ -141,111 +144,45 @@
return isRelevant;
}
-
- private boolean isAlreadyModified(Servlet servlet)
- {
- Iterator itParams = servlet.getInitParams().iterator();
- while (itParams.hasNext())
- {
- NameValuePair pair = (NameValuePair)itParams.next();
- if (INIT_PARAM_SERVICE_ENDPOINT_IMPL.equals(pair.getName()))
- return true;
- }
- return false;
- }
- static class WebAppClassLoaderFactory implements ClassLoaderFactory
+ private void modifyWebMetaData(DeploymentUnit unit) throws Exception
{
- // provide logging
- private static Logger log = Logger.getLogger(WebAppClassLoaderFactory.class);
-
- private ClassLoader classLoader;
-
- public ClassLoader createClassLoader(DeploymentContext context) throws Exception
+ Set<? extends WebMetaData> allMetaData =
unit.getAllMetaData(WebMetaData.class);
+ if (allMetaData.size() > 0)
{
- log.debug("createClassLoader: " + context.getRoot());
-
- ArrayList<URL> list = new ArrayList<URL>();
+ WebMetaData webMetaData = allMetaData.iterator().next();
+ ClassLoader anLoader = unit.getClassLoader();
+ String serviceEndpointServlet =
getServiceEndpointPublisher().getServiceEndpointServlet();
- URL warURL = context.getRoot().toURL();
- String externalForm = warURL.toExternalForm();
-
- if (externalForm.endsWith("!/"))
+ Iterator it = webMetaData.getServlets().iterator();
+ while (it.hasNext())
{
- String fileName = warURL.getFile();
- if (fileName.indexOf("!") > 0)
- fileName = fileName.substring(0, fileName.indexOf("!"));
-
- try
+ Servlet servlet = (Servlet)it.next();
+ String className = servlet.getServletClass();
+ Class<?> servletClass = anLoader.loadClass(className);
+ if (servletClass.isAnnotationPresent(WebService.class))
{
- URL url = new URL(fileName);
- fileName = url.getFile();
- }
- catch (MalformedURLException ex)
- {
- // ignore
- }
-
- File warFile = new File(fileName);
- if (warFile.exists())
- {
- ZipFile zipFile = new ZipFile(warFile);
- Enumeration en = zipFile.entries();
- while (en.hasMoreElements())
+ // Nothing to do if we have an <init-param>
+ if (isAlreadyModified(servlet) == false)
{
- ZipEntry entry = (ZipEntry)en.nextElement();
- String entryName = entry.getName();
- if (entryName.equals("WEB-INF/classes/"))
- {
- URL classesURL = new URL(externalForm + entryName);
- list.add(classesURL);
- }
- if (entryName.startsWith("WEB-INF/lib") &&
entryName.endsWith(".jar"))
- {
- URL jarURL = new URL(externalForm + entryName);
- list.add(jarURL);
- }
+ servlet.setServletClass(serviceEndpointServlet);
+ NameValuePair initParam = new
NameValuePair(INIT_PARAM_SERVICE_ENDPOINT_IMPL, className);
+ servlet.addInitParam(initParam);
}
}
- else
- {
- log.warn("WAR file does not exist: " + warFile);
- }
}
- else
- {
- String path = warURL.getFile();
-
- File classesDir = new File(path, "WEB-INF/classes");
- if (classesDir.exists())
- list.add(classesDir.toURL());
-
- File libDir = new File(path, "WEB-INF/lib");
- if (libDir.exists())
- {
- File[] jars = libDir.listFiles();
- int length = jars != null ? jars.length : 0;
- for (int j = 0; j < length; j++)
- {
- File jar = jars[j];
- if (jar.getAbsolutePath().endsWith(".jar"))
- {
- list.add(jar.toURL());
- }
- }
- }
- }
-
- ClassLoader parent = Thread.currentThread().getContextClassLoader();
- classLoader = new URLClassLoader(list.toArray(new URL[list.size()]), parent);
-
- return classLoader;
}
+ }
- public void removeClassLoader(DeploymentContext context) throws Exception
+ private boolean isAlreadyModified(Servlet servlet)
+ {
+ Iterator itParams = servlet.getInitParams().iterator();
+ while (itParams.hasNext())
{
- log.debug("removeClassLoader: " + context.getRoot());
- this.classLoader = null;
+ NameValuePair pair = (NameValuePair)itParams.next();
+ if (INIT_PARAM_SERVICE_ENDPOINT_IMPL.equals(pair.getName()))
+ return true;
}
+ return false;
}
}
Modified:
trunk/src/main/java/org/jboss/ws/integration/jboss50/ServiceEndpointGeneratorEJB.java
===================================================================
---
trunk/src/main/java/org/jboss/ws/integration/jboss50/ServiceEndpointGeneratorEJB.java 2006-11-02
21:03:00 UTC (rev 1347)
+++
trunk/src/main/java/org/jboss/ws/integration/jboss50/ServiceEndpointGeneratorEJB.java 2006-11-02
21:19:22 UTC (rev 1348)
@@ -79,6 +79,7 @@
String deploymentName = wsMetaData.getDeploymentName().replace('/',
'-') + "-ws";
tmpWar = File.createTempFile(deploymentName, ".war", tmpdir);
tmpWar.delete();
+
File webInf = new File(tmpWar, "WEB-INF");
webInf.mkdirs();
Modified:
trunk/src/main/java/org/jboss/ws/integration/jboss50/WebAppClassLoaderDeployer.java
===================================================================
---
trunk/src/main/java/org/jboss/ws/integration/jboss50/WebAppClassLoaderDeployer.java 2006-11-02
21:03:00 UTC (rev 1347)
+++
trunk/src/main/java/org/jboss/ws/integration/jboss50/WebAppClassLoaderDeployer.java 2006-11-02
21:19:22 UTC (rev 1348)
@@ -73,99 +73,4 @@
unit.getDeploymentContext().createClassLoader(new WebAppClassLoaderFactory());
}
}
-
- static class WebAppClassLoaderFactory implements ClassLoaderFactory
- {
- // provide logging
- private static Logger log = Logger.getLogger(WebAppClassLoaderFactory.class);
-
- private ClassLoader classLoader;
-
- public ClassLoader createClassLoader(DeploymentContext context) throws Exception
- {
- log.debug("createClassLoader: " + context.getRoot());
-
- ArrayList<URL> list = new ArrayList<URL>();
-
- URL warURL = context.getRoot().toURL();
- String externalForm = warURL.toExternalForm();
-
- if (externalForm.endsWith("!/"))
- {
- String fileName = warURL.getFile();
- if (fileName.indexOf("!") > 0)
- fileName = fileName.substring(0, fileName.indexOf("!"));
-
- try
- {
- URL url = new URL(fileName);
- fileName = url.getFile();
- }
- catch (MalformedURLException ex)
- {
- // ignore
- }
-
- File warFile = new File(fileName);
- if (warFile.exists())
- {
- ZipFile zipFile = new ZipFile(warFile);
- Enumeration en = zipFile.entries();
- while (en.hasMoreElements())
- {
- ZipEntry entry = (ZipEntry)en.nextElement();
- String entryName = entry.getName();
- if (entryName.equals("WEB-INF/classes/"))
- {
- URL classesURL = new URL(externalForm + entryName);
- list.add(classesURL);
- }
- if (entryName.startsWith("WEB-INF/lib") &&
entryName.endsWith(".jar"))
- {
- URL jarURL = new URL(externalForm + entryName);
- list.add(jarURL);
- }
- }
- }
- else
- {
- log.warn("WAR file does not exist: " + warFile);
- }
- }
- else
- {
- String path = warURL.getFile();
-
- File classesDir = new File(path, "WEB-INF/classes");
- if (classesDir.exists())
- list.add(classesDir.toURL());
-
- File libDir = new File(path, "WEB-INF/lib");
- if (libDir.exists())
- {
- File[] jars = libDir.listFiles();
- int length = jars != null ? jars.length : 0;
- for (int j = 0; j < length; j++)
- {
- File jar = jars[j];
- if (jar.getAbsolutePath().endsWith(".jar"))
- {
- list.add(jar.toURL());
- }
- }
- }
- }
-
- ClassLoader parent = Thread.currentThread().getContextClassLoader();
- classLoader = new URLClassLoader(list.toArray(new URL[list.size()]), parent);
-
- return classLoader;
- }
-
- public void removeClassLoader(DeploymentContext context) throws Exception
- {
- log.debug("removeClassLoader: " + context.getRoot());
- this.classLoader = null;
- }
- }
}
Added: trunk/src/main/java/org/jboss/ws/integration/jboss50/WebAppClassLoaderFactory.java
===================================================================
---
trunk/src/main/java/org/jboss/ws/integration/jboss50/WebAppClassLoaderFactory.java 2006-11-02
21:03:00 UTC (rev 1347)
+++
trunk/src/main/java/org/jboss/ws/integration/jboss50/WebAppClassLoaderFactory.java 2006-11-02
21:19:22 UTC (rev 1348)
@@ -0,0 +1,138 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.ws.integration.jboss50;
+
+//$Id$
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.jboss.deployers.spi.classloader.ClassLoaderFactory;
+import org.jboss.deployers.spi.structure.DeploymentContext;
+import org.jboss.logging.Logger;
+
+/**
+ * A class loader factory for web apps
+ *
+ * @author Thomas.Diesler(a)jboss.org
+ * @since 31-Oct-2005
+ */
+public class WebAppClassLoaderFactory implements ClassLoaderFactory
+{
+ // provide logging
+ private static Logger log = Logger.getLogger(WebAppClassLoaderFactory.class);
+
+ private ClassLoader classLoader;
+
+ public ClassLoader createClassLoader(DeploymentContext context) throws Exception
+ {
+ log.debug("createClassLoader: " + context.getRoot());
+
+ ArrayList<URL> list = new ArrayList<URL>();
+
+ URL warURL = context.getRoot().toURL();
+ String externalForm = warURL.toExternalForm();
+
+ if (externalForm.endsWith("!/"))
+ {
+ String fileName = warURL.getFile();
+ if (fileName.indexOf("!/") > 0)
+ fileName = fileName.substring(0, fileName.indexOf("!/"));
+
+ try
+ {
+ URL url = new URL(fileName);
+ fileName = url.getFile();
+ }
+ catch (MalformedURLException ex)
+ {
+ // ignore
+ }
+
+ File warFile = new File(fileName);
+ if (warFile.exists())
+ {
+ ZipFile zipFile = new ZipFile(warFile);
+ Enumeration en = zipFile.entries();
+ while (en.hasMoreElements())
+ {
+ ZipEntry entry = (ZipEntry)en.nextElement();
+ String entryName = entry.getName();
+ if (entryName.equals("WEB-INF/classes/"))
+ {
+ URL classesURL = new URL(externalForm + entryName);
+ list.add(classesURL);
+ }
+ if (entryName.startsWith("WEB-INF/lib") &&
entryName.endsWith(".jar"))
+ {
+ URL jarURL = new URL(externalForm + entryName);
+ list.add(jarURL);
+ }
+ }
+ }
+ else
+ {
+ log.warn("WAR file does not exist: " + warFile);
+ }
+ }
+ else
+ {
+ String path = warURL.getFile();
+
+ File classesDir = new File(path, "WEB-INF/classes");
+ if (classesDir.exists())
+ list.add(classesDir.toURL());
+
+ File libDir = new File(path, "WEB-INF/lib");
+ if (libDir.exists())
+ {
+ File[] jars = libDir.listFiles();
+ int length = jars != null ? jars.length : 0;
+ for (int j = 0; j < length; j++)
+ {
+ File jar = jars[j];
+ if (jar.getAbsolutePath().endsWith(".jar"))
+ {
+ list.add(jar.toURL());
+ }
+ }
+ }
+ }
+
+ ClassLoader parent = Thread.currentThread().getContextClassLoader();
+ classLoader = new URLClassLoader(list.toArray(new URL[list.size()]), parent);
+
+ return classLoader;
+ }
+
+ public void removeClassLoader(DeploymentContext context) throws Exception
+ {
+ log.debug("removeClassLoader: " + context.getRoot());
+ this.classLoader = null;
+ }
+}
Property changes on:
trunk/src/main/java/org/jboss/ws/integration/jboss50/WebAppClassLoaderFactory.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified: trunk/src/main/java/org/jboss/ws/metadata/ParameterMetaData.java
===================================================================
--- trunk/src/main/java/org/jboss/ws/metadata/ParameterMetaData.java 2006-11-02 21:03:00
UTC (rev 1347)
+++ trunk/src/main/java/org/jboss/ws/metadata/ParameterMetaData.java 2006-11-02 21:19:22
UTC (rev 1348)
@@ -39,7 +39,6 @@
import org.jboss.ws.jaxrpc.ParameterWrapping;
import org.jboss.ws.jaxws.DynamicWrapperGenerator;
import org.jboss.ws.utils.HolderUtils;
-import org.jboss.ws.utils.IOUtils;
import org.jboss.ws.utils.JavaUtils;
/**
@@ -119,7 +118,7 @@
public String toString()
{
- return "[name = " + name + ", type = " + type + ",
typeArgs = " + IOUtils.printArray(typeArguments) + ", variable = " +
variable + ", index = " + index + "]";
+ return "[name = " + name + ",type = " + type +
",typeArgs = " + JavaUtils.printArray(typeArguments) + ",variable = "
+ variable + ",index = " + index + "]";
}
}
Modified: trunk/src/main/java/org/jboss/ws/utils/IOUtils.java
===================================================================
--- trunk/src/main/java/org/jboss/ws/utils/IOUtils.java 2006-11-02 21:03:00 UTC (rev
1347)
+++ trunk/src/main/java/org/jboss/ws/utils/IOUtils.java 2006-11-02 21:19:22 UTC (rev
1348)
@@ -21,6 +21,8 @@
*/
package org.jboss.ws.utils;
+// $Id: $
+
import java.io.*;
import org.jboss.logging.Logger;
@@ -58,6 +60,7 @@
r = ins.read(bytes);
}
}
+
public static byte[] convertToBytes(DataHandler dh)
{
try
@@ -72,20 +75,6 @@
}
}
- public static String printArray(Object[] val)
- {
- if (val == null)
- return "null";
- StringBuilder out = new StringBuilder("[");
- for (int i = 0; i < val.length; i++)
- {
- if (i > 0)
- out.append(", ");
- out.append(val[i].getClass().isArray() ? printArray((Object[])val[i]) :
val[i]);
- }
- return out.append("]").toString();
- }
-
/**
* Transform a Reader to an InputStream
* Background is that DocumentBuilder.parse() cannot take the Reader directly
Modified: trunk/src/main/java/org/jboss/ws/utils/JavaUtils.java
===================================================================
--- trunk/src/main/java/org/jboss/ws/utils/JavaUtils.java 2006-11-02 21:03:00 UTC (rev
1347)
+++ trunk/src/main/java/org/jboss/ws/utils/JavaUtils.java 2006-11-02 21:19:22 UTC (rev
1348)
@@ -471,6 +471,23 @@
return (ret.charAt(0) == '[') ? ret : "L" + ret + ";";
}
+ public static String printArray(Object[] val)
+ {
+ if (val == null)
+ return "null";
+
+ StringBuilder out = new StringBuilder("[");
+ for (int i = 0; i < val.length; i++)
+ {
+ if (i > 0)
+ {
+ out.append(",");
+ }
+ out.append(val[i].getClass().isArray() ? printArray((Object[])val[i]) :
val[i]);
+ }
+ return out.append("]").toString();
+ }
+
public static String getSourceName(Class type)
{
if (! type.isArray())