protected boolean useTiling(Blob blob, DocumentModel dm) {
    Long width = Long.valueOf(0);
    Long height = Long.valueOf(0);

    if ("Picture".equals(dm.getType())) {
      try {
        PictureResourceAdapter adapter = dm.getAdapter(PictureResourceAdapter.class);
        String xpath = adapter.getViewXPath(ORIGINAL_JPEG_VIEW_NAME);
        if (xpath == null) {
          xpath = adapter.getViewXPath(ORIGINAL_VIEW_NAME);
          if (xpath == null) {
            xpath = adapter.getFirstViewXPath();
          }
        }

        width = (Long) dm.getPropertyValue(xpath + "width");
        height = (Long) dm.getPropertyValue(xpath + "height");
      } catch (ClientException e) {
        log.error("Failed to get picture dimensions", e);
      }
    } else {
      ImagingService imagingService = Framework.getLocalService(ImagingService.class);
      if (imagingService != null) {
        Map<String, Object> imageMetadata = imagingService.getImageMetadata(blob);
        width = ((Integer) imageMetadata.get(MetadataConstants.META_WIDTH)).longValue();
        height = ((Integer) imageMetadata.get(MetadataConstants.META_HEIGHT)).longValue();
      }
    }

    Integer widthThreshold =
        Integer.valueOf(PictureTilingComponent.getEnvValue("WidthThreshold", "1200"));
    Integer heightThreshold =
        Integer.valueOf(PictureTilingComponent.getEnvValue("HeightThreshold", "1200"));
    return width > widthThreshold || height > heightThreshold;
  }
  @Test
  public void testAutoCheckOut() throws Exception {
    DocumentModel doc = new DocumentModelImpl("/", "file", "File");
    doc.setPropertyValue("dc:title", "t0");
    doc = session.createDocument(doc);
    assertTrue(doc.isCheckedOut());
    session.checkIn(doc.getRef(), null, null);
    doc.refresh();
    assertFalse(doc.isCheckedOut());

    // auto-checkout
    doc.setPropertyValue("dc:title", "t1");
    doc = session.saveDocument(doc);
    assertTrue(doc.isCheckedOut());

    session.checkIn(doc.getRef(), null, null);
    doc.refresh();
    assertFalse(doc.isCheckedOut());

    // disable auto-checkout
    doc.setPropertyValue("dc:title", "t2");
    doc.putContextData(VersioningService.DISABLE_AUTO_CHECKOUT, Boolean.TRUE);
    doc = session.saveDocument(doc);
    assertFalse(doc.isCheckedOut());
    assertEquals("t2", doc.getPropertyValue("dc:title"));

    // can still be checked out normally afterwards
    doc.checkOut();
    assertTrue(doc.isCheckedOut());
    assertEquals("t2", doc.getPropertyValue("dc:title"));
  }
  @Test
  public void testSignPDFDocumentArchive() throws Exception {
    Blob pdfBlob = Blobs.createBlob(origPdfFile, "application/pdf", null, "foo.pdf");
    DocumentModel doc = session.createDocumentModel("File");
    doc.setPropertyValue("file:content", (Serializable) pdfBlob);

    Blob signedBlob =
        signatureService.signDocument(
            doc,
            user,
            USER_KEY_PASSWORD,
            "test",
            false,
            SigningDisposition.ARCHIVE,
            "foo archive.pdf");

    assertEquals("foo.pdf", signedBlob.getFilename());
    assertEquals(Arrays.asList("Signature1"), getSignatureNames(signedBlob));
    assertEquals(signedBlob, doc.getPropertyValue("file:content"));
    @SuppressWarnings("unchecked")
    List<Map<String, Serializable>> files =
        (List<Map<String, Serializable>>) doc.getPropertyValue("files:files");
    assertEquals(1, files.size());
    Blob archivedBlob = (Blob) files.get(0).get("file");
    assertEquals("application/pdf", archivedBlob.getMimeType());
    assertEquals("foo archive.pdf", archivedBlob.getFilename());
    assertEquals("foo archive.pdf", files.get(0).get("filename"));
  }
  private void emailEnglishAssertions(String filePath) throws Exception {
    // initialize mailboxes
    getPersonalMailbox("jdoe");

    injectEmail(filePath);
    DocumentRef dayRef = new PathRef(CaseConstants.CASE_ROOT_DOCUMENT_PATH + "/2009/03/17");
    assertTrue(session.exists(dayRef));
    DocumentModelList envelopes = session.getChildren(dayRef, MailConstants.MAIL_ENVELOPE_TYPE);
    assertEquals(1, envelopes.size());

    DocumentModel envelopeDoc = envelopes.get(0);
    Case envelope = envelopeDoc.getAdapter(Case.class);
    List<DocumentModel> linkedDocs = envelope.getDocuments();
    assertEquals(2, linkedDocs.size());
    DocumentModel firstDoc = linkedDocs.get(0);

    String title = (String) firstDoc.getPropertyValue(CaseConstants.TITLE_PROPERTY_NAME);
    assertEquals("[Fwd: RENOUVELLEMENT DE SUPPORT ANNUEL NUXEO]", title);
    Calendar originalReceptionDate =
        (Calendar) firstDoc.getPropertyValue(CaseConstants.DOCUMENT_IMPORT_DATE_PROPERTY_NAME);
    assertEquals(
        emailDateParser.parse("Wed, 14 Jan 2009 15:15:25 +0100").getTime(),
        originalReceptionDate.getTime().getTime());
    Calendar receptionDate =
        (Calendar) firstDoc.getPropertyValue(CaseConstants.DOCUMENT_RECEIVE_DATE_PROPERTY_NAME);
    assertEquals(
        emailDateParser.parse("Tue, 17 Mar 2009 13:39:05 +0100").getTime(),
        receptionDate.getTime().getTime());

    Contacts senders = Contacts.getContactsForDoc(firstDoc, CaseConstants.CONTACTS_SENDERS);
    assertNotNull(senders);
    assertEquals(1, senders.size());
    Contact sender = senders.get(0);
    assertEquals("Sylvie KAPCOM", sender.getName());
    assertEquals("*****@*****.**", sender.getEmail());

    Contacts recipients = Contacts.getContactsForDoc(firstDoc, CaseConstants.CONTACTS_PARTICIPANTS);
    assertNotNull(recipients);
    assertEquals(2, recipients.size());

    assertEquals("*****@*****.**", recipients.get(0).getEmail());

    assertTrue(
        (recipients.get(1).getName() == null) || ("".equals(recipients.get(1).getName().trim())));
    assertEquals("*****@*****.**", recipients.get(1).getEmail());

    // testing content
    DocumentModel secondDoc = linkedDocs.get(1);
    Blob fileBlob = (Blob) secondDoc.getPropertyValue(CaseConstants.FILE_PROPERTY_NAME);

    assertEquals("The file blob filename is", "testpdf.pdf", fileBlob.getFilename());
    assertEquals("the file blob length is", 24016, fileBlob.getLength());

    String fileNamePropertyValue =
        (String) secondDoc.getPropertyValue(CaseConstants.FILENAME_PROPERTY_NAME);
    assertEquals("The filename property value is", "testpdf.pdf", fileNamePropertyValue);
  }
 protected MailboxHeader getMailboxHeader(DocumentModel doc) {
   try {
     String id = (String) doc.getPropertyValue(MailboxConstants.ID_FIELD);
     String title = (String) doc.getPropertyValue(MailboxConstants.TITLE_FIELD);
     String type = (String) doc.getPropertyValue(MailboxConstants.TYPE_FIELD);
     return new MailboxHeaderImpl(id, title, type);
   } catch (ClientException e) {
     throw new ClientRuntimeException(e);
   }
 }
    protected AdministrativeStatus wrap(DocumentModel doc) {

      String userLogin = (String) doc.getPropertyValue(LOGIN_PROPERTY);
      String id = (String) doc.getPropertyValue(INSTANCE_PROPERTY);
      String service = (String) doc.getPropertyValue(SERVICE_PROPERTY);
      String message = (String) doc.getPropertyValue(MESSAGE_PROPERTY);
      String state = (String) doc.getPropertyValue(STATUS_PROPERTY);
      Calendar modified = (Calendar) doc.getPropertyValue("dc:modified");

      return new AdministrativeStatus(state, message, modified, userLogin, id, service);
    }
  @Test
  public void testScalarCreatedWithDefaultValue() throws Exception {
    // given a doc saved with a property with a default value not modified
    getResponse(RequestType.POST, "path/", createDocumentJSON(null));

    // when I get it
    fetchInvalidations();
    DocumentModel doc = session.getDocument(new PathRef("/doc1"));

    // then the default value must be set
    assertNull(doc.getPropertyValue("dv:simpleWithoutDefault"));
    assertEquals("value", doc.getPropertyValue("dv:simpleWithDefault"));
  }
  @Test
  public void testMultiCreatedWithDefaultValue() throws Exception {
    // given a doc saved with a property with a default value not modified
    getResponse(RequestType.POST, "path/", createDocumentJSON(null));

    // when I get it
    fetchInvalidations();
    DocumentModel doc = session.getDocument(new PathRef("/doc1"));

    // then the default value must be set
    assertEquals(0, ((String[]) doc.getPropertyValue("dv:multiWithoutDefault")).length);
    assertArrayEquals(
        new String[] {"value1", "value2"}, (String[]) doc.getPropertyValue("dv:multiWithDefault"));
  }
  @Test
  public void testSignPDFDocumentReplace() throws Exception {
    Blob pdfBlob = Blobs.createBlob(origPdfFile, "application/pdf", null, "foo.pdf");
    DocumentModel doc = session.createDocumentModel("File");
    doc.setPropertyValue("file:content", (Serializable) pdfBlob);

    Blob signedBlob =
        signatureService.signDocument(
            doc, user, USER_KEY_PASSWORD, "test", false, SigningDisposition.REPLACE, null);

    assertEquals("foo.pdf", signedBlob.getFilename());
    assertEquals(Arrays.asList("Signature1"), getSignatureNames(signedBlob));
    assertEquals(signedBlob, doc.getPropertyValue("file:content"));
    assertEquals(Collections.emptyList(), doc.getPropertyValue("files:files"));
  }
  public AuthorityRefDocList getReferencingObjects(
      ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
      UriTemplateRegistry uriTemplateRegistry,
      List<String> serviceTypes,
      String propertyName,
      String itemcsid)
      throws Exception {
    AuthorityRefDocList authRefDocList = null;
    RepositoryInstanceInterface repoSession = null;
    boolean releaseRepoSession = false;

    try {
      RepositoryJavaClientImpl repoClient =
          (RepositoryJavaClientImpl) this.getRepositoryClient(ctx);
      repoSession = this.getRepositorySession();
      if (repoSession == null) {
        repoSession = repoClient.getRepositorySession(ctx);
        releaseRepoSession = true;
      }
      DocumentFilter myFilter = getDocumentFilter();

      try {
        DocumentWrapper<DocumentModel> wrapper = repoClient.getDoc(repoSession, ctx, itemcsid);
        DocumentModel docModel = wrapper.getWrappedObject();
        String refName = (String) docModel.getPropertyValue(AuthorityItemJAXBSchema.REF_NAME);
        authRefDocList =
            RefNameServiceUtils.getAuthorityRefDocs(
                repoSession,
                ctx,
                uriTemplateRegistry,
                repoClient,
                serviceTypes,
                refName,
                propertyName,
                myFilter,
                true /*computeTotal*/);
      } catch (PropertyException pe) {
        throw pe;
      } catch (DocumentException de) {
        throw de;
      } catch (Exception e) {
        if (logger.isDebugEnabled()) {
          logger.debug("Caught exception ", e);
        }
        throw new DocumentException(e);
      } finally {
        // If we got/aquired a new seesion then we're responsible for releasing it.
        if (releaseRepoSession && repoSession != null) {
          repoClient.releaseRepositorySession(ctx, repoSession);
        }
      }
    } catch (Exception e) {
      if (logger.isDebugEnabled()) {
        logger.debug("Caught exception ", e);
      }
      throw new DocumentException(e);
    }

    return authRefDocList;
  }
  @Test
  public void testAllowVersionWrite() {
    DocumentModel doc = session.createDocumentModel("/", "doc", "File");
    doc.setPropertyValue("icon", "icon1");
    doc = session.createDocument(doc);
    DocumentRef verRef = session.checkIn(doc.getRef(), null, null);

    // regular version cannot be written
    DocumentModel ver = session.getDocument(verRef);
    ver.setPropertyValue("icon", "icon2");
    try {
      session.saveDocument(ver);
      fail("Should not allow version write");
    } catch (PropertyException e) {
      assertTrue(e.getMessage(), e.getMessage().contains("Cannot set property on a version"));
    }

    // with proper option, it's allowed
    ver.setPropertyValue("icon", "icon3");
    ver.putContextData(CoreSession.ALLOW_VERSION_WRITE, Boolean.TRUE);
    session.saveDocument(ver);
    // refetch to check
    ver = session.getDocument(verRef);
    assertEquals("icon3", ver.getPropertyValue("icon"));
  }
  @Test
  public void testSaveRestoredVersionWithVersionAutoIncrement() {
    // check-in version 1.0, 2.0 and restore version 1.0
    DocumentModel doc = new DocumentModelImpl("/", "myfile", "File");
    doc = session.createDocument(doc);
    doc = session.saveDocument(doc);
    DocumentRef co = doc.getRef();
    DocumentRef ci1 = session.checkIn(co, VersioningOption.MAJOR, "first check-in");
    session.checkOut(co);
    maybeSleepToNextSecond();
    DocumentRef ci2 = session.checkIn(co, VersioningOption.MAJOR, "second check-in");
    waitForFulltextIndexing();
    maybeSleepToNextSecond();
    session.restoreToVersion(co, ci1);

    // save document with auto-increment should produce version 3.0
    doc = session.getDocument(co);
    assertEquals(doc.getVersionLabel(), "1.0");
    doc.getContextData()
        .putScopedValue(
            ScopeType.DEFAULT, VersioningService.VERSIONING_OPTION, VersioningOption.MAJOR);
    // mark as dirty - must change the value
    doc.setPropertyValue("dc:title", doc.getPropertyValue("dc:title") + " dirty");
    doc = session.saveDocument(doc);
    assertEquals(doc.getVersionLabel(), "3.0");
  }
 public static List<FontSize> getFontSizes() {
   List<FontSize> list = new ArrayList<FontSize>();
   Directories dir = Directories.FONT_SIZES;
   for (DocumentModel entry : getThemeService().getDirFontSizes()) {
     try {
       list.add(
           new FontSize(
               (String) entry.getPropertyValue(dir.idField()),
               (String) entry.getPropertyValue(dir.labelField())));
     } catch (PropertyException e) {
       LOG.error(e, e);
     } catch (ClientException e) {
       LOG.error(e, e);
     }
   }
   return list;
 }
 protected long getVersion(DocumentModel doc, String prop) {
   Object propVal = doc.getPropertyValue(prop);
   if (propVal == null || !(propVal instanceof Long)) {
     return -1;
   } else {
     return ((Long) propVal).longValue();
   }
 }
 private long getValidVersionNumber(String propName) {
   Object propVal;
   try {
     propVal = doc.getPropertyValue(propName);
   } catch (ClientException e) {
     throw new ClientRuntimeException(e);
   }
   return (propVal == null || !(propVal instanceof Long)) ? 0 : ((Long) propVal).longValue();
 }
