@SuppressWarnings("unchecked")
  private AnnotationView buildAnnotationView(Annotation annotation, boolean loadAllReplies) {
    Object values[];
    try {
      values =
          (Object[])
              hibernateTemplate
                  .findByCriteria(
                      DetachedCriteria.forClass(Article.class)
                          .add(Restrictions.eq("ID", annotation.getArticleID()))
                          .setProjection(
                              Projections.projectionList()
                                  .add(Projections.property("doi"))
                                  .add(Projections.property("title"))),
                      0,
                      1)
                  .get(0);

    } catch (IndexOutOfBoundsException e) {
      // this should never happen
      throw new IllegalStateException(
          "Annotation "
              + annotation.getID()
              + " pointed to an article that didn't exist;"
              + " articleID: "
              + annotation.getArticleID());
    }

    String articleDoi = (String) values[0];
    String articleTitle = (String) values[1];

    return buildAnnotationView(annotation, articleDoi, articleTitle, loadAllReplies);
  }
  @SuppressWarnings("unchecked")
  private AnnotationView buildAnnotationView(
      Annotation annotation, String articleDoi, String articleTitle, boolean loadAllReplies) {
    Map<Long, List<Annotation>> fulReplyMap = null;
    if (loadAllReplies) {
      fulReplyMap = buildReplyMap(annotation.getArticleID());
    }

    return new AnnotationView(annotation, articleDoi, articleTitle, fulReplyMap);
  }
  @Override
  @Transactional
  public Long createReply(
      UserProfile user, Long parentId, String title, String body, @Nullable String ciStatement) {
    if (parentId == null) {
      throw new IllegalArgumentException("Attempting to create reply with null parent id");
    }
    log.debug("Creating reply to {}; title: {}; body: {}", new Object[] {parentId, title, body});
    Long articleID;
    try {
      articleID =
          (Long)
              hibernateTemplate
                  .findByCriteria(
                      DetachedCriteria.forClass(Annotation.class)
                          .add(Restrictions.eq("ID", parentId))
                          .setProjection(Projections.property("articleID")),
                      0,
                      1)
                  .get(0);
    } catch (IndexOutOfBoundsException e) {
      throw new IllegalArgumentException("Invalid annotation id: " + parentId);
    }

    Annotation reply = new Annotation(user, AnnotationType.REPLY, articleID);
    reply.setParentID(parentId);
    reply.setTitle(title);
    reply.setBody(body);
    reply.setCompetingInterestBody(ciStatement);
    reply.setAnnotationUri(URIGenerator.generate(reply));
    return (Long) hibernateTemplate.save(reply);
  }
  @Override
  @Transactional
  public Long createComment(
      UserProfile user, String articleDoi, String title, String body, String ciStatement) {
    if (articleDoi == null) {
      throw new IllegalArgumentException("Attempted to create comment with null article id");
    } else if (user == null || user.getID() == null) {
      throw new IllegalArgumentException("Attempted to create comment without a creator");
    } else if (body == null || body.isEmpty()) {
      throw new IllegalArgumentException("Attempted to create comment with no body");
    }

    log.debug(
        "Creating comment on article: {}; title: {}; body: {}",
        new Object[] {articleDoi, title, body});
    Long articleID;
    try {
      articleID =
          (Long)
              hibernateTemplate
                  .findByCriteria(
                      DetachedCriteria.forClass(Article.class)
                          .add(Restrictions.eq("doi", articleDoi))
                          .setProjection(Projections.id()))
                  .get(0);
    } catch (IndexOutOfBoundsException e) {
      throw new IllegalArgumentException("Invalid doi: " + articleDoi);
    }

    // generate an annotation uri
    Annotation comment = new Annotation(user, AnnotationType.COMMENT, articleID);
    comment.setAnnotationUri(URIGenerator.generate(comment));
    comment.setTitle(title);
    comment.setBody(body);
    comment.setCompetingInterestBody(ciStatement);

    Long id = (Long) hibernateTemplate.save(comment);

    return id;
  }
 /**
  * Build up a map of id, and replies to that id so we can initialize the reply tree
  *
  * @param articleId
  * @return
  */
 @SuppressWarnings("unchecked")
 private Map<Long, List<Annotation>> buildReplyMap(Long articleId) {
   Map<Long, List<Annotation>> fullReplyMap = new HashMap<Long, List<Annotation>>();
   List<Annotation> allReplies =
       hibernateTemplate.findByCriteria(
           DetachedCriteria.forClass(Annotation.class)
               .add(Restrictions.eq("articleID", articleId))
               .add(Restrictions.eq("type", AnnotationType.REPLY)));
   for (Annotation reply : allReplies) {
     // parent id should never be null on a reply
     if (reply.getParentID() == null) {
       log.warn("Found a reply with null parent id.  Reply id: " + reply.getID());
     } else {
       if (!fullReplyMap.containsKey(reply.getParentID())) {
         fullReplyMap.put(reply.getParentID(), new ArrayList<Annotation>());
       }
       fullReplyMap.get(reply.getParentID()).add(reply);
     }
   }
   return Collections.unmodifiableMap(fullReplyMap);
 }
