org.apache.cassandra.config.Replacements Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cassandra-all Show documentation
Show all versions of cassandra-all Show documentation
The Apache Cassandra Project develops a highly scalable second-generation distributed database, bringing together Dynamo's fully distributed design and Bigtable's ColumnFamily-based data model.
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.cassandra.config;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.cassandra.exceptions.ConfigurationException;
public final class Replacements
{
private Replacements()
{
}
/**
* @param klass to get replacements for
* @return map of old names and replacements needed.
*/
public static Map, Map> getNameReplacements(Class extends Object> klass)
{
List replacements = getReplacementsRecursive(klass);
Map, Map> objectOldNames = new HashMap<>();
for (Replacement r : replacements)
{
Map oldNames = objectOldNames.computeIfAbsent(r.parent, ignore -> new HashMap<>());
if (!oldNames.containsKey(r.oldName))
oldNames.put(r.oldName, r);
else
{
throw new ConfigurationException("Invalid annotations, you have more than one @Replaces annotation in " +
"Config class with same old name(" + r.oldName + ") defined.");
}
}
return objectOldNames;
}
/**
* @param klass to get replacements for
* @return map of old names and replacements needed.
*/
private static List getReplacementsRecursive(Class> klass)
{
Set> seen = new HashSet<>(); // to make sure not to process the same type twice
List accum = new ArrayList<>();
getReplacementsRecursive(seen, accum, klass);
return accum.isEmpty() ? Collections.emptyList() : accum;
}
private static void getReplacementsRecursive(Set> seen,
List accum,
Class> klass)
{
accum.addAll(getReplacements(klass));
for (Field field : klass.getDeclaredFields())
{
if (seen.add(field.getType()))
{
// first time looking at this type, walk it
getReplacementsRecursive(seen, accum, field.getType());
}
}
}
private static List getReplacements(Class> klass)
{
List replacements = new ArrayList<>();
for (Field field : klass.getDeclaredFields())
{
String newName = field.getName();
Class> newType = field.getType();
final ReplacesList[] byType = field.getAnnotationsByType(ReplacesList.class);
if (byType == null || byType.length == 0)
{
Replaces r = field.getAnnotation(Replaces.class);
if (r != null)
addReplacement(klass, replacements, newName, newType, r);
}
else
{
for (ReplacesList replacesList : byType)
for (Replaces r : replacesList.value())
addReplacement(klass, replacements, newName, newType, r);
}
}
return replacements.isEmpty() ? Collections.emptyList() : replacements;
}
private static void addReplacement(Class> klass,
List replacements,
String newName, Class> newType,
Replaces r)
{
String oldName = r.oldName();
boolean deprecated = r.deprecated();
Class> oldType = r.converter().getOldType();
if (oldType == null)
oldType = newType;
Class> expectedNewType = r.converter().getNewType();
if (expectedNewType != null)
assert expectedNewType.equals(newType) : String.format("Converter is expected to return %s but %s#%s expects %s", expectedNewType, klass, newName, newType);
replacements.add(new Replacement(klass, oldName, oldType, newName, r.converter(), deprecated));
}
}