You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@velocity.apache.org by jo...@locus.apache.org on 2000/11/04 00:26:53 UTC
cvs commit: jakarta-velocity/src/java/org/apache/velocity/test/misc Test.java
jon 00/11/03 15:26:53
Modified: src/java/org/apache/velocity/runtime/defaults
velocity.properties
src/java/org/apache/velocity/servlet VelocityServlet.java
src/java/org/apache/velocity/test TemplateTestCase.java
src/java/org/apache/velocity/test/misc Test.java
Added: src/java/org/apache/velocity/io ArrayByteData.java
ByteBuffer.java ByteBufferOutputStream.java
ByteData.java CharToByteBuffer.java
CharToByteBufferWriter.java DefaultByteBuffer.java
DefaultCharToByteBuffer.java FileByteBuffer.java
FileByteData.java IdentityMap.java
InternedCharToByteBuffer.java
SpilloverByteBuffer.java TemporaryFile.java
Removed: src/java/org/apache/velocity/io FastWriter.java
Log:
removed FastWriter and replaced it with TeaServlet's excellent IO code
Revision Changes Path
1.1 jakarta-velocity/src/java/org/apache/velocity/io/ArrayByteData.java
Index: ArrayByteData.java
===================================================================
package org.apache.velocity.io;
/* ====================================================================
* TeaServlet - Copyright (c) 1999-2000 Walt Disney Internet Group
* ====================================================================
* The Tea Software License, Version 1.1
*
* Copyright (c) 2000 Walt Disney Internet Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Walt Disney Internet Group (http://opensource.go.com/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Tea", "TeaServlet", "Kettle", "Trove" and "BeanDoc" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact opensource@dig.com.
*
* 5. Products derived from this software may not be called "Tea",
* "TeaServlet", "Kettle" or "Trove", nor may "Tea", "TeaServlet",
* "Kettle", "Trove" or "BeanDoc" appear in their name, without prior
* written permission of the Walt Disney Internet Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE WALT DISNEY INTERNET GROUP OR ITS
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* For more information about Tea, please see http://opensource.go.com/.
*/
import java.io.OutputStream;
import java.io.IOException;
/******************************************************************************
* A ByteData implementation that wraps an array of bytes.
*
* @author Brian S O'Neill
* @version
* <!--$$Revision: 1.1 $-->, <!--$$JustDate:--> 9/07/00 <!-- $-->
*/
public class ArrayByteData implements ByteData {
private byte[] mData;
private int mOffset;
private int mLength;
public ArrayByteData(byte[] data) {
this(data, 0, data.length);
}
public ArrayByteData(byte[] data, int offset, int length) {
mData = data;
mOffset = offset;
mLength = length;
}
public long getByteCount() {
return mLength;
}
public void writeTo(OutputStream out) throws IOException {
out.write(mData, mOffset, mLength);
}
public void reset() {
// No transient data to reset.
}
}
1.1 jakarta-velocity/src/java/org/apache/velocity/io/ByteBuffer.java
Index: ByteBuffer.java
===================================================================
package org.apache.velocity.io;
/* ====================================================================
* TeaServlet - Copyright (c) 1999-2000 Walt Disney Internet Group
* ====================================================================
* The Tea Software License, Version 1.1
*
* Copyright (c) 2000 Walt Disney Internet Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Walt Disney Internet Group (http://opensource.go.com/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Tea", "TeaServlet", "Kettle", "Trove" and "BeanDoc" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact opensource@dig.com.
*
* 5. Products derived from this software may not be called "Tea",
* "TeaServlet", "Kettle" or "Trove", nor may "Tea", "TeaServlet",
* "Kettle", "Trove" or "BeanDoc" appear in their name, without prior
* written permission of the Walt Disney Internet Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE WALT DISNEY INTERNET GROUP OR ITS
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* For more information about Tea, please see http://opensource.go.com/.
*/
import java.io.IOException;
/******************************************************************************
* ByteBuffer extends ByteData such that bytes can be added to it.
*
* @author Brian S O'Neill
* @version
* <!--$$Revision: 1.1 $-->, <!--$$JustDate:--> 9/07/00 <!-- $-->
*/
public interface ByteBuffer extends ByteData {
/**
* Returns the base byte count, which excludes surrogates.
*/
public long getBaseByteCount() throws IOException;
/**
* Add one byte to the end of this buffer.
*/
public void append(byte b) throws IOException;
/**
* Copy the given bytes to the end of this buffer.
*/
public void append(byte[] bytes) throws IOException;
/**
* Copy the given bytes to the end of this buffer, starting at the offset,
* using the length provided.
*/
public void append(byte[] bytes, int offset, int length)
throws IOException;
/**
* Append ByteData that will not be touched until this ByteBuffer needs
* to calculate its byte count, or it needs to write out. A null surrogate
* is not appended.
*/
public void appendSurrogate(ByteData s) throws IOException;
/**
* Add a ByteBuffer that will receive a copy of all the data appended to
* this ByteBuffer.
*/
public void addCaptureBuffer(ByteBuffer buffer) throws IOException;
/**
* Remove a capture buffer that was previously added by addCaptureBuffer.
*/
public void removeCaptureBuffer(ByteBuffer buffer) throws IOException;
}
1.1 jakarta-velocity/src/java/org/apache/velocity/io/ByteBufferOutputStream.java
Index: ByteBufferOutputStream.java
===================================================================
package org.apache.velocity.io;
/* ====================================================================
* TeaServlet - Copyright (c) 1999-2000 Walt Disney Internet Group
* ====================================================================
* The Tea Software License, Version 1.1
*
* Copyright (c) 2000 Walt Disney Internet Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Walt Disney Internet Group (http://opensource.go.com/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Tea", "TeaServlet", "Kettle", "Trove" and "BeanDoc" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact opensource@dig.com.
*
* 5. Products derived from this software may not be called "Tea",
* "TeaServlet", "Kettle" or "Trove", nor may "Tea", "TeaServlet",
* "Kettle", "Trove" or "BeanDoc" appear in their name, without prior
* written permission of the Walt Disney Internet Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE WALT DISNEY INTERNET GROUP OR ITS
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* For more information about Tea, please see http://opensource.go.com/.
*/
import java.io.OutputStream;
import java.io.IOException;
/******************************************************************************
* An OutputStream that writes into a ByteBuffer.
*
* @author Brian S O'Neill
* @version
* <!--$$Revision: 1.1 $-->, <!--$$JustDate:--> 9/07/00 <!-- $-->
*/
public class ByteBufferOutputStream extends OutputStream {
private ByteBuffer mBuffer;
private boolean mClosed;
public ByteBufferOutputStream(ByteBuffer buffer) {
mBuffer = buffer;
}
public void write(int b) throws IOException {
checkIfClosed();
mBuffer.append((byte)b);
}
public void write(byte[] bytes) throws IOException {
checkIfClosed();
mBuffer.append(bytes);
}
public void write(byte[] bytes, int offset, int length)
throws IOException {
checkIfClosed();
mBuffer.append(bytes, offset, length);
}
public void flush() throws IOException {
checkIfClosed();
}
public void close() {
mClosed = true;
}
private void checkIfClosed() throws IOException {
if (mClosed) {
throw new IOException("OutputStream closed");
}
}
}
1.1 jakarta-velocity/src/java/org/apache/velocity/io/ByteData.java
Index: ByteData.java
===================================================================
package org.apache.velocity.io;
/* ====================================================================
* TeaServlet - Copyright (c) 1999-2000 Walt Disney Internet Group
* ====================================================================
* The Tea Software License, Version 1.1
*
* Copyright (c) 2000 Walt Disney Internet Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Walt Disney Internet Group (http://opensource.go.com/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Tea", "TeaServlet", "Kettle", "Trove" and "BeanDoc" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact opensource@dig.com.
*
* 5. Products derived from this software may not be called "Tea",
* "TeaServlet", "Kettle" or "Trove", nor may "Tea", "TeaServlet",
* "Kettle", "Trove" or "BeanDoc" appear in their name, without prior
* written permission of the Walt Disney Internet Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE WALT DISNEY INTERNET GROUP OR ITS
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* For more information about Tea, please see http://opensource.go.com/.
*/
import java.io.OutputStream;
import java.io.IOException;
/******************************************************************************
* Simple interface for writing a list of bytes to an OutputStream.
*
* @author Brian S O'Neill
* @version
* <!--$$Revision: 1.1 $-->, <!--$$JustDate:--> 9/07/00 <!-- $-->
*/
public interface ByteData {
/**
* Return the amount of bytes that will be written by the writeTo method.
*/
public long getByteCount() throws IOException;
/**
* Writes all the bytes to the given OutputStream.
*/
public void writeTo(OutputStream out) throws IOException;
/**
* Reset any transient data stored in this ByteData. A call to getByteCount
* or writeTo will force this data to be restored.
*/
public void reset() throws IOException;
}
1.1 jakarta-velocity/src/java/org/apache/velocity/io/CharToByteBuffer.java
Index: CharToByteBuffer.java
===================================================================
package org.apache.velocity.io;
/* ====================================================================
* TeaServlet - Copyright (c) 1999-2000 Walt Disney Internet Group
* ====================================================================
* The Tea Software License, Version 1.1
*
* Copyright (c) 2000 Walt Disney Internet Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Walt Disney Internet Group (http://opensource.go.com/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Tea", "TeaServlet", "Kettle", "Trove" and "BeanDoc" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact opensource@dig.com.
*
* 5. Products derived from this software may not be called "Tea",
* "TeaServlet", "Kettle" or "Trove", nor may "Tea", "TeaServlet",
* "Kettle", "Trove" or "BeanDoc" appear in their name, without prior
* written permission of the Walt Disney Internet Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE WALT DISNEY INTERNET GROUP OR ITS
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* For more information about Tea, please see http://opensource.go.com/.
*/
import java.io.IOException;
import java.io.UnsupportedEncodingException;
/******************************************************************************
* A ByteBuffer that accepts characters and Strings as well.
*
* @author Brian S O'Neill
* @version
* <!--$$Revision: 1.1 $-->, <!--$$JustDate:--> 9/07/00 <!-- $-->
*/
public interface CharToByteBuffer extends ByteBuffer {
/**
* Set the encoding for converting characters to bytes. Calling getEncoding
* will return the canonical encoding name and may differ from the
* encoding name provided to this method.
*/
public void setEncoding(String enc)
throws IOException, UnsupportedEncodingException;
/**
* Returns the current encoding that is being used to convert characters
* to bytes or null if no encoding has been set yet. The encoding name
* that is returned is canonical and may differ from the name passed into
* setEncoding.
*/
public String getEncoding() throws IOException;
/**
* Add one character to the end of this buffer.
*/
public void append(char c) throws IOException;
/**
* Copy the given characters to the end of this buffer.
*/
public void append(char[] chars) throws IOException;
/**
* Copy the given characters to the end of this buffer, starting at the
* offset, using the length provided.
*/
public void append(char[] chars, int offset, int length)
throws IOException;
/**
* Copy the given String to the end of this buffer.
*/
public void append(String str) throws IOException;
/**
* Copy the given String to the end of this buffer, starting at the offset,
* using the length provided.
*/
public void append(String str, int offset, int length) throws IOException;
}
1.1 jakarta-velocity/src/java/org/apache/velocity/io/CharToByteBufferWriter.java
Index: CharToByteBufferWriter.java
===================================================================
package org.apache.velocity.io;
/* ====================================================================
* TeaServlet - Copyright (c) 1999-2000 Walt Disney Internet Group
* ====================================================================
* The Tea Software License, Version 1.1
*
* Copyright (c) 2000 Walt Disney Internet Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Walt Disney Internet Group (http://opensource.go.com/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Tea", "TeaServlet", "Kettle", "Trove" and "BeanDoc" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact opensource@dig.com.
*
* 5. Products derived from this software may not be called "Tea",
* "TeaServlet", "Kettle" or "Trove", nor may "Tea", "TeaServlet",
* "Kettle", "Trove" or "BeanDoc" appear in their name, without prior
* written permission of the Walt Disney Internet Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE WALT DISNEY INTERNET GROUP OR ITS
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* For more information about Tea, please see http://opensource.go.com/.
*/
import java.io.Writer;
import java.io.IOException;
/******************************************************************************
* A Writer that writes into a CharToByteBuffer.
*
* @author Brian S O'Neill
* @version
* <!--$$Revision: 1.1 $-->, <!--$$JustDate:--> 9/07/00 <!-- $-->
*/
public class CharToByteBufferWriter extends Writer {
private CharToByteBuffer mBuffer;
private boolean mClosed;
public CharToByteBufferWriter(CharToByteBuffer buffer) {
mBuffer = buffer;
}
public void write(int c) throws IOException {
checkIfClosed();
mBuffer.append((char)c);
}
public void write(char[] chars) throws IOException {
checkIfClosed();
mBuffer.append(chars);
}
public void write(char[] chars, int offset, int length)
throws IOException {
checkIfClosed();
mBuffer.append(chars, offset, length);
}
public void write(String str) throws IOException {
checkIfClosed();
mBuffer.append(str);
}
public void write(String str, int offset, int length) throws IOException {
checkIfClosed();
mBuffer.append(str, offset, length);
}
public void flush() throws IOException {
checkIfClosed();
}
public void close() {
mClosed = true;
}
private void checkIfClosed() throws IOException {
if (mClosed) {
throw new IOException("Writer closed");
}
}
}
1.1 jakarta-velocity/src/java/org/apache/velocity/io/DefaultByteBuffer.java
Index: DefaultByteBuffer.java
===================================================================
package org.apache.velocity.io;
/* ====================================================================
* TeaServlet - Copyright (c) 1999-2000 Walt Disney Internet Group
* ====================================================================
* The Tea Software License, Version 1.1
*
* Copyright (c) 2000 Walt Disney Internet Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Walt Disney Internet Group (http://opensource.go.com/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Tea", "TeaServlet", "Kettle", "Trove" and "BeanDoc" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact opensource@dig.com.
*
* 5. Products derived from this software may not be called "Tea",
* "TeaServlet", "Kettle" or "Trove", nor may "Tea", "TeaServlet",
* "Kettle", "Trove" or "BeanDoc" appear in their name, without prior
* written permission of the Walt Disney Internet Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE WALT DISNEY INTERNET GROUP OR ITS
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* For more information about Tea, please see http://opensource.go.com/.
*/
import java.io.OutputStream;
import java.io.IOException;
import java.util.List;
import java.util.ArrayList;
/******************************************************************************
* A ByteBuffer implementation that keeps byte data in memory.
*
* @author Brian S O'Neill
* @version
* <!--$$Revision: 1.1 $-->, <!--$$JustDate:--> 9/07/00 <!-- $-->
*/
public class DefaultByteBuffer implements ByteBuffer {
private static final int BUFFER_SIZE = 512;
// A List of ByteData instances.
private List mChunks;
private byte[] mBuffer;
private int mCursor;
private int mBaseCount;
private List mCaptureBuffers;
public DefaultByteBuffer() {
mChunks = new ArrayList(100);
}
public long getBaseByteCount() {
if (mBuffer != null) {
return mBaseCount + mCursor;
}
else {
return mBaseCount;
}
}
public long getByteCount() throws IOException {
long count;
if (mBuffer != null) {
count = mCursor;
}
else {
count = 0;
}
int size = mChunks.size();
for (int i=0; i<size; i++) {
count += ((ByteData)mChunks.get(i)).getByteCount();
}
return count;
}
public void writeTo(OutputStream out) throws IOException {
int size = mChunks.size();
for (int i=0; i<size; i++) {
((ByteData)mChunks.get(i)).writeTo(out);
}
if (mBuffer != null && mCursor != 0) {
out.write(mBuffer, 0, mCursor);
}
}
public void append(byte b) throws IOException {
List captureBuffers;
if ((captureBuffers = mCaptureBuffers) != null) {
int size = captureBuffers.size();
for (int i=0; i<size; i++) {
((ByteBuffer)captureBuffers.get(i)).append(b);
}
}
if (mBuffer == null) {
mBuffer = new byte[BUFFER_SIZE];
mCursor = 0;
}
else if (mCursor >= mBuffer.length) {
mChunks.add(new ArrayByteData(mBuffer));
mBaseCount += BUFFER_SIZE;
mBuffer = new byte[BUFFER_SIZE];
mCursor = 0;
}
mBuffer[mCursor++] = b;
}
public void append(byte[] bytes) throws IOException {
append(bytes, 0, bytes.length);
}
public void append(byte[] bytes, int offset, int length)
throws IOException
{
List captureBuffers;
if ((captureBuffers = mCaptureBuffers) != null) {
int size = captureBuffers.size();
for (int i=0; i<size; i++) {
((ByteBuffer)captureBuffers.get(i)).append
(bytes, offset, length);
}
}
while (length > 0) {
if (mBuffer == null) {
if (length >= BUFFER_SIZE) {
byte[] copy = new byte[length];
System.arraycopy(bytes, offset, copy, 0, length);
mChunks.add(new ArrayByteData(copy));
mBaseCount += length;
return;
}
mBuffer = new byte[BUFFER_SIZE];
mCursor = 0;
}
int available = BUFFER_SIZE - mCursor;
if (length <= available) {
System.arraycopy(bytes, offset, mBuffer, mCursor, length);
mCursor += length;
return;
}
System.arraycopy(bytes, offset, mBuffer, mCursor, available);
mChunks.add(new ArrayByteData(mBuffer));
mBaseCount += BUFFER_SIZE;
mBuffer = null;
offset += available;
length -= available;
}
}
public void appendSurrogate(ByteData s) throws IOException {
if (s == null) {
return;
}
List captureBuffers;
if ((captureBuffers = mCaptureBuffers) != null) {
int size = captureBuffers.size();
for (int i=0; i<size; i++) {
((ByteBuffer)captureBuffers.get(i)).appendSurrogate(s);
}
}
if (mBuffer != null && mCursor > 0) {
mChunks.add(new ArrayByteData(mBuffer, 0, mCursor));
mBaseCount += mCursor;
mBuffer = null;
}
mChunks.add(s);
}
public void addCaptureBuffer(ByteBuffer buffer) {
List captureBuffers;
if ((captureBuffers = mCaptureBuffers) == null) {
captureBuffers = mCaptureBuffers = new ArrayList();
}
captureBuffers.add(buffer);
}
public void removeCaptureBuffer(ByteBuffer buffer) {
List captureBuffers;
if ((captureBuffers = mCaptureBuffers) != null) {
captureBuffers.remove(buffer);
}
}
public void reset() throws IOException {
int size = mChunks.size();
for (int i=0; i<size; i++) {
((ByteData)mChunks.get(i)).reset();
}
List captureBuffers;
if ((captureBuffers = mCaptureBuffers) != null) {
size = captureBuffers.size();
for (int i=0; i<size; i++) {
((ByteData)captureBuffers.get(i)).reset();
}
}
}
}
1.1 jakarta-velocity/src/java/org/apache/velocity/io/DefaultCharToByteBuffer.java
Index: DefaultCharToByteBuffer.java
===================================================================
package org.apache.velocity.io;
/* ====================================================================
* TeaServlet - Copyright (c) 1999-2000 Walt Disney Internet Group
* ====================================================================
* The Tea Software License, Version 1.1
*
* Copyright (c) 2000 Walt Disney Internet Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Walt Disney Internet Group (http://opensource.go.com/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Tea", "TeaServlet", "Kettle", "Trove" and "BeanDoc" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact opensource@dig.com.
*
* 5. Products derived from this software may not be called "Tea",
* "TeaServlet", "Kettle" or "Trove", nor may "Tea", "TeaServlet",
* "Kettle", "Trove" or "BeanDoc" appear in their name, without prior
* written permission of the Walt Disney Internet Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE WALT DISNEY INTERNET GROUP OR ITS
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* For more information about Tea, please see http://opensource.go.com/.
*/
import java.io.*;
/******************************************************************************
* A CharToByteBuffer implementation that wraps a ByteBuffer for storage.
*
* @author Brian S O'Neill
* @version
* <!--$$Revision: 1.1 $-->, <!--$$JustDate:--> 9/07/00 <!-- $-->
*/
public class DefaultCharToByteBuffer implements CharToByteBuffer {
private ByteBuffer mBuffer;
private OutputStreamWriter mConvertor;
private char[] mChars;
private int mCapacity;
private int mCursor;
private String mDefaultEncoding;
/**
* @param buffer Buffer that receives the characters converted to bytes.
*/
public DefaultCharToByteBuffer(ByteBuffer buffer) {
this(buffer, null);
}
/**
* @param buffer Buffer that receives the characters converted to bytes.
* @param defaultEncoding Default character encoding to use if setEncoding
* is not called.
*/
public DefaultCharToByteBuffer(ByteBuffer buffer, String defaultEncoding) {
mBuffer = buffer;
mChars = new char[4000];
mCapacity = mChars.length;
mDefaultEncoding = defaultEncoding;
}
public void setEncoding(String enc) throws IOException {
drain(true);
mConvertor = new OutputStreamWriter
(new ByteBufferOutputStream(mBuffer), enc);
}
public String getEncoding() {
return (mConvertor == null) ? mDefaultEncoding :
mConvertor.getEncoding();
}
public long getBaseByteCount() throws IOException {
return mBuffer.getBaseByteCount();
}
public long getByteCount() throws IOException {
drain(true);
return mBuffer.getByteCount();
}
public void writeTo(OutputStream out) throws IOException {
drain(true);
mBuffer.writeTo(out);
}
public void append(byte b) throws IOException {
drain(true);
mBuffer.append(b);
}
public void append(byte[] bytes) throws IOException {
append(bytes, 0, bytes.length);
}
public void append(byte[] bytes, int offset, int length)
throws IOException {
if (length != 0) {
drain(true);
mBuffer.append(bytes, offset, length);
}
}
public void appendSurrogate(ByteData s) throws IOException {
if (s != null) {
drain(true);
mBuffer.appendSurrogate(s);
}
}
public void addCaptureBuffer(ByteBuffer buffer) throws IOException {
drain(true);
mBuffer.addCaptureBuffer(buffer);
}
public void removeCaptureBuffer(ByteBuffer buffer) throws IOException {
drain(true);
mBuffer.removeCaptureBuffer(buffer);
}
public void append(char c) throws IOException {
if (mCursor >= mCapacity) {
drain(false);
}
mChars[mCursor++] = c;
}
public void append(char[] chars) throws IOException {
append(chars, 0, chars.length);
}
public void append(char[] chars, int offset, int length)
throws IOException
{
if (length == 0) {
return;
}
int capacity = mCapacity;
if (length < (capacity - mCursor)) {
System.arraycopy(chars, offset, mChars, mCursor, length);
mCursor += length;
return;
}
// Make room and try again.
drain(false);
if (length < capacity) {
System.arraycopy(chars, offset, mChars, mCursor, length);
mCursor += length;
return;
}
// Write the whole chunk out at once.
getConvertor().write(chars, offset, length);
}
public void append(String str) throws IOException {
append(str, 0, str.length());
}
public void append(String str, int offset, int length) throws IOException {
if (length == 0) {
return;
}
int capacity = mCapacity;
int avail = capacity - mCursor;
if (length <= avail) {
str.getChars(offset, offset + length, mChars, mCursor);
mCursor += length;
return;
}
// Fill up the rest of the character buffer and drain it.
str.getChars(offset, offset + avail, mChars, mCursor);
offset += avail;
length -= avail;
mCursor = capacity;
drain(false);
// Drain chunks that completely fill the character buffer.
while (length >= capacity) {
str.getChars(offset, offset + capacity, mChars, 0);
offset += capacity;
length -= capacity;
mCursor = capacity;
drain(false);
}
// Copy the remainder into the character buffer, but don't drain.
if (length > 0) {
str.getChars(offset, offset + length, mChars, 0);
mCursor = length;
}
}
public void reset() throws IOException {
mBuffer.reset();
}
private OutputStreamWriter getConvertor()
throws UnsupportedEncodingException
{
if (mConvertor == null) {
if (mDefaultEncoding == null) {
mConvertor = new OutputStreamWriter
(new ByteBufferOutputStream(mBuffer));
}
else {
mConvertor = new OutputStreamWriter
(new ByteBufferOutputStream(mBuffer), mDefaultEncoding);
}
}
return mConvertor;
}
private void drain(boolean flush) throws IOException {
if (mCursor != 0) {
try {
getConvertor().write(mChars, 0, mCursor);
}
finally {
mCursor = 0;
}
}
if (flush && mConvertor != null) {
mConvertor.flush();
}
}
}
1.1 jakarta-velocity/src/java/org/apache/velocity/io/FileByteBuffer.java
Index: FileByteBuffer.java
===================================================================
package org.apache.velocity.io;
/* ====================================================================
* TeaServlet - Copyright (c) 1999-2000 Walt Disney Internet Group
* ====================================================================
* The Tea Software License, Version 1.1
*
* Copyright (c) 2000 Walt Disney Internet Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Walt Disney Internet Group (http://opensource.go.com/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Tea", "TeaServlet", "Kettle", "Trove" and "BeanDoc" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact opensource@dig.com.
*
* 5. Products derived from this software may not be called "Tea",
* "TeaServlet", "Kettle" or "Trove", nor may "Tea", "TeaServlet",
* "Kettle", "Trove" or "BeanDoc" appear in their name, without prior
* written permission of the Walt Disney Internet Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE WALT DISNEY INTERNET GROUP OR ITS
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* For more information about Tea, please see http://opensource.go.com/.
*/
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.io.IOException;
import java.util.List;
import java.util.ArrayList;
/******************************************************************************
* A ByteBuffer implementation that can read from an open file or can write
* to it. This implementation is best suited for temporary byte data that is
* too large to hold in memory.
*
* @author Brian S O'Neill
* @version
* <!--$$Revision: 1.1 $--> 5 <!-- $$JustDate:--> 9/07/00 <!-- $-->
*/
public class FileByteBuffer implements ByteBuffer {
private RandomAccessFile mFile;
private List mSurrogates;
private List mCaptureBuffers;
/**
* Creates a FileByteBuffer on a RandomAccessFile. If the file is opened
* read-only, then the append operations will fail.
*
* @param file The file to use as a buffer.
*/
public FileByteBuffer(RandomAccessFile file) throws IOException {
mFile = file;
file.seek(0);
}
public long getBaseByteCount() throws IOException {
return mFile.length();
}
public long getByteCount() throws IOException {
long count = getBaseByteCount();
if (mSurrogates == null) {
return count;
}
int size = mSurrogates.size();
for (int i=0; i<size; i++) {
count += ((Surrogate)mSurrogates.get(i)).mByteData.getByteCount();
}
return count;
}
public void writeTo(OutputStream out) throws IOException {
long length = mFile.length();
int bufSize;
if (length > 4000) {
bufSize = 4000;
}
else {
bufSize = (int)length;
}
byte[] inputBuffer = new byte[bufSize];
mFile.seek(0);
if (mSurrogates != null) {
long currentPos = 0;
int size = mSurrogates.size();
for (int i=0; i<size; i++) {
Surrogate s = (Surrogate)mSurrogates.get(i);
currentPos = writeTo(inputBuffer, out, currentPos, s.mPos);
s.mByteData.writeTo(out);
}
}
// Write out the rest of the file.
int readAmount;
while ((readAmount = mFile.read(inputBuffer, 0, bufSize)) > 0) {
out.write(inputBuffer, 0, readAmount);
}
}
private long writeTo(byte[] inputBuffer, OutputStream out,
long fromPos, long toPos) throws IOException {
if (toPos == fromPos) {
return fromPos;
}
int bufSize = inputBuffer.length;
int readAmount;
while (toPos > fromPos) {
int amount;
if (bufSize <= (toPos - fromPos)) {
amount = bufSize;
}
else {
amount = (int)(toPos - fromPos);
}
while ((readAmount = mFile.read(inputBuffer, 0, amount)) > 0) {
out.write(inputBuffer, 0, readAmount);
fromPos += readAmount;
amount -= readAmount;
if (amount <= 0) {
break;
}
}
if (readAmount <= 0) {
break;
}
}
return fromPos;
}
public void append(byte b) throws IOException {
List captureBuffers;
if ((captureBuffers = mCaptureBuffers) != null) {
int size = captureBuffers.size();
for (int i=0; i<size; i++) {
((ByteBuffer)captureBuffers.get(i)).append(b);
}
}
mFile.write(b);
}
public void append(byte[] bytes) throws IOException {
mFile.write(bytes);
}
public void append(byte[] bytes, int offset, int length)
throws IOException
{
List captureBuffers;
if ((captureBuffers = mCaptureBuffers) != null) {
int size = captureBuffers.size();
for (int i=0; i<size; i++) {
((ByteBuffer)captureBuffers.get(i)).append
(bytes, offset, length);
}
}
mFile.write(bytes, offset, length);
}
public void appendSurrogate(ByteData s) throws IOException {
if (s == null) {
return;
}
List captureBuffers;
if ((captureBuffers = mCaptureBuffers) != null) {
int size = captureBuffers.size();
for (int i=0; i<size; i++) {
((ByteBuffer)captureBuffers.get(i)).appendSurrogate(s);
}
}
if (mSurrogates == null) {
mSurrogates = new ArrayList();
}
mSurrogates.add(new Surrogate(s));
}
public void addCaptureBuffer(ByteBuffer buffer) {
List captureBuffers;
if ((captureBuffers = mCaptureBuffers) == null) {
captureBuffers = mCaptureBuffers = new ArrayList();
}
captureBuffers.add(buffer);
}
public void removeCaptureBuffer(ByteBuffer buffer) {
List captureBuffers;
if ((captureBuffers = mCaptureBuffers) != null) {
captureBuffers.remove(buffer);
}
}
public void reset() throws IOException {
List byteDatas;
int i, size;
if ((byteDatas = mSurrogates) != null) {
size = byteDatas.size();
for (i=0; i<size; i++) {
((ByteData)byteDatas.get(i)).reset();
}
}
if ((byteDatas = mCaptureBuffers) != null) {
size = byteDatas.size();
for (i=0; i<size; i++) {
((ByteData)byteDatas.get(i)).reset();
}
}
}
private class Surrogate {
public final ByteData mByteData;
public final long mPos;
public Surrogate(ByteData data) throws IOException {
mByteData = data;
mPos = mFile.getFilePointer();
}
}
}
1.1 jakarta-velocity/src/java/org/apache/velocity/io/FileByteData.java
Index: FileByteData.java
===================================================================
package org.apache.velocity.io;
/* ====================================================================
* TeaServlet - Copyright (c) 1999-2000 Walt Disney Internet Group
* ====================================================================
* The Tea Software License, Version 1.1
*
* Copyright (c) 2000 Walt Disney Internet Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Walt Disney Internet Group (http://opensource.go.com/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Tea", "TeaServlet", "Kettle", "Trove" and "BeanDoc" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact opensource@dig.com.
*
* 5. Products derived from this software may not be called "Tea",
* "TeaServlet", "Kettle" or "Trove", nor may "Tea", "TeaServlet",
* "Kettle", "Trove" or "BeanDoc" appear in their name, without prior
* written permission of the Walt Disney Internet Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE WALT DISNEY INTERNET GROUP OR ITS
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* For more information about Tea, please see http://opensource.go.com/.
*/
import java.io.OutputStream;
import java.io.File;
import java.io.RandomAccessFile;
import java.io.IOException;
/******************************************************************************
* A ByteData implementation that reads the contents of a file.
*
* @author Brian S O'Neill
* @version
* <!--$$Revision: 1.1 $-->, <!--$$JustDate:--> 9/07/00 <!-- $-->
*/
public class FileByteData implements ByteData {
private File mFile;
private boolean mTriedToOpen;
private RandomAccessFile mRAF;
public FileByteData(File file) {
mFile = file;
// Open here so that if file isn't found, error is logged earlier.
open();
}
public long getByteCount() throws IOException {
// Keep file open to ensure that length doesn't change between call to
// getByteCount and writeTo.
RandomAccessFile raf = open();
if (raf == null) {
return 0;
}
else {
return raf.length();
}
}
public void writeTo(OutputStream out) throws IOException {
RandomAccessFile raf = open();
if (raf == null) {
return;
}
try {
long length = raf.length();
int bufSize;
if (length > 4000) {
bufSize = 4000;
}
else {
bufSize = (int)length;
}
byte[] inputBuffer = new byte[bufSize];
raf.seek(0);
int readAmount;
while ((readAmount = raf.read(inputBuffer, 0, bufSize)) > 0) {
out.write(inputBuffer, 0, readAmount);
}
}
finally {
try {
finalize();
}
catch (IOException e) {
}
}
}
public void reset() throws IOException {
if (mRAF != null) {
try {
mRAF.close();
}
finally {
mTriedToOpen = false;
mRAF = null;
}
}
}
protected final void finalize() throws IOException {
reset();
}
private RandomAccessFile open() {
if (!mTriedToOpen) {
mTriedToOpen = true;
try {
mRAF = new RandomAccessFile(mFile, "r");
}
catch (IOException e) {
Thread t = Thread.currentThread();
t.getThreadGroup().uncaughtException(t, e);
}
}
return mRAF;
}
}
1.1 jakarta-velocity/src/java/org/apache/velocity/io/IdentityMap.java
Index: IdentityMap.java
===================================================================
package org.apache.velocity.io;
/* ====================================================================
* Trove - Copyright (c) 1997-2000 Walt Disney Internet Group
* ====================================================================
* The Tea Software License, Version 1.1
*
* Copyright (c) 2000 Walt Disney Internet Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Walt Disney Internet Group (http://opensource.go.com/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Tea", "TeaServlet", "Kettle", "Trove" and "BeanDoc" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact opensource@dig.com.
*
* 5. Products derived from this software may not be called "Tea",
* "TeaServlet", "Kettle" or "Trove", nor may "Tea", "TeaServlet",
* "Kettle", "Trove" or "BeanDoc" appear in their name, without prior
* written permission of the Walt Disney Internet Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE WALT DISNEY INTERNET GROUP OR ITS
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* For more information about Tea, please see http://opensource.go.com/.
*/
import java.lang.ref.*;
import java.util.*;
/******************************************************************************
* An IdentityMap is like WeakHashMap, except it uses a key's identity
* hashcode and equals methods. IdentityMap is not thread-safe and must be
* wrapped with Collections.synchronizedMap to be made thread-safe. Most of the
* implementation for this class is ripped off from java.util.HashMap, but not
* java.util.WeakHashMap, in order to acheive greater efficiency.
* <p>
* The documentation for WeakHashMap states that it is intended primarily
* for use with key objects whose equals methods test for object identity
* using the == operator. Because WeakHashMap uses a key's own equals and
* hashcode methods, it is better suited for implementing methods that behave
* like {@link String#intern}. However, because WeakHashMap stongly references
* values, {@link Utils#intern Utils.intern} provides a safer intern mechanism.
* <p>
* In this implementation, all key objects are tested for equality using the
* == operator, and null keys are not permitted. IdentityMap is therefore
* better suited for "canonicalized" mappings.
* <p>
* Note: Weakly referenced entries may be automatically removed during
* either accessor or mutator operations, possibly causing a concurrent
* modification to be detected. Therefore, even if multiple threads are only
* accessing this map, be sure to synchronize this map first. Also, do not
* rely on the value returned by size() when using an iterator from this map.
* The iterators may return less entries than the amount reported by size().
*
* @author Brian S O'Neill
* @version
* <!--$$Revision: 1.1 $-->, <!--$$JustDate:--> 9/07/00 <!-- $-->
* @see java.util.WeakHashMap
* @see java.util.HashMap
*/
public class IdentityMap extends AbstractMap implements Map, Cloneable {
// Types of Iterators
static final int KEYS = 0;
static final int VALUES = 1;
static final int ENTRIES = 2;
static final Iterator cEmptyHashIterator = new Iterator() {
public boolean hasNext() {
return false;
}
public Object next() {
throw new NoSuchElementException();
}
public void remove() {
throw new IllegalStateException();
}
};
/**
* Test program.
*/
/*
public static void main(String[] args) throws Exception {
Map map = new IdentityMap();
map.put("Hello", "There");
for (int i=0; i<1000000; i++) {
if (i % 5 == 0) {
map.put(new String("Hello"), "Dude");
}
map.get("Hello");
map.get("Stuff");
}
System.out.println(map.containsValue("Dude"));
System.out.println(map.get("Hello"));
System.gc();
System.out.println(map);
System.out.println(map.size());
System.out.println(map.containsValue("Dude"));
System.out.println(map.get("Hello"));
map.remove("Hello");
System.out.println(map);
System.out.println(map.size());
System.out.println(map.containsValue("Dude"));
System.out.println(map.get("Hello"));
}
*/
/**
* Converts a string to a collection without calling size(). Iterators from
* this map may return less entries than the amount reported by size().
*/
static String toString(Collection c) {
StringBuffer buf = new StringBuffer();
Iterator it = c.iterator();
buf.append("[");
for (int i = 0; it.hasNext(); i++) {
if (i > 0) {
buf.append(", ");
}
buf.append(String.valueOf(it.next()));
}
buf.append("]");
return buf.toString();
}
/**
* The hash table data.
*/
private transient Entry mTable[];
/**
* The total number of mappings in the hash table.
*/
private transient int mCount;
/**
* The table is rehashed when its size exceeds this threshold. (The
* value of this field is (int)(capacity * loadFactor).)
*
* @serial
*/
private int mThreshold;
/**
* The load factor for the hashtable.
*
* @serial
*/
private float mLoadFactor;
/**
* The number of times this HashMap has been structurally modified
* Structural modifications are those that change the number of mappings in
* the HashMap or otherwise modify its internal structure (e.g.,
* rehash). This field is used to make iterators on Collection-views of
* the HashMap fail-fast. (See ConcurrentModificationException).
*/
private transient int mModCount = 0;
// Views
private transient Set mKeySet = null;
private transient Set mEntrySet = null;
private transient Collection mValues = null;
/**
* Constructs a new, empty map with the specified initial
* capacity and the specified load factor.
*
* @param initialCapacity the initial capacity of the HashMap.
* @param loadFactor the load factor of the HashMap
* @throws IllegalArgumentException if the initial capacity is less
* than zero, or if the load factor is nonpositive.
*/
public IdentityMap(int initialCapacity, float loadFactor) {
if (initialCapacity < 0) {
throw new IllegalArgumentException("Illegal Initial Capacity: "+
initialCapacity);
}
if (loadFactor <= 0 || Float.isNaN(loadFactor)) {
throw new IllegalArgumentException("Illegal Load factor: "+
loadFactor);
}
if (initialCapacity == 0) {
initialCapacity = 1;
}
mLoadFactor = loadFactor;
mTable = new Entry[initialCapacity];
mThreshold = (int)(initialCapacity * loadFactor);
}
/**
* Constructs a new, empty map with the specified initial capacity
* and default load factor, which is <tt>0.75</tt>.
*
* @param initialCapacity the initial capacity of the HashMap.
* @throws IllegalArgumentException if the initial capacity is less
* than zero.
*/
public IdentityMap(int initialCapacity) {
this(initialCapacity, 0.75f);
}
/**
* Constructs a new, empty map with a default capacity and load
* factor, which is <tt>0.75</tt>.
*/
public IdentityMap() {
this(11, 0.75f);
}
/**
* Constructs a new map with the same mappings as the given map. The
* map is created with a capacity of twice the number of mappings in
* the given map or 11 (whichever is greater), and a default load factor,
* which is <tt>0.75</tt>.
*/
public IdentityMap(Map t) {
this(Math.max(2 * t.size(), 11), 0.75f);
putAll(t);
}
/**
* Returns the number of key-value mappings in this map, but this value
* may be larger than actual amount of entries produced by an iterator.
*
* @return the number of key-value mappings in this map.
*/
public int size() {
return mCount;
}
/**
* Returns <tt>true</tt> if this map contains no key-value mappings.
*
* @return <tt>true</tt> if this map contains no key-value mappings.
*/
public boolean isEmpty() {
return mCount == 0;
}
/**
* Returns <tt>true</tt> if this map maps one or more keys to the
* specified value.
*
* @param value value whose presence in this map is to be tested.
* @return <tt>true</tt> if this map maps one or more keys to the
* specified value.
*/
public boolean containsValue(Object value) {
Entry tab[] = mTable;
if (value == null) {
for (int i = tab.length ; i-- > 0 ;) {
for (Entry e = tab[i], prev = null; e != null; e = e.mNext) {
if (e.getKey() == null) {
// Clean up after a cleared Reference.
mModCount++;
if (prev != null) {
prev.mNext = e.mNext;
}
else {
tab[i] = e.mNext;
}
mCount--;
}
else if (e.mValue == null) {
return true;
}
else {
prev = e;
}
}
}
}
else {
for (int i = tab.length ; i-- > 0 ;) {
for (Entry e = tab[i], prev = null; e != null; e = e.mNext) {
if (e.getKey() == null) {
// Clean up after a cleared Reference.
mModCount++;
if (prev != null) {
prev.mNext = e.mNext;
}
else {
tab[i] = e.mNext;
}
mCount--;
}
else if (value.equals(e.mValue)) {
return true;
}
else {
prev = e;
}
}
}
}
return false;
}
/**
* Returns <tt>true</tt> if this map contains a mapping for the specified
* key.
*
* @return <tt>true</tt> if this map contains a mapping for the specified
* key.
* @param key key whose presence in this Map is to be tested.
*/
public boolean containsKey(Object key) {
if (key == null) {
return false;
}
Entry tab[] = mTable;
int hash = System.identityHashCode(key);
int index = (hash & 0x7FFFFFFF) % tab.length;
for (Entry e = tab[index], prev = null; e != null; e = e.mNext) {
Object entryKey = e.getKey();
if (entryKey == null) {
// Clean up after a cleared Reference.
mModCount++;
if (prev != null) {
prev.mNext = e.mNext;
}
else {
tab[index] = e.mNext;
}
mCount--;
}
else if (e.mHash == hash && key == entryKey) {
return true;
}
else {
prev = e;
}
}
return false;
}
/**
* Returns the value to which this map maps the specified key. Returns
* <tt>null</tt> if the map contains no mapping for this key. A return
* value of <tt>null</tt> does not <i>necessarily</i> indicate that the
* map contains no mapping for the key; it's also possible that the map
* explicitly maps the key to <tt>null</tt>. The <tt>containsKey</tt>
* operation may be used to distinguish these two cases.
*
* @return the value to which this map maps the specified key.
* @param key key whose associated value is to be returned.
*/
public Object get(Object key) {
if (key == null) {
return null;
}
Entry tab[] = mTable;
int hash = System.identityHashCode(key);
int index = (hash & 0x7FFFFFFF) % tab.length;
for (Entry e = tab[index], prev = null; e != null; e = e.mNext) {
Object entryKey = e.getKey();
if (entryKey == null) {
// Clean up after a cleared Reference.
mModCount++;
if (prev != null) {
prev.mNext = e.mNext;
}
else {
tab[index] = e.mNext;
}
mCount--;
}
else if (e.mHash == hash && key == entryKey) {
return e.mValue;
}
else {
prev = e;
}
}
return null;
}
/**
* Scans the contents of this map, removing all entries that have a
* cleared weak key.
*/
private void cleanup() {
Entry tab[] = mTable;
for (int i = tab.length ; i-- > 0 ;) {
for (Entry e = tab[i], prev = null; e != null; e = e.mNext) {
if (e.getKey() == null) {
// Clean up after a cleared Reference.
mModCount++;
if (prev != null) {
prev.mNext = e.mNext;
}
else {
tab[i] = e.mNext;
}
mCount--;
}
else {
prev = e;
}
}
}
}
/**
* Rehashes the contents of this map into a new <tt>HashMap</tt> instance
* with a larger capacity. This method is called automatically when the
* number of keys in this map exceeds its capacity and load factor.
*/
private void rehash() {
int oldCapacity = mTable.length;
Entry oldMap[] = mTable;
int newCapacity = oldCapacity * 2 + 1;
Entry newMap[] = new Entry[newCapacity];
mModCount++;
mThreshold = (int)(newCapacity * mLoadFactor);
mTable = newMap;
for (int i = oldCapacity ; i-- > 0 ;) {
for (Entry old = oldMap[i] ; old != null ; ) {
Entry e = old;
old = old.mNext;
// Only copy entry if its key hasn't been cleared.
if (e.getKey() == null) {
mCount--;
}
else {
int index = (e.mHash & 0x7FFFFFFF) % newCapacity;
e.mNext = newMap[index];
newMap[index] = e;
}
}
}
}
/**
* Associates the specified value with the specified key in this map.
* If the map previously contained a mapping for this key, the old
* value is replaced.
*
* @param key key with which the specified value is to be associated.
* @param value value to be associated with the specified key.
* @return previous value associated with specified key, or <tt>null</tt>
* if there was no mapping for key. A <tt>null</tt> return can
* also indicate that the HashMap previously associated
* <tt>null</tt> with the specified key.
*/
public Object put(Object key, Object value) {
if (key == null) {
throw new NullPointerException("Null key is not permitted");
}
// Makes sure the key is not already in the HashMap.
Entry tab[] = mTable;
int hash = System.identityHashCode(key);
int index = (hash & 0x7FFFFFFF) % tab.length;
for (Entry e = tab[index], prev = null; e != null; e = e.mNext) {
Object entryKey = e.getKey();
if (entryKey == null) {
// Clean up after a cleared Reference.
mModCount++;
if (prev != null) {
prev.mNext = e.mNext;
}
else {
tab[index] = e.mNext;
}
mCount--;
}
else if (e.mHash == hash && key == entryKey) {
Object old = e.mValue;
e.mValue = value;
return old;
}
else {
prev = e;
}
}
mModCount++;
if (mCount >= mThreshold) {
// Cleanup the table if the threshold is exceeded.
cleanup();
}
if (mCount >= mThreshold) {
// Rehash the table if the threshold is still exceeded.
rehash();
tab = mTable;
index = (hash & 0x7FFFFFFF) % tab.length;
}
// Creates the new entry.
Entry e = new Entry(hash, (Object)key, value, tab[index]);
tab[index] = e;
mCount++;
return null;
}
/**
* Removes the mapping for this key from this map if present.
*
* @param key key whose mapping is to be removed from the map.
* @return previous value associated with specified key, or <tt>null</tt>
* if there was no mapping for key. A <tt>null</tt> return can
* also indicate that the map previously associated <tt>null</tt>
* with the specified key.
*/
public Object remove(Object key) {
Entry tab[] = mTable;
int hash = System.identityHashCode(key);
int index = (hash & 0x7FFFFFFF) % tab.length;
for (Entry e = tab[index], prev = null; e != null; e = e.mNext) {
Object entryKey = e.getKey();
if (entryKey == null) {
// Clean up after a cleared Reference.
mModCount++;
if (prev != null) {
prev.mNext = e.mNext;
}
else {
tab[index] = e.mNext;
}
mCount--;
}
else if (e.mHash == hash && key == entryKey) {
mModCount++;
if (prev != null) {
prev.mNext = e.mNext;
}
else {
tab[index] = e.mNext;
}
mCount--;
Object oldValue = e.mValue;
e.mValue = null;
return oldValue;
}
else {
prev = e;
}
}
return null;
}
/**
* Copies all of the mappings from the specified map to this one.
*
* These mappings replace any mappings that this map had for any of the
* keys currently in the specified Map.
*
* @param t Mappings to be stored in this map.
*/
public void putAll(Map t) {
Iterator i = t.entrySet().iterator();
while (i.hasNext()) {
Map.Entry e = (Map.Entry) i.next();
put(e.getKey(), e.getValue());
}
}
/**
* Removes all mappings from this map.
*/
public void clear() {
Entry tab[] = mTable;
mModCount++;
for (int index = tab.length; --index >= 0; ) {
tab[index] = null;
}
mCount = 0;
}
/**
* Returns a shallow copy of this <tt>HashMap</tt> instance: the keys and
* values themselves are not cloned.
*
* @return a shallow copy of this map.
*/
public Object clone() {
try {
IdentityMap t = (IdentityMap)super.clone();
t.mTable = new Entry[mTable.length];
for (int i = mTable.length ; i-- > 0 ; ) {
t.mTable[i] = (mTable[i] != null)
? (Entry)mTable[i].clone() : null;
}
t.mKeySet = null;
t.mEntrySet = null;
t.mValues = null;
t.mModCount = 0;
return t;
}
catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError();
}
}
/**
* Returns a set view of the keys contained in this map. The set is
* backed by the map, so changes to the map are reflected in the set, and
* vice-versa. The set supports element removal, which removes the
* corresponding mapping from this map, via the <tt>Iterator.remove</tt>,
* <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt>, and
* <tt>clear</tt> operations. It does not support the <tt>add</tt> or
* <tt>addAll</tt> operations.
*
* @return a set view of the keys contained in this map.
*/
public Set keySet() {
if (mKeySet == null) {
mKeySet = new AbstractSet() {
public Iterator iterator() {
return getHashIterator(KEYS);
}
public int size() {
return mCount;
}
public boolean contains(Object o) {
return containsKey(o);
}
public boolean remove(Object o) {
return o == null ? false : IdentityMap.this.remove(o) == o;
}
public void clear() {
IdentityMap.this.clear();
}
public String toString() {
return IdentityMap.this.toString(this);
}
};
}
return mKeySet;
}
/**
* Returns a collection view of the values contained in this map. The
* collection is backed by the map, so changes to the map are reflected in
* the collection, and vice-versa. The collection supports element
* removal, which removes the corresponding mapping from this map, via the
* <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>,
* <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations.
* It does not support the <tt>add</tt> or <tt>addAll</tt> operations.
*
* @return a collection view of the values contained in this map.
*/
public Collection values() {
if (mValues==null) {
mValues = new AbstractCollection() {
public Iterator iterator() {
return getHashIterator(VALUES);
}
public int size() {
return mCount;
}
public boolean contains(Object o) {
return containsValue(o);
}
public void clear() {
IdentityMap.this.clear();
}
public String toString() {
return IdentityMap.this.toString(this);
}
};
}
return mValues;
}
/**
* Returns a collection view of the mappings contained in this map. Each
* element in the returned collection is a <tt>Map.Entry</tt>. The
* collection is backed by the map, so changes to the map are reflected in
* the collection, and vice-versa. The collection supports element
* removal, which removes the corresponding mapping from the map, via the
* <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>,
* <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations.
* It does not support the <tt>add</tt> or <tt>addAll</tt> operations.
*
* @return a collection view of the mappings contained in this map.
* @see Map.Entry
*/
public Set entrySet() {
if (mEntrySet==null) {
mEntrySet = new AbstractSet() {
public Iterator iterator() {
return getHashIterator(ENTRIES);
}
public boolean contains(Object o) {
if (!(o instanceof Map.Entry)) {
return false;
}
Map.Entry entry = (Map.Entry)o;
Object key = entry.getKey();
Entry tab[] = mTable;
int hash = System.identityHashCode(key);
int index = (hash & 0x7FFFFFFF) % tab.length;
for (Entry e = tab[index], prev = null; e != null; e = e.mNext) {
Object entryKey = e.getKey();
if (entryKey == null) {
// Clean up after a cleared Reference.
mModCount++;
if (prev != null) {
prev.mNext = e.mNext;
}
else {
tab[index] = e.mNext;
}
mCount--;
}
else if (e.mHash == hash && e.identityEquals(entry)) {
return true;
}
else {
prev = e;
}
}
return false;
}
public boolean remove(Object o) {
if (!(o instanceof Map.Entry)) {
return false;
}
Map.Entry entry = (Map.Entry)o;
Object key = entry.getKey();
Entry tab[] = mTable;
int hash = System.identityHashCode(key);
int index = (hash & 0x7FFFFFFF) % tab.length;
for (Entry e = tab[index], prev = null; e != null; e = e.mNext) {
Object entryKey = e.getKey();
if (entryKey == null) {
// Clean up after a cleared Reference.
mModCount++;
if (prev != null) {
prev.mNext = e.mNext;
}
else {
tab[index] = e.mNext;
}
mCount--;
}
else if (e.mHash == hash && e.identityEquals(entry)) {
mModCount++;
if (prev != null) {
prev.mNext = e.mNext;
}
else {
tab[index] = e.mNext;
}
mCount--;
e.mValue = null;
return true;
}
else {
prev = e;
}
}
return false;
}
public int size() {
return mCount;
}
public void clear() {
IdentityMap.this.clear();
}
public String toString() {
return IdentityMap.this.toString(this);
}
};
}
return mEntrySet;
}
public String toString() {
StringBuffer buf = new StringBuffer();
Iterator it = entrySet().iterator();
buf.append("{");
for (int i = 0; it.hasNext(); i++) {
if (i > 0) {
buf.append(", ");
}
Map.Entry e = (Map.Entry)it.next();
buf.append(e.getKey() + "=" + e.getValue());
}
buf.append("}");
return buf.toString();
}
private Iterator getHashIterator(int type) {
if (mCount == 0) {
return cEmptyHashIterator;
}
else {
return new HashIterator(type);
}
}
/**
* HashMap collision list entry.
*/
private static class Entry implements Map.Entry {
int mHash;
Object mValue;
Entry mNext;
private Reference mKey;
Entry(int hash, Object key, Object value, Entry next) {
mHash = hash;
mKey = new WeakReference(key);
mValue = value;
mNext = next;
}
private Entry(int hash, Reference key, Object value, Entry next) {
mHash = hash;
mKey = key;
mValue = value;
mNext = next;
}
protected Object clone() {
return new Entry(mHash, (Reference)mKey, mValue,
(mNext==null ? null : (Entry)mNext.clone()));
}
// Map.Entry Ops
public Object getKey() {
return mKey.get();
}
public Object getValue() {
return mValue;
}
public Object setValue(Object value) {
Object oldValue = mValue;
mValue = value;
return oldValue;
}
public boolean equals(Object o) {
if (!(o instanceof Map.Entry)) {
return false;
}
Map.Entry e = (Map.Entry)o;
Object key = getKey();
return (key==null ? e.getKey()==null : key.equals(e.getKey())) &&
(mValue==null ? e.getValue()==null : mValue.equals(e.getValue()));
}
public boolean identityEquals(Map.Entry e) {
return (getKey() == e.getKey()) &&
(mValue==null ? e.getValue()==null : mValue.equals(e.getValue()));
}
public int hashCode() {
return mHash ^ (mValue==null ? 0 : mValue.hashCode());
}
public String toString() {
return getKey() + "=" + mValue;
}
}
private class HashIterator implements Iterator {
private Entry[] mTable = IdentityMap.this.mTable;
private int mIndex = mTable.length;
private Entry mEntry;
// To ensure that the iterator doesn't return cleared entries, keep a
// hard reference to the key. Its existence will prevent the weak
// key from being cleared.
private Object mEntryKey;
private Entry mLastReturned;
private int mType;
/**
* The modCount value that the iterator believes that the backing
* List should have. If this expectation is violated, the iterator
* has detected concurrent modification.
*/
private int expectedModCount = mModCount;
HashIterator(int type) {
mType = type;
}
public boolean hasNext() {
while (mEntry == null ||
(mEntryKey = mEntry.getKey()) == null) {
if (mEntry != null) {
// Clean up after a cleared Reference.
remove(mEntry);
mEntry = mEntry.mNext;
}
if (mEntry == null) {
if (mIndex <= 0) {
return false;
}
else {
mEntry = mTable[--mIndex];
}
}
}
return true;
}
public Object next() {
if (mModCount != expectedModCount) {
throw new ConcurrentModificationException();
}
if (!hasNext()) {
throw new NoSuchElementException();
}
mLastReturned = mEntry;
mEntry = mEntry.mNext;
return mType == KEYS ? mLastReturned.getKey() :
(mType == VALUES ? mLastReturned.getValue() : mLastReturned);
}
public void remove() {
if (mLastReturned == null) {
throw new IllegalStateException();
}
if (mModCount != expectedModCount) {
throw new ConcurrentModificationException();
}
remove(mLastReturned);
mLastReturned = null;
}
private void remove(Entry toRemove) {
Entry[] tab = mTable;
int index = (toRemove.mHash & 0x7FFFFFFF) % tab.length;
for (Entry e = tab[index], prev = null; e != null; e = e.mNext) {
if (e == toRemove) {
mModCount++;
expectedModCount++;
if (prev == null) {
tab[index] = e.mNext;
}
else {
prev.mNext = e.mNext;
}
mCount--;
return;
}
else {
prev = e;
}
}
throw new ConcurrentModificationException();
}
}
}
1.1 jakarta-velocity/src/java/org/apache/velocity/io/InternedCharToByteBuffer.java
Index: InternedCharToByteBuffer.java
===================================================================
package org.apache.velocity.io;
/* ====================================================================
* TeaServlet - Copyright (c) 1999-2000 Walt Disney Internet Group
* ====================================================================
* The Tea Software License, Version 1.1
*
* Copyright (c) 2000 Walt Disney Internet Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Walt Disney Internet Group (http://opensource.go.com/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Tea", "TeaServlet", "Kettle", "Trove" and "BeanDoc" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact opensource@dig.com.
*
* 5. Products derived from this software may not be called "Tea",
* "TeaServlet", "Kettle" or "Trove", nor may "Tea", "TeaServlet",
* "Kettle", "Trove" or "BeanDoc" appear in their name, without prior
* written permission of the Walt Disney Internet Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE WALT DISNEY INTERNET GROUP OR ITS
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* For more information about Tea, please see http://opensource.go.com/.
*/
import java.io.*;
import java.util.*;
/******************************************************************************
* A CharToByteBuffer that keeps track of interned strings (mainly string
* literals) and statically caches the results of those strings after applying
* a byte conversion. This can improve performance if many of the strings being
* passed to the append method have been converted before.
*
* @author Brian S O'Neill
* @version
* <!--$$Revision: 1.1 $-->, <!--$$JustDate:--> 9/07/00 <!-- $-->
*/
public class InternedCharToByteBuffer implements CharToByteBuffer {
private static final Object MARKER = new Object();
// Maps String encodings to caches of Strings converted using that
// encoding. Use a TreeMap because it is good for small maps.
private static Map cEncodings = new TreeMap();
private static Random cLastRandom = new Random();
private static Map getConvertedCache(String encoding) {
synchronized (cEncodings) {
Map cache = (Map)cEncodings.get(encoding);
if (cache == null) {
cache =
Collections.synchronizedMap(new IdentityMap());
cEncodings.put(encoding, cache);
}
return cache;
}
}
private static Random getRandom() {
synchronized (cLastRandom) {
return cLastRandom = new Random(cLastRandom.nextLong());
}
}
private CharToByteBuffer mBuffer;
private Map mConvertedCache;
private Random mRandom;
public InternedCharToByteBuffer(CharToByteBuffer buffer)
throws IOException
{
mBuffer = buffer;
String encoding = buffer.getEncoding();
if (encoding != null) {
mConvertedCache = getConvertedCache(buffer.getEncoding());
}
mRandom = getRandom();
}
public void setEncoding(String enc) throws IOException {
mBuffer.setEncoding(enc);
mConvertedCache = getConvertedCache(mBuffer.getEncoding());
}
public String getEncoding() throws IOException {
return mBuffer.getEncoding();
}
public long getBaseByteCount() throws IOException {
return mBuffer.getBaseByteCount();
}
public long getByteCount() throws IOException {
return mBuffer.getByteCount();
}
public void writeTo(OutputStream out) throws IOException {
mBuffer.writeTo(out);
}
public void append(byte b) throws IOException {
mBuffer.append(b);
}
public void append(byte[] bytes) throws IOException {
mBuffer.append(bytes);
}
public void append(byte[] bytes, int offset, int length)
throws IOException {
mBuffer.append(bytes, offset, length);
}
public void appendSurrogate(ByteData s) throws IOException {
mBuffer.appendSurrogate(s);
}
public void addCaptureBuffer(ByteBuffer buffer) throws IOException {
mBuffer.addCaptureBuffer(buffer);
}
public void removeCaptureBuffer(ByteBuffer buffer) throws IOException {
mBuffer.removeCaptureBuffer(buffer);
}
public void append(char c) throws IOException {
mBuffer.append(c);
}
public void append(char[] chars) throws IOException {
mBuffer.append(chars);
}
public void append(char[] chars, int offset, int length)
throws IOException {
mBuffer.append(chars, offset, length);
}
public void append(String str) throws IOException {
if (str.length() == 0) {
return;
}
Map cache;
if ((cache = mConvertedCache) == null) {
mBuffer.append(str);
return;
}
// Caching performed using a two pass technique. This is done to
// avoid the cost of String.getBytes() for strings that aren't
// actually interned.
Object value;
if ((value = cache.get(str)) != null) {
///*
byte[] bytes;
if (value != MARKER) {
bytes = (byte[])value;
}
else {
// This is at least the second time the string has been seen,
// so assume it has been interned and call String.getBytes().
bytes = str.getBytes(getEncoding());
cache.put(str, bytes);
}
mBuffer.append(bytes);
//*/
/*
ByteData data;
if (value != MARKER) {
data = (ByteData)value;
}
else {
// This is at least the second time the string has been seen,
// so assume it has been interned and call String.getBytes().
data = new ArrayByteData(str.getBytes(getEncoding()));
cache.put(str, data);
}
mBuffer.appendSurrogate(data);
*/
}
else {
// Just put a marker at first to indicate that the string has been
// seen, but don't call String.getBytes() just yet.
if ((mRandom.nextInt() % 20) == 0) {
// Only mark sometimes in order to reduce the amount of times
// put is called for strings that will never be seen again.
// Calculating a random number is cheaper than putting into an
// IdentityMap because no objects are created. A consequence of
// this optimization is that it will take more iterations to
// discover the real string literals, but they will be
// discovered eventually.
cache.put(str, MARKER);
}
mBuffer.append(str);
}
}
public void append(String str, int offset, int length) throws IOException {
mBuffer.append(str, offset, length);
}
public void reset() throws IOException {
mBuffer.reset();
}
}
1.1 jakarta-velocity/src/java/org/apache/velocity/io/SpilloverByteBuffer.java
Index: SpilloverByteBuffer.java
===================================================================
package org.apache.velocity.io;
/* ====================================================================
* TeaServlet - Copyright (c) 1999-2000 Walt Disney Internet Group
* ====================================================================
* The Tea Software License, Version 1.1
*
* Copyright (c) 2000 Walt Disney Internet Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Walt Disney Internet Group (http://opensource.go.com/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Tea", "TeaServlet", "Kettle", "Trove" and "BeanDoc" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact opensource@dig.com.
*
* 5. Products derived from this software may not be called "Tea",
* "TeaServlet", "Kettle" or "Trove", nor may "Tea", "TeaServlet",
* "Kettle", "Trove" or "BeanDoc" appear in their name, without prior
* written permission of the Walt Disney Internet Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE WALT DISNEY INTERNET GROUP OR ITS
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* For more information about Tea, please see http://opensource.go.com/.
*/
import java.io.OutputStream;
import java.io.IOException;
import java.util.List;
import java.util.ArrayList;
/******************************************************************************
* A ByteBuffer implementation that initially stores its data in a
* DefaultByteBuffer, but after a certain threshold is reached, spills over
* into a FileByteBuffer.
*
* @author Brian S O'Neill
* @version
* <!--$$Revision: 1.1 $-->, <!--$$JustDate:--> 9/07/00 <!-- $-->
*/
public class SpilloverByteBuffer implements ByteBuffer {
private Group mGroup;
private ByteBuffer mLocalBuffer;
private ByteBuffer mSpillover;
private List mCaptureBuffers;
/**
* Create a SpilloverByteBuffer against a Group that sets the threshold
* and can create a spillover FileByteBuffer. The Group can be shared
* among many SpilloverByteBuffers.
*
* @param group a group that can be shared among many SpilloverByteBuffers
*/
public SpilloverByteBuffer(Group group) {
mGroup = group;
mLocalBuffer = new DefaultByteBuffer();
}
public long getBaseByteCount() throws IOException {
if (mSpillover == null) {
return mLocalBuffer.getBaseByteCount();
}
else {
return mSpillover.getBaseByteCount();
}
}
public long getByteCount() throws IOException {
if (mSpillover == null) {
return mLocalBuffer.getByteCount();
}
else {
return mSpillover.getByteCount();
}
}
public void writeTo(OutputStream out) throws IOException {
if (mSpillover == null) {
mLocalBuffer.writeTo(out);
}
else {
mSpillover.writeTo(out);
}
}
public void append(byte b) throws IOException {
List captureBuffers;
if ((captureBuffers = mCaptureBuffers) != null) {
int size = captureBuffers.size();
for (int i=0; i<size; i++) {
((ByteBuffer)captureBuffers.get(i)).append(b);
}
}
if (mSpillover == null) {
if (mGroup.adjustLevel(1)) {
mLocalBuffer.append(b);
return;
}
spillover();
}
mSpillover.append(b);
}
public void append(byte[] bytes) throws IOException {
append(bytes, 0, bytes.length);
}
public void append(byte[] bytes, int offset, int length)
throws IOException
{
List captureBuffers;
if ((captureBuffers = mCaptureBuffers) != null) {
int size = captureBuffers.size();
for (int i=0; i<size; i++) {
((ByteBuffer)captureBuffers.get(i)).append
(bytes, offset, length);
}
}
if (mSpillover == null) {
if (mGroup.adjustLevel(length)) {
mLocalBuffer.append(bytes, offset, length);
return;
}
spillover();
}
mSpillover.append(bytes, offset, length);
}
public void appendSurrogate(ByteData s) throws IOException {
if (s == null) {
return;
}
List captureBuffers;
if ((captureBuffers = mCaptureBuffers) != null) {
int size = captureBuffers.size();
for (int i=0; i<size; i++) {
((ByteBuffer)captureBuffers.get(i)).appendSurrogate(s);
}
}
if (mSpillover == null) {
mLocalBuffer.appendSurrogate(s);
}
else {
mSpillover.appendSurrogate(s);
}
}
public void addCaptureBuffer(ByteBuffer buffer) {
List captureBuffers;
if ((captureBuffers = mCaptureBuffers) == null) {
captureBuffers = mCaptureBuffers = new ArrayList();
}
captureBuffers.add(buffer);
}
public void removeCaptureBuffer(ByteBuffer buffer) {
List captureBuffers;
if ((captureBuffers = mCaptureBuffers) != null) {
captureBuffers.remove(buffer);
}
}
public void reset() throws IOException {
mLocalBuffer.reset();
if (mSpillover != null) {
mSpillover.reset();
}
List captureBuffers;
if ((captureBuffers = mCaptureBuffers) != null) {
int size = captureBuffers.size();
for (int i=0; i<size; i++) {
((ByteData)captureBuffers.get(i)).reset();
}
}
}
protected void finalize() throws IOException {
if (mLocalBuffer != null) {
long count = mLocalBuffer.getBaseByteCount();
mLocalBuffer = null;
mGroup.adjustLevel(-count);
}
}
private void spillover() throws IOException {
mSpillover = mGroup.createFileByteBuffer();
// TODO: This is bad! By writing out the contents of the existing
// buffer early, surrogates are evaluated too soon!
mLocalBuffer.writeTo(new ByteBufferOutputStream(mSpillover));
long count = mLocalBuffer.getBaseByteCount();
mLocalBuffer = null;
mGroup.adjustLevel(-count);
}
public static abstract class Group {
private final long mThreshold;
private long mLevel;
public Group(long threshold) {
mThreshold = threshold;
}
public final long getThreshold() {
return mThreshold;
}
public final synchronized long getCurrentLevel() {
return mLevel;
}
public abstract FileByteBuffer createFileByteBuffer()
throws IOException;
synchronized boolean adjustLevel(long delta) {
long newLevel;
if ((newLevel = mLevel + delta) > mThreshold) {
return false;
}
else {
if (newLevel < 0) {
newLevel = 0;
}
mLevel = newLevel;
return true;
}
}
}
}
1.1 jakarta-velocity/src/java/org/apache/velocity/io/TemporaryFile.java
Index: TemporaryFile.java
===================================================================
package org.apache.velocity.io;
/* ====================================================================
* TeaServlet - Copyright (c) 1999-2000 Walt Disney Internet Group
* ====================================================================
* The Tea Software License, Version 1.1
*
* Copyright (c) 2000 Walt Disney Internet Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Walt Disney Internet Group (http://opensource.go.com/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Tea", "TeaServlet", "Kettle", "Trove" and "BeanDoc" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact opensource@dig.com.
*
* 5. Products derived from this software may not be called "Tea",
* "TeaServlet", "Kettle" or "Trove", nor may "Tea", "TeaServlet",
* "Kettle", "Trove" or "BeanDoc" appear in their name, without prior
* written permission of the Walt Disney Internet Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE WALT DISNEY INTERNET GROUP OR ITS
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* For more information about Tea, please see http://opensource.go.com/.
*/
import java.io.*;
import java.util.*;
/******************************************************************************
* Provides references to temporary files that are automatically deleted when
* closed, finalized, or when the system exits.
*
* @author Brian S O'Neill
* @version
* <!--$$Revision: 1.1 $-->, <!--$$JustDate:--> 9/07/00 <!-- $-->
*/
public class TemporaryFile extends RandomAccessFile {
/**
* Creates a new writable temporary file that is deleted when closed,
* finalized, or when the system exits.
*
* @see File#createTempFile
*/
public static RandomAccessFile createTemporaryFile
(String prefix, String suffix, File directory) throws IOException {
File file = File.createTempFile(prefix, suffix, directory);
file.deleteOnExit();
return new TemporaryFile(file);
}
/**
* Creates a new writable temporary file that is deleted when closed,
* finalized, or when the system exits.
*
* @see File#createTempFile
*/
public static RandomAccessFile createTemporaryFile
(String prefix, String suffix) throws IOException {
return createTemporaryFile(prefix, suffix, null);
}
private File mFile;
private TemporaryFile(File file) throws IOException {
super(file, "rw");
mFile = file;
}
public void close() throws IOException {
try {
super.close();
}
finally {
mFile.delete();
}
}
protected void finalize() throws IOException {
close();
}
}
1.5 +1 -2 jakarta-velocity/src/java/org/apache/velocity/runtime/defaults/velocity.properties
Index: velocity.properties
===================================================================
RCS file: /home/cvs/jakarta-velocity/src/java/org/apache/velocity/runtime/defaults/velocity.properties,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- velocity.properties 2000/10/31 05:07:43 1.4
+++ velocity.properties 2000/11/03 23:26:48 1.5
@@ -8,8 +8,7 @@
template.modificationCheckInterval = 2
template.path=.
template.cache=false
-template.encoding = UTF8
-template.asciihack = false
+template.encoding=8859_1
counter.name = velocityCount
counter.initial.value = 1
default.contentType=text/html
1.11 +22 -18 jakarta-velocity/src/java/org/apache/velocity/servlet/VelocityServlet.java
Index: VelocityServlet.java
===================================================================
RCS file: /home/cvs/jakarta-velocity/src/java/org/apache/velocity/servlet/VelocityServlet.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- VelocityServlet.java 2000/10/27 23:12:42 1.10
+++ VelocityServlet.java 2000/11/03 23:26:50 1.11
@@ -70,7 +70,7 @@
import org.apache.velocity.runtime.Runtime;
-import org.apache.velocity.io.FastWriter;
+import org.apache.velocity.io.*;
/**
* Base class which simplifies the use of Velocity with Servlets.
@@ -93,7 +93,7 @@
*
* @author Dave Bryson
* @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
- * $Id: VelocityServlet.java,v 1.10 2000/10/27 23:12:42 daveb Exp $
+ * $Id: VelocityServlet.java,v 1.11 2000/11/03 23:26:50 jon Exp $
*/
public abstract class VelocityServlet extends HttpServlet
{
@@ -118,12 +118,6 @@
private static String encoding = null;
/**
- * Whether to use the <code>FasterWriter</code> hack for faster generation
- * of ASCII output.
- */
- private static boolean asciiHack = true;
-
- /**
* The default content type.
*/
private static String defaultContentType;
@@ -172,8 +166,7 @@
defaultContentType =
Runtime.getString(Runtime.DEFAULT_CONTENT_TYPE, "text/html");
- encoding = Runtime.getString(Runtime.TEMPLATE_ENCODING);
- asciiHack = Runtime.getBoolean(Runtime.TEMPLATE_ASCIIHACK);
+ encoding = Runtime.getString(Runtime.TEMPLATE_ENCODING, "8859_1");
}
catch( Exception e )
{
@@ -209,7 +202,7 @@
throws ServletException, IOException
{
ServletOutputStream output = response.getOutputStream();
- FastWriter writer = null;
+ CharToByteBufferWriter buffer = null;
String contentType = null;
try
{
@@ -237,10 +230,22 @@
if ( template == null )
throw new Exception ("Cannot find the template!" );
- // write the data out.
- writer = new FastWriter(output, encoding);
- writer.setAsciiHack(asciiHack);
- template.merge( context, writer );
+ // create the output buffer
+ InternedCharToByteBuffer ictbb = new InternedCharToByteBuffer(
+ new DefaultCharToByteBuffer(new DefaultByteBuffer(), encoding));
+ buffer = new CharToByteBufferWriter (ictbb);
+
+ // merge the context with the template and output in the buffer
+ template.merge( context, buffer );
+
+ // set the content length
+ long length = ictbb.getByteCount();
+ if (length <= Integer.MAX_VALUE)
+ {
+ response.setContentLength((int)length);
+ }
+
+ ictbb.writeTo(output);
}
catch (Exception e)
{
@@ -252,10 +257,9 @@
try
{
// flush and close
- if (writer != null)
+ if (buffer != null)
{
- writer.flush();
- writer.close();
+ buffer.close();
}
if (output != null)
{
1.15 +25 -48 jakarta-velocity/src/java/org/apache/velocity/test/TemplateTestCase.java
Index: TemplateTestCase.java
===================================================================
RCS file: /home/cvs/jakarta-velocity/src/java/org/apache/velocity/test/TemplateTestCase.java,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- TemplateTestCase.java 2000/10/31 04:44:11 1.14
+++ TemplateTestCase.java 2000/11/03 23:26:51 1.15
@@ -64,7 +64,7 @@
import org.apache.velocity.Template;
import org.apache.velocity.test.provider.TestProvider;
import org.apache.velocity.runtime.Runtime;
-import org.apache.velocity.io.FastWriter;
+import org.apache.velocity.io.*;
import org.apache.velocity.util.StringUtils;
@@ -73,7 +73,7 @@
*
* @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
* @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
- * @version $Id: TemplateTestCase.java,v 1.14 2000/10/31 04:44:11 geirm Exp $
+ * @version $Id: TemplateTestCase.java,v 1.15 2000/11/03 23:26:51 jon Exp $
*/
public class TemplateTestCase extends RuntimeTestCase
{
@@ -108,11 +108,6 @@
*/
protected String baseFileName;
- /**
- * The writer used to output evaluated templates.
- */
- private FastWriter writer;
-
private TestProvider provider;
private ArrayList al;
private Hashtable h;
@@ -162,10 +157,30 @@
Template template = Runtime.getTemplate
(getFileName(null, baseFileName, TMPL_FILE_EXT));
assureResultsDirectoryExists();
- template.merge(context, getWriter(new FileOutputStream
- (getFileName(RESULT_DIR, baseFileName, RESULT_FILE_EXT))));
- closeWriter();
+
+ // get the file to write to
+ FileOutputStream fos =
+ new FileOutputStream (getFileName(RESULT_DIR, baseFileName, RESULT_FILE_EXT));
+
+ // create the streams
+ InternedCharToByteBuffer ictbb = new InternedCharToByteBuffer(
+ new DefaultCharToByteBuffer(new DefaultByteBuffer(), Runtime.getString(
+ Runtime.TEMPLATE_ENCODING)));
+ // create the writer
+ CharToByteBufferWriter buffer = new CharToByteBufferWriter (ictbb);
+
+ // process the template
+ template.merge(context, buffer);
+
+ // write the output to the file
+ ictbb.writeTo(fos);
+ // close the buffer
+ buffer.close();
+
+ // close the file
+ fos.close();
+
if (!isMatch())
{
fail("Processed template did not match expected output");
@@ -255,43 +270,5 @@
protected void tearDown () throws Exception
{
// No op.
- }
-
- /**
- * Returns a <code>FastWriter</code> instance.
- *
- * @param out The output stream for the writer to write to. If
- * <code>null</code>, defaults to <code>System.out</code>.
- * @return The writer.
- */
- protected Writer getWriter (OutputStream out)
- throws UnsupportedEncodingException, IOException
- {
- if (writer == null)
- {
- if (out == null)
- {
- out = System.out;
- }
-
- writer = new FastWriter
- (out, Runtime.getString(Runtime.TEMPLATE_ENCODING));
- writer.setAsciiHack
- (Runtime.getBoolean(Runtime.TEMPLATE_ASCIIHACK));
- }
- return writer;
- }
-
- /**
- * Closes the writer (if it has been opened).
- */
- protected void closeWriter ()
- throws IOException
- {
- if (writer != null)
- {
- writer.flush();
- writer.close();
- }
}
}
1.2 +22 -18 jakarta-velocity/src/java/org/apache/velocity/test/misc/Test.java
Index: Test.java
===================================================================
RCS file: /home/cvs/jakarta-velocity/src/java/org/apache/velocity/test/misc/Test.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Test.java 2000/10/25 00:15:30 1.1
+++ Test.java 2000/11/03 23:26:52 1.2
@@ -54,17 +54,15 @@
* <http://www.apache.org/>.
*/
-import java.io.FileWriter;
-import java.io.FileOutputStream;
+import java.io.*;
import java.util.ArrayList;
import java.util.Hashtable;
-import org.apache.velocity.io.FastWriter;
-
import org.apache.velocity.Context;
import org.apache.velocity.Template;
+import org.apache.velocity.io.*;
import org.apache.velocity.runtime.Runtime;
import org.apache.velocity.test.provider.TestProvider;
@@ -73,7 +71,7 @@
* test all the directives support by Velocity.
*
* @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
- * @version $Id: Test.java,v 1.1 2000/10/25 00:15:30 jvanzyl Exp $
+ * @version $Id: Test.java,v 1.2 2000/11/03 23:26:52 jon Exp $
*/
public class Test
{
@@ -88,8 +86,10 @@
try
{
Runtime.init("velocity.properties");
+ if (templateFile == null)
+ templateFile = "examples/example.vm";
Template template = Runtime.getTemplate(templateFile);
-
+
Context context = new Context();
context.put("provider", provider);
context.put("name", "jason");
@@ -101,17 +101,17 @@
context.put("searchResults", provider.getRelSearches());
context.put("menu", provider.getMenu());
context.put("stringarray", provider.getArray());
-
- FastWriter fw = new FastWriter(
- System.out, Runtime.getString(
- Runtime.TEMPLATE_ENCODING));
-
- fw.setAsciiHack(Runtime.getBoolean(
- Runtime.TEMPLATE_ASCIIHACK));
-
- template.merge(context, fw);
- fw.flush();
- fw.close();
+
+ // create the output buffer
+ InternedCharToByteBuffer ictbb = new InternedCharToByteBuffer(
+ new DefaultCharToByteBuffer(new DefaultByteBuffer(), Runtime.getString(
+ Runtime.TEMPLATE_ENCODING)));
+ CharToByteBufferWriter buffer = new CharToByteBufferWriter (ictbb);
+ template.merge(context, buffer);
+ // write the buffer to the output stream
+ ictbb.writeTo(System.out);
+ ictbb.reset(); // calling this doesn't really have an effect
+ buffer.close();
}
catch( Exception e )
{
@@ -121,6 +121,10 @@
public static void main(String[] args)
{
- Test t = new Test(args[0]);
+ Test t;
+ if (args.length > 0)
+ t = new Test(args[0]);
+ else
+ t = new Test(null);
}
}