Submits externally collected annotation data.

@param   req             The HTTP request.
@param   annotationDtos  The annotation DTOs to submit.

@return  The number of annotations that were submitted, and the number of errors encountered.
326006
@POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    @Path("/annotations")
    @Description("Submits externally collected annotation data.")
    public Map<String, Object> submitAnnotations(@Context HttpServletRequest req, final List<AnnotationDto> annotationDtos) {
        PrincipalUser remoteUser = getRemoteUser(req);

        SystemAssert.requireArgument(annotationDtos != null, "Cannot submit null annotations list.");

        List<Annotation> legalAnnotations = new ArrayList<>();
        List<AnnotationDto> illegalAnnotations = new ArrayList<>();
        List<String> errorMessages = new ArrayList<>();

        for (AnnotationDto annotationDto : annotationDtos) {
            try {
                Annotation annotation = new Annotation(annotationDto.getSource(), annotationDto.getId(), annotationDto.getType(),
                    annotationDto.getScope(), annotationDto.getMetric(), annotationDto.getTimestamp());

                copyProperties(annotation, annotationDto);
                legalAnnotations.add(annotation);
            } catch (Exception e) {
                illegalAnnotations.add(annotationDto);
                errorMessages.add(e.getMessage());
            }
        }
        _collectionService.submitAnnotations(remoteUser, legalAnnotations);

        Map<String, Object> result = new HashMap<>();

        result.put("Success", legalAnnotations.size() + " annotations");
        result.put("Error", illegalAnnotations.size() + " annotations");
        result.put("Error Messages", errorMessages);
        return result;
    }
602446
public final void addAnnotations(final List<SgAnnotation> annotations) {
        if (annotations == null) {
            throw new IllegalArgumentException("The argument 'annotations' cannot be NULL!");
        }
        this.annotations.addAll(annotations);
    }
729231
public Method getRestrictAtViewMethod(Annotation annotation) {
        Method restrictAtViewMethod;
        try {
            restrictAtViewMethod = annotation.annotationType().getDeclaredMethod("restrictAtPhase");
        } catch (NoSuchMethodException ex) {
            restrictAtViewMethod = null;
        } catch (SecurityException ex) {
            throw new IllegalArgumentException("restrictAtView method must be accessible", ex);
        }
        return restrictAtViewMethod;
    }
476426
public static List<Route> collectRouteFromControllerAnnotations(Controller controller) {
        String prefix = getPath(controller);
        List<Route> routes = new ArrayList<>();
        Method[] methods = controller.getClass().getMethods();
        for (Method method : methods) {
            org.wisdom.api.annotations.Route annotation = method.getAnnotation(org.wisdom.api.annotations.Route.class);
            if (annotation != null) {
                String uri = annotation.uri();
                uri = getPrefixedUri(prefix, uri);
                final Route route = new RouteBuilder().route(annotation.method())
                        .on(uri)
                        .to(controller, method)
                        .accepting(annotation.accepts())
                        .producing(annotation.produces());
                routes.add(route);
            }
        }
        return routes;
    }
577766
public <A extends Annotation> List<A> getAnnotations(final Class<A> annoClass) {
        Objects.requireNonNull(annoClass, "annoClass should not be null.");
        
        return getAnnotationsByType(expandedAnnos, annoClass);
    }
484673
public void visitAnnotations(AnnotatedNode node) {
        super.visitAnnotations(node);

        Map<Integer, List<AnnotationNode>> existing = new TreeMap<Integer, List<AnnotationNode>>();
        Map<Integer, List<AnnotationNode>> replacements = new LinkedHashMap<Integer, List<AnnotationNode>>();
        Map<Integer, AnnotationCollectorMode> modes = new LinkedHashMap<Integer, AnnotationCollectorMode>();
        int index = 0;
        for (AnnotationNode annotation : node.getAnnotations()) {
            findCollectedAnnotations(annotation, node, index, modes, existing, replacements);
            index++;
        }
        for (Map.Entry<Integer, List<AnnotationNode>> entry : replacements.entrySet()) {
            Integer replacementIndex = entry.getKey();
            List<AnnotationNode> annotationNodeList = entry.getValue();
            mergeCollectedAnnotations(modes.get(replacementIndex), existing, annotationNodeList);
            existing.put(replacementIndex, annotationNodeList);
        }
        List<AnnotationNode> mergedList = new ArrayList<AnnotationNode>();
        for (List<AnnotationNode> next : existing.values()) {
            mergedList.addAll(next);
        }

        node.getAnnotations().clear();
        node.getAnnotations().addAll(mergedList);

        for (AnnotationNode annotation : node.getAnnotations()) {
            Annotation transformClassAnnotation = getTransformClassAnnotation(annotation.getClassNode());
            if (transformClassAnnotation == null) {
                // skip if there is no such annotation
                continue;
            }
            addTransformsToClassNode(annotation, transformClassAnnotation);
        }
    }