Exemple #6
0
  protected void checkAnnotationProperties(AnnotationView result, Annotation expected) {
    if (expected.getType() == AnnotationType.MINOR_CORRECTION) {
      assertEquals(
          result.getTitle(),
          "Minor Correction: " + expected.getTitle(),
          "Annotation view had incorrect title");
    } else if (expected.getType() == AnnotationType.FORMAL_CORRECTION) {
      assertEquals(
          result.getTitle(),
          "Formal Correction: " + expected.getTitle(),
          "Annotation view had incorrect title");
    } else if (expected.getType() == AnnotationType.RETRACTION) {
      assertEquals(
          result.getTitle(),
          "Retraction: " + expected.getTitle(),
          "Annotation view had incorrect title");
    }
    assertEquals(
        result.getBody(),
        "<p>" + expected.getBody() + "</p>",
        "Annotation view had incorrect body");
    assertEquals(
        result.getCompetingInterestStatement(),
        expected.getCompetingInterestBody() == null ? "" : expected.getCompetingInterestBody(),
        "Annotation view had incorrect ci statement");
    assertEquals(
        result.getAnnotationUri(),
        expected.getAnnotationUri(),
        "Annotation view had incorrect annotation uri");
    assertEquals(
        result.getCreatorID(),
        expected.getCreator().getID(),
        "Annotation view had incorrect creator id");
    assertEquals(
        result.getCreatorDisplayName(),
        expected.getCreator().getDisplayName(),
        "Annotation view had incorrect creator name");

    if (Arrays.asList(
            AnnotationType.FORMAL_CORRECTION,
            AnnotationType.MINOR_CORRECTION,
            AnnotationType.RETRACTION)
        .contains(expected.getType())) {
      assertTrue(result.isCorrection(), "Result should have been created as a correction");
    } else {
      assertFalse(result.isCorrection(), "Result should not have been created as a correction");
    }

    if (expected.getAnnotationCitation() == null) {
      assertNull(result.getCitation(), "returned non-null citation when null was expected");
    } else {
      assertNotNull(result.getCitation(), "returned null citation when non-null was expected");
      assertEquals(
          result.getCitation().getTitle(),
          expected.getAnnotationCitation().getTitle(),
          "Returned citation with incorrect title");
      assertEquals(
          result.getCitation().geteLocationId(),
          expected.getAnnotationCitation().getELocationId(),
          "Returned citation with incorrect eLocationId");
      assertEquals(
          result.getCitation().getJournal(),
          expected.getAnnotationCitation().getJournal(),
          "Returned citation with incorrect journal");
      assertEquals(
          result.getCitation().getYear(),
          expected.getAnnotationCitation().getYear(),
          "Returned citation with incorrect year");

      assertEquals(
          result.getCitation().getVolume(),
          expected.getAnnotationCitation().getVolume(),
          "Returned citation with incorrect volume");
      assertEquals(
          result.getCitation().getIssue(),
          expected.getAnnotationCitation().getIssue(),
          "Returned citation with incorrect issue");
      assertEquals(
          result.getCitation().getSummary(),
          expected.getAnnotationCitation().getSummary(),
          "Returned citation with incorrect summary");
      assertEquals(
          result.getCitation().getNote(),
          expected.getAnnotationCitation().getNote(),
          "Returned citation with incorrect note");

      if (expected.getAnnotationCitation().getCollaborativeAuthors() != null) {
        assertEqualsNoOrder(
            result.getCitation().getCollabAuthors(),
            expected.getAnnotationCitation().getCollaborativeAuthors().toArray(),
            "Returned citation with incorrect collab authors");
      } else {
        assertTrue(
            ArrayUtils.isEmpty(result.getCitation().getCollabAuthors()),
            "Returned non-empty collab authors when empty was expected");
      }
      if (expected.getAnnotationCitation().getAuthors() != null) {
        assertNotNull(
            result.getCitation().getAuthors(), "Returned null authors when authors were expected");
        assertEquals(
            result.getCitation().getAuthors().length,
            expected.getAnnotationCitation().getAuthors().size(),
            "Returned incorrect number of authors");
        for (int i = 0; i < result.getCitation().getAuthors().length; i++) {
          AuthorView actualAuthor = result.getCitation().getAuthors()[i];
          CorrectedAuthor expectedAuthor = expected.getAnnotationCitation().getAuthors().get(i);
          assertEquals(
              actualAuthor.getGivenNames(),
              expectedAuthor.getGivenNames(),
              "Author " + (i + 1) + " had incorrect given names");
          assertEquals(
              actualAuthor.getSurnames(),
              expectedAuthor.getSurName(),
              "Author " + (i + 1) + " had incorrect surnames");
          assertEquals(
              actualAuthor.getSuffix(),
              expectedAuthor.getSuffix(),
              "Author " + (i + 1) + " had incorrect suffix");
        }
      }
    }
  }
  /**
   * Get a list of all annotations satisfying the given criteria.
   *
   * @param startDate search for annotation after start date.
   * @param endDate is the date to search until. If null, search until present date
   * @param annotTypes List of annotation types
   * @param maxResults the maximum number of results to return, or 0 for no limit
   * @param journal journalName
   * @return the (possibly empty) list of article annotations.
   * @throws ParseException if any of the dates or query could not be parsed
   * @throws URISyntaxException if an element of annotType cannot be parsed as a URI
   */
  @Override
  @Transactional(readOnly = true)
  @SuppressWarnings("unchecked")
  public List<AnnotationView> getAnnotations(
      final Date startDate,
      final Date endDate,
      final Set<String> annotTypes,
      final int maxResults,
      final String journal)
      throws ParseException, URISyntaxException {
    /**
     * * There may be a more efficient way to do this other than querying the database twice, at
     * some point in time we might improve how hibernate does the object mappings
     *
     * <p>This execute returns annotationIDs, article DOIs and titles, which are needed to
     * construction the annotionView object
     */
    Map<Long, String[]> results =
        (Map<Long, String[]>)
            hibernateTemplate.execute(
                new HibernateCallback() {
                  @Override
                  public Object doInHibernate(Session session)
                      throws HibernateException, SQLException {

                    /**
                     * URIGen We have to do this with SQL because of how the mappings are currently
                     * defined And hence, there is no way to unit test this
                     */
                    StringBuilder sqlQuery = new StringBuilder();
                    Map<String, Object> params = new HashMap<String, Object>(3);

                    sqlQuery.append("select ann.annotationID, art.doi, art.title ");
                    sqlQuery.append("from annotation ann ");
                    sqlQuery.append("join article art on art.articleID = ann.articleID ");
                    sqlQuery.append("join journal j on art.eIssn = j.eIssn ");
                    sqlQuery.append("where j.journalKey = :journal ");
                    params.put("journal", journal);

                    if (startDate != null) {
                      sqlQuery.append(" and ann.created > :startDate");
                      params.put("startDate", startDate);
                    }

                    if (endDate != null) {
                      sqlQuery.append(" and ann.created < :endDate");
                      params.put("endDate", endDate);
                    }

                    if (annotTypes != null) {
                      sqlQuery.append(" and ann.type in (:annotTypes)");
                      params.put("annotTypes", annotTypes);
                    }

                    sqlQuery.append(" order by ann.created desc");

                    SQLQuery query = session.createSQLQuery(sqlQuery.toString());
                    query.setProperties(params);

                    if (maxResults > 0) {
                      query.setMaxResults(maxResults);
                    }

                    List<Object[]> tempResults = query.list();
                    Map<Long, String[]> results = new HashMap<Long, String[]>(tempResults.size());

                    for (Object[] obj : tempResults) {
                      // This forces this method to return Long values and not BigInteger
                      results.put(
                          (((Number) obj[0]).longValue()),
                          new String[] {(String) obj[1], (String) obj[2]});
                    }

                    return results;
                  }
                });

    // The previous query puts annotationID and doi into the map. annotationID is key
    // I do this to avoid extra doi lookups later in the code.

    if (results.size() > 0) {
      DetachedCriteria criteria =
          DetachedCriteria.forClass(Annotation.class)
              .add(Restrictions.in("ID", results.keySet()))
              .addOrder(Order.desc("created"))
              .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

      List<Annotation> annotations = hibernateTemplate.findByCriteria(criteria);
      List<AnnotationView> views = new ArrayList<AnnotationView>(annotations.size());

      for (Annotation ann : annotations) {
        String articleDoi = results.get(ann.getID())[0];
        String articleTitle = results.get(ann.getID())[1];
        views.add(buildAnnotationView(ann, articleDoi, articleTitle, false));
      }

      return views;
    } else {
      return new ArrayList<AnnotationView>();
    }
  }