package ca.uhn.fhir.jpa.util;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2017 University Health Network
* %%
* 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.
* #L%
*/
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.io.IOException;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.*;
import org.apache.commons.lang3.Validate;
import com.google.common.collect.ImmutableSet;
import com.google.common.reflect.ClassPath;
import com.google.common.reflect.ClassPath.ClassInfo;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
public class TestUtil {
private static final int MAX_LENGTH = 30;
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(TestUtil.class);
/** non instantiable */
private TestUtil() {
super();
}
/**
* This is really only useful for unit tests, do not call otherwise
*/
public static void scanEntities(String packageName) throws IOException, ClassNotFoundException {
ImmutableSet<ClassInfo> classes = ClassPath.from(TestUtil.class.getClassLoader()).getTopLevelClasses(packageName);
Set<String> names = new HashSet<String>();
if (classes.size() <= 1) {
throw new InternalErrorException("Found no classes");
}
for (ClassInfo classInfo : classes) {
Class<?> clazz = Class.forName(classInfo.getName());
Entity entity = clazz.getAnnotation(Entity.class);
if (entity == null) {
continue;
}
ourLog.info("Scanning: {}", clazz.getSimpleName());
scan(clazz, names);
for (Field nextField : clazz.getDeclaredFields()) {
ourLog.info(" * Scanning field: {}", nextField.getName());
scan(nextField, names);
}
}
}
private static void scan(AnnotatedElement ae, Set<String> theNames) {
Table table = ae.getAnnotation(Table.class);
if (table != null) {
assertThat(table.name(), theNames);
for (UniqueConstraint nextConstraint : table.uniqueConstraints()) {
assertThat(nextConstraint.name(), theNames);
Validate.isTrue(nextConstraint.name().startsWith("IDX_"), nextConstraint.name() + " must start with IDX_");
}
for (Index nextConstraint : table.indexes()) {
assertThat(nextConstraint.name(), theNames);
Validate.isTrue(nextConstraint.name().startsWith("IDX_"), nextConstraint.name() + " must start with IDX_");
}
}
JoinColumn joinColumn = ae.getAnnotation(JoinColumn.class);
if (joinColumn != null) {
assertThat(joinColumn.name(), null);
ForeignKey fk = joinColumn.foreignKey();
Validate.notNull(fk);
Validate.isTrue(isNotBlank(fk.name()));
Validate.isTrue(fk.name().startsWith("FK_"));
assertThat(fk.name(), theNames);
}
Column column = ae.getAnnotation(Column.class);
if (column != null) {
assertThat(column.name(), null);
}
GeneratedValue gen = ae.getAnnotation(GeneratedValue.class);
SequenceGenerator sg = ae.getAnnotation(SequenceGenerator.class);
Validate.isTrue((gen != null) == (sg != null));
if (gen != null) {
assertThat(gen.generator(), theNames);
assertThat(sg.name(), null);
assertThat(sg.sequenceName(), null);
assertEquals(gen.generator(), sg.name());
assertEquals(gen.generator(), sg.sequenceName());
}
}
private static void assertEquals(String theGenerator, String theName) {
Validate.isTrue(theGenerator.equals(theName));
}
private static void assertThat(String theName, Set<String> theNames) {
Validate.isTrue(theName.length() <= MAX_LENGTH, "Identifier \"" + theName + "\" is " + theName.length() + " chars long");
if (theNames != null) {
Validate.isTrue(theNames.add(theName), "Duplicate name: " + theName);
}
}
}