/* * (C) Copyright 2014 Nuxeo SA (http://nuxeo.com/) and others. * * 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. * * Contributors: * dmetzler * Vladimir Pasquir <vpasquier@nuxeo.com> */ package org.nuxeo.ecm.webengine; import java.io.IOException; import org.codehaus.jackson.JsonFactory; import org.codehaus.jackson.JsonGenerationException; import org.codehaus.jackson.JsonGenerator; import org.codehaus.jackson.Version; import org.codehaus.jackson.map.JsonSerializer; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.map.SerializationConfig; import org.codehaus.jackson.map.SerializerProvider; import org.codehaus.jackson.map.introspect.BasicBeanDescription; import org.codehaus.jackson.map.module.SimpleModule; import org.codehaus.jackson.map.ser.BeanSerializer; import org.codehaus.jackson.map.ser.BeanSerializerModifier; import org.nuxeo.runtime.api.Framework; /** * @since 6.0 */ public class JsonFactoryManagerImpl implements JsonFactoryManager { public static final String REST_STACK_DISPLAY = "org.nuxeo.rest.stack" + ".enable"; protected boolean stackDisplay; public JsonFactoryManagerImpl() { stackDisplay = Framework.isBooleanPropertyTrue(REST_STACK_DISPLAY); } private static class ThrowableSerializer extends BeanSerializer { public ThrowableSerializer(BeanSerializer src) { super(src); } @Override protected void serializeFields(Object bean, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException { serializeClassName(bean, jgen, provider); super.serializeFields(bean, jgen, provider); } @Override protected void serializeFieldsFiltered(Object bean, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException { serializeClassName(bean, jgen, provider); super.serializeFieldsFiltered(bean, jgen, provider); } protected void serializeClassName(Object bean, JsonGenerator jgen, SerializerProvider provider) throws JsonGenerationException, IOException { jgen.writeFieldName("className"); jgen.writeString(bean.getClass().getName()); } } private JsonFactory factory; @Override public JsonFactory getJsonFactory() { if (factory == null) { factory = createFactory(); } return factory; } @Override public JsonFactory createFactory() { JsonFactory factory = new JsonFactory(); final ObjectMapper oc = new ObjectMapper(factory); final SimpleModule module = new SimpleModule("webengine", Version.unknownVersion()) { @Override public void setupModule(SetupContext context) { super.setupModule(context); context.addBeanSerializerModifier(new BeanSerializerModifier() { @Override public JsonSerializer<?> modifySerializer(SerializationConfig config, BasicBeanDescription beanDesc, JsonSerializer<?> serializer) { if (!Throwable.class.isAssignableFrom(beanDesc.getBeanClass())) { return super.modifySerializer(config, beanDesc, serializer); } return new ThrowableSerializer((BeanSerializer) serializer); } }); } }; oc.registerModule(module); factory.setCodec(oc); return factory; } @Override public boolean toggleStackDisplay() { return stackDisplay = !stackDisplay; } public boolean isStackDisplay() { return stackDisplay; } }