/*
* Copyright 2015 Martin Grotzke
*
* 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 de.javakaffee.web.msm.serializer.kryo;
import com.esotericsoftware.kryo.ClassResolver;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.ReferenceResolver;
import com.esotericsoftware.kryo.StreamFactory;
import com.esotericsoftware.kryo.util.DefaultClassResolver;
import com.esotericsoftware.kryo.util.DefaultStreamFactory;
import com.esotericsoftware.kryo.util.MapReferenceResolver;
import org.objenesis.strategy.InstantiatorStrategy;
/**
* Builder for the {@link Kryo} instance, users can configure the builder via the
* {@link KryoBuilderConfiguration}.
*
* @author <a href="mailto:martin.grotzke@javakaffee.de">Martin Grotzke</a>
*/
public class KryoBuilder {
private ClassResolver classResolver;
private ReferenceResolver referenceResolver;
private StreamFactory streamFactory;
/**
* @return the configured {@link Kryo} instance.
*/
public Kryo build() {
return createKryo(
classResolver != null ? classResolver : new DefaultClassResolver(),
referenceResolver != null ? referenceResolver : new MapReferenceResolver(),
streamFactory != null ? streamFactory : new DefaultStreamFactory()
);
}
protected Kryo createKryo(ClassResolver classResolver, ReferenceResolver referenceResolver, StreamFactory streamFactory) {
Kryo kryo = new Kryo(classResolver, referenceResolver, streamFactory);
// Maintain Kryo compatibility (pre version 4) - can turn this off by calling withOptimizedGenerics(false)
kryo.getFieldSerializerConfig().setOptimizedGenerics(true);
return kryo;
}
public KryoBuilder withClassResolver(final ClassResolver classResolver) {
this.classResolver = classResolver;
return this;
}
public KryoBuilder withReferenceResolver(final ReferenceResolver referenceResolver) {
this.referenceResolver = referenceResolver;
return this;
}
public KryoBuilder withStreamFactory(final StreamFactory streamFactory) {
this.streamFactory = streamFactory;
return this;
}
protected Kryo buildFrom(KryoBuilder target) {
// we must transfer local fields to the target which creates the Kryo instance.
// yes, it's a bit hackish, but if s.o. calls the same method twice with different arguments it's kind of bullshit in...
if(target.classResolver == null) target.classResolver = classResolver;
if(target.referenceResolver == null) target.referenceResolver = referenceResolver;
if(target.streamFactory == null) target.streamFactory = streamFactory;
return target.build();
}
public KryoBuilder withRegistrationRequired(final boolean registrationRequired) {
return new KryoBuilder() {
@Override
public Kryo build() {
Kryo k = this.buildFrom(KryoBuilder.this);
k.setRegistrationRequired(registrationRequired);
return k;
}
};
}
public KryoBuilder withInstantiatorStrategy(final InstantiatorStrategy instantiatorStrategy) {
return new KryoBuilder() {
@Override
public Kryo build() {
Kryo k = this.buildFrom(KryoBuilder.this);
k.setInstantiatorStrategy(instantiatorStrategy);
return k;
}
};
}
public KryoBuilder withReferences(final boolean references) {
return new KryoBuilder() {
@Override
public Kryo build() {
Kryo k = this.buildFrom(KryoBuilder.this);
k.setReferences(references);
return k;
}
};
}
public KryoBuilder withKryoCustomization(final KryoCustomization kryoCustomization) {
return new KryoBuilder() {
@Override
public Kryo build() {
Kryo k = this.buildFrom(KryoBuilder.this);
kryoCustomization.customize(k);
return k;
}
};
}
public KryoBuilder withOptimizedGenerics(final boolean optimizedGenerics) {
return new KryoBuilder() {
@Override
public Kryo build() {
Kryo k = this.buildFrom(KryoBuilder.this);
k.getFieldSerializerConfig().setOptimizedGenerics(optimizedGenerics);
return k;
}
};
}
}