/**
* Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.util.annotation;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import org.fudgemsg.AnnotationReflector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
import com.opengamma.OpenGammaRuntimeException;
import com.opengamma.util.SingletonFactoryBean;
/**
* A Spring factory bean for obtaining a list of classes with a particular annotation.
*/
public class AnnotationScanningStringListFactoryBean extends SingletonFactoryBean<List<String>> {
private static final Logger s_logger = LoggerFactory.getLogger(AnnotationScanningStringListFactoryBean.class);
private String _cacheFile;
private String _forceScanSystemProperty;
private String _annotationClassName;
public String getCacheFile() {
return _cacheFile;
}
public void setCacheFile(String cacheFile) {
_cacheFile = cacheFile;
}
public String getForceScanSystemProperty() {
return _forceScanSystemProperty;
}
public void setForceScanSystemProperty(String forceScanSystemProperty) {
_forceScanSystemProperty = forceScanSystemProperty;
}
public String getAnnotationClassName() {
return _annotationClassName;
}
public void setAnnotationClassName(String annotationClassName) {
_annotationClassName = annotationClassName;
}
@Override
protected List<String> createObject() {
try {
boolean forceScan = shouldForceScan();
if (!forceScan && getCacheFile() != null) {
ClassPathResource cacheFileResource = new ClassPathResource(getCacheFile());
if (cacheFileResource.exists()) {
File cacheFile = cacheFileResource.getFile();
s_logger.debug("Getting classes containing annotation {} from cache {}", getAnnotationClassName(), cacheFile.getAbsoluteFile());
return getFromCache(cacheFile);
}
}
s_logger.debug("Scanning for classes containing annotation {}", getAnnotationClassName());
return new ArrayList<>(getByScanning(getAnnotationClassName()));
} catch (Exception e) {
s_logger.warn("Unable to retrieve classes containing annotation " + getAnnotationClassName(), e);
return Collections.emptyList();
}
}
private boolean shouldForceScan() {
if (getForceScanSystemProperty() == null) {
s_logger.debug("Force scan system property not specified");
return false;
}
String forceScanPropertyValue = System.getProperty(getForceScanSystemProperty());
s_logger.debug("Force scan system property set to '{}'", forceScanPropertyValue);
return forceScanPropertyValue != null;
}
private List<String> getFromCache(File cacheFile) {
List<String> stringList = new ArrayList<String>();
try (BufferedReader reader = new BufferedReader(new FileReader(cacheFile))) {
String nextLine;
while ((nextLine = reader.readLine()) != null) {
stringList.add(nextLine);
}
} catch (FileNotFoundException e) {
throw new IllegalArgumentException("File not found: " + cacheFile.getAbsoluteFile(), e);
} catch (IOException e) {
throw new OpenGammaRuntimeException("Error while reading file: " + cacheFile.getAbsoluteFile(), e);
}
return stringList;
}
private Set<String> getByScanning(String annotationClassName) {
Set<String> annotated = AnnotationReflector.getDefaultReflector().getReflector().getStore().getTypesAnnotatedWith(annotationClassName);
s_logger.debug("Found {} classes containing annotation: {}", annotated.size(), annotated);
return annotated;
}
}