[jbossws-commits] JBossWS SVN: r16775 - in stack/native/trunk/modules/core/src/main/java/org/jboss/ws/core: jaxrpc/handler and 1 other directories.

jbossws-commits at lists.jboss.org jbossws-commits at lists.jboss.org
Thu Sep 27 10:10:02 EDT 2012


Author: alessio.soldano at jboss.com
Date: 2012-09-27 10:10:02 -0400 (Thu, 27 Sep 2012)
New Revision: 16775

Added:
   stack/native/trunk/modules/core/src/main/java/org/jboss/ws/core/utils/CachedOutputStream.java
Modified:
   stack/native/trunk/modules/core/src/main/java/org/jboss/ws/core/MessageTrace.java
   stack/native/trunk/modules/core/src/main/java/org/jboss/ws/core/jaxrpc/handler/HandlerChainBaseImpl.java
Log:
[JBWS-3486] Allow dealing with SAAJ RI SOAP messages that might from client side and/or from user handlers; TRACE log level required to test this


Modified: stack/native/trunk/modules/core/src/main/java/org/jboss/ws/core/MessageTrace.java
===================================================================
--- stack/native/trunk/modules/core/src/main/java/org/jboss/ws/core/MessageTrace.java	2012-09-27 10:14:40 UTC (rev 16774)
+++ stack/native/trunk/modules/core/src/main/java/org/jboss/ws/core/MessageTrace.java	2012-09-27 14:10:02 UTC (rev 16775)
@@ -1,6 +1,6 @@
 /*
  * JBoss, Home of Professional Open Source.
- * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * Copyright 2012, Red Hat Middleware LLC, and individual contributors
  * as indicated by the @author tags. See the copyright.txt file in the
  * distribution for a full listing of individual contributors.
  *
@@ -22,30 +22,46 @@
 package org.jboss.ws.core;
 
 import java.io.ByteArrayInputStream;
+import java.io.StringWriter;
 import java.util.ResourceBundle;
 
 import javax.xml.soap.SOAPEnvelope;
-import javax.xml.soap.SOAPException;
 import javax.xml.soap.SOAPMessage;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamResult;
 import javax.xml.transform.stream.StreamSource;
 
 import org.jboss.logging.Logger;
 import org.jboss.ws.api.util.BundleUtils;
 import org.jboss.ws.common.DOMWriter;
+import org.jboss.ws.core.soap.SOAPMessageImpl;
+import org.jboss.ws.core.soap.attachment.MimeConstants;
 import org.jboss.ws.core.soap.utils.SOAPElementWriter;
 import org.jboss.ws.core.soap.utils.XMLFragment;
+import org.jboss.ws.core.utils.CachedOutputStream;
+import org.jboss.wsf.spi.SPIProvider;
+import org.jboss.wsf.spi.SPIProviderResolver;
+import org.jboss.wsf.spi.classloading.ClassLoaderProvider;
+import org.jboss.wsf.spi.management.ServerConfig;
+import org.jboss.wsf.spi.management.ServerConfigFactory;
 import org.w3c.dom.Element;
 
 /**
- * Trace incomming/outgoing messages
+ * Trace incoming/outgoing messages
  *
  * @author Thomas.Diesler at jboss.org
+ * @author alessio.soldano at jboss.com
+ * 
  * @since 04-Apr-2007
  */
 public final class MessageTrace
 {
    private static final ResourceBundle bundle = BundleUtils.getBundle(MessageTrace.class);
    private static final Logger msgLog = Logger.getLogger(MessageTrace.class);
+   private static ServerConfig serverConfig = null;
+   private static boolean serverConfigInit = false;
 
    private MessageTrace()
    {
@@ -60,14 +76,56 @@
       {
          try
          {
-            SOAPEnvelope soapEnv = ((SOAPMessage)message).getSOAPPart().getEnvelope();
-            if (soapEnv != null)
+            if (message instanceof SOAPMessageImpl) {
+               SOAPEnvelope soapEnv = ((SOAPMessage)message).getSOAPPart().getEnvelope();
+               if (soapEnv != null)
+               {
+                  String envStr = SOAPElementWriter.writeElement(soapEnv, true);
+                  msgLog.trace(messagePrefix + "\n" + envStr);
+               }
+            }
+            else
             {
-               String envStr = SOAPElementWriter.writeElement(soapEnv, true);
-               msgLog.trace(messagePrefix + "\n" + envStr);
+               SOAPMessage soapMessage = (SOAPMessage) message;
+               String encoding = (String)soapMessage.getProperty(SOAPMessage.CHARACTER_SET_ENCODING);
+               if (encoding == null)
+               {
+                  encoding = "UTF-8";
+               }
+               
+               CachedOutputStream os = null;
+               try
+               {
+                  os = new CachedOutputStream();
+                  os.setThreshold(64*1024);
+                  os.holdTempFile();
+                  ServerConfig sc = getServerConfig();
+                  if (sc != null) {
+                     os.setOutputDir(sc.getServerTempDir());
+                  }
+                  soapMessage.writeTo(os);
+                  os.flush();
+                  if (os.getTempFile() != null)
+                  {
+                     msgLog.trace("SOAP Message saved to tmp file: " + os.getTempFile().getAbsolutePath());
+                  }
+                  else
+                  {
+                     StringBuilder sb = new StringBuilder();
+                     write(sb, os, encoding, soapMessage.getMimeHeaders().getHeader(MimeConstants.CONTENT_TYPE)[0]);
+                     msgLog.trace(messagePrefix + "\n" + sb.toString());
+                  }
+               }
+               finally
+               {
+                  if (os != null)
+                  {
+                     os.close();
+                  }
+               }
             }
          }
-         catch (SOAPException ex)
+         catch (Exception ex)
          {
             msgLog.error(BundleUtils.getMessage(bundle, "CANNOT_TRACE_SOAPMESSAGE"),  ex);
          }
@@ -89,4 +147,51 @@
           msgLog.warn(BundleUtils.getMessage(bundle, "UNSUPPORTED_MESSAGE_TYPE",  message));
       }
    }
+   
+   private static void write(StringBuilder builder, CachedOutputStream cos, String encoding, String contentType) throws Exception
+   {
+      if ((contentType != null && contentType.indexOf("xml") >= 0 && contentType.toLowerCase().indexOf("multipart/related") < 0) && cos.size() > 0)
+      {
+         TransformerFactory tf = TransformerFactory.newInstance();
+         try {
+            tf.setAttribute("indent-number", 2);
+         } catch (Throwable t) {} //ignore
+         Transformer serializer = tf.newTransformer();
+         serializer.setOutputProperty(OutputKeys.INDENT, "yes");
+         serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
+
+         StringWriter swriter = new StringWriter();
+         serializer.transform(new StreamSource(cos.getInputStream()), new StreamResult(swriter));
+         builder.append(swriter.toString());
+      }
+      else
+      {
+         if (encoding == null || encoding.trim().length() == 0)
+         {
+            cos.writeCacheTo(builder, "UTF-8");
+         }
+         else
+         {
+            cos.writeCacheTo(builder, encoding);
+         }
+
+      }
+   }
+   
+   private static synchronized ServerConfig getServerConfig()
+   {
+      if (!serverConfigInit)
+      {
+         try {
+            final ClassLoader cl = ClassLoaderProvider.getDefaultProvider().getServerIntegrationClassLoader();
+            SPIProvider spiProvider = SPIProviderResolver.getInstance(cl).getProvider();
+            serverConfig = spiProvider.getSPI(ServerConfigFactory.class, cl).getServerConfig();
+         } catch (Exception e) {
+            //ignore
+         } finally {
+            serverConfigInit = true;
+         }
+      }
+      return serverConfig;
+   }
 }

