From: <ls...@us...> - 2011-01-05 09:25:30
|
Revision: 5784 http://jnode.svn.sourceforge.net/jnode/?rev=5784&view=rev Author: lsantha Date: 2011-01-05 09:25:21 +0000 (Wed, 05 Jan 2011) Log Message: ----------- Integrating OpenJDK 6 b20. Added Paths: ----------- classlib6/core/src/openjdk/com/com/sun/java/swing/Painter.java classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/ classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/Chunk.java classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/ChunkInputStream.java classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/Data.java classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/DataFile.java classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/DataHead.java classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/FileData.java classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/FinalArrayList.java classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/Header.java classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/InternetHeaders.java classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/MIMEConfig.java classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/MIMEEvent.java classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/MIMEMessage.java classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/MIMEParser.java classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/MIMEParsingException.java classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/MIMEPart.java classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/MemoryData.java classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/WeakDataFile.java classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/staxex/StreamingDataHandler.java classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/ws/org/ classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/ws/org/objectweb/ classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/ws/org/objectweb/asm/ classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/ws/org/objectweb/asm/AnnotationVisitor.java classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/ws/org/objectweb/asm/AnnotationWriter.java classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/ws/org/objectweb/asm/Attribute.java classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/ws/org/objectweb/asm/ByteVector.java classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/ws/org/objectweb/asm/ClassReader.java classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/ws/org/objectweb/asm/ClassVisitor.java classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/ws/org/objectweb/asm/ClassWriter.java classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/ws/org/objectweb/asm/Edge.java classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/ws/org/objectweb/asm/FieldVisitor.java classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/ws/org/objectweb/asm/FieldWriter.java classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/ws/org/objectweb/asm/Frame.java classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/ws/org/objectweb/asm/Handler.java classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/ws/org/objectweb/asm/Item.java classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/ws/org/objectweb/asm/Label.java classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/ws/org/objectweb/asm/MethodVisitor.java classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/ws/org/objectweb/asm/MethodWriter.java classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/ws/org/objectweb/asm/Opcodes.java classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/ws/org/objectweb/asm/Type.java classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/ws/protocol/soap/MessageCreationException.java Added: classlib6/core/src/openjdk/com/com/sun/java/swing/Painter.java =================================================================== --- classlib6/core/src/openjdk/com/com/sun/java/swing/Painter.java (rev 0) +++ classlib6/core/src/openjdk/com/com/sun/java/swing/Painter.java 2011-01-05 09:25:21 UTC (rev 5784) @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.sun.java.swing; + +import java.awt.Graphics2D; + +/** + * <p>A painting delegate. The Painter interface defines exactly one method, + * <code>paint</code>. It is used in situations where the developer can change + * the painting routine of a component without having to resort to subclassing + * the component. It is also generically useful when doing any form of painting + * delegation.</p> + * + * <p><code>Painter</code>s are simply encapsulations of Java2D code and make + * it fairly trivial to reuse existing <code>Painter</code>s or to combine + * them together. Implementations of this interface are also trivial to write, + * such that if you can't find a <code>Painter</code> that does what you need, + * you can write one with minimal effort. Writing a <code>Painter</code> requires + * knowledge of Java2D.</p> + * + * <p>A <code>Painter</code> may be created with a type parameter. This type will be + * expected in the <code>paint</code> method. For example, you may wish to write a + * <code>Painter</code> that only works with subclasses of {@link java.awt.Component}. + * In that case, when the <code>Painter</code> is declared, you may declare that + * it requires a <code>Component</code>, allowing the paint method to be type safe. Ex: + * <pre><code> + * Painter<Component> p = new Painter<Component>() { + * public void paint(Graphics2D g, Component c, int width, int height) { + * g.setColor(c.getBackground()); + * //and so forth + * } + * } + * </code></pre></p> + * + * <p>This interface makes no guarantees of threadsafety.</p> + * + * @author rbair + */ +public interface Painter<T> { + /** + * <p>Renders to the given {@link java.awt.Graphics2D} object. Implementations + * of this method <em>may</em> modify state on the <code>Graphics2D</code>, and are not + * required to restore that state upon completion. In most cases, it is recommended + * that the caller pass in a scratch graphics object. The <code>Graphics2D</code> + * must never be null.</p> + * + * <p>State on the graphics object may be honored by the <code>paint</code> method, + * but may not be. For instance, setting the antialiasing rendering hint on the + * graphics may or may not be respected by the <code>Painter</code> implementation.</p> + * + * <p>The supplied object parameter acts as an optional configuration argument. + * For example, it could be of type <code>Component</code>. A <code>Painter</code> + * that expected it could then read state from that <code>Component</code> and + * use the state for painting. For example, an implementation may read the + * backgroundColor and use that.</p> + * + * <p>Generally, to enhance reusability, most standard <code>Painter</code>s ignore + * this parameter. They can thus be reused in any context. The <code>object</code> + * may be null. Implementations must not throw a NullPointerException if the object + * parameter is null.</p> + * + * <p>Finally, the <code>width</code> and <code>height</code> arguments specify the + * width and height that the <code>Painter</code> should paint into. More + * specifically, the specified width and height instruct the painter that it should + * paint fully within this width and height. Any specified clip on the + * <code>g</code> param will further constrain the region.</p> + * + * <p>For example, suppose I have a <code>Painter</code> implementation that draws + * a gradient. The gradient goes from white to black. It "stretches" to fill the + * painted region. Thus, if I use this <code>Painter</code> to paint a 500 x 500 + * region, the far left would be black, the far right would be white, and a smooth + * gradient would be painted between. I could then, without modification, reuse the + * <code>Painter</code> to paint a region that is 20x20 in size. This region would + * also be black on the left, white on the right, and a smooth gradient painted + * between.</p> + * + * @param g The Graphics2D to render to. This must not be null. + * @param object an optional configuration parameter. This may be null. + * @param width width of the area to paint. + * @param height height of the area to paint. + */ + public void paint(Graphics2D g, T object, int width, int height); +} Added: classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/Chunk.java =================================================================== --- classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/Chunk.java (rev 0) +++ classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/Chunk.java 2011-01-05 09:25:21 UTC (rev 5784) @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.sun.xml.internal.org.jvnet.mimepull; + +import java.nio.ByteBuffer; + +/** + * @author Kohsuke Kawaguchi + */ +final class Chunk { + volatile Chunk next; + volatile Data data; + + public Chunk(Data data) { + this.data = data; + } + + /** + * Creates a new chunk and adds to linked list. + * + * @param dataHead of the linked list + * @param buf MIME part partial data + * @return created chunk + */ + public Chunk createNext(DataHead dataHead, ByteBuffer buf) { + return next = new Chunk(data.createNext(dataHead, buf)); + } +} Added: classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/ChunkInputStream.java =================================================================== --- classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/ChunkInputStream.java (rev 0) +++ classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/ChunkInputStream.java 2011-01-05 09:25:21 UTC (rev 5784) @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.sun.xml.internal.org.jvnet.mimepull; + +import java.io.InputStream; +import java.io.IOException; + +/** + * Constructs a InputStream from a linked list of {@link Chunk}s. + * + * @author Kohsuke Kawaguchi + * @author Jitendra Kotamraju + */ +final class ChunkInputStream extends InputStream { + Chunk current; + int offset; + int len; + final MIMEMessage msg; + final MIMEPart part; + byte[] buf; + + public ChunkInputStream(MIMEMessage msg, MIMEPart part, Chunk startPos) { + this.current = startPos; + len = current.data.size(); + buf = current.data.read(); + this.msg = msg; + this.part = part; + } + + @Override + public int read(byte b[], int off, int sz) throws IOException { + if(!fetch()) return -1; + + sz = Math.min(sz, len-offset); + System.arraycopy(buf,offset,b,off,sz); + return sz; + } + + public int read() throws IOException { + if(!fetch()) return -1; + return (buf[offset++] & 0xff); + } + + /** + * Gets to the next chunk if we are done with the current one. + * @return + */ + private boolean fetch() { + if (current == null) { + throw new IllegalStateException("Stream already closed"); + } + while(offset==len) { + while(!part.parsed && current.next == null) { + msg.makeProgress(); + } + current = current.next; + + if (current == null) { + return false; + } + this.offset = 0; + this.buf = current.data.read(); + this.len = current.data.size(); + } + return true; + } + + public void close() throws IOException { + super.close(); + current = null; + } +} Added: classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/Data.java =================================================================== --- classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/Data.java (rev 0) +++ classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/Data.java 2011-01-05 09:25:21 UTC (rev 5784) @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.sun.xml.internal.org.jvnet.mimepull; + +import java.nio.ByteBuffer; + +/** + * @author Kohsuke Kawaguchi + * @author Jitendra Kotamraju + */ +interface Data { + + /** + * size of the chunk given by the parser + * + * @return size of the chunk + */ + int size(); + + /** + * TODO: should the return type be ByteBuffer ?? + * Return part's partial data. The data is read only. + * + * @return a byte array which contains {#size()} bytes. The returned + * array may be larger than {#size()} bytes and contains data + * from offset 0. + */ + byte[] read(); + + /** + * Write this partial data to a file + * + * @param file to which the data needs to be written + * @return file pointer before the write operation(at which the data is + * written from) + */ + long writeTo(DataFile file); + + /** + * Factory method to create a Data. The implementation could + * be file based one or memory based one. + * + * @param dataHead start of the linked list of data objects + * @param buf contains partial content for a part + * @return Data + */ + Data createNext(DataHead dataHead, ByteBuffer buf); +} Added: classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/DataFile.java =================================================================== --- classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/DataFile.java (rev 0) +++ classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/DataFile.java 2011-01-05 09:25:21 UTC (rev 5784) @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.sun.xml.internal.org.jvnet.mimepull; + +import java.io.*; + +/** + * Use {@link RandomAccessFile} for concurrent access of read + * and write partial part's content. + * + * @author Kohsuke Kawaguchi + * @author Jitendra Kotamraju + */ +final class DataFile { + private WeakDataFile weak; + private long writePointer; + + DataFile(File file) { + writePointer=0; + weak = new WeakDataFile(this, file); + } + + /** + * + */ + void close() { + weak.close(); + } + + /** + * Read data from the given file pointer position. + * + * @param pointer read position + * @param buf that needs to be filled + * @param offset the start offset of the data. + * @param length of data that needs to be read + */ + synchronized void read(long pointer, byte[] buf, int offset, int length ) { + weak.read(pointer, buf, offset, length); + } + + void renameTo(File f) { + weak.renameTo(f); + } + + /** + * Write data to the file + * + * @param data that needs to written to a file + * @param offset start offset in the data + * @param length no bytes to write + * @return file pointer before the write operation(or at which the + * data is written) + */ + synchronized long writeTo(byte[] data, int offset, int length) { + long temp = writePointer; + writePointer = weak.writeTo(writePointer, data, offset, length); + return temp; + } + +} Added: classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/DataHead.java =================================================================== --- classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/DataHead.java (rev 0) +++ classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/DataHead.java 2011-01-05 09:25:21 UTC (rev 5784) @@ -0,0 +1,258 @@ +/* + * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.sun.xml.internal.org.jvnet.mimepull; + +import java.io.*; +import java.nio.ByteBuffer; + +/** + * Represents an attachment part in a MIME message. MIME message parsing is done + * lazily using a pull parser, so the part may not have all the data. {@link #read} + * and {@link #readOnce} may trigger the actual parsing the message. In fact, + * parsing of an attachment part may be triggered by calling {@link #read} methods + * on some other attachemnt parts. All this happens behind the scenes so the + * application developer need not worry about these details. + * + * @author Jitendra Kotamraju + */ +final class DataHead { + + /** + * Linked list to keep the part's content + */ + volatile Chunk head, tail; + + /** + * If the part is stored in a file, non-null. + */ + DataFile dataFile; + + private final MIMEPart part; + + boolean readOnce; + volatile long inMemory; + + /** + * Used only for debugging. This records where readOnce() is called. + */ + private Throwable consumedAt; + + DataHead(MIMEPart part) { + this.part = part; + } + + void addBody(ByteBuffer buf) { + synchronized(this) { + inMemory += buf.limit(); + } + if (tail != null) { + tail = tail.createNext(this, buf); + } else { + head = tail = new Chunk(new MemoryData(buf, part.msg.config)); + } + } + + void doneParsing() { + } + + void moveTo(File f) { + if (dataFile != null) { + dataFile.renameTo(f); + } else { + try { + OutputStream os = new FileOutputStream(f); + InputStream in = readOnce(); + byte[] buf = new byte[8192]; + int len; + while((len=in.read(buf)) != -1) { + os.write(buf, 0, len); + } + os.close(); + } catch(IOException ioe) { + throw new MIMEParsingException(ioe); + } + } + } + + void close() { + if (dataFile != null) { + head = tail = null; + dataFile.close(); + } + } + + + /** + * Can get the attachment part's content multiple times. That means + * the full content needs to be there in memory or on the file system. + * Calling this method would trigger parsing for the part's data. So + * do not call this unless it is required(otherwise, just wrap MIMEPart + * into a object that returns InputStream for e.g DataHandler) + * + * @return data for the part's content + */ + public InputStream read() { + if (readOnce) { + throw new IllegalStateException("readOnce() is called before, read() cannot be called later."); + } + + // Trigger parsing for the part + while(tail == null) { + if (!part.msg.makeProgress()) { + throw new IllegalStateException("No such MIME Part: "+part); + } + } + + if (head == null) { + throw new IllegalStateException("Already read. Probably readOnce() is called before."); + } + return new ReadMultiStream(); + } + + /** + * Used for an assertion. Returns true when readOnce() is not already called. + * or otherwise throw an exception. + * + * <p> + * Calling this method also marks the stream as 'consumed' + * + * @return true if readOnce() is not called before + */ + private boolean unconsumed() { + if (consumedAt != null) { + AssertionError error = new AssertionError("readOnce() is already called before. See the nested exception from where it's called."); + error.initCause(consumedAt); + throw error; + } + consumedAt = new Exception().fillInStackTrace(); + return true; + } + + /** + * Can get the attachment part's content only once. The content + * will be lost after the method. Content data is not be stored + * on the file system or is not kept in the memory for the + * following case: + * - Attachement parts contents are accessed sequentially + * + * In general, take advantage of this when the data is used only + * once. + * + * @return data for the part's content + */ + public InputStream readOnce() { + assert unconsumed(); + if (readOnce) { + throw new IllegalStateException("readOnce() is called before. It can only be called once."); + } + readOnce = true; + // Trigger parsing for the part + while(tail == null) { + if (!part.msg.makeProgress() && tail == null) { + throw new IllegalStateException("No such Part: "+part); + } + } + InputStream in = new ReadOnceStream(); + head = null; + return in; + } + + class ReadMultiStream extends InputStream { + Chunk current; + int offset; + int len; + byte[] buf; + + public ReadMultiStream() { + this.current = head; + len = current.data.size(); + buf = current.data.read(); + } + + @Override + public int read(byte b[], int off, int sz) throws IOException { + if(!fetch()) return -1; + + sz = Math.min(sz, len-offset); + System.arraycopy(buf,offset,b,off,sz); + offset += sz; + return sz; + } + + public int read() throws IOException { + if (!fetch()) { + return -1; + } + return (buf[offset++] & 0xff); + } + + void adjustInMemoryUsage() { + // Nothing to do in this case. + } + + /** + * Gets to the next chunk if we are done with the current one. + * @return + */ + private boolean fetch() { + if (current == null) { + throw new IllegalStateException("Stream already closed"); + } + while(offset==len) { + while(!part.parsed && current.next == null) { + part.msg.makeProgress(); + } + current = current.next; + + if (current == null) { + return false; + } + adjustInMemoryUsage(); + this.offset = 0; + this.buf = current.data.read(); + this.len = current.data.size(); + } + return true; + } + + public void close() throws IOException { + super.close(); + current = null; + } + } + + final class ReadOnceStream extends ReadMultiStream { + + @Override + void adjustInMemoryUsage() { + synchronized(DataHead.this) { + inMemory -= current.data.size(); // adjust current memory usage + } + } + + } + + +} Added: classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/FileData.java =================================================================== --- classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/FileData.java (rev 0) +++ classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/FileData.java 2011-01-05 09:25:21 UTC (rev 5784) @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.sun.xml.internal.org.jvnet.mimepull; + +import java.nio.ByteBuffer; + +/** + * Keeps the Part's partial content data in a file. + * + * @author Kohsuke Kawaguchi + * @author Jitendra Kotamraju + */ +final class FileData implements Data { + private final DataFile file; + private final long pointer; // read position + private final int length; + + FileData(DataFile file, ByteBuffer buf) { + this(file, file.writeTo(buf.array(), 0, buf.limit()), buf.limit()); + } + + FileData(DataFile file, long pointer, int length) { + this.file = file; + this.pointer = pointer; + this.length = length; + } + + public byte[] read() { + byte[] buf = new byte[length]; + file.read(pointer, buf, 0, length); + return buf; + } + + /* + * This shouldn't be called + */ + public long writeTo(DataFile file) { + throw new IllegalStateException(); + } + + public int size() { + return length; + } + + /* + * Always create FileData + */ + public Data createNext(DataHead dataHead, ByteBuffer buf) { + return new FileData(file, buf); + } +} Added: classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/FinalArrayList.java =================================================================== --- classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/FinalArrayList.java (rev 0) +++ classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/FinalArrayList.java 2011-01-05 09:25:21 UTC (rev 5784) @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.sun.xml.internal.org.jvnet.mimepull; + +import java.util.ArrayList; +import java.util.Collection; + +/** + * {@link java.util.ArrayList} with the final keyword. + * + * <p> + * This gives HotSpot a better hint that all methods can be inlined. + * + * @author Kohsuke Kawaguchi + */ +final class FinalArrayList<T> extends ArrayList<T> { + public FinalArrayList(int initialCapacity) { + super(initialCapacity); + } + + public FinalArrayList() { + } + + public FinalArrayList(Collection<? extends T> ts) { + super(ts); + } +} Added: classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/Header.java =================================================================== --- classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/Header.java (rev 0) +++ classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/Header.java 2011-01-05 09:25:21 UTC (rev 5784) @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.sun.xml.internal.org.jvnet.mimepull; + +/** + * The Header class stores a name/value pair to represent headers. + * + * @author John Mani + */ + +public interface Header { + + /** + * Returns the name of this header. + * + * @return name of the header + */ + String getName(); + + /** + * Returns the value of this header. + * + * @return value of the header + */ + String getValue(); +} Added: classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/InternetHeaders.java =================================================================== --- classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/InternetHeaders.java (rev 0) +++ classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/InternetHeaders.java 2011-01-05 09:25:21 UTC (rev 5784) @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.sun.xml.internal.org.jvnet.mimepull; + +import java.io.IOException; +import java.util.NoSuchElementException; +import java.util.List; + +/** + * InternetHeaders is a utility class that manages RFC822 style + * headers. Given an RFC822 format message stream, it reads lines + * until the blank line that indicates end of header. The input stream + * is positioned at the start of the body. The lines are stored + * within the object and can be extracted as either Strings or + * {@link Header} objects. <p> + * <p/> + * This class is mostly intended for service providers. MimeMessage + * and MimeBody use this class for holding their headers. <p> + * <p/> + * <hr> <strong>A note on RFC822 and MIME headers</strong><p> + * <p/> + * RFC822 and MIME header fields <strong>must</strong> contain only + * US-ASCII characters. If a header contains non US-ASCII characters, + * it must be encoded as per the rules in RFC 2047. The MimeUtility + * class provided in this package can be used to to achieve this. + * Callers of the <code>setHeader</code>, <code>addHeader</code>, and + * <code>addHeaderLine</code> methods are responsible for enforcing + * the MIME requirements for the specified headers. In addition, these + * header fields must be folded (wrapped) before being sent if they + * exceed the line length limitation for the transport (1000 bytes for + * SMTP). Received headers may have been folded. The application is + * responsible for folding and unfolding headers as appropriate. <p> + * + * @author John Mani + * @author Bill Shannon + */ +final class InternetHeaders { + + private final FinalArrayList<hdr> headers = new FinalArrayList<hdr>(); + + /** + * Read and parse the given RFC822 message stream till the + * blank line separating the header from the body. Store the + * header lines inside this InternetHeaders object. <p> + * <p/> + * Note that the header lines are added into this InternetHeaders + * object, so any existing headers in this object will not be + * affected. + * + * @param lis RFC822 input stream + */ + InternetHeaders(MIMEParser.LineInputStream lis) { + // Read header lines until a blank line. It is valid + // to have BodyParts with no header lines. + String line; + String prevline = null; // the previous header line, as a string + // a buffer to accumulate the header in, when we know it's needed + StringBuffer lineBuffer = new StringBuffer(); + + try { + //while ((line = lis.readLine()) != null) { + do { + line = lis.readLine(); + if (line != null && + (line.startsWith(" ") || line.startsWith("\t"))) { + // continuation of header + if (prevline != null) { + lineBuffer.append(prevline); + prevline = null; + } + lineBuffer.append("\r\n"); + lineBuffer.append(line); + } else { + // new header + if (prevline != null) + addHeaderLine(prevline); + else if (lineBuffer.length() > 0) { + // store previous header first + addHeaderLine(lineBuffer.toString()); + lineBuffer.setLength(0); + } + prevline = line; + } + } while (line != null && line.length() > 0); + } catch (IOException ioex) { + throw new MIMEParsingException("Error in input stream", ioex); + } + } + + /** + * Return all the values for the specified header. The + * values are String objects. Returns <code>null</code> + * if no headers with the specified name exist. + * + * @param name header name + * @return array of header values, or null if none + */ + List<String> getHeader(String name) { + // XXX - should we just step through in index order? + FinalArrayList<String> v = new FinalArrayList<String>(); // accumulate return values + + int len = headers.size(); + for( int i=0; i<len; i++ ) { + hdr h = (hdr) headers.get(i); + if (name.equalsIgnoreCase(h.name)) { + v.add(h.getValue()); + } + } + return (v.size() == 0) ? null : v; + } + + /** + * Return all the headers as an Enumeration of + * {@link Header} objects. + * + * @return Header objects + */ + FinalArrayList<? extends Header> getAllHeaders() { + return headers; // conceptually it should be read-only, but for performance reason I'm not wrapping it here + } + + /** + * Add an RFC822 header line to the header store. + * If the line starts with a space or tab (a continuation line), + * add it to the last header line in the list. <p> + * <p/> + * Note that RFC822 headers can only contain US-ASCII characters + * + * @param line raw RFC822 header line + */ + void addHeaderLine(String line) { + try { + char c = line.charAt(0); + if (c == ' ' || c == '\t') { + hdr h = (hdr) headers.get(headers.size() - 1); + h.line += "\r\n" + line; + } else + headers.add(new hdr(line)); + } catch (StringIndexOutOfBoundsException e) { + // line is empty, ignore it + return; + } catch (NoSuchElementException e) { + // XXX - vector is empty? + } + } + +} + +/* + * A private utility class to represent an individual header. + */ + +class hdr implements Header { + + String name; // the canonicalized (trimmed) name of this header + // XXX - should name be stored in lower case? + String line; // the entire RFC822 header "line" + + /* + * Constructor that takes a line and splits out + * the header name. + */ + hdr(String l) { + int i = l.indexOf(':'); + if (i < 0) { + // should never happen + name = l.trim(); + } else { + name = l.substring(0, i).trim(); + } + line = l; + } + + /* + * Constructor that takes a header name and value. + */ + hdr(String n, String v) { + name = n; + line = n + ": " + v; + } + + /* + * Return the "name" part of the header line. + */ + public String getName() { + return name; + } + + /* + * Return the "value" part of the header line. + */ + public String getValue() { + int i = line.indexOf(':'); + if (i < 0) + return line; + + int j; + if (name.equalsIgnoreCase("Content-Description")) { + // Content-Description should retain the folded whitespace after header unfolding - + // rf. RFC2822 section 2.2.3, rf. RFC2822 section 3.2.3 + for (j = i + 1; j < line.length(); j++) { + char c = line.charAt(j); + if (!(/*c == ' ' ||*/c == '\t' || c == '\r' || c == '\n')) + break; + } + } else { + // skip whitespace after ':' + for (j = i + 1; j < line.length(); j++) { + char c = line.charAt(j); + if (!(c == ' ' || c == '\t' || c == '\r' || c == '\n')) + break; + } + } + return line.substring(j); + } +} Added: classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/MIMEConfig.java =================================================================== --- classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/MIMEConfig.java (rev 0) +++ classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/MIMEConfig.java 2011-01-05 09:25:21 UTC (rev 5784) @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.sun.xml.internal.org.jvnet.mimepull; + +import java.io.File; +import java.io.IOException; + +/** + * Configuration for MIME message parsing and storing. + * + * @author Jitendra Kotamraju + */ +public class MIMEConfig { + + private static final int DEFAULT_CHUNK_SIZE = 8192; + private static final long DEFAULT_MEMORY_THRESHOLD = 1048576L; + private static final String DEFAULT_FILE_PREFIX = "MIME"; + + // Parses the entire message eagerly + boolean parseEagerly; + + // Approximate Chunk size + int chunkSize; + + // Maximum in-memory data per attachment + long memoryThreshold; + + // Do not store to disk + boolean onlyMemory; + + // temp Dir to store large files + File tempDir; + String prefix; + String suffix; + + + private MIMEConfig(boolean parseEagerly, int chunkSize, + long inMemoryThreshold, String dir, String prefix, String suffix) { + this.parseEagerly = parseEagerly; + this.chunkSize = chunkSize; + this.memoryThreshold = inMemoryThreshold; + this.prefix = prefix; + this.suffix = suffix; + setDir(dir); + } + + public MIMEConfig() { + this(false, DEFAULT_CHUNK_SIZE, DEFAULT_MEMORY_THRESHOLD, null, + DEFAULT_FILE_PREFIX, null); + } + + boolean isParseEagerly() { + return parseEagerly; + } + + public void setParseEagerly(boolean parseEagerly) { + this.parseEagerly = parseEagerly; + } + + int getChunkSize() { + return chunkSize; + } + + void setChunkSize(int chunkSize) { + this.chunkSize = chunkSize; + } + + long getMemoryThreshold() { + return memoryThreshold; + } + + /** + * If the attachment is greater than the threshold, it is + * written to the disk. + * + * @param memoryThreshold no of bytes per attachment + * if -1, then the whole attachment is kept in memory + */ + public void setMemoryThreshold(long memoryThreshold) { + this.memoryThreshold = memoryThreshold; + } + + boolean isOnlyMemory() { + return memoryThreshold == -1L; + } + + File getTempDir() { + return tempDir; + } + + String getTempFilePrefix() { + return prefix; + } + + String getTempFileSuffix() { + return suffix; + } + + /** + * @param dir + */ + public void setDir(String dir) { + if (tempDir == null && dir != null && !dir.equals("")) { + tempDir = new File(dir); + } + } + + /** + * Validates if it can create temporary files. Otherwise, it stores + * attachment contents in memory. + */ + public void validate() { + if (!isOnlyMemory()) { + try { + File tempFile = (tempDir == null) + ? File.createTempFile(prefix, suffix) + : File.createTempFile(prefix, suffix, tempDir); + tempFile.delete(); + } catch(Exception ioe) { + memoryThreshold = -1L; // whole attachment will be in-memory + } + } + } + +} Added: classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/MIMEEvent.java =================================================================== --- classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/MIMEEvent.java (rev 0) +++ classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/MIMEEvent.java 2011-01-05 09:25:21 UTC (rev 5784) @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.sun.xml.internal.org.jvnet.mimepull; + +import java.nio.ByteBuffer; + +/** + * @author Jitendra Kotamraju + */ +abstract class MIMEEvent { + + enum EVENT_TYPE {START_MESSAGE, START_PART, HEADERS, CONTENT, END_PART, END_MESSAGE} + + /** + * Returns a event for parser's current cursor location in the MIME message. + * + * <p> + * {@link EVENT_TYPE#START_MESSAGE} and {@link EVENT_TYPE#START_MESSAGE} events + * are generated only once. + * + * <p> + * {@link EVENT_TYPE#START_PART}, {@link EVENT_TYPE#END_PART}, {@link EVENT_TYPE#HEADERS} + * events are generated only once for each attachment part. + * + * <p> + * {@link EVENT_TYPE#CONTENT} event may be generated more than once for an attachment + * part. + * + * @return event type + */ + abstract EVENT_TYPE getEventType(); + + static final StartMessage START_MESSAGE = new StartMessage(); + static final StartPart START_PART = new StartPart(); + static final EndPart END_PART = new EndPart(); + static final EndMessage END_MESSAGE = new EndMessage(); + + static final class StartMessage extends MIMEEvent { + EVENT_TYPE getEventType() { + return EVENT_TYPE.START_MESSAGE; + } + } + + static final class StartPart extends MIMEEvent { + EVENT_TYPE getEventType() { + return EVENT_TYPE.START_PART; + } + } + + static final class EndPart extends MIMEEvent { + EVENT_TYPE getEventType () { + return EVENT_TYPE.END_PART; + } + } + + static final class Headers extends MIMEEvent { + InternetHeaders ih; + + Headers(InternetHeaders ih) { + this.ih = ih; + } + + EVENT_TYPE getEventType() { + return EVENT_TYPE.HEADERS; + } + + InternetHeaders getHeaders() { + return ih; + } + } + + static final class Content extends MIMEEvent { + private final ByteBuffer buf; + + Content(ByteBuffer buf) { + this.buf = buf; + } + + EVENT_TYPE getEventType() { + return EVENT_TYPE.CONTENT; + } + + ByteBuffer getData() { + return buf; + } + } + + static final class EndMessage extends MIMEEvent { + EVENT_TYPE getEventType() { + return EVENT_TYPE.END_MESSAGE; + } + } + +} Added: classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/MIMEMessage.java =================================================================== --- classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/MIMEMessage.java (rev 0) +++ classlib6/core/src/openjdk/jaxws/com/sun/xml/internal/org/jvnet/mimepull/MIMEMessage.java 2011-01-05 09:25:21 UTC (rev 5784) @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.sun.xml.internal.org.jvnet.mimepull; + +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.nio.ByteBuffer; +import java.util.*; +import java.util.logging.Logger; + +/** + * Represents MIME message. MIME message parsing is done lazily using a + * pull parser. + * + * @author Jitendra Kotamraju + */ +public class MIMEMessage { + private static final Logger LOGGER = Logger.getLogger(MIMEMessage.class.getName()); + + MIMEConfig config; + + private final InputStream in; + private final List<MIMEPart> partsList; + private final Map<String, MIMEPart> partsMap; + private final Iterator<MIMEEvent> it; + private boolean parsed; // true when entire message is parsed + private MIMEPart currentPart; + private int currentIndex; + + /** + * @see MIMEMessage(InputStream, String, MIMEConfig) + */ + public MIMEMessage(InputStream in, String boundary) { + this(in, boundary, new MIMEConfig()); + } + + /** + * Creates a MIME message from the content's stream. The content stream + * is closed when EOF is reached. + * + * @param in MIME message stream + * @param boundary the separator for parts(pass it without --) + * @param config various configuration parameters + */ + public MIMEMessage(InputStream in, String boundary, MIMEConfig config) { + this.in = in; + this.config = config; + MIMEParser parser = new MIMEParser(in, boundary, config); + it = parser.iterator(); + + partsList = new ArrayList<MIMEPart>(); + partsMap = new HashMap<String, MIMEPart>(); + if (config.isParseEagerly()) { + parseAll(); + } + } + + /** + * Gets all the attachments by parsing the entire MIME message. Avoid + * this if possible since it is an expensive operation. + * + * @return list of attachments. + */ + public List<MIMEPart> getAttachments() { + if (!parsed) { + parseAll(); + } + return partsList; + } + + /** + * Creates nth attachment lazily. It doesn't validate + * if the message has so many attachments. To + * do the validation, the message needs to be parsed. + * The parsing of the message is done lazily and is done + * while reading the bytes of the part. + * + * @param index sequential order of the part. starts with zero. + * @return attachemnt part + */ + public MIMEPart getPart(int index) { + LOGGER.fine("index="+index); + MIMEPart part = (index < partsList.size()) ? partsList.get(index) : null; + if (parsed && part == null) { + throw new MIMEParsingException("There is no "+index+" attachment part "); + } + if (part == null) { + // Parsing will done lazily and will be driven by reading the part + part = new MIMEPart(this); + partsList.add(index, part); + } + LOGGER.fine("Got attachment at index="+i... [truncated message content] |