package de.ppi.fuwesta.spring.mvc.util; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.List; import java.util.Properties; import javax.persistence.Entity; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.core.io.support.ResourcePatternResolver; import org.springframework.core.type.classreading.CachingMetadataReaderFactory; import org.springframework.core.type.classreading.MetadataReader; import org.springframework.core.type.classreading.MetadataReaderFactory; import org.springframework.util.ClassUtils; import org.springframework.util.SystemPropertyUtils; /** * Add all Entity-Information to messages, the key has the form * db.<simpleclassname>.<propertyname>. * */ public class EntityPropertiesToMessages { /** * The Logger for the controller. */ private static final Logger LOG = LoggerFactory .getLogger(EntityPropertiesToMessages.class); /** * the messages. */ private final Properties messages = new Properties(); private final String[] packageNames; private boolean analyzed = false; public EntityPropertiesToMessages(String... packageName) { this.packageNames = packageName; } public void analyze() { final List<Class<?>> entities = new ArrayList<>(); for (String packageName : packageNames) { try { entities.addAll(findEntities(packageName)); } catch (IOException e) { LOG.error("Error finding entities-classes", e); } } for (Class<?> entity : entities) { List<Field> fields = getAllFields(entity); for (Field field : fields) { final String key = "db." + entity.getSimpleName() + "." + field.getName(); messages.put(key, field.getName()); } } analyzed = true; } public Properties getProperties() { if (!analyzed) { analyze(); } return messages; } private List<Class<?>> findEntities(String basePackage) throws IOException { ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver(); MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resourcePatternResolver); final List<Class<?>> candidates = new ArrayList<Class<?>>(); final String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + resolveBasePackage(basePackage) + "/" + "**/*.class"; final Resource[] resources = resourcePatternResolver.getResources(packageSearchPath); for (Resource resource : resources) { if (resource.isReadable()) { MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(resource); try { if (isCandidate(metadataReader)) { candidates.add(Class.forName(metadataReader .getClassMetadata().getClassName())); } } catch (ClassNotFoundException cnfE) { LOG.error("Error finding entity-classes", cnfE); } } } return candidates; } private String resolveBasePackage(String basePackage) { return ClassUtils.convertClassNameToResourcePath(SystemPropertyUtils .resolvePlaceholders(basePackage)); } private boolean isCandidate(MetadataReader metadataReader) throws ClassNotFoundException { Class<?> c = Class.forName(metadataReader.getClassMetadata().getClassName()); if (c.getAnnotation(Entity.class) != null) { return true; } return false; } private List<Field> getAllFields(Class<?> type) { final List<Field> fields = new ArrayList<>(); for (Field field : type.getDeclaredFields()) { if (!Modifier.isStatic(field.getModifiers())) { fields.add(field); } } if (type.getSuperclass() != null) { fields.addAll(getAllFields(type.getSuperclass())); } return fields; } }