001/* 002 * Licensed to DuraSpace under one or more contributor license agreements. 003 * See the NOTICE file distributed with this work for additional information 004 * regarding copyright ownership. 005 * 006 * DuraSpace licenses this file to you under the Apache License, 007 * Version 2.0 (the "License"); you may not use this file except in 008 * compliance with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.fcrepo.http.commons.api.rdf; 019 020import org.apache.jena.rdf.model.Resource; 021import org.fcrepo.http.commons.session.HttpSession; 022import org.fcrepo.kernel.api.FedoraSession; 023import org.fcrepo.kernel.api.exception.InvalidResourceIdentifierException; 024import org.fcrepo.kernel.api.models.Container; 025import org.fcrepo.kernel.api.models.FedoraBinary; 026import org.fcrepo.kernel.api.models.FedoraResource; 027import org.fcrepo.kernel.api.models.FedoraTimeMap; 028import org.fcrepo.kernel.api.models.FedoraWebacAcl; 029import org.fcrepo.kernel.api.models.NonRdfSourceDescription; 030import org.fcrepo.kernel.modeshape.ContainerImpl; 031import org.fcrepo.kernel.modeshape.FedoraBinaryImpl; 032import org.fcrepo.kernel.modeshape.FedoraResourceImpl; 033import org.fcrepo.kernel.modeshape.FedoraSessionImpl; 034import org.fcrepo.kernel.modeshape.FedoraTimeMapImpl; 035import org.fcrepo.kernel.modeshape.FedoraWebacAclImpl; 036import org.fcrepo.kernel.modeshape.NonRdfSourceDescriptionImpl; 037import org.junit.Before; 038import org.junit.Test; 039import org.junit.runner.RunWith; 040import org.mockito.Mock; 041import org.mockito.junit.MockitoJUnitRunner; 042 043import javax.jcr.NamespaceRegistry; 044import javax.jcr.Node; 045import javax.jcr.Property; 046import javax.jcr.RepositoryException; 047import javax.jcr.Session; 048import javax.jcr.Workspace; 049import javax.jcr.version.VersionManager; 050import javax.ws.rs.core.UriBuilder; 051 052import static org.apache.jena.rdf.model.ResourceFactory.createResource; 053import static org.fcrepo.http.commons.test.util.TestHelpers.setField; 054import static org.fcrepo.kernel.api.FedoraTypes.FEDORA_BINARY; 055import static org.fcrepo.kernel.api.FedoraTypes.FEDORA_NON_RDF_SOURCE_DESCRIPTION; 056import static org.fcrepo.kernel.api.FedoraTypes.FEDORA_TIME_MAP; 057import static org.fcrepo.kernel.api.FedoraTypes.FEDORA_WEBAC_ACL; 058import static org.fcrepo.kernel.api.FedoraTypes.MEMENTO; 059import static org.fcrepo.kernel.api.FedoraTypes.MEMENTO_ORIGINAL; 060import static org.fcrepo.kernel.api.RdfLexicon.FEDORA_DESCRIPTION; 061import static org.fcrepo.kernel.modeshape.utils.FedoraTypesUtils.getJcrNode; 062import static org.junit.Assert.assertEquals; 063import static org.junit.Assert.assertTrue; 064import static org.mockito.Mockito.when; 065 066/** 067 * @author cabeer 068 */ 069@RunWith(MockitoJUnitRunner.Silent.class) 070public class HttpResourceConverterTest { 071 072 @Mock 073 private Session session, txSession; 074 075 @Mock 076 private Node node, mementoNode, timeMapNode, descriptionNode, webacAclNode; 077 078 @Mock 079 private Property mockOriginal; 080 081 @Mock 082 private NamespaceRegistry mockRegistry; 083 084 private FedoraSession testSession, testTxSession; 085 086 private HttpSession testHttpSession, testHttpBatchSession; 087 088 private HttpResourceConverter converter; 089 private final String uriTemplate = "http://localhost:8080/some/{path: .*}"; 090 private final String path = "arbitrary/path"; 091 092 private final String resourceUri = "http://localhost:8080/some/" + path; 093 094 private final Resource resource = createResource(resourceUri); 095 private final Resource metadataResource = createResource(resource.toString() + "/fcr:metadata"); 096 097 @Mock 098 private Workspace mockWorkspace; 099 100 @Mock 101 private VersionManager mockVersionManager; 102 103 private final String[] prefixes = { "fedora", "fcr", "test" }; 104 105 @Before 106 public void setUp() throws RepositoryException { 107 final UriBuilder uriBuilder = UriBuilder.fromUri(uriTemplate); 108 testSession = new FedoraSessionImpl(session); 109 testTxSession = new FedoraSessionImpl(txSession); 110 testHttpSession = new HttpSession(testSession); 111 testHttpBatchSession = new HttpSession(testTxSession); 112 testHttpBatchSession.makeBatchSession(); 113 converter = new HttpResourceConverter(testHttpSession, uriBuilder); 114 115 when(session.getNode("/" + path)).thenReturn(node); 116 when(session.getNode("/")).thenReturn(node); 117 when(node.getPath()).thenReturn("/" + path); 118 when(node.isNodeType(FEDORA_NON_RDF_SOURCE_DESCRIPTION)).thenReturn(false); 119 when(descriptionNode.getPath()).thenReturn("/" + path + "/" + FEDORA_DESCRIPTION); 120 when(descriptionNode.isNodeType(FEDORA_NON_RDF_SOURCE_DESCRIPTION)).thenReturn(true); 121 when(session.getWorkspace()).thenReturn(mockWorkspace); 122 when(mockWorkspace.getName()).thenReturn("default"); 123 when(mockWorkspace.getVersionManager()).thenReturn(mockVersionManager); 124 125 when(mockOriginal.getNode()).thenReturn(node); 126 when(timeMapNode.getProperty(MEMENTO_ORIGINAL)).thenReturn(mockOriginal); 127 when(timeMapNode.isNodeType(FEDORA_TIME_MAP)).thenReturn(true); 128 when(webacAclNode.isNodeType(FEDORA_WEBAC_ACL)).thenReturn(true); 129 130 when(session.getWorkspace()).thenReturn(mockWorkspace); 131 when(mockWorkspace.getNamespaceRegistry()).thenReturn(mockRegistry); 132 when(mockRegistry.getPrefixes()).thenReturn(prefixes); 133 when(mockRegistry.getURI("fedora")).thenReturn("info/fedora#"); 134 when(mockRegistry.getURI("fcr")).thenReturn("info/fcr#"); 135 when(mockRegistry.getURI("test")).thenReturn("info/test#"); 136 } 137 138 @Test 139 public void testDoForward() { 140 final FedoraResource converted = converter.convert(resource); 141 assertEquals(node, getJcrNode(converted)); 142 } 143 144 @Test 145 public void testDoForwardWithDatastreamContent() throws Exception { 146 when(node.isNodeType(FEDORA_BINARY)).thenReturn(true); 147 final FedoraResource converted = converter.convert(resource); 148 assertTrue(converted instanceof FedoraBinary); 149 assertEquals(node, getJcrNode(converted)); 150 } 151 152 @Test 153 public void testDoForwardWithDatastreamMetadata() throws Exception { 154 when(session.getNode("/" + path + "/" + FEDORA_DESCRIPTION)).thenReturn(node); 155 when(node.isNodeType(FEDORA_NON_RDF_SOURCE_DESCRIPTION)).thenReturn(true); 156 final FedoraResource converted = converter.convert(metadataResource); 157 assertTrue(converted instanceof NonRdfSourceDescription); 158 assertEquals(node, getJcrNode(converted)); 159 } 160 161 @Test 162 public void testDoForwardWithAHash() throws Exception { 163 when(session.getNode("/" + path + "/#/with-a-hash")).thenReturn(node); 164 final FedoraResource converted = 165 converter.convert(createResource("http://localhost:8080/some/" + path + "#with-a-hash")); 166 assertEquals(node, getJcrNode(converted)); 167 } 168 169 @Test 170 public void testDoForwardWithTransaction() throws Exception { 171 setField(testTxSession, "id", "xyz"); 172 final HttpResourceConverter converter = new HttpResourceConverter(testHttpBatchSession, 173 UriBuilder.fromUri(uriTemplate)); 174 when(txSession.getNode("/" + path)).thenReturn(node); 175 when(txSession.getWorkspace()).thenReturn(mockWorkspace); 176 final Resource resource = createResource("http://localhost:8080/some/tx:xyz/" + path); 177 final FedoraResource converted = converter.convert(resource); 178 assertEquals(node, getJcrNode(converted)); 179 } 180 181 @Test 182 public void testDoForwardWithUuid() throws Exception { 183 final Resource resource = createResource("http://localhost:8080/some/[xyz]"); 184 when(session.getNode("/[xyz]")).thenReturn(node); 185 final FedoraResource converted = converter.convert(resource); 186 assertEquals(node, getJcrNode(converted)); 187 } 188 189 @Test 190 public void testDoForwardRoot() { 191 final Resource resource = createResource("http://localhost:8080/some/"); 192 final FedoraResource converted = converter.convert(resource); 193 assertEquals(node, getJcrNode(converted)); 194 assertTrue(converter.inDomain(resource)); 195 } 196 197 @Test 198 public void testDoForwardRootWithoutSlash() { 199 final Resource resource = createResource("http://localhost:8080/some"); 200 final FedoraResource converted = converter.convert(resource); 201 assertEquals(node, getJcrNode(converted)); 202 assertTrue(converter.inDomain(resource)); 203 } 204 205 @Test 206 public void testDoBackward() { 207 final Resource converted = converter.reverse().convert(new FedoraResourceImpl(node)); 208 assertEquals(resource, converted); 209 } 210 211 @Test 212 public void testDoBackwardWithDatastreamContent() throws Exception { 213 when(node.isNodeType(FEDORA_BINARY)).thenReturn(true); 214 final Resource converted = converter.reverse().convert(new FedoraBinaryImpl(node)); 215 assertEquals(resource, converted); 216 } 217 218 @Test 219 public void testDoBackwardWithDatastreamMetadata() { 220 final Resource converted = converter.reverse().convert(new NonRdfSourceDescriptionImpl(descriptionNode)); 221 assertEquals(metadataResource, converted); 222 } 223 224 @Test 225 public void testDoBackwardWithHash() throws Exception { 226 when(node.getPath()).thenReturn(path + "/#/with-a-hash"); 227 final Resource converted = converter.reverse().convert(new FedoraResourceImpl(node)); 228 assertEquals(createResource("http://localhost:8080/some/" + path + "#with-a-hash"), converted); 229 } 230 231 @Test 232 public void testDoBackwardWithTransaction() throws Exception { 233 setField(testTxSession, "id", "xyz"); 234 final HttpResourceConverter converter = new HttpResourceConverter(testHttpBatchSession, 235 UriBuilder.fromUri(uriTemplate)); 236 when(txSession.getNode("/" + path)).thenReturn(node); 237 when(txSession.getWorkspace()).thenReturn(mockWorkspace); 238 when(node.getSession()).thenReturn(txSession); 239 final Resource resource = createResource("http://localhost:8080/some/tx:xyz/" + path); 240 final Resource converted = converter.reverse().convert(new FedoraResourceImpl(node)); 241 assertEquals(resource, converted); 242 } 243 244 @Test 245 public void testToStringWithRoot() { 246 assertEquals("/", converter.asString(createResource("http://localhost:8080/some/"))); 247 } 248 249 @Test (expected = InvalidResourceIdentifierException.class) 250 public void testToStringWithEmptPathSegment() { 251 converter.asString(createResource("http://localhost:8080/some/test/a//b/c/d")); 252 } 253 254 @Test 255 public void testDoForwardWithTimemap() throws Exception { 256 final Resource resource = createResource("http://localhost:8080/some/container/fcr:versions"); 257 when(session.getNode("/container")).thenReturn(node); 258 259 when(session.getNode("/container/fedora:timemap")).thenReturn(timeMapNode); 260 261 final FedoraResource converted = converter.convert(resource); 262 assertTrue("Converted resource must be a timemap", converted instanceof FedoraTimeMap); 263 264 final Node resultNode = getJcrNode(converted); 265 assertEquals(timeMapNode, resultNode); 266 } 267 268 @Test 269 public void testDoForwardWithBinaryTimemap() throws Exception { 270 final Resource resource = createResource("http://localhost:8080/some/binary/fcr:versions"); 271 when(session.getNode("/binary")).thenReturn(node); 272 when(node.isNodeType(FEDORA_BINARY)).thenReturn(true); 273 274 when(session.getNode("/binary/fedora:timemap")).thenReturn(timeMapNode); 275 276 final FedoraResource converted = converter.convert(resource); 277 assertTrue("Converted resource must be a timemap", converted instanceof FedoraTimeMap); 278 279 final Node resultNode = getJcrNode(converted); 280 assertEquals(timeMapNode, resultNode); 281 } 282 283 @Test 284 public void testDoForwardWithBinaryDescriptionTimemap() throws Exception { 285 final Resource resource = createResource("http://localhost:8080/some/binary/fcr:metadata/fcr:versions"); 286 when(node.isNodeType(FEDORA_NON_RDF_SOURCE_DESCRIPTION)).thenReturn(true); 287 when(session.getNode("/binary/fedora:description")).thenReturn(node); 288 289 when(session.getNode("/binary/fedora:description/fedora:timemap")).thenReturn(timeMapNode); 290 291 final FedoraResource converted = converter.convert(resource); 292 assertTrue("Converted resource must be a timemap", converted instanceof FedoraTimeMap); 293 294 final Node resultNode = getJcrNode(converted); 295 assertEquals(timeMapNode, resultNode); 296 } 297 298 @Test 299 public void testDoBackWithTimemap() throws Exception { 300 final FedoraTimeMap timemap = new FedoraTimeMapImpl(timeMapNode); 301 when(timeMapNode.getPath()).thenReturn(path + "/fedora:timemap"); 302 303 final Resource converted = converter.reverse().convert(timemap); 304 final Resource expectedResource = createResource("http://localhost:8080/some/" + path + "/fcr:versions"); 305 assertEquals(expectedResource, converted); 306 } 307 308 @Test 309 public void testDoBackWithBinaryTimemap() throws Exception { 310 final FedoraTimeMap timemap = new FedoraTimeMapImpl(timeMapNode); 311 when(timeMapNode.getPath()).thenReturn(path + "/fedora:timemap"); 312 313 when(node.isNodeType(FEDORA_BINARY)).thenReturn(true); 314 315 final Resource converted = converter.reverse().convert(timemap); 316 final Resource expectedResource = createResource( 317 "http://localhost:8080/some/" + path + "/fcr:versions"); 318 assertEquals(expectedResource, converted); 319 } 320 321 @Test 322 public void testDoBackWithBinaryDescriptionTimemap() throws Exception { 323 final FedoraTimeMap timemap = new FedoraTimeMapImpl(timeMapNode); 324 when(timeMapNode.getPath()).thenReturn(path + "/fedora:description/fedora:timemap"); 325 326 when(node.isNodeType(FEDORA_NON_RDF_SOURCE_DESCRIPTION)).thenReturn(true); 327 328 final Resource converted = converter.reverse().convert(timemap); 329 final Resource expectedResource = createResource( 330 "http://localhost:8080/some/" + path + "/fcr:metadata/fcr:versions"); 331 assertEquals(expectedResource, converted); 332 } 333 334 @Test 335 public void testDoForwardWithMemento() throws Exception { 336 final Resource resource = createResource( 337 "http://localhost:8080/some/container/fcr:versions/20180315180915"); 338 when(mementoNode.isNodeType(MEMENTO)).thenReturn(true); 339 when(session.getNode("/container/fedora:timemap/20180315180915")).thenReturn(mementoNode); 340 341 when(session.getNode("/container")).thenReturn(node); 342 343 final FedoraResource converted = converter.convert(resource); 344 assertTrue("Converted resource must be a container", converted instanceof Container); 345 346 final Node resultNode = getJcrNode(converted); 347 assertEquals(mementoNode, resultNode); 348 } 349 350 @Test 351 public void testDoForwardWithMementoWithHash() throws Exception { 352 final Resource resource = createResource( 353 "http://localhost:8080/some/container/fcr:versions/20180315180915#test"); 354 when(session.getNode("/container/fedora:timemap/20180315180915/#/test")).thenReturn(node); 355 356 final FedoraResource converted = converter.convert(resource); 357 final Node resultNode = getJcrNode(converted); 358 assertEquals(node, resultNode); 359 } 360 361 @Test 362 public void testDoForwardWithBinaryMemento() throws Exception { 363 final Resource resource = createResource( 364 "http://localhost:8080/some/binary/fcr:versions/20180315180915"); 365 when(mementoNode.isNodeType(MEMENTO)).thenReturn(true); 366 when(mementoNode.isNodeType(FEDORA_BINARY)).thenReturn(true); 367 when(session.getNode("/binary/fedora:timemap/20180315180915")).thenReturn(mementoNode); 368 369 when(session.getNode("/binary")).thenReturn(node); 370 when(node.isNodeType(FEDORA_BINARY)).thenReturn(true); 371 372 final FedoraResource converted = converter.convert(resource); 373 assertTrue("Converted resource must be a binary", converted instanceof FedoraBinary); 374 375 final Node resultNode = getJcrNode(converted); 376 assertEquals(mementoNode, resultNode); 377 } 378 379 @Test 380 public void testDoForwardWithBinaryDescriptionMemento() throws Exception { 381 final Resource resource = createResource( 382 "http://localhost:8080/some/binary/fcr:metadata/fcr:versions/20180315180915"); 383 when(mementoNode.isNodeType(MEMENTO)).thenReturn(true); 384 // Timemap for binary description uses fedora:timemap name 385 when(session.getNode("/binary/fedora:description/fedora:timemap/20180315180915")).thenReturn(mementoNode); 386 387 when(session.getNode("/binary/fedora:description")).thenReturn(node); 388 389 final FedoraResource converted = converter.convert(resource); 390 assertTrue("Converted resource must be a container", converted instanceof Container); 391 392 final Node resultNode = getJcrNode(converted); 393 assertEquals(mementoNode, resultNode); 394 } 395 396 @Test 397 public void testDoBackWithMemento() throws Exception { 398 when(node.getPath()).thenReturn("/" + path + "/fedora:timemap/20180315180915"); 399 when(node.isNodeType(MEMENTO)).thenReturn(true); 400 401 final Container memento = new ContainerImpl(node); 402 403 final Resource converted = converter.reverse().convert(memento); 404 final Resource expectedResource = createResource(resourceUri + "/fcr:versions/20180315180915"); 405 assertEquals(expectedResource, converted); 406 } 407 408 @Test 409 public void testDoBackWithBinaryMemento() throws Exception { 410 when(node.getPath()).thenReturn("/" + path + "/fedora:timemap/20180315180915"); 411 when(node.isNodeType(FEDORA_BINARY)).thenReturn(true); 412 413 when(node.isNodeType(MEMENTO)).thenReturn(true); 414 415 final FedoraBinary memento = new FedoraBinaryImpl(node); 416 417 final Resource converted = converter.reverse().convert(memento); 418 final Resource expectedResource = createResource(resourceUri + "/fcr:versions/20180315180915"); 419 assertEquals(expectedResource, converted); 420 } 421 422 @Test 423 public void testDoBackWithBinaryDescriptionMemento() throws Exception { 424 when(descriptionNode.getPath()).thenReturn("/" + path + "/fedora:description/fedora:timemap/20180315180915"); 425 when(descriptionNode.isNodeType(MEMENTO)).thenReturn(true); 426 427 final NonRdfSourceDescription memento = new NonRdfSourceDescriptionImpl(descriptionNode); 428 429 final Resource converted = converter.reverse().convert(memento); 430 final Resource expectedResource = createResource(resourceUri + "/fcr:metadata/fcr:versions/20180315180915"); 431 assertEquals(expectedResource, converted); 432 } 433 434 @Test 435 public void testDoForwardWithWebacAcl() throws Exception { 436 final Resource resource = createResource("http://localhost:8080/some/container/fcr:acl"); 437 when(session.getNode("/container")).thenReturn(node); 438 439 when(session.getNode("/container/fedora:acl")).thenReturn(webacAclNode); 440 441 final FedoraResource converted = converter.convert(resource); 442 assertTrue("Converted resource must be a FedoraWebacAcl", converted instanceof FedoraWebacAcl); 443 444 final Node resultNode = getJcrNode(converted); 445 assertEquals(webacAclNode, resultNode); 446 } 447 448 @Test 449 public void testDoBackWithWebacAcl() throws Exception { 450 final FedoraWebacAcl webacAcl = new FedoraWebacAclImpl(webacAclNode); 451 when(webacAclNode.getPath()).thenReturn(path + "/fedora:acl"); 452 453 final Resource converted = converter.reverse().convert(webacAcl); 454 final Resource expectedResource = createResource("http://localhost:8080/some/" + path + "/fcr:acl"); 455 assertEquals(expectedResource, converted); 456 } 457 458 @Test 459 public void testDoForwardWithWebacAclWithHash() throws Exception { 460 final Resource resource = createResource("http://localhost:8080/some/container/fcr:acl#hash_resource"); 461 when(session.getNode("/container")).thenReturn(node); 462 463 when(session.getNode("/container/fedora:acl/#/hash_resource")).thenReturn(webacAclNode); 464 465 final FedoraResource converted = converter.convert(resource); 466 assertTrue("Converted resource must be a FedoraWebacAcl", converted instanceof FedoraWebacAcl); 467 468 final Node resultNode = getJcrNode(converted); 469 assertEquals(webacAclNode, resultNode); 470 } 471 472 @Test 473 public void testDoBackWithWebacAclHash() throws Exception { 474 final FedoraWebacAcl webacAcl = new FedoraWebacAclImpl(webacAclNode); 475 when(webacAclNode.getPath()).thenReturn(path + "/fedora:acl/#/hash_resource"); 476 477 final Resource converted = converter.reverse().convert(webacAcl); 478 final Resource expectedResource = 479 createResource("http://localhost:8080/some/" + path + "/fcr:acl#hash_resource"); 480 assertEquals(expectedResource, converted); 481 } 482 483 @Test 484 public void testWithForwardUnregisteredPrefix() throws Exception { 485 final Resource resource = createResource("http://localhost:8080/some/new_ns:uuid"); 486 when(session.getNode("/new_ns%3Auuid")).thenReturn(node); 487 488 final FedoraResource converted = converter.convert(resource); 489 assertEquals(node, getJcrNode(converted)); 490 } 491 492 @Test 493 public void testWithReverseUnregisteredPrefix() throws Exception { 494 when(node.getPath()).thenReturn("/new_ns%3Auuid"); 495 final Resource resource = createResource("http://localhost:8080/some/new_ns:uuid"); 496 final FedoraResource fedoraRes = new ContainerImpl(node); 497 498 final Resource converted = converter.reverse().convert(fedoraRes); 499 assertEquals(resource, converted); 500 } 501 502}