You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ws.apache.org by ve...@apache.org on 2016/04/29 21:25:53 UTC
svn commit: r1741696 - in
/webservices/axiom/trunk/axiom-api/src/main/java/org/apache/axiom/attachments:
IncomingAttachmentStreams.java MIMEMessage.java MIMEMessageAdapter.java
Part.java PartImpl.java PartIterator.java
Author: veithen
Date: Fri Apr 29 19:25:53 2016
New Revision: 1741696
URL: http://svn.apache.org/viewvc?rev=1741696&view=rev
Log:
Reimplement IncomingAttachmentStreams so that it no longer accesses the MIME parser directly.
Added:
webservices/axiom/trunk/axiom-api/src/main/java/org/apache/axiom/attachments/PartIterator.java (with props)
Modified:
webservices/axiom/trunk/axiom-api/src/main/java/org/apache/axiom/attachments/IncomingAttachmentStreams.java
webservices/axiom/trunk/axiom-api/src/main/java/org/apache/axiom/attachments/MIMEMessage.java
webservices/axiom/trunk/axiom-api/src/main/java/org/apache/axiom/attachments/MIMEMessageAdapter.java
webservices/axiom/trunk/axiom-api/src/main/java/org/apache/axiom/attachments/Part.java
webservices/axiom/trunk/axiom-api/src/main/java/org/apache/axiom/attachments/PartImpl.java
Modified: webservices/axiom/trunk/axiom-api/src/main/java/org/apache/axiom/attachments/IncomingAttachmentStreams.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/axiom-api/src/main/java/org/apache/axiom/attachments/IncomingAttachmentStreams.java?rev=1741696&r1=1741695&r2=1741696&view=diff
==============================================================================
--- webservices/axiom/trunk/axiom-api/src/main/java/org/apache/axiom/attachments/IncomingAttachmentStreams.java (original)
+++ webservices/axiom/trunk/axiom-api/src/main/java/org/apache/axiom/attachments/IncomingAttachmentStreams.java Fri Apr 29 19:25:53 2016
@@ -20,14 +20,10 @@
package org.apache.axiom.attachments;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Iterator;
+import org.apache.axiom.mime.Header;
import org.apache.axiom.om.OMException;
-import org.apache.james.mime4j.MimeException;
-import org.apache.james.mime4j.stream.EntityState;
-import org.apache.james.mime4j.stream.Field;
-import org.apache.james.mime4j.stream.MimeTokenStream;
/**
* Container for AttachmentStream s. This class provides an SwA like access mechanism, allowing
@@ -35,7 +31,8 @@ import org.apache.james.mime4j.stream.Mi
* like (stream access), or MTOM like (part/data handler access via blob id), not both.
*/
public final class IncomingAttachmentStreams {
- private final MimeTokenStream parser;
+ private final Part rootPart;
+ private final Iterator<Part> partIterator;
/**
* Boolean indicating weather or not the next stream can be read (next stream cannot be read until
@@ -43,8 +40,9 @@ public final class IncomingAttachmentStr
*/
private boolean readyToGetNextStream = true;
- IncomingAttachmentStreams(MimeTokenStream parser) {
- this.parser = parser;
+ IncomingAttachmentStreams(MIMEMessage message) {
+ rootPart = message.getRootPart();
+ partIterator = message.iterator();
}
/** @return True if the next stream can be read, false otherwise. */
@@ -67,42 +65,31 @@ public final class IncomingAttachmentStr
* @return The next stream or null if no additional streams are left.
*/
public IncomingAttachmentInputStream getNextStream() throws OMException {
- IncomingAttachmentInputStream stream;
-
if (!readyToGetNextStream) {
throw new IllegalStateException("nextStreamNotReady");
}
- try {
- if (parser.getState() == EntityState.T_BODY) {
- if (parser.next() != EntityState.T_END_BODYPART) {
- throw new IllegalStateException();
- }
- parser.next();
- }
-
- if (parser.getState() != EntityState.T_START_BODYPART) {
- return null;
- }
-
- if (parser.next() != EntityState.T_START_HEADER) {
- throw new IllegalStateException();
- }
-
- List<Field> fields = new ArrayList<Field>();
- while (parser.next() == EntityState.T_FIELD) {
- fields.add(parser.getField());
+ Part part = null;
+ while (part == null && partIterator.hasNext()) {
+ part = partIterator.next();
+ // Skip the root part
+ if (part == rootPart) {
+ part = null;
}
-
- if (parser.next() != EntityState.T_BODY) {
- throw new IllegalStateException();
+ }
+
+ if (part != null) {
+ IncomingAttachmentInputStream stream;
+
+ try {
+ stream = new IncomingAttachmentInputStream(part.getInputStream(false), this);
+ } catch (IOException ex) {
+ throw new OMException(ex);
}
-
- stream = new IncomingAttachmentInputStream(parser.getInputStream(), this);
- for (Field field : fields) {
- String name = field.getName();
- String value = field.getBody();
+ for (Header header : part.getHeaders()) {
+ String name = header.getName();
+ String value = header.getValue();
if (IncomingAttachmentInputStream.HEADER_CONTENT_ID.equals(name)
|| IncomingAttachmentInputStream.HEADER_CONTENT_TYPE.equals(name)
|| IncomingAttachmentInputStream.HEADER_CONTENT_LOCATION.equals(name)) {
@@ -110,13 +97,11 @@ public final class IncomingAttachmentStr
}
stream.addHeader(name, value);
}
- } catch (MimeException ex) {
- throw new OMException(ex);
- } catch (IOException ex) {
- throw new OMException(ex);
+
+ readyToGetNextStream = false;
+ return stream;
+ } else {
+ return null;
}
-
- readyToGetNextStream = false;
- return stream;
}
}
\ No newline at end of file
Modified: webservices/axiom/trunk/axiom-api/src/main/java/org/apache/axiom/attachments/MIMEMessage.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/axiom-api/src/main/java/org/apache/axiom/attachments/MIMEMessage.java?rev=1741696&r1=1741695&r2=1741696&view=diff
==============================================================================
--- webservices/axiom/trunk/axiom-api/src/main/java/org/apache/axiom/attachments/MIMEMessage.java (original)
+++ webservices/axiom/trunk/axiom-api/src/main/java/org/apache/axiom/attachments/MIMEMessage.java Fri Apr 29 19:25:53 2016
@@ -23,6 +23,7 @@ import java.io.InputStream;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -49,7 +50,7 @@ import org.apache.james.mime4j.stream.Re
* {@link AttachmentsDelegate} implementation that represents a MIME multipart message read from a
* stream.
*/
-class MIMEMessage {
+class MIMEMessage implements Iterable<Part> {
private static final Log log = LogFactory.getLog(MIMEMessage.class);
/** <code>ContentType</code> of the MIME message */
@@ -68,15 +69,6 @@ class MIMEMessage {
*/
private PartImpl currentPart;
- /** Container to hold streams for direct access */
- private IncomingAttachmentStreams streams;
-
- /** <code>boolean</code> Indicating if any streams have been directly requested */
- private boolean streamsRequested;
-
- /** <code>boolean</code> Indicating if any data handlers have been directly requested */
- private boolean partsRequested;
-
private PartImpl firstPart;
private PartImpl rootPart;
@@ -112,13 +104,6 @@ class MIMEMessage {
throw new OMException(ex);
}
}
-
- // Read the root part and cache it
- getDataHandler(getRootPartContentID());
-
- // Now reset partsRequested. The root part is a special case which is always
- // read beforehand, regardless of request.
- partsRequested = false;
}
ContentType getContentType() {
@@ -135,6 +120,13 @@ class MIMEMessage {
return null;
}
+ PartImpl getFirstPart() {
+ if (firstPart == null) {
+ getNextPart();
+ }
+ return firstPart;
+ }
+
Part getRootPart() {
do {
if (rootPart != null) {
@@ -148,31 +140,13 @@ class MIMEMessage {
String getRootPartContentID() {
// to handle the Start parameter not mentioned situation
if (rootPartContentID == null) {
- if (partMap.isEmpty()) {
- getNextPart();
- }
+ Part firstPart = getFirstPart();
return firstPart == null ? null : firstPart.getContentID();
} else {
return rootPartContentID;
}
}
- IncomingAttachmentStreams getIncomingAttachmentStreams() {
- if (partsRequested) {
- throw new IllegalStateException(
- "The attachments stream can only be accessed once; either by using the IncomingAttachmentStreams class or by getting a " +
- "collection of AttachmentPart objects. They cannot both be called within the life time of the same service request.");
- }
-
- streamsRequested = true;
-
- if (this.streams == null) {
- this.streams = new IncomingAttachmentStreams(parser);
- }
-
- return this.streams;
- }
-
/**
* Force reading of all attachments.
*/
@@ -194,18 +168,12 @@ class MIMEMessage {
return Collections.<String,Part>unmodifiableMap(partMap);
}
- private PartImpl getNextPart() throws OMException {
- if (streamsRequested) {
- throw new IllegalStateException("The attachments stream can only be accessed once; either by using the IncomingAttachmentStreams class or by getting a collection of AttachmentPart objects. They cannot both be called within the life time of the same service request.");
- }
- partsRequested = true;
-
+ PartImpl getNextPart() throws OMException {
if (currentPart != null) {
currentPart.fetch();
- currentPart = null;
}
if (parser.getState() == EntityState.T_END_MULTIPART) {
- return null;
+ currentPart = null;
} else {
String partContentID = null;
boolean isRootPart;
@@ -241,7 +209,13 @@ class MIMEMessage {
"Part content ID cannot be blank for non root MIME parts");
}
- currentPart = new PartImpl(isRootPart ? MemoryBlob.FACTORY : attachmentBlobFactory, partContentID, headers, parser);
+ PartImpl part = new PartImpl(this, isRootPart ? MemoryBlob.FACTORY : attachmentBlobFactory, partContentID, headers, parser);
+ if (currentPart == null) {
+ firstPart = part;
+ } else {
+ currentPart.setNextPart(part);
+ }
+ currentPart = part;
} catch (IOException ex) {
throw new OMException(ex);
} catch (MimeException ex) {
@@ -252,9 +226,6 @@ class MIMEMessage {
// We only get here if isRootPart is true
partContentID = "firstPart_" + UIDGenerator.generateContentId();
}
- if (partMap.isEmpty()) {
- firstPart = currentPart;
- }
if (partMap.containsKey(partContentID)) {
throw new OMException(
"Two MIME parts with the same Content-ID not allowed.");
@@ -263,8 +234,8 @@ class MIMEMessage {
if (isRootPart) {
rootPart = currentPart;
}
- return currentPart;
}
+ return currentPart;
}
private static void checkParserState(EntityState state, EntityState expected) throws IllegalStateException {
@@ -273,4 +244,9 @@ class MIMEMessage {
+ expected + ", but got " + state);
}
}
+
+ @Override
+ public Iterator<Part> iterator() {
+ return new PartIterator(this);
+ }
}
Modified: webservices/axiom/trunk/axiom-api/src/main/java/org/apache/axiom/attachments/MIMEMessageAdapter.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/axiom-api/src/main/java/org/apache/axiom/attachments/MIMEMessageAdapter.java?rev=1741696&r1=1741695&r2=1741696&view=diff
==============================================================================
--- webservices/axiom/trunk/axiom-api/src/main/java/org/apache/axiom/attachments/MIMEMessageAdapter.java (original)
+++ webservices/axiom/trunk/axiom-api/src/main/java/org/apache/axiom/attachments/MIMEMessageAdapter.java Fri Apr 29 19:25:53 2016
@@ -44,6 +44,15 @@ final class MIMEMessageAdapter extends A
private final int contentLength;
private final CountingInputStream filterIS;
+ /** <code>boolean</code> Indicating if any streams have been directly requested */
+ private boolean streamsRequested;
+
+ /** <code>boolean</code> Indicating if any data handlers have been directly requested */
+ private boolean partsRequested;
+
+ /** Container to hold streams for direct access */
+ private IncomingAttachmentStreams streams;
+
MIMEMessageAdapter(InputStream inStream, String contentTypeString,
WritableBlobFactory<?> attachmentBlobFactory, int contentLength) {
this.contentLength = contentLength;
@@ -62,6 +71,13 @@ final class MIMEMessageAdapter extends A
this.message = new MIMEMessage(inStream, contentTypeString, attachmentBlobFactory);
}
+ private void requestParts() {
+ if (streamsRequested) {
+ throw new IllegalStateException("The attachments stream can only be accessed once; either by using the IncomingAttachmentStreams class or by getting a collection of AttachmentPart objects. They cannot both be called within the life time of the same service request.");
+ }
+ partsRequested = true;
+ }
+
@Override
ContentType getContentType() {
return message.getContentType();
@@ -69,6 +85,7 @@ final class MIMEMessageAdapter extends A
@Override
DataHandler getDataHandler(String contentID) {
+ requestParts();
DataHandler dh = addedDataHandlers.get(contentID);
if (dh != null) {
return dh;
@@ -81,11 +98,13 @@ final class MIMEMessageAdapter extends A
@Override
void addDataHandler(String contentID, DataHandler dataHandler) {
+ requestParts();
addedDataHandlers.put(contentID, dataHandler);
}
@Override
void removeDataHandler(String blobContentID) {
+ requestParts();
if (addedDataHandlers.remove(blobContentID) == null) {
removedDataHandlers.add(blobContentID);
}
@@ -112,11 +131,25 @@ final class MIMEMessageAdapter extends A
@Override
IncomingAttachmentStreams getIncomingAttachmentStreams() {
- return message.getIncomingAttachmentStreams();
+ if (partsRequested) {
+ throw new IllegalStateException(
+ "The attachments stream can only be accessed once; either by using the IncomingAttachmentStreams class or by getting a " +
+ "collection of AttachmentPart objects. They cannot both be called within the life time of the same service request.");
+ }
+
+ streamsRequested = true;
+
+ if (streams == null) {
+ streams = new IncomingAttachmentStreams(message);
+ }
+
+ return streams;
}
+
@Override
Set<String> getContentIDs(boolean fetchAll) {
+ requestParts();
Set<String> result = new LinkedHashSet<String>(message.getContentIDs(fetchAll));
result.removeAll(removedDataHandlers);
result.addAll(addedDataHandlers.keySet());
@@ -125,6 +158,7 @@ final class MIMEMessageAdapter extends A
@Override
Map<String,DataHandler> getMap() {
+ requestParts();
Map<String,DataHandler> result = new LinkedHashMap<String,DataHandler>();
for (Map.Entry<String,Part> entry : message.getMap().entrySet()) {
String contentID = entry.getKey();
@@ -141,6 +175,7 @@ final class MIMEMessageAdapter extends A
if (contentLength > 0) {
return contentLength;
} else {
+ requestParts();
// Ensure all parts are read
message.fetchAllParts();
// Now get the count from the filter
Modified: webservices/axiom/trunk/axiom-api/src/main/java/org/apache/axiom/attachments/Part.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/axiom-api/src/main/java/org/apache/axiom/attachments/Part.java?rev=1741696&r1=1741695&r2=1741696&view=diff
==============================================================================
--- webservices/axiom/trunk/axiom-api/src/main/java/org/apache/axiom/attachments/Part.java (original)
+++ webservices/axiom/trunk/axiom-api/src/main/java/org/apache/axiom/attachments/Part.java Fri Apr 29 19:25:53 2016
@@ -20,10 +20,12 @@ package org.apache.axiom.attachments;
import java.io.IOException;
import java.io.InputStream;
+import java.util.List;
import javax.activation.DataHandler;
import org.apache.axiom.blob.Blob;
+import org.apache.axiom.mime.Header;
/**
* Interface representing a MIME part. A part can be the SOAP part (or more generally the root part
@@ -75,4 +77,6 @@ public interface Part {
public InputStream getInputStream(boolean preserve) throws IOException;
public void releaseContent() throws IOException;
+
+ List<Header> getHeaders();
}
Modified: webservices/axiom/trunk/axiom-api/src/main/java/org/apache/axiom/attachments/PartImpl.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/axiom-api/src/main/java/org/apache/axiom/attachments/PartImpl.java?rev=1741696&r1=1741695&r2=1741696&view=diff
==============================================================================
--- webservices/axiom/trunk/axiom-api/src/main/java/org/apache/axiom/attachments/PartImpl.java (original)
+++ webservices/axiom/trunk/axiom-api/src/main/java/org/apache/axiom/attachments/PartImpl.java Fri Apr 29 19:25:53 2016
@@ -68,6 +68,7 @@ final class PartImpl implements Part {
private static final Log log = LogFactory.getLog(PartImpl.class);
+ private final MIMEMessage message;
private final WritableBlobFactory<?> blobFactory;
private final String contentID;
@@ -90,7 +91,10 @@ final class PartImpl implements Part {
private PartInputStream partInputStream;
- PartImpl(WritableBlobFactory<?> blobFactory, String contentID, List<Header> headers, MimeTokenStream parser) {
+ private PartImpl nextPart;
+
+ PartImpl(MIMEMessage message, WritableBlobFactory<?> blobFactory, String contentID, List<Header> headers, MimeTokenStream parser) {
+ this.message = message;
this.blobFactory = blobFactory;
this.contentID = contentID;
this.headers = headers;
@@ -114,6 +118,10 @@ final class PartImpl implements Part {
return value;
}
+ public List<Header> getHeaders() {
+ return headers;
+ }
+
public String getContentID() {
return contentID;
}
@@ -263,4 +271,15 @@ final class PartImpl implements Part {
content.release();
}
}
+
+ PartImpl getNextPart() {
+ if (nextPart == null) {
+ message.getNextPart();
+ }
+ return nextPart;
+ }
+
+ void setNextPart(PartImpl nextPart) {
+ this.nextPart = nextPart;
+ }
}
Added: webservices/axiom/trunk/axiom-api/src/main/java/org/apache/axiom/attachments/PartIterator.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/axiom-api/src/main/java/org/apache/axiom/attachments/PartIterator.java?rev=1741696&view=auto
==============================================================================
--- webservices/axiom/trunk/axiom-api/src/main/java/org/apache/axiom/attachments/PartIterator.java (added)
+++ webservices/axiom/trunk/axiom-api/src/main/java/org/apache/axiom/attachments/PartIterator.java Fri Apr 29 19:25:53 2016
@@ -0,0 +1,60 @@
+/*
+ * 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.attachments;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+final class PartIterator implements Iterator<Part> {
+ private final MIMEMessage message;
+ private PartImpl part;
+ private boolean hasNextCalled;
+
+ PartIterator(MIMEMessage message) {
+ this.message = message;
+ }
+
+ @Override
+ public boolean hasNext() {
+ if (!hasNextCalled) {
+ if (part == null) {
+ part = message.getFirstPart();
+ } else {
+ part = part.getNextPart();
+ }
+ hasNextCalled = true;
+ }
+ return part != null;
+ }
+
+ @Override
+ public Part next() {
+ if (hasNext()) {
+ hasNextCalled = false;
+ return part;
+ } else {
+ throw new NoSuchElementException();
+ }
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+}
Propchange: webservices/axiom/trunk/axiom-api/src/main/java/org/apache/axiom/attachments/PartIterator.java
------------------------------------------------------------------------------
svn:eol-style = native