示例#16
0
 public String getVideoPosterLink() throws PropertyException, ClientException {
   String lastModification =
       "" + (((Calendar) doc.getPropertyValue("dc:modified")).getTimeInMillis());
   String url = uriInfo.getBaseUri().toASCIIString().replace("/site/", "/");
   url +=
       DocumentModelFunctions.fileUrl(
           "downloadPicture", doc, "StaticPlayerView:content", lastModification);
   return url;
 }
  @Test
  public void testSignDocumentAttach() throws Exception {
    Blob txtBlob = Blobs.createBlob(helloTxtFile, "text/plain", null, "foo.txt");
    DocumentModel doc = session.createDocumentModel("File");
    doc.setPropertyValue("file:content", (Serializable) txtBlob);

    Blob signedBlob =
        signatureService.signDocument(
            doc, user, USER_KEY_PASSWORD, "test", false, SigningDisposition.ATTACH, null);

    assertEquals("foo.pdf", signedBlob.getFilename());
    assertEquals(Arrays.asList("Signature1"), getSignatureNames(signedBlob));
    assertEquals(txtBlob, doc.getPropertyValue("file:content"));
    @SuppressWarnings("unchecked")
    List<Map<String, Serializable>> files =
        (List<Map<String, Serializable>>) doc.getPropertyValue("files:files");
    assertEquals(1, files.size());
    assertEquals(signedBlob, files.get(0).get("file"));
  }
