<commit_before>/*
 * Copyright 2006-2008 Web Cohesion
 *
 * 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 com.webcohesion.enunciate.modules.jaxrs.model;

import com.webcohesion.enunciate.javac.decorations.element.DecoratedExecutableElement;
import com.webcohesion.enunciate.javac.decorations.type.TypeMirrorUtils;
import com.webcohesion.enunciate.modules.jaxrs.EnunciateJaxrsContext;

import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeMirror;
import javax.ws.rs.Path;
import java.util.*;

import static com.webcohesion.enunciate.modules.jaxrs.model.Resource.extractPathComponents;

/**
 * A sub-resource locator.  Invoked on a JAX-RS resource in order to locate a subresource.
 *
 * @author <NAME>
 */
public class SubResourceLocator extends DecoratedExecutableElement implements PathContext {

  private final Path path;
  private final LinkedHashMap<String, String> pathComponents;
  private final SubResource resource;
  private final Resource parent;
  private final List<ResourceParameter> resourceParameters;
  private final VariableElement entityParameter;
  private final EnunciateJaxrsContext context;

  public SubResourceLocator(ExecutableElement delegate, Resource parent, EnunciateJaxrsContext context) {
    super(delegate, context.getContext().getProcessingEnvironment());
    this.context = context;
    this.parent = parent;

    this.path = delegate.getAnnotation(Path.class);
    if (this.path == null) {
      throw new IllegalArgumentException("A subresource locator must specify a path with the @javax.ws.rs.Path annotation.");
    }
    this.pathComponents = extractPathComponents(this.path.value());

    SubResource resource;
    TypeMirror returnType = delegate.getReturnType();
    if ((returnType instanceof DeclaredType) && ((DeclaredType) returnType).asElement() != null) {
      TypeElement declaration = (TypeElement) ((DeclaredType) returnType).asElement();
      resource = findRecursiveSubResource(declaration, getPath());
      resource = resource == null ? new SubResource(declaration, getPath(), this, context) : resource;
    }
    else {
      resource = new SubResource((TypeElement) TypeMirrorUtils.objectType(context.getContext().getProcessingEnvironment()).asElement(), getPath(), this, context);
    }
    this.resource = resource;

    VariableElement entityParameter = null;
    List<ResourceParameter> resourceParameters = new ArrayList<ResourceParameter>();
    for (VariableElement parameterDeclaration : delegate.getParameters()) {
      if (ResourceParameter.isResourceParameter(parameterDeclaration, context)) {
        resourceParameters.add(new ResourceParameter(parameterDeclaration, this));
      }
      else {
        entityParameter = parameterDeclaration;
      }
    }
<commit_msg>support sub-resource locators that return the class instead of the instance per #307<commit_after>/*
 * Copyright 2006-2008 Web Cohesion
 *
 * 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 com.webcohesion.enunciate.modules.jaxrs.model;

import com.webcohesion.enunciate.javac.decorations.element.DecoratedExecutableElement;
import com.webcohesion.enunciate.javac.decorations.type.TypeMirrorUtils;
import com.webcohesion.enunciate.modules.jaxrs.EnunciateJaxrsContext;

import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeMirror;
import javax.ws.rs.Path;
import java.util.*;

import static com.webcohesion.enunciate.modules.jaxrs.model.Resource.extractPathComponents;

/**
 * A sub-resource locator.  Invoked on a JAX-RS resource in order to locate a subresource.
 *
 * @author <NAME>
 */
public class SubResourceLocator extends DecoratedExecutableElement implements PathContext {

  private final Path path;
  private final LinkedHashMap<String, String> pathComponents;
  private final SubResource resource;
  private final Resource parent;
  private final List<ResourceParameter> resourceParameters;
  private final VariableElement entityParameter;
  private final EnunciateJaxrsContext context;

  public SubResourceLocator(ExecutableElement delegate, Resource parent, EnunciateJaxrsContext context) {
    super(delegate, context.getContext().getProcessingEnvironment());
    this.context = context;
    this.parent = parent;

    this.path = delegate.getAnnotation(Path.class);
    if (this.path == null) {
      throw new IllegalArgumentException("A subresource locator must specify a path with the @javax.ws.rs.Path annotation.");
    }
    this.pathComponents = extractPathComponents(this.path.value());

    SubResource resource;
    TypeMirror returnType = delegate.getReturnType();
    if ((returnType instanceof DeclaredType) && ((DeclaredType) returnType).asElement() != null) {
      TypeElement declaration = (TypeElement) ((DeclaredType) returnType).asElement();
      if (Class.class.getName().equals(declaration.getQualifiedName().toString())) {
        //subresource locators may return the class instead of the instance, so unwrap.
        List<? extends TypeMirror> classTypes = ((DeclaredType) returnType).getTypeArguments();
        if (classTypes != null && classTypes.size() > 0) {
          returnType = classTypes.get(0);
          if ((returnType instanceof DeclaredType) && ((DeclaredType) returnType).asElement() != null) {
            declaration = (TypeElement) ((DeclaredType) returnType).asElement();
            resource = findRecursiveSubResource(declaration, getPath());
            resource = resource == null ? new SubResource(declaration, getPath(), this, context) : resource;
          }
          else {
            resource = new SubResource((TypeElement) TypeMirrorUtils.objectType(context.getContext().getProcessingEnvironment()).asElement(), getPath(), this, context);
          }
        }
        else {
          resource = new SubResource((TypeElement) TypeMirrorUtils.objectType(context.getContext().getProcessingEnvironment()).asElement(), getPath(), this, context);
        }
      }
      else {
        resource = findRecursiveSubResource(declaration, getPath());
        resource = resource == null ? new SubResource(declaration, getPath(), this, context) : resource;
      }
    }
    else {
      resource = new SubResource((TypeElement) TypeMirrorUtils.objectType(context.getContext().getProcessingEnvironment()).asElement(), getPath(), this, context);
    }
    this.resource = resource;

    VariableElement entityParameter = null;
    List<ResourceParameter> resourceParameters = new ArrayList<ResourceParameter>();
    for (VariableElement parameterDeclaration : delegate.getParameters()) {
      if (ResourceParameter.isResourceParameter(parameterDeclaration, context)) {
        resourceParameters.add(new ResourceParameter(parameterDeclaration, this));
      }
      else {
        entityParameter = parameterDeclaration;
      }
    }

{'fraction_non_alphanumeric': 0.09586002957121735, 'fraction_numerical': 0.0035731887629374074, 'mean_word_length': 4.400532268795742, 'pattern_counts': {'":': 0, '<': 14, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6893740', 'n_tokens_mistral': 2112, 'n_tokens_neox': 2077, 'n_words': 583}