/**
* Copyright © 2006-2016 Web Cohesion (info@webcohesion.com)
*
* 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.spring_web;
import com.webcohesion.enunciate.EnunciateContext;
import com.webcohesion.enunciate.api.ApiRegistrationContext;
import com.webcohesion.enunciate.api.InterfaceDescriptionFile;
import com.webcohesion.enunciate.api.resources.Resource;
import com.webcohesion.enunciate.api.resources.ResourceGroup;
import com.webcohesion.enunciate.facets.FacetFilter;
import com.webcohesion.enunciate.javac.TypeElementComparator;
import com.webcohesion.enunciate.module.EnunciateModuleContext;
import com.webcohesion.enunciate.modules.spring_web.api.impl.AnnotationBasedResourceGroupImpl;
import com.webcohesion.enunciate.modules.spring_web.api.impl.PathBasedResourceGroupImpl;
import com.webcohesion.enunciate.modules.spring_web.api.impl.ResourceClassResourceGroupImpl;
import com.webcohesion.enunciate.modules.spring_web.api.impl.ResourceImpl;
import com.webcohesion.enunciate.modules.spring_web.model.RequestMapping;
import com.webcohesion.enunciate.modules.spring_web.model.SpringController;
import com.webcohesion.enunciate.modules.spring_web.model.SpringControllerAdvice;
import com.webcohesion.enunciate.util.PathSortStrategy;
import com.webcohesion.enunciate.util.ResourceComparator;
import com.webcohesion.enunciate.util.ResourceGroupComparator;
import com.webcohesion.enunciate.util.SortedList;
import java.util.*;
/**
* @author Ryan Heaton
*/
@SuppressWarnings ( "unchecked" )
public class EnunciateSpringWebContext extends EnunciateModuleContext {
public enum GroupingStrategy {
path,
annotation,
resource_class
}
private final Set<SpringController> controllers;
private final Set<SpringControllerAdvice> advice;
private String relativeContextPath = "";
private GroupingStrategy groupingStrategy = GroupingStrategy.resource_class;
private InterfaceDescriptionFile wadlFile = null;
private PathSortStrategy pathSortStrategy = PathSortStrategy.breadth_first;
private final boolean disableExamples;
public EnunciateSpringWebContext(EnunciateContext context, boolean disableExamples) {
super(context);
this.disableExamples = disableExamples;
this.controllers = new TreeSet<SpringController>(new TypeElementComparator());
this.advice = new TreeSet<SpringControllerAdvice>(new TypeElementComparator());
}
public EnunciateContext getContext() {
return context;
}
public Set<SpringController> getControllers() {
return controllers;
}
public Set<SpringControllerAdvice> getAdvice() {
return advice;
}
public void add(SpringController controller) {
this.controllers.add(controller);
debug("Added %s as a Spring controller.", controller.getQualifiedName());
}
public void add(SpringControllerAdvice advice) {
this.advice.add(advice);
debug("Added %s as Spring controller advice.", advice.getQualifiedName());
}
public boolean isIncludeResourceGroupName() {
return this.groupingStrategy != GroupingStrategy.path;
}
public boolean isDisableExamples() {
return disableExamples;
}
public void setRelativeContextPath(String relativeContextPath) {
this.relativeContextPath = relativeContextPath;
}
public void setGroupingStrategy(GroupingStrategy groupingStrategy) {
this.groupingStrategy = groupingStrategy;
}
public PathSortStrategy getPathSortStrategy() {
return pathSortStrategy;
}
public void setPathSortStrategy(PathSortStrategy pathSortStrategy) {
this.pathSortStrategy = pathSortStrategy;
}
public InterfaceDescriptionFile getWadlFile() {
return wadlFile;
}
public void setWadlFile(InterfaceDescriptionFile wadlFile) {
this.wadlFile = wadlFile;
}
public List<ResourceGroup> getResourceGroups(ApiRegistrationContext registrationContext) {
List<ResourceGroup> resourceGroups;
if (this.groupingStrategy == GroupingStrategy.path) {
//group resources by path.
resourceGroups = getResourceGroupsByPath(registrationContext);
}
else if (this.groupingStrategy == GroupingStrategy.annotation) {
resourceGroups = getResourceGroupsByAnnotation(registrationContext);
}
else {
resourceGroups = getResourceGroupsByClass(registrationContext);
}
Collections.sort(resourceGroups, new Comparator<ResourceGroup>() {
@Override
public int compare(ResourceGroup o1, ResourceGroup o2) {
return o1.getLabel().compareTo(o2.getLabel());
}
});
return resourceGroups;
}
public List<ResourceGroup> getResourceGroupsByClass(ApiRegistrationContext registrationContext) {
List<ResourceGroup> resourceGroups = new ArrayList<ResourceGroup>();
Set<String> slugs = new TreeSet<String>();
FacetFilter facetFilter = context.getConfiguration().getFacetFilter();
for (SpringController springController : controllers) {
if (!facetFilter.accept(springController)) {
continue;
}
String slug = springController.getSimpleName().toString();
if (slugs.contains(slug)) {
slug = "";
String[] qualifiedNameTokens = springController.getQualifiedName().toString().split("\\.");
for (int i = qualifiedNameTokens.length - 1; i >= 0; i--) {
slug = slug.isEmpty() ? qualifiedNameTokens[i] : slug + "_" + qualifiedNameTokens[i];
if (!slugs.contains(slug)) {
break;
}
}
}
slugs.add(slug);
ResourceGroup group = new ResourceClassResourceGroupImpl(springController, slug, relativeContextPath, registrationContext);
if (!group.getResources().isEmpty()) {
resourceGroups.add(group);
}
}
Collections.sort(resourceGroups, new ResourceGroupComparator(this.pathSortStrategy));
return resourceGroups;
}
public List<ResourceGroup> getResourceGroupsByPath(ApiRegistrationContext registrationContext) {
Map<String, PathBasedResourceGroupImpl> resourcesByPath = new HashMap<String, PathBasedResourceGroupImpl>();
FacetFilter facetFilter = context.getConfiguration().getFacetFilter();
for (SpringController springController : controllers) {
if (!facetFilter.accept(springController)) {
continue;
}
for (RequestMapping method : springController.getRequestMappings()) {
if (facetFilter.accept(method)) {
String path = method.getFullpath();
PathBasedResourceGroupImpl resourceGroup = resourcesByPath.get(path);
if (resourceGroup == null) {
resourceGroup = new PathBasedResourceGroupImpl(relativeContextPath, path, new ArrayList<Resource>());
resourcesByPath.put(path, resourceGroup);
}
resourceGroup.getResources().add(new ResourceImpl(method, resourceGroup, registrationContext));
}
}
}
ArrayList<ResourceGroup> resourceGroups = new ArrayList<ResourceGroup>(resourcesByPath.values());
Collections.sort(resourceGroups, new ResourceGroupComparator(this.pathSortStrategy));
return resourceGroups;
}
public List<ResourceGroup> getResourceGroupsByAnnotation(ApiRegistrationContext registrationContext) {
Map<String, AnnotationBasedResourceGroupImpl> resourcesByAnnotation = new HashMap<String, AnnotationBasedResourceGroupImpl>();
FacetFilter facetFilter = context.getConfiguration().getFacetFilter();
for (SpringController springController : controllers) {
if (!facetFilter.accept(springController)) {
continue;
}
for (RequestMapping method : springController.getRequestMappings()) {
if (facetFilter.accept(method)) {
com.webcohesion.enunciate.metadata.rs.ResourceGroup annotation = method.getAnnotation(com.webcohesion.enunciate.metadata.rs.ResourceGroup.class);
String label = annotation == null ? "Other" : annotation.value();
AnnotationBasedResourceGroupImpl resourceGroup = resourcesByAnnotation.get(label);
if (resourceGroup == null) {
resourceGroup = new AnnotationBasedResourceGroupImpl(relativeContextPath, label, new SortedList<Resource>(new ResourceComparator(this.pathSortStrategy)), this.pathSortStrategy);
resourcesByAnnotation.put(label, resourceGroup);
}
resourceGroup.getResources().add(new ResourceImpl(method, resourceGroup, registrationContext));
}
}
}
ArrayList<ResourceGroup> resourceGroups = new ArrayList<ResourceGroup>(resourcesByAnnotation.values());
Collections.sort(resourceGroups, new ResourceGroupComparator(this.pathSortStrategy));
return resourceGroups;
}
}