/*
* Copyright 2011 cruxframework.org.
*
* 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 org.cruxframework.crux.scanner;
import java.lang.annotation.Annotation;
import java.util.HashSet;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* @author Thiago da Rosa de Bustamante
*
*/
public class ClassScanner
{
private static final Log logger = LogFactory.getLog(ClassScanner.class);
private static AnnotationDB scannerDB = new AnnotationDB();
private static boolean initialized = false;
private static boolean scannerInitialized = false;
/**
*
*/
private ClassScanner()
{
}
/**
*
* @param urls
*/
public synchronized static void initialize()
{
if (!isInitialized())
{
if (!scannerInitialized)
{
initializeScanner();
}
buildIndex();
setInitialized();
}
}
static void setInitialized()
{
initialized = true;
}
public static void reset()
{
initialized = false;
}
public static void initializeScanner()
{
if (!scannerInitialized)
{
Scanners.registerScanner(scannerDB);
scannerDB.setScanFieldAnnotations(false);
scannerDB.setScanMethodAnnotations(false);
scannerDB.setScanParameterAnnotations(false);
scannerInitialized = true;
}
}
/**
*
* @param urls
* @throws ClassScannerException
*/
private static void buildIndex() throws ClassScannerException
{
try
{
if (logger.isInfoEnabled())
{
logger.info("Building index of annotations for classes.");
}
scannerDB.scanArchives();
}
catch (Exception e)
{
throw new ClassScannerException("Error creating index of annotations.", e);
}
}
/**
* Search into the internal index for the set of classes that contains the given annotation.
* @param annotationClass
* @return
*/
public static Set<String> searchClassesByAnnotation(Class<? extends Annotation> annotationClass)
{
if (!isInitialized())
{
initialize();
}
return scannerDB.getAnnotationIndex().get(annotationClass.getName());
}
/**
* Search into the internal index for the set of classes that implements the given interface.
* @param annotationClass
* @return
*/
public static Set<String> searchClassesByInterface(Class<?> interfaceClass)
{
if (!interfaceClass.isInterface())
{
throw new ClassScannerException("The class ["+interfaceClass.getName()+"] is not an interface.");
}
return searchClassesByInterface(interfaceClass.getName(), true);
}
/**
*
* @param className
* @param deep
* @return
*/
public static Set<String> searchClassesByInterface(String className, boolean deep)
{
if (!isInitialized())
{
initialize();
}
Set<String> result = new HashSet<String>();
Set<String> classes = scannerDB.getInterfacesIndex().get(className);
if (classes != null && classes.size() > 0)
{
result.addAll(classes);
if (deep)
{
for(String c: classes)
{
Set<String> deepInterfaces = searchClassesByInterface(c, deep);
if (deepInterfaces != null)
{
result.addAll(deepInterfaces);
}
}
}
}
return result;
}
/**
* return true if the scanner was already loaded.
* @return
*/
public static boolean isInitialized()
{
return initialized;
}
}