1334180
@SuppressWarnings("unchecked")
    private List<Route> createControllerRoutes(Map<Method, Class<? extends Annotation>> controllerMethods) {
        List<Route> routes = new ArrayList<>();

        Class<? extends Controller> controllerClass = (Class<? extends Controller>) controllerMethods.keySet().iterator().next().getDeclaringClass();
        Set<String> controllerPaths = getControllerPaths(controllerClass);
        Collection<Method> methods = sortControllerMethods(controllerMethods.keySet());
        for (Method method : methods) {
            Class<? extends Annotation> httpMethodAnnotationClass = controllerMethods.get(method);
            Annotation httpMethodAnnotation = method.getAnnotation(httpMethodAnnotationClass);

            String httpMethod = httpMethodAnnotation.annotationType().getAnnotation(HttpMethod.class).value();
            String[] methodPaths = ClassUtils.executeDeclaredMethod(httpMethodAnnotation, "value");

            if (controllerPaths.isEmpty()) {
                // add an empty string to allow controllerPaths iteration
                controllerPaths.add("");
            }

            for (String controllerPath : controllerPaths) {
                if (methodPaths.length == 0) {
                    // controllerMethod does not specify a path, inherit from controller
                    String fullPath = StringUtils.addStart(controllerPath, "/");

                    // create the route handler
                    RouteHandler handler = new ControllerHandler(application, method);

                    // create the route
                    Route route = new Route(httpMethod, fullPath, handler)
                        .bind("__controllerClass", controllerClass)
                        .bind("__controllerMethod", method);

                    // add the route to the list of routes
                    routes.add(route);
                } else {
                    // controllerMethod specifies one or more paths, concatenate with controller paths
                    for (String methodPath : methodPaths) {
                        String path = Stream.of(StringUtils.removeEnd(controllerPath, "/"), StringUtils.removeStart(methodPath, "/"))
                            .filter(Objects::nonNull)
                            .collect(Collectors.joining("/"));
                        String fullPath = StringUtils.addStart(path, "/");

                        // create the route handler
                        RouteHandler handler = new ControllerHandler(application, method);

                        // create the route
                        Route route = new Route(httpMethod, fullPath, handler)
                            .bind("__controllerClass", controllerClass)
                            .bind("__controllerMethod", method);

                        // add the route to the list of routes
                        routes.add(route);
                    }
                }
            }
        }

        return routes;
    }
1015613
@SuppressWarnings("unchecked")
	public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
		for (Annotation annotation : this.annotations) {
			if (annotation.annotationType().equals(annotationType)) {
				return (T) annotation;
			}
		}
		for (Annotation metaAnn : this.annotations) {
			T ann = metaAnn.annotationType().getAnnotation(annotationType);
			if (ann != null) {
				return ann;
			}
		}
		return null;
	}
427566
public static List<Method> findMethods(Class<?> type,
			Class<? extends Annotation> annotation) {
		List<Method> list = new ArrayList<Method>();
		while (type != null) {
			for (Method method : type.getDeclaredMethods()) {
				if (method.getAnnotation(annotation) != null) {
					list.add(method);
				}
			}
			type = type.getSuperclass();
		}
		return list;
	}
1049405
private <T extends PackageDoc> void mapAnnotations(Map<String,List<T>> map, PackageDoc doc,
            T holder) {
        AnnotationDesc[] annotations;
        annotations = doc.annotations();
        for (int i = 0; i < annotations.length; i++) {
            AnnotationTypeDoc annotationDoc = annotations[i].annotationType();
            refList(map, annotationDoc).add(holder);
        }
    }
124004
private static Set<Annotation> getAnnotations(final Annotation[] annotations, final Class<? extends Annotation> neededAnnotationType) {
        final Set<Annotation> ret = new HashSet<>();

        for (final Annotation annotation : annotations) {
            annotation.annotationType().getAnnotations();
            final Annotation[] metaAnnotations = annotation.annotationType().getAnnotations();
            for (final Annotation metaAnnotation : metaAnnotations) {
                if (metaAnnotation.annotationType().equals(neededAnnotationType)) {
                    ret.add(annotation);
                }
            }
        }

        return ret;
    }
1000329
private void populateAnnotations(Collection<Annotation> annotations) {
        for (Annotation each : annotations) {
            this.annotations.put(each.annotationType(), each);
        }
    }
