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>(); 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){ for( DataGetter dg : dgList){
Map<String,Object> moreData = dg.getData(getServletContext(),vreq,body); Map<String,Object> moreData = dg.getData(getServletContext(),vreq,body);

View file

@ -282,7 +282,7 @@ public class MenuManagementController extends FreemarkerHttpServlet {
try{ try{
String className = DataGetterUtils.getJClassForDataGetterURI(displayModel, dataGetterURI); String className = DataGetterUtils.getJClassForDataGetterURI(displayModel, dataGetterURI);
//TODO: Change so that instantiation here occurs correctly <-- how should data getter be instantiated //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? //TODO: Check template data variable and what that is?
Map<String, Object> pageData = pg.getData(getServletContext(), vreq, templateData); Map<String, Object> pageData = pg.getData(getServletContext(), vreq, templateData);
//Map<String, Object> pageInfo = vreq.getWebappDaoFactory().getPageDao().getPage(pageURI); //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.dao.DisplayVocabulary;
import edu.cornell.mannlib.vitro.webapp.utils.dataGetter.DataGetter; 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.dataGetter.DataGetterUtils;
import edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter.PageDataGetterUtils;
/** /**
* Controller for getting data for pages defined in the display model. * 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) private void executeDataGetters(String pageUri, VitroRequest vreq, ServletContext context, Map<String, Object> mapForTemplate)
throws Exception { throws Exception {
List<DataGetter> dgList = DataGetterUtils.getDataGettersForPage(vreq.getDisplayModel(), pageUri); List<DataGetter> dgList = DataGetterUtils.getDataGettersForPage(vreq, vreq.getDisplayModel(), pageUri);
for( DataGetter dg : dgList){ for( DataGetter dg : dgList){
Map<String,Object> moreData = dg.getData(context,vreq,mapForTemplate); 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 * This should not return PageDataGetters and should not throw an
* exception if a page has PageDataGetters. * 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{ throws InstantiationException, IllegalAccessException, ClassNotFoundException, IllegalArgumentException, SecurityException, InvocationTargetException, NoSuchMethodException{
//get data getter uris for pageURI //get data getter uris for pageURI
List<String> dgUris = getDataGetterURIsForPageURI( displayModel, pageURI); List<String> dgUris = getDataGetterURIsForPageURI( displayModel, pageURI);
List<DataGetter> dgList = new ArrayList<DataGetter>(); List<DataGetter> dgList = new ArrayList<DataGetter>();
for( String dgURI: dgUris){ for( String dgURI: dgUris){
DataGetter dg =dataGetterForURI(displayModel, dgURI) ; DataGetter dg =dataGetterForURI(vreq, displayModel, dgURI) ;
if( dg != null ) if( dg != null )
dgList.add(dg); dgList.add(dg);
} }
@ -83,7 +83,7 @@ public class DataGetterUtils {
* This should not throw an exception if the URI exists and has a type * This should not throw an exception if the URI exists and has a type
* that does not implement the DataGetter interface. * 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 throws InstantiationException, IllegalAccessException, ClassNotFoundException, IllegalArgumentException, InvocationTargetException, SecurityException, NoSuchMethodException
{ {
//get java class for dataGetterURI //get java class for dataGetterURI
@ -95,27 +95,43 @@ public class DataGetterUtils {
log.debug("Class doesn't implement DataGetter: '" + dgClassName + "'"); log.debug("Class doesn't implement DataGetter: '" + dgClassName + "'");
return null; 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); // look through the available constructors for the best fit
if (ct != null) { for (Object[] argList: argLists) {
for (Constructor<?> ct: clz.getConstructors()) {
if (isConstructorSuitableForArguments(ct, argList)) {
log.debug("Using this constructor: " + ct); log.debug("Using this constructor: " + ct);
return ct.newInstance(displayModel, dataGetterURI); return (DataGetter) ct.newInstance(argList);
}
} }
ct = dgClass.getConstructor();
if (ct != null) {
log.debug("Using this constructor: " + ct);
return ct.newInstance();
} }
log.debug("Didn't find a suitable constructor for '" + dgClassName + "'"); log.debug("Didn't find a suitable constructor for '" + dgClassName + "'");
return null; 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 { public static String getJClassForDataGetterURI(Model displayModel, String dataGetterURI) throws IllegalAccessException {
String query = prefixes + String query = prefixes +
"SELECT ?type WHERE { ?dgURI rdf:type ?type } "; "SELECT ?type WHERE { ?dgURI rdf:type ?type } ";
@ -390,11 +406,11 @@ public class DataGetterUtils {
* @throws IllegalAccessException * @throws IllegalAccessException
* @throws InstantiationException * @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 //Get PageDataGetter types associated with pageUri
JSONObject rObj = null; JSONObject rObj = null;
try{ try{
List<DataGetter> dataGetters = getDataGettersForPage(displayModel, pageUri); List<DataGetter> dataGetters = getDataGettersForPage(vreq, displayModel, pageUri);
for(DataGetter getter: dataGetters) { for(DataGetter getter: dataGetters) {
JSONObject typeObj = null; JSONObject typeObj = null;
try{ try{

View file

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