/*******************************************************************************
* Copyright (c) 2007, 2014 compeople AG and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* compeople AG - initial API and implementation
*******************************************************************************/
package org.eclipse.riena.internal.communication.factory.hessian.serializer;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import com.caucho.hessian.io.AbstractSerializerFactory;
import com.caucho.hessian.io.Deserializer;
import com.caucho.hessian.io.HessianProtocolException;
import com.caucho.hessian.io.Serializer;
import com.caucho.hessian.io.SerializerFactory;
import org.eclipse.riena.communication.factory.hessian.serializer.AbstractRienaSerializerFactory;
import org.eclipse.riena.core.util.Orderer;
import org.eclipse.riena.core.util.ReflectionUtils;
import org.eclipse.riena.core.wire.InjectExtension;
import org.eclipse.riena.core.wire.Wire;
import org.eclipse.riena.internal.communication.factory.hessian.Activator;
/**
* The {@code RienaSerializerFactory} is a delegating
* {@code AbstractSerializerFactory}. It�s main purpose is to act like a regular
* {@code AbstractSerializerFactory} but internally (not visible to hessian) it
* manages a configurable, ordered list of
* {@code AbstractRienaSerializerFactory}.
*
* @since 4.0
*/
public class RienaSerializerFactory extends AbstractSerializerFactory {
private List<AbstractRienaSerializerFactory> serializerFactories = Collections.emptyList();
public RienaSerializerFactory() {
Wire.instance(this).andStart(Activator.getDefault().getContext());
}
@Override
public Deserializer getDeserializer(final Class cl) throws HessianProtocolException {
synchronized (this) {
for (final AbstractSerializerFactory serializerFactory : serializerFactories) {
final Deserializer deserializer = serializerFactory.getDeserializer(cl);
if (deserializer != null) {
return deserializer;
}
}
}
return null;
}
@Override
public Serializer getSerializer(final Class cl) throws HessianProtocolException {
synchronized (this) {
for (final AbstractSerializerFactory serializerFactory : serializerFactories) {
final Serializer serializer = serializerFactory.getSerializer(cl);
if (serializer != null) {
return serializer;
}
}
}
return null;
}
@InjectExtension
public void update(final ISerializerFactoryExtension[] serializerFactoryDefinitions) {
final Orderer<AbstractRienaSerializerFactory> orderer = new Orderer<AbstractRienaSerializerFactory>();
for (final ISerializerFactoryExtension serializerFactoryExtension : serializerFactoryDefinitions) {
orderer.add(serializerFactoryExtension.newSerializerFactory(), serializerFactoryExtension.getName(),
serializerFactoryExtension.getPreSerializerFactories(),
serializerFactoryExtension.getPostSerializerFactories());
}
// order ..
final List<AbstractRienaSerializerFactory> tempOrdered = orderer.getOrderedObjects();
// .. get those static maps from the hessian {@code SerializerFactory} ..
final HashMap<Class<?>, ?> staticDeserializerMap = ReflectionUtils.getHidden(SerializerFactory.class,
"_staticDeserializerMap"); //$NON-NLS-1$
final HashMap<Class<?>, ?> staticSerializerMap = ReflectionUtils.getHidden(SerializerFactory.class,
"_staticSerializerMap"); //$NON-NLS-1$
synchronized (this) {
// .. tweak the static hessian maps
for (final AbstractRienaSerializerFactory serializerFactory : tempOrdered) {
for (final Class<?> replaced : serializerFactory.getReplacedDeserializerTypes()) {
staticDeserializerMap.remove(replaced);
}
for (final Class<?> replaced : serializerFactory.getReplacedSerializerTypes()) {
staticSerializerMap.remove(replaced);
}
}
// .. and make active
serializerFactories = tempOrdered;
}
}
}