/**
  * Create a class that acts as a container for a hierarchy of static inner classes, one for each
  * resource described by the WADL file.
  *
  * @param root the resource element that corresponds to the root of the resource tree
  * @throws com.sun.codemodel.JClassAlreadyExistsException if, during code generation, the WADL
  *     processor attempts to create a duplicate class. This indicates a structural problem with
  *     the WADL file, e.g. duplicate peer resource entries.
  */
 protected void generateEndpointClass(ResourceNode root) throws JClassAlreadyExistsException {
   JDefinedClass impl = jPkg._class(JMod.PUBLIC, root.getClassName());
   javaDoc.generateClassDoc(root, impl);
   for (ResourceNode r : root.getChildResources()) {
     generateSubClass(impl, r);
   }
 }
  /**
   * Creates an inner static class that represents a resource and its methods. Recurses the tree of
   * child resources.
   *
   * @param parent the outer class for the static inner class being generated. This can either be
   *     the top level <code>Endpoint</code> class or a nested static inner class for a parent
   *     resource.
   * @param resource the WADL <code>resource</code> element being processed.
   * @throws com.sun.codemodel.JClassAlreadyExistsException if, during code generation, the WADL
   *     processor attempts to create a duplicate class. This indicates a structural problem with
   *     the WADL file, e.g. duplicate peer resource entries.
   */
  protected void generateSubClass(JDefinedClass parent, ResourceNode resource)
      throws JClassAlreadyExistsException {

    ResourceClassGenerator rcGen =
        new ResourceClassGenerator(s2jModel, codeModel, jPkg, generatedPackages, javaDoc, resource);
    JDefinedClass impl = rcGen.generateClass(parent);

    // generate Java methods for each resource method
    for (MethodNode m : resource.getMethods()) {
      rcGen.generateMethodDecls(m, false);
    }

    // generate sub classes for each child resource
    for (ResourceNode r : resource.getChildResources()) {
      generateSubClass(impl, r);
    }
  }
  /**
   * Add a type to a resource. Follow references to types across WADL file boundaries
   *
   * @param href the identifier of the resource_type element to process
   * @param resource the resource
   * @param file the URI of the current WADL file being processed
   */
  protected void addTypeToResource(ResourceNode resource, String href, URI file) {
    // dereference resource
    if (!href.startsWith("#")) {
      // referecnce to element in another document
      file = getReferencedFile(file, href);
    }
    ResourceTypeNode n = ifaceMap.get(file.toString() + href.substring(href.indexOf('#')));

    if (n != null) {
      resource.addResourceType(n);
    } else {
      System.err.println(Wadl2JavaMessages.SKIPPING_REFERENCE(href, file.toString()));
    }
  }
 /**
  * Add a resource and (recursively) its children to a tree starting at the parent. Follow
  * references to resources across WADL file boundaries
  *
  * @param parent the parent resource in the tree being built
  * @param resource the WADL resource to process
  * @param file the URI of the current WADL file being processed
  */
 protected void buildResourceTree(ResourceNode parent, Resource resource, URI file) {
   if (resource != null) {
     ResourceNode n = parent.addChild(resource);
     for (String type : resource.getType()) {
       addTypeToResource(n, type, file);
     }
     for (Object child : resource.getMethodOrResource()) {
       if (child instanceof Resource) {
         Resource childResource = (Resource) child;
         buildResourceTree(n, childResource, file);
       } else if (child instanceof Method) {
         Method m = (Method) child;
         addMethodToResource(n, m, file);
       }
     }
   }
 }