/*
* Copyright [2011] [Pettersen Consulting]
*
* 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 com.edb.os.xstream;
import java.io.Writer;
import java.util.Stack;
import com.edb.os.xstream.writer.ClassWriter;
import com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
/**
* @author Oystein Pettersen
*
*/
public class JavaWriter implements ExtendedHierarchicalStreamWriter {
private final Writer writer;
private Stack<ClassWriter> stack;
private int currentDepth = 0;
private int paramNameIndex = 0;
private ClassWriter currentParent = null;
private ClassWriterFactory classWriterFactory;
public JavaWriter(Writer writer, ClassWriterFactory classWriterFactory) {
this.writer = writer;
stack = new Stack<ClassWriter>();
this.classWriterFactory = classWriterFactory;
}
public JavaWriter(Writer writer) {
this(writer, new ClassWriterFactory());
}
/* (non-Javadoc)
* @see com.thoughtworks.xstream.io.HierarchicalStreamWriter#startNode(java.lang.String)
*
* This gets called with special stuff such as the inner list for a list implementation
*/
public void startNode(String name) {
// get the current parent to create the correct class writer for this element
ClassWriter childWriter = currentParent.createChildWriter(name, currentDepth++);
stack.add(childWriter);
}
public void addAttribute(String name, String value) {
System.out.println("addAttribute - name: " + name + " value: " + value);
}
public void setValue(String text) {
ClassWriter dataClass = stack.peek();
dataClass.setValue(text);
}
public void endNode() {
currentDepth--;
ClassWriter poppedElement = stack.pop();
// check if we are at the top
if (stack.isEmpty()) {
currentParent = null;
// write the return statement
poppedElement.writeReturnStatement(writer);
} else {
// check if the pop results to moving up one level, if so set a new current parent
// if the next item on the stack as a different index then we are moving up, so set the parent to the next level
if (poppedElement.depthIndex() != stack.peek().depthIndex()) {
currentParent = stack.peek();
}
currentParent.add(poppedElement, writer);
}
}
public void flush() {
}
public void close() {
}
public HierarchicalStreamWriter underlyingWriter() {
return null;
}
@SuppressWarnings("rawtypes")
public void startNode(String name, Class clazz) {
ClassWriter classWriter;
// determine the type of class provided
// set initial parent if first run
if (stack.isEmpty()) {
classWriter = classWriterFactory.create(name, clazz, currentDepth, paramNameIndex++);
currentParent = classWriter;
}
else {
classWriter = currentParent.createChildWriter(name, clazz, currentDepth, paramNameIndex);
}
stack.push(classWriter);
currentDepth++;
paramNameIndex++;
// inform the writer that it has been located. It is up to it if it needs to write something (like new) to the writer
classWriter.create(writer);
}
}