NIHVIVO-3746 Permit DataGetter classes to have 4 different types of constructor - make reflection logic more rigorous to avoid NoSuchMethodException.

This commit is contained in:
j2blake 2012-05-02 17:04:24 +00:00
parent 18e171e1b9
commit a26f0c2809
6 changed files with 55 additions and 30 deletions

View file

@ -28,7 +28,7 @@ public class HomePageController extends FreemarkerHttpServlet {
Map<String, Object> body = new HashMap<String, Object>();
List<DataGetter> dgList = DataGetterUtils.getDataGettersForPage(vreq.getDisplayModel(), DisplayVocabulary.HOME_PAGE_URI);
List<DataGetter> dgList = DataGetterUtils.getDataGettersForPage(vreq, vreq.getDisplayModel(), DisplayVocabulary.HOME_PAGE_URI);
for( DataGetter dg : dgList){
Map<String,Object> moreData = dg.getData(getServletContext(),vreq,body);

View file

@ -282,7 +282,7 @@ public class MenuManagementController extends FreemarkerHttpServlet {
try{
String className = DataGetterUtils.getJClassForDataGetterURI(displayModel, dataGetterURI);
//TODO: Change so that instantiation here occurs correctly <-- how should data getter be instantiated
DataGetter pg = DataGetterUtils.dataGetterForURI(vreq.getDisplayModel(), dataGetterURI);
DataGetter pg = DataGetterUtils.dataGetterForURI(vreq, vreq.getDisplayModel(), dataGetterURI);
//TODO: Check template data variable and what that is?
Map<String, Object> pageData = pg.getData(getServletContext(), vreq, templateData);
//Map<String, Object> pageInfo = vreq.getWebappDaoFactory().getPageDao().getPage(pageURI);

View file

@ -23,7 +23,6 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.Tem
import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary;
import edu.cornell.mannlib.vitro.webapp.utils.dataGetter.DataGetter;
import edu.cornell.mannlib.vitro.webapp.utils.dataGetter.DataGetterUtils;
import edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter.PageDataGetterUtils;
/**
* Controller for getting data for pages defined in the display model.
*
@ -78,7 +77,7 @@ public class PageController extends FreemarkerHttpServlet{
private void executeDataGetters(String pageUri, VitroRequest vreq, ServletContext context, Map<String, Object> mapForTemplate)
throws Exception {
List<DataGetter> dgList = DataGetterUtils.getDataGettersForPage(vreq.getDisplayModel(), pageUri);
List<DataGetter> dgList = DataGetterUtils.getDataGettersForPage(vreq, vreq.getDisplayModel(), pageUri);
for( DataGetter dg : dgList){
Map<String,Object> moreData = dg.getData(context,vreq,mapForTemplate);

View file

@ -59,14 +59,14 @@ public class DataGetterUtils {
* This should not return PageDataGetters and should not throw an
* exception if a page has PageDataGetters.
*/
public static List<DataGetter> getDataGettersForPage( Model displayModel, String pageURI)
public static List<DataGetter> getDataGettersForPage( VitroRequest vreq, Model displayModel, String pageURI)
throws InstantiationException, IllegalAccessException, ClassNotFoundException, IllegalArgumentException, SecurityException, InvocationTargetException, NoSuchMethodException{
//get data getter uris for pageURI
List<String> dgUris = getDataGetterURIsForPageURI( displayModel, pageURI);
List<DataGetter> dgList = new ArrayList<DataGetter>();
for( String dgURI: dgUris){
DataGetter dg =dataGetterForURI(displayModel, dgURI) ;
DataGetter dg =dataGetterForURI(vreq, displayModel, dgURI) ;
if( dg != null )
dgList.add(dg);
}
@ -83,7 +83,7 @@ public class DataGetterUtils {
* This should not throw an exception if the URI exists and has a type
* that does not implement the DataGetter interface.
*/
public static DataGetter dataGetterForURI(Model displayModel, String dataGetterURI)
public static DataGetter dataGetterForURI(VitroRequest vreq, Model displayModel, String dataGetterURI)
throws InstantiationException, IllegalAccessException, ClassNotFoundException, IllegalArgumentException, InvocationTargetException, SecurityException, NoSuchMethodException
{
//get java class for dataGetterURI
@ -95,26 +95,42 @@ public class DataGetterUtils {
log.debug("Class doesn't implement DataGetter: '" + dgClassName + "'");
return null;
}
@SuppressWarnings("unchecked")
Class<DataGetter> dgClass = (Class<DataGetter>) clz;
Constructor<DataGetter> ct = null;
// we want a constructor that will work for one of these argument lists (in this order)
Object[][] argLists = new Object[][] {
{ vreq, displayModel, dataGetterURI },
{ displayModel, dataGetterURI },
{ vreq },
{}
};
ct = dgClass.getConstructor(Model.class, String.class);
if (ct != null) {
log.debug("Using this constructor: " + ct);
return ct.newInstance(displayModel, dataGetterURI);
}
ct = dgClass.getConstructor();
if (ct != null) {
log.debug("Using this constructor: " + ct);
return ct.newInstance();
// look through the available constructors for the best fit
for (Object[] argList: argLists) {
for (Constructor<?> ct: clz.getConstructors()) {
if (isConstructorSuitableForArguments(ct, argList)) {
log.debug("Using this constructor: " + ct);
return (DataGetter) ct.newInstance(argList);
}
}
}
log.debug("Didn't find a suitable constructor for '" + dgClassName + "'");
return null;
}
private static boolean isConstructorSuitableForArguments(Constructor<?> ct, Object[] args) {
Class<?>[] parameterTypes = ct.getParameterTypes();
if (args.length != parameterTypes.length) {
return false;
}
for (int i = 0; i < args.length; i++) {
Class<? extends Object> argClass = args[i].getClass();
if (! parameterTypes[i].isAssignableFrom(argClass)) {
return false;
}
}
return true;
}
public static String getJClassForDataGetterURI(Model displayModel, String dataGetterURI) throws IllegalAccessException {
String query = prefixes +
@ -390,11 +406,11 @@ public class DataGetterUtils {
* @throws IllegalAccessException
* @throws InstantiationException
*/
public static JSONObject covertDataToJSONForPage(String pageUri, Model displayModel) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
public static JSONObject covertDataToJSONForPage(VitroRequest vreq, String pageUri, Model displayModel) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
//Get PageDataGetter types associated with pageUri
JSONObject rObj = null;
try{
List<DataGetter> dataGetters = getDataGettersForPage(displayModel, pageUri);
List<DataGetter> dataGetters = getDataGettersForPage(vreq, displayModel, pageUri);
for(DataGetter getter: dataGetters) {
JSONObject typeObj = null;
try{

View file

@ -1,8 +1,6 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.utils.dataGetter;
import static org.junit.Assert.fail;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
@ -13,6 +11,8 @@ import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import stubs.javax.servlet.http.HttpServletRequestStub;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.rdf.model.Model;
@ -20,10 +20,12 @@ import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.impl.RDFDefaultErrorHandler;
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
public class DataGetterUtilsTest extends AbstractTestClass{
OntModel displayModel;
VitroRequest vreq;
String testDataGetterURI_1 = "http://vitro.mannlib.cornell.edu/ontologies/display/1.1#query1data";
String pageURI_1 = "http://vitro.mannlib.cornell.edu/ontologies/display/1.1#SPARQLPage";
String pageX = "http://vitro.mannlib.cornell.edu/ontologies/display/1.1#pageX";
@ -38,6 +40,8 @@ public class DataGetterUtilsTest extends AbstractTestClass{
InputStream in = DataGetterUtilsTest.class.getResourceAsStream("resources/dataGetterTest.n3");
model.read(in,"","N3");
displayModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_DL_MEM,model);
vreq = new VitroRequest(new HttpServletRequestStub());
}
@Test
@ -50,14 +54,14 @@ public class DataGetterUtilsTest extends AbstractTestClass{
@Test
public void testDataGetterForURI() throws IllegalArgumentException, SecurityException, InstantiationException, IllegalAccessException, ClassNotFoundException, InvocationTargetException, NoSuchMethodException {
DataGetter dg = DataGetterUtils.dataGetterForURI(displayModel, testDataGetterURI_1);
DataGetter dg = DataGetterUtils.dataGetterForURI(vreq, displayModel, testDataGetterURI_1);
Assert.assertNotNull(dg);
}
@Test
public void testGetDataGettersForPage() throws IllegalArgumentException, SecurityException, InstantiationException, IllegalAccessException, ClassNotFoundException, InvocationTargetException, NoSuchMethodException {
List<DataGetter> dgList =
DataGetterUtils.getDataGettersForPage(displayModel, pageURI_1);
DataGetterUtils.getDataGettersForPage(vreq, displayModel, pageURI_1);
Assert.assertNotNull(dgList);
Assert.assertTrue("List of DataGetters was empty, it should not be.", dgList.size() > 0);
}
@ -65,11 +69,11 @@ public class DataGetterUtilsTest extends AbstractTestClass{
@Test
public void testNonPageDataGetter() throws IllegalArgumentException, SecurityException, InstantiationException, IllegalAccessException, ClassNotFoundException, InvocationTargetException, NoSuchMethodException{
DataGetter dg = DataGetterUtils.dataGetterForURI(displayModel,dataGetterX);
DataGetter dg = DataGetterUtils.dataGetterForURI(vreq, displayModel,dataGetterX);
Assert.assertNull(dg);
List<DataGetter> dgList =
DataGetterUtils.getDataGettersForPage(displayModel, pageX);
DataGetterUtils.getDataGettersForPage(vreq, displayModel, pageX);
Assert.assertNotNull(dgList);
Assert.assertTrue("List should be, it was not", dgList.size() == 0);
}

View file

@ -12,6 +12,8 @@ import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import stubs.javax.servlet.http.HttpServletRequestStub;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.rdf.model.Model;
@ -21,6 +23,7 @@ import com.hp.hpl.jena.rdf.model.impl.RDFDefaultErrorHandler;
import com.hp.hpl.jena.vocabulary.RDF;
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.dao.jena.SimpleOntModelSelector;
import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactoryJena;
@ -30,6 +33,7 @@ public class SparqlQueryDataGetterTest extends AbstractTestClass{
OntModel displayModel;
String testDataGetterURI_1 = "http://vitro.mannlib.cornell.edu/ontologies/display/1.1#query1data";
WebappDaoFactory wdf;
VitroRequest vreq;
@Before
public void setUp() throws Exception {
@ -43,12 +47,14 @@ public class SparqlQueryDataGetterTest extends AbstractTestClass{
SimpleOntModelSelector sos = new SimpleOntModelSelector( ModelFactory.createOntologyModel(OntModelSpec.OWL_DL_MEM));
sos.setDisplayModel(displayModel);
wdf = new WebappDaoFactoryJena(sos);
wdf = new WebappDaoFactoryJena(sos);
vreq = new VitroRequest(new HttpServletRequestStub());
}
@Test
public void testBasicGetData() throws IllegalArgumentException, SecurityException, InstantiationException, IllegalAccessException, ClassNotFoundException, InvocationTargetException, NoSuchMethodException {
DataGetter dg = DataGetterUtils.dataGetterForURI(displayModel, testDataGetterURI_1);
DataGetter dg = DataGetterUtils.dataGetterForURI(vreq, displayModel, testDataGetterURI_1);
Assert.assertNotNull(dg);
Assert.assertTrue(
"DataGetter should be of type " + SparqlQueryDataGetter.class.getName(),