Skip to content
This repository has been archived by the owner on Oct 12, 2021. It is now read-only.

Bug 393073 - NPE in the hasNext method #5

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,23 @@
import org.apache.jena.rdf.model.Statement;
import org.apache.jena.rdf.model.StmtIterator;
import org.apache.jena.vocabulary.RDFS;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* The results of an OSLC query. If the query was paged, subsequent pages can be retrieved using the Iterator interface.
*
* This class is not currently thread safe.
*/
public class OslcQueryResult implements Iterator<OslcQueryResult> {

private final static Logger log = LoggerFactory.getLogger(OslcQueryResult.class);

/**
* The default member property to look for in OSLC query results
* (rdfs:member). Can be changed using {@link #setMemberProperty(Property)}.
* (rdfs:member). Can be changed using {@link #setMemberProperty(String)}.
*/
public final static Property DEFAULT_MEMBER_PROPERTY = RDFS.member;
public final static Property DEFAULT_MEMBER_PROPERTY = RDFS.member;

/**
* If system property {@value} is set to true, find any member in the
Expand All @@ -73,14 +77,13 @@ private AnyMemberSelector(Resource subject) {
}

public boolean selects(Statement s) {
String fqPredicateName = s.getPredicate().getNameSpace() + s.getPredicate().getLocalName();
if (OSLCConstants.RDF_TYPE_PROP.equals(fqPredicateName)) {
return false;
}
String fqPredicateName = s.getPredicate().getNameSpace() + s.getPredicate()
.getLocalName();
return !OSLCConstants.RDF_TYPE_PROP.equals(fqPredicateName) && s.getObject()
.isResource();

return s.getObject().isResource();
}
}
}
}

private final OslcQuery query;

Expand All @@ -101,20 +104,15 @@ public boolean selects(Statement s) {
public OslcQueryResult(OslcQuery query, ClientResponse response) {
this.query = query;
this.response = response;

this.pageNumber = 1;


}

private OslcQueryResult(OslcQueryResult prev) {
this.query = new OslcQuery(prev);
this.query = prev.query;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need to check for possible regression

this.response = this.query.getResponse();
this.membersResource = prev.membersResource;
this.memberProperty = prev.memberProperty;

this.pageNumber = prev.pageNumber + 1;

}

private synchronized void initializeRdf() {
Expand All @@ -128,11 +126,10 @@ private synchronized void initializeRdf() {
Property responseInfo = rdfModel.createProperty(OslcConstants.OSLC_CORE_NAMESPACE, "ResponseInfo");
ResIterator iter = rdfModel.listResourcesWithProperty(rdfType, responseInfo);

//There should only be one - take the first
infoResource = null;
while (iter.hasNext()) {
if (iter.hasNext()) {
// There should only be one - take the first
infoResource = iter.next();
break;
}
membersResource = rdfModel.getResource(query.getCapabilityUrl());
}
Expand All @@ -146,7 +143,14 @@ String getNextPageUrl() {
StmtIterator iter = rdfModel.listStatements(select);
if (iter.hasNext()) {
Statement nextPage = iter.next();
nextPageUrl = nextPage.getResource().getURI();
final RDFNode nextPageObject = nextPage.getObject();
if(nextPageObject != null && nextPageObject.isResource()) {
final Resource nextPageResource = nextPageObject.asResource();
nextPageUrl = nextPageResource.getURI();
} else {
log.warn("oslc:nextPage does not point to an RDF resource: {}", nextPageObject);
nextPageUrl = null;
}
} else {
nextPageUrl = "";
}
Expand All @@ -158,12 +162,13 @@ String getNextPageUrl() {
* @return whether there is another page of results after this
*/
public boolean hasNext() {
return (!"".equals(getNextPageUrl()));
final String nextPageUrl = getNextPageUrl();
final boolean nextUrlNotEmpty = nextPageUrl != null && nextPageUrl.trim().length() > 0;
return nextUrlNotEmpty;
}

/**
* @return the next page of results
* @throws NoSuchElementException if there is no next page
*/
public OslcQueryResult next() {
return new OslcQueryResult(this);
Expand Down Expand Up @@ -234,7 +239,7 @@ private Selector getMemberSelector() {
*/
public String[] getMembersUrls() {
initializeRdf();
ArrayList<String> membersUrls = new ArrayList<String>();
ArrayList<String> membersUrls = new ArrayList<>();
Selector select = getMemberSelector();
StmtIterator iter = rdfModel.listStatements(select);
while (iter.hasNext()) {
Expand All @@ -247,7 +252,6 @@ public String[] getMembersUrls() {
/**
* Return the enumeration of queried results from this page
*
* @param T
* @param clazz
*
* @return member statements from current page.
Expand All @@ -257,47 +261,30 @@ public <T> Iterable<T> getMembers(final Class<T> clazz) {

Selector select = getMemberSelector();
final StmtIterator iter = rdfModel.listStatements(select);
Iterable<T> result = new Iterable<T>() {
public Iterator<T>
iterator() {
return new Iterator<T>() {
public boolean hasNext() {
return iter.hasNext();
}

@SuppressWarnings("unchecked")
public T next() {
Statement member = iter.next();

try {
return (T)JenaModelHelper.fromJenaResource((Resource)member.getObject(), clazz);
} catch (IllegalArgumentException e) {
throw new IllegalStateException(e.getMessage());
} catch (SecurityException e) {
throw new IllegalStateException(e.getMessage());
} catch (DatatypeConfigurationException e) {
throw new IllegalStateException(e.getMessage());
} catch (IllegalAccessException e) {
throw new IllegalStateException(e.getMessage());
} catch (InstantiationException e) {
throw new IllegalStateException(e.getMessage());
} catch (InvocationTargetException e) {
throw new IllegalStateException(e.getMessage());
} catch (OslcCoreApplicationException e) {
throw new IllegalStateException(e.getMessage());
} catch (URISyntaxException e) {
throw new IllegalStateException(e.getMessage());
} catch (NoSuchMethodException e) {
throw new IllegalStateException(e.getMessage());
}
}

public void remove() {
iter.remove();
}
};
}
};
Iterable<T> result = () -> new Iterator<T>() {
public boolean hasNext() {
return iter.hasNext();
}

@SuppressWarnings("unchecked")
public T next() {
Statement member = iter.next();

try {
return (T) JenaModelHelper.fromJenaResource((Resource) member.getObject(),
clazz);
} catch (IllegalArgumentException | SecurityException | IllegalAccessException |
DatatypeConfigurationException | InvocationTargetException |
InstantiationException | URISyntaxException | OslcCoreApplicationException
| NoSuchMethodException e) {
throw new IllegalStateException(e.getMessage());
}
}

public void remove() {
iter.remove();
}
};

return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*******************************************************************************/
package org.eclipse.lyo.client.test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.*;
import static org.mockito.Mockito.when;

import java.io.InputStream;
Expand Down Expand Up @@ -72,6 +72,30 @@ public void testQuery() {
assertEquals(2, result.getMembersUrls().length);
}

@Test
public void testQueryResultHasNext() {
ClientResponse mockedResponse = mockClientResponse("/queryResponseWithNext.xml");

OslcQueryParameters params = new OslcQueryParameters();
params.setWhere("ex:product=\"Product A\"");
OslcQuery query = new OslcQuery(new OslcClient(), "http://example.com/provider/query",
params);
OslcQueryResult result = new OslcQueryResult(query, mockedResponse);
assertTrue("Next URI resource should be detected", result.hasNext());
}

@Test
public void testQueryResultWithEmptyNext() {
ClientResponse mockedResponse = mockClientResponse("/queryResponseWithEmptyNext.xml");

OslcQueryParameters params = new OslcQueryParameters();
params.setWhere("ex:product=\"Product A\"");
OslcQuery query = new OslcQuery(new OslcClient(), "http://example.com/provider/query",
params);
OslcQueryResult result = new OslcQueryResult(query, mockedResponse);
assertFalse("Empty Next URI resource should be ignored", result.hasNext());
}

@Test
public void testBlogQuery() {
ClientResponse mockedResponse = mockClientResponse("/blogQuery.rdf");
Expand Down
2 changes: 1 addition & 1 deletion oslc-java-client/src/test/resources/queryResponse.rdf
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<rdf:RDF xmlns:oslc="http://open-services.net/ns/core#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
<oslc:ResponseInfo rdf:about="http://example.com/provider/query?oslc.where=ex%3Aproduct%3D%22Product%20A%2">
<oslc:ResponseInfo rdf:about="http://example.com/provider/query?oslc.where=ex%3Aproduct%3D%22Product%20A%22">
<oslc:totalCount rdf:datatype="http://www.w3.org/2001/XMLSchema#int">2</oslc:totalCount>
</oslc:ResponseInfo>
<rdf:Description rdf:about="http://example.com/provider/query">
Expand Down
12 changes: 12 additions & 0 deletions oslc-java-client/src/test/resources/queryResponseWithEmptyNext.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:oslc="http://open-services.net/ns/core#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
<oslc:ResponseInfo rdf:about="http://example.com/provider/query?oslc.where=ex%3Aproduct%3D%22Product%20A%22">
<oslc:totalCount rdf:datatype="http://www.w3.org/2001/XMLSchema#int">2</oslc:totalCount>
<oslc:nextPage />
</oslc:ResponseInfo>
<rdf:Description rdf:about="http://example.com/provider/query">
<rdfs:member rdf:resource="http://example.com/resources/1"/>
<rdfs:member rdf:resource="http://example.com/resources/3"/>
</rdf:Description>
</rdf:RDF>
12 changes: 12 additions & 0 deletions oslc-java-client/src/test/resources/queryResponseWithNext.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:oslc="http://open-services.net/ns/core#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
<oslc:ResponseInfo rdf:about="http://example.com/provider/query?oslc.where=ex%3Aproduct%3D%22Product%20A%22">
<oslc:totalCount rdf:datatype="http://www.w3.org/2001/XMLSchema#int">2</oslc:totalCount>
<oslc:nextPage rdf:resource="http://example.com/provider/query?oslc.where=ex%3Aproduct%3D%22Product%20A%22&amp;page=2" />
</oslc:ResponseInfo>
<rdf:Description rdf:about="http://example.com/provider/query">
<rdfs:member rdf:resource="http://example.com/resources/1"/>
<rdfs:member rdf:resource="http://example.com/resources/3"/>
</rdf:Description>
</rdf:RDF>
2 changes: 1 addition & 1 deletion oslc4j-client/src/test/resources/queryResponse.rdf
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<rdf:RDF xmlns:oslc="http://open-services.net/ns/core#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
<oslc:ResponseInfo rdf:about="http://example.com/provider/query?oslc.where=ex%3Aproduct%3D%22Product%20A%2">
<oslc:ResponseInfo rdf:about="http://example.com/provider/query?oslc.where=ex%3Aproduct%3D%22Product%20A%22">
<oslc:totalCount rdf:datatype="http://www.w3.org/2001/XMLSchema#int">2</oslc:totalCount>
</oslc:ResponseInfo>
<rdf:Description rdf:about="http://example.com/provider/query">
Expand Down