Exemple #1
0
  public static Constructor<?> findResourceConstructor(Class<?> resourceClass, boolean perRequest) {
    List<Constructor<?>> cs = new LinkedList<Constructor<?>>();
    for (Constructor<?> c : resourceClass.getConstructors()) {
      Class<?>[] params = c.getParameterTypes();
      Annotation[][] anns = c.getParameterAnnotations();
      boolean match = true;
      for (int i = 0; i < params.length; i++) {
        if (!perRequest) {
          if (AnnotationUtils.getAnnotation(anns[i], Context.class) == null) {
            match = false;
            break;
          }
        } else if (!AnnotationUtils.isValidParamAnnotations(anns[i])) {
          match = false;
          break;
        }
      }
      if (match) {
        cs.add(c);
      }
    }
    Collections.sort(
        cs,
        new Comparator<Constructor<?>>() {

          public int compare(Constructor<?> c1, Constructor<?> c2) {
            int p1 = c1.getParameterTypes().length;
            int p2 = c2.getParameterTypes().length;
            return p1 > p2 ? -1 : p1 < p2 ? 1 : 0;
          }
        });
    return cs.size() == 0 ? null : cs.get(0);
  }
Exemple #2
0
  @Test
  public void testGetFromMethodOrClass() throws Exception {
    Path path =
        AnnotationUtils.getFromMethodOrClass(
            ExampleService.class.getMethod("getTicker", String.class, String.class), Path.class);
    assertThat("Wrong path.", path.value(), equalTo("{ident}_{currency}/ticker"));

    Path pathFromIntf =
        AnnotationUtils.getFromMethodOrClass(
            ExampleService.class.getMethod("getInfo", Long.class, Long.class), Path.class);
    assertThat("Wrong path.", pathFromIntf.value(), equalTo("api/2"));
  }