Modified: stack/native/trunk/modules/core/src/main/java/org/jboss/ws/core/jaxrpc/handler/HandlerChainBaseImpl.java
===================================================================
--- stack/native/trunk/modules/core/src/main/java/org/jboss/ws/core/jaxrpc/handler/HandlerChainBaseImpl.java	2012-09-27 10:14:40 UTC (rev 16774)
+++ stack/native/trunk/modules/core/src/main/java/org/jboss/ws/core/jaxrpc/handler/HandlerChainBaseImpl.java	2012-09-27 14:10:02 UTC (rev 16775)
@@ -39,11 +39,13 @@
 import javax.xml.rpc.handler.HandlerChain;
 import javax.xml.rpc.handler.HandlerInfo;
 import javax.xml.rpc.handler.MessageContext;
-import javax.xml.soap.SOAPPart;
+import javax.xml.soap.SOAPEnvelope;
+import javax.xml.soap.SOAPMessage;
 
 import org.jboss.logging.Logger;
 import org.jboss.ws.api.util.BundleUtils;
 import org.jboss.ws.common.Constants;
+import org.jboss.ws.core.MessageTrace;
 import org.jboss.ws.core.soap.SOAPEnvelopeImpl;
 import org.jboss.ws.core.soap.utils.SOAPElementWriter;
 import org.jboss.wsf.spi.deployment.Endpoint;
