You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commons-dev@ws.apache.org by Davanum Srinivas <da...@gmail.com> on 2008/04/09 22:26:45 UTC

Potential problem with 646502 (Re: svn commit: r646502 - in /webservices/commons/trunk/modules/axiom/modules: axiom-api/src/main/java/org/apache/axiom/attachments/impl/ axiom-api/src/main/java/org/apache/axiom/om/ axiom-api/src/main/java/org/apache/axiom/om/impl/ axiom-tests/src/test/ja...)

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Nikhil,

For some DataSources, when you read the contents once, you lose 'em. The code just after the following snippet

| +        //read bytes from input stream to check if
| +        //attachment size is greater than the optimized size.

reads the input stream and we lose the data...So can you please add some additional conditions.

1. Check if it is a FileDataSource
2. If it's not a FileDataSource, check if the InputStream supports mark/reset and use that instead.

thanks,
dims

nthaker@apache.org wrote:
| Author: nthaker
| Date: Wed Apr  9 12:42:39 2008
| New Revision: 646502
|
| URL: http://svn.apache.org/viewvc?rev=646502&view=rev
| Log:
| WSCOMMONS-313
|
| Modified:
|
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/attachments/impl/BufferUtils.java
|     webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/OMOutputFormat.java
|
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/MTOMXMLStreamWriter.java
|
webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/attachments/impl/BufferUtilsTests.java
|
| Modified:
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/attachments/impl/BufferUtils.java
| URL:
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/attachments/impl/BufferUtils.java?rev=646502&r1=646501&r2=646502&view=diff
| ==============================================================================
| ---
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/attachments/impl/BufferUtils.java
(original)
| +++
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/attachments/impl/BufferUtils.java
Wed Apr  9 12:42:39 2008
| @@ -16,7 +16,6 @@
|   * specific language governing permissions and limitations
|   * under the License.
|   */
| -
|  package org.apache.axiom.attachments.impl;
|
|  import java.io.FileOutputStream;
| @@ -27,13 +26,19 @@
|  import java.nio.channels.FileChannel;
|  import java.nio.channels.FileLock;
|
| +import javax.activation.DataHandler;
| +
| +import org.apache.axiom.om.OMException;
| +import org.apache.commons.logging.Log;
| +import org.apache.commons.logging.LogFactory;
| +
|  /**
|   * Attachment processing uses a lot of buffers.
|   * The BufferUtils class attempts to reuse buffers to prevent
|   * excessive GarbageCollection
|   */
|  public class BufferUtils {
| -
| +    private static Log log = LogFactory.getLog(BufferUtils.class);
|      // Performance testing indicates that 4K is the best size for medium
|      // and small payloads.  And there is a neglible effect on large payloads.
|      static int BUFFER_LEN = 4 * 1024;         // Copy Buffer size
| @@ -181,6 +186,80 @@
|             releaseTempByteBuffer(bb);
|          }
|          return true;
| +    }
| +    /**
| +     * The method checks to see if attachment is eligble for optimization.
| +     * An attachment is eligible for optimization if and only if the size of
| +     * the attachment is greated then the optimzation threshold size limit.
| +     * if the Content represented by DataHandler has size less than the
| +     * optimize threshold size, the attachment will not be eligible for
| +     * optimization, instead it will be inlined.
| +     * returns 1 if DataHandler data is bigger than limit.
| +     * returns 0 if DataHandler data is smaller.
| +     * return -1 if an error occurs or unsupported.
| +     * @param in
| +     * @return
| +     * @throws IOException
| +     */
| +    public static int doesDataHandlerExceedLimit(DataHandler dh, long limit){
| +        if(log.isDebugEnabled()){
| +            log.debug("start isEligibleForOptimization");
| +        }
| +        //If Optimized Threshold not set return true.
| +        if(limit==0){
| +            if(log.isDebugEnabled()){
| +                log.debug("optimizedThreshold not set");
| +            }
| +            return -1;
| +        }
| +        InputStream in = getInputStream(dh);
| +        if(in == null){
| +            if(log.isDebugEnabled()){
| +                log.debug("Input Stream is null");
| +            }
| +            return -1;
| +        }
| +
| +        //read bytes from input stream to check if
| +        //attachment size is greater than the optimized size.
| +        int totalRead = 0;
| +        try{
| +            do{
| +                byte[] buffer = getTempBuffer();
| +                int bytesRead = in.read(buffer, 0, BUFFER_LEN);
| +                totalRead = totalRead+bytesRead;
| +                releaseTempBuffer(buffer);
| +            }while((limit>totalRead) && (in.available()>0));
| +
| +            if(totalRead > limit){
| +                if(log.isDebugEnabled()){
| +                    log.debug("Attachment size greater than limit");
| +                }
| +                return 1;
| +            }
| +        }catch(IOException e){
| +            return -1;
| +        }
| +
| +        if(log.isDebugEnabled()){
| +            log.debug("Attachment Size smaller than limit");
| +        }
| +
| +        return 0;
| +    }
| +
| +    private static java.io.InputStream getInputStream(DataHandler dataHandlerObject) throws OMException {
| +        InputStream inStream;
| +        javax.activation.DataHandler dataHandler =
| +            (javax.activation.DataHandler) dataHandlerObject;
| +        try {
| +            inStream = dataHandler.getDataSource().getInputStream();
| +        } catch (IOException e) {
| +            throw new OMException(
| +                "Cannot get InputStream from DataHandler." + e);
| +        }
| +        return inStream;
| +
|      }
|
|      private static synchronized byte[] getTempBuffer() {
|
| Modified: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/OMOutputFormat.java
| URL:
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/OMOutputFormat.java?rev=646502&r1=646501&r2=646502&view=diff
| ==============================================================================
| --- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/OMOutputFormat.java
(original)
| +++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/OMOutputFormat.java
Wed Apr  9 12:42:39 2008
| @@ -19,6 +19,8 @@
|
|  package org.apache.axiom.om;
|
| +import java.util.HashMap;
| +
|  import org.apache.axiom.om.impl.MTOMConstants;
|  import org.apache.axiom.om.util.UUIDGenerator;
|  import org.apache.axiom.soap.SOAP11Constants;
| @@ -26,8 +28,6 @@
|  import org.apache.commons.logging.Log;
|  import org.apache.commons.logging.LogFactory;
|
| -import java.util.HashMap;
| -
|
|  /**
|   * Formats options for OM Output.
| @@ -46,7 +46,8 @@
|      private boolean doOptimize = false;
|      private boolean doingSWA = false;
|      private boolean isSoap11 = true;
| -
| +    private long optimizedThreshold = 0;
| +
|      /** Field DEFAULT_CHAR_SET_ENCODING. Specifies the default character encoding scheme to be used. */
|      public static final String DEFAULT_CHAR_SET_ENCODING = "utf-8";
|
| @@ -337,11 +338,21 @@
|          // TODO Print all properties
|          sb.append(" actionProperty=");
|          sb.append(getProperty(ACTION_PROPERTY));
| +
| +        sb.append(" optimizedThreshold=");
| +        sb.append(optimizedThreshold);
|
|          sb.append("]");
|          return sb.toString();
|
|      }
| +
| +    public void setOptimizedThreshold(long optimizedThreshold) {
| +        this.optimizedThreshold = optimizedThreshold;
| +    }
|
| +    public long getOptimizedThreshold() {
| +        return optimizedThreshold;
| +    }
|
|  }
|
| Modified:
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/MTOMXMLStreamWriter.java
| URL:
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/MTOMXMLStreamWriter.java?rev=646502&r1=646501&r2=646502&view=diff
| ==============================================================================
| ---
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/MTOMXMLStreamWriter.java
(original)
| +++
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/MTOMXMLStreamWriter.java
Wed Apr  9 12:42:39 2008
| @@ -19,25 +19,28 @@
|
|  package org.apache.axiom.om.impl;
|
| -import org.apache.axiom.om.OMException;
| -import org.apache.axiom.om.OMOutputFormat;
| -import org.apache.axiom.om.OMText;
| -import org.apache.axiom.om.util.StAXUtils;
| -import org.apache.axiom.soap.SOAP11Constants;
| -import org.apache.axiom.soap.SOAP12Constants;
| -import org.apache.axiom.attachments.ByteArrayDataSource;
| +import java.io.ByteArrayOutputStream;
| +import java.io.IOException;
| +import java.io.OutputStream;
| +import java.io.UnsupportedEncodingException;
| +import java.util.LinkedList;
|
| +import javax.activation.DataHandler;
|  import javax.xml.namespace.NamespaceContext;
|  import javax.xml.stream.FactoryConfigurationError;
|  import javax.xml.stream.XMLStreamException;
|  import javax.xml.stream.XMLStreamWriter;
|
| -import java.io.ByteArrayOutputStream;
| -import java.io.IOException;
| -import java.io.OutputStream;
| -import java.io.StringWriter;
| -import java.io.UnsupportedEncodingException;
| -import java.util.LinkedList;
| +import org.apache.axiom.attachments.impl.BufferUtils;
| +import org.apache.axiom.om.OMException;
| +import org.apache.axiom.om.OMNode;
| +import org.apache.axiom.om.OMOutputFormat;
| +import org.apache.axiom.om.OMText;
| +import org.apache.axiom.om.util.StAXUtils;
| +import org.apache.axiom.soap.SOAP11Constants;
| +import org.apache.axiom.soap.SOAP12Constants;
| +import org.apache.commons.logging.Log;
| +import org.apache.commons.logging.LogFactory;
|
|
|  /**
| @@ -48,6 +51,9 @@
|   * optimizable content.
|   */
|  public class MTOMXMLStreamWriter implements XMLStreamWriter {
| +    private static Log log = LogFactory.getLog(MTOMXMLStreamWriter.class);
| +    private final static int UNSUPPORTED = -1;
| +    private final static int EXCEED_LIMIT = 1;
|      private XMLStreamWriter xmlWriter;
|      private OutputStream outStream;
|      private LinkedList binaryNodeList = new LinkedList();
| @@ -268,7 +274,33 @@
|      }
|
|      public void writeOptimized(OMText node) {
| -        binaryNodeList.add(node);
| +        if(log.isDebugEnabled()){
| +            log.debug("Start MTOMXMLStreamWriter.writeOptimized()");
| +        }
| +        DataHandler dh = (DataHandler)node.getDataHandler();
| +        int optimized = UNSUPPORTED;
| +        if(dh!=null){
| +            if(log.isDebugEnabled()){
| +                log.debug("DataHandler fetched, starting optimized Threshold processing");
| +            }
| +            optimized= BufferUtils.doesDataHandlerExceedLimit(dh, format.getOptimizedThreshold());
| +        }
| +        if(optimized == UNSUPPORTED || optimized == EXCEED_LIMIT){
| +            if(log.isDebugEnabled()){
| +                log.debug("node added to binart NodeList for optimization");
| +            }
| +            binaryNodeList.add(node);
| +        }
| +        else{
| +            try{
| +                writeOutput(node);
| +            }catch(XMLStreamException e){
| +                throw new RuntimeException("XMLStreamException in writeOutput() call", e);
| +            }
| +        }
| +        if(log.isDebugEnabled()){
| +            log.debug("Exit MTOMXMLStreamWriter.writeOptimized()");
| +        }
|      }
|
|      public void setXmlStreamWriter(XMLStreamWriter xmlWriter) {
| @@ -356,5 +388,22 @@
|              this.flush();
|          }
|          return os;
| +    }
| +
| +    /**
| +     * Writes the relevant output.
| +     *
| +     * @param writer
| +     * @throws XMLStreamException
| +     */
| +    private void writeOutput(OMText textNode) throws XMLStreamException {
| +        int type = textNode.getType();
| +        if (type == OMNode.TEXT_NODE || type == OMNode.SPACE_NODE) {
| +            writeCharacters(textNode.getText());
| +        } else if (type == OMNode.CDATA_SECTION_NODE) {
| +            writeCData(textNode.getText());
| +        } else if (type == OMNode.ENTITY_REFERENCE_NODE) {
| +            writeEntityRef(textNode.getText());
| +        }
|      }
|  }
|
| Modified:
webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/attachments/impl/BufferUtilsTests.java
| URL:
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/attachments/impl/BufferUtilsTests.java?rev=646502&r1=646501&r2=646502&view=diff
| ==============================================================================
| ---
webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/attachments/impl/BufferUtilsTests.java
(original)
| +++
webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/attachments/impl/BufferUtilsTests.java
Wed Apr  9 12:42:39 2008
| @@ -16,13 +16,17 @@
|   * specific language governing permissions and limitations
|   * under the License.
|   */
| -
|  package org.apache.axiom.attachments.impl;
|
|  import java.io.ByteArrayInputStream;
|  import java.io.File;
|  import java.io.FileInputStream;
|  import java.io.FileOutputStream;
| +import java.io.IOException;
| +
| +import javax.activation.DataHandler;
| +import javax.activation.FileDataSource;
| +import javax.activation.MimeType;
|
|  import junit.framework.TestCase;
|
| @@ -77,4 +81,41 @@
|          file.delete();
|      }
|
| +    public void testDataSourceBackedDataHandlerExceedLimit(){
| +        String imgFileLocation="modules/axiom-tests/test-resources/mtom/img/test2.jpg";
| +        try{
| +            String baseDir = new File(System.getProperty("basedir",".")).getCanonicalPath();
| +            imgFileLocation = new File(baseDir +File.separator+ imgFileLocation).getAbsolutePath();
| +        }catch(IOException e){
| +            e.printStackTrace();
| +            fail();
| +        }
| +
| +        File imgFile = new File(imgFileLocation);
| +        FileDataSource fds = new FileDataSource(imgFile);
| +        DataHandler dh = new DataHandler(fds);
| +        int unsupported= BufferUtils.doesDataHandlerExceedLimit(dh, 0);
| +        assertEquals(unsupported, -1);
| +        int doesExceed = BufferUtils.doesDataHandlerExceedLimit(dh, 1000);
| +        assertEquals(doesExceed, 1);
| +        int doesNotExceed = BufferUtils.doesDataHandlerExceedLimit(dh, 100000);
| +        assertEquals(doesNotExceed, 0);
| +
| +    }
| +    public void testObjectBackedDataHandlerExceedLimit(){
| +        String str = "This is a test String";
| +        try{
| +            DataHandler dh = new DataHandler(str, "text/plain");
| +            int unsupported= BufferUtils.doesDataHandlerExceedLimit(dh, 0);
| +            assertEquals(unsupported, -1);
| +            int doesExceed = BufferUtils.doesDataHandlerExceedLimit(dh, 10);
| +            assertEquals(doesExceed, 1);
| +            int doesNotExceed = BufferUtils.doesDataHandlerExceedLimit(dh, 100);
| +            assertEquals(doesNotExceed, 0);
| +        }catch(Exception e){
| +            e.printStackTrace();
| +            fail();
| +        }
| +
| +    }
|  }
|
|
|
| ---------------------------------------------------------------------
| To unsubscribe, e-mail: commons-dev-unsubscribe@ws.apache.org
| For additional commands, e-mail: commons-dev-help@ws.apache.org
|
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (Cygwin)

iD8DBQFH/SaFgNg6eWEDv1kRAo2WAJoDs/6w8CMQ4jbMbD8G4ayQujGnZQCcDvfT
a4gIe3dB5Z3RZzR9Qz4lCH4=
=XAQI
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: commons-dev-help@ws.apache.org