/** * */ package org.minnal.instrument; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.ws.rs.core.Application; import org.minnal.instrument.entity.AggregateRootScanner; import org.minnal.instrument.resource.PathScanner; import org.minnal.instrument.resource.ResourceEnhancer; import org.minnal.instrument.resource.metadata.ResourceMetaData; import org.minnal.instrument.resource.metadata.ResourceMetaDataProvider; import org.minnal.utils.http.HttpUtil; import org.minnal.utils.scanner.Scanner; import org.minnal.utils.scanner.Scanner.Listener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author ganeshs * */ public class ApplicationEnhancer { private Application application; private NamingStrategy namingStrategy; private String[] entityPackages; private String[] resourcePackages; private static final Logger logger = LoggerFactory.getLogger(ApplicationEnhancer.class); /** * @param application * @param namingStrategy * @param entityPackages */ public ApplicationEnhancer(Application application, NamingStrategy namingStrategy, String[] entityPackages, String[] resourcePackages) { this.application = application; this.namingStrategy = namingStrategy; this.entityPackages = Arrays.copyOf(entityPackages, entityPackages.length); this.resourcePackages = Arrays.copyOf(resourcePackages, resourcePackages.length); } /** * @return the application */ protected Application getApplication() { return application; } /** * Enhances the application */ public void enhance() { logger.info("Enhancing the application"); List<Class<?>> entities = scanEntities(); List<Class<?>> resources = scanResources(); for (Class<?> resourceClass : resources) { ResourceMetaData resource = ResourceMetaDataProvider.instance().getResourceMetaData(resourceClass); String path = HttpUtil.getRootSegment(resource.getPath()); for (Class<?> entityClass : entities) { String rootPath = HttpUtil.structureUrl(namingStrategy.getResourceName(entityClass)); if (path.equals(rootPath)) { entities.remove(entityClass); addResource(createEnhancer(resource, entityClass).enhance()); break; } } } for (Class<?> entityClass : entities) { addResource(createEnhancer(null, entityClass).enhance()); } } /** * @param resourceClass */ protected void addResource(Class<?> resourceClass) { application.getClasses().add(resourceClass); } /** * Returns the entities defined under the entity packages * * @return */ protected List<Class<?>> scanEntities() { return scanClasses(new AggregateRootScanner(entityPackages)); } /** * Returns the resources defined under the resource packages * * @return */ protected List<Class<?>> scanResources() { return scanClasses(new PathScanner(resourcePackages)); } /** * Scan the classes using the scanner * * @param scanner * @return */ protected List<Class<?>> scanClasses(Scanner<Class<?>> scanner) { final List<Class<?>> classes = new ArrayList<Class<?>>(); scanner.scan(new Listener<Class<?>>() { public void handle(Class<?> t) { classes.add(t); } }); return classes; } /** * Creates the resource enhancer * * @param resource * @param entityClass * @return */ protected ResourceEnhancer createEnhancer(ResourceMetaData resource, Class<?> entityClass) { return new ResourceEnhancer(resource, entityClass, namingStrategy); } }