package org.jboss.resteasy.jsapi; import org.jboss.logging.Logger.Level; import org.jboss.resteasy.core.ResourceInvoker; import org.jboss.resteasy.core.ResourceLocatorInvoker; import org.jboss.resteasy.core.ResourceMethodInvoker; import org.jboss.resteasy.core.ResourceMethodRegistry; import org.jboss.resteasy.jsapi.i18n.LogMessages; import org.jboss.resteasy.jsapi.i18n.Messages; import org.jboss.resteasy.spi.ResteasyProviderFactory; import org.jboss.resteasy.spi.metadata.ResourceLocator; import org.jboss.resteasy.util.GetRestful; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import java.util.Map.Entry; /** * @author Stéphane Épardaud <stef@epardaud.fr> */ public class ServiceRegistry { private static final long serialVersionUID = -1985015444704126795L; private ResourceMethodRegistry registry; private ResteasyProviderFactory providerFactory; private ServiceRegistry parent; private ArrayList<MethodMetaData> methods; private ArrayList<ServiceRegistry> locators; private ResourceLocatorInvoker invoker; private String uri; private String functionPrefix; public ServiceRegistry getParent() { return parent; } public ServiceRegistry(ServiceRegistry parent, ResourceMethodRegistry registry, ResteasyProviderFactory providerFactory, ResourceLocatorInvoker invoker) throws Exception { this.parent = parent; this.registry = registry; this.providerFactory = providerFactory; this.invoker = invoker; if(invoker != null){ Method method = invoker.getMethod(); ResourceLocator resourceLocator = MethodMetaData.getResourceLocator(invoker); String methodPathVal = resourceLocator.getPath(); String classPathVal = resourceLocator.getResourceClass().getPath(); this.uri = MethodMetaData.appendURIFragments(parent, classPathVal, methodPathVal); if(parent.isRoot()) this.functionPrefix = method.getDeclaringClass().getSimpleName() + "." + method.getName(); else this.functionPrefix = parent.getFunctionPrefix() + "." + method.getName(); } scanRegistry(); } private void scanRegistry() throws Exception { methods = new ArrayList<MethodMetaData>(); locators = new ArrayList<ServiceRegistry>(); for (Entry<String, List<ResourceInvoker>> entry : registry.getBounded().entrySet()) { List<ResourceInvoker> invokers = entry.getValue(); for (ResourceInvoker invoker : invokers) { if (invoker instanceof ResourceMethodInvoker) { methods.add(new MethodMetaData(this, (ResourceMethodInvoker) invoker)); } else if(invoker instanceof ResourceLocatorInvoker) { ResourceLocatorInvoker locator = (ResourceLocatorInvoker) 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 if (LogMessages.LOGGER.isEnabled(Level.WARN)) LogMessages.LOGGER.warn(Messages.MESSAGES.impossibleToGenerateJsapi(method.getDeclaringClass().getName(), method.getName())); // skip this continue; } ResourceMethodRegistry locatorRegistry = new ResourceMethodRegistry(providerFactory); locatorRegistry.addResourceFactory(null, null, locatorResourceType); locators.add(new ServiceRegistry(this, locatorRegistry, providerFactory, locator)); } } } } } public List<MethodMetaData> getMethodMetaData() { return methods; } public List<ServiceRegistry> 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(invoker.getMethod()); parent.collectResourceMethodsUntilRoot(methods); } }