blob: 7df4d3604d1289ef806fe176df2d3054366d1cc2 [file] [log] [blame]
/*
* Copyright (c) 2006, 2009 Borland Software Corporation
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.gmf.internal.xpand;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
import org.eclipse.gmf.internal.xpand.model.XpandStreamsHolder;
public class BufferOutput extends AbstractOutput {
/**
* INV: size > 0
*/
private final Stack<StringBuilder> outletStack;
/**
* INV: size == outletStack.size - 1
*/
private final Stack<String> outletNamesStack;
private final Map<String, StringBuilder> namedSlots;
private final XpandStreamsHolder streamsHolder;
private final boolean enforceReadOnlyAfterAccess;
public BufferOutput(StringBuilder buffer) {
this(buffer, null);
}
// XXX not map but config to show whether to append/overwrite content
public BufferOutput(StringBuilder buffer, Map<String, StringBuilder> namedSlots) {
this(buffer, namedSlots, false);
}
public BufferOutput(StringBuilder buffer, boolean enforceReadOnlyAfterRead) {
this(buffer, null, enforceReadOnlyAfterRead);
}
public BufferOutput(StringBuilder buffer, Map<String, StringBuilder> namedSlots, boolean enforceReadOnlyAfterRead) {
assert buffer != null;
outletStack = new Stack<StringBuilder>();
outletStack.push(buffer);
outletNamesStack = new Stack<String>();
streamsHolder = new XpandStreamsHolder();
if (namedSlots == null) {
this.namedSlots = new HashMap<String, StringBuilder>();
} else {
this.namedSlots = namedSlots;
for (Map.Entry<String, StringBuilder> next : namedSlots.entrySet()) {
streamsHolder.addNamedStream(next.getKey(), next.getValue());
}
}
this.enforceReadOnlyAfterAccess = enforceReadOnlyAfterRead;
}
public void closeFile() {
if (outletStack.size() == 1) {
String msg = "CLOSE FILE without previous openFile";
System.err.println("<<<" + msg);
throw new UnsupportedOperationException(msg);
}
checkAccessPermitted();
outletStack.pop();
outletNamesStack.pop();
}
/**
* Throws an exception if the buffer has been configured not to allow write operations after reading and the stream
* has in fact been accessed.
*/
private void checkAccessPermitted() {
if (enforceReadOnlyAfterAccess && streamsHolder.isAccessed(outletNamesStack.peek())) {
throw new UnsupportedOperationException("Cannot write to a stream after its contents have been accessed");
}
}
public void openFile(String path, String outletName) {
if (!namedSlots.containsKey(outletName)) {
// String msg = "OPEN FILE ('" + path + "', " + outletName + ")";
// System.err.println(">>>" + msg);
// throw new UnsupportedOperationException(msg);
StringBuilder newSlot = new StringBuilder();
namedSlots.put(outletName, newSlot);
streamsHolder.addNamedStream(outletName, newSlot);
}
outletStack.push(namedSlots.get(outletName));
outletNamesStack.push(outletName);
checkAccessPermitted();
assert outletStack.peek() != null;
}
@Override
protected void doAppend(String text) {
outletStack.peek().append(text);
}
public StreamsHolder getNamedStreams() {
return streamsHolder;
}
}