/* * Copyright (c) 2009-2012 Clark & Parsia, LLC. <http://www.clarkparsia.com> * * 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.clarkparsia.empire.util; import com.google.common.collect.Sets; import com.google.inject.Inject; import com.google.inject.name.Named; import com.google.common.base.Splitter; import java.util.Collection; import java.util.Set; import java.util.HashSet; import java.util.Properties; import java.lang.annotation.Annotation; import java.io.File; import java.io.IOException; import java.io.FileInputStream; import java.io.InputStream; import java.io.FileNotFoundException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * <p>Implementation of the EmpireAnnotationProvider interface which reads a property file from disk and * uses that to create the index of classes with specified annotations. The properties are expected to be in a simple * format, the key's in the file should be the fully qualified class names of the annotations and the values of * these keys should be a comma separated list of the fully qualified class names of all the classes which have * the specified annotation.</p> * * @author Michael Grove * @since 0.1 * @version 0.7 */ public final class PropertiesAnnotationProvider implements EmpireAnnotationProvider { /** * The logger */ private static final Logger LOGGER = LoggerFactory.getLogger(PropertiesAnnotationProvider.class.getName()); /** * The file to read the Annotations index from */ private final File mFile; /** * The properties read in from disk */ private Properties mProperties; /** * Create a new PropertiesAnnotationProvider which will read it's Annotation information from the default location, * a file in the top level of the application called "empire.annotation.index" */ private PropertiesAnnotationProvider() { this(new File("empire.annotation.index")); } /** * Create a new PropertiesAnnotationProvider * @param theFile the file to read the annotation properties from */ @Inject PropertiesAnnotationProvider(@Named("annotation.index") File theFile) { mFile = theFile; } /** * Return the Properties for this AnnotationProvider * @return the properties read from the specified file */ private Properties getProperties() { if (mProperties == null) { mProperties = new Properties(); InputStream aStream = null; try { if (mFile.exists()) { aStream = new FileInputStream(mFile); } else { aStream = getClass().getResourceAsStream("/" + mFile.getName()); } if (aStream != null) { mProperties.load(aStream); } else { LOGGER.warn("Annotation properties file could not be found on disk or in the jar"); } } catch (FileNotFoundException ex) { LOGGER.warn("Reading annotation index properties for Annotation provider failed, index file not found."); } catch (IOException e) { LOGGER.warn("Reading annotation index properties for Annotation provider failed", e); } finally { try { if (aStream != null) aStream.close(); } catch (IOException e) { LOGGER.warn("Error while closing annotation index properties stream", e); } } } return mProperties; } /** * @inheritDoc */ @Override public Collection<Class<?>> getClassesWithAnnotation(final Class<? extends Annotation> theAnnotation) { Set<Class<?>> aClasses = Sets.newHashSet(); Properties aProps = getProperties(); String aVal = aProps.getProperty(theAnnotation.getName()); if (aVal != null) { for (String aName : Splitter.on(",").omitEmptyStrings().trimResults().split(aVal)) { try { Class aClass = BeanReflectUtil.loadClass(aName); if (aClass.isAnnotationPresent(theAnnotation)) { aClasses.add(aClass); } else { LOGGER.warn("Class specified in AnnotationProvider file '" + aName + "' " + "does not actually have the specified annotation '" + theAnnotation + "'"); } } catch (ClassNotFoundException e) { LOGGER.warn("Class specified in AnnotationProvider file '" + aName + "' cannot be found."); } } } return aClasses; } }