package org.jboss.resteasy.wadl; import org.jboss.resteasy.core.ResourceInvoker; import org.jboss.resteasy.core.ResourceMethodInvoker; import org.jboss.resteasy.core.ResourceMethodRegistry; import org.jboss.resteasy.spi.ResteasyProviderFactory; import org.jboss.resteasy.spi.metadata.ResourceLocator; import org.jboss.resteasy.util.GetRestful; import org.jboss.resteasy.wadl.i18n.LogMessages; import org.jboss.resteasy.wadl.i18n.Messages; import javax.ws.rs.Path; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @author <a href="mailto:l.weinan@gmail.com">Weinan Li</a> */ public class ResteasyWadlServiceRegistry { private ResourceMethodRegistry registry; public ResteasyProviderFactory getProviderFactory() { return providerFactory; } private ResteasyProviderFactory providerFactory; private ResteasyWadlServiceRegistry parent; private Map<String, ResteasyWadlResourceMetaData> resources; private List<ResteasyWadlServiceRegistry> locators; private ResourceLocator locator; private String uri; private String functionPrefix; public ResteasyWadlServiceRegistry(ResteasyWadlServiceRegistry parent, ResourceMethodRegistry registry, ResteasyProviderFactory providerFactory, ResourceLocator locator) { this.parent = parent; this.registry = registry; this.providerFactory = providerFactory; this.locator = locator; if (locator != null) { Method method = locator.getMethod(); Path methodPath = method.getAnnotation(Path.class); Class<?> declaringClass = method.getDeclaringClass(); Path classPath = declaringClass.getAnnotation(Path.class); this.uri = ResteasyWadlMethodMetaData.appendURIFragments(parent, classPath, methodPath); if (parent.isRoot()) this.functionPrefix = declaringClass.getSimpleName() + "." + method.getName(); else this.functionPrefix = parent.getFunctionPrefix() + "." + method.getName(); } scanRegistry(); } private void scanRegistry() { resources = new HashMap<String, ResteasyWadlResourceMetaData>(); locators = new ArrayList<ResteasyWadlServiceRegistry>(); for (Map.Entry<String, List<ResourceInvoker>> entry : registry.getBounded().entrySet()) { List<ResourceInvoker> invokers = entry.getValue(); for (ResourceInvoker invoker : invokers) { if (invoker instanceof ResourceMethodInvoker) { ResteasyWadlMethodMetaData methodMetaData = new ResteasyWadlMethodMetaData(this, (ResourceMethodInvoker) invoker); ResteasyWadlResourceMetaData resourceMetaData = resources.get(methodMetaData.getKlassUri()); if (resourceMetaData == null) { resourceMetaData = new ResteasyWadlResourceMetaData(methodMetaData.getKlassUri()); resources.put(methodMetaData.getKlassUri(), resourceMetaData); } resourceMetaData.addMethodMetaData(methodMetaData); } else if (invoker instanceof ResourceLocator) { ResourceLocator locator = (ResourceLocator) invoker; Method method = locator.getMethod(); Class<?> locatorType = method.getReturnType(); Class<?>[] locatorResourceTypes = GetRestful.getSubResourceClasses(locatorType); for (Class<?> locatorResourceType : locatorResourceTypes) { if (locatorResourceType == null) { // FIXME: we could generate an error for the client, which would be more informative than // just logging this LogMessages.LOGGER.warn(Messages.MESSAGES.impossibleToGenerateWADL(method.getDeclaringClass().getName(), method.getName())); // skip this continue; } ResourceMethodRegistry locatorRegistry = new ResourceMethodRegistry(providerFactory); locatorRegistry.addResourceFactory(null, null, locatorResourceType); locators.add(new ResteasyWadlServiceRegistry(this, locatorRegistry, providerFactory, locator)); } } } } } public Map<String, ResteasyWadlResourceMetaData> getResources() { return resources; } public List<ResteasyWadlServiceRegistry> getLocators() { return locators; } public String getUri() { return uri; } public boolean isRoot() { return parent == null; } public String getFunctionPrefix() { return functionPrefix; } public void collectResourceMethodsUntilRoot(List<Method> methods) { if (isRoot()) return; methods.add(locator.getMethod()); parent.collectResourceMethodsUntilRoot(methods); } }