Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
working on refactoring a identifier builder that can translate from s…
…ome combination of session, node, rdf resource and http uri.
- Loading branch information
Showing
7 changed files
with
517 additions
and
0 deletions.
There are no files selected for viewing
164 changes: 164 additions & 0 deletions
164
fcrepo-http-commons/src/main/java/org/fcrepo/http/commons/api/rdf/HttpIdentifierBuilder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
package org.fcrepo.http.commons.api.rdf; | ||
|
||
import org.fcrepo.kernel.Transaction; | ||
import org.fcrepo.kernel.exception.TransactionMissingException; | ||
import org.fcrepo.kernel.rdf.DefaultIdentifierBuilder; | ||
import org.fcrepo.kernel.rdf.IdentifierBuilder; | ||
import org.fcrepo.kernel.services.TransactionService; | ||
import org.modeshape.jcr.api.ServletCredentials; | ||
import org.slf4j.Logger; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
|
||
import javax.jcr.Repository; | ||
import javax.jcr.RepositoryException; | ||
import javax.jcr.Session; | ||
import javax.jcr.Workspace; | ||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpSession; | ||
import javax.ws.rs.core.UriBuilder; | ||
import javax.ws.rs.core.UriInfo; | ||
|
||
import static org.fcrepo.kernel.services.TransactionService.getCurrentTransactionId; | ||
import static org.slf4j.LoggerFactory.getLogger; | ||
|
||
public class HttpIdentifierBuilder extends DefaultIdentifierBuilder { | ||
|
||
|
||
private static final Logger logger = getLogger(HttpIdentifierBuilder.class); | ||
|
||
private final String basePath; | ||
|
||
@Autowired | ||
private Repository repo; | ||
|
||
@Autowired | ||
private TransactionService transactionService; | ||
|
||
public HttpIdentifierBuilder(final Class<?> relativeTo, final UriInfo uris) { | ||
|
||
UriBuilder nodesBuilder = uris.getBaseUriBuilder().path(relativeTo); | ||
String basePath = nodesBuilder.build("").toString(); | ||
if (basePath.endsWith("/")) { | ||
basePath = basePath.substring(0, basePath.length() - 1); | ||
} | ||
this.basePath = basePath; | ||
|
||
} | ||
|
||
public HttpIdentifierBuilder(final String basePath) { | ||
this.basePath = basePath; | ||
} | ||
|
||
@Override | ||
public HttpIdentifierBuilder newInstance(final Session session, final String path) { | ||
final HttpIdentifierBuilder defaultIdentifierBuilder = new HttpIdentifierBuilder(basePath); | ||
|
||
defaultIdentifierBuilder.setSession(session); | ||
defaultIdentifierBuilder.setPath(path); | ||
|
||
return defaultIdentifierBuilder; | ||
|
||
} | ||
|
||
public HttpIdentifierBuilder fromServletRequest(final HttpServletRequest servletRequest) throws RepositoryException { | ||
|
||
final ServletCredentials creds = | ||
new ServletCredentials(servletRequest); | ||
|
||
final String workspace = getEmbeddedWorkspace(servletRequest); | ||
final Transaction transaction = | ||
getEmbeddedTransaction(servletRequest); | ||
|
||
final Session session; | ||
|
||
if (transaction != null) { | ||
|
||
final HttpSession httpSession = | ||
servletRequest.getSession(true); | ||
|
||
if (httpSession != null && transaction.getId().equals(httpSession.getAttribute("currentTx"))) { | ||
session = transaction.getSession().impersonate(creds); | ||
} else { | ||
session = transaction.getSession(); | ||
} | ||
} else if (workspace != null) { | ||
session = repo.login(creds, workspace); | ||
} else { | ||
session = repo.login(); | ||
} | ||
|
||
return newInstance(session, "/"); | ||
|
||
} | ||
|
||
@Override | ||
public String getBaseUri() { | ||
|
||
String path = basePath; | ||
final Session session = getSession(); | ||
|
||
final Workspace workspace = session.getWorkspace(); | ||
|
||
final String txId = getCurrentTransactionId(session); | ||
|
||
if (txId != null) { | ||
path += "/tx:" + txId; | ||
} else if (workspace != null && | ||
!workspace.getName().equals("default")) { | ||
path += "/workspace:" + workspace.getName(); | ||
} else { | ||
path += ""; | ||
} | ||
|
||
return path; | ||
} | ||
|
||
/** | ||
* Extract the workspace id embedded at the beginning of a request | ||
* | ||
* @param request | ||
* @return | ||
*/ | ||
private String getEmbeddedWorkspace(final HttpServletRequest request) { | ||
final String requestPath = request.getPathInfo(); | ||
|
||
if (requestPath == null) { | ||
return null; | ||
} | ||
|
||
final String[] part = requestPath.split("/"); | ||
|
||
if (part.length > 1 && part[1].startsWith("workspace:")) { | ||
return part[1].substring("workspace:".length()); | ||
} else { | ||
return null; | ||
} | ||
|
||
} | ||
|
||
/** | ||
* Extract the transaction id embedded at the beginning of a request | ||
* | ||
* @param servletRequest | ||
* @return | ||
* @throws org.fcrepo.kernel.exception.TransactionMissingException | ||
*/ | ||
private Transaction getEmbeddedTransaction( | ||
final HttpServletRequest servletRequest) | ||
throws TransactionMissingException { | ||
final String requestPath = servletRequest.getPathInfo(); | ||
|
||
if (requestPath == null) { | ||
return null; | ||
} | ||
|
||
final String[] part = requestPath.split("/"); | ||
|
||
if (part.length > 1 && part[1].startsWith("tx:")) { | ||
final String txid = part[1].substring("tx:".length()); | ||
return transactionService.getTransaction(txid); | ||
} else { | ||
return null; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
141 changes: 141 additions & 0 deletions
141
...http-commons/src/test/java/org/fcrepo/http/commons/api/rdf/HttpIdentifierBuilderTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
package org.fcrepo.http.commons.api.rdf; | ||
|
||
import com.hp.hpl.jena.rdf.model.Resource; | ||
import com.sun.jersey.api.uri.UriBuilderImpl; | ||
import org.fcrepo.kernel.Transaction; | ||
import org.fcrepo.kernel.rdf.IdentifierBuilder; | ||
import org.fcrepo.kernel.services.TransactionService; | ||
import org.junit.Before; | ||
import org.junit.Test; | ||
import org.mockito.Mock; | ||
|
||
import javax.jcr.Node; | ||
import javax.jcr.Repository; | ||
import javax.jcr.RepositoryException; | ||
import javax.jcr.Session; | ||
import javax.jcr.ValueFactory; | ||
import javax.jcr.Workspace; | ||
import javax.servlet.http.HttpServletRequest; | ||
import javax.ws.rs.Path; | ||
import javax.ws.rs.core.UriBuilder; | ||
import javax.ws.rs.core.UriInfo; | ||
|
||
import java.net.URI; | ||
|
||
import static org.fcrepo.http.commons.test.util.TestHelpers.setField; | ||
import static org.junit.Assert.assertEquals; | ||
import static org.mockito.Mockito.mock; | ||
import static org.mockito.Mockito.when; | ||
import static org.mockito.MockitoAnnotations.initMocks; | ||
|
||
public class HttpIdentifierBuilderTest { | ||
private HttpIdentifierBuilder testObj; | ||
|
||
private String testPath = "/foo/bar"; | ||
|
||
@Mock | ||
private Session mockSession; | ||
|
||
@Mock | ||
private Workspace mockWorkspace; | ||
|
||
@Mock private Resource mockSubject; | ||
|
||
@Mock | ||
private Node mockNode; | ||
|
||
@Mock | ||
private ValueFactory mockValueFactory; | ||
|
||
@Mock | ||
private HttpServletRequest mockServletRequest; | ||
|
||
@Mock | ||
private TransactionService mockTxService; | ||
|
||
@Mock | ||
private Transaction mockTx; | ||
|
||
@Mock | ||
private Repository mockRepo; | ||
|
||
private UriInfo uriInfo; | ||
|
||
@Before | ||
public void setUp() throws RepositoryException, NoSuchFieldException { | ||
initMocks(this); | ||
uriInfo = getUriInfoImpl(testPath); | ||
when(mockSession.getValueFactory()).thenReturn(mockValueFactory); | ||
testObj = | ||
new HttpIdentifierBuilder(MockNodeController.class, | ||
uriInfo); | ||
|
||
setField(testObj, "repo", mockRepo); | ||
setField(testObj, "transactionService", mockTxService); | ||
when(mockRepo.login()).thenReturn(mockSession); | ||
} | ||
|
||
@Test | ||
public void testFromServletRequest() throws RepositoryException { | ||
final HttpIdentifierBuilder identifierBuilder = testObj.fromServletRequest(mockServletRequest); | ||
|
||
assertEquals("http://localhost:8080/fcrepo/rest/", identifierBuilder.getResource().getURI()); | ||
} | ||
|
||
@Test | ||
public void testFromServletRequestAndPath() throws RepositoryException { | ||
final HttpIdentifierBuilder baseIdentifierBuilder = testObj.fromServletRequest(mockServletRequest); | ||
|
||
final IdentifierBuilder identifierBuilder = baseIdentifierBuilder.replacePath("/some/path/to/node"); | ||
|
||
assertEquals("http://localhost:8080/fcrepo/rest/some/path/to/node", identifierBuilder.getResource().getURI()); | ||
} | ||
|
||
@Test | ||
public void testFromServletRequestInTransaction() throws RepositoryException { | ||
|
||
when(mockServletRequest.getPathInfo()).thenReturn("/tx:123/some/path"); | ||
|
||
final Session mockTxSession = mock(Session.class); | ||
when(mockTxSession.getNamespaceURI("fcrepo4.tx.id")).thenReturn("123"); | ||
when(mockTx.getSession()).thenReturn(mockTxSession); | ||
when(mockTxService.getTransaction("123")).thenReturn(mockTx); | ||
|
||
final HttpIdentifierBuilder baseIdentifierBuilder = testObj.fromServletRequest(mockServletRequest); | ||
|
||
final IdentifierBuilder identifierBuilder = baseIdentifierBuilder.replacePath("/some/path/to/node"); | ||
|
||
assertEquals("http://localhost:8080/fcrepo/rest/tx:123/some/path/to/node", identifierBuilder.getResource().getURI()); | ||
|
||
} | ||
|
||
private static UriInfo getUriInfoImpl(final String path) { | ||
// UriInfo ui = mock(UriInfo.class,withSettings().verboseLogging()); | ||
final UriInfo ui = mock(UriInfo.class); | ||
final UriBuilder ub = new UriBuilderImpl(); | ||
ub.scheme("http"); | ||
ub.host("localhost"); | ||
ub.port(8080); | ||
ub.path("/fcrepo"); | ||
|
||
final UriBuilder rb = new UriBuilderImpl(); | ||
rb.scheme("http"); | ||
rb.host("localhost"); | ||
rb.port(8080); | ||
rb.path("/fcrepo/rest" + path); | ||
|
||
when(ui.getRequestUri()).thenReturn( | ||
URI.create("http://localhost:8080/fcrepo/rest" + path)); | ||
when(ui.getBaseUri()).thenReturn( | ||
URI.create("http://localhost:8080/fcrepo")); | ||
when(ui.getBaseUriBuilder()).thenReturn(ub); | ||
when(ui.getAbsolutePathBuilder()).thenReturn(rb); | ||
|
||
return ui; | ||
} | ||
|
||
@Path("/rest/{path}") | ||
private class MockNodeController { | ||
|
||
} | ||
} |
Oops, something went wrong.