001/* 
002 * JKNIV, whinstone one contract to access your database.
003 * 
004 * Copyright (C) 2017, the original author or authors.
005 *
006 * This library is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either
009 * version 2.1 of the License.
010 * 
011 * This library is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014 * Lesser General Public License for more details.
015 * 
016 * You should have received a copy of the GNU Lesser General Public
017 * License along with this library; if not, write to the Free Software Foundation, Inc., 
018 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
019 */
020package net.sf.jkniv.whinstone.cassandra;
021
022import java.lang.reflect.Field;
023import java.util.HashMap;
024import java.util.Map;
025
026import org.slf4j.Logger;
027import org.slf4j.LoggerFactory;
028
029import com.datastax.driver.core.Cluster;
030import com.datastax.driver.core.TypeCodec;
031
032import net.sf.jkniv.reflect.beans.ObjectProxy;
033import net.sf.jkniv.reflect.beans.ObjectProxyFactory;
034
035/**
036 * Registry codec for Cassandra
037 * 
038 * @author Alisson Gomes
039 * @since 0.6.0
040 *
041 */
042@SuppressWarnings("rawtypes")
043public class RegisterCodec
044{
045    private static final Logger        LOG = LoggerFactory.getLogger(RegisterCodec.class);
046    public final Map<String, CodecMap> codecs;
047    
048    public RegisterCodec()
049    {
050        codecs = new HashMap<String, CodecMap>();
051        codecs.put("arrays.DoubleArrayCodec", new CodecMap("com.datastax.driver.extras.codecs.arrays.DoubleArrayCodec"));
052        codecs.put("arrays.FloatArrayCodec", new CodecMap("com.datastax.driver.extras.codecs.arrays.FloatArrayCodec"));
053        codecs.put("arrays.IntArrayCodec", new CodecMap("com.datastax.driver.extras.codecs.arrays.IntArrayCodec"));
054        codecs.put("arrays.LongArrayCodec", new CodecMap("com.datastax.driver.extras.codecs.arrays.LongArrayCodec"));
055        codecs.put("arrays.ObjectArrayCodec", new CodecMap("com.datastax.driver.extras.codecs.arrays.ObjectArrayCodec"));
056        
057        codecs.put("date.SimpleDateCodec", new CodecMap("com.datastax.driver.extras.codecs.date.SimpleDateCodec"));
058        codecs.put("date.SimpleTimestampCodec", new CodecMap("com.datastax.driver.extras.codecs.date.SimpleTimestamp"));
059        
060        codecs.put("enums.EnumNameCodec", new CodecMap("com.datastax.driver.extras.codecs.enums.EnumNameCodec"));
061        codecs.put("enums.EnumOrdinalCodec", new CodecMap("com.datastax.driver.extras.codecs.enums.EnumOrdinalCodec"));
062        
063        codecs.put("guava.OptionalCodec", new CodecMap("com.datastax.driver.extras.codecs.guava.OptionalCodec"));
064        
065        codecs.put("jdk8.InstantCodec", new CodecMap("com.datastax.driver.extras.codecs.jdk8.InstantCodec"));
066        codecs.put("jdk8.LocalDateCodec", new CodecMap("com.datastax.driver.extras.codecs.jdk8.LocalDateCodec"));
067        codecs.put("jdk8.LocalDateTimeCodec", new CodecMap("com.datastax.driver.extras.codecs.jdk8.LocalDateTimeCodec"));
068        codecs.put("jdk8.LocalTimeCodec", new CodecMap("com.datastax.driver.extras.codecs.jdk8.LocalTimeCodec"));
069        codecs.put("jdk8.OptinalCodec", new CodecMap("com.datastax.driver.extras.codecs.jdk8.OptionalCodec"));
070        codecs.put("jdk8.ZonedDateTimeCodec", new CodecMap("com.datastax.driver.extras.codecs.jdk8.ZonedDateTimeCodec"));
071        codecs.put("jdk8.ZonaIdCodec", new CodecMap("com.datastax.driver.extras.codecs.jdk8.ZoneIdCodec"));
072        
073        codecs.put("joda.DateTimeCodec", new CodecMap("com.datastax.driver.extras.codecs.joda.DateTimeCodec"));
074        codecs.put("joda.InstantCodec", new CodecMap("com.datastax.driver.extras.codecs.joda.InstantCodec"));
075        codecs.put("joda.LocalDateCodec", new CodecMap("com.datastax.driver.extras.codecs.joda.LocalDateCodec"));
076        codecs.put("joda.LocalTimeCodec", new CodecMap("com.datastax.driver.extras.codecs.joda.LocalTimeCodec"));
077        codecs.put("json.JacksonJsonCodec", new CodecMap("com.datastax.driver.extras.codecs.json.JacksonJsonCodec"));
078        
079        codecs.put("InstantCodec", new CodecMap("com.datastax.driver.extras.codecs.jdk8.InstantCodec"));
080        codecs.put("LocalDateCodec", new CodecMap("com.datastax.driver.extras.codecs.jdk8.LocalDateCodec"));
081        codecs.put("LocalDateTimeCodec", new CodecMap("com.datastax.driver.extras.codecs.jdk8.LocalDateTimeCodec"));
082        codecs.put("LocalTimeCodec", new CodecMap("com.datastax.driver.extras.codecs.jdk8.LocalTimeCodec"));
083        codecs.put("OptinalCodec", new CodecMap("com.datastax.driver.extras.codecs.jdk8.OptionalCodec"));
084    }
085    
086    public void register(Cluster cluster, String codecName, boolean enable)
087    {
088        if (enable)
089        {
090            CodecMap codecMap = codecs.get(codecName);
091            Field field = null;
092            if (codecMap != null)
093            {
094                ObjectProxy<TypeCodec<?>> proxy = ObjectProxyFactory.of(codecMap.codecClassName);
095                field = proxy.getDeclaredField("instance");
096                if (field != null)
097                {
098                    TypeCodec<?> instance = null;
099                    try
100                    {
101                        instance = (TypeCodec<?>) field.get(null);
102                        cluster.getConfiguration().getCodecRegistry().register(instance);
103                        codecMap.instance = instance;
104                        if (codecName.endsWith("InstantCodec"))
105                            codecs.get("InstantCodec").instance = instance;
106                        else if (codecName.endsWith("LocalDateCodec"))
107                            codecs.get("LocalDateCodec").instance = instance;
108                        else if (codecName.endsWith("LocalTimeCodec"))
109                            codecs.get("LocalTimeCodec").instance = instance;
110                        else if (codecName.endsWith("LocalDateTimeCodec"))
111                            codecs.get("LocalDateTimeCodec").instance = instance;
112                        else if (codecName.endsWith("OptinalCodec"))
113                            codecs.get("OptinalCodec").instance = instance;
114                        
115                        LOG.info("The codec {} was registered with {}", codecName, codecMap.codecClassName);
116                    }
117                    catch (Exception e)//IllegalArgumentException, IllegalAccessException
118                    {
119                        LOG.error("Error registering codec {}", codecName, e);
120                    }
121                }
122            }
123            if (codecMap == null || field == null)
124                LOG.error("Codec {} not found ", codecName);
125        }
126    }
127    
128    public CodecMap getCodec(String codecName)
129    {
130        return codecs.get(codecName);
131    }
132    
133    public static class CodecMap
134    {
135        public final String codecClassName;
136        public TypeCodec    instance;
137        
138        CodecMap(String codecClassName)
139        {
140            this.codecClassName = codecClassName;
141        }
142    }
143}