com.adobe.internal.io.stream.StreamDatabase Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aem-sdk-api Show documentation
Show all versions of aem-sdk-api Show documentation
The Adobe Experience Manager SDK
The newest version!
/**
*
*/
package com.adobe.internal.io.stream;
import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import com.adobe.internal.io.ByteReader;
import com.adobe.internal.io.ByteWriter;
/**
* @author sgill
*
*/
class StreamDatabase
{
private static class StreamData
{
private long references;
private long maxReferences;
private String stackTrace;
public StreamData()
{
if (false)
{
try {
throw new RuntimeException();
} catch (RuntimeException e) {
Writer writer = new CharArrayWriter();
PrintWriter printWriter = new PrintWriter(writer);
e.printStackTrace(printWriter);
printWriter.close();
this.stackTrace = writer.toString();
}
}
}
public long getReferences()
{
return this.references;
}
public long getMaxReferences()
{
return this.maxReferences;
}
public void addReference()
{
this.references++;
this.maxReferences++;
}
public boolean removeReference()
{
this.references--;
if (this.references < 0)
{
throw new RuntimeException("Stream closed and not removed from stream database.");
}
return this.references == 0;
}
public String toString()
{
StringBuilder buffer = new StringBuilder("Number of open references = ");
buffer.append(this.getReferences()).append("\n").
append("Number of max references = ").append(this.getMaxReferences()).append("\n").
append("Originally created = \n").append(this.stackTrace).append("\n");
return buffer.toString();
}
}
private Map inputStreamData;
private Map outputStreamData;
private ByteReader masterByteReader;
//private long maxOBS;
private boolean lenientMasterByteReader = false;
private boolean ignoreRemoveOnNonexistentReader = false;
private boolean ignoreRemoveOnNonexistentWriter = false;
/**
*
*/
/*package protected*/ StreamDatabase(ByteReader masterByteReader, boolean lenientMasterByteReader,
boolean ignoreRemoveOnNonexistentReader, boolean ignoreRemoveOnNonexistentWriter)
{
super();
this.inputStreamData = new HashMap();
this.outputStreamData = new HashMap();
this.lenientMasterByteReader = lenientMasterByteReader;
this.ignoreRemoveOnNonexistentReader = ignoreRemoveOnNonexistentReader;
this.ignoreRemoveOnNonexistentWriter = ignoreRemoveOnNonexistentWriter;
this.initMasterByteReader(masterByteReader);
}
/*package protected*/ ByteReader resetMasterByteReader(ByteReader masterByteReader)
throws IOException
{
ByteReader oldMasterByteReader = this.masterByteReader;
StreamData oldBRData = (StreamData) this.inputStreamData.get(this.masterByteReader);
// what to do with open references?
if (oldBRData != null)
{
if (oldBRData.getReferences() != 0)
{
// TODO - stop being nice
// are we're gonna be nice?
if (!this.lenientMasterByteReader)
{
throw new RuntimeException("Closing master ByteReader with open streams.");
}
}
}
// force the old master bytereader down
if (oldMasterByteReader != null)
{
this.inputStreamData.remove(oldMasterByteReader);
try
{
oldMasterByteReader.close();
} catch (IOException e) {
IOException ioe = new IOException("Unable to close master ByteReader: " + oldMasterByteReader);
ioe.initCause(e);
throw ioe;
}
}
// finally, reset the master bytereader
this.initMasterByteReader(masterByteReader);
return oldMasterByteReader;
}
private void initMasterByteReader(ByteReader masterByteReader)
{
this.masterByteReader = masterByteReader;
if (this.masterByteReader != null)
{
StreamData newBRData = new StreamData();
this.inputStreamData.put(this.masterByteReader, newBRData);
}
}
/*package protected*/ boolean addIBS(InputByteStream ibs, ByteReader br)
{
boolean ibsFirstTime = false;
StreamData data = (StreamData) this.inputStreamData.get(br);
if (data == null)
{
data = new StreamData();
this.inputStreamData.put(br, data);
ibsFirstTime = true;
}
data.addReference();
return ibsFirstTime;
}
/*package protected*/ boolean removeIBS(InputByteStream ibs, ByteReader br)
{
boolean lastReference = true;
StreamData data = (StreamData) this.inputStreamData.get(br);
if (data == null)
{
if (!this.ignoreRemoveOnNonexistentReader)
{
throw new RuntimeException("Closing an InputByteStream that isn't in the stream database.");
}
} else {
lastReference = data.removeReference();
if (lastReference)
{
this.inputStreamData.remove(br);
}
}
return lastReference;
}
/*package protected*/ boolean addOBS(OutputByteStream obs, ByteWriter bw)
{
boolean obsFirstTime = false;
StreamData data = (StreamData) this.outputStreamData.get(bw);
if (data == null)
{
data = new StreamData();
this.outputStreamData.put(bw, data);
obsFirstTime = true;
//this.maxOBS++;
}
data.addReference();
return obsFirstTime;
}
/*package protected*/ boolean removeOBS(OutputByteStream obs, ByteWriter bw)
{
boolean lastReference = true;
StreamData data = (StreamData) this.outputStreamData.get(bw);
if (data == null)
{
if (!this.ignoreRemoveOnNonexistentWriter)
{
throw new RuntimeException("Closing an OutputByteStream that isn't in the stream database.");
}
} else {
lastReference = data.removeReference();
if (lastReference)
{
this.outputStreamData.remove(bw);
}
}
return lastReference & !this.inputStreamData.containsKey(bw);
}
/*package protected*/ boolean isOutputEmpty()
{
return this.outputStreamData.isEmpty();
}
/*package protected*/ boolean isInputEmpty()
{
return this.inputStreamData.isEmpty();
}
/*package protected*/ boolean isEmpty()
{
return this.isInputEmpty() && this.isOutputEmpty();
}
// /*package protected*/ boolean isEmptyExceptForMasterByteReader()
// {
// // must be both empty OR the output is empty and the only thing in the input is the master
// boolean output = this.isOutputEmpty();
// boolean input = this.isInputEmpty();
// boolean onlyMaster = (this.getInputCount() == 1) && this.inputStreamData.containsKey(this.masterByteReader);
// boolean empty = output && (input || (!input && onlyMaster));
// return empty;
// }
/*package protected*/ int getOutputCount()
{
return this.outputStreamData.size();
}
/*package protected*/ int getInputCount()
{
return this.inputStreamData.size();
}
/*package protected*/ int getCount()
{
return this.getOutputCount() + this.getInputCount();
}
public String toString()
{
StringBuilder buffer = new StringBuilder("Open ByteReader = ");
buffer.append(this.getInputCount()).append("\n").append("Open ByteWriter = ").append(this.getOutputCount()).append("\n").
append("======== ByteReaders\n");
Iterator iter = this.inputStreamData.keySet().iterator();
while (iter.hasNext())
{
Object key = iter.next();
buffer.append("ByteReader = ").append(key.toString()).append("\n");
StreamData data = (StreamData) this.inputStreamData.get(key);
buffer.append(data.toString());
}
buffer.append("======== ByteWriters\n");
iter = this.outputStreamData.keySet().iterator();
while (iter.hasNext())
{
Object key = iter.next();
buffer.append("ByteWriter = ").append(key.toString()).append("\n");
StreamData data = (StreamData) this.outputStreamData.get(key);
buffer.append(data.toString());
}
return buffer.toString();
}
/*package protected*/ int closeAllOpen(boolean ignoreMaster)
throws IOException
{
int numberOpen = closeAllOpenReaders(ignoreMaster);
numberOpen += closeAllOpenWriters(ignoreMaster);
return numberOpen;
}
private int closeAllOpenReaders(boolean ignoreMaster)
throws IOException
{
int numberOpen = 0;
// close the readers
Set openReaderSet = this.inputStreamData.keySet();
numberOpen += openReaderSet.size();
Iterator readerIter = openReaderSet.iterator();
while (readerIter.hasNext())
{
ByteReader openReader = (ByteReader) readerIter.next();
if (ignoreMaster && openReader == this.masterByteReader)
{
continue;
}
try {
openReader.close();
} catch (IOException e) {
IOException ioe = new IOException("Unable to close ByteReader: " + openReader);
ioe.initCause(e);
throw ioe;
}
}
this.inputStreamData.clear();
return numberOpen;
}
private int closeAllOpenWriters(boolean ignoreMaster)
throws IOException
{
int numberOpen = 0;
// close the writers
Set openWriterSet = this.outputStreamData.keySet();
numberOpen += openWriterSet.size();
Iterator writerIter = openWriterSet.iterator();
while (writerIter.hasNext())
{
ByteWriter openWriter = (ByteWriter) writerIter.next();
if (ignoreMaster && openWriter == this.masterByteReader)
{
continue;
}
try {
openWriter.close();
} catch (IOException e) {
IOException ioe = new IOException("Unable to close ByteWriter: " + openWriter);
ioe.initCause(e);
throw ioe;
}
}
this.outputStreamData.clear();
return numberOpen;
}
}