| package org.codehaus.jackson.map.ser.std; |
| |
| import java.io.IOException; |
| import java.lang.reflect.InvocationTargetException; |
| import java.lang.reflect.Type; |
| |
| import org.codehaus.jackson.JsonGenerationException; |
| import org.codehaus.jackson.JsonGenerator; |
| import org.codehaus.jackson.JsonNode; |
| import org.codehaus.jackson.map.*; |
| import org.codehaus.jackson.map.annotate.JacksonStdImpl; |
| import org.codehaus.jackson.node.JsonNodeFactory; |
| import org.codehaus.jackson.node.ObjectNode; |
| import org.codehaus.jackson.schema.SchemaAware; |
| import org.codehaus.jackson.type.JavaType; |
| |
| /** |
| * Base class used by all standard serializers. Provides some convenience |
| * methods for implementing {@link SchemaAware} |
| * |
| * @since 1.9 (renamed from 'org.codehaus.jackson.map.ser.SerializerBase') |
| */ |
| public abstract class SerializerBase<T> |
| extends JsonSerializer<T> |
| implements SchemaAware |
| { |
| protected final Class<T> _handledType; |
| |
| protected SerializerBase(Class<T> t) { |
| _handledType = t; |
| } |
| |
| /** |
| * @since 1.7 |
| */ |
| @SuppressWarnings("unchecked") |
| protected SerializerBase(JavaType type) { |
| _handledType = (Class<T>) type.getRawClass(); |
| } |
| |
| /** |
| * Alternate constructor that is (alas!) needed to work |
| * around kinks of generic type handling |
| */ |
| @SuppressWarnings("unchecked") |
| protected SerializerBase(Class<?> t, boolean dummy) { |
| _handledType = (Class<T>) t; |
| } |
| |
| @Override |
| public final Class<T> handledType() { return _handledType; } |
| |
| @Override |
| public abstract void serialize(T value, JsonGenerator jgen, SerializerProvider provider) |
| throws IOException, JsonGenerationException; |
| |
| /** |
| * Note: since Jackson 1.9, default implementation claims type is "string" |
| */ |
| @Override |
| public JsonNode getSchema(SerializerProvider provider, Type typeHint) |
| throws JsonMappingException |
| { |
| return createSchemaNode("string"); |
| } |
| |
| protected ObjectNode createObjectNode() { |
| return JsonNodeFactory.instance.objectNode(); |
| } |
| |
| protected ObjectNode createSchemaNode(String type) |
| { |
| ObjectNode schema = createObjectNode(); |
| schema.put("type", type); |
| return schema; |
| } |
| |
| protected ObjectNode createSchemaNode(String type, boolean isOptional) |
| { |
| ObjectNode schema = createSchemaNode(type); |
| // as per [JACKSON-563]. Note that 'required' defaults to false |
| if (!isOptional) { |
| schema.put("required", !isOptional); |
| } |
| return schema; |
| } |
| |
| /** |
| * Method that can be called to determine if given serializer is the default |
| * serializer Jackson uses; as opposed to a custom serializer installed by |
| * a module or calling application. Determination is done using |
| * {@link JacksonStdImpl} annotation on serializer class. |
| * |
| * @since 1.7 |
| */ |
| protected boolean isDefaultSerializer(JsonSerializer<?> serializer) |
| { |
| return (serializer != null && serializer.getClass().getAnnotation(JacksonStdImpl.class) != null); |
| } |
| |
| /** |
| * Method that will modify caught exception (passed in as argument) |
| * as necessary to include reference information, and to ensure it |
| * is a subtype of {@link IOException}, or an unchecked exception. |
| *<p> |
| * Rules for wrapping and unwrapping are bit complicated; essentially: |
| *<ul> |
| * <li>Errors are to be passed as is (if uncovered via unwrapping) |
| * <li>"Plain" IOExceptions (ones that are not of type |
| * {@link JsonMappingException} are to be passed as is |
| *</ul> |
| */ |
| public void wrapAndThrow(SerializerProvider provider, |
| Throwable t, Object bean, String fieldName) |
| throws IOException |
| { |
| /* 05-Mar-2009, tatu: But one nasty edge is when we get |
| * StackOverflow: usually due to infinite loop. But that |
| * usually gets hidden within an InvocationTargetException... |
| */ |
| while (t instanceof InvocationTargetException && t.getCause() != null) { |
| t = t.getCause(); |
| } |
| // Errors and "plain" IOExceptions to be passed as is |
| if (t instanceof Error) { |
| throw (Error) t; |
| } |
| // Ditto for IOExceptions... except for mapping exceptions! |
| boolean wrap = (provider == null) || provider.isEnabled(SerializationConfig.Feature.WRAP_EXCEPTIONS); |
| if (t instanceof IOException) { |
| if (!wrap || !(t instanceof JsonMappingException)) { |
| throw (IOException) t; |
| } |
| } else if (!wrap) { // [JACKSON-407] -- allow disabling wrapping for unchecked exceptions |
| if (t instanceof RuntimeException) { |
| throw (RuntimeException) t; |
| } |
| } |
| // [JACKSON-55] Need to add reference information |
| throw JsonMappingException.wrapWithPath(t, bean, fieldName); |
| } |
| |
| public void wrapAndThrow(SerializerProvider provider, |
| Throwable t, Object bean, int index) |
| throws IOException |
| { |
| while (t instanceof InvocationTargetException && t.getCause() != null) { |
| t = t.getCause(); |
| } |
| // Errors are to be passed as is |
| if (t instanceof Error) { |
| throw (Error) t; |
| } |
| // Ditto for IOExceptions... except for mapping exceptions! |
| boolean wrap = (provider == null) || provider.isEnabled(SerializationConfig.Feature.WRAP_EXCEPTIONS); |
| if (t instanceof IOException) { |
| if (!wrap || !(t instanceof JsonMappingException)) { |
| throw (IOException) t; |
| } |
| } else if (!wrap) { // [JACKSON-407] -- allow disabling wrapping for unchecked exceptions |
| if (t instanceof RuntimeException) { |
| throw (RuntimeException) t; |
| } |
| } |
| // [JACKSON-55] Need to add reference information |
| throw JsonMappingException.wrapWithPath(t, bean, index); |
| } |
| |
| /** |
| * @deprecated Use version that takes <code>SerializerProvider</code> instead. |
| */ |
| @Deprecated |
| public void wrapAndThrow(Throwable t, Object bean, String fieldName) throws IOException { |
| wrapAndThrow(null, t, bean, fieldName); |
| } |
| |
| /** |
| * @deprecated Use version that takes <code>SerializerProvider</code> instead. |
| */ |
| @Deprecated |
| public void wrapAndThrow(Throwable t, Object bean, int index) throws IOException { |
| wrapAndThrow(null, t, bean, index); |
| } |
| } |