示例#18
0
 public boolean isVideoPlayerReady() throws PropertyException, ClientException {
   String FILE_CONTENT = "file:content";
   Blob mainBlob = (Blob) doc.getPropertyValue(FILE_CONTENT);
   if (mainBlob != null
       && ("video/mp4".equals(mainBlob.getMimeType())
           || "video/webm".equals(mainBlob.getMimeType()))) {
     return true;
   }
   return webmTranscodedVideo != null || mp4TranscodedVideo != null;
 }
  @Test
  public void testCreateSingleTaskAndRunOperationChain() throws Exception {
    OperationContext ctx = new OperationContext(coreSession);
    ctx.setInput(document);

    List<Task> tasks = taskService.getTaskInstances(document, (NuxeoPrincipal) null, coreSession);
    assertNotNull(tasks);
    assertEquals(0, tasks.size());

    automationService.run(ctx, "createSingleTaskAndRunOperationChain");

    tasks = taskService.getTaskInstances(document, (NuxeoPrincipal) null, coreSession);
    assertEquals(1, tasks.size());

    Task task = tasks.get(0);

    // accept task
    taskService.acceptTask(
        coreSession, (NuxeoPrincipal) coreSession.getPrincipal(), task, "ok i'm in");
    coreSession.save();
    // test task again
    tasks = taskService.getTaskInstances(document, (NuxeoPrincipal) null, coreSession);
    // ended tasks are filtered
    assertEquals(0, tasks.size());

    // check document metadata, refetching doc from core
    document = coreSession.getDocument(document.getRef());
    assertEquals("This document has been accepted", document.getPropertyValue("dc:description"));

    // run another time, and this time reject
    automationService.run(ctx, "createSingleTaskAndRunOperationChain");
    tasks = taskService.getTaskInstances(document, (NuxeoPrincipal) null, coreSession);
    assertEquals(1, tasks.size());
    taskService.rejectTask(
        coreSession,
        (NuxeoPrincipal) coreSession.getPrincipal(),
        tasks.get(0),
        "i don't agree with what you're saying");
    document = coreSession.getDocument(document.getRef());
    assertEquals(
        "This document has been rejected !!!", document.getPropertyValue("dc:description"));
  }
 protected List<String> getList(DocumentModel doc, String property) {
   String[] content;
   try {
     content = (String[]) doc.getPropertyValue(property);
   } catch (PropertyException e) {
     return Collections.emptyList();
   }
   if (content != null) {
     return Collections.unmodifiableList(Arrays.asList(content));
   }
   return Collections.emptyList();
 }
 private List<String> getAvailableNameWidget(String docType) {
   List<String> available = new ArrayList<String>();
   try {
     for (DocumentModel doc : getPageWidgets(docType)) {
       available.add((String) doc.getPropertyValue("labshtmlpagewidgets:wname"));
     }
   } catch (PropertyException e) {
     LOG.error(e, e);
   } catch (ClientException e) {
     LOG.error(e, e);
   }
   return available;
 }