@@ -289,16 +291,14 @@
 
                   if (log.isTraceEnabled())
                   {
-                     SOAPPart soapPart = jaxrpcContext.getSOAPMessage().getSOAPPart();
-                     lastMessageTrace = traceSOAPPart("BEFORE handleRequest - " + currHandler, soapPart, lastMessageTrace);
+                     lastMessageTrace = traceSOAPPart("BEFORE handleRequest - " + currHandler, jaxrpcContext.getSOAPMessage(), lastMessageTrace);
                   }
 
                   doNext = currHandler.handleRequest(msgContext);
 
                   if (log.isTraceEnabled())
                   {
-                     SOAPPart soapPart = jaxrpcContext.getSOAPMessage().getSOAPPart();
-                     lastMessageTrace = traceSOAPPart("AFTER handleRequest - " + currHandler, soapPart, lastMessageTrace);
+                     lastMessageTrace = traceSOAPPart("AFTER handleRequest - " + currHandler, jaxrpcContext.getSOAPMessage(), lastMessageTrace);
                   }
                }
             }
@@ -368,16 +368,14 @@
 
                   if (log.isTraceEnabled())
                   {
-                     SOAPPart soapPart = jaxrpcContext.getSOAPMessage().getSOAPPart();
-                     lastMessageTrace = traceSOAPPart("BEFORE handleResponse - " + currHandler, soapPart, lastMessageTrace);
+                     lastMessageTrace = traceSOAPPart("BEFORE handleResponse - " + currHandler, jaxrpcContext.getSOAPMessage(), lastMessageTrace);
                   }
 
                   doNext = currHandler.handleResponse(msgContext);
 
                   if (log.isTraceEnabled())
                   {
-                     SOAPPart soapPart = jaxrpcContext.getSOAPMessage().getSOAPPart();
-                     lastMessageTrace = traceSOAPPart("AFTER handleResponse - " + currHandler, soapPart, lastMessageTrace);
+                     lastMessageTrace = traceSOAPPart("AFTER handleResponse - " + currHandler, jaxrpcContext.getSOAPMessage(), lastMessageTrace);
                   }
                }
             }
@@ -449,22 +447,28 @@
 
    /** Trace the SOAPPart, do nothing if the String representation is equal to the last one.
     */
