package com.oracle.appbundler;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.Stack;
/**
* Class that handles Info.plist files. Started because of Java's brain dead
* XML implementation doesn't have simple indentation support, but evolved
* from there to hide some of the Info.plist innards for cleaner code in the
* AppBundlerTask object.
* @author fry at processing dot org
*/
class PropertyLister {
static private final String XML_HEADER = "<?xml version=\"1.0\" ?>";
static private final String PLIST_DTD = "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">";
static private final String PLIST_TAG = "plist";
static private final String PLIST_VERSION_ATTRIBUTE = "version";
static private final String DICT_TAG = "dict";
static private final String KEY_TAG = "key";
static private final String ARRAY_TAG = "array";
static private final String STRING_TAG = "string";
PrintWriter writer;
String indentSpaces = " ";
Stack<String> elements = new Stack<>();
public PropertyLister(OutputStream output) throws UnsupportedEncodingException {
OutputStreamWriter osw = new OutputStreamWriter(output, "UTF-8");
writer = new PrintWriter(osw);
}
void writeStartDocument() {
writer.println(XML_HEADER);
writer.println(PLIST_DTD);
// Begin root 'plist' element
writeStartElement(PLIST_TAG, PLIST_VERSION_ATTRIBUTE, "1.0");
}
void writeEndDocument() {
// End root 'plist' element
writeEndElement();
writer.flush();
writer.close();
}
void writeStartElement(String element, String... args) {
emitIndent();
writer.print("<" + element);
for (int i = 0; i < args.length; i += 2) {
String attr = args[i];
String value = args[i+1];
writer.print(" " + attr + "=\"" + value + "\"");
}
writer.println(">");
elements.push(element);
}
void writeStartElement(String element) {
emitIndent();
writer.println("<" + element + ">");
elements.push(element);
}
void writeStartDictElement() {
writeStartElement(DICT_TAG);
}
void writeStartArrayElement() {
writeStartElement(ARRAY_TAG);
}
void writeEndElement() {
emitOutdent();
writer.println("</" + elements.pop() + ">");
}
void writeKey(String key) {
emitSingle(KEY_TAG, key);
}
void writeString(String value) {
emitSingle(STRING_TAG, value);
}
void writeBoolean(boolean value) {
emitIndent();
writer.println("<" + (value ? "true" : "false") + "/>");
}
void writeProperty(String property, String value) {
writeKey(property);
writeString(value);
}
private void emitSingle(String tag, String content) {
emitIndent();
writer.println("<" + tag + ">" + content + "</" + tag + ">");
}
private void emitIndent() {
for (int i = 0; i < elements.size(); i++) {
writer.print(indentSpaces);
}
}
private void emitOutdent() {
for (int i = 0; i < elements.size() - 1; i++) {
writer.print(indentSpaces);
}
}
}