965075
protected List<MetricDatum> metricOfRequestOrRetryCount(
            Field metricType, Request<?> req, Object resp) {
        AWSRequestMetrics m = req.getAWSRequestMetrics();
        TimingInfo ti = m.getTimingInfo();
        // Always retrieve the request count even for retry which is equivalent
        // to the number of requests minus one.
        Number counter = ti.getCounter(Field.RequestCount.name());
        if (counter == null) {
            // this is possible if one of the request handlers screwed up
            return Collections.emptyList();
        }
        int requestCount = counter.intValue();
        if (requestCount < 1) {
            LogFactory.getLog(getClass()).debug(
                "request count must be at least one");
            return Collections.emptyList();
        }
        final double count = metricType == Field.RequestCount
                           ? requestCount
                           : requestCount-1 // retryCount = requestCount - 1
                           ;
        if (count < 1) {
            return Collections.emptyList();
        } else {
            return Collections.singletonList(new MetricDatum()
                .withMetricName(req.getServiceName())
                .withDimensions(new Dimension()
                    .withName(Dimensions.MetricType.name())
                    .withValue(metricType.name()))
                .withUnit(StandardUnit.Count)
                .withValue(Double.valueOf(count))
                .withTimestamp(endTimestamp(ti)))
                ;
        }
    }
1014835
private boolean isAnnotatedResponseBody(MethodDoc method) {
		AnnotationDesc[] annotations = method.annotations();
		for (int i = 0; i < annotations.length; i++) {
			if (annotations[i].annotationType().name().equals("ResponseBody")) {
				return true;
			}
		}
		return false;
	}
219675
@Override
    public List<AnnotationInfoImpl> getAnnotations() {
        if (annotations != null) {
            return annotations;
        }

        // Several cases where superclasses contribute no annotations.  In
        // each of these cases case, simply re-use the declared annotations
        // collection.
        //
        // (One case: All of the inheritable superclass annotations is
        // overridden by the immediate class, is not detected.)

        ClassInfoImpl useSuperClass = getSuperclass(); // Null for 'java.lang.Object'; null for interfaces.  
        if (useSuperClass == null) {
                annotations = declaredAnnotations;
            return annotations;
                    }

        // Retrieve *all* annotations of the superclass.  The effect
        // is to recurse across annotations of all superclasses.

        List<AnnotationInfoImpl> superAnnos = useSuperClass.getAnnotations();
        if (superAnnos.isEmpty()) {
            annotations = declaredAnnotations;
            return annotations;
                }

        Map<String, AnnotationInfoImpl> allAnnotations =
                        new HashMap<String, AnnotationInfoImpl>(superAnnos.size() + declaredAnnotations.size(), 1.0f);

        boolean sawInherited = false;
        for (AnnotationInfoImpl superAnno : superAnnos) {
            if (sawInherited = superAnno.isInherited()) {
                allAnnotations.put(superAnno.getAnnotationClassName(), superAnno);
            }
                }

        if (!sawInherited) {
            annotations = declaredAnnotations;
            return annotations;
        }

        // Make sure to add the declared annotations *after* adding the super class
        // annotations.  The immediate declared annotations have precedence.

        // We could test the number of overwritten annotations against the
        // number of inherited annotations.  That case seems infrequent, and
        // is not implemented.

        for (AnnotationInfoImpl declaredAnno : declaredAnnotations) {
            AnnotationInfoImpl overwrittenAnno = allAnnotations.put(declaredAnno.getAnnotationClassName(), declaredAnno);
            if (overwrittenAnno != null) {
                // NO-OP: But maybe we want to log this
            }
        }

        annotations = new ArrayList<AnnotationInfoImpl>(allAnnotations.values());
        return annotations;
    }
