/* * Copyright (c) 2012-2014 Savoir Technologies, Inc. * * 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. */ package com.savoirtech.hecate.cql3.table; import com.savoirtech.hecate.cql3.FieldMapper; import com.savoirtech.hecate.cql3.ReflectionUtils; import com.savoirtech.hecate.cql3.annotations.Id; import com.savoirtech.hecate.cql3.annotations.IdColumn; import com.savoirtech.hecate.cql3.annotations.PrimaryKey; import com.savoirtech.hecate.cql3.exception.HecateException; import org.apache.commons.lang3.StringUtils; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; public class TableCreator { //---------------------------------------------------------------------------------------------------------------------- // Static Methods //---------------------------------------------------------------------------------------------------------------------- public static String createNestedTables(Map<String, StringBuilder> tables, String keySpace, String tableName, Class cls) throws HecateException { StringBuilder builder = new StringBuilder(); builder.append("CREATE TABLE IF NOT EXISTS "); builder.append(keySpace); builder.append("."); builder.append(tableName); builder.append(" ( "); boolean idFound = false; //Look for compound primary key annotation. String primaryKey = null; if (cls.isAnnotationPresent(PrimaryKey.class)) { PrimaryKey p = (PrimaryKey) cls.getAnnotation(PrimaryKey.class); primaryKey = p.pk(); idFound = true; } StringBuilder flds = new StringBuilder(); for (Field field : ReflectionUtils.getFieldsUpTo(cls, null)) { if (flds.length() > 0) { flds.append(","); } flds.append(field.getName()); flds.append(" "); String csType = FieldMapper.getRawCassandraType(field); if (csType == null) { field.getType(); createNestedTables(tables, keySpace, ReflectionUtils.tableName(field), field.getType()); } if (csType != null && csType.toLowerCase().startsWith("list<blob")) { Type type = field.getGenericType(); if (type instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType) type; Class clazz = null; try { clazz = ReflectionUtils.typeToClass(pt.getActualTypeArguments()[0], field.getDeclaringClass().getClassLoader()); } catch (ClassNotFoundException e) { throw new HecateException(e); } createNestedTables(tables, keySpace, ReflectionUtils.tableName(field), clazz); } } if (csType != null && csType.toLowerCase().startsWith("set<blob")) { Type type = field.getGenericType(); if (type instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType) type; Class clazz = null; try { clazz = ReflectionUtils.typeToClass(pt.getActualTypeArguments()[0], field.getDeclaringClass().getClassLoader()); } catch (ClassNotFoundException e) { throw new HecateException(e); } createNestedTables(tables, keySpace, ReflectionUtils.tableName(field), clazz); } } if (csType != null && csType.toLowerCase().contains("map<") && csType.toLowerCase().contains(",blob>")) { Type type = field.getGenericType(); if (type instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType) type; Class clazz = null; try { clazz = ReflectionUtils.typeToClass(pt.getActualTypeArguments()[1], field.getDeclaringClass().getClassLoader()); } catch (ClassNotFoundException e) { throw new HecateException(e); } createNestedTables(tables, keySpace, ReflectionUtils.tableName(field), clazz); } } flds.append(FieldMapper.getCassandraType(field)); if (field.isAnnotationPresent(IdColumn.class) || field.isAnnotationPresent(Id.class)) { if (idFound) { throw new HecateException("Cannot have multiple PRIMARY KEY declarations"); } else { //Idcolumn flds.append(" PRIMARY KEY"); idFound = true; } } } builder.append(flds); if (primaryKey != null) { builder.append(","); builder.append(" PRIMARY KEY ("); List<String> pkl = Arrays.asList(primaryKey.split(",")); StringBuilder keyBuilder = new StringBuilder(); for (String key : pkl) { if (keyBuilder.length() > 0) { keyBuilder.append(","); } keyBuilder.append(key.trim()); } builder.append(keyBuilder); builder.append(")"); } builder.append(" );"); tables.put(tableName, builder); return builder.toString(); } public static List<TableDescriptor> createPojoTables(String keySpace, String tableName, Class cls) { List<TableDescriptor> descriptors = new ArrayList<>(); return descriptors; } public static String createTable(String keySpace, String tableName, Class cls) throws HecateException { StringBuilder builder = new StringBuilder(); builder.append("CREATE TABLE IF NOT EXISTS "); builder.append(keySpace); builder.append("."); builder.append(tableName); builder.append(" ( "); boolean idFound = false; //Look for compound primary key annotation. String primaryKey = null; if (cls.isAnnotationPresent(PrimaryKey.class)) { PrimaryKey p = (PrimaryKey) cls.getAnnotation(PrimaryKey.class); primaryKey = p.pk(); idFound = true; } StringBuilder flds = new StringBuilder(); for (Field field : ReflectionUtils.getFieldsUpTo(cls, null)) { if (flds.length() > 0) { flds.append(","); } flds.append(field.getName()); flds.append(" "); String csType = FieldMapper.getRawCassandraType(field); if (StringUtils.isEmpty(csType)) { flds.append("blob"); } else { flds.append(FieldMapper.getRawCassandraType(field)); } if (field.isAnnotationPresent(IdColumn.class) || field.isAnnotationPresent(Id.class)) { if (idFound) { throw new HecateException("Cannot have multiple PRIMARY KEY declarations"); } else { //Idcolumn flds.append(" PRIMARY KEY"); idFound = true; } } } builder.append(flds); if (primaryKey != null) { builder.append(","); builder.append(" PRIMARY KEY ("); List<String> pkl = Arrays.asList(primaryKey.split(",")); StringBuilder keyBuilder = new StringBuilder(); for (String key : pkl) { if (keyBuilder.length() > 0) { keyBuilder.append(","); } keyBuilder.append(key.trim()); } builder.append(keyBuilder); builder.append(")"); } builder.append(" );"); return builder.toString(); } //---------------------------------------------------------------------------------------------------------------------- // Constructors //---------------------------------------------------------------------------------------------------------------------- private TableCreator() { } }