Exemple #3
0
 public static Object[] createConstructorArguments(
     Constructor<?> c, Message m, boolean perRequest, Map<Class<?>, Object> contextValues) {
   Class<?>[] params = c.getParameterTypes();
   Annotation[][] anns = c.getParameterAnnotations();
   Type[] genericTypes = c.getGenericParameterTypes();
   @SuppressWarnings("unchecked")
   MultivaluedMap<String, String> templateValues =
       m == null ? null : (MultivaluedMap<String, String>) m.get(URITemplate.TEMPLATE_PARAMETERS);
   Object[] values = new Object[params.length];
   for (int i = 0; i < params.length; i++) {
     if (AnnotationUtils.getAnnotation(anns[i], Context.class) != null) {
       Object contextValue = contextValues != null ? contextValues.get(params[i]) : null;
       if (contextValue == null) {
         if (perRequest) {
           values[i] = JAXRSUtils.createContextValue(m, genericTypes[i], params[i]);
         } else {
           values[i] = InjectionUtils.createThreadLocalProxy(params[i]);
         }
       } else {
         values[i] = contextValue;
       }
     } else {
       // this branch won't execute for singletons given that the found constructor
       // is guaranteed to have only Context parameters, if any, for singletons
       Parameter p = ResourceUtils.getParameter(i, anns[i], params[i]);
       values[i] =
           JAXRSUtils.createHttpParameterValue(
               p, params[i], genericTypes[i], anns[i], m, templateValues, null);
     }
   }
   return values;
 }
  /**
   * Returns the type qualifier hierarchy graph to be used by this processor.
   *
   * <p>The implementation builds the type qualifier hierarchy for the {@link
   * #getSupportedTypeQualifiers()} using the meta-annotations found in them. The current
   * implementation returns an instance of {@code GraphQualifierHierarchy}.
   *
   * <p>Subclasses may override this method to express any relationships that cannot be inferred
   * using meta-annotations (e.g. due to lack of meta-annotations).
   *
   * @return an annotation relation tree representing the supported qualifiers
   */
  protected QualifierHierarchy createQualifierHierarchy() {
    MultiGraphQualifierHierarchy.MultiGraphFactory factory = this.createQualifierHierarchyFactory();
    Elements elements = processingEnv.getElementUtils();

    for (Class<? extends Annotation> typeQualifier : getSupportedTypeQualifiers()) {
      AnnotationMirror typeQualifierAnno = AnnotationUtils.fromClass(elements, typeQualifier);
      assert typeQualifierAnno != null : "Loading annotation \"" + typeQualifier + "\" failed!";
      factory.addQualifier(typeQualifierAnno);
      // Polymorphic qualifiers can't declare their supertypes.
      // An error is raised if one is present.
      if (typeQualifier.getAnnotation(PolymorphicQualifier.class) != null) {
        if (typeQualifier.getAnnotation(SubtypeOf.class) != null) {
          // This is currently not supported. At some point we might add
          // polymorphic qualifiers with upper and lower bounds.
          errorAbort(
              "BaseTypeChecker: "
                  + typeQualifier
                  + " is polymorphic and specifies super qualifiers. "
                  + "Remove the @checkers.quals.SubtypeOf or @checkers.quals.PolymorphicQualifier annotation from it.");
        }
        continue;
      }
      if (typeQualifier.getAnnotation(SubtypeOf.class) == null) {
        errorAbort(
            "BaseTypeChecker: "
                + typeQualifier
                + " does not specify its super qualifiers. "
                + "Add an @checkers.quals.SubtypeOf annotation to it.");
      }
      Class<? extends Annotation>[] superQualifiers =
          typeQualifier.getAnnotation(SubtypeOf.class).value();
      for (Class<? extends Annotation> superQualifier : superQualifiers) {
        AnnotationMirror superAnno = null;
        superAnno = AnnotationUtils.fromClass(elements, superQualifier);
        factory.addSubtype(typeQualifierAnno, superAnno);
      }
    }

    QualifierHierarchy hierarchy = factory.build();
    if (hierarchy.getTypeQualifiers().size() < 1) {
      errorAbort(
          "BaseTypeChecker: invalid qualifier hierarchy: hierarchy requires at least one annotation: "
              + hierarchy.getTypeQualifiers());
    }

    return hierarchy;
  }
Exemple #5
0
  // CHECKSTYLE:OFF
  public static Parameter getParameter(int index, Annotation[] anns, Class<?> type) {

    Context ctx = AnnotationUtils.getAnnotation(anns, Context.class);
    if (ctx != null) {
      return new Parameter(ParameterType.CONTEXT, index, null);
    }

    boolean isEncoded = AnnotationUtils.getAnnotation(anns, Encoded.class) != null;

    BeanParam bp = AnnotationUtils.getAnnotation(anns, BeanParam.class);
    if (bp != null) {
      return new Parameter(ParameterType.BEAN, index, null, isEncoded, null);
    }

    String dValue = AnnotationUtils.getDefaultParameterValue(anns);

    PathParam a = AnnotationUtils.getAnnotation(anns, PathParam.class);
    if (a != null) {
      return new Parameter(ParameterType.PATH, index, a.value(), isEncoded, dValue);
    }
    QueryParam q = AnnotationUtils.getAnnotation(anns, QueryParam.class);
    if (q != null) {
      return new Parameter(ParameterType.QUERY, index, q.value(), isEncoded, dValue);
    }
    MatrixParam m = AnnotationUtils.getAnnotation(anns, MatrixParam.class);
    if (m != null) {
      return new Parameter(ParameterType.MATRIX, index, m.value(), isEncoded, dValue);
    }

    FormParam f = AnnotationUtils.getAnnotation(anns, FormParam.class);
    if (f != null) {
      return new Parameter(ParameterType.FORM, index, f.value(), isEncoded, dValue);
    }

    HeaderParam h = AnnotationUtils.getAnnotation(anns, HeaderParam.class);
    if (h != null) {
      return new Parameter(ParameterType.HEADER, index, h.value(), isEncoded, dValue);
    }

    CookieParam c = AnnotationUtils.getAnnotation(anns, CookieParam.class);
    if (c != null) {
      return new Parameter(ParameterType.COOKIE, index, c.value(), isEncoded, dValue);
    }

    return new Parameter(ParameterType.REQUEST_BODY, index, null);
  }
