blob: b3543862e118637e845ec464e863a965912eb260 [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.support;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.etch.bindings.java.msg.Field;
import org.apache.etch.bindings.java.msg.ImportExportHelper;
import org.apache.etch.bindings.java.msg.Message;
import org.apache.etch.bindings.java.msg.StructValue;
import org.apache.etch.bindings.java.msg.Type;
import org.apache.etch.bindings.java.msg.TypeMap;
import org.apache.etch.bindings.java.msg.ValueFactory;
import org.apache.etch.bindings.java.msg.Validator.Level;
import org.apache.etch.bindings.java.util.DateSerializer;
import org.apache.etch.bindings.java.util.ListSerializer;
import org.apache.etch.bindings.java.util.MapSerializer;
import org.apache.etch.bindings.java.util.SetSerializer;
import org.apache.etch.util.URL;
/**
* Default implementation of ValueFactory which provides some
* dynamic type and field support, as well as standard
* value conversions and import and rt.
*/
public class DefaultValueFactory implements ValueFactory
{
private static final String ETCH_RUNTIME_EXCEPTION_TYPE_NAME = "_Etch_RuntimeException";
private static final String ETCH_LIST_TYPE_NAME = "_Etch_List";
private static final String ETCH_MAP_TYPE_NAME = "_Etch_Map";
private static final String ETCH_SET_TYPE_NAME = "_Etch_Set";
private static final String ETCH_DATETIME_TYPE_NAME = "_Etch_Datetime";
private static final String ETCH_AUTH_EXCEPTION_TYPE_NAME = "_Etch_AuthException";
private static final String ETCH_EXCEPTION_MESSAGE_NAME = "_exception";
private static final String MSG_FIELD_NAME = "msg";
private static final String MESSAGE_ID_FIELD_NAME = "_messageId";
private static final String IN_REPLY_TO_FIELD_NAME = "_inReplyTo";
private static final String RESULT_FIELD_NAME = "result";
/**
* Initializes the standard types and fields needed by
* all etch generated value factories.
* @param types
* @param class2type
*/
public static final void init( TypeMap types, Class2TypeMap class2type )
{
RuntimeExceptionSerializer.init(
types.get( ETCH_RUNTIME_EXCEPTION_TYPE_NAME ), class2type );
ListSerializer.init(
types.get( ETCH_LIST_TYPE_NAME ), class2type );
MapSerializer.init(
types.get( ETCH_MAP_TYPE_NAME ), class2type );
SetSerializer.init(
types.get( ETCH_SET_TYPE_NAME ), class2type );
DateSerializer.init(
types.get( ETCH_DATETIME_TYPE_NAME ), class2type );
AuthExceptionSerializer.init(
types.get( ETCH_AUTH_EXCEPTION_TYPE_NAME ), class2type );
// ------------------ _mt__Etch_AuthException ------------------
{
final Type t = types.get( ETCH_EXCEPTION_MESSAGE_NAME );
t.putValidator( _mf_result, Validator_RuntimeException.get() );
t.putValidator( _mf__messageId, Validator_long.get( 0 ) );
t.putValidator( _mf__inReplyTo, Validator_long.get( 0 ) );
}
}
/**
* The msg field of the standard unchecked exception.
*/
public static final Field _mf_msg = new Field( MSG_FIELD_NAME );
/**
* The well-known _messageId field.
*/
public static final Field _mf__messageId = new Field( MESSAGE_ID_FIELD_NAME );
/**
* The well-known _inReplyTo field.
*/
public static final Field _mf__inReplyTo = new Field( IN_REPLY_TO_FIELD_NAME );
/**
* The well-known result field.
*/
public static final Field _mf_result = new Field( RESULT_FIELD_NAME );
///////////////////////
// ValueFactory impl //
///////////////////////
/**
* Constructs the DefaultValueFactory.
* @param uri uri of this transport stack.
* @param types the type map for this instance of value factory.
* @param class2type the class to type map for this instance of value factory.
*/
public DefaultValueFactory( String uri, TypeMap types,
Class2TypeMap class2type )
{
URL u = new URL( uri );
level = Level.valueOf( u.getTerm( "DefaultValueFactory.level", "FULL" ) );
this.types = types;
this.class2type = class2type;
_mt__Etch_RuntimeException = types.get( ETCH_RUNTIME_EXCEPTION_TYPE_NAME );
_mt__Etch_List = types.get( ETCH_LIST_TYPE_NAME );
_mt__Etch_Map = types.get( ETCH_MAP_TYPE_NAME );
_mt__Etch_Set = types.get( ETCH_SET_TYPE_NAME );
_mt__Etch_Datetime = types.get( ETCH_DATETIME_TYPE_NAME );
_mt__Etch_AuthException = types.get( ETCH_AUTH_EXCEPTION_TYPE_NAME );
_mt__exception = types.get( ETCH_EXCEPTION_MESSAGE_NAME );
}
private final TypeMap types;
private final TypeMap dynamicTypes = new TypeMap();
private final Class2TypeMap class2type;
private final Type _mt__Etch_RuntimeException;
private final Type _mt__Etch_List;
private final Type _mt__Etch_Map;
private final Type _mt__Etch_Set;
private final Type _mt__Etch_Datetime;
private final Type _mt__Etch_AuthException;
private final Type _mt__exception;
/**
* @return the standard _mt__Etch_RuntimeException.
*/
public final Type get_mt__Etch_RuntimeException()
{
return _mt__Etch_RuntimeException;
}
/**
* @return the standard _mt__Etch_List.
*/
public final Type get_mt__Etch_List()
{
return _mt__Etch_List;
}
/**
* @return the standard _mt__Etch_Map.
*/
public final Type get_mt__Etch_Map()
{
return _mt__Etch_Map;
}
/**
* @return the standard _mt__Etch_Set.
*/
public final Type get_mt__Etch_Set()
{
return _mt__Etch_Set;
}
/**
* @return the standard _mt__Etch_Datetime.
*/
public final Type get_mt__Etch_Datetime()
{
return _mt__Etch_Datetime;
}
/**
* @return the standard _mt__Etch_AuthException.
*/
public final Type get_mt__Etch_AuthException()
{
return _mt__Etch_AuthException;
}
public final Type get_mt__exception()
{
return _mt__exception;
}
/**
* Adds a value factory as a mixin to this one.
* @param vf
*/
protected void addMixin( ValueFactory vf )
{
ValueFactory[] newMixins = new ValueFactory[mixins.length+1];
System.arraycopy( mixins, 0, newMixins, 0, mixins.length );
newMixins[mixins.length] = vf;
mixins = newMixins;
}
private ValueFactory[] mixins = {};
public final Type getType( Integer id )
{
Type type = types.get( id );
if (type != null)
return type;
for (ValueFactory vf: mixins)
if ((type = vf.getType( id )) != null)
return type;
synchronized (dynamicTypes)
{
return dynamicTypes.get( id );
}
}
public final Type getType( String name )
{
Type type = types.get( name );
if (type != null)
return type;
for (ValueFactory vf: mixins)
if ((type = vf.getType( name )) != null)
return type;
synchronized (dynamicTypes)
{
return dynamicTypes.get( name );
}
}
public void addType( Type type )
{
try
{
synchronized (dynamicTypes)
{
dynamicTypes.add( type );
}
}
catch ( IllegalArgumentException e )
{
// ignore.
}
}
public final Set<Type> getTypes()
{
Set<Type> values = types.values();
for (ValueFactory vf: mixins)
values.addAll( vf.getTypes() );
synchronized (dynamicTypes)
{
values.addAll( dynamicTypes.values() );
}
return values;
}
public final StructValue exportCustomValue( Object value )
{
Class<?> clss = value.getClass();
Type type = getCustomStructType( clss );
if (type == null && clss == StructValue.class)
{
StructValue struct = (StructValue) value;
type = struct.type();
}
if (type == null)
{
if (Throwable.class.isAssignableFrom( clss ))
type = _mt__Etch_RuntimeException;
else if (List.class.isAssignableFrom( clss ))
type = _mt__Etch_List;
else if (Map.class.isAssignableFrom( clss ))
type = _mt__Etch_Map;
else if (Set.class.isAssignableFrom( clss ))
type = _mt__Etch_Set;
else
return null;
}
ImportExportHelper helper = type.getImportExportHelper();
if (helper == null)
return null;
return helper.exportValue( this, value );
}
public final Object importCustomValue( StructValue struct )
{
ImportExportHelper helper = struct.type().getImportExportHelper();
if (helper == null)
return null;
return helper.importValue( struct );
}
public final Type getCustomStructType( Class<?> c )
{
Type type = class2type.get( c );
if (type != null)
return type;
for (ValueFactory vf: mixins)
if ((type = vf.getCustomStructType( c )) != null)
return type;
return null;
}
/////////////////////
// STRING ENCODING //
/////////////////////
public String getStringEncoding()
{
return "utf-8";
}
////////////////
// MESSAGE ID //
////////////////
public final Long getMessageId( Message msg )
{
return (Long) msg.get( _mf__messageId );
}
public final void setMessageId( Message msg, Long msgid )
{
msg.put( _mf__messageId, msgid );
}
public Field get_mf__messageId()
{
return _mf__messageId;
}
/////////////////
// IN REPLY TO //
/////////////////
public final Long getInReplyTo( Message msg )
{
return (Long) msg.get( _mf__inReplyTo );
}
public final void setInReplyTo( Message msg, Long msgid )
{
msg.put( _mf__inReplyTo, msgid );
}
public Field get_mf__inReplyTo()
{
return _mf__inReplyTo;
}
public void lockDynamicTypes()
{
dynamicTypes.lock();
}
public Level getLevel()
{
return level;
}
public Level setLevel( Level level )
{
Level oldLevel = this.level;
this.level = level;
return oldLevel;
}
private Level level = Level.FULL;
public void unlockDynamicTypes()
{
// TODO implement dynamicTypes.unlock();
throw new UnsupportedOperationException( "unlockDynamicTypes not implemented" );
}
}