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 sc...@apache.org on 2008/04/23 03:34:43 UTC
svn commit: r650719 - in /webservices/commons/trunk/modules/axiom/modules:
axiom-api/src/main/java/org/apache/axiom/attachments/
axiom-api/src/main/java/org/apache/axiom/om/util/
axiom-tests/src/test/java/org/apache/axiom/attachments/
Author: scheu
Date: Tue Apr 22 18:34:41 2008
New Revision: 650719
URL: http://svn.apache.org/viewvc?rev=650719&view=rev
Log:
WSCOMMONS-330
Contributor:Rich Scheuerle
Provide a mechanism to get the content length of the incoming message from the attachments object
Added:
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/util/DetachableInputStream.java
Modified:
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/attachments/Attachments.java
webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/attachments/AttachmentsTest.java
Modified: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/attachments/Attachments.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/attachments/Attachments.java?rev=650719&r1=650718&r2=650719&view=diff
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/attachments/Attachments.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/attachments/Attachments.java Tue Apr 22 18:34:41 2008
@@ -24,6 +24,7 @@
import org.apache.axiom.attachments.lifecycle.impl.LifecycleManagerImpl;
import org.apache.axiom.om.OMException;
import org.apache.axiom.om.impl.MTOMConstants;
+import org.apache.axiom.om.util.DetachableInputStream;
import org.apache.axiom.om.util.UUIDGenerator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -64,6 +65,7 @@
*/
PushbackInputStream pushbackInStream;
int PUSHBACK_SIZE = 4 * 1024;
+ DetachableInputStream filterIS = null;
/**
* <code>attachmentsMap</code> stores the Data Handlers of the already parsed Mime Body Parts.
@@ -196,9 +198,14 @@
throw new OMException(e);
}
- // do we need to wrap InputStream from a BufferedInputStream before
- // wrapping from PushbackStream
- pushbackInStream = new PushbackInputStream(inStream,
+ // If the length is not known, install a TeeInputStream
+ // so that we can retrieve it later.
+ InputStream is = inStream;
+ if (contentLength <= 0) {
+ filterIS = new DetachableInputStream(inStream);
+ is = filterIS;
+ }
+ pushbackInStream = new PushbackInputStream(is,
PUSHBACK_SIZE);
// Move the read pointer to the beginning of the first part
@@ -498,7 +505,28 @@
public List getContentIDList() {
return cids;
}
-
+
+ /**
+ * If the Attachments is backed by an InputStream, then this
+ * method returns the length of the message contents
+ * (Length of the entire message - Length of the Transport Headers)
+ * @return length of message content or -1 if Attachments is not
+ * backed by an InputStream
+ * @see getMessageLength
+ */
+ public long getContentLength() throws IOException {
+ if (contentLength > 0) {
+ return contentLength;
+ } else if (filterIS != null) {
+ // Ensure all parts are read
+ this.getContentIDSet();
+ // Now get the count from the filter
+ return filterIS.length();
+ } else {
+ return -1; // not backed by an input stream
+ }
+ }
+
/**
* endOfStreamReached will be set to true if the message ended in MIME Style having "--" suffix
* with the last mime boundary
Added: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/util/DetachableInputStream.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/util/DetachableInputStream.java?rev=650719&view=auto
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/util/DetachableInputStream.java (added)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/util/DetachableInputStream.java Tue Apr 22 18:34:41 2008
@@ -0,0 +1,169 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.axiom.om.util;
+
+import org.apache.axiom.attachments.impl.BufferUtils;
+import org.apache.axiom.attachments.utils.BAAInputStream;
+import org.apache.axiom.attachments.utils.BAAOutputStream;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * FilterInputStream that delegates to the original
+ * InputStream. When detach() is called, the original
+ * InputStream is consumed, and closed. The unread bytes are
+ * stored in a local stream.
+ * Subsequent requests are serviced by the local stream.
+ *
+ * Rationale: The detached stream can be closed and its
+ * resources freed, but the consumer of the stream can
+ * continue to receive data.
+ *
+ * Cons: If there are a lot of bytes remaining, these are
+ * buffered. Currently they are buffered incore (this
+ * could be improved to buffer in a file).
+ *
+ */
+public class DetachableInputStream extends FilterInputStream {
+
+
+
+ private long count = 0;
+ BAAInputStream localStream = null;
+ public DetachableInputStream(InputStream in) {
+ super(in);
+ count = 0;
+ }
+
+ /**
+ * @return count of bytes read
+ */
+ public long length() throws IOException {
+ if (localStream == null) {
+ detach();
+ }
+ return count;
+
+ }
+
+ /**
+ * Consume the input stream and close it.
+ * The bytes in the input stream are buffered.
+ * (Thus the original input stream can release its
+ * resources, but the consumer of the stream can
+ * still receive data).
+ * @throws IOException
+ */
+ public void detach() throws IOException {
+ if (localStream == null) {
+
+ BAAOutputStream baaos = new BAAOutputStream();
+ BufferUtils.inputStream2OutputStream(in, baaos);
+ super.close();
+ in = null; // GC the incoming stream
+
+ localStream = new BAAInputStream(baaos.buffers(), baaos.length());
+ count = count + baaos.length();
+ }
+ }
+
+ public int available() throws IOException {
+ if (localStream != null) {
+ return localStream.available();
+ } else {
+ return super.available();
+ }
+ }
+
+ public void close() throws IOException {
+ if (localStream != null) {
+ localStream.close();
+ } else {
+ super.close();
+ }
+ }
+
+ public boolean markSupported() {
+ // Mark is not supported because stream can
+ // switch
+ return false;
+ }
+
+ public synchronized void mark(int readlimit) {
+ throw new UnsupportedOperationException();
+ }
+
+ public int read() throws IOException {
+ if (localStream == null) {
+ int rc = super.read();
+ if (rc != -1) {
+ count++;
+ }
+ return rc;
+ } else {
+ return localStream.read();
+ }
+ }
+
+ public int read(byte[] b, int off, int len) throws IOException {
+ if (localStream == null) {
+ int rc = super.read(b, off, len);
+ if (rc > 0) {
+ count += rc;
+ }
+ return rc;
+ } else {
+ return localStream.read(b, off, len);
+ }
+ }
+
+ public int read(byte[] b) throws IOException {
+ if (localStream == null) {
+ int rc = super.read(b);
+ if (rc > 0) {
+ count += rc;
+ }
+ return rc;
+ } else {
+ return localStream.read(b);
+ }
+ }
+
+ public synchronized void reset() throws IOException {
+ throw new IOException();
+ }
+
+ public long skip(long n) throws IOException {
+ if (localStream == null) {
+ long rc = super.skip(n);
+ if (rc > 0) {
+ count += rc;
+ }
+ return rc;
+ } else {
+ return localStream.skip(n);
+ }
+ }
+
+
+
+
+}
Modified: webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/attachments/AttachmentsTest.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/attachments/AttachmentsTest.java?rev=650719&r1=650718&r2=650719&view=diff
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/attachments/AttachmentsTest.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/attachments/AttachmentsTest.java Tue Apr 22 18:34:41 2008
@@ -24,6 +24,7 @@
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import java.io.ByteArrayOutputStream;
+import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -145,11 +146,11 @@
// Confirm that no more streams are left
assertEquals(null, ias.getNextStream());
-
+
// After all is done, we should *still* be able to access and
// re-consume the SOAP part stream, as it should be cached.. can we?
is = attachments.getSOAPPartInputStream();
- while (is.read() != -1) ;
+ while (is.read() != -1) ;
}
private void compareStreams(InputStream data, InputStream expected) throws Exception {
@@ -190,7 +191,8 @@
public void testGetAllContentIDs() throws Exception {
- InputStream inStream = new FileInputStream(getTestResourceFile(inMimeFileName));
+ File f = getTestResourceFile(inMimeFileName);
+ InputStream inStream = new FileInputStream(f);
Attachments attachments = new Attachments(inStream, contentTypeString);
String[] contentIDs = attachments.getAllContentIDs();
@@ -203,6 +205,12 @@
assertTrue(idSet.contains("0.urn:uuid:A3ADBAEE51A1A87B2A11443668160702@apache.org"));
assertTrue(idSet.contains("2.urn:uuid:A3ADBAEE51A1A87B2A11443668160994@apache.org"));
assertTrue(idSet.contains("1.urn:uuid:A3ADBAEE51A1A87B2A11443668160943@apache.org"));
+
+ // Make sure the length is correct
+ long length = attachments.getContentLength();
+ long fileSize = f.length();
+ assertTrue("Expected MessageContent Length of " + fileSize + " but received " + length,
+ length == fileSize);
}
/**