Exemple #6
0
 private void testForAnns(Method method, List<Class<? extends Annotation>> classes) {
   Map<Class<? extends Annotation>, Annotation> map =
       AnnotationUtils.getMethodAnnotationMap(method, classes);
   assertThat(sorted(map.keySet()), equalTo(sorted(classes)));
   for (Class<? extends Annotation> annClass : classes) {
     assertThat(map.get(annClass), IsInstanceOf.instanceOf(annClass));
   }
 }
Exemple #7
0
  private static void evaluateResourceClass(ClassResourceInfo cri, boolean enableStatic) {
    MethodDispatcher md = new MethodDispatcher();
    Class<?> serviceClass = cri.getServiceClass();

    boolean isFineLevelLoggable = LOG.isLoggable(Level.FINE);
    for (Method m : serviceClass.getMethods()) {

      Method annotatedMethod = AnnotationUtils.getAnnotatedMethod(serviceClass, m);

      String httpMethod = AnnotationUtils.getHttpMethodValue(annotatedMethod);
      Path path = AnnotationUtils.getMethodAnnotation(annotatedMethod, Path.class);

      if (httpMethod != null || path != null) {
        md.bind(createOperationInfo(m, annotatedMethod, cri, path, httpMethod), m);
        if (httpMethod == null) {
          // subresource locator
          Class<?> subClass = m.getReturnType();
          if (enableStatic) {
            ClassResourceInfo subCri = cri.findResource(subClass, subClass);
            if (subCri == null) {
              ClassResourceInfo ancestor = getAncestorWithSameServiceClass(cri, subClass);
              subCri =
                  ancestor != null
                      ? ancestor
                      : createClassResourceInfo(
                          subClass, subClass, cri, false, enableStatic, cri.getBus());
            }

            if (subCri != null) {
              cri.addSubClassResourceInfo(subCri);
            }
          }
        }
      } else if (isFineLevelLoggable) {
        LOG.fine(
            new org.apache.cxf.common.i18n.Message(
                    "NOT_RESOURCE_METHOD", BUNDLE, m.getDeclaringClass().getName(), m.getName())
                .toString());
      }
    }
    cri.setMethodDispatcher(md);
  }
