blob: 0617a304fb82d3862f6509a8e85293f63e66e7e8 [file] [log] [blame]
/* $Id$
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.etch.bindings.java.transport.fmt.xml;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Stack;
import org.apache.etch.bindings.java.msg.Field;
import org.apache.etch.bindings.java.msg.Message;
import org.apache.etch.bindings.java.msg.StructValue;
import org.apache.etch.bindings.java.msg.Validator;
import org.apache.etch.bindings.java.msg.ValueFactory;
import org.apache.etch.bindings.java.transport.ArrayValue;
import org.apache.etch.bindings.java.transport.TaggedDataOutput;
import org.apache.etch.bindings.java.transport.fmt.TypeCode;
import org.apache.etch.util.FlexBuffer;
import org.apache.etch.util.core.xml.XmlParser.DefaultTagElement;
import org.apache.etch.util.core.xml.XmlParser.TagElement;
/**
* Description of TaggedDataOutputStream.
*/
@SuppressWarnings("all")
final public class XmlTaggedDataOutput extends XmlTaggedData
implements TaggedDataOutput, XmlTags
{
/**
* Constructs the TaggedDataOutputStream.
*
* @param wtr
* @param vf
*/
public XmlTaggedDataOutput( Writer wtr, ValueFactory vf )
{
super( vf );
this.wtr = wtr;
}
private final Writer wtr;
private final Stack<TagElement> stack = new Stack<TagElement>();
public void startMessage( Message msg )
{
stack.clear();
TagElement te = new DefaultTagElement( MESSAGE_TAG );
te.setAttr( null, STRUCT_TYPE_ATTR, msg.type().getId() );
stack.push( te );
}
public void endMessage( Message msg ) throws IOException
{
TagElement te = stack.pop();
if (!stack.isEmpty())
throw new IOException( "stack sequence error: "+stack );
te.toString( wtr );
}
public void startStruct( StructValue struct )
{
// the caller has already created an element tag for us.
TagElement te = stack.peek();
te.setAttr( null, STRUCT_TYPE_ATTR, struct.type().getId() );
}
public void endStruct( StructValue struct )
{
// stack.pop();
}
public void startArray( ArrayValue array )
{
// the caller has already created an element tag for us.
// TagElement te = stack.peek();
}
public void endArray( ArrayValue array )
{
// stack.pop();
}
public void writeStructElement( Field key, Object value ) throws IOException
{
TagElement te = stack.peek().addTag( ELEMENT_TAG );
te.setAttr( null, KEY_ATTR, key.getId() );
stack.push( te );
writeValue( value );
stack.pop();
}
public void writeArrayElement( Object value ) throws IOException
{
TagElement te = stack.peek().addTag( ELEMENT_TAG );
stack.push( te );
writeValue( value );
stack.pop();
}
public void close() throws IOException
{
wtr.close();
}
@SuppressWarnings("deprecation")
private void writeValue( Object value ) throws IOException
{
// the caller has already created an element for us.
TagElement te = stack.peek();
int type = checkValue( value );
switch (type)
{
case TypeCode.NULL:
{
te.setAttr( null, ELEMENT_TYPE_ATTR, NULL_TYPE );
break;
}
case TypeCode.BOOLEAN_FALSE:
case TypeCode.BOOLEAN_TRUE:
{
te.setAttr( null, ELEMENT_TYPE_ATTR, BOOLEAN_TYPE );
te.addCdata( value.toString() );
break;
}
case TypeCode.BYTE:
case TypeCode.SHORT:
case TypeCode.INT:
{
te.setAttr( null, ELEMENT_TYPE_ATTR, INTEGER_TYPE );
te.addCdata( value.toString() );
break;
}
case TypeCode.LONG:
{
te.setAttr( null, ELEMENT_TYPE_ATTR, LONG_TYPE );
te.addCdata( value.toString() );
break;
}
case TypeCode.FLOAT:
{
te.setAttr( null, ELEMENT_TYPE_ATTR, FLOAT_TYPE );
te.addCdata( value.toString() );
break;
}
case TypeCode.DOUBLE:
{
te.setAttr( null, ELEMENT_TYPE_ATTR, DOUBLE_TYPE );
te.addCdata( value.toString() );
break;
}
case TypeCode.BYTES:
{
byte[] b = (byte[]) value;
te.setAttr( null, ELEMENT_TYPE_ATTR, BYTES_TYPE );
te.addCdata( bytes2string( b ) );
break;
}
case TypeCode.EMPTY_STRING:
case TypeCode.STRING:
{
String s = (String) value;
te.setAttr( null, ELEMENT_TYPE_ATTR, STRING_TYPE );
te.addCdata( s );
break;
}
case TypeCode.ARRAY:
te.setAttr( null, ELEMENT_TYPE_ATTR, ARRAY_TYPE );
if (value instanceof ArrayValue)
writeArray( (ArrayValue) value, null );
else
writeArray( toArrayValue( value, null ), null );
break;
case TypeCode.STRUCT:
case TypeCode.CUSTOM:
{
StructValue struct = vf.exportCustomValue( value );
if (struct == null)
throw new UnsupportedOperationException( "unsupported type "+value.getClass() );
te.setAttr( null, ELEMENT_TYPE_ATTR, CUSTOM_TYPE );
writeStruct( struct );
break;
}
default:
throw new IllegalArgumentException( "unsupported type code "+type );
}
}
private String bytes2string( byte[] buf )
{
StringBuffer sb = new StringBuffer();
for (byte b: buf)
{
if (sb.length() > 0)
sb.append( ' ' );
sb.append( Integer.toString( b, 16 ) );
}
return sb.toString();
}
/**
* @param msg
* @param vf
* @return the xml of the specified message.
* @throws IOException
*/
public static String getXml( Message msg, ValueFactory vf ) throws IOException
{
StringWriter sw = new StringWriter();
TaggedDataOutput tdo = new XmlTaggedDataOutput( sw, vf );
tdo.writeMessage( msg, null );
return sw.toString();
}
public void setBuffer( FlexBuffer msgBuf )
{
// TODO implement setBuffer function
}
public void writeMessage( Message msg, FlexBuffer buf ) throws IOException
{
// TODO implement writeMessage function
}
private void writeStruct( StructValue sv ) throws IOException
{
// TODO implement writeStruct function
}
private void writeArray( ArrayValue av, Validator v ) throws IOException
{
// TODO implement writeArray function
}
}