868504
private <T extends Attribute.Compound> T processRepeatedAnnotations(List<T> annotations,
            AnnotateRepeatedContext<T> ctx,
            Symbol on) {
        T firstOccurrence = annotations.head;
        List<Attribute> repeated = List.nil();
        Type origAnnoType = null;
        Type arrayOfOrigAnnoType = null;
        Type targetContainerType = null;
        MethodSymbol containerValueSymbol = null;

        Assert.check(!annotations.isEmpty() &&
                     !annotations.tail.isEmpty()); // i.e. size() > 1

        int count = 0;
        for (List<T> al = annotations;
             !al.isEmpty();
             al = al.tail)
        {
            count++;

            // There must be more than a single anno in the annotation list
            Assert.check(count > 1 || !al.tail.isEmpty());

            T currentAnno = al.head;

            origAnnoType = currentAnno.type;
            if (arrayOfOrigAnnoType == null) {
                arrayOfOrigAnnoType = types.makeArrayType(origAnnoType);
            }

            // Only report errors if this isn't the first occurrence I.E. count > 1
            boolean reportError = count > 1;
            Type currentContainerType = getContainingType(currentAnno, ctx.pos.get(currentAnno), reportError);
            if (currentContainerType == null) {
                continue;
            }
            // Assert that the target Container is == for all repeated
            // annos of the same annotation type, the types should
            // come from the same Symbol, i.e. be '=='
            Assert.check(targetContainerType == null || currentContainerType == targetContainerType);
            targetContainerType = currentContainerType;

            containerValueSymbol = validateContainer(targetContainerType, origAnnoType, ctx.pos.get(currentAnno));

            if (containerValueSymbol == null) { // Check of CA type failed
                // errors are already reported
                continue;
            }

            repeated = repeated.prepend(currentAnno);
        }

        if (!repeated.isEmpty()) {
            repeated = repeated.reverse();
            TreeMaker m = make.at(ctx.pos.get(firstOccurrence));
            Pair<MethodSymbol, Attribute> p =
                    new Pair<MethodSymbol, Attribute>(containerValueSymbol,
                                                      new Attribute.Array(arrayOfOrigAnnoType, repeated));
            if (ctx.isTypeCompound) {
                /* TODO: the following code would be cleaner:
                Attribute.TypeCompound at = new Attribute.TypeCompound(targetContainerType, List.of(p),
                        ((Attribute.TypeCompound)annotations.head).position);
                JCTypeAnnotation annoTree = m.TypeAnnotation(at);
                at = enterTypeAnnotation(annoTree, targetContainerType, ctx.env);
                */
                // However, we directly construct the TypeCompound to keep the
                // direct relation to the contained TypeCompounds.
                Attribute.TypeCompound at = new Attribute.TypeCompound(targetContainerType, List.of(p),
                        ((Attribute.TypeCompound)annotations.head).position);

                // TODO: annotation applicability checks from below?

                at.setSynthesized(true);

                @SuppressWarnings("unchecked")
                T x = (T) at;
                return x;
            } else {
                Attribute.Compound c = new Attribute.Compound(targetContainerType, List.of(p));
                JCAnnotation annoTree = m.Annotation(c);

                if (!chk.annotationApplicable(annoTree, on))
                    log.error(annoTree.pos(), "invalid.repeatable.annotation.incompatible.target", targetContainerType, origAnnoType);

                if (!chk.validateAnnotationDeferErrors(annoTree))
                    log.error(annoTree.pos(), "duplicate.annotation.invalid.repeated", origAnnoType);

                c = enterAnnotation(annoTree, targetContainerType, ctx.env);
                c.setSynthesized(true);

                @SuppressWarnings("unchecked")
                T x = (T) c;
                return x;
            }
        } else {
            return null; // errors should have been reported elsewhere
        }
    }
508689
private Description checkAnnotations(
      Tree tree,
      int treePos,
      List<? extends AnnotationTree> annotations,
      Comment danglingJavadoc,
      int firstModifierPos,
      int lastModifierPos,
      VisitorState state) {
    SuggestedFix.Builder builder = SuggestedFix.builder();
    List<AnnotationTree> moveBefore = new ArrayList<>();
    List<AnnotationTree> moveAfter = new ArrayList<>();

    boolean annotationProblem = false;
    for (AnnotationTree annotation : annotations) {
      int annotationPos = ((JCTree) annotation).getStartPosition();
      if (annotationPos <= firstModifierPos) {
        continue;
      }
      AnnotationType annotationType =
          ASTHelpers.getAnnotationType(annotation, getSymbol(tree), state);
      if (annotationPos >= lastModifierPos) {
        if (tree instanceof ClassTree || annotationType == AnnotationType.DECLARATION) {
          annotationProblem = true;
          moveBefore.add(annotation);
        }
      } else {
        annotationProblem = true;
        if (tree instanceof ClassTree
            || annotationType == AnnotationType.DECLARATION
            || annotationType == null) {
          moveBefore.add(annotation);
        } else {
          moveAfter.add(annotation);
        }
      }
    }
    if (annotationProblem) {
      for (AnnotationTree annotation : moveBefore) {
        builder.delete(annotation);
      }
      for (AnnotationTree annotation : moveAfter) {
        builder.delete(annotation);
      }
      String javadoc =
          danglingJavadoc == null ? "" : removeJavadoc(state, treePos, danglingJavadoc, builder);
      builder
          .replace(
              firstModifierPos,
              firstModifierPos,
              String.format("%s%s ", javadoc, joinSource(state, moveBefore)))
          .replace(
              lastModifierPos, lastModifierPos, String.format("%s ", joinSource(state, moveAfter)));
      ImmutableList<String> names =
          annotations.stream()
              .map(ASTHelpers::getSymbol)
              .filter(Objects::nonNull)
              .map(Symbol::getSimpleName)
              .map(a -> "@" + a)
              .collect(toImmutableList());
      String flattened = names.stream().collect(joining(", "));
      String isAre = names.size() > 1 ? "are not type annotations" : "is not a type annotation";
      String message =
          String.format(
              "%s %s, so should appear before any modifiers and after Javadocs.", flattened, isAre);
      return buildDescription(tree).setMessage(message).addFix(builder.build()).build();
    }
    return NO_MATCH;
  }