blob: d1cb266e511e3e269b66f5d994af33c1be214a23 [file] [log] [blame]
/*
*
* 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.qpid.server.protocol.v1_0.type.codec;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.qpid.server.protocol.v1_0.codec.*;
import org.apache.qpid.server.protocol.v1_0.type.RestrictedType;
import org.apache.qpid.server.protocol.v1_0.type.messaging.StdDistMode;
import org.apache.qpid.server.protocol.v1_0.type.messaging.TerminusDurability;
import org.apache.qpid.server.protocol.v1_0.type.messaging.TerminusExpiryPolicy;
import org.apache.qpid.server.protocol.v1_0.type.messaging.codec.*;
import org.apache.qpid.server.protocol.v1_0.type.security.SaslCode;
import org.apache.qpid.server.protocol.v1_0.type.security.codec.SaslChallengeConstructor;
import org.apache.qpid.server.protocol.v1_0.type.security.codec.SaslChallengeWriter;
import org.apache.qpid.server.protocol.v1_0.type.security.codec.SaslInitConstructor;
import org.apache.qpid.server.protocol.v1_0.type.security.codec.SaslInitWriter;
import org.apache.qpid.server.protocol.v1_0.type.security.codec.SaslMechanismsConstructor;
import org.apache.qpid.server.protocol.v1_0.type.security.codec.SaslMechanismsWriter;
import org.apache.qpid.server.protocol.v1_0.type.security.codec.SaslOutcomeConstructor;
import org.apache.qpid.server.protocol.v1_0.type.security.codec.SaslOutcomeWriter;
import org.apache.qpid.server.protocol.v1_0.type.security.codec.SaslResponseConstructor;
import org.apache.qpid.server.protocol.v1_0.type.security.codec.SaslResponseWriter;
import org.apache.qpid.server.protocol.v1_0.type.transaction.TransactionErrors;
import org.apache.qpid.server.protocol.v1_0.type.transaction.TxnCapability;
import org.apache.qpid.server.protocol.v1_0.type.transaction.codec.CoordinatorConstructor;
import org.apache.qpid.server.protocol.v1_0.type.transaction.codec.CoordinatorWriter;
import org.apache.qpid.server.protocol.v1_0.type.transaction.codec.DeclareConstructor;
import org.apache.qpid.server.protocol.v1_0.type.transaction.codec.DeclareWriter;
import org.apache.qpid.server.protocol.v1_0.type.transaction.codec.DeclaredConstructor;
import org.apache.qpid.server.protocol.v1_0.type.transaction.codec.DeclaredWriter;
import org.apache.qpid.server.protocol.v1_0.type.transaction.codec.DischargeConstructor;
import org.apache.qpid.server.protocol.v1_0.type.transaction.codec.DischargeWriter;
import org.apache.qpid.server.protocol.v1_0.type.transaction.codec.TransactionalStateConstructor;
import org.apache.qpid.server.protocol.v1_0.type.transaction.codec.TransactionalStateWriter;
import org.apache.qpid.server.protocol.v1_0.type.transport.AmqpError;
import org.apache.qpid.server.protocol.v1_0.type.transport.ConnectionError;
import org.apache.qpid.server.protocol.v1_0.type.transport.LinkError;
import org.apache.qpid.server.protocol.v1_0.type.transport.ReceiverSettleMode;
import org.apache.qpid.server.protocol.v1_0.type.transport.Role;
import org.apache.qpid.server.protocol.v1_0.type.transport.SenderSettleMode;
import org.apache.qpid.server.protocol.v1_0.type.transport.SessionError;
import org.apache.qpid.server.protocol.v1_0.type.transport.codec.*;
public class AMQPDescribedTypeRegistry implements DescribedTypeConstructorRegistry, ValueWriter.Registry
{
private final Map<Object, DescribedTypeConstructor> _constructorRegistry = new HashMap<Object, DescribedTypeConstructor>();
public void register(Object descriptor, DescribedTypeConstructor constructor)
{
_constructorRegistry.put(descriptor, constructor);
}
public void register(Object descriptor, DescribedTypeConstructor constructor, TypeConstructor describedConstructor)
{
_constructorRegistry.put(descriptor, constructor);
}
public DescribedTypeConstructor getConstructor(Object descriptor)
{
return _constructorRegistry.get(descriptor);
}
private AMQPDescribedTypeRegistry()
{
}
public AMQPDescribedTypeRegistry registerTransportLayer()
{
registerTransportConstructors(this);
registerTransportWriters(this);
return this;
}
public AMQPDescribedTypeRegistry registerMessagingLayer()
{
registerMessagingConstructors(this);
registerMessagingWriters(this);
return this;
}
public AMQPDescribedTypeRegistry registerTransactionLayer()
{
registerTransactionsConstructors(this);
registerTransactionsWriters(this);
return this;
}
public AMQPDescribedTypeRegistry registerSecurityLayer()
{
registerSecurityConstructors(this);
registerSecurityWriters(this);
return this;
}
public static AMQPDescribedTypeRegistry newInstance()
{
AMQPDescribedTypeRegistry registry = new AMQPDescribedTypeRegistry();
NullWriter.register(registry);
BooleanWriter.register(registry);
ByteWriter.register(registry);
UnsignedByteWriter.register(registry);
ShortWriter.register(registry);
UnsignedShortWriter.register(registry);
IntegerWriter.register(registry);
UnsignedIntegerWriter.register(registry);
CharWriter.register(registry);
FloatWriter.register(registry);
LongWriter.register(registry);
UnsignedLongWriter.register(registry);
DoubleWriter.register(registry);
TimestampWriter.register(registry);
UUIDWriter.register(registry);
StringWriter.register(registry);
SymbolWriter.register(registry);
BinaryWriter.register(registry);
ByteArrayWriter.register(registry);
ListWriter.register(registry);
MapWriter.register(registry);
SymbolArrayWriter.register(registry);
return registry;
}
private static void registerTransportWriters(final AMQPDescribedTypeRegistry registry)
{
OpenWriter.register(registry);
BeginWriter.register(registry);
AttachWriter.register(registry);
FlowWriter.register(registry);
TransferWriter.register(registry);
DispositionWriter.register(registry);
DetachWriter.register(registry);
EndWriter.register(registry);
CloseWriter.register(registry);
RestrictedTypeValueWriter.register(registry,Role.class);
RestrictedTypeValueWriter.register(registry,SenderSettleMode.class);
RestrictedTypeValueWriter.register(registry,ReceiverSettleMode.class);
ErrorWriter.register(registry);
RestrictedTypeValueWriter.register(registry,AmqpError.class);
RestrictedTypeValueWriter.register(registry,ConnectionError.class);
RestrictedTypeValueWriter.register(registry,SessionError.class);
RestrictedTypeValueWriter.register(registry,LinkError.class);
}
private static void registerMessagingWriters(final AMQPDescribedTypeRegistry registry)
{
HeaderWriter.register(registry);
DeliveryAnnotationsWriter.register(registry);
MessageAnnotationsWriter.register(registry);
PropertiesWriter.register(registry);
ApplicationPropertiesWriter.register(registry);
DataWriter.register(registry);
AmqpSequenceWriter.register(registry);
AmqpValueWriter.register(registry);
FooterWriter.register(registry);
ReceivedWriter.register(registry);
AcceptedWriter.register(registry);
RejectedWriter.register(registry);
ReleasedWriter.register(registry);
ModifiedWriter.register(registry);
SourceWriter.register(registry);
TargetWriter.register(registry);
RestrictedTypeValueWriter.register(registry,TerminusDurability.class);
RestrictedTypeValueWriter.register(registry,TerminusExpiryPolicy.class);
RestrictedTypeValueWriter.register(registry,StdDistMode.class);
DeleteOnCloseWriter.register(registry);
DeleteOnNoLinksWriter.register(registry);
DeleteOnNoMessagesWriter.register(registry);
DeleteOnNoLinksOrMessagesWriter.register(registry);
ExactSubjectFilterWriter.register(registry);
MatchingSubjectFilterWriter.register(registry);
JMSSelectorFilterWriter.register(registry);
NoLocalFilterWriter.register(registry);
}
private static void registerTransactionsWriters(final AMQPDescribedTypeRegistry registry)
{
CoordinatorWriter.register(registry);
DeclareWriter.register(registry);
DischargeWriter.register(registry);
DeclaredWriter.register(registry);
TransactionalStateWriter.register(registry);
RestrictedTypeValueWriter.register(registry,TxnCapability.class);
RestrictedTypeValueWriter.register(registry,TransactionErrors.class);
}
private static void registerSecurityWriters(final AMQPDescribedTypeRegistry registry)
{
SaslMechanismsWriter.register(registry);
SaslInitWriter.register(registry);
SaslChallengeWriter.register(registry);
SaslResponseWriter.register(registry);
SaslOutcomeWriter.register(registry);
RestrictedTypeValueWriter.register(registry,SaslCode.class);
}
private static void registerTransportConstructors(final AMQPDescribedTypeRegistry registry)
{
OpenConstructor.register(registry);
BeginConstructor.register(registry);
AttachConstructor.register(registry);
FlowConstructor.register(registry);
TransferConstructor.register(registry);
DispositionConstructor.register(registry);
DetachConstructor.register(registry);
EndConstructor.register(registry);
CloseConstructor.register(registry);
ErrorConstructor.register(registry);
}
private static void registerMessagingConstructors(final AMQPDescribedTypeRegistry registry)
{
HeaderConstructor.register(registry);
DeliveryAnnotationsConstructor.register(registry);
MessageAnnotationsConstructor.register(registry);
PropertiesConstructor.register(registry);
ApplicationPropertiesConstructor.register(registry);
DataConstructor.register(registry);
AmqpSequenceConstructor.register(registry);
AmqpValueConstructor.register(registry);
FooterConstructor.register(registry);
ReceivedConstructor.register(registry);
AcceptedConstructor.register(registry);
RejectedConstructor.register(registry);
ReleasedConstructor.register(registry);
ModifiedConstructor.register(registry);
SourceConstructor.register(registry);
TargetConstructor.register(registry);
DeleteOnCloseConstructor.register(registry);
DeleteOnNoLinksConstructor.register(registry);
DeleteOnNoMessagesConstructor.register(registry);
DeleteOnNoLinksOrMessagesConstructor.register(registry);
ExactSubjectFilterConstructor.register(registry);
MatchingSubjectFilterConstructor.register(registry);
JMSSelectorFilterConstructor.register(registry);
NoLocalFilterConstructor.register(registry);
}
private static void registerTransactionsConstructors(final AMQPDescribedTypeRegistry registry)
{
CoordinatorConstructor.register(registry);
DeclareConstructor.register(registry);
DischargeConstructor.register(registry);
DeclaredConstructor.register(registry);
TransactionalStateConstructor.register(registry);
}
private static void registerSecurityConstructors(final AMQPDescribedTypeRegistry registry)
{
SaslMechanismsConstructor.register(registry);
SaslInitConstructor.register(registry);
SaslChallengeConstructor.register(registry);
SaslResponseConstructor.register(registry);
SaslOutcomeConstructor.register(registry);
}
private final Map<Class, ValueWriter.Factory> _writerMap = new HashMap<Class, ValueWriter.Factory>();
public <V extends Object> ValueWriter<V> getValueWriter(V value, Map<Class, ValueWriter> localCache)
{
return getValueWriter(value);
}
public <V extends Object> ValueWriter<V> getValueWriter(V value)
{
ValueWriter writer;
Class<? extends Object> clazz = value == null ? Void.TYPE : value.getClass();
ValueWriter.Factory<V> factory = (ValueWriter.Factory<V>) (_writerMap.get(clazz));
if(factory == null)
{
if(value instanceof List)
{
factory = _writerMap.get(List.class);
_writerMap.put(value.getClass(), factory);
writer = factory.newInstance(this);
writer.setValue(value);
}
else if(value instanceof Map)
{
factory = _writerMap.get(Map.class);
_writerMap.put(value.getClass(), factory);
writer = factory.newInstance(this);
writer.setValue(value);
}
else if(value.getClass().isArray())
{
if(RestrictedType.class.isAssignableFrom(value.getClass().getComponentType()))
{
RestrictedType[] restrictedTypes = (RestrictedType[]) value;
Object[] newVals = (Object[]) Array.newInstance(restrictedTypes[0].getValue().getClass(),
restrictedTypes.length);
for(int i = 0; i < restrictedTypes.length; i++)
{
newVals[i] = restrictedTypes[i].getValue();
}
return (ValueWriter<V>) getValueWriter(newVals);
}
// TODO primitive array types
factory = _writerMap.get(List.class);
writer = factory.newInstance(this);
writer.setValue(Arrays.asList((Object[])value));
}
else
{
return null;
}
}
else
{
writer = factory.newInstance(this);
writer.setValue(value);
}
return writer;
}
public <V extends Object> ValueWriter<V> register(Class<V> clazz, ValueWriter.Factory<V> writer)
{
return (ValueWriter<V>) _writerMap.put(clazz, writer);
}
}