/*
* This is eMonocot, a global online biodiversity information resource.
*
* Copyright © 2011–2015 The Board of Trustees of the Royal Botanic Gardens, Kew and The University of Oxford
*
* eMonocot is free software: you can redistribute it and/or modify it under the terms of the
* GNU Affero General Public License as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* eMonocot is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* The complete text of the GNU Affero General Public License is in the source repository as the file
* ‘COPYING’. It is also available from <http://www.gnu.org/licenses/>.
*/
package org.emonocot.model.marshall.json.hibernate;
import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.AnnotationIntrospector;
import com.fasterxml.jackson.databind.Module;
public class HibernateModule extends Module
{
private final String NAME = "HibernateModule";
// Should externalize this somehow
private final static Version VERSION = new Version(0, 1, 0, null); // 0.1.0
/**
* Enumeration that defines all togglable features this module
*/
public enum Feature {
/**
* Whether lazy-loaded object should be forced to be loaded and then serialized
* (true); or serialized as nulls (false).
*<p>
* Default value is false.
*/
FORCE_LAZY_LOADING(false),
/**
* Whether @Transient annotation should be checked or not; if true, will consider
* @Transient to mean that property is to be ignored; if false annotation will
* have no effect.
*<p>
* Default value is true.
*
* @since 0.7.0
*/
USE_TRANSIENT_ANNOTATION(true)
;
final boolean _defaultState;
final int _mask;
/**
* Method that calculates bit set (flags) of all features that
* are enabled by default.
*/
public static int collectDefaults()
{
int flags = 0;
for (Feature f : values()) {
if (f.enabledByDefault()) {
flags |= f.getMask();
}
}
return flags;
}
private Feature(boolean defaultState) {
_defaultState = defaultState;
_mask = (1 << ordinal());
}
public boolean enabledByDefault() { return _defaultState; }
public int getMask() { return _mask; }
}
protected final static int DEFAULT_FEATURES = Feature.collectDefaults();
/**
* Bit flag composed of bits that indicate which
* {@link Feature}s
* are enabled.
*/
protected int _moduleFeatures = DEFAULT_FEATURES;
/*
/**********************************************************************
/* Life-cycle
/**********************************************************************
*/
public HibernateModule() { }
@Override public String getModuleName() { return NAME; }
@Override public Version version() { return VERSION; }
@Override
public void setupModule(SetupContext context)
{
/* First, append annotation introspector (no need to override, esp.
* as we just implement couple of methods)
*/
// Then add serializers we need
AnnotationIntrospector ai = annotationIntrospector();
if (ai != null) {
context.appendAnnotationIntrospector(ai);
}
context.addSerializers(new HibernateSerializers(_moduleFeatures));
}
/**
* Method called during {@link #setupModule}, to create {@link AnnotationIntrospector}
* to register along with module. If null is returned, no introspector is added.
*/
protected AnnotationIntrospector annotationIntrospector() {
HibernateAnnotationIntrospector ai = new HibernateAnnotationIntrospector();
ai.setUseTransient(isEnabled(Feature.USE_TRANSIENT_ANNOTATION));
return ai;
}
/*
/**********************************************************************
/* Extended API, configuration
/**********************************************************************
*/
public HibernateModule enable(Feature f) {
_moduleFeatures |= f.getMask();
return this;
}
public HibernateModule disable(Feature f) {
_moduleFeatures &= ~f.getMask();
return this;
}
public final boolean isEnabled(Feature f) {
return (_moduleFeatures & f.getMask()) != 0;
}
public HibernateModule configure(Feature f, boolean state) {
if (state) {
enable(f);
} else {
disable(f);
}
return this;
}
}