/* ******************************************************************************
* Copyright (c) 2006-2012 XMind Ltd. and others.
*
* This file is a part of XMind 3. XMind releases 3 and
* above are dual-licensed under the Eclipse Public License (EPL),
* which is available at http://www.eclipse.org/legal/epl-v10.html
* and the GNU Lesser General Public License (LGPL),
* which is available at http://www.gnu.org/licenses/lgpl.html
* See http://www.xmind.net/license.html for details.
*
* Contributors:
* XMind Ltd. - initial API and implementation
*******************************************************************************/
package org.xmind.core.io;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* @author frankshaka
*
*/
public class ByteArrayStorage implements IStorage {
private static Collection<String> NO_ENTRIES = Collections.emptyList();
protected class ByteArrayInputSource implements IInputSource {
/*
* (non-Javadoc)
*
* @see org.xmind.core.io.IInputSource#getEntries()
*/
public Iterator<String> getEntries() {
return dataTable == null ? NO_ENTRIES.iterator()
: dataTable.keySet().iterator();
}
public boolean isEntryAvailable(String entryName) {
return dataTable != null && dataTable.get(entryName) != null;
}
/*
* (non-Javadoc)
*
* @see org.xmind.core.io.IInputSource#getEntryStream(java.lang.String)
*/
public InputStream getEntryStream(String entryName) {
if (dataTable != null && entryName != null) {
byte[] bs = dataTable.get(entryName);
if (bs != null) {
return new ByteArrayInputStream(bs);
}
}
return null;
}
public InputStream openEntryStream(String entryName)
throws IOException {
InputStream stream = getEntryStream(entryName);
if (stream == null)
throw new FileNotFoundException(entryName);
return stream;
}
/*
* (non-Javadoc)
*
* @see org.xmind.core.io.IInputSource#getEntrySize(java.lang.String)
*/
public long getEntrySize(String entryName) {
if (dataTable != null && entryName != null) {
byte[] bs = dataTable.get(entryName);
if (bs != null) {
return bs.length;
}
}
return -1;
}
/*
* (non-Javadoc)
*
* @see org.xmind.core.io.IInputSource#getEntryTime(java.lang.String)
*/
public long getEntryTime(String entryName) {
if (timeTable != null && entryName != null) {
Long time = timeTable.get(entryName);
if (time != null)
return time.longValue();
}
return 0;
}
/*
* (non-Javadoc)
*
* @see org.xmind.core.io.IInputSource#hasEntry(java.lang.String)
*/
public boolean hasEntry(String entryName) {
return dataTable != null && dataTable.containsKey(entryName);
}
}
protected class ByteArrayOutputTarget implements IOutputTarget {
private class EntryByteArrayOutputStream extends ByteArrayOutputStream {
private String entryName;
/**
*
*/
public EntryByteArrayOutputStream(String entryName) {
this.entryName = entryName;
}
/*
* (non-Javadoc)
*
* @see java.io.OutputStream#flush()
*/
@Override
public void flush() throws IOException {
super.flush();
pushBytes();
}
/*
* (non-Javadoc)
*
* @see java.io.ByteArrayOutputStream#close()
*/
@Override
public void close() throws IOException {
super.close();
pushBytes();
synchronized (ByteArrayOutputTarget.this) {
if (timeTable == null
|| !timeTable.containsKey(entryName)) {
setEntryTime(entryName, System.currentTimeMillis());
}
}
}
/**
*
*/
private void pushBytes() {
putEntryData(entryName, toByteArray());
}
}
/*
* (non-Javadoc)
*
* @see org.xmind.core.io.IOutputTarget#getEntryStream(java.lang.String)
*/
public OutputStream getEntryStream(String entryName) {
return new EntryByteArrayOutputStream(entryName);
}
public OutputStream openEntryStream(String entryName)
throws IOException {
return new EntryByteArrayOutputStream(entryName);
}
/*
* (non-Javadoc)
*
* @see
* org.xmind.core.io.IOutputTarget#isEntryAvaialble(java.lang.String)
*/
public boolean isEntryAvaialble(String entryName) {
return entryName != null;
}
/*
* (non-Javadoc)
*
* @see org.xmind.core.io.IOutputTarget#setEntryTime(long)
*/
public void setEntryTime(String entryName, long time) {
synchronized (this) {
if (timeTable == null) {
timeTable = new HashMap<String, Long>();
}
timeTable.put(entryName, time);
}
}
}
private Map<String, byte[]> dataTable;
private Map<String, Long> timeTable;
/*
* (non-Javadoc)
*
* @see org.xmind.core.io.IArchive#getFullPath()
*/
public String getFullPath() {
return getName();
}
/*
* (non-Javadoc)
*
* @see org.xmind.core.io.IArchive#getInputSource()
*/
public IInputSource getInputSource() {
return new ByteArrayInputSource();
}
/*
* (non-Javadoc)
*
* @see org.xmind.core.io.IArchive#getName()
*/
public String getName() {
return toString();
}
/*
* (non-Javadoc)
*
* @see org.xmind.core.io.IArchive#getOutputTarget()
*/
public IOutputTarget getOutputTarget() {
return new ByteArrayOutputTarget();
}
/*
* (non-Javadoc)
*
* @see org.xmind.core.io.IStorage#clear()
*/
public void clear() {
dataTable = null;
timeTable = null;
}
public void deleteEntry(String entryName) {
if (dataTable != null) {
dataTable.remove(entryName);
}
if (timeTable != null) {
timeTable.remove(entryName);
}
}
public void renameEntry(String entryName, String newName) {
if (dataTable != null) {
byte[] data = dataTable.remove(entryName);
if (data != null) {
dataTable.put(newName, data);
} else {
dataTable.remove(newName);
}
}
if (timeTable != null) {
Long time = timeTable.remove(entryName);
if (time != null) {
timeTable.put(newName, time);
} else {
timeTable.remove(newName);
}
}
}
public byte[] getEntryData(String entryPath) {
return dataTable == null ? null : dataTable.get(entryPath);
}
public void putEntryData(String entryPath, byte[] data) {
if (dataTable == null) {
dataTable = new HashMap<String, byte[]>();
}
dataTable.put(entryPath, data);
}
}