/*
* $Header: /home/cvs/jakarta-slide/src/share/org/apache/slide/content/NodeRevisionContent.java,v 1.14.2.2 2004/02/05 16:05:07 mholz Exp $
* $Revision: 1.14.2.2 $
* $Date: 2004/02/05 16:05:07 $
*
* ====================================================================
*
* Copyright 1999-2002 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.slide.content;
import java.io.ByteArrayInputStream;
import java.io.CharArrayReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import org.apache.slide.common.ObjectValidationFailedException;
import org.apache.slide.util.Messages;
/**
* Encapsultes the contents of a revision.
*
* @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
* @author Juergen Pill
* @version $Revision: 1.14.2.2 $
*/
public final class NodeRevisionContent implements Serializable {
// -------------------------------------------------------------- Constants
private static final int CHUNK = 1024*4;
// ----------------------------------------------------- Instance Variables
/**
* Content.
*/
private char[] content = null;
private byte[] contentBytes = null;
/**
* Reader.
*/
private transient Reader reader = null;
/**
* Input stream.
*/
private transient InputStream inputStream = null;
// ------------------------------------------------------------- Properties
/**
* Content accessor.
*
* @return char[] Content
*/
public char[] getContent() {
char[] result = null;
if (content != null) {
result = content;
inputStream = null;
reader = null;
}
else if (reader != null) {
try {
content = read(reader);
} catch (IOException e) {
e.printStackTrace();
}
result = content;
inputStream = null;
reader = null;
}
else if (contentBytes != null) {
content = new String(contentBytes).toCharArray();
result = content;
inputStream = null;
reader = null;
}
else if (inputStream != null) {
try {
contentBytes = read(inputStream);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
inputStream.close();
} catch (IOException e) {
}
}
content = new String(contentBytes).toCharArray();
result = content;
inputStream = null;
reader = null;
}
return result;
}
/**
* Content accessor.
*
* @return char[] Content
*/
public byte[] getContentBytes() {
byte[] result = null;
if (contentBytes != null) {
result = contentBytes;
inputStream = null;
reader = null;
}
else if (inputStream != null) {
try {
contentBytes = read(inputStream);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
inputStream.close();
} catch (IOException e) {
}
}
result = contentBytes;
inputStream = null;
reader = null;
}
else if (content != null) {
contentBytes = new String(content).getBytes();
result = contentBytes;
inputStream = null;
reader = null;
}
else if (reader != null) {
try {
content = read(reader);
} catch (IOException e) {
e.printStackTrace();
}
contentBytes = new String(content).getBytes();
result = contentBytes;
inputStream = null;
reader = null;
}
return result;
}
/**
* Content accessor.
*
* @return Reader
*/
public Reader readContent()
throws IOException {
Reader result = null;
if (reader != null) {
result = reader;
inputStream = null;
}
else if (content != null) {
result = new CharArrayReader(content);
inputStream = null;
reader = null;
}
else if (inputStream != null) {
result = new InputStreamReader(inputStream);
reader = null;
}
else if (contentBytes != null) {
result = new CharArrayReader(new String(contentBytes).toCharArray());
inputStream = null;
reader = null;
}
return result;
}
/**
* Content accessor.
*
* @return InputStream
*/
public InputStream streamContent()
throws IOException {
InputStream result = null;
if (inputStream != null) {
result = inputStream;
content = null;
reader = null;
}
else if (contentBytes != null) {
result = new ByteArrayInputStream( contentBytes );
reader = null;
inputStream = null;
}
// else if( reader != null ) {
// result = ???;
// inputStream = null;
// }
else if (content != null) {
// Class StringBufferInputStream is deprecated !!
// result = new StringBufferInputStream(new String(content));
result = new ByteArrayInputStream( new String(content).getBytes() );
reader = null;
inputStream = null;
}
return result;
}
/**
* Content mutator.
*
* @param contentBytes New content
*/
public void setContent(byte[] contentBytes) {
this.contentBytes = contentBytes;
this.reader = null;
this.inputStream = null;
this.content = null;
}
/**
* Content mutator.
*
* @param content New content
*/
public void setContent(char[] content) {
this.content = content;
this.reader = null;
this.inputStream = null;
this.contentBytes = null;
}
/**
* Content mutator.
*
* @param reader New reader
*/
public void setContent(Reader reader) {
this.reader = reader;
this.inputStream = null;
this.content = null;
this.contentBytes = null;
}
/**
* Content mutator.
*
* @param inputStream New input stream
*/
public void setContent(InputStream inputStream) {
this.inputStream = inputStream;
this.reader = null;
this.content = null;
this.contentBytes = null;
}
// TODO : Add real serialization support
/**
* Validate.
*/
public void validate() {
if ((content == null) && (contentBytes == null) && (reader == null) && (inputStream == null))
throw new ObjectValidationFailedException
(Messages.message
(NodeRevisionContent.class.getName() + ".noContent"));
}
// -------------------------------------------------------- Private Methods
/**
** Read the data from the stream and return the result in a byte array.
** Return null in case of an error.
**/
public static byte[] read(InputStream inputStream) throws IOException {
byte[] chunk;
byte[] all;
int len;
List chunks;
int i;
int last;
chunks = new ArrayList();
do {
chunk = new byte[CHUNK];
chunks.add(chunk);
len = read(inputStream, chunk);
} while (len == CHUNK);
last = chunks.size() - 1;
all = new byte[last * CHUNK + len ];
for (i = 0; i <= last; i++) {
chunk = (byte[]) chunks.get(i);
System.arraycopy(chunk, 0, all, CHUNK * i, (i == last)? len : CHUNK);
}
return all;
}
/**
** Read until EOF or the buffer is filled.
**
** @return bytes actually read; != buffer.length for eof
**/
private static int read(InputStream stream, byte[] buffer) throws IOException {
int ofs;
int len;
ofs = 0;
while (true) {
len = stream.read(buffer, ofs, buffer.length - ofs);
if (len == -1) {
return ofs;
}
ofs += len;
if (ofs == buffer.length) {
return ofs;
}
}
}
/**
** Read the data from the reader and return the result in a char array.
** Return null in case of an error.
**/
public static char[] read(Reader reader) throws IOException {
char[] chunk;
char[] all;
int len;
List chunks;
int i;
int last;
chunks = new ArrayList();
do {
chunk = new char[CHUNK];
chunks.add(chunk);
len = read(reader, chunk);
} while (len == CHUNK);
last = chunks.size() - 1;
all = new char[last * CHUNK + len];
for (i = 0; i <= last; i++) {
System.arraycopy(chunks.get(i), 0, all, CHUNK * i, (i == last)? len : CHUNK);
}
return all;
}
/**
** Reads until EOF or the buffer is filled.
**
** @return chars actually read; != buffer.length for EOF
**/
private static int read(Reader dest, char[] buffer) throws IOException {
int ofs;
int len;
for (ofs = 0; ofs < buffer.length; ofs += len) {
len = dest.read(buffer, ofs, buffer.length - ofs);
if (len == -1) {
break;
}
}
return ofs;
}
}