/* * Copyright (c) 2014 Oculus Info Inc. http://www.oculusinfo.com/ * * Released under the MIT License. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package com.oculusinfo.binning.io.serialization; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import com.oculusinfo.binning.io.serialization.impl.*; import com.oculusinfo.binning.util.TypeDescriptor; import com.oculusinfo.factory.ConfigurableFactory; import com.oculusinfo.factory.providers.AbstractFactoryProvider; import com.oculusinfo.factory.util.Pair; /** * Basic enum of all the default {@link FactoryProvider} types * availables in the system.<br> * <br> * To create one use the create method for the desired type. Example:<br> * * This isn't really an enum, but acts like one in all ways except * initialization; it is not one to allow us to use loops and generification * during initialization. * * <pre> * <code> * DefaultPyramidIOFactoryProvider.FILE.create(); * </code> * </pre> */ public final class DefaultTileSerializerFactoryProvider extends AbstractFactoryProvider<TileSerializer<?>> implements Comparable<DefaultTileSerializerFactoryProvider> { private static int __currentOrdinal = 0; private static List<DefaultTileSerializerFactoryProvider> __values = new ArrayList<>(); private static Map<String, DefaultTileSerializerFactoryProvider> __reverse = new HashMap<>(); // Specific, un-generified serializer types // Our old pre-avro serializer @Deprecated public static final DefaultTileSerializerFactoryProvider LEGACY = new DefaultTileSerializerFactoryProvider("legacy", new Constructor() { @Override public ConfigurableFactory<? extends TileSerializer<?>> create (ConfigurableFactory<?> parent, List<String> path) { return new com.oculusinfo.binning.io.serialization.impl.BackwardsCompatibilitySerializerFactory(parent, path); } }); // JSON serializers public static final DefaultTileSerializerFactoryProvider DOUBLE_JSON = new DefaultTileSerializerFactoryProvider("double_json", new Constructor() { @Override public ConfigurableFactory<? extends TileSerializer<?>> create (ConfigurableFactory<?> parent, List<String> path) { return new DoubleJsonSerializerFactory(parent, path); } }); public static final DefaultTileSerializerFactoryProvider STRING_INT_PAIR_ARRAY_JSON = new DefaultTileSerializerFactoryProvider("string_int_pair_array_json", new Constructor() { @Override public ConfigurableFactory<? extends TileSerializer<?>> create (ConfigurableFactory<?> parent, List<String> path) { return new StringIntPairArrayJsonSerializerFactory(parent, path); } }); public static final DefaultTileSerializerFactoryProvider STRING_LONG_PAIR_ARRAY_MAP_JSON = new DefaultTileSerializerFactoryProvider("string_long_pair_array_map_json", new Constructor() { @Override public ConfigurableFactory<? extends TileSerializer<?>> create (ConfigurableFactory<?> parent, List<String> path) { return new StringLongPairArrayMapJsonSerializerFactory(parent, path); } }); // Generified serializer types // Single-value serialziers public static final List<DefaultTileSerializerFactoryProvider> PRIMITIVES = Collections.unmodifiableList(new ArrayList<DefaultTileSerializerFactoryProvider>() { private static final long serialVersionUID = 1L; { for (final Class<?> type: PrimitiveAvroSerializer.PRIMITIVE_TYPES) { String name = PrimitiveAvroSerializer.getAvroType(type)+"_avro"; // Note that the double-valued primitive serializer should be the default. add(new DefaultTileSerializerFactoryProvider(name, new Constructor() { @Override public ConfigurableFactory<? extends TileSerializer<?>> create (ConfigurableFactory<?> parent, List<String> path) { return new PrimitiveAvroSerializerFactory<>(parent, path, type); } }, Double.class.equals(type))); } } }); // Array serializers public static final List<DefaultTileSerializerFactoryProvider> PRIMITIVE_ARRAYS = Collections.unmodifiableList(new ArrayList<DefaultTileSerializerFactoryProvider>() { private static final long serialVersionUID = 1L; { for (final Class<?> type: PrimitiveAvroSerializer.PRIMITIVE_TYPES) { String name = PrimitiveAvroSerializer.getAvroType(type)+"_array_avro"; add(new DefaultTileSerializerFactoryProvider(name, new Constructor() { @Override public ConfigurableFactory<? extends TileSerializer<?>> create (ConfigurableFactory<?> parent, List<String> path) { return new PrimitiveArrayAvroSerializerFactory<>(parent, path, type); } })); } } }); // Simple Pair serializers public static final List<DefaultTileSerializerFactoryProvider> PAIRS = Collections.unmodifiableList(new ArrayList<DefaultTileSerializerFactoryProvider>() { private static final long serialVersionUID = 1L; { for (final Class<?> keyType: PrimitiveAvroSerializer.PRIMITIVE_TYPES) { String keyName = PrimitiveAvroSerializer.getAvroType(keyType); for (final Class<?> valueType: PrimitiveAvroSerializer.PRIMITIVE_TYPES) { String valueName = PrimitiveAvroSerializer.getAvroType(valueType); String name = keyName + "_" + valueName + "_pair_avro"; add(new DefaultTileSerializerFactoryProvider(name, new Constructor() { @Override public ConfigurableFactory<? extends TileSerializer<?>> create (ConfigurableFactory<?> parent, List<String> path) { return new PairAvroSerializerFactory<>(parent, path, keyType, valueType); } })); } } } }); // Array of Pair (can be used for maps) serializers public static final List<DefaultTileSerializerFactoryProvider> PAIR_ARRAYS = Collections.unmodifiableList(new ArrayList<DefaultTileSerializerFactoryProvider>() { private static final long serialVersionUID = 1L; { for (final Class<?> keyType: PrimitiveAvroSerializer.PRIMITIVE_TYPES) { String keyName = PrimitiveAvroSerializer.getAvroType(keyType); for (final Class<?> valueType: PrimitiveAvroSerializer.PRIMITIVE_TYPES) { String name = keyName+"_"+PrimitiveAvroSerializer.getAvroType(valueType)+"_pair_array_avro"; add(new DefaultTileSerializerFactoryProvider(name, new Constructor() { @Override public ConfigurableFactory<? extends TileSerializer<?>> create (ConfigurableFactory<?> parent, List<String> path) { return new PairArrayAvroSerializerFactory<>(parent, path, keyType, valueType); } })); } } } }); // Kryo serializers public static final List<DefaultTileSerializerFactoryProvider> KRYO = Collections.unmodifiableList(new ArrayList<DefaultTileSerializerFactoryProvider>() { private static final long serialVersionUID = 1L; { List<Pair<String, TypeDescriptor>> primitives = new ArrayList<>(); for (Class<?> primitive: KryoSerializer.PRIMITIVE_TYPES) { primitives.add(new Pair<String, TypeDescriptor>(primitive.getSimpleName().toLowerCase(), new TypeDescriptor(primitive))); } // Simple types for (final Pair<String, TypeDescriptor> primitive: primitives) { String name = primitive.getFirst()+"_kryo"; add(new DefaultTileSerializerFactoryProvider(name, new Constructor() { @Override public ConfigurableFactory<? extends TileSerializer<?>> create (ConfigurableFactory<?> parent, List<String> path) { return new KryoSerializerFactory<>(parent, path, primitive.getSecond()); } })); } // Array types for (final Pair<String, TypeDescriptor> primitive: primitives) { String name = primitive.getFirst()+"_array_kryo"; add(new DefaultTileSerializerFactoryProvider(name, new Constructor() { @Override public ConfigurableFactory<? extends TileSerializer<?>> create (ConfigurableFactory<?> parent, List<String> path) { return new KryoSerializerFactory<>(parent, path, new TypeDescriptor(List.class, primitive.getSecond())); } })); } // Map types for (final Pair<String, TypeDescriptor> kPrimitive: primitives) { for (final Pair<String, TypeDescriptor> vPrimitive: primitives) { String name = kPrimitive.getFirst()+"_"+vPrimitive.getFirst()+"_pair_array_kryo"; add(new DefaultTileSerializerFactoryProvider(name, new Constructor() { @Override public ConfigurableFactory<? extends TileSerializer<?>> create (ConfigurableFactory<?> parent, List<String> path) { return new KryoSerializerFactory<>(parent, path, new TypeDescriptor(List.class, new TypeDescriptor(Pair.class, kPrimitive.getSecond(), vPrimitive.getSecond()))); } })); } } } }); // ------------------------------------- private final String _name; private final Constructor _constructor; private final int _ordinal; private DefaultTileSerializerFactoryProvider (String name, Constructor constructor) { this(name, constructor, false); } private DefaultTileSerializerFactoryProvider (String name, Constructor constructor, boolean isDefault) { _name = name; _constructor = constructor; _ordinal = __currentOrdinal; __currentOrdinal = __currentOrdinal+1; if (isDefault) { __values.add(0, this); } else { __values.add(this); } __reverse.put(name, this); } public int oridinal () { return _ordinal; } @Override public ConfigurableFactory<? extends TileSerializer<?>> createFactory (List<String> path) { return createFactory(null, path); } @Override public ConfigurableFactory<? extends TileSerializer<?>> createFactory (String name, ConfigurableFactory<?> parent, List<String> path) { return _constructor.create(parent, path); } // Enum mimics @Override public String toString () { return _name; } @Override protected Object clone () throws CloneNotSupportedException { throw new CloneNotSupportedException("Default Tile Serializer Factory Providers should be treated like enums."); } @Override public int compareTo (DefaultTileSerializerFactoryProvider that) { return this._ordinal - that._ordinal; } public final Class<DefaultTileSerializerFactoryProvider> getDeclaringClass () { return DefaultTileSerializerFactoryProvider.class; } @Override public final boolean equals (Object that) { return this == that; } @Override public final int hashCode () { return super.hashCode(); } // Enum static mimics public static DefaultTileSerializerFactoryProvider valueOf (String name) { return __reverse.get(name.toLowerCase()); } public static DefaultTileSerializerFactoryProvider[] values () { return __values.toArray(new DefaultTileSerializerFactoryProvider[__values.size()]); } private static interface Constructor { ConfigurableFactory<? extends TileSerializer<?>> create (ConfigurableFactory<?> parent, List<String> path); } }