Exemple #8
0
  private static void checkJaxbType(
      Class<?> serviceClass,
      Class<?> type,
      Type genericType,
      ResourceTypes types,
      Annotation[] anns,
      MessageBodyWriter<?> jaxbWriter) {
    boolean isCollection = false;
    if (InjectionUtils.isSupportedCollectionOrArray(type)) {
      type = InjectionUtils.getActualType(genericType);
      isCollection = true;
    }
    if (type == Object.class && !(genericType instanceof Class)) {
      Type theType =
          InjectionUtils.processGenericTypeIfNeeded(serviceClass, Object.class, genericType);
      type = InjectionUtils.getActualType(theType);
    }
    if (type == null
        || InjectionUtils.isPrimitive(type)
        || JAXBElement.class.isAssignableFrom(type)
        || Response.class.isAssignableFrom(type)
        || type.isInterface()) {
      return;
    }

    MessageBodyWriter<?> writer = jaxbWriter;
    if (writer == null) {
      JAXBElementProvider<Object> defaultWriter = new JAXBElementProvider<Object>();
      defaultWriter.setMarshallAsJaxbElement(true);
      defaultWriter.setXmlTypeAsJaxbElementOnly(true);
      writer = defaultWriter;
    }
    if (writer.isWriteable(type, type, anns, MediaType.APPLICATION_XML_TYPE)) {
      types.getAllTypes().put(type, type);
      Class<?> genCls = InjectionUtils.getActualType(genericType);
      if (genCls != type
          && genCls != null
          && genCls != Object.class
          && !InjectionUtils.isSupportedCollectionOrArray(genCls)) {
        types.getAllTypes().put(genCls, genCls);
      }

      XMLName name = AnnotationUtils.getAnnotation(anns, XMLName.class);
      QName qname = name != null ? JAXRSUtils.convertStringToQName(name.value()) : null;
      if (isCollection) {
        types.getCollectionMap().put(type, qname);
      } else {
        types.getXmlNameMap().put(type, qname);
      }
    }
  }
 private void configureContext(Context context) {
   Set<Model> models = AnnotationUtils.getAnnotations(context.getClass(), Model.class);
   GraphWalker annotation = context.getClass().getAnnotation(GraphWalker.class);
   if (!models.isEmpty()) {
     Path path = Paths.get(models.iterator().next().file());
     ContextFactoryScanner.get(reflections, path).create(path, context);
   }
   if (!"".equals(annotation.value())) {
     context.setPathGenerator(GeneratorFactory.parse(annotation.value()));
   } else {
     context.setPathGenerator(PathGeneratorFactory.createPathGenerator(annotation));
   }
   if (!"".equals(annotation.start())) {
     context.setNextElement(getElement(context.getModel(), annotation.start()));
   }
 }
Exemple #10
0
  @SuppressWarnings("unchecked")
  @Test
  public void testGetMethodAnnotations() throws Exception {
    Method method = ExampleService.class.getMethod("testJsonBody", DummyAccountInfo.class);
    testForAnns(method, Arrays.<Class<? extends Annotation>>asList(POST.class, Consumes.class));
    testForAnns(method, Arrays.<Class<? extends Annotation>>asList(Path.class));
    testForAnns(method, Arrays.<Class<? extends Annotation>>asList());

    List<Class<? extends Annotation>> classes =
        Arrays.asList(POST.class, GET.class, DELETE.class, PUT.class, HEAD.class);
    Map<Class<? extends Annotation>, Annotation> map =
        AnnotationUtils.getMethodAnnotationMap(method, classes);
    assertThat(
        map.keySet(), equalTo(sorted(Arrays.<Class<? extends Annotation>>asList(POST.class))));
    assertThat(map.get(POST.class), IsInstanceOf.instanceOf(POST.class));
  }
  public static void saveCoNLLFiles(
      String dir, Annotation dataset, boolean useSubTypes, boolean alreadyBIO) throws IOException {
    List<CoreMap> sentences = dataset.get(CoreAnnotations.SentencesAnnotation.class);

    String docid = null;
    PrintStream os = null;
    for (CoreMap sentence : sentences) {
      String myDocid = sentence.get(CoreAnnotations.DocIDAnnotation.class);
      if (docid == null || !myDocid.equals(docid)) {
        if (os != null) {
          os.close();
        }
        docid = myDocid;
        os = new PrintStream(new FileOutputStream(dir + File.separator + docid + ".conll"));
      }
      List<CoreLabel> labeledSentence =
          AnnotationUtils.sentenceEntityMentionsToCoreLabels(
              sentence, true, null, null, useSubTypes, alreadyBIO);
      assert (labeledSentence != null);

      String prev = null;
      for (CoreLabel word : labeledSentence) {
        String w = word.word().replaceAll("[ \t\n]+", "_");
        String t = word.get(CoreAnnotations.PartOfSpeechAnnotation.class);
        String l = word.get(CoreAnnotations.AnswerAnnotation.class);
        String nl = l;
        if (!alreadyBIO && !l.equals("O")) {
          if (prev != null && l.equals(prev)) nl = "I-" + l;
          else nl = "B-" + l;
        }
        String line = w + ' ' + t + ' ' + nl;
        String[] toks = line.split("[ \t\n]+");
        if (toks.length != 3) {
          throw new RuntimeException("INVALID LINE: \"" + line + '"');
        }
        os.printf("%s %s %s\n", w, t, nl);
        prev = l;
      }
      os.println();
    }
    if (os != null) {
      os.close();
    }
  }
