Skip to content

Commit

Permalink
working on refactoring a identifier builder that can translate from s…
Browse files Browse the repository at this point in the history
…ome combination of session, node, rdf resource and http uri.
  • Loading branch information
cbeer committed Oct 23, 2013
1 parent ab2c787 commit e66a189
Show file tree
Hide file tree
Showing 7 changed files with 517 additions and 0 deletions.
@@ -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;
}
}
}
Expand Up @@ -41,6 +41,7 @@
*/
public class SessionFactory {


private static final Logger logger = getLogger(SessionFactory.class);

@Autowired
Expand Down
@@ -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 {

}
}

0 comments on commit e66a189

Please sign in to comment.