-   protected String traceSOAPPart(String logMsg, SOAPPart soapPart, String lastMessageTrace)
+   protected String traceSOAPPart(String logMsg, SOAPMessage message, String lastMessageTrace)
    {
       try
       {
-         SOAPEnvelopeImpl soapEnv = (SOAPEnvelopeImpl)soapPart.getEnvelope();
-         String envStr = SOAPElementWriter.writeElement(soapEnv, true);
-         if (envStr.equals(lastMessageTrace))
-         {
-            log.trace(logMsg + ": unchanged");
+         SOAPEnvelope se = message.getSOAPPart().getEnvelope();
+         if (se instanceof SOAPEnvelopeImpl) {
+            SOAPEnvelopeImpl soapEnv = (SOAPEnvelopeImpl)se;
+            String envStr = SOAPElementWriter.writeElement(soapEnv, true);
+            if (envStr.equals(lastMessageTrace))
+            {
+               log.trace(logMsg + ": unchanged");
+            }
+            else
+            {
+               log.trace(logMsg + "\n" + envStr);
+               lastMessageTrace = envStr;
+            }
+            return lastMessageTrace;
+         } else {
+            MessageTrace.traceMessage(logMsg, message);
+            return null;
          }
-         else
-         {
-            log.trace(logMsg + "\n" + envStr);
-            lastMessageTrace = envStr;
-         }
-         return lastMessageTrace;
       }
       catch (Exception ex)
       {

Added: stack/native/trunk/modules/core/src/main/java/org/jboss/ws/core/utils/CachedOutputStream.java
===================================================================
--- stack/native/trunk/modules/core/src/main/java/org/jboss/ws/core/utils/CachedOutputStream.java	                        (rev 0)
+++ stack/native/trunk/modules/core/src/main/java/org/jboss/ws/core/utils/CachedOutputStream.java	2012-09-27 14:10:02 UTC (rev 16775)
@@ -0,0 +1,539 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2012, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file 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.core.utils;
+
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+public class CachedOutputStream extends OutputStream
+{
+   private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
+   private static final File DEFAULT_TEMP_DIR;
+   private static int defaultThreshold;
+   private static long defaultMaxSize;
+   static
+   {
+      String s = getSystemProperty("java.io.tmpdir");
+      if (s != null)
+      {
+         File f = new File(s);
+         if (f.exists() && f.isDirectory())
+         {
+            DEFAULT_TEMP_DIR = f;
+         }
+         else
+         {
+            DEFAULT_TEMP_DIR = null;
+         }
+      }
+      else
+      {
+         DEFAULT_TEMP_DIR = null;
+      }
+      setDefaultThreshold(-1);
+      setDefaultMaxSize(-1);
+   }
+
+   protected boolean outputLocked;
+   protected OutputStream currentStream;
+   private long threshold = defaultThreshold;
+   private long maxSize = defaultMaxSize;
+   private long totalLength;
+   private boolean inmem;
+   private boolean tempFileFailed;
+   private File tempFile;
+   private File outputDir = DEFAULT_TEMP_DIR;
+   private boolean allowDeleteOfFile = true;
+   private List<Object> streamList = new ArrayList<Object>();
+
+   public CachedOutputStream(PipedInputStream stream) throws IOException
+   {
+      currentStream = new PipedOutputStream(stream);
+      inmem = true;
+   }
+
+   public CachedOutputStream()
+   {
+      currentStream = new LoadingByteArrayOutputStream(2048);
+      inmem = true;
+   }
+
+   public CachedOutputStream(long threshold)
+   {
+      this.threshold = threshold;
+      currentStream = new LoadingByteArrayOutputStream(2048);
+      inmem = true;
+   }
+
+   public void holdTempFile()
+   {
+      allowDeleteOfFile = false;
+   }
+
+   public void releaseTempFileHold()
+   {
+      allowDeleteOfFile = true;
+   }
+
+   public void flush() throws IOException
+   {
+      currentStream.flush();
+   }
+
+   /**
+    * Locks the output stream to prevent additional writes, but maintains
+    * a pointer to it so an InputStream can be obtained
+    * @throws IOException
+    */
+   public void lockOutputStream() throws IOException
+   {
+      if (outputLocked)
+      {
+         return;
+      }
+      currentStream.flush();
+      outputLocked = true;
+      streamList.remove(currentStream);
+   }
+
+   public void close() throws IOException
+   {
+      currentStream.flush();
+      outputLocked = true;
+      currentStream.close();
+      maybeDeleteTempFile(currentStream);
+   }
+
+   public boolean equals(Object obj)
+   {
+      if (obj == this)
+      {
+         return true;
+      }
+      if (obj instanceof CachedOutputStream)
+      {
+         return currentStream.equals(((CachedOutputStream) obj).currentStream);
+      }
+      return currentStream.equals(obj);
+   }
+
+   public long size()
+   {
+      return totalLength;
+   }
+
+   public byte[] getBytes() throws IOException
+   {
+      flush();
+      if (inmem)
+      {
+         if (currentStream instanceof ByteArrayOutputStream)
+         {
+            return ((ByteArrayOutputStream) currentStream).toByteArray();
+         }
+         else
+         {
+            throw new IOException("Unknown format of currentStream");
+         }
+      }
+      else
+      {
+         FileInputStream fin = new FileInputStream(tempFile);
+         return readBytesFromStream(fin);
+      }
+   }
+
+   public void writeCacheTo(StringBuilder out, String charsetName) throws IOException
+   {
+      flush();
+      if (inmem)
+      {
+         if (currentStream instanceof ByteArrayOutputStream)
+         {
+            byte[] bytes = ((ByteArrayOutputStream) currentStream).toByteArray();
+            out.append(new String(bytes, charsetName));
+         }
+         else
+         {
+            throw new IOException("Unknown format of currentStream");
+         }
+      }
+      else
+      {
+         FileInputStream fin = new FileInputStream(tempFile);
+         byte bytes[] = new byte[1024];
+         int x = fin.read(bytes);
+         while (x != -1)
+         {
+            out.append(new String(bytes, 0, x, charsetName));
+            x = fin.read(bytes);
+         }
+         fin.close();
+      }
+   }
+
+   /**
+    * @return the underlying output stream
+    */
+   public OutputStream getOut()
+   {
+      return currentStream;
+   }
+
+   public int hashCode()
+   {
+      return currentStream.hashCode();
+   }
+
+   public String toString()
+   {
+      StringBuilder builder = new StringBuilder().append("[").append(CachedOutputStream.class.getName()).append(" Content: ");
+      try
+      {
+         writeCacheTo(builder, "UTF-8");
+      }
+      catch (IOException e)
+      {
+         //ignore
+      }
+      return builder.append("]").toString();
+   }
+
+   protected void onWrite() throws IOException
+   {
+
+   }
+
+   private void enforceLimits() throws IOException
+   {
+      if (maxSize > 0 && totalLength > maxSize)
+      {
+         throw new IOException();
+      }
+      if (inmem && totalLength > threshold && currentStream instanceof ByteArrayOutputStream)
+      {
+         createFileOutputStream();
+      }
+   }
+
+   public void write(byte[] b, int off, int len) throws IOException
+   {
+      if (!outputLocked)
+      {
+         onWrite();
+         this.totalLength += len;
+         enforceLimits();
+         currentStream.write(b, off, len);
+      }
+   }
+
+   public void write(byte[] b) throws IOException
+   {
+      if (!outputLocked)
+      {
+         onWrite();
+         this.totalLength += b.length;
+         enforceLimits();
+         currentStream.write(b);
+      }
+   }
+
+   public void write(int b) throws IOException
+   {
+      if (!outputLocked)
+      {
+         onWrite();
+         this.totalLength++;
+         enforceLimits();
+         currentStream.write(b);
+      }
+   }
+
+   private void createFileOutputStream() throws IOException
+   {
+      if (tempFileFailed)
+      {
+         return;
+      }
+      ByteArrayOutputStream bout = (ByteArrayOutputStream) currentStream;
+      try
+      {
+         tempFile = File.createTempFile("jbossws-cached-output-stream-", ".tmp", outputDir);
+         currentStream = new BufferedOutputStream(new FileOutputStream(tempFile));
+         bout.writeTo(currentStream);
+         inmem = false;
+         streamList.add(currentStream);
+      }
+      catch (Exception ex)
+      {
+         tempFileFailed = true;
+         if (currentStream != bout)
+         {
+            currentStream.close();
+         }
+         deleteTempFile();
+         inmem = true;
+         currentStream = bout;
+      }
+   }
+
+   public File getTempFile()
+   {
+      return tempFile != null && tempFile.exists() ? tempFile : null;
+   }
+
+   public InputStream getInputStream() throws IOException
+   {
+      flush();
+      if (inmem)
+      {
+         if (currentStream instanceof LoadingByteArrayOutputStream)
+         {
+            return ((LoadingByteArrayOutputStream) currentStream).createInputStream();
+         }
+         else if (currentStream instanceof ByteArrayOutputStream)
+         {
+            return new ByteArrayInputStream(((ByteArrayOutputStream) currentStream).toByteArray());
+         }
+         else if (currentStream instanceof PipedOutputStream)
+         {
+            return new PipedInputStream((PipedOutputStream) currentStream);
+         }
+         else
+         {
+            return null;
+         }
+      }
+      else
+      {
+         try
+         {
+            FileInputStream fileInputStream = new FileInputStream(tempFile)
+            {
+               boolean closed;
+
+               public void close() throws IOException
+               {
+                  if (!closed)
+                  {
+                     super.close();
+                     maybeDeleteTempFile(this);
+                  }
+                  closed = true;
+               }
+            };
+            streamList.add(fileInputStream);
+            return fileInputStream;
+         }
+         catch (FileNotFoundException e)
+         {
+            throw new IOException("Cached file was deleted, " + e.toString());
+         }
+      }
+   }
+
+   private synchronized void deleteTempFile()
+   {
+      if (tempFile != null)
+      {
+         File file = tempFile;
+         tempFile = null;
+         delete(file);
+      }
+   }
+
+   private void maybeDeleteTempFile(Object stream)
+   {
+      streamList.remove(stream);
+      if (!inmem && tempFile != null && streamList.isEmpty() && allowDeleteOfFile)
+      {
+         if (currentStream != null)
+         {
+            try
+            {
+               currentStream.close();
+            }
+            catch (Exception e)
+            {
+               //ignore
+            }
+         }
+         deleteTempFile();
+         currentStream = new LoadingByteArrayOutputStream(1024);
+         inmem = true;
+      }
+   }
+
+   public void setOutputDir(File outputDir) throws IOException
+   {
+      this.outputDir = outputDir;
+   }
+
+   public void setThreshold(long threshold)
+   {
+      this.threshold = threshold;
+   }
+
+   public void setMaxSize(long maxSize)
+   {
+      this.maxSize = maxSize;
+   }
+
+   public static void setDefaultMaxSize(long l)
+   {
+      defaultMaxSize = l;
+   }
+
+   public static void setDefaultThreshold(int i)
+   {
+      if (i < 0)
+      {
+         i = 64 * 1024;
+      }
+      defaultThreshold = i;
+   }
+
+   private static byte[] readBytesFromStream(InputStream in) throws IOException
+   {
+      int i = in.available();
+      if (i < DEFAULT_BUFFER_SIZE)
+      {
+         i = DEFAULT_BUFFER_SIZE;
+      }
+      ByteArrayOutputStream bos = new ByteArrayOutputStream(i);
+      copy(in, bos, DEFAULT_BUFFER_SIZE);
+      in.close();
+      return bos.toByteArray();
+   }
+
+   private static int copy(final InputStream input, final OutputStream output, int bufferSize) throws IOException
+   {
+      int avail = input.available();
+      if (avail > 262144)
+      {
+         avail = 262144;
+      }
+      if (avail > bufferSize)
+      {
+         bufferSize = avail;
+      }
+      final byte[] buffer = new byte[bufferSize];
+      int n = 0;
+      n = input.read(buffer);
+      int total = 0;
+      while (-1 != n)
+      {
+         if (n == 0)
+         {
+            throw new IOException("0 bytes read in violation of InputStream.read(byte[])");
+         }
+         output.write(buffer, 0, n);
+         total += n;
+         n = input.read(buffer);
+      }
+      return total;
+   }
+
+   private static void delete(File f)
+   {
+      if (!f.delete())
+      {
+         if (isWindows())
+         {
+            System.gc();
+         }
+         try
+         {
+            Thread.sleep(10);
+         }
+         catch (InterruptedException ex)
+         {
+            // Ignore Exception
+         }
+         if (!f.delete())
+         {
+            f.deleteOnExit();
+         }
+      }
+   }
+
+   private static boolean isWindows()
+   {
+      String osName = getSystemProperty("os.name").toLowerCase(Locale.US);
+      return osName.indexOf("windows") > -1;
+   }
+
+   private static String getSystemProperty(final String name)
+   {
+      PrivilegedAction<String> action = new PrivilegedAction<String>()
+      {
+         public String run()
+         {
+            return System.getProperty(name);
+         }
+      };
+      return AccessController.doPrivileged(action);
+   }
+
+   private static class LoadingByteArrayOutputStream extends ByteArrayOutputStream
+   {
+      public LoadingByteArrayOutputStream(int i)
+      {
+         super(i);
+      }
+
+      public ByteArrayInputStream createInputStream()
+      {
+         return new ByteArrayInputStream(buf, 0, count)
+         {
+            public String toString()
+            {
+               return new String(buf, 0, count);
+            }
+         };
+      }
+
+      public byte[] toByteArray()
+      {
+         if (count != buf.length)
+         {
+            buf = super.toByteArray();
+         }
+         return buf;
+      }
+   }
+}



More information about the jbossws-commits mailing list