Exemple #12
0
  /**
   * @param annotation
   * @return true if the annotation is used to describe the role of a feature in an interaction
   */
  public static boolean isFeatureRole(Annotation annotation) {

    // we have an intercation dependency
    return (AnnotationUtils.doesAnnotationHaveTopic(
            annotation, Feature.PREREQUISITE_PTM_MI, Feature.PREREQUISITE_PTM)
        || AnnotationUtils.doesAnnotationHaveTopic(
            annotation, Feature.RESULTING_PTM_MI, Feature.RESULTING_PTM)
        || AnnotationUtils.doesAnnotationHaveTopic(
            annotation, Feature.RESULTING_CLEAVAGE_MI, Feature.RESULTING_CLEAVAGE)
        || AnnotationUtils.doesAnnotationHaveTopic(
            annotation, Feature.DECREASING_PTM_MI, Feature.DECREASING_PTM)
        || AnnotationUtils.doesAnnotationHaveTopic(
            annotation, Feature.INCREASING_PTM_MI, Feature.INCREASING_PTM)
        || AnnotationUtils.doesAnnotationHaveTopic(
            annotation, Feature.DISRUPTING_PTM_MI, Feature.DISRUPTING_PTM)
        || AnnotationUtils.doesAnnotationHaveTopic(
            annotation, Feature.OBSERVED_PTM, Feature.OBSERVED_PTM_MI));
  }
  /*
   *  Model creation, saving, loading, and saving
   */
  public void train(Annotation doc) {
    List<List<CoreLabel>> trainingSet =
        AnnotationUtils.entityMentionsToCoreLabels(doc, annotationsToSkip, useSubTypes, useBIO);

    if (SAVE_CONLL_2003) {
      // dump a file in CoNLL-2003 format
      try {
        PrintStream os = new PrintStream(new FileOutputStream("train.conll"));
        // saveCoNLLFiles("/tmp/ace/train/", doc, useSubTypes, useBIO);
        saveCoNLL(os, trainingSet, useBIO);
        os.close();
      } catch (IOException e) {
        e.printStackTrace();
        System.exit(1);
      }
    }

    this.classifier = createClassifier();
    if (trainingSet.size() > 0) {
      this.classifier.train(Collections.unmodifiableCollection(trainingSet));
    }
  }
  @Test
  public void findAndSynthesizeAnnotationAttributesOnClassWithAttributeAliasesInTargetAnnotation() {
    String qualifier = "aliasForQualifier";

    // 1) Find and merge AnnotationAttributes from the annotation hierarchy
    AnnotationAttributes attributes =
        findMergedAnnotationAttributes(
            AliasedTransactionalComponentClass.class, AliasedTransactional.class);
    assertNotNull("@AliasedTransactional on AliasedTransactionalComponentClass.", attributes);

    // 2) Synthesize the AnnotationAttributes back into the target annotation
    AliasedTransactional annotation =
        AnnotationUtils.synthesizeAnnotation(
            attributes, AliasedTransactional.class, AliasedTransactionalComponentClass.class);
    assertNotNull(annotation);

    // 3) Verify that the AnnotationAttributes and synthesized annotation are equivalent
    assertEquals("TX value via attributes.", qualifier, attributes.getString("value"));
    assertEquals("TX value via synthesized annotation.", qualifier, annotation.value());
    assertEquals("TX qualifier via attributes.", qualifier, attributes.getString("qualifier"));
    assertEquals("TX qualifier via synthesized annotation.", qualifier, annotation.qualifier());
  }
  /**
   * Annotate an ExtractionDataSet with entities. This will modify the ExtractionDataSet in place.
   *
   * @param doc The dataset to label
   */
  @Override
  public void annotate(Annotation doc) {
    if (SAVE_CONLL_2003) {
      // dump a file in CoNLL-2003 format
      try {
        PrintStream os = new PrintStream(new FileOutputStream("test.conll"));
        List<List<CoreLabel>> labels =
            AnnotationUtils.entityMentionsToCoreLabels(doc, annotationsToSkip, useSubTypes, useBIO);
        BasicEntityExtractor.saveCoNLL(os, labels, true);
        // saveCoNLLFiles("/tmp/ace/test", doc, useSubTypes, useBIO);
        os.close();
      } catch (IOException e) {
        e.printStackTrace();
        System.exit(1);
      }
    }

    List<CoreMap> sents = doc.get(CoreAnnotations.SentencesAnnotation.class);
    int sentCount = 1;
    for (CoreMap sentence : sents) {
      if (useNERTags) {
        this.makeAnnotationFromAllNERTags(sentence);
      } else extractEntities(sentence, sentCount);
      sentCount++;
    }

    /*
    if(SAVE_CONLL_2003){
      try {
        saveCoNLLFiles("test_output/", doc, useSubTypes, useBIO);
        System.err.println("useBIO = " + useBIO);
      } catch (IOException e) {
        e.printStackTrace();
        System.exit(1);
      }
    }
    */
  }
  @Test
  public void findMergedAnnotationForMultipleMetaAnnotationsWithClashingAttributeNames() {
    String[] xmlLocations = asArray("test.xml");
    String[] propFiles = asArray("test.properties");

    Class<?> element = AliasedComposedContextConfigAndTestPropSourceClass.class;

    ContextConfig contextConfig = findMergedAnnotation(element, ContextConfig.class);
    assertNotNull("@ContextConfig on " + element, contextConfig);
    assertArrayEquals("locations", xmlLocations, contextConfig.locations());
    assertArrayEquals("value", xmlLocations, contextConfig.value());

    // Synthesized annotation
    TestPropSource testPropSource = AnnotationUtils.findAnnotation(element, TestPropSource.class);
    assertArrayEquals("locations", propFiles, testPropSource.locations());
    assertArrayEquals("value", propFiles, testPropSource.value());

    // Merged annotation
    testPropSource = findMergedAnnotation(element, TestPropSource.class);
    assertNotNull("@TestPropSource on " + element, testPropSource);
    assertArrayEquals("locations", propFiles, testPropSource.locations());
    assertArrayEquals("value", propFiles, testPropSource.value());
  }
 public TestExecutor(Configuration configuration) {
   this.configuration = configuration;
   this.machineConfiguration = createMachineConfiguration(AnnotationUtils.findTests(reflections));
   this.machine = createMachine(machineConfiguration);
 }
  public MBeanOperation build() {
    if (target == null) {
      throw new IllegalArgumentException("JmxOperation must have a target object");
    }

    // We must have a method to invoke
    if (concreteMethod == null) {
      throw new IllegalArgumentException("JmxOperation must have a concrete method");
    }

    String operationName = name;
    if (operationName == null) {
      operationName = concreteMethod.getName();
    }

    //
    // Build Parameter Infos
    // Extract parameter names from debug symbols
    String[] parameterNames = getParameterNames(concreteMethod);
    Class<?>[] types = concreteMethod.getParameterTypes();

    // Parameter annotations used form descriptor come from the annotated method, not the public
    // method
    Annotation[][] parameterAnnotations;
    if (annotatedMethod != null) {
      parameterAnnotations = annotatedMethod.getParameterAnnotations();
    } else {
      parameterAnnotations = new Annotation[parameterNames.length][];
    }

    MBeanParameterInfo[] parameterInfos = new MBeanParameterInfo[parameterNames.length];
    for (int i = 0; i < parameterNames.length; ++i) {
      // Parameter Descriptor
      Descriptor parameterDescriptor = AnnotationUtils.buildDescriptor(parameterAnnotations[i]);
      // Parameter Description
      String parameterDescription =
          AnnotationUtils.getDescription(parameterDescriptor, parameterAnnotations[i]);

      parameterInfos[i] =
          new MBeanParameterInfo(
              parameterNames[i], types[i].getName(), parameterDescription, parameterDescriptor);
    }

    // Descriptor
    Descriptor descriptor = null;
    if (annotatedMethod != null) {
      descriptor = AnnotationUtils.buildDescriptor(annotatedMethod);
    }

    // Description
    String description = AnnotationUtils.getDescription(descriptor, annotatedMethod);

    MBeanOperationInfo mbeanOperationInfo =
        new MBeanOperationInfo(
            operationName,
            description,
            parameterInfos,
            concreteMethod.getReturnType().getName(),
            MBeanOperationInfo.UNKNOWN,
            descriptor);

    return new ReflectionMBeanOperation(mbeanOperationInfo, target, concreteMethod);
  }
 private void executeAnnotation(Class<? extends Annotation> annotation, Context context) {
   AnnotationUtils.execute(annotation, context);
 }
  /**
   * Label entities in an ExtractionSentence. Assumes the classifier has already been trained.
   *
   * @param sentence ExtractionSentence that we want to extract entities from
   * @return an ExtractionSentence with text content, tree and entities set. Relations will not be
   *     set.
   */
  private CoreMap extractEntities(CoreMap sentence, int sentCount) {
    // don't add answer annotations
    List<CoreLabel> testSentence =
        AnnotationUtils.sentenceEntityMentionsToCoreLabels(
            sentence, false, annotationsToSkip, null, useSubTypes, useBIO);

    // now label the sentence
    List<CoreLabel> annotatedSentence = this.classifier.classify(testSentence);
    if (logger.isLoggable(Level.FINEST)) {
      logger.finest("CLASSFIER OUTPUT: " + annotatedSentence);
    }

    List<EntityMention> extractedEntities = new ArrayList<>();
    int i = 0;

    // variables which keep track of partially seen entities (i.e. we've seen
    // some but not all the words in them so far)
    String lastType = null;
    int startIndex = -1;

    //
    // note that labels may be in the BIO or just the IO format. we must handle both transparently
    //
    for (CoreLabel label : annotatedSentence) {
      String type = label.get(AnswerAnnotation.class);
      if (type.equals(SeqClassifierFlags.DEFAULT_BACKGROUND_SYMBOL)) {
        type = null;
      }

      // this is an entity end boundary followed by O
      if (type == null && lastType != null) {
        makeEntityMention(sentence, startIndex, i, lastType, extractedEntities, sentCount);
        logger.info("Found entity: " + extractedEntities.get(extractedEntities.size() - 1));
        startIndex = -1;
      }

      // entity start preceded by an O
      else if (lastType == null && type != null) {
        startIndex = i;
      }

      // entity end followed by another entity of different type
      else if (lastType != null
          && type != null
          && (type.startsWith("B-")
              || (lastType.startsWith("I-") && type.startsWith("I-") && !lastType.equals(type))
              || (notBIO(lastType) && notBIO(type) && !lastType.equals(type)))) {
        makeEntityMention(sentence, startIndex, i, lastType, extractedEntities, sentCount);
        logger.info("Found entity: " + extractedEntities.get(extractedEntities.size() - 1));
        startIndex = i;
      }

      lastType = type;
      i++;
    }

    // replace the original annotation with the predicted entities
    sentence.set(MachineReadingAnnotations.EntityMentionsAnnotation.class, extractedEntities);
    logger.finest("EXTRACTED ENTITIES: ");
    for (EntityMention e : extractedEntities) {
      if (logger.isLoggable(Level.FINEST)) {
        logger.finest("\t" + e);
      }
    }

    postprocessSentence(sentence, sentCount);

    return sentence;
  }