示例#22
0
 protected String getVideoLink(String mimetype, TranscodedVideo transcodedVideo)
     throws PropertyException, ClientException {
   String FILE_CONTENT = "file:content";
   Blob mainBlob = (Blob) doc.getPropertyValue(FILE_CONTENT);
   if (mainBlob != null && mimetype.equals(mainBlob.getMimeType())) {
     return bigFileUrl(FILE_CONTENT, mainBlob.getFilename());
   } else if (transcodedVideo != null) {
     String blobPropertyName = transcodedVideo.getBlobPropertyName();
     return bigFileUrl(blobPropertyName, transcodedVideo.getBlob().getFilename());
   } else {
     return null;
   }
 }
  @Test
  @Ignore
  // FIXME: NXP-19466 - default value lifecycle is not correctly managed
  public void testScalarSetOnNullDontSetDefaultValueAgain() throws Exception {
    // given a doc saved with a property with a default value set to null
    getResponse(RequestType.POST, "path/", createDocumentJSON("\"dv:simpleWithDefault\": null"));

    // when I get it
    fetchInvalidations();
    DocumentModel doc = session.getDocument(new PathRef("/doc1"));

    // then the property should remain null
    doc = session.getDocument(doc.getRef());
    assertNull(doc.getPropertyValue("dv:simpleWithDefault"));
  }
 public List<String> getUncategorizedWidgets(String docType) {
   List<String> declaredWidgets = getDeclaredHtmlWidgets(docType);
   for (String group : getPageWidgetGroups(docType)) {
     for (DocumentModel widget : getPageWidgets(docType, group)) {
       try {
         declaredWidgets.remove(widget.getPropertyValue("labshtmlpagewidgets:wname"));
       } catch (PropertyException e) {
         LOG.error(e, e);
       } catch (ClientException e) {
         LOG.error(e, e);
       }
     }
   }
   return declaredWidgets;
 }
 @Override
 public Locale getLocale(CoreSession repo) throws ClientException {
   UserProfileService userProfileService = Framework.getLocalService(UserProfileService.class);
   DocumentModel userProfileDoc = userProfileService.getUserProfileDocument(repo);
   String locale =
       (String) userProfileDoc.getPropertyValue(UserProfileConstants.USER_PROFILE_LOCALE);
   if (locale == null || locale.trim().length() == 0) {
     // undefined if not set
     return null;
   }
   try {
     return LocaleUtils.toLocale(locale);
   } catch (Exception e) {
     log.error("Locale parse exception:  \"" + locale + "\"", e);
   }
   return null;
 }
 @SuppressWarnings("unchecked")
 public ContentViewConfigurationAdapter(DocumentModel doc) {
   documentRef = doc.getRef();
   typeToContentViewNames = new HashMap<String, List<String>>();
   try {
     List<Map<String, String>> cvNamesByType =
         (List<Map<String, String>>)
             doc.getPropertyValue(CONTENT_VIEW_CONFIGURATION_NAMES_BY_TYPE);
     for (Map<String, String> typeToCv : cvNamesByType) {
       String type = typeToCv.get(CONTENT_VIEW_CONFIGURATION_DOC_TYPE);
       String cvName = typeToCv.get(CONTENT_VIEW_CONFIGURATION_CONTENT_VIEW);
       if (typeToContentViewNames.containsKey(type)) {
         typeToContentViewNames.get(type).add(cvName);
       } else {
         List<String> cvNames = new ArrayList<String>();
         cvNames.add(cvName);
         typeToContentViewNames.put(type, cvNames);
       }
     }
   } catch (ClientException e) {
     log.error("Failed to get ContentViewConfiguration", e);
   }
 }
    @Override
    public void run() {
      StringBuilder sb = new StringBuilder("select * from ");
      sb.append(ADMINISTRATIVE_STATUS_DOCUMENT_TYPE);

      boolean onlyFetchIds = false;
      if (instanceId == null) {
        onlyFetchIds = true;
      } else {
        sb.append(" where ");
        sb.append(INSTANCE_PROPERTY);
        sb.append("='");
        sb.append(instanceId);
        sb.append("'");
        if (serviceId != null) {
          sb.append(" AND ");
          sb.append(SERVICE_PROPERTY);
          sb.append("='");
          sb.append(serviceId);
          sb.append("'");
        }
      }

      DocumentModelList result = session.query(sb.toString());

      for (DocumentModel doc : result) {
        if (onlyFetchIds) {
          String id = (String) doc.getPropertyValue(INSTANCE_PROPERTY);
          if (!allInstanceIds.contains(id)) {
            allInstanceIds.add(id);
          }
        } else {
          statuses.add(wrap(doc));
        }
      }
    }
  protected void checkFileItem(
      FileItem fileItem,
      String fileItemIdPrefix,
      DocumentModel doc,
      String parentId,
      String parentPath,
      String name,
      String creator,
      String lastContributor) {

    String expectedFileItemId = fileItemIdPrefix + doc.getId();
    assertEquals(expectedFileItemId, fileItem.getId());
    assertEquals(parentId, fileItem.getParentId());
    assertEquals(parentPath + "/" + expectedFileItemId, fileItem.getPath());
    assertEquals(name, fileItem.getName());
    assertFalse(fileItem.isFolder());
    assertEquals(creator, fileItem.getCreator());
    assertEquals(lastContributor, fileItem.getLastContributor());
    assertEquals("nxfile/test/" + doc.getId() + "/blobholder:0/" + name, fileItem.getDownloadURL());
    assertEquals("MD5", fileItem.getDigestAlgorithm());
    assertEquals(
        ((org.nuxeo.ecm.core.api.Blob) doc.getPropertyValue("file:content")).getDigest(),
        fileItem.getDigest());
  }
 @SuppressWarnings("unchecked")
 protected <T> T getPropertyValue(DocumentModel doc, String propertyName) {
   return (T) doc.getPropertyValue(propertyName);
 }
  @Override
  public int compare(DocumentModel doc1, DocumentModel doc2) {
    if (sortPropertyPath == null) {
      log.error("Cannot sort: no sort property path set");
      return 0;
    }

    if (doc1 == null && doc2 == null) {
      return 0;
    } else if (doc1 == null) {
      return -1;
    } else if (doc2 == null) {
      return 1;
    }

    Object v1;
    try {
      v1 = doc1.getPropertyValue(sortPropertyPath);
    } catch (PropertyException e) {
      v1 = null;
    }
    Object v2;
    try {
      v2 = doc2.getPropertyValue(sortPropertyPath);
    } catch (PropertyException e) {
      v2 = null;
    }
    boolean useHash = false;
    if (v1 == null && v2 == null) {
      useHash = true;
    } else if (v1 == null) {
      return -1;
    } else if (v2 == null) {
      return 1;
    }

    final int cmp;
    if (v1 instanceof Long && v2 instanceof Long) {
      cmp = ((Long) v1).compareTo((Long) v2);
    } else if (v1 instanceof Integer && v2 instanceof Integer) {
      cmp = ((Integer) v1).compareTo((Integer) v2);
    } else if (!useHash) { // avoid NPE
      cmp = collator.compare(v1.toString(), v2.toString());
    } else {
      cmp = 0;
    }

    if (cmp == 0) {
      useHash = true;
    }
    if (useHash) {
      // everything being equal, provide consistent ordering
      if (doc1.hashCode() == doc2.hashCode()) {
        return 0;
      } else if (doc1.hashCode() < doc2.hashCode()) {
        return -1;
      } else {
        return 1;
      }
    }
    return cmp;
  }