diff --git a/pom.xml b/pom.xml index db2528b..b4ee872 100644 --- a/pom.xml +++ b/pom.xml @@ -55,6 +55,7 @@ 9.4.9.v20180320 + UTF-8 @@ -141,6 +142,12 @@ 4.11 test + + org.mockito + mockito-core + 2.23.0 + test + @@ -159,6 +166,7 @@ WebContent false true + WEB-INF/lib/jetty*.jar diff --git a/src/main/java/org/linkeddatafragments/fragments/FragmentRequestParserBase.java b/src/main/java/org/linkeddatafragments/fragments/FragmentRequestParserBase.java index 092d2ab..0185fcc 100644 --- a/src/main/java/org/linkeddatafragments/fragments/FragmentRequestParserBase.java +++ b/src/main/java/org/linkeddatafragments/fragments/FragmentRequestParserBase.java @@ -9,133 +9,132 @@ * * @author Olaf Hartig */ -abstract public class FragmentRequestParserBase implements IFragmentRequestParser -{ - @Override - final public ILinkedDataFragmentRequest parseIntoFragmentRequest( - final HttpServletRequest httpRequest, - final ConfigReader config ) - throws IllegalArgumentException - { - return getWorker( httpRequest, config ).createFragmentRequest(); - } - - /** +abstract public class FragmentRequestParserBase implements + IFragmentRequestParser { + @Override + final public ILinkedDataFragmentRequest parseIntoFragmentRequest( + final HttpServletRequest httpRequest, final ConfigReader config) + throws IllegalArgumentException { + return getWorker(httpRequest, config).createFragmentRequest(); + } + + /** + * + * @param httpRequest + * @param config + * @return + * @throws IllegalArgumentException + */ + abstract protected Worker getWorker(final HttpServletRequest httpRequest, + final ConfigReader config) throws IllegalArgumentException; + + /** * - * @param httpRequest - * @param config - * @return - * @throws IllegalArgumentException */ - abstract protected Worker getWorker( final HttpServletRequest httpRequest, - final ConfigReader config ) - throws IllegalArgumentException; + abstract static protected class Worker { - /** - * - */ - abstract static protected class Worker - { - - /** - * - */ - public final HttpServletRequest request; - - /** + /** * */ - public final ConfigReader config; + public final HttpServletRequest request; - /** + /** * */ - public final boolean pageNumberWasRequested; + public final ConfigReader config; - /** - * - */ - public final long pageNumber; - - /** - * - * @param request - * @param config - */ - public Worker( final HttpServletRequest request, - final ConfigReader config ) - { - this.request = request; - this.config = config; - - final String givenPageNumber = request.getParameter( - ILinkedDataFragmentRequest.PARAMETERNAME_PAGE ); - if ( givenPageNumber != null ) { - long pageNumber; - try { - pageNumber = Long.parseLong( givenPageNumber ); - } catch (NumberFormatException ex) { - pageNumber = 1L; - } - this.pageNumber = ( pageNumber > 0 ) ? pageNumber : 1L; - this.pageNumberWasRequested = true; - } - else { - this.pageNumber = 1L; - this.pageNumberWasRequested = false; - } - } - - /** + /** * - * @return - * @throws IllegalArgumentException */ - abstract public ILinkedDataFragmentRequest createFragmentRequest() - throws IllegalArgumentException; + public final boolean pageNumberWasRequested; - /** + /** * - * @return */ - public String getFragmentURL() { - final String datasetURL = getDatasetURL(); - final String query = request.getQueryString(); - return query == null ? datasetURL : (datasetURL + "?" + query); - } - - /** - * - * @return - */ - public String getDatasetURL() { - return extractBaseURL( request, config ) + request.getRequestURI(); - } - - } // end of class Worker - - - // ----- HELPERS --------- - - /** - * - * @param request - * @param config - * @return - */ - - public static String extractBaseURL( final HttpServletRequest request, - final ConfigReader config ) { - if (config.getBaseURL() != null) { - return config.getBaseURL(); - } else if ((request.getServerPort() == 80) - || (request.getServerPort() == 443)) { - return request.getScheme() + "://" - + request.getServerName(); - } else { - return request.getScheme() + "://" - + request.getServerName() + ":" + request.getServerPort(); - } - } + public final long pageNumber; + + /** + * + * @param request + * @param config + */ + public Worker(final HttpServletRequest request, + final ConfigReader config) { + this.request = request; + this.config = config; + + final String givenPageNumber = request + .getParameter(ILinkedDataFragmentRequest.PARAMETERNAME_PAGE); + if (givenPageNumber != null) { + long pageNumber; + try { + pageNumber = Long.parseLong(givenPageNumber); + } catch (final NumberFormatException ex) { + pageNumber = 1L; + } + this.pageNumber = (pageNumber > 0) ? pageNumber : 1L; + this.pageNumberWasRequested = true; + } else { + this.pageNumber = 1L; + this.pageNumberWasRequested = false; + } + } + + /** + * + * @return + * @throws IllegalArgumentException + */ + abstract public ILinkedDataFragmentRequest createFragmentRequest() + throws IllegalArgumentException; + + /** + * + * @return + */ + public String getFragmentURL() { + final String datasetURL = getDatasetURL(); + final String query = this.request.getQueryString(); + return query == null ? datasetURL : (datasetURL + "?" + query); + } + + /** + * Returns the dataset URL + * + * @return the dataset URL. This consists of the base URL of the + * application, the servlet path and the pathinfo as supplied by + * request.getPathInfo() + */ + public String getDatasetURL() { + return extractBaseURL(this.request, this.config) + + this.request.getServletPath() + + this.request.getPathInfo(); + } + + } // end of class Worker + + // ----- HELPERS --------- + + /** + * + * @param request + * @param config + * @return + */ + + public static String extractBaseURL(final HttpServletRequest request, + final ConfigReader config) { + final String contextPath = request.getServletContext().getContextPath(); + if (config.getBaseURL() != null) { + return config.getBaseURL(); + } else if ((request.getServerPort() == 80) + || (request.getServerPort() == 443)) { + return request.getScheme() + "://" + request.getServerName() + + contextPath; + } else { + return request.getScheme() + "://" + request.getServerName() + ":" + + request.getServerPort() + contextPath; + } + } } diff --git a/src/main/java/org/linkeddatafragments/fragments/tpf/TriplePatternFragmentBase.java b/src/main/java/org/linkeddatafragments/fragments/tpf/TriplePatternFragmentBase.java index 9f46228..17b29c7 100644 --- a/src/main/java/org/linkeddatafragments/fragments/tpf/TriplePatternFragmentBase.java +++ b/src/main/java/org/linkeddatafragments/fragments/tpf/TriplePatternFragmentBase.java @@ -1,165 +1,173 @@ -package org.linkeddatafragments.fragments.tpf; - -import java.util.NoSuchElementException; -import org.apache.jena.datatypes.xsd.XSDDatatype; -import org.apache.jena.rdf.model.Literal; -import org.apache.jena.rdf.model.Model; -import org.apache.jena.rdf.model.Resource; -import org.apache.jena.rdf.model.Statement; -import org.apache.jena.rdf.model.StmtIterator; -import org.apache.jena.util.iterator.NiceIterator; - -import org.linkeddatafragments.fragments.LinkedDataFragmentBase; -import org.linkeddatafragments.util.CommonResources; - - - -/** - * Base class for implementations of {@link ITriplePatternFragment}. - * - * @author Ruben Verborgh - * @author Olaf Hartig - */ -abstract public class TriplePatternFragmentBase extends LinkedDataFragmentBase - implements ITriplePatternFragment -{ - private final long totalSize; - - /** - * Creates an empty Triple Pattern Fragment. - * @param fragmentURL - * @param datasetURL - */ - public TriplePatternFragmentBase( final String fragmentURL, - final String datasetURL ) { - this( 0L, fragmentURL, datasetURL, 1, true ); - } - - /** - * Creates an empty Triple Pattern Fragment page. - * @param fragmentURL - * @param isLastPage - * @param datasetURL - * @param pageNumber - */ - public TriplePatternFragmentBase( final String fragmentURL, - final String datasetURL, - final long pageNumber, - final boolean isLastPage ) { - this( 0L, fragmentURL, datasetURL, pageNumber, isLastPage ); - } - - /** - * Creates a new Triple Pattern Fragment. - * @param totalSize the total size - * @param fragmentURL - * @param datasetURL - * @param pageNumber - * @param isLastPage - */ - public TriplePatternFragmentBase( long totalSize, - final String fragmentURL, - final String datasetURL, - final long pageNumber, - final boolean isLastPage ) { - super( fragmentURL, datasetURL, pageNumber, isLastPage ); - this.totalSize = totalSize < 0L ? 0L : totalSize; - } - - @Override - public StmtIterator getTriples() { - if ( totalSize == 0L ) - return emptyStmtIterator; - else - return getNonEmptyStmtIterator(); - } - - /** - * - * @return - */ - abstract protected StmtIterator getNonEmptyStmtIterator(); - - @Override - public long getTotalSize() { - return totalSize; - } - - @Override - public void addMetadata( final Model model ) - { - super.addMetadata( model ); - - final Resource fragmentId = model.createResource( fragmentURL ); - - final Literal totalTyped = model.createTypedLiteral( totalSize, - XSDDatatype.XSDinteger ); - final Literal limitTyped = model.createTypedLiteral( getMaxPageSize(), - XSDDatatype.XSDinteger ); - - fragmentId.addLiteral( CommonResources.VOID_TRIPLES, totalTyped ); - fragmentId.addLiteral( CommonResources.HYDRA_TOTALITEMS, totalTyped ); - fragmentId.addLiteral( CommonResources.HYDRA_ITEMSPERPAGE, limitTyped ); - } - - @Override - public void addControls( final Model model ) - { - super.addControls( model ); - - final Resource datasetId = model.createResource( getDatasetURI() ); - - final Resource triplePattern = model.createResource(); - final Resource subjectMapping = model.createResource(); - final Resource predicateMapping = model.createResource(); - final Resource objectMapping = model.createResource(); - - datasetId.addProperty( CommonResources.HYDRA_SEARCH, triplePattern ); - - triplePattern.addProperty( CommonResources.HYDRA_TEMPLATE, getTemplate() ); - triplePattern.addProperty( CommonResources.HYDRA_MAPPING, subjectMapping ); - triplePattern.addProperty( CommonResources.HYDRA_MAPPING, predicateMapping ); - triplePattern.addProperty( CommonResources.HYDRA_MAPPING, objectMapping ); - - subjectMapping.addProperty( CommonResources.HYDRA_VARIABLE, ITriplePatternFragmentRequest.PARAMETERNAME_SUBJ ); - subjectMapping.addProperty( CommonResources.HYDRA_PROPERTY, CommonResources.RDF_SUBJECT ); - - predicateMapping.addProperty( CommonResources.HYDRA_VARIABLE, ITriplePatternFragmentRequest.PARAMETERNAME_PRED ); - predicateMapping.addProperty( CommonResources.HYDRA_PROPERTY, CommonResources.RDF_PREDICATE ); - - objectMapping.addProperty( CommonResources.HYDRA_VARIABLE, ITriplePatternFragmentRequest.PARAMETERNAME_OBJ ); - objectMapping.addProperty( CommonResources.HYDRA_PROPERTY, CommonResources.RDF_OBJECT ); - } - - /** - * - * @return - */ - public String getTemplate() { - return datasetURL + "{?" + - ITriplePatternFragmentRequest.PARAMETERNAME_SUBJ + "," + - ITriplePatternFragmentRequest.PARAMETERNAME_PRED + "," + - ITriplePatternFragmentRequest.PARAMETERNAME_OBJ + "}"; - } - - /** - * - */ - public static final StmtIterator emptyStmtIterator = new EmptyStmtIterator(); - - /** - * - */ - public static class EmptyStmtIterator - extends NiceIterator - implements StmtIterator - { - - /** - * - * @return - */ - public Statement nextStatement() { throw new NoSuchElementException(); } - } - -} +package org.linkeddatafragments.fragments.tpf; + +import java.util.NoSuchElementException; + +import org.apache.jena.datatypes.xsd.XSDDatatype; +import org.apache.jena.rdf.model.Literal; +import org.apache.jena.rdf.model.Model; +import org.apache.jena.rdf.model.Resource; +import org.apache.jena.rdf.model.Statement; +import org.apache.jena.rdf.model.StmtIterator; +import org.apache.jena.util.iterator.NiceIterator; +import org.linkeddatafragments.fragments.LinkedDataFragmentBase; +import org.linkeddatafragments.fragments.tpf.ITriplePatternFragment; +import org.linkeddatafragments.fragments.tpf.ITriplePatternFragmentRequest; +import org.linkeddatafragments.fragments.tpf.TriplePatternFragmentBase.EmptyStmtIterator; +import org.linkeddatafragments.util.CommonResources; + +/** + * Base class for implementations of {@link ITriplePatternFragment}. + * + * @author Ruben Verborgh + * @author Olaf Hartig + */ +abstract public class TriplePatternFragmentBase extends LinkedDataFragmentBase + implements ITriplePatternFragment { + private final long totalSize; + + /** + * Creates an empty Triple Pattern Fragment. + * + * @param fragmentURL + * @param datasetURL + */ + public TriplePatternFragmentBase(final String fragmentURL, + final String datasetURL) { + this(0L, fragmentURL, datasetURL, 1, true); + } + + /** + * Creates an empty Triple Pattern Fragment page. + * + * @param fragmentURL + * @param isLastPage + * @param datasetURL + * @param pageNumber + */ + public TriplePatternFragmentBase(final String fragmentURL, + final String datasetURL, final long pageNumber, + final boolean isLastPage) { + this(0L, fragmentURL, datasetURL, pageNumber, isLastPage); + } + + /** + * Creates a new Triple Pattern Fragment. + * + * @param totalSize + * the total size + * @param fragmentURL + * @param datasetURL + * @param pageNumber + * @param isLastPage + */ + public TriplePatternFragmentBase(long totalSize, final String fragmentURL, + final String datasetURL, final long pageNumber, + final boolean isLastPage) { + super(fragmentURL, datasetURL, pageNumber, isLastPage); + this.totalSize = totalSize < 0L ? 0L : totalSize; + } + + @Override + public StmtIterator getTriples() { + if (totalSize == 0L) + return emptyStmtIterator; + else + return getNonEmptyStmtIterator(); + } + + /** + * + * @return + */ + abstract protected StmtIterator getNonEmptyStmtIterator(); + + @Override + public long getTotalSize() { + return totalSize; + } + + @Override + public void addMetadata(final Model model) { + super.addMetadata(model); + + final Resource fragmentId = model.createResource(fragmentURL); + + final Literal totalTyped = model.createTypedLiteral(totalSize, + XSDDatatype.XSDinteger); + final Literal limitTyped = model.createTypedLiteral(getMaxPageSize(), + XSDDatatype.XSDinteger); + + fragmentId.addLiteral(CommonResources.VOID_TRIPLES, totalTyped); + fragmentId.addLiteral(CommonResources.HYDRA_TOTALITEMS, totalTyped); + fragmentId.addLiteral(CommonResources.HYDRA_ITEMSPERPAGE, limitTyped); + } + + @Override + public void addControls(final Model model) { + super.addControls(model); + + final Resource datasetId = model.createResource(getDatasetURI()); + + final Resource triplePattern = model.createResource(); + final Resource subjectMapping = model.createResource(); + final Resource predicateMapping = model.createResource(); + final Resource objectMapping = model.createResource(); + + datasetId.addProperty(CommonResources.HYDRA_SEARCH, triplePattern); + + triplePattern + .addProperty(CommonResources.HYDRA_TEMPLATE, getTemplate()); + triplePattern + .addProperty(CommonResources.HYDRA_MAPPING, subjectMapping); + triplePattern.addProperty(CommonResources.HYDRA_MAPPING, + predicateMapping); + triplePattern.addProperty(CommonResources.HYDRA_MAPPING, objectMapping); + + subjectMapping.addProperty(CommonResources.HYDRA_VARIABLE, + ITriplePatternFragmentRequest.PARAMETERNAME_SUBJ); + subjectMapping.addProperty(CommonResources.HYDRA_PROPERTY, + CommonResources.RDF_SUBJECT); + + predicateMapping.addProperty(CommonResources.HYDRA_VARIABLE, + ITriplePatternFragmentRequest.PARAMETERNAME_PRED); + predicateMapping.addProperty(CommonResources.HYDRA_PROPERTY, + CommonResources.RDF_PREDICATE); + + objectMapping.addProperty(CommonResources.HYDRA_VARIABLE, + ITriplePatternFragmentRequest.PARAMETERNAME_OBJ); + objectMapping.addProperty(CommonResources.HYDRA_PROPERTY, + CommonResources.RDF_OBJECT); + } + + /** + * + * @return + */ + public String getTemplate() { + return datasetURL + "{?" + + ITriplePatternFragmentRequest.PARAMETERNAME_SUBJ + "," + + ITriplePatternFragmentRequest.PARAMETERNAME_PRED + "," + + ITriplePatternFragmentRequest.PARAMETERNAME_OBJ + "}"; + } + + /** + * + */ + public static final StmtIterator emptyStmtIterator = new EmptyStmtIterator(); + + /** + * + */ + public static class EmptyStmtIterator extends NiceIterator + implements StmtIterator { + + /** + * + * @return + */ + public Statement nextStatement() { + throw new NoSuchElementException(); + } + } + +} diff --git a/src/test/java/org/linkeddatafragments/test/TestSuite.java b/src/test/java/org/linkeddatafragments/TestSuite.java similarity index 59% rename from src/test/java/org/linkeddatafragments/test/TestSuite.java rename to src/test/java/org/linkeddatafragments/TestSuite.java index 1accb53..6e24d87 100644 --- a/src/test/java/org/linkeddatafragments/test/TestSuite.java +++ b/src/test/java/org/linkeddatafragments/TestSuite.java @@ -1,10 +1,9 @@ -package org.linkeddatafragments.test; +package org.linkeddatafragments; import org.junit.runner.RunWith; import org.junit.runners.Suite; - -import org.linkeddatafragments.test.datasource.HdtDataSourceTest; -import org.linkeddatafragments.test.datasource.JenaTDBDataSourceTest; +import org.linkeddatafragments.datasource.HdtDataSourceTest; +import org.linkeddatafragments.datasource.JenaTDBDataSourceTest; /** * diff --git a/src/test/java/org/linkeddatafragments/test/datasource/DataSourceTest.java b/src/test/java/org/linkeddatafragments/datasource/DataSourceTest.java similarity index 96% rename from src/test/java/org/linkeddatafragments/test/datasource/DataSourceTest.java rename to src/test/java/org/linkeddatafragments/datasource/DataSourceTest.java index 8836620..3c4cb54 100644 --- a/src/test/java/org/linkeddatafragments/test/datasource/DataSourceTest.java +++ b/src/test/java/org/linkeddatafragments/datasource/DataSourceTest.java @@ -1,4 +1,4 @@ -package org.linkeddatafragments.test.datasource; +package org.linkeddatafragments.datasource; import com.google.gson.JsonObject; diff --git a/src/test/java/org/linkeddatafragments/test/datasource/HdtDataSourceTest.java b/src/test/java/org/linkeddatafragments/datasource/HdtDataSourceTest.java similarity index 94% rename from src/test/java/org/linkeddatafragments/test/datasource/HdtDataSourceTest.java rename to src/test/java/org/linkeddatafragments/datasource/HdtDataSourceTest.java index bd1c52e..4c56a22 100644 --- a/src/test/java/org/linkeddatafragments/test/datasource/HdtDataSourceTest.java +++ b/src/test/java/org/linkeddatafragments/datasource/HdtDataSourceTest.java @@ -1,4 +1,4 @@ -package org.linkeddatafragments.test.datasource; +package org.linkeddatafragments.datasource; import com.google.gson.JsonObject; diff --git a/src/test/java/org/linkeddatafragments/test/datasource/IndexRequestProcessorForTPFsTest.java b/src/test/java/org/linkeddatafragments/datasource/IndexRequestProcessorForTPFsTest.java similarity index 100% rename from src/test/java/org/linkeddatafragments/test/datasource/IndexRequestProcessorForTPFsTest.java rename to src/test/java/org/linkeddatafragments/datasource/IndexRequestProcessorForTPFsTest.java diff --git a/src/test/java/org/linkeddatafragments/test/datasource/JenaTDBDataSourceTest.java b/src/test/java/org/linkeddatafragments/datasource/JenaTDBDataSourceTest.java similarity index 94% rename from src/test/java/org/linkeddatafragments/test/datasource/JenaTDBDataSourceTest.java rename to src/test/java/org/linkeddatafragments/datasource/JenaTDBDataSourceTest.java index 1af273d..f766caa 100644 --- a/src/test/java/org/linkeddatafragments/test/datasource/JenaTDBDataSourceTest.java +++ b/src/test/java/org/linkeddatafragments/datasource/JenaTDBDataSourceTest.java @@ -1,4 +1,4 @@ -package org.linkeddatafragments.test.datasource; +package org.linkeddatafragments.datasource; import com.google.gson.JsonObject; diff --git a/src/test/java/org/linkeddatafragments/fragments/FragmentRequestParserBaseTest.java b/src/test/java/org/linkeddatafragments/fragments/FragmentRequestParserBaseTest.java new file mode 100644 index 0000000..6eb8840 --- /dev/null +++ b/src/test/java/org/linkeddatafragments/fragments/FragmentRequestParserBaseTest.java @@ -0,0 +1,34 @@ +package org.linkeddatafragments.fragments; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.IOException; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; + +import org.junit.Assert; +import org.junit.Test; +import org.linkeddatafragments.config.ConfigReader; + +public class FragmentRequestParserBaseTest { + + @Test + public void shouldIncludeContextPathInBaseUrl() throws IOException { + final ServletContext servletContext = mock(ServletContext.class); + when(servletContext.getContextPath()).thenReturn("/foo"); + final HttpServletRequest request = mock(HttpServletRequest.class); + when(request.getServletContext()).thenReturn(servletContext); + when(request.getServerPort()).thenReturn(123); + when(request.getScheme()).thenReturn("https"); + when(request.getServerName()).thenReturn("foo.bla"); + final ConfigReader configReader = mock(ConfigReader.class); + when(configReader.getBaseURL()).thenReturn(null); + final String baseUrl = FragmentRequestParserBase.extractBaseURL( + request, configReader); + Assert.assertEquals("Wrong baseUrl extracted", + "https://foo.bla:123/foo", baseUrl); + + } +} diff --git a/src/test/java/org/linkeddatafragments/fragments/tpf/TPFRequestParserTest.java b/src/test/java/org/linkeddatafragments/fragments/tpf/TPFRequestParserTest.java new file mode 100644 index 0000000..959de7e --- /dev/null +++ b/src/test/java/org/linkeddatafragments/fragments/tpf/TPFRequestParserTest.java @@ -0,0 +1,37 @@ +package org.linkeddatafragments.fragments.tpf; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; + +import org.junit.Assert; +import org.junit.Test; +import org.linkeddatafragments.config.ConfigReader; +import org.linkeddatafragments.fragments.tpf.TPFRequestParser.Worker; + +public class TPFRequestParserTest { + + @Test + public void shouldReturnCorrectDatasetUrl() { + final TPFRequestParser parser = new TPFRequestParser(null); + final ServletContext servletContext = mock(ServletContext.class); + when(servletContext.getContextPath()).thenReturn("/foo"); + final HttpServletRequest request = mock(HttpServletRequest.class); + when(request.getServletContext()).thenReturn(servletContext); + when(request.getServerPort()).thenReturn(123); + when(request.getScheme()).thenReturn("https"); + when(request.getServerName()).thenReturn("foo.bla"); + when(request.getServletPath()).thenReturn(""); + when(request.getPathInfo()).thenReturn("/someDataset"); + when(request.getRequestURI()).thenReturn("/foo" + "" + "/someDataset"); + final ConfigReader config = mock(ConfigReader.class); + when(config.getBaseURL()).thenReturn(null); + final Worker worker = parser.getWorker(request, config); + final String datasetUrl = worker.getDatasetURL(); + Assert.assertEquals("wrong datasetUrl returned", + "https://foo.bla:123/foo/someDataset", datasetUrl); + } + +}