@Test
  public void testResolveDocumentReference() throws Exception {
    EntityReference reference = resolver.resolve("", EntityType.DOCUMENT);
    Assert.assertNull(reference);

    reference = resolver.resolve("space.page", EntityType.DOCUMENT);
    Assert.assertNull(reference.extractReference(EntityType.WIKI));
    Assert.assertEquals("space", reference.extractReference(EntityType.SPACE).getName());
    Assert.assertEquals("page", reference.getName());

    reference = resolver.resolve("wiki:space.page", EntityType.DOCUMENT);
    Assert.assertEquals("wiki", reference.extractReference(EntityType.WIKI).getName());
    Assert.assertEquals("space", reference.extractReference(EntityType.SPACE).getName());
    Assert.assertEquals("page", reference.getName());
  }
  @Test
  public void testAuthorWithDocument() throws Exception {
    EntityReferenceSerializer<String> compactWikiEntityReferenceSerializer =
        this.oldcore.getMocker().getInstance(EntityReferenceSerializer.TYPE_STRING, "compactwiki");
    DocumentReferenceResolver<EntityReference> explicitDocumentReferenceResolver =
        this.oldcore
            .getMocker()
            .registerMockComponent(DocumentReferenceResolver.TYPE_REFERENCE, "explicit");
    EntityReferenceResolver<String> xclassEntityReferenceResolver =
        this.oldcore
            .getMocker()
            .registerMockComponent(EntityReferenceResolver.TYPE_STRING, "xclass");

    XWikiDocument document = new XWikiDocument(new DocumentReference("wiki", "space", "page"));
    XWikiAttachment attachment = new XWikiAttachment(document, "filename");

    // getAuthor() based on getAuthorReference()
    DocumentReference userReference = new DocumentReference("userwiki", "userspace", "userpage");
    attachment.setAuthorReference(userReference);
    assertEquals(userReference, attachment.getAuthorReference());
    when(compactWikiEntityReferenceSerializer.serialize(userReference, attachment.getReference()))
        .thenReturn("stringUserReference");
    assertEquals("stringUserReference", attachment.getAuthor());

    // getAuthorReference() based on getAuthor()
    attachment.setAuthor("author");
    assertEquals("author", attachment.getAuthor());
    userReference = new DocumentReference("wiki", "XWiki", "author");
    EntityReference relativeUserReference =
        userReference.removeParent(userReference.getWikiReference());
    when(xclassEntityReferenceResolver.resolve("author", EntityType.DOCUMENT))
        .thenReturn(relativeUserReference);
    when(explicitDocumentReferenceResolver.resolve(
            relativeUserReference, attachment.getReference()))
        .thenReturn(userReference);
    assertEquals(userReference, attachment.getAuthorReference());

    // Guest author.
    attachment.setAuthor(XWikiRightService.GUEST_USER);
    userReference = new DocumentReference("wiki", "XWiki", XWikiRightService.GUEST_USER);
    relativeUserReference = userReference.removeParent(userReference.getWikiReference());
    when(xclassEntityReferenceResolver.resolve(any(String.class), eq(EntityType.DOCUMENT)))
        .thenReturn(relativeUserReference);
    when(explicitDocumentReferenceResolver.resolve(
            relativeUserReference, attachment.getReference()))
        .thenReturn(userReference);
    assertNull(attachment.getAuthorReference());
  }
  @Test
  public void testSerializeReferenceWithChild() {
    EntityReference reference = resolver.resolve("wiki:Space.Page", EntityType.DOCUMENT);
    Assert.assertEquals("wiki:Space", serializer.serialize(reference.getParent()));

    Assert.assertEquals("wiki", serializer.serialize(reference.getParent().getParent()));
  }
  @Test
  public void testAuthorWithoutDocument() throws Exception {
    EntityReferenceSerializer<String> compactWikiEntityReferenceSerializer =
        this.oldcore.getMocker().getInstance(EntityReferenceSerializer.TYPE_STRING, "compactwiki");
    AttachmentReferenceResolver<String> currentAttachmentReferenceResolver =
        this.oldcore.getMocker().getInstance(AttachmentReferenceResolver.TYPE_STRING, "current");
    DocumentReferenceResolver<EntityReference> explicitDocumentReferenceResolver =
        this.oldcore
            .getMocker()
            .registerMockComponent(DocumentReferenceResolver.TYPE_REFERENCE, "explicit");
    EntityReferenceResolver<String> xclassEntityReferenceResolver =
        this.oldcore
            .getMocker()
            .registerMockComponent(EntityReferenceResolver.TYPE_STRING, "xclass");

    XWikiAttachment attachment = new XWikiAttachment(null, "filename");
    DocumentReference currentDocumentReference =
        new DocumentReference("currentWiki", "currentSpage", "currentPage");
    AttachmentReference attachmentReference =
        new AttachmentReference(attachment.getFilename(), currentDocumentReference);

    // getAuthor() based on getAuthorReference()
    DocumentReference userReference = new DocumentReference("userwiki", "userspace", "userpage");
    attachment.setAuthorReference(userReference);
    assertEquals(userReference, attachment.getAuthorReference());
    when(currentAttachmentReferenceResolver.resolve(attachment.getFilename()))
        .thenReturn(attachmentReference);
    when(compactWikiEntityReferenceSerializer.serialize(userReference, attachmentReference))
        .thenReturn("stringUserReference");
    assertEquals("stringUserReference", attachment.getAuthor());

    // getAuthorReference() based on getAuthor()
    attachment.setAuthor("author");
    assertEquals("author", attachment.getAuthor());
    userReference = new DocumentReference("wiki", "XWiki", "author");
    EntityReference relativeUserReference =
        userReference.removeParent(userReference.getWikiReference());
    when(xclassEntityReferenceResolver.resolve("author", EntityType.DOCUMENT))
        .thenReturn(relativeUserReference);
    when(explicitDocumentReferenceResolver.resolve(
            relativeUserReference, attachment.getReference()))
        .thenReturn(userReference);
    assertEquals(userReference, attachment.getAuthorReference());
  }
  @Test
  public void testSerializeAttachmentReference() throws Exception {
    EntityReference reference = resolver.resolve("wiki:space.page@filename", EntityType.ATTACHMENT);
    Assert.assertEquals("wiki:space.page@filename", serializer.serialize(reference));

    reference = resolver.resolve("", EntityType.ATTACHMENT);
    Assert.assertEquals("defwiki:defspace.defpage@deffilename", serializer.serialize(reference));

    reference = resolver.resolve("wiki:[email protected]", EntityType.ATTACHMENT);
    Assert.assertEquals("wiki:[email protected]", serializer.serialize(reference));

    reference = resolver.resolve("some:file.name", EntityType.ATTACHMENT);
    Assert.assertEquals("defwiki:defspace.defpage@some:file.name", serializer.serialize(reference));

    // Test escapes

    reference = resolver.resolve(":.\\@", EntityType.ATTACHMENT);
    Assert.assertEquals("defwiki:defspace.defpage@:.\\@", serializer.serialize(reference));
  }
  /**
   * Add rendered document to ZIP stream.
   *
   * @param pageName the name (used with {@link com.xpn.xwiki.XWiki#getDocument(String,
   *     XWikiContext)}) of the page to render.
   * @param zos the ZIP output stream.
   * @param context the XWiki context.
   * @param vcontext the Velocity context.
   * @throws XWikiException error when rendering document.
   * @throws IOException error when rendering document.
   */
  private void renderDocument(
      String pageName, ZipOutputStream zos, XWikiContext context, VelocityContext vcontext)
      throws XWikiException, IOException {
    @SuppressWarnings("unchecked")
    EntityReferenceResolver<String> resolver = Utils.getComponent(EntityReferenceResolver.class);
    DocumentReference docReference =
        new DocumentReference(resolver.resolve(pageName, EntityType.DOCUMENT));
    XWikiDocument doc = context.getWiki().getDocument(docReference, context);

    String zipname = doc.getDocumentReference().getWikiReference().getName();
    for (EntityReference space : doc.getDocumentReference().getSpaceReferences()) {
      zipname += POINT + space.getName();
    }
    zipname += POINT + doc.getDocumentReference().getName();
    String language = doc.getLanguage();
    if (language != null && language.length() != 0) {
      zipname += POINT + language;
    }

    zipname += ".html";

    ZipEntry zipentry = new ZipEntry(zipname);
    zos.putNextEntry(zipentry);

    String originalDatabase = context.getDatabase();
    try {
      context.setDatabase(doc.getDocumentReference().getWikiReference().getName());
      context.setDoc(doc);
      vcontext.put(VCONTEXT_DOC, doc.newDocument(context));
      vcontext.put(VCONTEXT_CDOC, vcontext.get(VCONTEXT_DOC));

      XWikiDocument tdoc = doc.getTranslatedDocument(context);
      context.put(CONTEXT_TDOC, tdoc);
      vcontext.put(VCONTEXT_TDOC, tdoc.newDocument(context));

      String content = context.getWiki().evaluateTemplate("view.vm", context);

      zos.write(content.getBytes(context.getWiki().getEncoding()));
      zos.closeEntry();
    } finally {
      context.setDatabase(originalDatabase);
    }
  }
  /** Tests resolving and re-serializing an object reference. */
  @Test
  public void testSerializeClassPropertyReference() {
    EntityReference reference =
        resolver.resolve("wiki:space.page^ClassProperty", EntityType.CLASS_PROPERTY);
    Assert.assertEquals("wiki:space.page^ClassProperty", serializer.serialize(reference));

    // default values
    reference = resolver.resolve("", EntityType.CLASS_PROPERTY);
    Assert.assertEquals(
        "defwiki:defspace.defpage^defclassproperty", serializer.serialize(reference));

    // property reference with no object
    reference = resolver.resolve("wiki:space.page.property", EntityType.CLASS_PROPERTY);
    Assert.assertEquals(
        "defwiki:defspace.defpage^wiki:space\\.page\\.property", serializer.serialize(reference));

    // test escaping character
    reference = resolver.resolve("wiki:space.page^Obje\\^ct", EntityType.CLASS_PROPERTY);
    Assert.assertEquals("wiki:space.page^Obje\\^ct", serializer.serialize(reference));

    reference = resolver.resolve("wiki:spa^ce.page^Obje\\^ct", EntityType.CLASS_PROPERTY);
    Assert.assertEquals("wiki:spa^ce.page^Obje\\^ct", serializer.serialize(reference));

    reference = resolver.resolve(":.\\^@", EntityType.CLASS_PROPERTY);
    Assert.assertEquals("defwiki:defspace.defpage^:\\.\\^@", serializer.serialize(reference));
  }
  /** Tests resolving and re-serializing an object reference. */
  @Test
  public void testSerializeObjectPropertyReference() {
    EntityReference reference =
        resolver.resolve("wiki:space.page^xwiki.class[0].prop", EntityType.OBJECT_PROPERTY);
    Assert.assertEquals("wiki:space.page^xwiki.class[0].prop", serializer.serialize(reference));

    // default values
    reference = resolver.resolve("", EntityType.OBJECT_PROPERTY);
    Assert.assertEquals(
        "defwiki:defspace.defpage^defobject.defproperty", serializer.serialize(reference));

    // using separators
    reference = resolver.resolve("space^page@attachment", EntityType.OBJECT_PROPERTY);
    Assert.assertEquals(
        "defwiki:defspace.defpage^defobject.space^page@attachment",
        serializer.serialize(reference));

    reference = resolver.resolve("wiki:space^object", EntityType.OBJECT_PROPERTY);
    Assert.assertEquals(
        "defwiki:defspace.defpage^defobject.wiki:space^object", serializer.serialize(reference));

    // test escaping character
    reference =
        resolver.resolve("wiki:space.page^xwiki.class[0].prop\\.erty", EntityType.OBJECT_PROPERTY);
    Assert.assertEquals(
        "wiki:space.page^xwiki.class[0].prop\\.erty", serializer.serialize(reference));

    reference = resolver.resolve(":\\.^@", EntityType.OBJECT_PROPERTY);
    Assert.assertEquals(
        "defwiki:defspace.defpage^defobject.:\\.^@", serializer.serialize(reference));
  }
  /** Tests resolving and re-serializing an object reference. */
  @Test
  public void serializeObjectReferences() {
    EntityReference reference = resolver.resolve("wiki:space.page^Object", EntityType.OBJECT);
    assertEquals("wiki:space.page^Object", serializer.serialize(reference));

    // default values
    reference = resolver.resolve("", EntityType.OBJECT);
    assertEquals("defwiki:defspace.defpage^defobject", serializer.serialize(reference));

    // property reference with no object
    reference = resolver.resolve("wiki:space.page.property", EntityType.OBJECT);
    assertEquals(
        "defwiki:defspace.defpage^wiki:space.page.property", serializer.serialize(reference));

    // test escaping character
    reference = resolver.resolve("wiki:space.page^Obje\\^ct", EntityType.OBJECT);
    assertEquals("wiki:space.page^Obje\\^ct", serializer.serialize(reference));

    reference = resolver.resolve("wiki:spa^ce.page^Obje\\^ct", EntityType.OBJECT);
    assertEquals("wiki:spa^ce.page^Obje\\^ct", serializer.serialize(reference));

    reference = resolver.resolve(":.\\^@", EntityType.OBJECT);
    assertEquals("defwiki:defspace.defpage^:.\\^@", serializer.serialize(reference));
  }
  @Test
  public void testSerializeDocumentReference() throws Exception {
    EntityReference reference = resolver.resolve("wiki:space.page", EntityType.DOCUMENT);
    Assert.assertEquals("wiki:space.page", serializer.serialize(reference));

    reference = resolver.resolve("wiki:space.", EntityType.DOCUMENT);
    Assert.assertEquals("wiki:space.defpage", serializer.serialize(reference));

    reference = resolver.resolve("space.", EntityType.DOCUMENT);
    Assert.assertEquals("defwiki:space.defpage", serializer.serialize(reference));

    reference = resolver.resolve("page", EntityType.DOCUMENT);
    Assert.assertEquals("defwiki:defspace.page", serializer.serialize(reference));

    reference = resolver.resolve(".", EntityType.DOCUMENT);
    Assert.assertEquals("defwiki:defspace.defpage", serializer.serialize(reference));

    reference = resolver.resolve(null, EntityType.DOCUMENT);
    Assert.assertEquals("defwiki:defspace.defpage", serializer.serialize(reference));

    reference = resolver.resolve("", EntityType.DOCUMENT);
    Assert.assertEquals("defwiki:defspace.defpage", serializer.serialize(reference));

    reference = resolver.resolve("wiki1.wiki2:wiki3:some.space.page", EntityType.DOCUMENT);
    Assert.assertEquals("wiki1.wiki2:wiki3:some\\.space.page", serializer.serialize(reference));

    reference = resolver.resolve("some.space.page", EntityType.DOCUMENT);
    Assert.assertEquals("defwiki:some\\.space.page", serializer.serialize(reference));

    reference = resolver.resolve("wiki:page", EntityType.DOCUMENT);
    Assert.assertEquals("defwiki:defspace.wiki:page", serializer.serialize(reference));

    // Verify that passing null doesn't throw a NPE
    Assert.assertNull(serializer.serialize(null));

    // Test escapes

    reference = resolver.resolve("\\.:@\\.", EntityType.DOCUMENT);
    Assert.assertEquals("defwiki:defspace.\\.:@\\.", serializer.serialize(reference));

    reference = resolver.resolve("\\\\:\\\\.\\\\", EntityType.DOCUMENT);
    Assert.assertEquals("\\\\:\\\\.\\\\", serializer.serialize(reference));

    // The escaping here is not necessary but we want to test that it works
    reference = resolver.resolve("\\wiki:\\space.\\page", EntityType.DOCUMENT);
    Assert.assertEquals("wiki:space.page", serializer.serialize(reference));
  }
 @Test
 public void testSerializeSpaceReference() throws Exception {
   EntityReference reference = resolver.resolve("wiki:space1.space2", EntityType.SPACE);
   Assert.assertEquals("wiki:space1\\.space2", serializer.serialize(reference));
 }
  private boolean renameLink(
      Block block,
      DocumentReference currentDocumentReference,
      DocumentReference oldTarget,
      DocumentReference newTarget)
      throws InvalidArgumentException {
    boolean modified = false;

    ResourceReference resourceReference = linkedResourceHelper.getResourceReference(block);
    if (resourceReference == null) {
      // Skip invalid blocks.
      throw new InvalidArgumentException();
    }

    ResourceType resourceType = resourceReference.getType();

    // TODO: support ATTACHMENT as well.
    if (!ResourceType.DOCUMENT.equals(resourceType) && !ResourceType.SPACE.equals(resourceType)) {
      // We are currently only interested in Document or Space references.
      throw new InvalidArgumentException();
    }

    // Resolve the resource reference.
    EntityReference linkEntityReference =
        resourceReferenceResolver.resolve(resourceReference, null, currentDocumentReference);
    // Resolve the document of the reference.
    DocumentReference linkTargetDocumentReference =
        defaultReferenceDocumentReferenceResolver.resolve(linkEntityReference);
    EntityReference newTargetReference = newTarget;
    ResourceType newResourceType = resourceType;

    // If the link was resolved to a space...
    if (EntityType.SPACE.equals(linkEntityReference.getType())) {
      if (XWiki.DEFAULT_SPACE_HOMEPAGE.equals(newTarget.getName())) {
        // If the new document reference is also a space (non-terminal doc), be careful to keep it
        // serialized as a space still (i.e. without ".WebHome") and not serialize it as a doc by
        // mistake
        // (i.e. with ".WebHome").
        newTargetReference = newTarget.getLastSpaceReference();
      } else {
        // If the new target is a non-terminal document, we can not use a "space:" resource type to
        // access
        // it anymore. To fix it, we need to change the resource type of the link reference "doc:".
        newResourceType = ResourceType.DOCUMENT;
      }
    }

    // If the link targets the old (renamed) document reference, we must update it.
    if (linkTargetDocumentReference.equals(oldTarget)) {
      modified = true;
      String newReferenceString =
          this.compactEntityReferenceSerializer.serialize(
              newTargetReference, currentDocumentReference);

      // Update the reference in the XDOM.
      linkedResourceHelper.setResourceReferenceString(block, newReferenceString);
      linkedResourceHelper.setResourceType(block, newResourceType);
    }

    return modified;
  }
 @Test
 public void serializeWikiReferences() throws Exception {
   EntityReference reference = resolver.resolve("wiki", EntityType.WIKI);
   assertEquals("wiki", serializer.serialize(reference));
 }